I have a working AUv3 host implementation and I'm in the process of adding support for MIDI output from the plugin (introduced in iOS 11).
My host is written using the C AudioUnit API, but I know that the plugin (which supports MIDI output since iOS 11) is written using the AUAudioUnit API.
My host can successfully obtain a list of the MIDI outputs from the plugin with the following code:
UInt32 DataSize = 0;
Boolean IsWritable = false;
UInt32 NumMIDIOutputs = 0;
if ((AudioUnitGetPropertyInfo(mpAudioUnit, kAudioUnitProperty_MIDIOutputCallbackInfo, kAudioUnitScope_Global, 0, &DataSize, &IsWritable) == noErr) && (DataSize != 0))
{
CFArrayRef MIDIArray;
if (AudioUnitGetProperty (mpAudioUnit, kAudioUnitProperty_MIDIOutputCallbackInfo, kAudioUnitScope_Global, 0, &MIDIArray, &DataSize) == noErr)
{
NumMIDIOutputs = CFArrayGetCount(MIDIArray);
CFRelease(MIDIArray);
}
}
However, when the host attempts to set the MIDI output callback:
// Function prototype for the host's callback (shown for reference)
static OSStatus MIDIOutCallback(void* zpThis, const AudioTimeStamp* zpTimestamp, UInt32 zMIDIOutNum, const MIDIPacketList* zpPacketList)
// Does the plugin have at least one MIDI output?
if (NumMIDIOutputs > 0)
{
// Set up the host's callback
AUMIDIOutputCallbackStruct CallbackInfo;
zerostruct(CallbackInfo);
CallbackInfo.userData = this;
CallbackInfo.midiOutputCallback = HostMIDIOutCallback;
// Tell the plugin to use our callback for its MIDI output
OSStatus ReturnCode = AudioUnitSetProperty(mpAudioUnit, kAudioUnitProperty_MIDIOutputCallback, kAudioUnitScope_Global, 0, &CallbackInfo, sizeof(CallbackInfo));
if (ReturnCode != noErr)
{
// THIS FAILS WITH RETURN CODE -10879 (kAudioUnitErr_InvalidProperty) !!!
InfoPrintf("Couldn't set MIDI output callback : return code = %d\n", ReturnCode);
}
}
... it gets a return code of -10879 (kAudioUnitErr_InvalidProperty).
The plugin's developer informs me that MIDI output definitely works for hosts implemented using AUAudioUnit, but he hasn't tried it with hosts written using the C AudioUnit API.
- Is there anything I'm obviously doing wrong with my call to AudioUnitSetProperty(kAudioUnitProperty_MIDIOutputCallback)?
- Is there anything extra the plugin developer needs to do in order to make this work? (for example, the plugin implements AUAudioUnit's MIDIOutputNames property, but does not implement MIDIOutputBufferSizeHint)
- Is this a bug/lack of implentation in AUAudioUnit?