diff --git a/Sound/SoundFile/CoreAudioFile.h b/Sound/SoundFile/CoreAudioFile.h index 5c4757779..437e65586 100644 --- a/Sound/SoundFile/CoreAudioFile.h +++ b/Sound/SoundFile/CoreAudioFile.h @@ -20,24 +20,22 @@ #import -#include +#include #import "SoundFile.h" +#define _USE_WRAPPER_ + @interface CoreAudioFile : SoundFile { - AudioFileID _in; + ExtAudioFileRef _in; + +#ifdef _USE_WRAPPER_ + FILE * _inFd; + AudioFileID _audioID; - SInt64 _packetCount; - SInt64 _totalPackets; SInt64 _fileSize; - UInt32 _maxPacketSize; - UInt32 _framesPerPacket; - - AudioConverterRef _converter; - void *_convBuf; - - FILE *_inFd; +#endif } @end diff --git a/Sound/SoundFile/CoreAudioFile.m b/Sound/SoundFile/CoreAudioFile.m index aa14c36fa..09cc7048b 100644 --- a/Sound/SoundFile/CoreAudioFile.m +++ b/Sound/SoundFile/CoreAudioFile.m @@ -21,28 +21,26 @@ #import "CoreAudioFile.h" @interface CoreAudioFile (Private) -- (BOOL) readInfoFromAudioFile; -- (BOOL) setupConverter: (AudioStreamBasicDescription *)inputFormat; +- (BOOL) readInfoFromExtAudioFileRef; @end @implementation CoreAudioFile -#define _USE_CALLBACKS_ -//#undef _USE_CALLBACKS_ - -#ifdef _USE_CALLBACKS_ +#ifdef _USE_WRAPPER_ OSStatus readFunc(void * inRefCon, SInt64 inPosition, ByteCount requestCount, void *buffer, ByteCount* actualCount) { CoreAudioFile *caf = (CoreAudioFile *)inRefCon; FILE *fd = caf->_inFd; - + fseek(fd, inPosition, SEEK_SET); - + *actualCount = fread(buffer, 1, requestCount, fd); if (*actualCount <= 0) + { return -1000; //Error? - + } + return noErr; } @@ -50,7 +48,8 @@ SInt64 getSizeFunc(void *inRefCon) { CoreAudioFile *caf = (CoreAudioFile *)inRefCon; FILE *fd = caf->_inFd; - + + if (caf->_fileSize != 0) { return caf->_fileSize; @@ -58,88 +57,31 @@ SInt64 getSizeFunc(void *inRefCon) long curPos; - NSLog(@"SIZE FUNC"); - curPos = ftell(fd); fseek(fd, 0, SEEK_END); - + caf->_fileSize = ftell(fd); fseek(fd, curPos, SEEK_SET); - + return caf->_fileSize; } OSStatus setSizeFunc(void * inRefCon, SInt64 inSize) { + NSLog(@"setsize FUNC"); + return -1000; //Not supported at the moment } OSStatus writeFunc(void * inRefCon, SInt64 inPosition, ByteCount requestCount, const void *buffer, ByteCount* actualCount) { + NSLog(@"WRITE FUNC"); return -1000; //Not supported at the moment } #endif -OSStatus ACInputProc(AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPackets, AudioBufferList *ioData, AudioStreamPacketDescription **outDataPacketDescription, void *inUserData) -{ - CoreAudioFile *caf = (CoreAudioFile *)inUserData; - OSStatus err = noErr; - UInt32 numBytes = 0; - - if (caf->_packetCount + *ioNumberDataPackets > caf->_totalPackets) - { - *ioNumberDataPackets = caf->_totalPackets - caf->_packetCount; - } - - if (*ioNumberDataPackets <= 0) - { - ioData->mBuffers[0].mData = NULL; - ioData->mBuffers[0].mDataByteSize = 0; - - return noErr; - } - - if (caf->_convBuf) - { - free(caf->_convBuf); - caf->_convBuf = NULL; - } - caf->_convBuf = malloc(*ioNumberDataPackets * caf->_maxPacketSize); - - SInt64 localPacketCount; - - localPacketCount = caf->_packetCount; - - err = AudioFileReadPackets(caf->_in, false, &numBytes, NULL, localPacketCount, ioNumberDataPackets, caf->_convBuf); - if(err != noErr) { - NSLog(@"Error reading AudioFile: %i", err); - return 0; - } - - caf->_packetCount += *ioNumberDataPackets; - - ioData->mBuffers[0].mData = caf->_convBuf; - ioData->mBuffers[0].mDataByteSize = numBytes; - - return err; -} - -- (id)init -{ - self = [super init]; - if (self) - { - _packetCount = 0; - _convBuf = NULL; - _totalPackets = 0; - _maxPacketSize = 0; - } - - return self; -} - - (BOOL) open:(const char *)filename { return [self readInfo:filename]; @@ -147,30 +89,24 @@ OSStatus ACInputProc(AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPac - (void) close { -#ifdef _USE_CALLBACKS_ - int err; - - err = fclose(_inFd); - if(err != 0) - { - NSLog(@"Error closing AudioFile: %i", err); - } -#else - OSStatus err; - - err = AudioFileClose(_in); - if (err != noErr) - { - NSLog(@"Error closing AudioFile: %i", err); - } + OSStatus err; + +#ifdef _USE_WRAPPER_ + fclose(_inFd); + AudioFileClose(_audioID); #endif + + err = ExtAudioFileDispose(_in); + if(noErr != err) { + NSLog(@"Error closing ExtAudioFile"); + } } - (BOOL) readInfo:(const char *)filename { OSStatus err; - -#ifdef _USE_CALLBACKS_ + +#ifdef _USE_WRAPPER_ // Open the input file _inFd = fopen(filename, "r"); if (!_inFd) @@ -180,85 +116,83 @@ OSStatus ACInputProc(AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPac } //Using callbacks with fopen, ftell, fseek, fclose, because the default pread hangs when accessing the same file from multiple threads. - err = AudioFileOpenWithCallbacks(self, readFunc, writeFunc, getSizeFunc, setSizeFunc, 0, &_in); + err = AudioFileOpenWithCallbacks(self, readFunc, writeFunc, getSizeFunc, setSizeFunc, 0, &_audioID); + if(noErr != err) + { + FSRef ref; + fclose(_inFd); + + err = FSPathMakeRef((const UInt8 *)filename, &ref, NULL); + if(noErr != err) { + return NO; + } + + err = AudioFileOpen(&ref, fsRdPerm, 0, &_audioID); + if(noErr != err) { + NSLog(@"Error opening AudioFile: %i", (char *)&err); + return NO; + } + } + + err = ExtAudioFileWrapAudioFileID(_audioID, NO, &_in); if(noErr != err) { - NSLog(@"Error opening AudioFile: %i", err); return NO; } + #else - FSRef ref; + FSRef ref; + + // Open the input file err = FSPathMakeRef((const UInt8 *)filename, &ref, NULL); if(noErr != err) { return NO; } - err = AudioFileOpen(&ref, fsRdPerm, 0, &_in); + err = ExtAudioFileOpen(&ref, &_in); if(noErr != err) { - NSLog(@"Error opening AudioFile: %i", err); return NO; } -#endif - - return [self readInfoFromAudioFile]; +#endif + return [self readInfoFromExtAudioFileRef]; } -- (BOOL) readInfoFromAudioFile +- (BOOL) readInfoFromExtAudioFileRef { OSStatus err; UInt32 size; + SInt64 totalFrames; AudioStreamBasicDescription asbd; - SInt64 totalBytes; // Get input file information size = sizeof(asbd); - err = AudioFileGetProperty(_in, kAudioFilePropertyDataFormat, &size, &asbd); + err = ExtAudioFileGetProperty(_in, kExtAudioFileProperty_FileDataFormat, &size, &asbd); if(err != noErr) { - [self close]; + err = ExtAudioFileDispose(_in); return NO; } - size = sizeof(_totalPackets); - err = AudioFileGetProperty(_in, kAudioFilePropertyAudioDataPacketCount, &size, &_totalPackets); + size = sizeof(totalFrames); + err = ExtAudioFileGetProperty(_in, kExtAudioFileProperty_FileLengthFrames, &size, &totalFrames); if(err != noErr) { - [self close]; + err = ExtAudioFileDispose(_in); return NO; } - - size = sizeof(totalBytes); - err = AudioFileGetProperty(_in, kAudioFilePropertyAudioDataByteCount, &size, &totalBytes); - if(err != noErr) { - [self close]; - return NO; - } - - bitRate = ((totalBytes*8)/((_totalPackets * asbd.mFramesPerPacket)/asbd.mSampleRate))/1000.0; + // Set our properties bitsPerSample = asbd.mBitsPerChannel; channels = asbd.mChannelsPerFrame; frequency = asbd.mSampleRate; - - _framesPerPacket = asbd.mFramesPerPacket; // mBitsPerChannel will only be set for lpcm formats if(0 == bitsPerSample) { bitsPerSample = 16; } - totalSize = _totalPackets * asbd.mFramesPerPacket *channels * (bitsPerSample/8); - - isBigEndian = YES; - isUnsigned = NO; - - return [self setupConverter:&asbd]; -} - -- (BOOL)setupConverter: (AudioStreamBasicDescription *)inputFormat -{ - OSStatus err; - UInt32 size; - AudioStreamBasicDescription result; + totalSize = totalFrames * channels * (bitsPerSample / 8); + bitRate = 0; // Set output format + AudioStreamBasicDescription result; bzero(&result, sizeof(AudioStreamBasicDescription)); @@ -272,87 +206,52 @@ OSStatus ACInputProc(AudioConverterRef inAudioConverter, UInt32 *ioNumberDataPac result.mBytesPerPacket = channels * (bitsPerSample / 8); result.mFramesPerPacket = 1; result.mBytesPerFrame = channels * (bitsPerSample / 8); - - err = AudioConverterNew(inputFormat, &result, &_converter); - if (err != noErr) - { - [self close]; - - NSLog(@"Error creating converter"); - return NO; - } - - err = AudioFileGetPropertyInfo( _in, - kAudioFilePropertyMagicCookieData, - &size, - NULL); - - if (err == noErr) //Some data can be read without magic cookies... - { - void *magicCookie = malloc (size); - //Get Magic Cookie data from Audio File - err = AudioFileGetProperty(_in, - kAudioFilePropertyMagicCookieData, - &size, - magicCookie); - // Give the AudioConverter the magic cookie decompression params if there are any - if (err == noErr) - { - err = AudioConverterSetProperty( _converter, - kAudioConverterDecompressionMagicCookie, - size, - magicCookie); - } - - free(magicCookie); - } - - size = sizeof(_maxPacketSize); - err = AudioFileGetProperty( _in, - kAudioFilePropertyMaximumPacketSize, - &size, - &_maxPacketSize); - if(err != noErr) { - err = AudioFileClose(_in); - NSLog(@"Error getting maximum packet size: %i", err); + err = ExtAudioFileSetProperty(_in, kExtAudioFileProperty_ClientDataFormat, sizeof(result), &result); + if(noErr != err) { + err = ExtAudioFileDispose(_in); return NO; } + // Further properties + isBigEndian = YES; + isUnsigned = NO; + return YES; } - (int) fillBuffer:(void *)buf ofSize:(UInt32)size { - OSStatus err; - UInt32 frameCount; - AudioBufferList ioData; + OSStatus err; + AudioBufferList bufferList; + UInt32 frameCount; + + // Set up the AudioBufferList + bufferList.mNumberBuffers = 1; + bufferList.mBuffers[0].mNumberChannels = channels; + bufferList.mBuffers[0].mData = buf; + bufferList.mBuffers[0].mDataByteSize = size; - ioData.mNumberBuffers = 1; - ioData.mBuffers[0].mData = buf; - ioData.mBuffers[0].mDataByteSize = size; - - frameCount = size / (channels * (bitsPerSample / 8)); - // Read a chunk of PCM input (converted from whatever format) - err = AudioConverterFillComplexBuffer(_converter, ACInputProc , self , &frameCount, &ioData, NULL); + frameCount = (size / (channels * (bitsPerSample / 8))); + err = ExtAudioFileRead(_in, &frameCount, &bufferList); if(err != noErr) { - NSLog(@"Error reading converter: %i", err); return 0; } - - return ioData.mBuffers[0].mDataByteSize; + + return frameCount * (channels * (bitsPerSample / 8)); } - (double) seekToTime:(double)milliseconds { - double newTime; - - _packetCount = ((milliseconds / 1000.f) * frequency)/_framesPerPacket; + OSStatus err; - newTime = ((_packetCount * _framesPerPacket)/frequency)*1000.0; + err = ExtAudioFileSeek(_in, ((milliseconds / 1000.f) * frequency)); + if(noErr != err) { + return -1.f; + } - return newTime; + return milliseconds; } @end