Looks like Apple audio bug to me.
The first version uses older API and it works ok (in that it calls the callback):
func startMic1(_ mic: AudioDeviceID) {
var desc = AudioComponentDescription(componentType: kAudioUnitType_Output, componentSubType: kAudioUnitSubType_HALOutput,
componentManufacturer: kAudioUnitManufacturer_Apple, componentFlags: 0, componentFlagsMask: 0)
let comp = AudioComponentFindNext(nil, &desc)
var unit: AudioUnit!
AudioComponentInstanceNew(comp!, &unit)
var enable: UInt32 = 1
AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enable, 4)
var disable: UInt32 = 0
AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &disable, 4)
var device = mic
AudioUnitSetProperty(unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &device, 8)
var cb = AURenderCallbackStruct(inputProc: { _, _, _, _, _, _ in
fatalError("callback")
}, inputProcRefCon: nil)
AudioUnitSetProperty(unit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 1, &cb, 16)
AudioUnitInitialize(unit)
AudioOutputUnitStart(unit)
}
The second version utilises a newer API and doesn't work (doesn't call the callback):
func startMic2(_ mic: AudioDeviceID) {
let desc = AudioComponentDescription(componentType: kAudioUnitType_Output, componentSubType: kAudioUnitSubType_HALOutput,
componentManufacturer: kAudioUnitManufacturer_Apple, componentFlags: 0, componentFlagsMask: 0)
let unit = try! AUAudioUnit(componentDescription: desc, options: [])
unit.isInputEnabled = true
unit.isOutputEnabled = false
try! unit.setDeviceID(mic)
unit.inputHandler = { _, _, _, _ in
fatalError("callback")
}
try! unit.allocateRenderResources()
try! unit.startHardware()
}
Error handling removed for brevity.
Topic:
App & System Services
SubTopic:
Core OS
Tags: