[alsa-devel] Keyclick latency
Hello,
I am working on an embedded device which does audio playback. Now when the user presses a key, we want to play a tone to provide a keyclick feedback to the user.
What we always did (we were using OSS before) was pretty much the simplest thing possible which is for the application to: -stop sending playback samples -send the keyclick samples -resume sending the playback samples
With our new hardware this approach does not produce good results because of the size of the device's ringbuffer. The larger buffer introduces a significant latency issue for the user feedback. Reducing the ring buffer size is not a viable option to ensure no underruns are generated on the system.
Now I was wondering if there a good approach for this using alsa. Checking the api, a simple solution would be to: -call snd_pcm_drop -send the keyclick samples -resume sending the playback samples
I've tried this and the latency is good, unfortunately there is the drawback that some samples were dropped. So I guess the application could : -keep a copy of the samples sent, -check the amount of samples left in the ringbuffer before calling snd_pcm_drop, -send the keyclick -resend dropped samples -resume sending the playback samples
Seems a little overcomplicated so I was wondering if I was missing something. Would there be a simpler approach? Something like pausing the stream or reading the contents of the ringbuffer before dropping.
Thanks Marc
Marc-André Hébert wrote:
I am working on an embedded device which does audio playback. Now when the user presses a key, we want to play a tone to provide a keyclick feedback to the user.
What we always did (we were using OSS before) was pretty much the simplest thing possible which is for the application to: -stop sending playback samples -send the keyclick samples -resume sending the playback samples
With our new hardware this approach does not produce good results because of the size of the device's ringbuffer. The larger buffer introduces a significant latency issue for the user feedback. Reducing the ring buffer size is not a viable option to ensure no underruns are generated on the system. [...] Would there be a simpler approach? Something like pausing the stream or reading the contents of the ringbuffer before dropping.
Depending on what plugins sits between your application and the hardware, your ALSA device might support snd_pcm_rewind()/ snd_pcm_forward(). Please note that rewinding will increase the chance of an underrun (just like a smaller buffer), so you might want to disable xrun detection (which means that instead of stopping, the old buffer data will be played in place of the beginning of the click).
Regards, Clemens
participants (2)
-
Clemens Ladisch
-
Marc-André Hébert