PCM state machine

A PCM device is, at its simplest, a data buffer that's converted, one sample at a time, by either a Digital Analog Converter (DAC) or an Analog Digital Converter (ADC), depending on direction.

This simple idea becomes a little more complicated in QSA because of the concept that the PCM subchannel is in a state at any given moment. These states are defined as follows:

SND_PCM_STATUS_NOTREADY
The initial state of the device.
SND_PCM_STATUS_READY
The device has its parameters set for the data it will operate on.
SND_PCM_STATUS_PREPARED
The device has been prepared for operation and is able to run.
SND_PCM_STATUS_RUNNING
The device is running, transferring data to or from the buffer.
SND_PCM_STATUS_UNDERRUN
This state happens only to a playback device and is entered when the buffer has no more data to be played.
SND_PCM_STATUS_OVERRUN
This state happens only to a capture device and is entered when the buffer has no room for data.
SND_PCM_STATUS_PAUSED
The device is paused and is no longer playing the audio stream. To resume playing, you must explicitly call the appropriate snd_pcm_*_resume() function.

This state occurs when a user explicitly calls a snd_pcm_*_pause() function. It can also occur because the audio concurrency management policy in place has moved a subchannel that was previously in the SND_PCM_STATUS_SUSPEND to the SND_PCM_STATUS_PAUSED state.

SND_PCM_STATUS_SUSPENDED
Audio concurrency management has suspended the play of the audio stream based on the current audio concurrency management policies that are configured on the system.
SND_PCM_STATUS_SUSPENDED is a transient or temporary state that's controlled by the audio concurrency management policies running on the system. This transient state has two modes called soft suspended and hard suspended. For more information about these modes and how they work, see the Understanding preemption section in the Audio Concurrency Management chapter of this guide.
SND_PCM_STATUS_UNSECURE
The application marked the stream as protected, the hardware level supports a secure transport (e.g., HDCP for HDMI), and authentication was lost.
SND_PCM_STATUS_ERROR
A hardware error has occurred, and the stream must be prepared again.
SND_PCM_STATUS_CHANGE
The stream has changed and the audio stream must be reconfigured.

When the subchannel is put into the SND_PCM_STATUS_CHANGE state, the client must reconfigure the audio stream as the hardware capabilities have changed. For example, for an HDMI connection, the audio mode of the HDMI source (display, amplifier, etc.) may have changed from stereo to 5.1 surround sound, therefore, your subchannel must be reconfigured to enable the voice conversion plugin.

To reconfigure an audio stream, you must call snd_pcm_plugin_params() or snd_pcm_channel_params() and then the corresponding snd_pcm_plugin_setup() or snd_pcm_channel_setup() functions. If you want to check what new hardware capabilities are available, you can call snd_pcm_channel_info(), which gets information directly from the hardware.

After you reconfigure the audio stream, then you can call snd_pcm_plugin_prepare() or snd_pcm_channel_prepare() to move to the SND_PCM_STATUS_PREPARED state and to continue writing audio data to the subchannel.

Note: The call to the snd_pcm_plugin_params() or snd_pcm_channel_params() functions may cause the fragment size to change. For that reason, ensure that after you make a snd_pcm_*_params() call, that you call the snd_pcm_*_setup() and snd_pcm_*_prepare() functions before you write your audio data.
SND_PCM_STATUS_PREEMPTED
Audio is blocked because another libasound session has initiated playback, and the audio driver has determined that that session has higher priority, and therefore the lower priority session is terminated with state SND_PCM_STATUS_PREEMPTED. This state occurs only if there aren't enough resources available on the system. When it receives this state, the client should give up on playback, and not attempt to resume until either the sound it wishes to produce has increased in priority, or a user initiates a retry.
Note: Don't confuse the SND_PCM_STATUS_PREEMPTED state with the SND_PCM_STATUS_SUSPENDED state. When a subchannel gets preempted because audio concurrency management has occurred, it moves to SND_PCM_STATUS_SUSPENDED state.
Figure 1. General state diagram for PCM devices.

In the figure above, the oval groups the Underrun/Overrun, Error, and Unsecure states together to indicate that each state can transition to the Prepared state.

The transition between states is the result of executing an API call, or the result of conditions that occur in the hardware. For more details, see the Playing and Capturing Audio Data chapter.