Ok, after re-reading the docs for the 10th time, I noticed AVAudioEngine
has members inputNode and outputNode (not sure how I missed that!).
The following code seems to do the job:
AudioDeviceID inputDeviceID = 53; // get this using AudioObjectGetPropertyData
AVAudioEngine *engine = [[AVAudioEngine alloc] init];
AudioUnit audioUnit = [[engine inputNode] audioUnit];
OSStatus error = AudioUnitSetProperty(audioUnit,
kAudioOutputUnitProperty_CurrentDevice,
kAudioUnitScope_Global,
0,
&inputDeviceID,
sizeof(inputDeviceID));
I borrowed the non-AVFoundation C code from the CAPlayThrough example.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…