[alsa-devel] DMA and delay feedback
Hi,
Would there be benefit in separating the DMA and the transfer of audio samples to the sound card hardware from the delay and hw position feedback. For example, If the playback position is 0, the hardware has probably already transferred one period of the sound card. So, one cannot write to playback position 2 and expect it to be output to the sound card if the period size is 1024.
For transfer purposes, one only needs to know that DMA transfer is complete on period X so that period X can now be over-written. I believe that this is what the DMA interrupt indicates. One needs to reliably detect a missed interrupt. It one took this approach, one might be able to hide the "missed interrupt" problem. When the interrupt finally did arrive, we would know where the next free period X is, and continue writing samples to that, irrespective of what went wrong before. This would allow for auto-recovery of the audio stream without having to stop and start the ring buffers again.
One then needs to determine how one can get accurate "delay" values back from all sound card types. The "delay" value is used for applications like ensuring that audio and video play in sync. The problem ones at the moment appear to be the intel8x0 and hd-audio ones. There may be benefits from making the "delay" value return in nanoseconds instead of samples, particularly if gettimeofdate() is being used to try to produce accurate "delay" values.
Kind Regards
James
For transfer purposes, one only needs to know that DMA transfer is complete on period X so that period X can now be over-written.
That's the 'traditional' view. ALSA is now used in different ways. PulseAudio sets a timer and relies on snd_pcm_avail() to query how many samples it can write to the ring buffer, the notion of period isn't used at all. I think we could use additional information in the way the hw_ptr position is reported, namely hints on how precise this information is and the granularity of the updates. - Pierre
2009/12/14 pl bossart bossart.nospam@gmail.com:
For transfer purposes, one only needs to know that DMA transfer is complete on period X so that period X can now be over-written.
That's the 'traditional' view. ALSA is now used in different ways. PulseAudio sets a timer and relies on snd_pcm_avail() to query how many samples it can write to the ring buffer, the notion of period isn't used at all. I think we could use additional information in the way the hw_ptr position is reported, namely hints on how precise this information is and the granularity of the updates.
- Pierre
There is a problem with getting snd_pcm_avail() accurate from a hardware perspective. I was trying to come up with a method for letting the application (pulseaudio) know how much data it can write in a more accurate fashion. An extra bit of information is also useful, and that is some prediction of when one should next write samples after this write. One then has a sensible value to use for the timer. People use snd_pcm_avail for different tasks, and I was trying to break the use cases out and analyse each one it turn and see if a better API interface could result. The use cases are: 1) Deciding when and how many sample to write and when one is likely to need to write again. 2) Syncing the samples to a video stream or other time source. There are other requiremets: 1) Having the application buffer size different from the hardware buffer size. 2) Having the application sample rate different from the hardware sample rate, and thus doing resampling.
James
2009/12/14 pl bossart bossart.nospam@gmail.com:
For transfer purposes, one only needs to know that DMA transfer is complete on period X so that period X can now be over-written.
That's the 'traditional' view. ALSA is now used in different ways. PulseAudio sets a timer and relies on snd_pcm_avail() to query how many samples it can write to the ring buffer, the notion of period isn't used at all. I think we could use additional information in the way the hw_ptr position is reported, namely hints on how precise this information is and the granularity of the updates.
- Pierre
There is a problem with getting snd_pcm_avail() accurate from a hardware perspective. I was trying to come up with a method for letting the application (pulseaudio) know how much data it can write in a more accurate fashion. An extra bit of information is also useful, and that is some prediction of when one should next write samples after this write. One then has a sensible value to use for the timer. People use snd_pcm_avail for different tasks, and I was trying to break the use cases out and analyse each one it turn and see if a better API interface could result. The use cases are: 1) Deciding when and how many sample to write and when one is likely to need to write again. 2) Syncing the samples to a video stream or other time source. There are other requiremets: 1) Having the application buffer size different from the hardware buffer size. 2) Having the application sample rate different from the hardware sample rate, and thus doing resampling.
James
On Mon, 2009-12-14 at 16:35 +0100, ext James Courtier-Dutton wrote:
2009/12/14 pl bossart bossart.nospam@gmail.com:
For transfer purposes, one only needs to know that DMA transfer is complete on period X so that period X can now be over-written.
That's the 'traditional' view. ALSA is now used in different ways. PulseAudio sets a timer and relies on snd_pcm_avail() to query how many samples it can write to the ring buffer, the notion of period isn't used at all. I think we could use additional information in the way the hw_ptr position is reported, namely hints on how precise this information is and the granularity of the updates.
- Pierre
There is a problem with getting snd_pcm_avail() accurate from a hardware perspective. I was trying to come up with a method for letting the application (pulseaudio) know how much data it can write in a more accurate fashion. An extra bit of information is also useful, and that is some prediction of when one should next write samples after this write. One then has a sensible value to use for the timer. People use snd_pcm_avail for different tasks, and I was trying to break the use cases out and analyse each one it turn and see if a better API interface could result. The use cases are:
- Deciding when and how many sample to write and when one is likely
to need to write again. 2) Syncing the samples to a video stream or other time source. There are other requiremets:
- Having the application buffer size different from the hardware buffer size.
- Having the application sample rate different from the hardware
sample rate, and thus doing resampling.
James
At every DMA IRQ, I guess you may be calling snd_pcm_period_elapsed(). If so, a timestamp is taken that may be polled out with the SNDRV_PCM_IOCTL_TTSTAMP. So comparing the timestamp to the current time gives you the exact 'delta'? (Of course there may be issues such as the call propagation delay (if an IRQ occurs during the ioctl call that takes time) or the DMA IRQ may arrive at the same time with a more high priority IRQ etc, but that's all basics...)
- Eero
2009/12/14 pl bossart bossart.nospam@gmail.com
For transfer purposes, one only needs to know that DMA transfer is complete on period X so that period X can now be over-written.
That's the 'traditional' view. ALSA is now used in different ways. PulseAudio sets a timer and relies on snd_pcm_avail() to query how many samples it can write to the ring buffer, the notion of period isn't used at all. I think we could use additional information in the way the hw_ptr position is reported, namely hints on how precise this information is and the granularity of the updates.
- Pierre
Pulseaudio need more than a timer and relies on snd_pcm_avail() to query how many samples it can write to the ring buffer,
Refer to http://0pointer.de/blog/projects/pulse-glitch-free.html
The third basic idea is to allow rewriting of the hardware buffer at any time. .
For example, If the playback position is 0, the hardware has probably already transferred one period of the sound card. So, one cannot write to playback position 2 and expect it to be output to the sound card if the period size is 1024
Using mmap only can allow writing of the hardware buffer at any time but rewriting of the hardware buffer depend on the two new function snd_pcm_rewind() and snd_pcm_rewindable()
2009/12/14 James Courtier-Dutton james.dutton@gmail.com
Hi,
Would there be benefit in separating the DMA and the transfer of audio samples to the sound card hardware from the delay and hw position feedback. For example, If the playback position is 0, the hardware has probably already transferred one period of the sound card. So, one cannot write to playback position 2 and expect it to be output to the sound card if the period size is 1024.
For transfer purposes, one only needs to know that DMA transfer is complete on period X so that period X can now be over-written. I believe that this is what the DMA interrupt indicates. One needs to reliably detect a missed interrupt. It one took this approach, one might be able to hide the "missed interrupt" problem. When the interrupt finally did arrive, we would know where the next free period X is, and continue writing samples to that, irrespective of what went wrong before. This would allow for auto-recovery of the audio stream without having to stop and start the ring buffers again.
One then needs to determine how one can get accurate "delay" values back from all sound card types.
The accurate "delay" value may be different for different chipsets using the same driver
snd_pcm_rewindable() should provide the value to rewind to the period_boundary , if you want to play the audio as soon as possible , you should reduce the period size
Using software mixing but unwilling to spend CPU time (power saving) and using large period size does not make any sense at all.
The "delay" value is used for applications like ensuring that audio and video play in sync. The problem ones at the moment appear to be the intel8x0 and hd-audio ones. There may be benefits from making the "delay" value return in nanoseconds instead of samples, particularly if gettimeofdate() is being used to try to produce accurate "delay" values.
Kind Regards
James
participants (4)
-
Eero Nurkkala
-
James Courtier-Dutton
-
pl bossart
-
Raymond Yau