Dne 09. 03. 20 v 21:29 Ruslan Bilovol napsal(a):
When doing loopback between two audio card with same sampling frequency, I noticed slow increase of pitch_diff.
When I changed order of get_queued_playback_samples() vs get_queued_capture_samples(), I noticed same drift of pitch_diff but if was decreasing this time.
This seems to be caused by non-atomic consecutive snd_pcm_delay() invocation for playback then for capture. snd_pcm_delay() measures delay between read/write call and actual ADC/DAC operation.
So while we get this value for playback path in get_queued_playback_samples(), next call to get_queued_capture_samples() will happen a little bit later so snd_pcm_delay() may return incorrect value.
Be interleaving get_queued_{playback,capture}_samples() order, we divide this small error between playback and capture paths. I do not see any issues anymore with one-way drift of pitch_diff.
Signed-off-by: Ruslan Bilovol ruslan.bilovol@gmail.com
Nice catch and implementation. Applied.
Thank you, Jaroslav
alsaloop/pcmjob.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/alsaloop/pcmjob.c b/alsaloop/pcmjob.c index b252486..1b7925a 100644 --- a/alsaloop/pcmjob.c +++ b/alsaloop/pcmjob.c @@ -1951,8 +1951,16 @@ int pcmjob_pollfds_handle(struct loopback *loop, struct pollfd *fds) } if (loop->sync != SYNC_TYPE_NONE) { snd_pcm_sframes_t pqueued, cqueued;
pqueued = get_queued_playback_samples(loop);
cqueued = get_queued_capture_samples(loop);
/* Reduce cumulative error by interleaving playback vs capture reading order */
if (loop->total_queued_count & 1) {
pqueued = get_queued_playback_samples(loop);
cqueued = get_queued_capture_samples(loop);
} else {
cqueued = get_queued_capture_samples(loop);
pqueued = get_queued_playback_samples(loop);
}
- if (verbose > 4) snd_output_printf(loop->output, "%s: queued %li/%li samples\n", loop->id, pqueued, cqueued); if (pqueued > 0)