diff options
Diffstat (limited to 'virtio-sound.tex')
-rw-r--r-- | virtio-sound.tex | 734 |
1 files changed, 734 insertions, 0 deletions
diff --git a/virtio-sound.tex b/virtio-sound.tex new file mode 100644 index 0000000..ca07bb9 --- /dev/null +++ b/virtio-sound.tex @@ -0,0 +1,734 @@ +\section{Sound Device}\label{sec:Device Types / Sound Device} + +The virtio sound card is a virtual audio device supporting input, output and +bidirectional PCM streams. + +A device is managed by control requests and can send various notifications +through dedicated queues. A driver can transmit PCM frames using message-based +transport or shared memory. + +\subsection{Device ID}\label{sec:Device Types / Sound Device / Device ID} + +25 + +\subsection{Virtqueues}\label{sec:Device Types / Sound Device / Virtqueues} + +\begin{description} +\item[0] controlq +\item[1] eventq +\item[2] txq +\item[3] rxq +\end{description} + +The control queue is used for sending control messages from the driver to +the device. + +The event queue is used for sending notifications from the device to the driver. + +The tx queue is used for sending PCM I/O messages for an output stream. + +The rx queue is used for sending PCM I/O messages for an input stream. + +\subsection{Feature bits}\label{sec:Device Types / Sound Device / Feature bits} + +None currently defined. + +\subsection{Device configuration layout}\label{sec:Device Types / Sound Device / Device configuration layout} + +\begin{lstlisting} +struct virtio_snd_config { + le32 jacks; + le32 streams; +}; +\end{lstlisting} + +A configuration space contains the following fields: + +\begin{description} +\item[\field{jacks}] (driver-read-only) is a total number of all available jacks. +\item[\field{streams}] (driver-read-only) is a total number of all available PCM +streams. +\end{description} + +\subsection{Device Initialization} + +\begin{enumerate} +\item Configure the control, event, tx and rx queues. +\item Read the \field{jacks} field and send control requests to query configuration +for each available jack. +\item Read the \field{streams} field and send control requests to query configuration +for each available PCM stream. +\item Populate the event queue with empty buffers. +\end{enumerate} + +\devicenormative{\subsubsection}{Device Initialization}{Device Types / Sound Device / Device Initialization} + +\begin{itemize} +\item The device MUST set a non-zero value for the \field{jacks} configuration +field. +\item The device MUST set a non-zero value for the \field{streams} configuration +field. +\end{itemize} + +\drivernormative{\subsubsection}{Device Initialization}{Device Types / Sound Device / Device Initialization} + +\begin{itemize} +\item The driver MUST populate the event queue with empty buffers of at least +the struct virtio_snd_event size. +\item The driver MUST NOT put a device-readable buffers in the event queue. +\end{itemize} + +\subsection{Device Operation}\label{sec:Device Types / Sound Device / Device Operation} + +All control messages are placed into the control queue and all notifications +are placed into the event queue. They use the following layout structure and +definitions: + +\begin{lstlisting} +enum { + /* jack control request types */ + VIRTIO_SND_R_JACK_GET_CONFIG = 1, + VIRTIO_SND_R_JACK_REMAP, + + /* PCM control request types */ + VIRTIO_SND_R_PCM_GET_CONFIG = 0x0100, + VIRTIO_SND_R_PCM_SET_PARAMS, + VIRTIO_SND_R_PCM_PREPARE, + VIRTIO_SND_R_PCM_RELEASE, + VIRTIO_SND_R_PCM_START, + VIRTIO_SND_R_PCM_STOP, + VIRTIO_SND_R_PCM_PAUSE, + VIRTIO_SND_R_PCM_UNPAUSE, + + /* jack event types */ + VIRTIO_SND_EVT_JACK_CONNECTED = 0x1000, + VIRTIO_SND_EVT_JACK_DISCONNECTED, + + /* PCM event types */ + VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED = 0x1100, + VIRTIO_SND_EVT_PCM_XRUN, + + /* common status codes */ + VIRTIO_SND_S_OK = 0x8000, + VIRTIO_SND_S_BAD_MSG, + VIRTIO_SND_S_NOT_SUPP, + VIRTIO_SND_S_IO_ERR +}; + +/* a common header */ +struct virtio_snd_hdr { + le32 code; +}; + +/* an event notification */ +struct virtio_snd_event { + le32 type; + le32 data; +}; +\end{lstlisting} + +A generic control message consists of a request part and a response part. + +A request part has, or consists of, a common header containing the following +field: + +\begin{description} +\item[\field{code}] (device-readable) specifies a device request type +(VIRTIO_SND_R_*). +\end{description} + +A response part has, or consists of, a common header containing the following +field: + +\begin{description} +\item[\field{code}] (device-writable) specifies a device request status +(VIRTIO_SND_S_*). +\end{description} + +The status field can take one of the following values: + +\begin{itemize} +\item VIRTIO_SND_S_OK - success. +\item VIRTIO_SND_S_BAD_MSG - a control message is malformed or contains invalid +parameters. +\item VIRTIO_SND_S_NOT_SUPP - requested operation or parameters are not supported. +\item VIRTIO_SND_S_IO_ERR - an I/O error occurred. +\end{itemize} + +The request part may be followed by an additional device-readable payload, +and the response part may be followed by an additional device-writable payload. + +An event notification contains the following fields: + +\begin{description} +\item[\field{type}] (device-writable) specifies an event type (VIRTIO_SND_EVT_*). +\item[\field{data}] (device-writable) specifies an optional event data. +\end{description} + +\subsubsection{Jack Control Messages}\label{sec:Device Types / Sound Device / Device Operation / Jack Control Messages} + +A jack control request has, or consists of, a common header with the following +layout structure: + +\begin{lstlisting} +struct virtio_snd_jack_hdr { + struct virtio_snd_hdr hdr; + le32 jack_id; +}; +\end{lstlisting} + +The header consists of the following field: + +\begin{description} +\item[\field{hdr}] (device-readable) contains request type (VIRTIO_SND_R_JACK_*). +\item[\field{jack_id}] (device-readable) specifies a jack identifier from 0 to +\field{jacks} - 1. +\end{description} + +\paragraph{VIRTIO_SND_R_JACK_GET_CONFIG} + +Query a jack configuration for the specified jack ID. + +The request has no additional payload, and the response uses the following +structure and layout definitions: + +\begin{lstlisting} +/* supported jack features */ +enum { + VIRTIO_SND_JACK_F_REMAP = 0 +}; + +/* a response containing jack configuration */ +struct virtio_snd_jack_config { + struct virtio_snd_hdr hdr; /* VIRTIO_SND_S_XXX */ + le32 association; + le32 sequence; + le32 features; /* 1 << VIRTIO_SND_JACK_F_XXX */ + u8 connected; + u8 color; + u8 connection_type; + u8 device; + u8 location; + u8 port_connectivity; + + u8 padding[2]; +}; +\end{lstlisting} + +The response contains the following fields: + +\begin{description} +\item[\field{association}] (device-writable) indicates the current jack association. +All jacks with the same association number are intended to be grouped together to +provide multichannel support. +\item[\field{sequence}] (device-writable) indicates the order of the jacks in the +association. The lowest numbered jack in the association should be assigned the +lowest numbered channels in the stream, etc. +\item[\field{features}] (device-writable) is a supported feature bit map: +\begin{itemize} +\item VIRTIO_SND_JACK_F_REMAP - jack remapping support. +\end{itemize} +\item[\field{connected}] (device-writable) is the current jack connection status +(1 - connected, 0 - disconnected). +\item[\field{color}] (device-writable) indicates the color of the physical jack +(values are documented in \hyperref[intro:HDA]{HDA}). +\item[\field{connection_type}] (device-writable) indicates the type of physical +connection (values are documented in \hyperref[intro:HDA]{HDA}). +\item[\field{device}] (device-writable) indicates the intended use of the jack or +device (values are documented in \hyperref[intro:HDA]{HDA}). +\item[\field{location}] (device-writable) indicates the physical location of the +jack or device (values are documented in \hyperref[intro:HDA]{HDA}). +\item[\field{port_connectivity}] (device-writable) indicates the external connectivity +(values are documented in \hyperref[intro:HDA]{HDA}). +\end{description} + +\devicenormative{\subparagraph}{Jack Configuration}{Device Types / Sound Device / Device Operation / Jack Configuration} + +\begin{itemize} +\item The device MUST NOT set undefined jack feature bits. +\item The device MUST initialize \field{padding} bytes to 0. +\end{itemize} + +\paragraph{VIRTIO_SND_R_JACK_REMAP} + +If the VIRTIO_SND_JACK_F_REMAP feature bit is set in the jack configuration, +then the driver can send a control request to change the association and/or +sequence number for the specified jack ID. + +The request uses the following structure and layout definitions: + +\begin{lstlisting} +struct virtio_snd_jack_remap { + struct virtio_snd_jack_hdr hdr; /* .code = VIRTIO_SND_R_JACK_REMAP */ + le32 association; + le32 sequence; +}; +\end{lstlisting} + +The request contains the following fields: + +\begin{description} +\item[\field{association}] (device-readable) specifies the selected association +number. +\item[\field{sequence}] (device-readable) specifies the selected sequence +number. +\end{description} + +\subsubsection{Jack Notifications} + +Jack notifications consist of a virtio_snd_event structure, which has the following +fields: + +\begin{description} +\item[\field{type}] (device-writable) indicates a jack event type: +\begin{itemize} +\item VIRTIO_SND_EVT_JACK_CONNECTED - an external device has been connected to the jack. +\item VIRTIO_SND_EVT_JACK_DISCONNECTED - an external device has been disconnected from the jack. +\end{itemize} +\item[\field{data}] (device-writable) indicates a jack identifier from 0 to +\field{jacks} - 1. +\end{description} + +\subsubsection{PCM Control Messages}\label{sec:Device Types / Sound Device / Device Operation / PCM Control Messages} + +A PCM control request has, or consists of, a common header with the following +layout structure: + +\begin{lstlisting} +struct virtio_snd_pcm_hdr { + struct virtio_snd_hdr hdr; + le32 stream_id; +}; +\end{lstlisting} + +The header consists of the following field: + +\begin{description} +\item[\field{hdr}] (device-readable) contains request type (VIRTIO_SND_R_PCM_*). +\item[\field{stream_id}] (device-readable) specifies a PCM stream identifier +from 0 to \field{streams} - 1. +\end{description} + +\paragraph{PCM Command Lifecycle} + +A PCM stream has the following command lifecycle: + +\begin{enumerate} +\item SET PARAMETERS + +The driver negotiates the stream parameters (format, transport, etc) with +the device. + +Possible valid transitions: set parameters, prepare. + +\item PREPARE + +The device prepares the stream (allocates resources, etc). + +Possible valid transitions: start, release. + +\item Output only: the driver transfers data for pre-buffing. +\item START + +The device starts the stream (unmute, putting into running state, etc). + +Possible valid transitions: pause, stop. + +\item The driver transfers data to/from the stream. +\begin{enumerate} +\item PAUSE + +The device pauses the stream. + +Possible valid transitions: unpause, stop. + +\item UNPAUSE + +The device releases the stream from pause. + +Possible valid transitions: pause, stop. + +\end{enumerate} +\item STOP + +The device stops the stream (mute, putting into non-running state, etc). + +Possible valid transitions: start, release. + +\item RELEASE + +The device releases the stream (frees resources, etc). + +Possible valid transitions: set parameters, prepare. + +\end{enumerate} + +\paragraph{VIRTIO_SND_R_PCM_GET_CONFIG} + +Query stream configuration for the specified stream ID. + +The request has no additional payload, and the response uses the following +structure and layout definitions: + +\begin{lstlisting} +/* supported PCM stream directions */ +enum { + VIRTIO_SND_PCM_T_OUTPUT = 0, + VIRTIO_SND_PCM_T_INPUT +}; + +/* supported PCM stream features */ +enum { + VIRTIO_SND_PCM_F_SHMEM_HOST = 0, + VIRTIO_SND_PCM_F_SHMEM_GUEST, + VIRTIO_SND_PCM_F_CHMAP, + VIRTIO_SND_PCM_F_EVT_SHMEM_PERIODS, + VIRTIO_SND_PCM_F_EVT_XRUNS +}; + +/* supported PCM sample formats */ +enum { + /* analog formats (width / physical width) */ + VIRTIO_SND_PCM_FMT_IMA_ADPCM = 0, /* 4 / 4 bits */ + VIRTIO_SND_PCM_FMT_MU_LAW, /* 8 / 8 bits */ + VIRTIO_SND_PCM_FMT_A_LAW, /* 8 / 8 bits */ + VIRTIO_SND_PCM_FMT_S8, /* 8 / 8 bits */ + VIRTIO_SND_PCM_FMT_U8, /* 8 / 8 bits */ + VIRTIO_SND_PCM_FMT_S16, /* 16 / 16 bits */ + VIRTIO_SND_PCM_FMT_U16, /* 16 / 16 bits */ + VIRTIO_SND_PCM_FMT_S18_3, /* 18 / 24 bits */ + VIRTIO_SND_PCM_FMT_U18_3, /* 18 / 24 bits */ + VIRTIO_SND_PCM_FMT_S20_3, /* 20 / 24 bits */ + VIRTIO_SND_PCM_FMT_U20_3, /* 20 / 24 bits */ + VIRTIO_SND_PCM_FMT_S24_3, /* 24 / 24 bits */ + VIRTIO_SND_PCM_FMT_U24_3, /* 24 / 24 bits */ + VIRTIO_SND_PCM_FMT_S20, /* 20 / 32 bits */ + VIRTIO_SND_PCM_FMT_U20, /* 20 / 32 bits */ + VIRTIO_SND_PCM_FMT_S24, /* 24 / 32 bits */ + VIRTIO_SND_PCM_FMT_U24, /* 24 / 32 bits */ + VIRTIO_SND_PCM_FMT_S32, /* 32 / 32 bits */ + VIRTIO_SND_PCM_FMT_U32, /* 32 / 32 bits */ + VIRTIO_SND_PCM_FMT_FLOAT, /* 32 / 32 bits */ + VIRTIO_SND_PCM_FMT_FLOAT64, /* 64 / 64 bits */ + /* digital formats (width / physical width) */ + VIRTIO_SND_PCM_FMT_DSD_U8, /* 8 / 8 bits */ + VIRTIO_SND_PCM_FMT_DSD_U16, /* 16 / 16 bits */ + VIRTIO_SND_PCM_FMT_DSD_U32, /* 32 / 32 bits */ + VIRTIO_SND_PCM_FMT_IEC958_SUBFRAME /* 32 / 32 bits */ +}; + +/* supported PCM frame rates */ +enum { + VIRTIO_SND_PCM_RATE_5512 = 0, + VIRTIO_SND_PCM_RATE_8000, + VIRTIO_SND_PCM_RATE_11025, + VIRTIO_SND_PCM_RATE_16000, + VIRTIO_SND_PCM_RATE_22050, + VIRTIO_SND_PCM_RATE_32000, + VIRTIO_SND_PCM_RATE_44100, + VIRTIO_SND_PCM_RATE_48000, + VIRTIO_SND_PCM_RATE_64000, + VIRTIO_SND_PCM_RATE_88200, + VIRTIO_SND_PCM_RATE_96000, + VIRTIO_SND_PCM_RATE_176400, + VIRTIO_SND_PCM_RATE_192000, + VIRTIO_SND_PCM_RATE_384000 +}; + +/* standard channel position definition */ +enum { + VIRTIO_SND_PCM_CH_NONE = 0, /* undefined */ + VIRTIO_SND_PCM_CH_NA, /* silent */ + VIRTIO_SND_PCM_CH_MONO, /* mono stream */ + VIRTIO_SND_PCM_CH_FL, /* front left */ + VIRTIO_SND_PCM_CH_FR, /* front right */ + VIRTIO_SND_PCM_CH_RL, /* rear left */ + VIRTIO_SND_PCM_CH_RR, /* rear right */ + VIRTIO_SND_PCM_CH_FC, /* front center */ + VIRTIO_SND_PCM_CH_LFE, /* low frequency (LFE) */ + VIRTIO_SND_PCM_CH_SL, /* side left */ + VIRTIO_SND_PCM_CH_SR, /* side right */ + VIRTIO_SND_PCM_CH_RC, /* rear center */ + VIRTIO_SND_PCM_CH_FLC, /* front left center */ + VIRTIO_SND_PCM_CH_FRC, /* front right center */ + VIRTIO_SND_PCM_CH_RLC, /* rear left center */ + VIRTIO_SND_PCM_CH_RRC, /* rear right center */ + VIRTIO_SND_PCM_CH_FLW, /* front left wide */ + VIRTIO_SND_PCM_CH_FRW, /* front right wide */ + VIRTIO_SND_PCM_CH_FLH, /* front left high */ + VIRTIO_SND_PCM_CH_FCH, /* front center high */ + VIRTIO_SND_PCM_CH_FRH, /* front right high */ + VIRTIO_SND_PCM_CH_TC, /* top center */ + VIRTIO_SND_PCM_CH_TFL, /* top front left */ + VIRTIO_SND_PCM_CH_TFR, /* top front right */ + VIRTIO_SND_PCM_CH_TFC, /* top front center */ + VIRTIO_SND_PCM_CH_TRL, /* top rear left */ + VIRTIO_SND_PCM_CH_TRR, /* top rear right */ + VIRTIO_SND_PCM_CH_TRC, /* top rear center */ + VIRTIO_SND_PCM_CH_TFLC, /* top front left center */ + VIRTIO_SND_PCM_CH_TFRC, /* top front right center */ + VIRTIO_SND_PCM_CH_TSL, /* top side left */ + VIRTIO_SND_PCM_CH_TSR, /* top side right */ + VIRTIO_SND_PCM_CH_LLFE, /* left LFE */ + VIRTIO_SND_PCM_CH_RLFE, /* right LFE */ + VIRTIO_SND_PCM_CH_BC, /* bottom center */ + VIRTIO_SND_PCM_CH_BLC, /* bottom left center */ + VIRTIO_SND_PCM_CH_BRC /* bottom right center */ +}; + +/* a maximum possible number of channels */ +#define VIRTIO_SND_PCM_CH_MAX 16 + +/* a response containing PCM stream capabilities */ +struct virtio_snd_pcm_caps { + struct virtio_snd_hdr hdr; /* VIRTIO_SND_S_XXX */ + u8 directions; /* 1 << VIRTIO_SND_PCM_T_XXX */ + u8 channels_min; + u8 channels_max; + u8 features; /* 1 << VIRTIO_SND_PCM_F_XXX */ + le64 formats; /* 1 << VIRTIO_SND_PCM_FMT_XXX */ + le32 rates; /* 1 << VIRTIO_SND_PCM_RATE_XXX */ + le32 association; + u8 chmap[VIRTIO_SND_PCM_CH_MAX]; +}; +\end{lstlisting} + +The response contains the following fields: + +\begin{description} +\item[\field{directions}] (device-writable) is a supported direction bit map. +\item[\field{channels_min}] (device-writable) is a minimum number of supported +channels. +\item[\field{channels_max}] (device-writable) is a maximum number of supported +channels. +\item[\field{features}] (device-writable) is a supported feature bit map: +\begin{itemize} +\item VIRTIO_SND_PCM_F_SHMEM_HOST - supports sharing a host memory with a guest, +\item VIRTIO_SND_PCM_F_SHMEM_GUEST - supports sharing a guest memory with a host, +\item VIRTIO_SND_PCM_F_CHMAP - supports a channel map, +\item VIRTIO_SND_PCM_F_EVT_SHMEM_PERIODS - supports elapsed period notifications +for shared memory transport, +\item VIRTIO_SND_PCM_F_EVT_XRUNS - supports underrun/overrun notifications. +\end{itemize} +\item[\field{formats}] (device-writable) is a supported sample format bit map. +\item[\field{rates}] (device-writable) is a supported frame rate bit map. +\item[\field{association}] (device-writable) indicates a stream association. +All streams with the same association number are intended to be grouped together to +share all jacks with the same association number as their physical input/output. +The association can also be used by software to prioritize resource allocation in +constrained situations. Lower association values would be higher in priority for +resources. Unlike jacks, stream associations cannot be changed. +\item[\field{chmap}] (device-writable) if the VIRTIO_SND_PCM_F_CHMAP feature bit +is set, then the first \field{channels_max} elements are valid and contain +channel positions (VIRTIO_SND_PCM_CH_*). +\end{description} + +Only interleaved samples are supported. + +\devicenormative{\subparagraph}{Stream Configuration}{Device Types / Sound Device / Device Operation / PCM Stream Configuration} + +\begin{itemize} +\item The device MUST NOT set undefined direction, feature, format and rate bits. +\item If the VIRTIO_SND_PCM_F_CHMAP feature bit is not set, then the device +MUST initialize the \field{chmap} field with the VIRTIO_SND_PCM_CH_NONE position +values. +\end{itemize} + +\paragraph{VIRTIO_SND_R_PCM_SET_PARAMS}\label{sec:Device Types / Sound Device / Device Operation / PCM Stream Parameters} + +Set selected stream parameters for the specified stream ID. + +The request uses the following structure and layout definitions: + +\begin{lstlisting} +struct virtio_snd_pcm_set_params { + struct virtio_snd_pcm_hdr hdr; /* .code = VIRTIO_SND_R_PCM_SET_PARAMS */ + le32 buffer_bytes; + le32 period_bytes; + u8 direction; + u8 features; + u8 channels; + u8 format; + u8 rate; + + u8 padding[3]; +}; +\end{lstlisting} + +The request contains the following fields: + +\begin{description} +\item[\field{buffer_bytes}] (device-readable) specifies the size of the hardware +buffer used by the driver. +\item[\field{period_bytes}] (device-readable) specifies the size of the hardware +period used by the driver. +\item[\field{direction}] (device-readable) specifies a selected stream direction +(VIRTIO_SND_PCM_T_*). +\item[\field{features}] (device-readable) specifies a selected feature bit map: +\begin{itemize} +\item VIRTIO_SND_PCM_F_SHMEM_HOST: use shared memory allocated by the host +(is a placeholder and MUST NOT be selected at the moment), +\item VIRTIO_SND_PCM_F_SHMEM_GUEST: use shared memory allocated by the guest +(is a placeholder and MUST NOT be selected at the moment), +\item VIRTIO_SND_PCM_F_EVT_SHMEM_PERIODS: enable elapsed period notifications +for shared memory transport, +\item VIRTIO_SND_PCM_F_EVT_XRUNS: enable underrun/overrun notifications. +\end{itemize} +\item[\field{channels}] (device-readable) specifies a selected number of channels. +\item[\field{format}] (device-readable) specifies a selected sample format +(VIRTIO_SND_PCM_FMT_*). +\item[\field{rate}] (device-readable) specifies a selected frame rate +(VIRTIO_SND_PCM_RATE_*). + +\end{description} + +\devicenormative{\subparagraph}{Stream Parameters}{Device Types / Sound Device / Device Operation / PCM Stream Parameters} + +\begin{itemize} +\item If the device has an intermediate buffer, its size MUST be no less than +the specified \field{buffer_bytes} value. +\end{itemize} + +\drivernormative{\subparagraph}{Stream Parameters}{Device Types / Sound Device / Device Operation / PCM Stream Parameters} + +\begin{itemize} +\item \field{period_bytes} MUST be a divider \field{buffer_bytes}, i.e. \field{buffer_bytes} \% \field{period_bytes} == 0. +\item The driver MUST NOT set undefined direction, feature, format and rate values. +\item The driver MUST NOT set the direction, feature, format, and rate that are +not specified in the stream configuration. +\item In the case of a unidirectional stream, the driver MUST use the same direction +value as specified in the stream configuration. +\item The driver MUST NOT set the \field{channels} value as less than the \field{channels_min} +or greater than the \field{channels_max} values specified in the stream configuration. +\item The driver MUST NOT set the VIRTIO_SND_PCM_F_SHMEM_HOST and VIRTIO_SND_PCM_F_SHMEM_GUEST +bits at the same time. +\item The driver MUST initialize the \field{padding} bytes to 0. +\item If the bits associated with the shared memory are not selected, the driver +MUST use the tx and rx queues for data transfer +(see \nameref{sec:Device Types / Sound Device / Device Operation / PCM IO Messages}). +\end{itemize} + +\paragraph{VIRTIO_SND_R_PCM_PREPARE} + +Prepare a stream with specified stream ID. + +\paragraph{VIRTIO_SND_R_PCM_RELEASE} + +Release a stream with specified stream ID. + +\paragraph{VIRTIO_SND_R_PCM_START} + +Start a stream with specified stream ID. + +\paragraph{VIRTIO_SND_R_PCM_STOP} + +Stop a stream with specified stream ID. + +\paragraph{VIRTIO_SND_R_PCM_PAUSE} + +Set a stream with specified stream ID on pause. + +\paragraph{VIRTIO_SND_R_PCM_UNPAUSE} + +Resume a paused stream with specified stream ID. + +\subsubsection{PCM Notifications} + +The device can announce support for different PCM events using feature bits +in the stream configuration structure. To enable notifications, the driver +must negotiate these features using the set stream parameters request +(see \ref{sec:Device Types / Sound Device / Device Operation / PCM Stream Parameters}). + +PCM stream notifications consist of a virtio_snd_event structure, which has the +following fields: + +\begin{description} +\item[\field{type}] (device-writable) indicates a PCM stream event type: +\begin{itemize} +\item VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED - a hardware buffer period has elapsed, +the period size is controlled using the \field{period_bytes} field. +\item VIRTIO_SND_EVT_PCM_XRUN - an underflow for the output stream or an overflow +for the input stream has occurred. +\end{itemize} +\item[\field{data}] (device-writable) indicates a PCM stream identifier +from 0 to \field{streams} - 1. +\end{description} + +\subsubsection{PCM I/O Messages}\label{sec:Device Types / Sound Device / Device Operation / PCM IO Messages} + +An I/O message consists of the header part, followed by the buffer, and then +the status part. + +\begin{lstlisting} +/* an I/O header */ +struct virtio_snd_pcm_xfer { + le32 stream_id; +}; + +/* an I/O status */ +struct virtio_snd_pcm_status { + le32 status; + le32 latency_bytes; +}; +\end{lstlisting} + +The header part consists of the following field: + +\begin{description} +\item[\field{stream_id}] (device-readable) specifies a PCM stream identifier +from 0 to \field{streams} - 1. +\end{description} + +The status part consists of the following fields: + +\begin{description} +\item[\field{status}] (device-writable) contains VIRTIO_SND_S_OK if an operation +is successful, and VIRTIO_SND_S_IO_ERR otherwise. +\item[\field{latency_bytes}] (device-writable) indicates the current device latency. +\end{description} + +Since all buffers in the queue (with one exception) must be of the size +\field{period_bytes}, the completion of an I/O request can be considered an elapsed +period notification. + +\paragraph{Output Stream} + +In case of an output stream, the header is followed by a device-readable buffer +containing PCM frames for writing to the device. All messages are placed into +the tx queue. + +\devicenormative{\subparagraph}{Output Stream}{Device Types / Sound Device / Device Operation / PCM Output Stream} + +\begin{itemize} +\item The device MUST NOT complete the I/O request until the buffer is totally +consumed. +\end{itemize} + +\drivernormative{\subparagraph}{Output Stream}{Device Types / Sound Device / Device Operation / PCM Output Stream} + +\begin{itemize} +\item The driver MUST populate the tx queue with \field{period_bytes} sized +buffers. The only exception is the end of the stream. +\item The driver MUST NOT place device-writable buffers into the tx queue. +\end{itemize} + +\paragraph{Input Stream} + +In case of an input stream, the header is followed by a device-writable buffer +being populated with PCM frames from the device. All messages are placed into +the rx queue. + +\devicenormative{\subparagraph}{Input Stream}{Device Types / Sound Device / Device Operation / PCM Input Stream} + +\begin{itemize} +\item The device MUST NOT complete the I/O request until the buffer is full. +The only exception is the end of the stream. +\end{itemize} + +\drivernormative{\subparagraph}{Input Stream}{Device Types / Sound Device / Device Operation / PCM Input Stream} + +\begin{itemize} +\item The driver MUST populate the rx queue with \field{period_bytes} sized +empty buffers before starting the stream. +\item The driver MUST NOT place device-readable buffers into the rx queue. +\end{itemize} |