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

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

【问题讨论】:

    标签: macos audio core-audio


    【解决方案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 */ 
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-09
        相关资源
        最近更新 更多