iOS Reference Library Apple Developer
Search

Handling Audio Interruptions

Adding audio session code to handle interruptions ensures that your application’s audio continues behaving gracefully when a phone call arrives or a Clock or Calendar alarm sounds.

An audio interruption is the deactivation of your application’s audio session—which immediately stops or pauses your audio, depending on which technology you are using. Interruptions happen when a competing audio session from a built-in application activates and that session is not categorized by the system to mix with yours. After your session goes inactive, the system sends a “you were interrupted” message which you can respond to by saving state, updating the user interface, and so on.

Your application may get shut down following an interruption. This happens when a user decides to accept a phone call. If a user instead elects to ignore a call, or dismisses an alarm, the system issues an interruption-ended message and your application continues running. For your audio to resume, your audio session must be reactivated.

Audio Interruption Handling Techniques

There are two alternative approaches for responding to interruptions:

With either approach, what you do within your interruption code depends a great deal on the audio technology you are using and on what you are using it for—playback, recording, audio format conversion, reading streamed audio packets, and so on. Generally speaking, you need to ensure the minimum possible disruption, and the most graceful possible recovery, from the perspective of the user.

Table 3-1 summarizes the steps that need to happen during an interruption. When using the AVAudioPlayer or AVAudioRecorder objects, some of these steps are handled automatically by the system.

Table 3-1  What needs to happen during an audio session interruption

After interruption starts

  • Check¬†whether¬†resumption¬†of¬†audio¬†process¬†is¬†supported

  • Save¬†state¬†and¬†context

  • Update¬†user¬†interface

After interruption ends

  • Restore¬†state¬†and¬†context

  • Reactivate¬†audio¬†session

  • Update¬†user¬†interface

Table 3-2 briefly summarizes how to handle audio interruptions according to technology. The rest of this chapter provides details.

Table 3-2  Audio interruption handling techniques according to audio technology

Audio technology

How interruptions work

AV Foundation framework

The AVAudioPlayer and AVAudioRecorder classes provide delegate methods for interruption start and end. Implement these methods to update your user interface and optionally, after interruption ends, to resume paused playback. The system automatically pauses playback or recording upon interruption, and reactivates your audio session when you resume playback or recording.

If you want to save and restore playback position between application launches, save playback position on interruption as well as on application quit.

Audio Queue Services, I/O audio unit

These technologies put your application in control of handling interruptions. You are responsible for saving playback or recording position and reactivating your audio session after interruption ends. As explained in “Responding to Audio Session Interruptions,” implement the AVAudioSession interruption delegate methods or write an interruption listener callback function.

If using these technologies for hardware-assisted encoding to AAC, refer to “Hardware-Assisted Codecs and Audio Interruptions.”

OpenAL

When using OpenAL for playback, implement the AVAudioSession interruption delegate methods or write an interruption listener callback function—as when using Audio Queue Services. However, the delegate or callback must additionally manage the OpenAL context. See “OpenAL and Audio Interruptions.”

System Sound Services

Sounds played using System Sound Services go silent when an interruption starts. They can automatically be used again if the interruption ends. Applications cannot influence the interruption behavior for sounds that use this playback technology.

The Interruption Life Cycle

Figure 3-1 illustrates the sequence of events before, during, and after an audio session interruption for a playback application.

Figure 3-1  An audio session gets interrupted

A timeline representation of an application's audio session getting interrupted by a phone call.

An interruption event—in this example, the arrival of a phone call—proceeds as follows. The numbered steps correspond to the numbers in the figure.

  1. Your application is active, playing back audio.

  2. A phone call arrives. The system activates the phone application’s audio session.

  3. The system deactivates your audio session. At this point, playback in your application has stopped.

  4. The system invokes your interruption listener callback function (or calls your interruption-started delegate method), indicating that your session has been deactivated.

  5. Your callback (or delegate method) takes appropriate action. For example, it could update the user interface and save the information needed to resume playback at the point where it stopped.

  6. If the user dismisses the interruption—electing to ignore an incoming phone call in this case—the system invokes your callback or delegate method, indicating that the interruption has ended.

  7. Your callback or delegate method takes action appropriate to the end of an interruption. For example, it updates the user interface, reactivates your audio session, and resumes playback.

  8. (Not shown in the figure.) If, instead of dismissing the interruption at step (6), the user accepted a phone call, your application would have then quit. This is the other possible end of the interruption life cycle.

Handling Interruptions Using Delegate Methods

The AVAudioSession class provides delegate methods, described in AVAudioSessionDelegate Protocol Reference, for responding to interruptions. You can implement and use these methods to respond to interruptions no matter which audio technology you are are using:

What you do within these methods depends on the audio technology you're using and on what you’re using it for. At a minimum, ensure that your internal state and user interface remain consistent and, if you get the endInterruption message, that your audio session is reactivated.

The AVAudioRecorder and AVAudioPlayback classes provide their own delegate methods for responding to audio interruptions, as listed here:

The AVAudioRecorder and AVAudioPlayback classes automatically pause upon interruption. You need not save the recording or playback position unless you want that position to persist across launches of your application. In addition, the system automatically reactivates your audio session should you resume playback or recording after an interruption ends.

For a code example showing how to use an AV Foundation interruption delegate method, see “Handling Interruptions with the AVAudioPlayer Class.”

Handling Interruptions Using a Callback Function

If you prefer to use a C-language interruption listener callback function rather than Objective-C delegate methods, base your callback on the AudioSessionInterruptionListener callback prototype from Audio Session Services.

When the system invokes your callback, it sends two values: a reference to the data that you (optionally) specified when you initialized the session and a constant that indicates the interruption state. Listing 3-1 shows the declaration of the AudioSessionInterruptionListener callback.

Listing 3-1  The interruption callback declaration

typedef void (*AudioSessionInterruptionListener) (
                 void    *inClientData,
                 UInt32  inInterruptionState
             );

There are two interruption states:

When using a callback, there are three parts to adding interruption support to your application:

  1. Define methods that take appropriate action upon interruption-begin and interruption-end. Some of these actions—such as to stop recording—are ones you define anyway for your application. Others—such as to pause playback—may be ones that you invoke only from the callback. See “Defining Interruption Methods.”

  2. Define a callback function, to be invoked upon interruption begin and end, that calls these methods as appropriate. See “Defining an Interruption Listener Callback Function.”

  3. Register the callback function with your audio session. You do this as part of initializing the session. See “Initializing an Audio Session.”

OpenAL and Audio Interruptions

When using OpenAL for audio playback, implement AVAudioSession delegate methods or write an interruption listener callback function, as you do when using Audio Queue Services. However, your interruption code must additionally manage the OpenAL context. Upon interruption, set the OpenAL context to NULL. After interruption ends, set the context to its prior state.

Prior to iOS version 3.0, handling OpenAL interruptions was more involved. You had to save and then destroy the OpenAL context after getting an interruption, and then rebuild the context on interruption end. To make your code compatible with older versions of iOS, you can conditionalize it by testing the OS version at runtime.

For code examples showing how to manage the OpenAL context during an audio interruption, see “Responding to Interruptions When Using OpenAL.”

Hardware-Assisted Codecs and Audio Interruptions

Previous sections in this chapter explained how to handle interruptions to the two most common audio operations: playing back and recording. Another operation that requires interruption handling is offline audio format conversion. You have a bit more work to do in this case. Specifically, you must handle interruptions at the audio data buffer level.

By way of background, you can use a hardware assisted-codec—on certain devices—to encode linear PCM audio to AAC format. The codec is available on the iPhone 3GS and on the iPod touch (2nd generation), but not on older models. You use the codec as part of an audio converter object (of type AudioConverterRef), which in turn is part of an extended audio file object (of type ExtAudioFileRef). For information on these opaque types, refer to Audio Converter Services Reference and Extended Audio File Services Reference.

To handle an interruption during hardware-assisted encoding, take two things into account:

  1. The codec may or may not be able to resume encoding after the interruption ends.

  2. The last buffer that you sent to the codec, before the interruption, may or may not have been successfully written to disk.

Encoding takes place as you repeatedly call the ExtAudioFileWrite function with new buffers of audio data. To handle an interruption, respond according to the function’s result code, as described here:

To check if the AAC codec can resume, obtain the value of the associated converter’s kAudioConverterPropertyCanResumeFromInterruption property. The value is 1 (can resume) or 0 (cannot resume). You can obtain this value any time after instantiating the converter—immediately after instantiation, upon interruption, or after interruption ends.

If the converter cannot resume, then on interruption you must abandon the conversion. After the interruption ends, or after the user relaunches your application and indicates they want to resume conversion, re-instantiate the extended audio file object and perform the conversion again.




Last updated: 2010-07-09

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