On Wed, Jun 24, 2009 at 11:24 AM, Takashi Iwaitiwai@suse.de wrote:
At Wed, 24 Jun 2009 11:14:33 -0400, Jon Smirl wrote:
On Wed, Jun 24, 2009 at 10:39 AM, Takashi Iwaitiwai@suse.de wrote:
The glitch-free problem of PA comes from the fact that PA assumes that the driver returns the current hw position accurately at any time. But, in many hardwares, including HDA, this is not true. The hardware lies. It doesn't report the right position at all. Thus, there are many workarounds implemented in HD-audio side.
Why does pulse need to know the DMA position?
If it is so that it can write into the buffer with minimal latency there are other ways to accomplish that. The simplest is to just add an entry into ALSA core that says, play this buffer with minimal latency. That would let the transfer be pushed down into the specific driver and that driver could handle it in an optimal way.
To get a minimum latency, you need to program the sound hardware to notify that. And, most hardware can't do anything but issue IRQs periodically at buffer, fragment or period or whatever boundary.
Instead of the hardware irqs (that can wake up too often), PA uses the timer. Then it must check the position because the clock on the hardware isn't quite accurate and very likely you'll get a drift sooner or later if you use the other timer source.
Pulse should not need to mess with this. Doesn't pulse need to do just two things? 1) play this buffer as soon as possible - abandon previously queued samples 2) ALSA call back saying I have room for more data in my queue 2a) ALSA call back saying underrun happen
When pulse gets new low latency data from a client app, it should make a new buffer, call into ALSA core and say, play this buffer ASAP. This new buffer would replace the old one. Pulse does not need to know where the DMA pointer is or mess with timers. Messing with those should be internal to ALSA and it's drivers. The ring buffer hardware model should not be exposed to pulse, especially since not all hardware has ring buffers.
Inside ALSA this play-ASAP buffer should just be passed into the driver. Only the driver really know how to play something ASAP. The implementation of play-ASAP will be quite different on ring buffer hardware, scatter/gather DMA hardware or hardware that needs indirect access to the buffer.
Trying to directly expose the ring buffer to the app seems like a good way to avoid a copy, but it isn't achieving that. pulse is not decoding audio straight into the ring buffer, it decodes first and then copies into the buffer. Pulse is using the timers to estimate the destination for the copy. Move this copy down into the drivers, the drivers know the correct destination for the copy.
Yes, there can be optimizations for hardwares that are capable to notify any free size chunks. This is a missing piece.
Optimal on my hardware would be to reprogram the DMA hardware to immediately start playing from the new buffer. No copies involved. The FIFO will hide the buffer swap from the audio hardware.
Yes. But it's rather a rare case that you can do such an operation.
Optimal on ring buffer hardware would be to locate where DMA was in the ring and copy to a position in front of it.
That's exactly what PA does. But you must know where to copy beforehand. And the hardware lies where is the current position.
Takashi