【问题标题】:Cannot get output volume from any audio devices from cocoa objective-c无法从可可objective-c的任何音频设备获取输出音量
【发布时间】:2012-04-03 18:05:32
【问题描述】:

我正在尝试在 mac os x 应用程序中实现音量控制。当我运行代码循环安装在我的 macbook pro 中的音频设备并查询它们的主音量(或单个通道音量——我也尝试过)时,我无法得到任何结果。

这是我正在运行的代码:

- (NSArray*)getAudioDevices
{
  AudioObjectPropertyAddress propertyAddress = { 
    kAudioHardwarePropertyDevices, 
    kAudioObjectPropertyScopeGlobal, 
    kAudioObjectPropertyElementMaster 
  };

  UInt32 dataSize = 0;
  OSStatus status = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &dataSize);
  if(kAudioHardwareNoError != status)
  {
    NSLog(@"Unable to get number of audio devices. Error: %d",status);
    return NULL;
  }

  UInt32 deviceCount = dataSize / sizeof(AudioDeviceID);

  AudioDeviceID *audioDevices = malloc(dataSize);

  status = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &dataSize, audioDevices);
  if(kAudioHardwareNoError != status) 
  {
    NSLog(@"AudioObjectGetPropertyData failed when getting device IDs. Error: %d",status);
    free(audioDevices), audioDevices = NULL;
    return NULL;
  }

  NSMutableArray* devices = [NSMutableArray array];

  for(UInt32 i = 0; i < deviceCount; i++)
  {    

    // Query device name
    CFStringRef deviceName = NULL;
    dataSize = sizeof(deviceName);
    propertyAddress.mSelector = kAudioDevicePropertyDeviceNameCFString;
    status = AudioObjectGetPropertyData(audioDevices[i], &propertyAddress, 0, NULL, &dataSize, &deviceName);
    if(kAudioHardwareNoError != status) {
      fprintf(stderr, "AudioObjectGetPropertyData (kAudioDevicePropertyDeviceNameCFString) failed: %i\n", status);
      continue;
    }

    // Query device output volume
    Float32 volume;
    propertyAddress.mSelector = kAudioHardwareServiceDeviceProperty_VirtualMasterVolume;
    status = AudioHardwareServiceHasProperty(audioDevices[i], &propertyAddress);
    if(status) {
      fprintf(stderr, "AudioObjectGetPropertyData (kAudioHardwareServiceDeviceProperty_VirtualMasterVolume) failed: %i\n", status);
    } else {
      dataSize = sizeof(volume);
      status = AudioObjectGetPropertyData(audioDevices[i], &propertyAddress, 0, NULL, &dataSize, &volume);
      if (status) {
        // handle error
      }
    }

    NSLog(@"device found: %d - %@ || Vol: %f || status %i",audioDevices[i], deviceName, volume, status);  

    [devices addObject:[NSNumber numberWithInt:audioDevices[i]]];
  }

  free(audioDevices);

  return [NSArray arrayWithArray:devices];
}

以及我从日志中得到的输出:

device found: 58 - Built-in Microphone || Vol: 0.000000 || status 2003332927
device found: 78 - Built-in Input || Vol: 0.000000 || status 2003332927
device found: 68 - Built-in Output || Vol: 0.000000 || status 2003332927
device found: 54 - Microsoft LifeCam VX-5000 || Vol: 0.000000 || status 2003332927
device found: 87 - Microsoft LifeChat LX-3000  || Vol: 0.000000 || status 2003332927

我正在运行 OS X 10.7.3 / Xcode 4.3.2

设备上的卷实际上并未设置为零。谁能告诉我为什么我不能得到任何值?

【问题讨论】:

    标签: objective-c cocoa audio core-audio


    【解决方案1】:

    我不确定仅通过更改 mSelector 是否正确形成了您的 propertyAddress。尝试使用以下值创建一个新的 propertyAddress:

    AudioObjectPropertyAddress propertyAddress = { 
        kAudioDevicePropertyVolumeScalar, 
        kAudioDevicePropertyScopeOutput,
        1 
    };
    

    并在最终的 AudioObjectGetPropertyData 调用中使用它。

    【讨论】:

    • 嘿,谢谢。更改 mSelector 似乎可以正常获取设备名称。尽管您指定了 kAudioDevicePropertyVolumeScalar 而不是 kAudioHardwareServiceDeviceProperty_VirtualMasterVolume,但您发送的代码确实为我提供了几个设备的音量值。我想无论出于何种原因,后者在我的情况下都不是一个好的选择器。该 propertyAddress 中的 1 是否意味着我正在获取设备通道 1 的级别?
    • 是的,这就是频道。 Tech Note 2223中有几个例子。
    猜你喜欢
    • 1970-01-01
    • 2013-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-09
    • 1970-01-01
    • 2023-03-25
    相关资源
    最近更新 更多