在这个应该将音频从输入设备传递到输出设备的 Swift 代码中,0 的对象 id 来自哪里?查看错误信息

问题描述

我对此很陌生并且正在努力学习,所以如果以下不正确,请原谅,但我认为它应该做的是:

  • 初始化输入输出节点
  • 为每个节点创建一个音频单元
  • 为每个音频单元分配一个特定设备 ID 的“CurrentDevice”
  • 连接输入和输出
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。我怀疑您设置设备的尝试在失败时使引擎处于错误状态。