[pulseaudio-discuss] Handling audio skew during playback
nicholas.wilson at realvnc.com
Wed Sep 20 17:00:22 UTC 2017
I have a question about how PulseAudio expects skew to be handled during playback.
When you make a stream running at 48kHz, does it consume samples at 48kHz as measured by the OS clock (clock_gettime) or as measured by the soundcard's clock?
Suppose that I have a 24-hour audio stream, which has 24 * 3600 * 48000 = 4147200000 samples. It's common for crystal oscillators to have a small inaccuracy (eg 50 parts per million), which is a four-second error after 24 hours.
I'm playing back using PulseAudio's stream API in "push mode", writing data to the PulseAudio stream as it arrives over the network, using pa_stream_write, with enough buffering to ensure no underruns.
If the soundcard has 50ppm error, then after 24 hours it could potentially have consumed 4147407360 samples, ie 207360 samples or 4 seconds' worth of extra samples which have to come from somewhere! Or we could have overflowed the stream's buffer by that much if the soundcard is running slowly.
I could regulate the received audio data against clock_gettime(CLOCK_MONOTONIC), which is the same timing source that PulseAudio uses internally, such that after 24 hours have elapsed (according to that clock), I have fed in 24-hours exactly of samples. Is that enough to satisfy PulseAudio, or do I potentially to stuff in extra samples if the soundcard is running fast (and drop samples if the soundcard is running slow)?
If I were playing an audio file, the rate of playback could of course simply be matched to the soundcard, so that it takes 23:00:56 - 24:00:04 by the wall clock to play a 24-hour file, but when the data arrives at a fixed rate that won't do.
Ultimately I don't mind if either my code or PulseAudio inserts a few skips every 24 hours to "keep up" with the soundcard; in fact that's what I want, a small number of skips to readjust playback for the skew, so that the buffer fill level stays within a good bound, rather than allowing the fill level to drift to the point where underflow or overflow occurs. I already have code to cope with the case where the audio stream I'm receiving drifts relative to the CPU clock - I just don't know whether it's my responsibility s a caller of the API to correct for the case where the local soundcard drifts relative to the local CPU clock, or whether PulseAudio will do it internally, if it notices a discrepancy between the device sample rate and clock_gettime.
Thanks for helping me to understand this,
More information about the pulseaudio-discuss