On Sat, Nov 07, 2009 at 11:51:16AM -0700, Grant Likely wrote:
On Sat, Nov 7, 2009 at 5:51 AM, Jon Smirl jonsmirl@gmail.com wrote:
current period. My understanding of ALSA is that the application is supposed to make sure there is enough silence in the buffer to handle the lag between notification that the last period with valid data has been played out and the stop trigger.
This is certainly the most robust approach for applications. For a large proportion of hardware it won't matter too much since they're able to shut down the audio very quickly but that can't be entirely relied upon, especially at higher rates on slower machines.
occur. That says to me that the real problem is an unbounded latency caused by another part of the kernel (the tty console in this case).
That's certainly not going to help anything here - if a delay is introduced in telling the hardware to shut down the DMA then that increases the chance for the DMA controller to start pushing valid audio data from the buffer to the audio interface.
A much cleaner solution would be for ALSA to provide a field that indicates the last valid address in the ring buffer system. Then in the driver's buffer complete callback I could get that value and reprogram the DMA engine not to run off the end of valid data. As each buffer completes I would reread the value and update the DMA stop address. You also need the last valid address field when DMA is first started.
... assuming that audio needs to stop exactly at the end of valid data. But if the last few periods are silence, then this assumption isn't true.
Indeed, it makes the whole thing much more reliable.
Providing a final valid data point to the driver would possibly even make things worse since if it were used then you'd have the equivalent race where the application has initialised some data but not yet managed to update the driver to tell it it's being handed over; if the driver just carries on running through the data there's a reasonable chance nobody will notice that case.