All of lore.kernel.org
 help / color / mirror / Atom feed
* Trouble understanding ALSA's DMA buffers
@ 2007-06-11 19:57 Timur Tabi
  2007-06-11 20:29 ` Nobin Mathew
  0 siblings, 1 reply; 7+ messages in thread
From: Timur Tabi @ 2007-06-11 19:57 UTC (permalink / raw)
  To: alsa-devel

I'm writing an ALSA SOC driver for an I2S-based device, and I'm having a really hard time 
understanding how ALSA uses the DMA buffers.  And yes, I've read the documentation and 
studied some sample source code.

I used to write audio drivers for a living, but that was many years ago, and it wasn't for 
Linux.  Perhaps the concepts in my head are outdated, but I just don't see enough 
explanation as to how DMA buffers are supposed to work.

Back then, audio drivers used "ping pong" DMA buffers.  A single DMA buffer is allocated, 
and the audio hardware is programmed to read from that buffer in a loop.  That is, it 
would automatically restart reading from the beginning of the buffer without any 
reprogramming.  The hardware would also be programmed to issue an interrupt when it got to 
the end of the buffer, and when it got to the half-way point.

To start playback, you first filled the whole buffer with audio data, and then told the 
hardware to start playing.  After the hardware got to the half-way point, it would issue 
an interrupt.  You would then tell the OS you need more data, and you'd get it.  You then 
copy that data into the first half of the buffer *while* the hardware was playing the 
second half.  Later, the hardware would interrupt you when it got to the end of the 
buffer.  You'd then copy more data to the 2nd half while the hardware is playing the first
half.

And so - hardware plays one half while you copy data to the other half.  Hence, "ping pong".

So how do I implement this in ALSA?  The "Writing an ALSA Driver" document doesn't even 
contain the words "ping" or "pong".

-- 
Timur Tabi
Linux Kernel Developer @ Freescale

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Trouble understanding ALSA's DMA buffers
  2007-06-11 19:57 Trouble understanding ALSA's DMA buffers Timur Tabi
@ 2007-06-11 20:29 ` Nobin Mathew
  2007-06-12 10:36   ` Takashi Iwai
  0 siblings, 1 reply; 7+ messages in thread
From: Nobin Mathew @ 2007-06-11 20:29 UTC (permalink / raw)
  To: Timur Tabi; +Cc: alsa-devel

Hi,

Now ALSA (audio ) buffer is divided into periods, i.e. a chain of small packets.

periods size is configurable. Data transfer to the codec starts only
after reaching start_threshold point (start_threshold is in periods),
this time DMA trigger is called.

This trigger onwards application will get notification from the kernel
saying that period buffer is empty you can write into it.Till the end
of music file.

Nobin Mathew



On 6/12/07, Timur Tabi <timur@freescale.com> wrote:
> I'm writing an ALSA SOC driver for an I2S-based device, and I'm having a really hard time
> understanding how ALSA uses the DMA buffers.  And yes, I've read the documentation and
> studied some sample source code.
>
> I used to write audio drivers for a living, but that was many years ago, and it wasn't for
> Linux.  Perhaps the concepts in my head are outdated, but I just don't see enough
> explanation as to how DMA buffers are supposed to work.
>
> Back then, audio drivers used "ping pong" DMA buffers.  A single DMA buffer is allocated,
> and the audio hardware is programmed to read from that buffer in a loop.  That is, it
> would automatically restart reading from the beginning of the buffer without any
> reprogramming.  The hardware would also be programmed to issue an interrupt when it got to
> the end of the buffer, and when it got to the half-way point.
>
> To start playback, you first filled the whole buffer with audio data, and then told the
> hardware to start playing.  After the hardware got to the half-way point, it would issue
> an interrupt.  You would then tell the OS you need more data, and you'd get it.  You then
> copy that data into the first half of the buffer *while* the hardware was playing the
> second half.  Later, the hardware would interrupt you when it got to the end of the
> buffer.  You'd then copy more data to the 2nd half while the hardware is playing the first
> half.
>
> And so - hardware plays one half while you copy data to the other half.  Hence, "ping pong".
>
> So how do I implement this in ALSA?  The "Writing an ALSA Driver" document doesn't even
> contain the words "ping" or "pong".
>
> --
> Timur Tabi
> Linux Kernel Developer @ Freescale
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Trouble understanding ALSA's DMA buffers
  2007-06-11 20:29 ` Nobin Mathew
@ 2007-06-12 10:36   ` Takashi Iwai
  2007-06-12 15:21     ` Pharaoh .
  2007-06-12 16:36     ` Timur Tabi
  0 siblings, 2 replies; 7+ messages in thread
From: Takashi Iwai @ 2007-06-12 10:36 UTC (permalink / raw)
  To: Nobin Mathew; +Cc: alsa-devel, Timur Tabi

At Tue, 12 Jun 2007 01:59:45 +0530,
Nobin Mathew wrote:
> 
> Hi,
> 
> Now ALSA (audio ) buffer is divided into periods, i.e. a chain of small packets.
> 
> periods size is configurable. Data transfer to the codec starts only
> after reaching start_threshold point (start_threshold is in periods),
> this time DMA trigger is called.
> 
> This trigger onwards application will get notification from the kernel
> saying that period buffer is empty you can write into it.Till the end
> of music file.

Yes.  And the "ping-poing" is the case that you have two periods in a
ring buffer.

Most hardwares support more periods practically.  That's why "periods"
(corresponds to "fragments" in OSS) was introduced, as more generic
abstraction.


Takashi

> 
> Nobin Mathew
> 
> 
> 
> On 6/12/07, Timur Tabi <timur@freescale.com> wrote:
> > I'm writing an ALSA SOC driver for an I2S-based device, and I'm having a really hard time
> > understanding how ALSA uses the DMA buffers.  And yes, I've read the documentation and
> > studied some sample source code.
> >
> > I used to write audio drivers for a living, but that was many years ago, and it wasn't for
> > Linux.  Perhaps the concepts in my head are outdated, but I just don't see enough
> > explanation as to how DMA buffers are supposed to work.
> >
> > Back then, audio drivers used "ping pong" DMA buffers.  A single DMA buffer is allocated,
> > and the audio hardware is programmed to read from that buffer in a loop.  That is, it
> > would automatically restart reading from the beginning of the buffer without any
> > reprogramming.  The hardware would also be programmed to issue an interrupt when it got to
> > the end of the buffer, and when it got to the half-way point.
> >
> > To start playback, you first filled the whole buffer with audio data, and then told the
> > hardware to start playing.  After the hardware got to the half-way point, it would issue
> > an interrupt.  You would then tell the OS you need more data, and you'd get it.  You then
> > copy that data into the first half of the buffer *while* the hardware was playing the
> > second half.  Later, the hardware would interrupt you when it got to the end of the
> > buffer.  You'd then copy more data to the 2nd half while the hardware is playing the first
> > half.
> >
> > And so - hardware plays one half while you copy data to the other half.  Hence, "ping pong".
> >
> > So how do I implement this in ALSA?  The "Writing an ALSA Driver" document doesn't even
> > contain the words "ping" or "pong".
> >
> > --
> > Timur Tabi
> > Linux Kernel Developer @ Freescale
> > _______________________________________________
> > Alsa-devel mailing list
> > Alsa-devel@alsa-project.org
> > http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> >
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Trouble understanding ALSA's DMA buffers
  2007-06-12 10:36   ` Takashi Iwai
@ 2007-06-12 15:21     ` Pharaoh .
  2007-06-12 15:44       ` Pharaoh .
  2007-06-12 16:36     ` Timur Tabi
  1 sibling, 1 reply; 7+ messages in thread
From: Pharaoh . @ 2007-06-12 15:21 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Nobin Mathew, Timur Tabi

On 6/12/07, Takashi Iwai <tiwai@suse.de> wrote:
>
> At Tue, 12 Jun 2007 01:59:45 +0530,
> Nobin Mathew wrote:
> >
> > Hi,
> >
> > Now ALSA (audio ) buffer is divided into periods, i.e. a chain of small
> packets.
> >
> > periods size is configurable. Data transfer to the codec starts only
> > after reaching start_threshold point (start_threshold is in periods),
> > this time DMA trigger is called.
> >
> > This trigger onwards application will get notification from the kernel
> > saying that period buffer is empty you can write into it.Till the end
> > of music file.
>
> Yes.  And the "ping-poing" is the case that you have two periods in a
> ring buffer.
>
> Most hardwares support more periods practically.  That's why "periods"
> (corresponds to "fragments" in OSS) was introduced, as more generic
> abstraction.
>
>
> Takashi
>
> >
> > Nobin Mathew
> >
> >
> >
> > On 6/12/07, Timur Tabi <timur@freescale.com> wrote:
> > > I'm writing an ALSA SOC driver for an I2S-based device, and I'm having
> a really hard time
> > > understanding how ALSA uses the DMA buffers.  And yes, I've read the
> documentation and
> > > studied some sample source code.
> > >
> > > I used to write audio drivers for a living, but that was many years
> ago, and it wasn't for
> > > Linux.  Perhaps the concepts in my head are outdated, but I just don't
> see enough
> > > explanation as to how DMA buffers are supposed to work.
> > >
> > > Back then, audio drivers used "ping pong" DMA buffers.  A single DMA
> buffer is allocated,
> > > and the audio hardware is programmed to read from that buffer in a
> loop.  That is, it
> > > would automatically restart reading from the beginning of the buffer
> without any
> > > reprogramming.  The hardware would also be programmed to issue an
> interrupt when it got to
> > > the end of the buffer, and when it got to the half-way point.
> > >
> > > To start playback, you first filled the whole buffer with audio data,
> and then told the
> > > hardware to start playing.  After the hardware got to the half-way
> point, it would issue
> > > an interrupt.  You would then tell the OS you need more data, and
> you'd get it.  You then
> > > copy that data into the first half of the buffer *while* the hardware
> was playing the
> > > second half.  Later, the hardware would interrupt you when it got to
> the end of the
> > > buffer.  You'd then copy more data to the 2nd half while the hardware
> is playing the first
> > > half.
> > >
> > > And so - hardware plays one half while you copy data to the other
> half.  Hence, "ping pong".
> > >
> > > So how do I implement this in ALSA?  The "Writing an ALSA Driver"
> document doesn't even
> > > contain the words "ping" or "pong".
> > >
> > > --
> > > Timur Tabi
> > > Linux Kernel Developer @ Freescale
> > > _______________________________________________
> > > Alsa-devel mailing list
> > > Alsa-devel@alsa-project.org
> > > http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> > >
> > _______________________________________________
> > Alsa-devel mailing list
> > Alsa-devel@alsa-project.org
> > http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> >
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>


Hi

yet another newbie question about periods here:

1. AFAIK, the period size is closely dependent on the h/w, but after reading
some docs I collected
that,  they can be given values depending on how much we care about the
latency. Does it mean
that, I can vary it without paying any attention to what h/w manual says
just because I want low or
high latency? I hope this question is clear.

2. As periods correspond to fragment size from OSS world, what the other
periods related fields
correspond to i.e. what do the following fields mean?

period_bytes_min,
period_bytes_max,
periods_min,
periods_max,

I know what they mean after looking at them but I want to know the
relationship between various
fields.

For e.g.

I have,

buffer_bytes_max = 8192 * 8
i.e. = AUDIO_FRAGSIZE_DEFAULT * AUDIO_NBFRAGS_DEFAULT

here AUDIO_FRAGSIZE_DEFAULT is size of period right? Then to get the max
buffer size we should multiply it
by number of periods, is this correct? Also, these are default values of the
period and no of periods, then do
I need to see the h/w manual to decide the periods_min/periods_max and
period_bytes_min/period_bytes_max
fields?

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Trouble understanding ALSA's DMA buffers
  2007-06-12 15:21     ` Pharaoh .
@ 2007-06-12 15:44       ` Pharaoh .
  0 siblings, 0 replies; 7+ messages in thread
From: Pharaoh . @ 2007-06-12 15:44 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Nobin Mathew, Timur Tabi

I found the following doc, it talks about periods in depth with a figure.

http://delivery.acm.org/10.1145/1020000/1017977/6735.html?key1=1017977&key2=0592661811&coll=GUIDE&dl=GUIDE&CFID=15151515&CFTOKEN=6184618

-pharaoh.

On 6/12/07, Pharaoh . <pharaoh137@gmail.com> wrote:
> On 6/12/07, Takashi Iwai <tiwai@suse.de> wrote:
> >
> > At Tue, 12 Jun 2007 01:59:45 +0530,
> > Nobin Mathew wrote:
> > >
> > > Hi,
> > >
> > > Now ALSA (audio ) buffer is divided into periods, i.e. a chain of small
> > packets.
> > >
> > > periods size is configurable. Data transfer to the codec starts only
> > > after reaching start_threshold point (start_threshold is in periods),
> > > this time DMA trigger is called.
> > >
> > > This trigger onwards application will get notification from the kernel
> > > saying that period buffer is empty you can write into it.Till the end
> > > of music file.
> >
> > Yes.  And the "ping-poing" is the case that you have two periods in a
> > ring buffer.
> >
> > Most hardwares support more periods practically.  That's why "periods"
> > (corresponds to "fragments" in OSS) was introduced, as more generic
> > abstraction.
> >
> >
> > Takashi
> >
> > >
> > > Nobin Mathew
> > >
> > >
> > >
> > > On 6/12/07, Timur Tabi <timur@freescale.com> wrote:
> > > > I'm writing an ALSA SOC driver for an I2S-based device, and I'm having
> > a really hard time
> > > > understanding how ALSA uses the DMA buffers.  And yes, I've read the
> > documentation and
> > > > studied some sample source code.
> > > >
> > > > I used to write audio drivers for a living, but that was many years
> > ago, and it wasn't for
> > > > Linux.  Perhaps the concepts in my head are outdated, but I just don't
> > see enough
> > > > explanation as to how DMA buffers are supposed to work.
> > > >
> > > > Back then, audio drivers used "ping pong" DMA buffers.  A single DMA
> > buffer is allocated,
> > > > and the audio hardware is programmed to read from that buffer in a
> > loop.  That is, it
> > > > would automatically restart reading from the beginning of the buffer
> > without any
> > > > reprogramming.  The hardware would also be programmed to issue an
> > interrupt when it got to
> > > > the end of the buffer, and when it got to the half-way point.
> > > >
> > > > To start playback, you first filled the whole buffer with audio data,
> > and then told the
> > > > hardware to start playing.  After the hardware got to the half-way
> > point, it would issue
> > > > an interrupt.  You would then tell the OS you need more data, and
> > you'd get it.  You then
> > > > copy that data into the first half of the buffer *while* the hardware
> > was playing the
> > > > second half.  Later, the hardware would interrupt you when it got to
> > the end of the
> > > > buffer.  You'd then copy more data to the 2nd half while the hardware
> > is playing the first
> > > > half.
> > > >
> > > > And so - hardware plays one half while you copy data to the other
> > half.  Hence, "ping pong".
> > > >
> > > > So how do I implement this in ALSA?  The "Writing an ALSA Driver"
> > document doesn't even
> > > > contain the words "ping" or "pong".
> > > >
> > > > --
> > > > Timur Tabi
> > > > Linux Kernel Developer @ Freescale
> > > > _______________________________________________
> > > > Alsa-devel mailing list
> > > > Alsa-devel@alsa-project.org
> > > > http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> > > >
> > > _______________________________________________
> > > Alsa-devel mailing list
> > > Alsa-devel@alsa-project.org
> > > http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> > >
> > _______________________________________________
> > Alsa-devel mailing list
> > Alsa-devel@alsa-project.org
> > http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> >
>
>
> Hi
>
> yet another newbie question about periods here:
>
> 1. AFAIK, the period size is closely dependent on the h/w, but after reading
> some docs I collected
> that,  they can be given values depending on how much we care about the
> latency. Does it mean
> that, I can vary it without paying any attention to what h/w manual says
> just because I want low or
> high latency? I hope this question is clear.
>
> 2. As periods correspond to fragment size from OSS world, what the other
> periods related fields
> correspond to i.e. what do the following fields mean?
>
> period_bytes_min,
> period_bytes_max,
> periods_min,
> periods_max,
>
> I know what they mean after looking at them but I want to know the
> relationship between various
> fields.
>
> For e.g.
>
> I have,
>
> buffer_bytes_max = 8192 * 8
> i.e. = AUDIO_FRAGSIZE_DEFAULT * AUDIO_NBFRAGS_DEFAULT
>
> here AUDIO_FRAGSIZE_DEFAULT is size of period right? Then to get the max
> buffer size we should multiply it
> by number of periods, is this correct? Also, these are default values of the
> period and no of periods, then do
> I need to see the h/w manual to decide the periods_min/periods_max and
> period_bytes_min/period_bytes_max
> fields?
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Trouble understanding ALSA's DMA buffers
  2007-06-12 10:36   ` Takashi Iwai
  2007-06-12 15:21     ` Pharaoh .
@ 2007-06-12 16:36     ` Timur Tabi
  2007-06-12 16:45       ` Takashi Iwai
  1 sibling, 1 reply; 7+ messages in thread
From: Timur Tabi @ 2007-06-12 16:36 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, Nobin Mathew

Takashi Iwai wrote:

> Yes.  And the "ping-poing" is the case that you have two periods in a
> ring buffer.

Ok, I understand the 'periods' concept now, thanks.

So when/where does ALSA copy data to the DMA buffer?  Isn't there supposed to be some kind 
of callback where ALSA calls the driver and says, "here's some data, please copy it to 
your DMA buffer?"

Or does ALSA do all the copying itself whenever the driver calls snd_pcm_period_elapsed()?

-- 
Timur Tabi
Linux Kernel Developer @ Freescale

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Trouble understanding ALSA's DMA buffers
  2007-06-12 16:36     ` Timur Tabi
@ 2007-06-12 16:45       ` Takashi Iwai
  0 siblings, 0 replies; 7+ messages in thread
From: Takashi Iwai @ 2007-06-12 16:45 UTC (permalink / raw)
  To: Timur Tabi; +Cc: alsa-devel, Nobin Mathew

At Tue, 12 Jun 2007 11:36:33 -0500,
Timur Tabi wrote:
> 
> Takashi Iwai wrote:
> 
> > Yes.  And the "ping-poing" is the case that you have two periods in a
> > ring buffer.
> 
> Ok, I understand the 'periods' concept now, thanks.
> 
> So when/where does ALSA copy data to the DMA buffer?  Isn't there supposed to be some kind 
> of callback where ALSA calls the driver and says, "here's some data, please copy it to 
> your DMA buffer?"
> 
> Or does ALSA do all the copying itself whenever the driver calls snd_pcm_period_elapsed()?

It depends on the implementation, but usually the latter case.
The whole data-transfer task is done by ALSA PCM middle layer, and
each driver has to take care of the DMA setup -- as long as your
hardware can have a buffer on RAM.  If you need to copy the data to
hardware buffer manually in some way, the things become
complicated...


Takashi

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2007-06-12 16:45 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-06-11 19:57 Trouble understanding ALSA's DMA buffers Timur Tabi
2007-06-11 20:29 ` Nobin Mathew
2007-06-12 10:36   ` Takashi Iwai
2007-06-12 15:21     ` Pharaoh .
2007-06-12 15:44       ` Pharaoh .
2007-06-12 16:36     ` Timur Tabi
2007-06-12 16:45       ` Takashi Iwai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.