[alsa-devel] periods*period_size vs. buffer_size; should they be equal?

Jassi Brar jassisinghbrar at gmail.com
Sat Dec 18 03:06:45 CET 2010


On Sat, Dec 18, 2010 at 5:04 AM, Stephen Warren <swarren at nvidia.com> wrote:
> I'm attempting to understand the layout of the DMA buffer used by ASoC
> devices. It seems like the buffer should consist of runtime->periods entries
> each of runtime->period_size frames of audio data. Hence, runtime->buffer_size
> should be equal to runtime->periods * runtime->period_size in frames.
>
> This assumption holds true in many cases. However, it doesn't in others:
>
> (sizes in hex)
>
> Playing WAVE '8000.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Stereo
> [  217.910867] Trigger: runtime->periods=4
> [  217.914696] Trigger: runtime->period_size=3e8
> [  217.919043] Trigger: runtime->buffer_size=fa0
> [  217.923389] Trigger: f2b(4)=10
>
> Playing WAVE '11025.wav' : Signed 16 bit Little Endian, Rate 11025 Hz, Stereo
> [  268.543821] Trigger: runtime->periods=5
> [  268.547651] Trigger: runtime->period_size=400
> [  268.551998] Trigger: runtime->buffer_size=1589
>
> Playing WAVE '16000.wav' : Signed 16 bit Little Endian, Rate 16000 Hz, Stereo
> [  315.889280] Trigger: runtime->periods=7
> [  315.893109] Trigger: runtime->period_size=400
> [  315.897456] Trigger: runtime->buffer_size=1f40
>
> Yet for any higher sample rate the layout is identical:
>
> Playing WAVE '96000.wav' : Signed 16 bit Little Endian, Rate 96000 Hz, Stereo
> [  385.494764] Trigger: runtime->periods=8
> [  385.498594] Trigger: runtime->period_size=400
> [  385.502941] Trigger: runtime->buffer_size=2000
>
> Is my assumption wrong? Is there some bug somewhere?

You assumption doesn't seem to be accurate.
Theoretically, your buffer_size may not be a multiple of period_size. But that
would mean points shifting on the ring buffer at which interrupts are generated.

Usually embedded systems don't have dedicated ring buffer DMA for use
with ASoC... and it is cumbersome to reprogram the next interrupt point if
buffer_size is not a multiple of period_size. So, we usually call
snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
in the stream open callback, which ensures constrainst buffer_size to
be a multiple of period_size.


More information about the Alsa-devel mailing list