Understanding preemption

Preemption is an optional audio policy that can be applied to an audio type.

Preemption and audio ducking polices work together. Preemption of an audio stream means that the system has suspended the play of an audio stream (i.e., the audio stream stops playing). Preemption only occurs if the audio type of an audio stream is ducked to zero (volume level is 0) and the stream is active (in the RUNNING, SUSPENDED, or PAUSED state). This can occur cumulatively when multiple, higher and same priority audio types are configured.
Note: If preemption isn't configured and it's ducked to zero, then the audio stream stays in the RUNNING state (SND_PCM_STATUS_RUNNINNG) while it's muted.
For example, you may decide to stop playing music if a voice call comes in. You can configure whether preemption occurs when an audio stream of the same or higher priority causes preemption using the preemption_by_same and preemption_by_higher keys for an audio type in the audio policy configuration file. If these keys are aren't specified for an audio type, preemption policies aren't applied.

Preemption puts the audio stream into the SUSPENDED (SND_PCM_STATUS_SUSPENDED) state. Movement to this status is controlled by the audio management policies in place on the system when an audio stream's volume level is ducked to zero. Depending on whether your audio stream is soft suspended or hard suspended determines whether you can use an API call to move out of the SUSPENDED state. For more information, see the Soft suspended and hard suspended section in this chapter.

Tip: If you have Audio component BuildID 237—June 29, 2017 (7.0.237.S201706290957) or a later update installed, the following applies:

Previously, audio management preemption didn't occur when you enabled audio ducking on a subchannel that wasn't in an active, streaming state (e.g., calling snd_pcm_channel_audio_ducking()). Active subchannels are those channels in the RUNNING, SUSPENDED, or PAUSED state.

This update permits audio preemption to occur on a non-active channel and allows a subchannel to receive SND_PCM_EVENT_* events when you enable ducking behavior on a non-active subchannel. This allows, for example, a subchannel to transition from the PREPARED to the SUSPENDED state. Note, audio preemption doesn't occur unless you call snd_pcm_*_prepare(). You can call snd_pcm_channel_audio_ducking() before or after the subchannel transitions to the PREPARED state.

The following is a summary of the state transitions that can occur with this update when audio management policies are in place:

  • If a subchannel is in the READY state, audio ducking policies are applied, but audio management preemption policies are not, and therefore the subchannel stays in the READY state.
  • If the subchannel is in a PREPARED state and audio preemption occurs, the subchannel changes to the SUSPENDED state.
    • If the client application attempts to start the subchannel while it's in the SUSPENDED state, what occurs depends on whether it's soft- or hard-suspended:
      • If the subchannel is soft-suspended and the client application calls snd_pcm_*_go() or snd_pcm_*_write() (depending on your start mode), it transitions to the RUNNING state.
      • If the subchannel is hard-suspended, it remains in the SUSPENDED state, but if the audio type is configured to pause, it moves to the PAUSED state when the SUSPENDED state is cleared. Note that you can transition to the PAUSED state only if you have called snd_pcm_*_go() or snd_pcm_*_write() while the subchannel was SUSPENDED.
      • If the preemption state is cleared and the client application didn't previously called snd_pcm_*_go() or snd_pcm_*_write(), the subchannel transitions back to the PREPARED state.
      • If the subchannel isn't streaming and snd_pcm_*_resume() is called while the subchannel is soft-suspended, the subchannel transitions back to the PREPARED state.

Configuring preemption behavior

You can't explicitly move to or out of the SUSPENDED (SND_PCM_STATUS_SUSPENDED) state, but you can define the behavior when audio management transitions your audio stream out of the SUSPENDED (SND_PCM_STATUS_SUSPENDED) state in the audio policy configuration file.
Tip: If you have Audio component BuildID 237—June 29, 2017 (7.0.237.S201706290957) or a later update installed, the following applies:

Previously, there was no way to determine whether a subchannel was soft- or hard-suspended. With this release, you can use the snd_pcm_channel_status_t to determine the status using the ducking_state member.

These are the two configuration options you can use to define the behavior:

suspend
This setting means that when the audio stream gets ducked to zero, the audio stream no longer plays. When the audio stream is no longer ducked to zero (i.e., the volume level is greater than zero), the audio stream continues playing where it left off.
pause
This setting means that when the preempted audio is no longer ducked to zero (i.e., a volume level of zero) that audio management moves the suspended audio stream from the SUSPENDED (SND_PCM_STATUS_SUSPENDED) state to the PAUSED (SND_PCM_STATUS_PAUSED) state. It's important to note that when preemption occurs, audio streams always transition to the SUSPENDED (SND_PCM_STATUS_SUSPENDED) state.
Once in the PAUSED (SND_PCM_STATUS_PAUSED) state, the application is responsible to call the appropriate snd_pcm_*_resume() function to resume the play of the audio stream. To be informed of this using the PCM events. For more information about audio events, see the PCM events section in the Playing and Capturing Audio Data chapter of this guide.

Soft suspended and hard suspended

It's important to understand that an audio stream can be preempted by an audio stream with the same or higher priority — depending on the audio management policies that are configured. When an audio stream is preempted, it moves into the SUSPENDED state (SND_PCM_STATUS_SUSPENDED), which has two modes that are referred to as soft suspended and hard suspended modes.

These modes differ primarily in respects to what happens when you call snd_pcm_*_resume() and based on whether your audio stream was preempted by a higher or same priority audio type. When your audio type is preempted by an audio type of the same priority, your audio stream is moved to the SUSPENDED (soft suspended) state. If snd_pcm_*_resume() is called, that suspended audio stream immediately moves from the SUSPENDED state to the RUNNING state. If there are multiple audio streams, any stream that is SUSPENDED that calls snd_pcm_*_resume() preempts other streams of the same priority. It's important to mention that if your audio stream was in the PAUSED state because of an API call, the audio stream is still preempted.

When your audio type is preempted by a higher priority audio type, calling snd_pcm_*_resume() doesn't transition your preempted audio stream from the SUSPENDED state to the RUNNING or PAUSED state. A call to the snd_pcm_*_pause() also doesn't change the state either.

This concept is best represented in the following table. The audio management framework allows you to move from any row to any other row in the table and from the “NOT PAUSED” to “PAUSED” column; however, state transitions from the “PAUSED” to “NOT PAUSED” column aren't permitted.
  not PAUSED state PAUSED state
Not suspended (1)

status: SND_PCM_STATUS_RUNNING

snd_pcm_*_resume does nothing

snd_pcm_*_pause moves you to (2)

(2)

status: SND_PCM_STATUS_PAUSED

snd_pcm_*_resume moves you to (1)

snd_pcm_*_pause does nothing

Soft Suspended (preemption by same priority audio type) (3)

status: SND_PCM_STATUS_SUSPENDED

snd_pcm_*_resume moves you to (1)

snd_pcm_*_pause moves you to (4)

(4)

status: SND_PCM_STATUS_SUSPENDED

snd_pcm_*_resume moves you to (1)

snd_pcm_*_pause does nothing

Note: In actuality, the PAUSED state is pending. You stay in the SUSPENDED state, but once audio management clears the SUSPENDED state, you move to the PAUSED state.
Hard Suspended ((preemption by higher priority audio type) (5)

status: SND_PCM_STATUS_SUSPENDED

snd_pcm_*_resume does nothing

snd_pcm_*_pause moves you to (6)

(6)

status: SND_PCM_STATUS_SUSPENDED

snd_pcm_*_resume moves you to (5)

snd_pcm_*_pause does nothing

Note: The PAUSED state is pending. You stay in the SUSPENDED state, but once audio management clears the SUSPENDED state, you move to the PAUSED state.