I have an app which can change the volume under OSX. What it lacks is the visual feedback provided when one presses the sound up/down keys. Does anyone know how to programmatically invoke that behavior? Thanks
Asked
Active
Viewed 1,091 times
2 Answers
7
Here's a little code from George Warner and Casey Fleser that does this trick. Think carefully that this is really the way you want to do things.
// Save as sound_up.m
// Compile: gcc -o sound_up sound_up.m -framework IOKit -framework Cocoa
#import <Cocoa/Cocoa.h>
#import <IOKit/hidsystem/IOHIDLib.h>
#import <IOKit/hidsystem/ev_keymap.h>
static io_connect_t get_event_driver(void)
{
static mach_port_t sEventDrvrRef = 0;
mach_port_t masterPort, service, iter;
kern_return_t kr;
if (!sEventDrvrRef)
{
// Get master device port
kr = IOMasterPort( bootstrap_port, &masterPort );
check( KERN_SUCCESS == kr);
kr = IOServiceGetMatchingServices( masterPort, IOServiceMatching( kIOHIDSystemClass ), &iter );
check( KERN_SUCCESS == kr);
service = IOIteratorNext( iter );
check( service );
kr = IOServiceOpen( service, mach_task_self(),
kIOHIDParamConnectType, &sEventDrvrRef );
check( KERN_SUCCESS == kr );
IOObjectRelease( service );
IOObjectRelease( iter );
}
return sEventDrvrRef;
}
static void HIDPostAuxKey( const UInt8 auxKeyCode )
{
NXEventData event;
kern_return_t kr;
IOGPoint loc = { 0, 0 };
// Key press event
UInt32 evtInfo = auxKeyCode << 16 | NX_KEYDOWN << 8;
bzero(&event, sizeof(NXEventData));
event.compound.subType = NX_SUBTYPE_AUX_CONTROL_BUTTONS;
event.compound.misc.L[0] = evtInfo;
kr = IOHIDPostEvent( get_event_driver(), NX_SYSDEFINED, loc, &event, kNXEventDataVersion, 0, FALSE );
check( KERN_SUCCESS == kr );
// Key release event
evtInfo = auxKeyCode << 16 | NX_KEYUP << 8;
bzero(&event, sizeof(NXEventData));
event.compound.subType = NX_SUBTYPE_AUX_CONTROL_BUTTONS;
event.compound.misc.L[0] = evtInfo;
kr = IOHIDPostEvent( get_event_driver(), NX_SYSDEFINED, loc, &event, kNXEventDataVersion, 0, FALSE );
check( KERN_SUCCESS == kr );
}
int main(int argc, char *argv[]) {
HIDPostAuxKey(NX_KEYTYPE_SOUND_UP);
}
Other interesting keycodes include: NX_KEYTYPE_SOUND_DOWN
, NX_KEYTYPE_MUTE
, NX_KEYTYPE_PLAY
.

George McGregor
- 71
- 1
-
Ah, so IOKit stuff may be needed. I'm going to take a look at this and see how it works out. – Lazloman May 11 '12 at 00:29
-
This actually raises/lowers the volume in full increments, i.e. one "block" at a time. What I want to do is recreate the behavior that existed pre-Lion, when one could press the option key and the up/down button and the volume would increase/decrease in fractional amounts, i.e. a quarter of a block. I can increase/decrease the volume in code by fractional amounts, and I want to get the OS to report that fractional increase/decrease in volume by those same fractional amounts, i.e., a quarter block at a time. I'll look through IOKit and see if I can do this, thanks, this gives me some ideas. – Lazloman May 12 '12 at 20:30
0
I would implement this by simulating the physical press of the up/down volume keys, and letting the OS deal with the details. Perhaps the user has disabled the visual feedback, perhaps it changes, etc. - this is the safest way of pulling it off.
Have a look at this: Simulating key press events in Mac OS X

Community
- 1
- 1

Mahmoud Al-Qudsi
- 28,357
- 12
- 85
- 125
-
I thought about, and I should have been clearer, but what I'm doing is raising/lowering the volume in smaller increments than the key presses would do. I expect that if I post key events, I'll end up with the standard increment in volume instead of the fraction increments as intended. – Lazloman Apr 23 '12 at 01:38
-
In that case, honestly, you probably should not be trying to use the default OS X volume notification thingy because it indicates the level as an atomic increment/decrement of one block - it could be misleading if shown when the user is actually making, as you say, much finer changes. – Mahmoud Al-Qudsi Apr 23 '12 at 03:04
-
I'm trying to re-create the behavior that existed before Lion. Are you saying that this is not possible anymore? – Lazloman Apr 23 '12 at 17:18
-
1you could always post the key events with shift+alt(vol up/down) to control the vol in smaller increments. – drunknbass Oct 25 '12 at 07:43