Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect something in headphone jack on a Mac?

Is there a way to detect if something is plugged into the headphone jack of a Mac using c or objective-c?

Thanks

like image 505
David Avatar asked May 05 '11 05:05

David


2 Answers

Should you still want to dive in and mess with this deep magic I was able to construct something together form the code I found here:

http://www.iphonedevsdk.com/forum/iphone-sdk-development/54013-hardware-volume-change-listener-callback.html

You want to register a listen to the AudioProperties and catch any messages about 'kAudioSessionProperty_AudioRouteChange'. Using the 'reason' and the 'name' you can parse togather what happened. You can also read more about that here:

http://developer.apple.com/library/ios/#DOCUMENTATION/AudioToolbox/Reference/AudioSessionServicesReference/Reference/reference.html

// Registers this class as the delegate of the audio session.
[[AVAudioSession sharedInstance] setDelegate: self];

// Use this code instead to allow the app sound to continue to play when the screen is locked.
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: nil];

// Registers the audio route change listener callback function
AudioSessionAddPropertyListener (kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, self);

Callback:

void audioRouteChangeListenerCallback (void *inUserData, AudioSessionPropertyID inPropertyID, UInt32 inPropertyValueSize, const void *inPropertyValue ) {
    // ensure that this callback was invoked for a route change
    if (inPropertyID != kAudioSessionProperty_AudioRouteChange) return;


    {
        // Determines the reason for the route change, to ensure that it is not
        //      because of a category change.
        CFDictionaryRef routeChangeDictionary = (CFDictionaryRef)inPropertyValue;

        CFNumberRef routeChangeReasonRef = (CFNumberRef)CFDictionaryGetValue (routeChangeDictionary, CFSTR (kAudioSession_AudioRouteChangeKey_Reason) );
        SInt32 routeChangeReason;
        CFNumberGetValue (routeChangeReasonRef, kCFNumberSInt32Type, &routeChangeReason);

        if (routeChangeReason == kAudioSessionRouteChangeReason_OldDeviceUnavailable) {

            //Handle Headset Unplugged
        } else if (routeChangeReason == kAudioSessionRouteChangeReason_NewDeviceAvailable) {
                    //Handle Headset plugged in
        }

    }
}
like image 163
TurqMage Avatar answered Sep 28 '22 03:09

TurqMage


This is one of "those things": Things you should never, ever need to do or know. The general idea is that you use the APIs provided for playing sounds, and the sound subsystem takes care of the rest.

If you need a specific configuration, you can ask the user via dialog box to kindly configure his system in a specific manner, but that's about it.

Edit: The reason for this is that driver programming in general and sound programming in particular constitutes deep magic, and any application that tries to wrangle the hardware of the machine for any reason usually fail spectacularly, but often quite subtly.

Unless you are developing enterprise apps for a known, closed set of machines, never make assumptions about machine hardware: before you know it, the next model of the iMac comes without an analog jack, like, at all.

And even if the analog jack is present and empty, sound could be directed via a secondary sound card, either on-board, PCI or USB. Heck, there is even FireWire sound cards floating around out there, if memory serves.

like image 24
Williham Totland Avatar answered Sep 28 '22 02:09

Williham Totland