Set/get volume in OS X
June 25, 2019
How to get/set master volume in OS X. Many sample codes online use the deprecated API. This uses the currently 'legal' API.
#include <CoreAudio/CoreAudio.h>
#include <AudioToolbox/AudioToolbox.h>
#include <AudioToolbox/AudioServices.h>
#include <AppKit/AppKit.h>
#include <CoreGraphics/CGEvent.h>
static AudioDeviceID getDefaultOutputDeviceID()
{
AudioDeviceID outputDeviceID = kAudioObjectUnknown;
// get output device device
OSStatus status = noErr;
AudioObjectPropertyAddress propertyAOPA;
propertyAOPA.mScope = kAudioObjectPropertyScopeGlobal;
propertyAOPA.mElement = kAudioObjectPropertyElementMaster;
propertyAOPA.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
if (!AudioObjectHasProperty(
kAudioObjectSystemObject,
&propertyAOPA))
{
printf("Cannot find default output device!");
return outputDeviceID;
}
status = AudioObjectGetPropertyData(
kAudioObjectSystemObject,
&propertyAOPA,
0,
NULL,
(UInt32[]){sizeof(AudioDeviceID)},
&outputDeviceID);
if (status != 0)
{
printf("Cannot find default output device!");
}
return outputDeviceID;
}
float getVolume()
{
Float32 outputVolume;
OSStatus status = noErr;
AudioObjectPropertyAddress propertyAOPA;
propertyAOPA.mElement = kAudioObjectPropertyElementMaster;
propertyAOPA.mSelector = kAudioHardwareServiceDeviceProperty_VirtualMasterVolume;
propertyAOPA.mScope = kAudioDevicePropertyScopeOutput;
AudioDeviceID outputDeviceID = getDefaultOutputDeviceID();
if (outputDeviceID == kAudioObjectUnknown)
{
printf("Unknown device");
return 0.0;
}
if (!AudioObjectHasProperty(outputDeviceID, &propertyAOPA))
{
printf("No volume returned for device 0x%0x", outputDeviceID);
return 0.0;
}
status = AudioObjectGetPropertyData(
outputDeviceID,
&propertyAOPA,
0,
NULL,
(UInt32[]){sizeof(Float32)},
&outputVolume);
if (status)
{
printf("No volume returned for device 0x%0x", outputDeviceID);
return 0.0;
}
if (outputVolume < 0.0 || outputVolume > 1.0) return 0.0;
return outputVolume;
}
void setVolume(float volume)
{
AudioDeviceID outputDeviceID;
AudioObjectPropertyAddress propertyAddress = {
kAudioHardwareServiceDeviceProperty_VirtualMasterVolume,
kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMaster
};
outputDeviceID = getDefaultOutputDeviceID();
// Deprecated API. Switch to AudioObjectSetPropertyData
/*
AudioHardwareServiceSetPropertyData(outputDeviceID,
&propertyAddress,
0,
NULL,
sizeof(Float32),
&volume);
*/
AudioObjectSetPropertyData(
outputDeviceID,
&propertyAddress,
0,
NULL,
sizeof(Float32),
&volume);
}
Adapted from this SO post.