[alsa-devel] paravirtualized alsa kernel driver for XEN

Clemens Ladisch clemens at ladisch.de
Wed Apr 11 20:41:07 CEST 2012

Stefano Panella wrote:
> To make echo cancellation work in the guest the guest needs to know
> exactly which sample in the buffer is going in and out, right?

Yes.  (Although many drivers don't bother to report the delay, and Skype
works anyway, but that's probably because the delay isn't too big anyway.)

> How can I design my alsa backend userspace program and the pv alsa
> kernel driver for the guest to do this?

Report the correct delay, i.e., in the pv pointer callback, call
snd_pcm_status() in the backend to get both DMA position and delay, and
compute from these the delay to set in runtime->delay.

(Well, I don't know if Skype actually uses the delay value ...)

> Is there any echo cancellation test program

None that I know of.

> What would be very critical in the guest pv alsa driver?
> - Should the first audio sample be played/captured right after the
>   trigger or it can happen at later time

In your pv trigger callback, you should ultimately call the backend
trigger, i.e., snd_pcm_start() etc.

How fast the first sample is played depends on the host sound driver
(and the latency of your pv->dom0 call).

> (runtime->delay maybe could be setted)?

You do not know if there is a constant delay or if it can change (as
with, e.g., the USB driver), so you should recompute the delay in the
pointer callback.

> - should the pointer callback reflect the sample being currently
>   played/captured?

No, it's the DMA position, i.e., the position in the buffer where the
application can read or write data.

> - what should the pointer callback return in case of a fixed delay in
>   playback and capture?

The callback's return value doesn't depend on the delay.  However, if
the delay changes, it must adjust runtime->delay.

> - do I need an interrupt every period triggered from the backend or
>   can I use the hrtimer as in the dummy sound card example?

The interrupts (i.e., the snd_pcm_period_elapsed() calls) must be
synchronized with the sample clock.  A period trigger is a guarantee
from the driver to the ALSA framework that
1) (at least) one period has elapsed since the last call, and
2) all the data in the period has been played, so the application
   can overwrite it with new data (i.e., the return value of the
   pointer callback is now at least at the end of the period).

The dummy driver uses a timer because there is no other clock, and what
is in the buffer doesn't actually matter for it.

You must ensure that a period_elapsed call in the pv driver does not
happen earlier than the corresponding period interrupt in the backend;
the easiest way to do this would be to connect them.

> -in order to only use the copy callback, and remove mmap support, what
> should I do?

Er, implement the copy callback (copy the indicated data from userspace
into the shared buffer, or the other way around), and drop the
SNDRV_PCM_INFO_MMAP* flags.  And you don't need to allocate a buffer in
the pv driver.

> On the backend application side:
> - how using dmix, dsnoop, asym plugins affects sample position
>   accuracy using snd_pcm_delay, snd_pcm_avail, snd_pcm_status_get_delay ?

The asym plugin just instantiates another plugin.

The dmix and dsnoop plugins just pass through snd_pcm_avail, but AFAICS
they do not report the delay at all.

> - how could I be woken up exactly every period using dmix, dsnoop,
>   asym plugins?

The dmix/dsnoop plugins get their interrupts from the base device; they
are woken up normally like any other type of device.

> all is working well but echo cancellation

Try with hw instead of dmix.  If that works, it would imply that echo
cancellation does not work with an unvirtualized dmix either, but I
don't know what device Skype actually opens.


More information about the Alsa-devel mailing list