I’m just working on getting at samples for processing from the microphone. I have an audio unit set up for input and output and both have render callbacks. My question is about the callback for the microphone callback.
I want core-audio to allocate the buffer in the microphone callback for me.
UInt32 shouldAllocateBuffer = 1;
AudioUnitSetProperty(audioUnit, kAudioUnitProperty_ShouldAllocateBuffer, kAudioUnitScope_Global, 1, &shouldAllocateBuffer, sizeof(shouldAllocateBuffer));
Doing this however always results in a NULL ioData pointer in the callback. Am I stuck allocating my own buffer?
Input
static OSStatus recordingCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData) {
OSStatus status;
status = AudioUnitRender(audioUnit,
ioActionFlags,
inTimeStamp,
inBusNumber,
inNumberFrames,
ioData); // ioData is null here
}
Playback
static OSStatus playbackCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData) {
// ioData is not NULL here but I get silence in the headphones.
return noErr;
}
AudioUnitRender still expects the AudioBufferList parameter (ioData) to be non-NULL.
If ioData is a pointer to AudioBufferList, then the buffer that should be is ioData->mBuffers[0].mData for most cases (see docs). If you are not allocating buffers, the buffer list should probably be a local variable, since it is only valid for the callback.
So, basically use a local variable and not ioData.
Note that you still need to set up your AudioBufferList to match the topology you are describing.
Here’s an example:
Note that if you need more than one buffers (you probably don’t, even for stereo), you can use malloc to extend the size of the mBuffers array.