mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-01 22:58:50 -04:00
alsa-pcm: scale max_error with quantum size
Adjust the max-error between the hardware delay and the quantum. Limit this between 256 and quantum/2 to make sure we are not too sensitive.
This commit is contained in:
parent
e6c2ac3450
commit
9d186cf622
2 changed files with 12 additions and 14 deletions
|
|
@ -1873,6 +1873,7 @@ static inline void check_position_config(struct state *state)
|
||||||
state->duration = state->position->clock.duration;
|
state->duration = state->position->clock.duration;
|
||||||
state->rate_denom = state->position->clock.rate.denom;
|
state->rate_denom = state->position->clock.rate.denom;
|
||||||
state->threshold = (state->duration * state->rate + state->rate_denom-1) / state->rate_denom;
|
state->threshold = (state->duration * state->rate + state->rate_denom-1) / state->rate_denom;
|
||||||
|
state->max_error = SPA_MAX(256.0f, state->threshold / 2.0f);
|
||||||
state->resample = ((uint32_t)state->rate != state->rate_denom) || state->matching;
|
state->resample = ((uint32_t)state->rate != state->rate_denom) || state->matching;
|
||||||
state->alsa_sync = true;
|
state->alsa_sync = true;
|
||||||
}
|
}
|
||||||
|
|
@ -2412,11 +2413,10 @@ int spa_alsa_start(struct state *state)
|
||||||
state->following = is_following(state);
|
state->following = is_following(state);
|
||||||
setup_matching(state);
|
setup_matching(state);
|
||||||
|
|
||||||
|
spa_dll_init(&state->dll);
|
||||||
state->threshold = (state->duration * state->rate + state->rate_denom-1) / state->rate_denom;
|
state->threshold = (state->duration * state->rate + state->rate_denom-1) / state->rate_denom;
|
||||||
state->last_threshold = state->threshold;
|
state->last_threshold = state->threshold;
|
||||||
|
state->max_error = SPA_MAX(256.0f, state->threshold / 2.0f);
|
||||||
spa_dll_init(&state->dll);
|
|
||||||
state->max_error = (256.0 * state->rate) / state->rate_denom;
|
|
||||||
|
|
||||||
spa_log_debug(state->log, "%p: start %d duration:%d rate:%d follower:%d match:%d resample:%d",
|
spa_log_debug(state->log, "%p: start %d duration:%d rate:%d follower:%d match:%d resample:%d",
|
||||||
state, state->threshold, state->duration, state->rate_denom,
|
state, state->threshold, state->duration, state->rate_denom,
|
||||||
|
|
|
||||||
|
|
@ -32,15 +32,13 @@
|
||||||
#include <alsa/asoundlib.h>
|
#include <alsa/asoundlib.h>
|
||||||
|
|
||||||
#include <spa/utils/dll.h>
|
#include <spa/utils/dll.h>
|
||||||
|
#include <spa/utils/defs.h>
|
||||||
|
|
||||||
#define DEFAULT_DEVICE "hw:0"
|
#define DEFAULT_DEVICE "hw:0"
|
||||||
|
|
||||||
#define M_PI_M2 (M_PI + M_PI)
|
#define M_PI_M2 (M_PI + M_PI)
|
||||||
|
|
||||||
#define NSEC_PER_SEC 1000000000ll
|
#define BW_PERIOD (SPA_NSEC_PER_SEC * 3)
|
||||||
#define TIMESPEC_TO_NSEC(ts) ((ts)->tv_sec * NSEC_PER_SEC + (ts)->tv_nsec)
|
|
||||||
|
|
||||||
#define BW_PERIOD (NSEC_PER_SEC * 3)
|
|
||||||
|
|
||||||
struct state {
|
struct state {
|
||||||
const char *device;
|
const char *device;
|
||||||
|
|
@ -65,8 +63,8 @@ struct state {
|
||||||
static int set_timeout(struct state *state, uint64_t time)
|
static int set_timeout(struct state *state, uint64_t time)
|
||||||
{
|
{
|
||||||
struct itimerspec ts;
|
struct itimerspec ts;
|
||||||
ts.it_value.tv_sec = time / NSEC_PER_SEC;
|
ts.it_value.tv_sec = time / SPA_NSEC_PER_SEC;
|
||||||
ts.it_value.tv_nsec = time % NSEC_PER_SEC;
|
ts.it_value.tv_nsec = time % SPA_NSEC_PER_SEC;
|
||||||
ts.it_interval.tv_sec = 0;
|
ts.it_interval.tv_sec = 0;
|
||||||
ts.it_interval.tv_nsec = 0;
|
ts.it_interval.tv_nsec = 0;
|
||||||
return timerfd_settime(state->timerfd, TFD_TIMER_ABSTIME, &ts, NULL);
|
return timerfd_settime(state->timerfd, TFD_TIMER_ABSTIME, &ts, NULL);
|
||||||
|
|
@ -133,12 +131,12 @@ static int on_timer_wakeup(struct state *state)
|
||||||
CHECK(snd_pcm_htimestamp(state->hndl, &avail, &tstamp), "htimestamp");
|
CHECK(snd_pcm_htimestamp(state->hndl, &avail, &tstamp), "htimestamp");
|
||||||
delay = state->buffer_frames - avail;
|
delay = state->buffer_frames - avail;
|
||||||
|
|
||||||
then = TIMESPEC_TO_NSEC(&tstamp);
|
then = SPA_TIMESPEC_TO_NSEC(&tstamp);
|
||||||
if (then != 0) {
|
if (then != 0) {
|
||||||
if (then < state->next_time) {
|
if (then < state->next_time) {
|
||||||
delay -= (state->next_time - then) * state->rate / NSEC_PER_SEC;
|
delay -= (state->next_time - then) * state->rate / SPA_NSEC_PER_SEC;
|
||||||
} else {
|
} else {
|
||||||
delay += (then - state->next_time) * state->rate / NSEC_PER_SEC;
|
delay += (then - state->next_time) * state->rate / SPA_NSEC_PER_SEC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -278,7 +276,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
spa_dll_init(&state.dll);
|
spa_dll_init(&state.dll);
|
||||||
spa_dll_set_bw(&state.dll, SPA_DLL_BW_MAX, state.period, state.rate);
|
spa_dll_set_bw(&state.dll, SPA_DLL_BW_MAX, state.period, state.rate);
|
||||||
state.max_error = 256.0;
|
state.max_error = SPA_MAX(256.0, state.period / 2.0f);
|
||||||
|
|
||||||
if ((state.timerfd = timerfd_create(CLOCK_MONOTONIC, 0)) < 0)
|
if ((state.timerfd = timerfd_create(CLOCK_MONOTONIC, 0)) < 0)
|
||||||
perror("timerfd");
|
perror("timerfd");
|
||||||
|
|
@ -290,7 +288,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
/* set our first timeout for now */
|
/* set our first timeout for now */
|
||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
state.prev_time = state.next_time = TIMESPEC_TO_NSEC(&now);
|
state.prev_time = state.next_time = SPA_TIMESPEC_TO_NSEC(&now);
|
||||||
set_timeout(&state, state.next_time);
|
set_timeout(&state, state.next_time);
|
||||||
|
|
||||||
/* and start playback */
|
/* and start playback */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue