[alsa-devel] Qustions on dmix - aplay - hw_ptr - appl_ptr

Matthew Foster matt at breakcode.com
Mon Apr 23 06:06:35 CEST 2007

Ok I am just tracking the hw_ptr and I keep track of the last value of the
hw_ptr and transfer the difference between the two. 

I also solved another problem where I wasn't waiting for my device buffer to
drain in the open callback. In my open callback I was querying my device
buffer to set the max_buf_size variable and if I didn't wait for the
previous data to transfer out it would report the wrong value. 

However I am still stumped on a problem where if the file size aplay tries
to play is smaller than our buffer (64KB) it randomly plays sometimes and
randomly there is silence. If I modify the file to be at least 64KB it plays
fine. Here is my HW params setup:

  Runtime->hw.buffer_bytes_max = (1024 *64); //The size of our non-HW buffer
  runtime->hw.period_bytes_min = runtime->hw.buffer_bytes_max/2;
  runtime->hw.period_bytes_max = runtime->hw.buffer_bytes_max/2;
  runtime->hw.periods_min = 2;
  runtime->hw.periods_max = 2;

I have tried playing around the these values to only get unpredictable
playback results. Sometimes playback would sound all messed up or corrupted.
Perhaps I don't understand how these values are used. Also if I run aplay
over and over fast enough with these smaller clips I can prevent the driver
from ever calling the close callback function and this results in only
hearing part of this clip sometimes and silence for the majority of the time
I keep trying to run aplay quickly over and over. 

Is there any way for me to avoid this un-predictable behavior with these
smaller clips? I am leaning towards a setup issue or something but I am
definitely stumped. Any help on this would be GREATLY appreciated. Thanks so

Matthew Foster

-----Original Message-----
From: Takashi Iwai [mailto:tiwai at suse.de] 
Sent: Wednesday, April 18, 2007 6:10 AM
To: matt at breakcode.com
Cc: alsa-devel at alsa-project.org
Subject: Re: [alsa-devel] Qustions on dmix - aplay - hw_ptr - appl_ptr

At Tue, 17 Apr 2007 10:12:07 -0700,
Matthew Foster wrote:
> I am a driver developer that is new to ALSA. I have read the tutorial as
> example on how to write an ALSA driver. I appreciate the documentation you
> have provided online. I was wondering if you might have time to possibly
> answer a question. I am having trouble understanding things in the
> memory/buffer management area. 
>  I am not writing a driver for a PCI device, I am writing a driver that
> as an interface from the ALSA to a render device. So I essentially have a
> circular buffer I am transferring the ALSA data to.  I set up the ALSA
> buffer like this:
> snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
> snd_dma_continuous_data(GFP_KERNEL),
> And later on in my driver after open is called I have a buffer polling
> that does the period notification and constantly monitors my render
> buffer. I have my asound.conf setup like this:
>     pcm.mix {
>         type dmix
>         ipc_key 1024
>         slave {
>         pcm "hw:0,0"
>             rate 48000
>         }
>     }
>     pcm.!default {
>         type plug
>         slave.pcm "mix"
>     }
> This is to enable the dmix plugin so I can run aplay more than once and
> the two streams mixed in.  
> The problem I am having is that it seems that when I run aplay like this:
> "aplay close.wav" I only see this pointer moving:
> substream->runtime->status->hw_ptrbir
> And if I run aplay like this: "aplay -D plughw:0,0 close.wav" I only see
> this pointer moving:
> substream->runtime->control->appl_ptr
> This seems odd to me and currently in my code I just check which pointer
> moves and use that to calculate how much data I need to write to my render
> device. This is so I can support both use cases.

The behavior of dmix is somehow special.  It mmaps a buffer to
multiple instances and runs continuously without XRUN check as long as
clients are connected.  Dmix assumes the driver running a la DMA.
That is, hw_ptr can be constantly updated in a ring buffer.  Since it
disables the XRUN check by adjusting stop_threshold, appl_ptr is
meaningless here. 

Thus, for supporting dmix on your device, you may need to ignore
appl_ptr and simply transfer the period-size chunk at each time.

Currently, the support of non-DMA style hardwares is poor on ALSA,
which I'd like to improve in near future.  At least, we should provide
a proper framework.

> Another major problem is that when I play a short wav file 25KB or so and
> use the dmix "aplay close.wav" it randomly doesn't play at sometimes. Also
> if I run "aplay close.wav" and then very quickly run "aplay close.wav"
> at the same prompt I get corruption of the data which produces screeching.
> In the case where I run aplay one right after the other I notice that the
> hw_ptr moves differently (less) than if I run it, wait, run again. 

Possibly depending on the behavior above?

> I am also noticing also that when I do the aplay over and over quickly
> these values change (get lower) in my snd_pcm_prepare callback:
>   chip_data->buf_size        = snd_pcm_lib_buffer_bytes(substream);
>   chip_data->period_buf_size = snd_pcm_lib_period_bytes(substream);
> It seems like those value should remain constant, and I use those values
> calculate later in my polling thread to notify of a period lapse. It's
> almost like the runtime is telling me the period has changed and the
> size has changed. But this only happens in this case with a short wav file
> and running aplay over and over quickly. 

This sounds odd.  Do you call snd_pcm_lib_malloc() in hw_params


More information about the Alsa-devel mailing list