I'm getting unexpected values for the volume level using kAudioDevicePropertyVolumeScalarToDecibels on my laptop's built-in audio.
The output is:
The same thing occurs using the underlying AudioControl directly.
Interestingly, using my external display's audio and the elements from kAudioDevicePropertyPreferredChannelsForStereo (since it has no master element), the values match.
Also of note, for the display audio kAudioDevicePropertyVolumeDecibelsToScalarTransferFunction is 5, or kAudioLevelControlTranferFunction2Over1. Attempting to retrieve kAudioDevicePropertyVolumeDecibelsToScalarTransferFunction for the laptop fails with the message
which is not a "normal" error message for an unsupported property.
How should kAudioDevicePropertyVolumeScalarToDecibels be used?
Code Block 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); }
The output is:
Code Block Direct = 0.0620 -47.69 dB Converted = 0.0620 -59.56 dB dB range -63.50 ... +0.00
The same thing occurs using the underlying AudioControl directly.
Interestingly, using my external display's audio and the elements from kAudioDevicePropertyPreferredChannelsForStereo (since it has no master element), the values match.
Also of note, for the display audio kAudioDevicePropertyVolumeDecibelsToScalarTransferFunction is 5, or kAudioLevelControlTranferFunction2Over1. Attempting to retrieve kAudioDevicePropertyVolumeDecibelsToScalarTransferFunction for the laptop fails with the message
Code Block HALC_ShellObject::GetPropertyData: call to the proxy failed, Error: 2003332927 (who?) HALPlugIn::ObjectGetPropertyData: got an error from the plug-in routine, Error: 2003332927 (who?)
which is not a "normal" error message for an unsupported property.
How should kAudioDevicePropertyVolumeScalarToDecibels be used?