[alsa-devel] underruns and POLLERR when copying audio frames

Stefan Schoenleitner dev.c0debabe at gmail.com
Tue Jul 20 13:00:41 CEST 2010


I have some code that basically captures audio frames from one device
and then writes it for playback to another device.

Ideally mmapped IO could be used for such a task, but in my application
this is not possible at the moment, as at least one of the audio devices
does not support it.

In my application copying audio frames works with a poll() based approach:

If the capture device is ready for reading, a new audio frame is being read.
And if there is a new captured frame available AND the playback device
is ready, then it is written to the playback device.

So far so good, the approach works.
However, it doesn't take long until poll() on the playback device
returns POLLERR since an underrun has occurred.
If I just ignore POLLERR, then the next write operation to the playback
device fails and I need to snd_pcm_recover().

My question is how to avoid these underruns.
Basically I have two ideas:

1. The avail_min parameter specifies when the playback device should
start to play buffered frames back.
Hence if for example avail_min=160, then the playback device would wait
until at least 160 frames have been written to the playback device (i.e.
to the internal buffer) and then start with playing back these frames.
My idea would be to just increment avail_min to something bigger, so
that more frames are being buffered before playback starts.
Would this work ?

2. Another idea would be to do some buffering on my own in the application.
Thus I would first capture a number of frames and write them to a FIFO
Once the buffer has been filled with enough frames, I would start to
write them to the playback device.
Therefore while the FIFO is being drained on the one side (playback), it
is also refilled on the other side (capture).

* So, which of these ideas do you think is better in terms of avoiding
underruns ?

To me it seems that both solutions would lead to the same results.
Yet just setting avail_min to something higher seems to be the easier
solution as it does not require me to implement a buffering solution on
my own.


More information about the Alsa-devel mailing list