How to get the computer's current volume level?
There are two options available. The first step is to determine what device you'd like and get its ID. Assuming the default output device, the code will look something like:
AudioObjectPropertyAddress propertyAddress = {
kAudioHardwarePropertyDefaultOutputDevice,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster
};
AudioDeviceID deviceID;
UInt32 dataSize = sizeof(deviceID);
OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &dataSize, &deviceID);
if(kAudioHardwareNoError != result)
// Handle the error
Next, you can use the kAudioHardwareServiceDeviceProperty_VirtualMasterVolume
property to get the device's virtual master volume:
AudioObjectPropertyAddress propertyAddress = {
kAudioHardwareServiceDeviceProperty_VirtualMasterVolume,
kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMaster
};
if(!AudioHardwareServiceHasProperty(deviceID, &propertyAddress))
// An error occurred
Float32 volume;
UInt32 dataSize = sizeof(volume);
OSStatus result = AudioHardwareServiceGetPropertyData(deviceID, &propertyAddress, 0, NULL, &dataSize, &volume);
if(kAudioHardwareNoError != result)
// An error occurred
Alternatively, you can use kAudioDevicePropertyVolumeScalar
to get the volume for a specific channel:
UInt32 channel = 1; // Channel 0 is master, if available
AudioObjectPropertyAddress propertyAddress = {
kAudioDevicePropertyVolumeScalar,
kAudioDevicePropertyScopeOutput,
channel
};
if(!AudioObjectHasProperty(deviceID, &propertyAddress))
// An error occurred
Float32 volume;
UInt32 dataSize = sizeof(volume);
OSStatus result = AudioObjectGetPropertyData(deviceID, &propertyAddress, 0, NULL, &dataSize, &volume);
if(kAudioHardwareNoError != result)
// An error occurred
The difference between the two is explained in Apple's docs:
kAudioHardwareServiceDeviceProperty_VirtualMasterVolume
A Float32 value that represents the value of the volume control. The range for this property’s value is 0.0 (silence) through 1.0 (full level). The effect of this property depends on the hardware device associated with the HAL audio object. If the device has a master volume control, this property controls it. If the device has individual channel volume controls, this property applies to those identified by the device's preferred multichannel layout, or the preferred stereo pair if the device is stereo only. This control maintains relative balance between the channels it affects.
So it can be tricky to define exactly what a device's volume is, especially for multichannel devices with non-standard channel maps.
From CocoaDev, these class methods look like they should work, though it's not particularly Cocoa-like:
#import <AudioToolbox/AudioServices.h>
+(AudioDeviceID)defaultOutputDeviceID
{
AudioDeviceID outputDeviceID = kAudioObjectUnknown;
// get output device device
UInt32 propertySize = 0;
OSStatus status = noErr;
AudioObjectPropertyAddress propertyAOPA;
propertyAOPA.mScope = kAudioObjectPropertyScopeGlobal;
propertyAOPA.mElement = kAudioObjectPropertyElementMaster;
propertyAOPA.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
if (!AudioHardwareServiceHasProperty(kAudioObjectSystemObject, &propertyAOPA))
{
NSLog(@"Cannot find default output device!");
return outputDeviceID;
}
propertySize = sizeof(AudioDeviceID);
status = AudioHardwareServiceGetPropertyData(kAudioObjectSystemObject, &propertyAOPA, 0, NULL, &propertySize, &outputDeviceID);
if(status)
{
NSLog(@"Cannot find default output device!");
}
return outputDeviceID;
}
// getting system volume
+(float)volume
{
Float32 outputVolume;
UInt32 propertySize = 0;
OSStatus status = noErr;
AudioObjectPropertyAddress propertyAOPA;
propertyAOPA.mElement = kAudioObjectPropertyElementMaster;
propertyAOPA.mSelector = kAudioHardwareServiceDeviceProperty_VirtualMasterVolume;
propertyAOPA.mScope = kAudioDevicePropertyScopeOutput;
AudioDeviceID outputDeviceID = [[self class] defaultOutputDeviceID];
if (outputDeviceID == kAudioObjectUnknown)
{
NSLog(@"Unknown device");
return 0.0;
}
if (!AudioHardwareServiceHasProperty(outputDeviceID, &propertyAOPA))
{
NSLog(@"No volume returned for device 0x%0x", outputDeviceID);
return 0.0;
}
propertySize = sizeof(Float32);
status = AudioHardwareServiceGetPropertyData(outputDeviceID, &propertyAOPA, 0, NULL, &propertySize, &outputVolume);
if (status)
{
NSLog(@"No volume returned for device 0x%0x", outputDeviceID);
return 0.0;
}
if (outputVolume < 0.0 || outputVolume > 1.0) return 0.0;
return outputVolume;
}