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 has been paused.

It's possible to transition from the SND_PCM_STATUS_PAUSED to the SND_PCM_STATUS_PREPARED when the PCM start mode (snd_pcm_channel_params_t.start_mode) is set to SND_PCM_START_DATA or SND_PCM_START_FULL (using snd_pcm_plugin_params()).

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 must be prepared again.

In some cases, audio is redirected transparently between different audio devices, with different capabilities. You can enable this by calling:

snd_pcm_plugin_set_enable(handle, PLUGIN_ROUTING);
  

If routing is enabled and the preferred device changes to an external device such as HDMI, audio is automatically redirected to that device. Once routing changes, the client receives a status of SND_PCM_STATUS_CHANGE.

When the client receives this, it may just call snd_pcm_channel_prepare() to enter the SND_PCM_STATUS_PREPARED state, and be ready to continue playback, but as the capabilities may have changed, (e.g., HDMI may support surround sound output while a local speaker doesn't), the client may wish to call snd_pcm_channel_info() to check the capabilities, and change the audio characteristics in response before preparing.

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. 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.
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.