如何设置AVAudioEngine输入输出设备(swift/macos)

Ric*_*son 6 macos core-audio swift avaudioengine

我到处寻找,但找不到解决这个问题的方法。我正在寻找一种方法来更改将AVAudioEngine在 macOS 上使用的输入/输出设备。

当简单地播放音频文件时,以下内容按预期工作:

var outputDeviceID:AudioDeviceID = xxx 
let result:OSStatus = AudioUnitSetProperty(outputUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &outputDeviceID, UInt32(MemoryLayout<AudioObjectPropertyAddress>.size))
if result != 0  {
   print("error setting output device \(result)")
   return
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我初始化音频输入(使用let input = engine.inputNode),那么当我尝试启动引擎时,我会收到错误消息:

AVAEInternal.h:88 必需条件为 false: [AVAudioEngine.mm:1055:CheckCanPerformIO: (canPerformIO)]

我知道我的播放代码没问题,因为如果我避免更改输出设备,那么我可以听到麦克风和音频文件,如果我更改输出设备但不初始化文件,则文件会播放inputNode到指定的目的地。

除此之外,我一直在尝试更改输入设备,我从各个地方了解到以下应该执行此操作:

let result1:OSStatus = AudioUnitSetProperty(inputUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Output, 0, &inputDeviceID, UInt32(MemoryLayout<AudioObjectPropertyAddress>.size))
if result1 != 0  {
    print("failed with error \(result1)")
    return
}
Run Code Online (Sandbox Code Playgroud)

但是,这不起作用 - 在大多数情况下它会抛出错误(10853),尽管如果我选择同时具有输入和输出的声卡,它会成功 - 看来当我尝试设置输出或输入节点时它实际上是为两者设置设备。

我认为这意味着一个AVAudioEngine实例只能处理一个设备,但是它很高兴使用默认设备(麦克风和扬声器/耳机),所以我相信这不是问题。查看一些解决方案,我看到网上人们只是简单地更改默认输入,但这并不是一个非常好的解决方案。

有谁知道这是否可能?

值得注意的是,这kAudioOutputUnitProperty_CurrentDevice是唯一可用的属性,没有等效的kAudioInputUnitProperty_CurrentDevice键,因为据我了解, 和 都inputNodeoutputNode归类为“输出单位”(因为它们都在某处发出声音)。

任何想法将不胜感激,因为这非常非常令人沮丧!

谢谢

Ric*_*son 5

因此,我就这个问题和另一个问题向苹果提出了支持请求,响应确认 AVAudioEngine 只能分配给单个聚合设备(即具有输入和输出通道的设备) - 系统默认单位有效地创建一个内部聚合设备,这就是它们工作的原因,尽管我发现了一个额外的问题,如果输入设备也具有输出功能(并且您激活了 inputNode),那么该设备必须既是输入设备又是输出设备,否则输出设备似乎不起作用。

所以答案是我认为没有答案..