首页 > 解决方案 > 在 osx 上同时使用多个音频设备

问题描述

我的目标是在 OSX 上编写一个用于低延迟实时音频分析的音频应用程序。这将涉及连接到一个或多个 USB 接口并从这些设备获取特定通道。

我从学习核心有声读物开始,并使用 C 编写此书。当我沿着这条路走下去时,我发现许多旧框架已被弃用。看来,我想要实现的大部分内容都可以使用 AVAudioengine 并连接 AVAudioUnits 来编写,只为配置硬件设备等较低的事情深入挖掘核心音频级别。

我在这里对如何同时访问两个设备感到困惑。我不想创建聚合设备,因为我想单独处理这些设备。

使用核心音频,我可以列出所有设备的音频设备 ID,并在此处更改默认的系统输出设备(并且可以使用类似的方法进行输入设备)。但是,这只允许我使用一台物理设备,并且将始终在系统偏好设置中跟踪该设备。

static func setOutputDevice(newDeviceID: AudioDeviceID) {
    let propertySize = UInt32(MemoryLayout<UInt32>.size)
    var deviceID = newDeviceID
    var propertyAddress = AudioObjectPropertyAddress(
        mSelector: AudioObjectPropertySelector(kAudioHardwarePropertyDefaultOutputDevice),
        mScope: AudioObjectPropertyScope(kAudioObjectPropertyScopeGlobal),
        mElement: AudioObjectPropertyElement(kAudioObjectPropertyElementMaster))
        AudioObjectSetPropertyData(AudioObjectID(kAudioObjectSystemObject), &propertyAddress, 0, nil, propertySize, &deviceID)
}

然后我发现 kAudioUnitSubType_HALOutput 是指定只能通过此属性访问的静态设备的方法。我可以使用以下方法创建这种类型的组件:

var outputHAL = AudioComponentDescription(componentType: kAudioUnitType_Output, componentSubType: kAudioUnitSubType_HALOutput, componentManufacturer: kAudioUnitManufacturer_Apple, componentFlags: 0, componentFlagsMask: 0)

    let component = AudioComponentFindNext(nil, &outputHAL)

    guard component != nil else {
        print("Can't get input unit")
        exit(-1)
    }

但是,我对如何创建此组件的描述然后找到与描述匹配的下一个设备感到困惑。是否有可以选择音频设备 ID 并将 AUHAL 链接到此的属性?

我也无法弄清楚如何将 AUHAL 分配给 AVAudioEngine。我可以为 HAL 创建一个节点,但不能将它附加到引擎。最后是否可以创建多个 kAudioUnitSubType_HALOutput 组件并将它们输入混音器?

上周我一直在尝试研究这个问题,但离答案还很近。我已经阅读了通道映射以及我需要知道的所有内容,但是在这个级别上可以获得音频。较低的级别似乎没有记录,尤其是在使用 swift 时。

标签: swiftmacosavaudioengine

解决方案


推荐阅读