mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-11-10 00:55:42 +01:00
alsaloop: reduce cumulative error caused by non-atomic samples calculation
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> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
f31f5df42a
commit
ec8717d588
1 changed files with 10 additions and 2 deletions
|
@ -1951,8 +1951,16 @@ int pcmjob_pollfds_handle(struct loopback *loop, struct pollfd *fds)
|
||||||
}
|
}
|
||||||
if (loop->sync != SYNC_TYPE_NONE) {
|
if (loop->sync != SYNC_TYPE_NONE) {
|
||||||
snd_pcm_sframes_t pqueued, cqueued;
|
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)
|
if (verbose > 4)
|
||||||
snd_output_printf(loop->output, "%s: queued %li/%li samples\n", loop->id, pqueued, cqueued);
|
snd_output_printf(loop->output, "%s: queued %li/%li samples\n", loop->id, pqueued, cqueued);
|
||||||
if (pqueued > 0)
|
if (pqueued > 0)
|
||||||
|
|
Loading…
Reference in a new issue