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 occurs only when the audio stream has been ducked to zero (volume level is 0). Preemption only occurs if the audio type of an audio stream is ducked to zero. 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 (SND_PCM_STATUS_SUSPENDED) 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.

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.

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.