[alsa-devel] PCM buffering ussues ( or probably the lack of understanding )

marcelg marcelsbox at quicknet.nl
Sat Apr 20 09:13:34 CEST 2013

I am working on a PCM driver, have some issues and thing which are 
unclear to me, hopefully somebody here can clarify something for me.

My PCM driver is straigh forward:

- Copy callback copies the frames received in the callback into a small 
ringbuffer and starts a DMA transfer to the hardware.
- DMA interrupt each times take the next chunk from the ringbuffer.
- In the DMA interrupt the number of frames is counted, if te number >= 
period_size reported in runtime_struct   pcm_period_elapsed() is called.
- the pointer which is read by the pcm_pointer() callback is updated in 
each DMA interrupt.

When using mplayer this works without problems, however with other 
applications like mpg123 its causes a lot of problems, for some reaosns 
I do not understand yet.
It has something to do with buffer handling.

basically in the cm driver I can influence a few parameters:

period_bytes_min, period_bytes_max
buffer_size  ( should be sufficient to hold periods_max with 
period_bytes_max I assume )

As far as I understand periods_min/periods_max is the size (number of 
buffer entries) of the internal ringbuffer Alsa uses.
- Why is there both a min and a max ?  How is chosen what will be used ?
- Currently my period_min is set to 1 and my period_max  set to 4, If I 
increase the period_max value it does not start properly, it seems  that 
the samples are not deliverered in time.
   Is there any explanation for this,   does the Alsa layer not any 
pre-buffering before the first copy() is called ?
- Is there any advice / guidline for period min/max values ?  I checked 
sourecs of severl drivers, some use 1 and some use values like 32 or 
more for period_max.

The same applies to buffer_bytes min/max, currently my min is set to 
128bytes , max to 2kB, larger values of max seem to cause more problems.

 From the documentation I understand that it does not matter if 
pcm_period_elapsed()  is not always called,  How dows the ALSA layer 
then know how many samples are played.
the pointer value read the pcm_pointer()  only counts from 
[0..period_max]  so what if 2 or more calls to period_elapsed()  are 
skipped ?

Suppose I want to have some buffering inside my pcm driver, how will I 
be able to get some samples in advance before starting playback ? Can I 
just call pcm_period_elapsed() a few times in  a row to get the buffer 
before starting the actual playcback, or does this cause side effects ?

I noticed that the number of frames passed to pcm_copy is often less 
than the periods_size, is this determined by the application ?

Lots of questions, but I try to understand the odd behaviour with 
certain applications ( and the best settings for a pcm driver which will 
work with most applications )

Any help would be appreciated.


More information about the Alsa-devel mailing list