[alsa-devel] Proposal for more reliable audio DMA.
Jon Smirl
jonsmirl at gmail.com
Sun Jun 21 04:06:07 CEST 2009
This algorithm is fairly similar to what currently exists in ALSA with
a few modifications. I'm trying to come up with guaranteed way to play
glitch free audio. Does this algorithm work or could it be modified to
work?
The main change is to track a high resolution timer as the means of
estimating where in the buffer to insert new, low latency data. This
tracking is done in a timer tick interrupt. Jiffies are too coarse and
not all hardware allows you to ask the current DMA position.
The other change is to keep all of the buffers filled with silence if
there isn't any pending data. (not doing this caused problem in my
mpc5200 AC97 driver)
Three buffers are used as a way to deterministically bound the DMA
pointer without needing interrupts.
---
Use three chained buffers.
Buffer size is samples/tick (or maybe 1.5 samples/tick)
Initialize buffers to silence.
Set end of buffer three to automatically terminate DMA
Set FIFO to minimum bus allows
Fill buffer one with samples available, start playing.
On timer tick call into driver..
If buffer one has finished playing move it to third position.
New last buffer is set to automatically stop DMA.
Return swap status to ALSA
If swapped, fill buffer three with silence or pending data
It is important to fill this buffer with silence if there is no pending data
The size of the buffers needs to be large enough to cover worst case
timer tick latency. Buffer two has to be large enough to ensure that
the tick routine will notice buffer one has been played before buffer
three starts.
If two buffers have been completed when the tick runs, let the third
buffer finish without swapping. Since you don't know where you are in
the third buffer, it is unsafe to swap at this point.
Playing the last buffer causes the end of buffer interrupt to happen.
Callback into ALSA to alert it of the underrun and need to restart DMA.
If this callback happens, make the buffers larger.
Long term observation of buffer completion status in tick handler will allow
accurate computation of samples/HPET unit. Record high accuracy timer
(HPET) on tick.
New low latency data that arrives can be inserted into the buffers dynamically.
Use the high resolution timer source to estimate where to place it.
Minimum FIFO ensures low latency play.
Design a minimum power mode.
Allows a huge FIFO to be loaded (like 128KB).
Call into driver to reset to minimum latency, small FIFO mode.
Advantages:
1) If ALSA goes away, hardware will stop on it's own with no noise.
2) No need to know the current position of DMA hardware.
3) Both low and high latency modes.
4) Audio interrupts only generated as error condition
5) Behavior is deterministic. Nothing is left to guess work.
--
Jon Smirl
jonsmirl at gmail.com
More information about the Alsa-devel
mailing list