Re: [virtio-dev] virtio-snd comments/questions

Matias Ezequiel Vara Larsen
2023-11-27T11:20:57Z

On Wed, Nov 22, 2023 at 06:59:15PM +0000, Radu Ocica wrote:
> Hi Matias,
>
>
> > >
> > > > Could you elaborate on this? Which audio backend would not support
> > > > PAUSE? I am not very familiar with audio engines.
> > >
> > > For instance in linux, alsa-lib has a flag that specifies pause support by a PCM stream:
> > > #define SNDRV_PCM_INFO_PAUSE (1UL<<19) /* pause ioctl is supported */
> > > The snd_pcm_pause API can only be used successfully if the PCM stream has this bit set in its PCM info.
> > > A similar concept exists in QNX sound.
> > >
>
> > Oh, I see. I was unaware of this flag. Not supporting PAUSE in the host
> > sound card may not be a problem. In our case, the pw backend in the host
> > stops playing when a guest sends STOP immediately. As soon as START is
> > sent again, pw begins consuming from the tx queue. Tx buffers are only
> > signaled as complete after START is reissued. In the meantime, the msgs
> > are in the available ring of the tx queue.
>
> > > However, if the host stream does not support pause the only option
> > > left is to perform a drop operation on the host stream and in this
> > > case all pending messages in the tx/rx queue need to be returned to
> > > the guest as completed, because at the next start possibly all
> > > messages will be needed to prime the host stream (in the case of
> > > playback).
>
> > If STOP is sent and there is still msgs in the TX queue, can't the
> > device just stop playing until START is issued again? Why does the
> > device require to drop the msgs in this case?
> Invoking the pcm drop API on the host has been the modality chosen by us to stop playing, with immediate effect. Whatever io messages were buffered at the time by the host pcm device need then to be returned to the guest driver as completed. Messages in the TX queue at the time of the STOP request can be left untouched. Depending on the relationship between number of periods used by the guest device vs number of periods used by the host device, the TX queue might be normally empty though (for instance if host and guest device use the same number of periods, all pcm data received from the guest driver would end up immediately in the backend buffer).
> The way you describe STOP it sounds like you just stop writing new data to the host pcm device, without invoking any API to explicitly stop it (if pause API not available for the host pcm device). This allows for currently backend buffered data to continue playing and correspondingly io messages need to be returned to the guest driver as they are consumed. If no START is received before the backend buffered data completes playing, the host device then underruns. At this point it either continues running by injecting silence or stops, depending on setup options. The effective stop of sound playback occurs when the backend buffered data completes playing, which might be after a considerable delay, depending on backend buffer size. Keeping the host device running and injecting silence sounds like the easiest way to avoid the need to re-prepare the host pcm device when restarting. Have I captured your approach accurately?

For example, in the audio backend for pipewire, the STOP cmd stops
playing, i.e., the device stops to consume from the tx queue. This cmd
translates to something like `stream.set_active(false)`. In the pw
backend, the consumption happens from a thread named the threadloop.
When setting `set_active(false)`, such a thread stops to execute. There
is no need to insert silence from the audio backend. The threadloop
starts to execute again and thus consuming from tx when issuing
`set_active(true)` during the START cmd.

Matias