I am using the AudioFileOpenWithCallbacks
function in my app to provide MP3 data in chunks. I call the function as follows:
AudioFileOpenWithCallbacks((__bridge void *)(self), TTMAudioFile_ReadProc, NULL, TTMAudioFile_GetSizeProc, NULL, 0, &aqData.mAudioFile);
In this case, self
is the containing Objective-C class.
My TTMAudioFile_ReadProc
callback function is as follows:
OSStatus TTMAudioFile_ReadProc(void *inClientData, SInt64 inPosition, UInt32 requestCount, void *buffer, UInt32 *actualCount) {
TTMAudioQueuePlayer *this = (__bridge TTMAudioQueuePlayer *)inClientData;
NSData *data = [this.decryptor dataAtOffset:inPosition length:requestCount error:NULL];
memcpy(buffer, data.bytes, data.length);
NSUInteger length = data.length;
*actualCount = (UInt32)length;
return noErr;
}
This works, but the NSData isn't being released. Profiling Allocations in Instruments reveal many allocations that look like the following:
Apparently there are two extra retain
calls in my callback function, but I don't see where I can be retaining them. Furthermore, I am using ARC, so I don't know why this is happening either.
I needed an autorelease pool.
The C callback function TTMAudioFile_ReadProc
is called on a separate thread from the main thread. In this case, an autorelease pool is not automatically created, unlike when working with dispatch queues.
OSStatus TTMAudioFile_ReadProc(void *inClientData, SInt64 inPosition, UInt32 requestCount, void *buffer, UInt32 *actualCount) {
@autoreleasepool {
TTMAudioQueuePlayer *this = (__bridge TTMAudioQueuePlayer *)inClientData;
NSData *data = [this.decryptor dataAtOffset:inPosition length:requestCount error:NULL];
memcpy(buffer, data.bytes, data.length);
NSUInteger length = data.length;
*actualCount = (UInt32)length;
return noErr;
}
}