In playing a tone (e.g., here), we have to tell the machine what function will fill the IO buffer:
// Set our tone rendering function on the unit
AURenderCallbackStruct input;
input.inputProc = RenderTone;
input.inputProcRefCon = self;
err = AudioUnitSetProperty(toneUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input,
0,
&input,
sizeof(input));
It's clear that inputProc
is the procedure from which to take input for the audiounit. But what is inputProcRefCon
exactly? Would there ever be a case where it cannot be set to self
?
The refCon is a void (untyped) pointer to arbitrary data, in your example to the C struct backing the calling object. If the inputProc callback function doesn't need any extra parameters (instance variables) from the calling object passed, then you don't need to pass it self, or you can point refCon at some other data (a different C struct or object). But most callbacks do need some parameters.
It's a C void pointer because the API is for real-time code that predates newer Objective C idioms.
It's short for "input procedure's reference context". So, to elaborate on @hotpaw2's answer, it's a reference to arbitrary data that can be used in an audio unit's render callback.
For example, if your Audio Unit is supposed to process incoming audio, then inputProc
must point to the buffer containing the samples you need it to process.
float **_myBuffer; // initialise this properly!
AURenderCallbackStruct callback = {0};
callback.inputProc = MyAudioUnitEffectCallback;
callback.inputProcRefCon = _myBuffer;
UInt32 propertySize = sizeof(AURenderCallbackStruct);
status = AudioUnitSetProperty(_myAudioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, 0, &callback, propertySize);
assert(status == noErr);
// then elsewhere in the file:
OSStatus MyAudioUnitEffectCallback(void * inRefCon,
AudioUnitRenderActionFlags * ioActionFlags,
const AudioTimeStamp * inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * __nullable ioData) {
// inputBuffer is going to be _myBuffer
float ** inputBuffer = static_cast<float **>(inRefCon);
// process the samples inside it and then place them into ioData
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With