首页 > 解决方案 > 使用 kAudioDevicePropertyVolumeScalarToDecibels 的意外值

问题描述

我在kAudioDevicePropertyVolumeScalarToDecibels笔记本电脑的内置音频上使用的音量级别得到了意想不到的值。

void volume_test()
{
    AudioObjectPropertyAddress address = {
        .mSelector = kAudioHardwarePropertyDefaultOutputDevice,
        .mScope = kAudioObjectPropertyScopeGlobal,
        .mElement = kAudioObjectPropertyElementMaster
    };

    AudioObjectID deviceID = kAudioObjectUnknown;
    UInt32 dataSize = sizeof(deviceID);
    OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &address, 0, NULL, &dataSize, &deviceID);
    assert(result == noErr);

    address.mSelector = kAudioDevicePropertyVolumeScalar;
    address.mScope = kAudioObjectPropertyScopeOutput;

    Float32 volumeScalar = 0;
    dataSize = sizeof(volumeScalar);
    result = AudioObjectGetPropertyData(deviceID, &address, 0, NULL, &dataSize, &volumeScalar);
    assert(result == noErr);

    address.mSelector = kAudioDevicePropertyVolumeDecibels;

    Float32 volumeDecibels = 0;
    dataSize = sizeof(volumeDecibels);
    result = AudioObjectGetPropertyData(deviceID, &address, 0, NULL, &dataSize, &volumeDecibels);
    assert(result == noErr);

    address.mSelector = kAudioDevicePropertyVolumeScalarToDecibels;

    Float32 convertedVolumeDecibels = volumeScalar;
    dataSize = sizeof(convertedVolumeDecibels);
    result = AudioObjectGetPropertyData(deviceID, &address, 0, NULL, &dataSize, &convertedVolumeDecibels);
    assert(result == noErr);

    address.mSelector = kAudioDevicePropertyVolumeDecibelsToScalar;

    Float32 convertedVolumeScalar = volumeDecibels;
    dataSize = sizeof(convertedVolumeScalar);
    result = AudioObjectGetPropertyData(deviceID, &address, 0, NULL, &dataSize, &convertedVolumeScalar);
    assert(result == noErr);

    NSLog(@"Direct    = %.4f %+2.2f dB", volumeScalar, volumeDecibels);
    NSLog(@"Converted = %.4f %+2.2f dB", convertedVolumeScalar, convertedVolumeDecibels);

    address.mSelector = kAudioDevicePropertyVolumeRangeDecibels;

    AudioValueRange decibelRange;
    dataSize = sizeof(decibelRange);
    result = AudioObjectGetPropertyData(deviceID, &address, 0, NULL, &dataSize, &decibelRange);
    assert(result == noErr);

    NSLog(@"dB range %+2.2f ... %+2.2f", decibelRange.mMinimum, decibelRange.mMaximum);
}

输出是:

Direct    = 0.0620 -47.69 dB
Converted = 0.0620 -59.56 dB
dB range -63.50 ... +0.00

直接使用底层证券也会发生同样的事情AudioControl

作为参考,音频 MIDI 设置显示:

音频 MIDI 设置

有趣的是,使用我的外部显示器的音频和来自kAudioDevicePropertyPreferredChannelsForStereo(因为它没有主元素)的元素,值匹配。

另外值得注意的是,对于显示音频kAudioDevicePropertyVolumeDecibelsToScalarTransferFunction5, 或kAudioLevelControlTranferFunction2Over1。尝试检索kAudioDevicePropertyVolumeDecibelsToScalarTransferFunction笔记本电脑失败并显示消息

HALC_ShellObject::GetPropertyData: call to the proxy failed, Error: 2003332927 (who?)
HALPlugIn::ObjectGetPropertyData: got an error from the plug-in routine, Error: 2003332927 (who?)

对于不受支持的属性,这不是“正常”错误消息。

应该如何kAudioDevicePropertyVolumeScalarToDecibels使用?

标签: macoscore-audio

解决方案


推荐阅读