mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
alsa: improve resync
Use the max error to do a resync. Don't reset the dll, there is no reason for that. Don't use _rewind, but instead limit the amount of samples we read and write Should keep more stable sync in most cases.
This commit is contained in:
parent
87f4726164
commit
761199be70
1 changed files with 23 additions and 23 deletions
|
|
@ -1775,7 +1775,13 @@ static int update_time(struct state *state, uint64_t current_time, snd_pcm_sfram
|
|||
state, follower, state->last_threshold, state->threshold, diff, err);
|
||||
state->last_threshold = state->threshold;
|
||||
}
|
||||
err = SPA_CLAMP(err, -state->max_error, state->max_error);
|
||||
if (err > state->max_error) {
|
||||
err = state->max_error;
|
||||
state->alsa_sync = true;
|
||||
} else if (err < -state->max_error) {
|
||||
err = -state->max_error;
|
||||
state->alsa_sync = true;
|
||||
}
|
||||
|
||||
if (!follower || state->matching)
|
||||
corr = spa_dll_update(&state->dll, err);
|
||||
|
|
@ -1789,10 +1795,10 @@ static int update_time(struct state *state, uint64_t current_time, snd_pcm_sfram
|
|||
state->base_time = state->next_time;
|
||||
|
||||
spa_log_debug(state->log, "%s: follower:%d match:%d rate:%f "
|
||||
"bw:%f thr:%u del:%ld target:%ld err:%f",
|
||||
"bw:%f thr:%u del:%ld target:%ld err:%f max:%f",
|
||||
state->props.device, follower, state->matching,
|
||||
corr, state->dll.bw, state->threshold, delay, target,
|
||||
err);
|
||||
err, state->max_error);
|
||||
}
|
||||
|
||||
if (state->rate_match) {
|
||||
|
|
@ -1862,12 +1868,14 @@ int spa_alsa_write(struct state *state)
|
|||
{
|
||||
snd_pcm_t *hndl = state->hndl;
|
||||
const snd_pcm_channel_area_t *my_areas;
|
||||
snd_pcm_uframes_t written, frames, offset, off, to_write, total_written;
|
||||
snd_pcm_uframes_t written, frames, offset, off, to_write, total_written, max_write;
|
||||
snd_pcm_sframes_t commitres;
|
||||
int res = 0;
|
||||
|
||||
check_position_config(state);
|
||||
|
||||
max_write = state->buffer_frames;
|
||||
|
||||
if (state->following && state->alsa_started) {
|
||||
uint64_t current_time;
|
||||
snd_pcm_uframes_t delay, target;
|
||||
|
|
@ -1877,22 +1885,16 @@ int spa_alsa_write(struct state *state)
|
|||
if (SPA_UNLIKELY((res = get_status(state, current_time, &delay, &target)) < 0))
|
||||
return res;
|
||||
|
||||
if (SPA_UNLIKELY(!state->alsa_recovering && (delay < target / 2 || delay > 2 * target))) {
|
||||
spa_dll_init(&state->dll);
|
||||
state->alsa_sync = true;
|
||||
}
|
||||
if (SPA_UNLIKELY(state->alsa_sync)) {
|
||||
spa_log_warn(state->log, "%s: follower delay:%ld target:%ld thr:%u, resync",
|
||||
state->props.device, delay, target, state->threshold);
|
||||
target += state->threshold / 2;
|
||||
if (delay > target)
|
||||
snd_pcm_rewind(state->hndl, delay - target);
|
||||
else
|
||||
max_write = delay - target;
|
||||
else if (delay < target)
|
||||
spa_alsa_silence(state, target - delay);
|
||||
delay = target;
|
||||
state->alsa_sync = false;
|
||||
}
|
||||
|
||||
if (SPA_UNLIKELY((res = update_time(state, current_time, delay, target, true)) < 0))
|
||||
return res;
|
||||
}
|
||||
|
|
@ -1900,8 +1902,8 @@ int spa_alsa_write(struct state *state)
|
|||
total_written = 0;
|
||||
again:
|
||||
|
||||
frames = state->buffer_frames;
|
||||
if (state->use_mmap) {
|
||||
frames = max_write;
|
||||
if (state->use_mmap && frames > 0) {
|
||||
if (SPA_UNLIKELY((res = snd_pcm_mmap_begin(hndl, &my_areas, &offset, &frames)) < 0)) {
|
||||
spa_log_error(state->log, "%s: snd_pcm_mmap_begin error: %s",
|
||||
state->props.device, snd_strerror(res));
|
||||
|
|
@ -2099,7 +2101,7 @@ push_frames(struct state *state,
|
|||
int spa_alsa_read(struct state *state)
|
||||
{
|
||||
snd_pcm_t *hndl = state->hndl;
|
||||
snd_pcm_uframes_t total_read = 0, to_read;
|
||||
snd_pcm_uframes_t total_read = 0, to_read, max_read;
|
||||
const snd_pcm_channel_area_t *my_areas;
|
||||
snd_pcm_uframes_t read, frames, offset;
|
||||
snd_pcm_sframes_t commitres;
|
||||
|
|
@ -2123,6 +2125,8 @@ int spa_alsa_read(struct state *state)
|
|||
}
|
||||
}
|
||||
|
||||
max_read = state->buffer_frames;
|
||||
|
||||
if (state->following && state->alsa_started) {
|
||||
uint64_t current_time;
|
||||
snd_pcm_uframes_t delay, target;
|
||||
|
|
@ -2133,16 +2137,11 @@ int spa_alsa_read(struct state *state)
|
|||
if ((res = get_status(state, current_time, &delay, &target)) < 0)
|
||||
return res;
|
||||
|
||||
if (!state->alsa_recovering && delay > target * 2) {
|
||||
spa_dll_init(&state->dll);
|
||||
state->alsa_sync = true;
|
||||
}
|
||||
if (state->alsa_sync) {
|
||||
spa_log_warn(state->log, "%s: follower delay:%lu target:%lu thr:%u, resync",
|
||||
state->props.device, delay, target, threshold);
|
||||
target += threshold / 2;
|
||||
if (delay < target)
|
||||
snd_pcm_rewind(state->hndl, target - delay);
|
||||
max_read = target - delay;
|
||||
else if (delay > target)
|
||||
snd_pcm_forward(state->hndl, delay - target);
|
||||
delay = target;
|
||||
|
|
@ -2151,11 +2150,12 @@ int spa_alsa_read(struct state *state)
|
|||
|
||||
if ((res = update_time(state, current_time, delay, target, true)) < 0)
|
||||
return res;
|
||||
|
||||
if (delay < state->read_size)
|
||||
state->read_size = 0;
|
||||
max_read = 0;
|
||||
}
|
||||
|
||||
frames = state->read_size;
|
||||
frames = SPA_MIN(max_read, state->read_size);
|
||||
|
||||
if (state->use_mmap) {
|
||||
to_read = state->buffer_frames;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue