iOS Reference Library Apple Developer
Search

Handling Audio Hardware Route Changes

As your application runs, a user might plug in or unplug a headset, or use a docking station with audio connections. iPhone Human Interface Guidelines describes how iOS applications should respond to such events. To implement the recommendations, write audio session code to handle audio hardware route changes.

Note: To handle route changes, employ the C-based Audio Session Services interface‚Äîeven if your other audio session code employs the Objective-C-based AV Foundation framework.

Varieties of Audio Hardware Route Change

An audio hardware route is a wired electronic pathway for audio signals. When a user of an iOS device plugs in or unplugs a headset, the system automatically changes the audio hardware route. Your application can listen for such changes by way of the audio session property mechanism.

Figure 4-1 depicts the sequence of events for various route changes during recording and playback. The four possible outcomes, shown across the bottom of the figure, result from actions taken by a property listener callback function that you write.

Figure 4-1  Handling audio hardware route changes

A flowchart representation of how Core Audio, and your property listener callback function, interact to provide good user experience upon an audio hardware route change.

In the figure, The system initially determines the audio route after your application launches. It continues to monitor the active route as your application runs. Consider first the case of a user tapping a Record button in your application, represented by the “Recording starts” box on the left side of the figure.

During recording, the user may plug in or unplug a headset—see the diamond-shaped decision element toward the lower-left of the figure. In response, the system invokes your property listener callback function. To follow Apple’s recommendations, your callback would tell your application to stop recording.

The case for playback is similar but has different outcomes, as shown on the right of the figure. If a user unplugs the headset during playback, your callback should pause the audio. If a user plugs in the headset during playback, your callback should simply allow playback to continue.

The AddMusic sample code project demonstrates how to implement the playback portion of this behavior.

Responding to Audio Hardware Route Changes

There are three parts to configuring your application to respond to route changes:

  1. Implement methods to be invoked upon a route change.

  2. Implement a property listener callback function that responds to route changes and uses the methods you implemented in step 1.

  3. Register the callback function with the audio session.

For example, say that you write your callback (following Apple guidelines) to pause playback when a user unplugs their headset. After pausing, the callback could display an alert configured with buttons that let the user stop or resume. To support this user interaction, you’d write a method to display the alert and you’d invoke that method from within the callback. You’d register the callback when initializing the audio session during application launch.

When the system invokes a route-change callback, it provides the information you need to figure out which action to take. Base your callback on the AudioSessionPropertyListener prototype from audio session services, as shown here:

void MyPropertyListener (
   void                    *inClientData,
   AudioSessionPropertyID  inID,
   UInt32                  inDataSize,
   const void              *inData
);

For a route change event, the system sends the kAudioSessionProperty_AudioRouteChange in the inID parameter.

The inData parameter sent to your callback contains a CFDictionaryRef object that describes:

The keys for the dictionary are described in Audio Route Change Dictionary Keys. The various reasons why a hardware audio route might have changed—accessed by the kAudioSession_AudioRouteChangeKey_Reason key—are listed and described in Audio Session Route Change Reasons. The previous route information—accessed by the kAudioSession_AudioRouteChangeKey_OldRoute key—is a string value that names the old route, such as “Headphone” or “Speaker”.

The information supplied to the callback is usually enough to decide which action to take. For instance, if the reason for the route change is kAudioSessionRouteChangeReason_OldDeviceUnavailable and the previous route was Headphone, you know that the user just unplugged the headset. If you also need to know what the new route is, call, within your callback, the AudioSessionGetProperty function for the kAudioSessionProperty_AudioRoute property.

One of the audio hardware route change reasons in iOS is kAudioSessionRouteChangeReason_CategoryChange. In other words, a change in audio session category is considered by the system—in this context—to be a route change, and will invoke a route change property listener callback. As a consequence, such a callback—if it is intended to respond only to headset plugging and unplugging—should explicitly ignore this type of route change. The example code in “Defining a Property Listener Callback Function” demonstrates this.

Here’s a practical example. A well-written recorder/playback application sets the audio session category when beginning playback or recording. Because of this, a route-change property listener callback gets invoked upon starting playback (if you were previously recording) or upon starting recording (if you were previously playing back). Clearly, such an application should not pause or stop each time a user taps Record or Play. To avoid inappropriate pausing or stopping, the callback in this example should branch based on the reason for the route change and simply return if it was a category change.

For a complete example of how to respond to a route change, see “Responding to Audio Hardware Route Changes” in “Audio Session Cookbook.” To see such a callback in action, download the AddMusic sample.




Last updated: 2010-07-09

Did this document help you? Yes It's good, but... Not helpful...