mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-02 09:01:46 -05:00
* Increase history set to 64 to simplify reduction of indexes
* Decrease memory consumption a bit by using bitfields for some bools * Rework reduction code * Drop an unnessacary counter * Before adding a new entry to the history, try to figure out if we already have an existing entry with the same x value and replace that. This fixes a division by zero * Fix up input x for all functions, according to the time offset git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/glitch-free@2316 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
563f4b63cd
commit
f49df7a3b0
1 changed files with 42 additions and 32 deletions
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
#include "time-smoother.h"
|
||||
|
||||
#define HISTORY_MAX 50
|
||||
#define HISTORY_MAX 64
|
||||
|
||||
/*
|
||||
* Implementation of a time smoothing algorithm to synchronize remote
|
||||
|
|
@ -61,7 +61,6 @@
|
|||
|
||||
struct pa_smoother {
|
||||
pa_usec_t adjust_time, history_time;
|
||||
pa_bool_t monotonic;
|
||||
|
||||
pa_usec_t time_offset;
|
||||
|
||||
|
|
@ -82,7 +81,9 @@ struct pa_smoother {
|
|||
double a, b, c;
|
||||
pa_bool_t abc_valid;
|
||||
|
||||
pa_bool_t paused;
|
||||
pa_bool_t monotonic:1;
|
||||
pa_bool_t paused:1;
|
||||
|
||||
pa_usec_t pause_time;
|
||||
};
|
||||
|
||||
|
|
@ -122,39 +123,58 @@ void pa_smoother_free(pa_smoother* s) {
|
|||
pa_xfree(s);
|
||||
}
|
||||
|
||||
#define REDUCE(x) \
|
||||
do { \
|
||||
x = (x) % HISTORY_MAX; \
|
||||
} while(FALSE)
|
||||
|
||||
#define REDUCE_INC(x) \
|
||||
do { \
|
||||
x = ((x)+1) % HISTORY_MAX; \
|
||||
} while(FALSE)
|
||||
|
||||
|
||||
static void drop_old(pa_smoother *s, pa_usec_t x) {
|
||||
unsigned j;
|
||||
|
||||
/* First drop items from history which are too old, but make sure
|
||||
* to always keep two entries in the history */
|
||||
/* Drop items from history which are too old, but make sure to
|
||||
* always keep two entries in the history */
|
||||
|
||||
for (j = s->n_history; j > 2; j--) {
|
||||
while (s->n_history > 2) {
|
||||
|
||||
if (s->history_x[s->history_idx] + s->history_time >= x) {
|
||||
if (s->history_x[s->history_idx] + s->history_time >= x)
|
||||
/* This item is still valid, and thus all following ones
|
||||
* are too, so let's quit this loop */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Item is too old, let's drop it */
|
||||
s->history_idx ++;
|
||||
while (s->history_idx >= HISTORY_MAX)
|
||||
s->history_idx -= HISTORY_MAX;
|
||||
REDUCE_INC(s->history_idx);
|
||||
|
||||
s->n_history --;
|
||||
}
|
||||
}
|
||||
|
||||
static void add_to_history(pa_smoother *s, pa_usec_t x, pa_usec_t y) {
|
||||
unsigned j;
|
||||
unsigned j, i;
|
||||
pa_assert(s);
|
||||
|
||||
/* First try to update an existing history entry */
|
||||
i = s->history_idx;
|
||||
for (j = s->n_history; j > 0; j--) {
|
||||
|
||||
if (s->history_x[i] == x) {
|
||||
s->history_y[i] = y;
|
||||
return;
|
||||
}
|
||||
|
||||
REDUCE_INC(i);
|
||||
}
|
||||
|
||||
/* Drop old entries */
|
||||
drop_old(s, x);
|
||||
|
||||
/* Calculate position for new entry */
|
||||
j = s->history_idx + s->n_history;
|
||||
while (j >= HISTORY_MAX)
|
||||
j -= HISTORY_MAX;
|
||||
REDUCE(j);
|
||||
|
||||
/* Fill in entry */
|
||||
s->history_x[j] = x;
|
||||
|
|
@ -166,6 +186,7 @@ static void add_to_history(pa_smoother *s, pa_usec_t x, pa_usec_t y) {
|
|||
/* And make sure we don't store more entries than fit in */
|
||||
if (s->n_history >= HISTORY_MAX) {
|
||||
s->history_idx += s->n_history - HISTORY_MAX;
|
||||
REDUCE(s->history_idx);
|
||||
s->n_history = HISTORY_MAX;
|
||||
}
|
||||
}
|
||||
|
|
@ -185,9 +206,7 @@ static double avg_gradient(pa_smoother *s, pa_usec_t x) {
|
|||
ay += s->history_y[i];
|
||||
c++;
|
||||
|
||||
i++;
|
||||
while (i >= HISTORY_MAX)
|
||||
i -= HISTORY_MAX;
|
||||
REDUCE_INC(i);
|
||||
}
|
||||
|
||||
/* Too few measurements, assume gradient of 1 */
|
||||
|
|
@ -210,14 +229,12 @@ static double avg_gradient(pa_smoother *s, pa_usec_t x) {
|
|||
k += dx*dy;
|
||||
t += dx*dx;
|
||||
|
||||
i++;
|
||||
while (i >= HISTORY_MAX)
|
||||
i -= HISTORY_MAX;
|
||||
REDUCE_INC(i);
|
||||
}
|
||||
|
||||
r = (double) k / t;
|
||||
|
||||
return s->monotonic && r < 0 ? 0 : r;
|
||||
return (s->monotonic && r < 0) ? 0 : r;
|
||||
}
|
||||
|
||||
static void estimate(pa_smoother *s, pa_usec_t x, pa_usec_t *y, double *deriv) {
|
||||
|
|
@ -305,14 +322,12 @@ void pa_smoother_put(pa_smoother *s, pa_usec_t x, pa_usec_t y) {
|
|||
double nde;
|
||||
|
||||
pa_assert(s);
|
||||
pa_assert(x >= s->time_offset);
|
||||
|
||||
/* Fix up x value */
|
||||
if (s->paused)
|
||||
x = s->pause_time;
|
||||
|
||||
pa_assert(x >= s->time_offset);
|
||||
x -= s->time_offset;
|
||||
x = PA_LIKELY(x >= s->time_offset) ? x - s->time_offset : 0;
|
||||
|
||||
pa_assert(x >= s->ex);
|
||||
|
||||
|
|
@ -340,15 +355,12 @@ pa_usec_t pa_smoother_get(pa_smoother *s, pa_usec_t x) {
|
|||
pa_usec_t y;
|
||||
|
||||
pa_assert(s);
|
||||
pa_assert(x >= s->time_offset);
|
||||
|
||||
/* Fix up x value */
|
||||
if (s->paused)
|
||||
x = s->pause_time;
|
||||
|
||||
pa_assert(x >= s->time_offset);
|
||||
x -= s->time_offset;
|
||||
|
||||
x = PA_LIKELY(x >= s->time_offset) ? x - s->time_offset : 0;
|
||||
pa_assert(x >= s->ex);
|
||||
|
||||
estimate(s, x, &y, NULL);
|
||||
|
|
@ -397,14 +409,12 @@ pa_usec_t pa_smoother_translate(pa_smoother *s, pa_usec_t x, pa_usec_t y_delay)
|
|||
double nde;
|
||||
|
||||
pa_assert(s);
|
||||
pa_assert(x >= s->time_offset);
|
||||
|
||||
/* Fix up x value */
|
||||
if (s->paused)
|
||||
x = s->pause_time;
|
||||
|
||||
pa_assert(x >= s->time_offset);
|
||||
x -= s->time_offset;
|
||||
x = PA_LIKELY(x >= s->time_offset) ? x - s->time_offset : 0;
|
||||
|
||||
pa_assert(x >= s->ex);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue