How to detect something in headphone jack on a Mac?

淺唱寂寞╮ 提交于 2019-11-29 02:28:55

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
        }

    }
}

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.

This is a hidden function that exist (or not) on your embedded chip. If the manufacture release an API you can control it, otherwise you can't.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!