mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-31 22:25:33 -04:00
echo-cancel: Fix calc_diff for asymmetric sample specs
In case that source and sink use different sample specs (e.g., different number of channels) the computation of the latency difference fails. To fix this, we obtain the corresponding latencies in terms of time using the respective sample specs instead of buffer sizes. Signed-off-by: Stefan Huber <s.huber@bct-electronic.com> Acked-by: Peter Meerwald <p.meerwald@bct-electronic.com>
This commit is contained in:
parent
fc9ad93bb4
commit
84e4584322
1 changed files with 20 additions and 16 deletions
|
|
@ -294,34 +294,38 @@ enum {
|
|||
};
|
||||
|
||||
static int64_t calc_diff(struct userdata *u, struct snapshot *snapshot) {
|
||||
int64_t buffer, diff_time, buffer_latency;
|
||||
int64_t diff_time, buffer_latency;
|
||||
pa_usec_t plen, rlen, source_delay, sink_delay, recv_counter, send_counter;
|
||||
|
||||
/* get the number of samples between capture and playback */
|
||||
if (snapshot->plen > snapshot->rlen)
|
||||
buffer = snapshot->plen - snapshot->rlen;
|
||||
/* get latency difference between playback and record */
|
||||
plen = pa_bytes_to_usec(snapshot->plen, &u->sink_input->sample_spec);
|
||||
rlen = pa_bytes_to_usec(snapshot->rlen, &u->source_output->sample_spec);
|
||||
if (plen > rlen)
|
||||
buffer_latency = plen - rlen;
|
||||
else
|
||||
buffer = 0;
|
||||
buffer_latency = 0;
|
||||
|
||||
buffer += snapshot->source_delay + snapshot->sink_delay;
|
||||
source_delay = pa_bytes_to_usec(snapshot->source_delay, &u->source_output->sample_spec);
|
||||
sink_delay = pa_bytes_to_usec(snapshot->sink_delay, &u->sink_input->sample_spec);
|
||||
buffer_latency += source_delay + sink_delay;
|
||||
|
||||
/* add the amount of samples not yet transferred to the source context */
|
||||
if (snapshot->recv_counter <= snapshot->send_counter)
|
||||
buffer += (int64_t) (snapshot->send_counter - snapshot->recv_counter);
|
||||
/* add the latency difference due to samples not yet transferred */
|
||||
send_counter = pa_bytes_to_usec(snapshot->send_counter, &u->sink_input->sample_spec);
|
||||
recv_counter = pa_bytes_to_usec(snapshot->recv_counter, &u->source_output->sample_spec);
|
||||
if (recv_counter <= send_counter)
|
||||
buffer_latency += (int64_t) (send_counter - recv_counter);
|
||||
else
|
||||
buffer += PA_CLIP_SUB(buffer, (int64_t) (snapshot->recv_counter - snapshot->send_counter));
|
||||
buffer_latency += PA_CLIP_SUB(buffer_latency, (int64_t) (recv_counter - send_counter));
|
||||
|
||||
/* convert to time */
|
||||
buffer_latency = pa_bytes_to_usec(buffer, &u->source_output->sample_spec);
|
||||
|
||||
/* capture and playback samples are perfectly aligned when diff_time is 0 */
|
||||
/* capture and playback are perfectly aligned when diff_time is 0 */
|
||||
diff_time = (snapshot->sink_now + snapshot->sink_latency - buffer_latency) -
|
||||
(snapshot->source_now - snapshot->source_latency);
|
||||
|
||||
pa_log_debug("Diff %lld (%lld - %lld + %lld) %lld %lld %lld %lld", (long long) diff_time,
|
||||
(long long) snapshot->sink_latency,
|
||||
(long long) buffer_latency, (long long) snapshot->source_latency,
|
||||
(long long) snapshot->source_delay, (long long) snapshot->sink_delay,
|
||||
(long long) (snapshot->send_counter - snapshot->recv_counter),
|
||||
(long long) source_delay, (long long) sink_delay,
|
||||
(long long) (send_counter - recv_counter),
|
||||
(long long) (snapshot->sink_now - snapshot->source_now));
|
||||
|
||||
return diff_time;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue