如何在Mac OS X上使用Core Audio API以编程方式设置扬声器配置?

Rau*_*nak 5 macos iokit core-audio kernel-extension

我有一个7.1声道音频输出设备和一个自定义kext来驱动它.我的自定义应用程序需要向设备发送7.1后置声道音频数据,但设备只接收2声道音频数据.我在"音频MIDI设置"应用程序中选中了"配置扬声器"选项,并将其设置为立体声.当我将它设置为"7.1后环绕"时一切正常.在我的最终产品中,我不希望用户必须手动完成所有这些操作.所以,问题是 - 是否有任何Core Audio API或任何其他方式以编程方式执行此操作?

在此输入图像描述

Rau*_*nak 5

好的,在玩了一些Core Audio API后,我终于可以完成这项工作了.

  1. 获取AudioDeviceID:

    AudioDeviceID audioDevice = getMyAwesomeDeviceID();
    
    Run Code Online (Sandbox Code Playgroud)
  2. 创建AudioObjectPropertyAddress:

    AudioObjectPropertyAddress propertyAddress;
    propertyAddress.mSelector = kAudioDevicePropertyPreferredChannelLayout;
    propertyAddress.mScope = kAudioDevicePropertyScopeOutput;
    propertyAddress.mElement = kAudioObjectPropertyElementMaster;
    
    Run Code Online (Sandbox Code Playgroud)
  3. 查询音频对象是否具有此属性:

    AudioObjectHasProperty(audioDevice, &propertyAddress)
    
    Run Code Online (Sandbox Code Playgroud)
  4. 获取此属性的数据大小并创建AudioChannelLayout:

    UInt32 propSize(0);
    AudioObjectGetPropertyDataSize(audioDevice, &propertyAddress, 0, NULL, &propSize);
    AudioChannelLayout* layout = (AudioChannelLayout*)malloc(propSize);
    
    Run Code Online (Sandbox Code Playgroud)
  5. 配置AudioChannelLayout结构(例如:立体声布局):

    AudioChannelLabel labels[2] = {kAudioChannelLabel_Right, kAudioChannelLabel_Left};
    
    layout->mNumberChannelDescriptions = 2;
    for (UInt32 i = 2; i < layout->mNumberChannelDescriptions; i++) {
        layout->mChannelDescriptions[i].mChannelLabel = labels[i];
        layout->mChannelDescriptions[i].mChannelFlags = kAudioChannelFlags_AllOff;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  6. 设置AudioObject属性数据:

    AudioObjectSetPropertyData(audioDevice, &propertyAddress, 0, NULL, propSize, layout);
    
    Run Code Online (Sandbox Code Playgroud)