[alsa-devel] Audio DMA buffer layout

Takashi Iwai tiwai at suse.de
Wed May 9 15:15:17 CEST 2007

At Tue, 08 May 2007 13:47:47 +0200,
Markus Korber wrote:
> Hi,
> I'm working with a custom sound chip with its own DMA hardware.  The
> figure shows how the I2S DMA expects data to be prepared:
>      IRQ1 +----------------+
>           | page_3 (right) |\
>           +----------------+ > double buffer 1
>           | page_2 (left)  |/
>      IRQ0 +----------------+
>           | page_1 (right) |\
>           +----------------+ > double buffer 0
>           | page_0 (left)  |/
>           +----------------+
> The hardware has 2 double buffers, each containing left and right sample
> regions, i.e. it alternately transmits samples from page_0 and page_1,
> i.e. double buffer 0, then generates an interrupt and starts
> transmitting page_2 and page_3.  After that another interrupt is
> generated and the process begins again with double buffer 0.
> So my question is, how to tell ALSA about this memory layout?  Is it
> possible to operate in MMAP mode with SNDRV_PCM_INFO_NONINTERLEAVED?
> But then, how to tell the application that it should either fill double
> buffer 0 or 1?  Or should I use RW mode and copy samples manually to
> another buffer?  Or something else?  SG-DMA?  page()-callback?

If I understand correctly, the samples for a channel (e.g. left) is
practically split to two regions, page 0 and page 2 in the above?
If yes, this h/w design is hard to implement mmap mode
straightforwardly because the alsa-lib (and apps) assume "linear" 
buffers.  For normal read/write without mmap, this shouldn't be that
hard as you guess, though.

A workaround would be to use SG-buffer (if possible).  The constraint
is thta both double buffers above have to be aligned in PAGE_SIZE
(depending on architecture, 4KB mostly).  For implementing a SG
buffer, you can use either mmap or page pcm_ops.  The mmap is to
do the whole mmap operation, so you can do all what you'd like.  The
page is a callback used by the default ALSA mmap handler and you can
return the page pointer corresponding to the given buffer offset.


More information about the Alsa-devel mailing list