问题描述
我对此很陌生并且正在努力学习,所以如果以下不正确,请原谅,但我认为它应该做的是:
func start() {
let engine = AVAudioEngine()
let inputNode = engine.inputNode
let outputNode = engine.outputNode
guard let inputUnit: AudioUnit = inputNode.audioUnit else { return }
guard let outputUnit: AudioUnit = outputNode.audioUnit else { return }
var inputdeviceid: Audiodeviceid = 46 // External input device
var outputdeviceid: Audiodeviceid = 57 // Mac mini speakers
AudioUnitSetProperty(inputUnit,kAudioOutputUnitProperty_CurrentDevice,kAudioUnitScope_Global,&inputdeviceid,UInt32(MemoryLayout<Audiodeviceid>.size))
AudioUnitSetProperty(outputUnit,&outputdeviceid,UInt32(MemoryLayout<Audiodeviceid>.size))
let bus = 0
engine.connect(inputNode,to: outputNode,fromBus: bus,toBus: bus,format: nil)
engine.prepare()
do {
try engine.start()
} catch {
print("error")
}
}
当我运行它时,日志充满:
AudioObjectGetPropertyDataSize: no object with given ID 0
AudioObjectGetPropertyData: no object with given ID 0
AudioObjectGetPropertyDataSize: no object with given ID 0
AudioObjectGetPropertyData: no object with given ID 0
AudioObjectGetPropertyDataSize: no object with given ID 0
AudioObjectGetPropertyData: no object with given ID 0
...
这个 0 的 ID 是从哪里来的?
如果我注释掉 AudioUnitSetProperty(...)
,错误就不会发生。
我在这里做错了什么?
解决方法
你所做的在我看来是正确的,尽管我通常使用 AUAudioUnit
:
try inputNode.AUAudioUnit.setDeviceID(inputDeviceID)
try outputNode.AUAudioUnit.setDeviceID(outputDeviceID)
我不知道在这种情况下它会有所作为。
以前对 AVAudioEngine
有一个未公开的限制,将同时输入和输出限制到默认系统设备 (https://www.mail-archive.com/[email protected]/msg01663.html)。我不确定 Big Sur 上是否仍然存在该限制。
一种可能的解决方法(我还没有机会尝试)是创建一个包含您想要的输入和输出设备的聚合设备,并将该设备与 AVAudioEngine
一起使用。
AudioObjectID
0 是 kAudioObjectUnknown
。我怀疑您设置设备的尝试在失败时使引擎处于错误状态。