4

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

4

3 回答 3

2

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

如果没有子设备,它将设置OSStatusnoErr. 如果是这种情况,您可以假设您手上有一个聚合设备。

于 2012-04-23T11:16:43.140 回答
1

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

聚合设备具有不同的类 ID kAudioAggregateDeviceClassID,因此检查会更直接一些。

这个片段似乎可以解决问题:

                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

于 2020-06-30T23:18:49.777 回答
0

@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 */ 
}
于 2021-08-31T22:54:03.400 回答