From 89fb9c95ba79556ba6c60b759b5c6acd5140dee6 Mon Sep 17 00:00:00 2001 From: vspader Date: Sat, 3 Jun 2006 20:26:19 +0000 Subject: [PATCH] Added new SHN decoder (Derek Scott) --- Sound/SoundFile/ShnFile.mm | 158 +++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 Sound/SoundFile/ShnFile.mm diff --git a/Sound/SoundFile/ShnFile.mm b/Sound/SoundFile/ShnFile.mm new file mode 100644 index 000000000..e52a55983 --- /dev/null +++ b/Sound/SoundFile/ShnFile.mm @@ -0,0 +1,158 @@ +// +// ShnFile.mm +// Cog +// +// Created by Vincent Spader on 6/6/05. +// Copyright 2005 Vincent Spader All rights reserved. +// + +#import "ShnFile.h" + +@implementation ShnFile + +- (BOOL)open:(const char *)filename +{ + if ([self readInfo:filename] == NO) + return NO; + + return YES; +} + +- (BOOL)readInfo:(const char *)filename +{ + decoder = new shn_reader; + + if (!decoder) + { + return NO; + } + + decoder->open(filename, true); + + bufferSize = decoder->shn_get_buffer_block_size(512); + buffer = malloc(bufferSize); + + unsigned int length; + int chan; + float freq; + int bps; + + decoder->file_info(NULL, &chan, &freq, NULL, &bps, NULL); + + /*NSLog(@"chan: %d",chan); + NSLog(@"freq: %f",freq); + NSLog(@"bps: %d",bps);*/ + + channels = chan; + frequency = (int)freq; + bitsPerSample = bps; + + /*NSLog(@"channels: %d",channels); + NSLog(@"frequency: %f",(double)frequency); + NSLog(@"bitsPerSample: %d",bitsPerSample);*/ + + length = decoder->shn_get_song_length(); + //NSLog(@"length: %d",length); + totalSize = (((double)(length)*frequency)/1000.0) * channels * (bitsPerSample/8); + bitRate = (int)((double)totalSize/((double)length/1000.0)); + + /*NSLog(@"totalSize: %d",totalSize); + NSLog(@"bitRate: %d",bitRate);*/ + + decoder->go(); + + return YES; +} + +- (int)fillBuffer:(void *)buf ofSize:(UInt32)size +{ + + //long numread = bufferAmount; + //long count = 0; + long numread, count; + bufferAmount = 0; + inputBuffer = malloc(bufferSize); + + //Fill from buffer, going by bufferAmount + //if still needs more, decode and repeat + if (bufferAmount == 0) + { + //bufferAmount = shn_read(handle, buffer, bufferSize); + while((bufferAmount = decoder->read(inputBuffer, bufferSize)) == (unsigned)(-1)) + { + bufferAmount = decoder->read(inputBuffer, bufferSize); + } + if (bufferAmount == 0) + return 0; + else if(bufferAmount == (unsigned)( -2)) + { + //NSLog(@"closing file, eof"); + return -2; + } + else + { + memcpy(buffer, inputBuffer, bufferAmount); + free(inputBuffer); + } + } + + //NSLog(@"bufferAmount: %d",bufferAmount); + + + count = bufferAmount; + if (bufferAmount > size) + { + count = size; + } + + memcpy(buf, buffer, count); + + bufferAmount -= count; + + if (bufferAmount > 0) + memmove(buffer, (&((char *)buffer)[count]), bufferAmount); + + if (count < size) + numread = [self fillBuffer:(&((char *)buf)[count]) ofSize:(size - count)]; + else + numread = 0; + + return count + numread; +} + +- (double)seekToTime:(double)milliseconds +{ + unsigned int sec; + + /*if (!shn_seekable(handle)) + return -1.0;*/ + + sec = (int)(milliseconds/1000.0); + + //shn_seek(handle, sec); + + decoder->seek(sec); + + return (sec * 1000.0); +} + +- (void)close +{ + if(decoder) + { + decoder->exit(); + delete decoder; + decoder = NULL; + } + + if (buffer) + { + free(buffer); + buffer = NULL; + } + + /*if (shn_cleanup_decoder(handle)) + shn_unload(handle);*/ +} + +@end