[alsa-devel] appl_ptr and DMA overrun at end of stream

Takashi Iwai tiwai at suse.de
Thu May 14 12:39:53 CEST 2009

At Mon, 11 May 2009 14:00:59 -0400,
Jon Smirl wrote:
> On Mon, May 11, 2009 at 1:37 PM, Jaroslav Kysela <perex at perex.cz> wrote:
> > On Mon, 11 May 2009, Jon Smirl wrote:
> >
> >> Checking for over/under run in software is not reliable since the DMA
> >> hardware runs asynchronously with the CPU. There will always be
> >> variable latencies between when the CPU detects the condition and when
> >> it can control the DMA hardware.  The only reliable way to do this is
> >> to program the DMA hardware to do itself. AFAIK all DMA modern
> >> hardware can be programed to do this if the right information is made
> >> available. Programming the DMA hardware to do this is a 100% reliable
> >> solution and not subject to random latency problems.
> >
> > I comment playback for simplicity.
> >
> > The key point is when you fill DMA engine. Nothing forces you to queue whole
> > ring buffer in the scatter-gather list. You may queue just one period and
> > then next one (including partial). The available samples can be determined
> > using snd_pcm_playback_hw_avail() function at any time. If you have large
> I didn't know about this function. I can use it to replace the direct
> manipulation of appl_ptr.

Well, this computes a value between appl_ptr and hw_ptr.  That is, it
relies on the current hw_ptr value.  Just to make sure...

> > FIFO and you receive interrupt before FIFO goes empty, you can fill partial
> > period. The elapsed notifier does not require any change.
> >
> > The underruns should be avoided as first step, because it's really unwanted
> > system behaviour. All methods to fix underruns fails in some respects.
> >
> > Also note that we have also mode when appl_ptr is not updated at all (when
> > stop_threshold == boundary).
> How does this mode work? Could it be hidden inside
> snd_pcm_playback_hw_avail() such that low level drivers don't have to
> worry about it?

Hm, no, in this case, it won't work properly.
*_avail() simply tells you a bogus value, even a negative one.

Basically this is a free-wheeling mode, e.g. used by dmix.
In this mode, you simply ignore appl_ptr but assume that period_size
samples are available at each period update.  So, this would be a
different implementation.

I don't know whether this mode has to be implemented for the hardware
like yours.  I feel it's better to avoid the free-wheel mode by some
condition (a new pcm_info flag?)



More information about the Alsa-devel mailing list