如何检查音频设备是不是为聚合设备

Posted

技术标签:

【中文标题】如何检查音频设备是不是为聚合设备【英文标题】:How to check if an audio device is an aggregate如何检查音频设备是否为聚合设备 【发布时间】:2012-04-23 07:31:50 【问题描述】:

我只是一个简短的问题: 有没有办法检查我拥有的 AudioDeviceID 是否是聚合设备? 我不确定如何检查这个,因为我没有找到可以与 AudioObjectGetPropertyDataSize 一起使用的相应选择器。 提前致谢!

【问题讨论】:

【参考方案1】:

所以我自己想出了一个解决方案: 通过获取属性kAudioAggregateDevicePropertyActiveSubDeviceList获取子设备列表

如果没有子设备,它会将OSStatus 设置为noErr 以外的其他值。如果是这种情况,您可以假设您手上有一个聚合设备。

【讨论】:

使用上述属性获取子设备列表的函数是哪个?任何代码 sn-ps ?【参考方案2】:

这是我在搜索 Coreaudio-api 邮件列表档案时遇到的另一个选项(其中有一些非常有用的东西,虽然可能需要一些搜索)。

聚合设备有一个独特的类 ID kAudioAggregateDeviceClassID,因此检查会更直接一些。

这个 sn-p 似乎可以解决问题:

                AudioObjectPropertyAddress classAddress = 
                    kAudioObjectPropertyClass,
                    kAudioObjectPropertyScopeGlobal,
                    kAudioObjectPropertyElementMaster
                ;

                AudioClassID classId;
                size = sizeof(AudioClassID);
                err = AudioObjectGetPropertyData(ioDeviceId, &classAddress, 0, NULL, &size, &classId);

对于聚合设备,classId 将是 kAudioAggregateDeviceClassID ('aagg'),而不是 kAudioDeviceClassID 或其他类 ID 之一。

原文出处: https://lists.apple.com/archives/Coreaudio-api//2009/Oct/msg00182.html

【讨论】:

【参考方案3】:

@Hobotrons 答案为您提供绑定到聚合设备的设备,不是聚合设备本身,这导致需要额外工作来查找没有此类设备的 SubDeviceLists。

您获得的聚合设备的 deviceID 与您对所有其他普通设备所做的相同,只是聚合设备具有子设备,因此需要一个特殊的 AudioDeviceTransportType 可用于区分它们。所以尽量留意kAudioDeviceTransportTypeAggregate

static bool isAggregateDevice(AudioDeviceID deviceID)

    AudioDevicePropertyID deviceType = getDeviceTransportType(deviceID);
    return deviceType == kAudioDeviceTransportTypeAggregate;


static AudioDevicePropertyID getDeviceTransportType(AudioDeviceID deviceID)

    AudioDevicePropertyID deviceTransportType = 0;
    UInt32 propSize = sizeof(AudioDevicePropertyID);
    AudioObjectPropertyAddress propAddress = addressForPropertySelector(kAudioDevicePropertyTransportType);
    AudioObjectGetPropertyData(deviceID, &propAddress, 0, nil, &propSize, &deviceTransportType);
    return deviceTransportType;


AudioObjectPropertyAddress addressForPropertySelector(AudioObjectPropertySelector selector)

    AudioObjectPropertyAddress address;
    address.mScope = kAudioObjectPropertyScopeGlobal;
    address.mElement = kAudioObjectPropertyElementMaster;
    address.mSelector = selector;
    return address;

从这里大部分与普通设备相同。

isAggregateDevice() 允许您构建逻辑,允许您在请求任何设备输入或输出之前进入子例程。尝试请求聚合设备的输入或输出可能会使您的应用程序崩溃,因为它们也可以有零输入和零输出。可以这么说,聚合设备也不喜欢以正常方式被要求输入或输出,当您假设每个设备也必须有一个输入或输出时,情况并非如此,并且属性获取的结果在以下情况下具有误导性返回 0。 (用户或其他代码可以随时更改聚合设备)。

因此,请确保您知道您的 deviceID 是否表示聚合设备的 ID,然后在此步骤中询问 In & Out OR SubDeviceList 及其在每个绑定设备中的 In & Out..

if (isAggregateDevice(deviceID)==true) 
 
    /* here ask for SubDeviceList */ 
    /* and maybe after that, climb into each */
    /* aggregated devices for its in's & outs */
 else 
    /* here ask for in's & outs of your normal device */ 

【讨论】:

以上是关于如何检查音频设备是不是为聚合设备的主要内容,如果未能解决你的问题,请参考以下文章

如何检测音频是不是无法静音?

UIImagePickerController 抛出错误:185:创建聚合音频设备时出错:尝试选择视频时出现“啥”

使用 CoreAudio 以编程方式在 Swift 中创建聚合音频设备

如何在 Mac OS X 中检测是不是连接了蓝牙音频设备?

如何检测断开的蓝牙音频设备是当前播放音乐流的设备?

如何监控设备的音频输出以判断声音是不是来自扬声器/耳机插孔?