mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
alsa: correct dll error after quantum change
When the quantum is changed, the error between the current and expected buffer levels needs to be corrected with the quantum difference. For example, say we are running with a 1024 quantum and the quantum is changed to 8192, when we wake up the filled level might be 1016 vs expected 8192, 1024 - 8192 = -7168. The real error for the timeout was 1016 - 8192 - (-7168) = -8.
This commit is contained in:
parent
ffeb2e0f0e
commit
2c1f8af2e6
1 changed files with 11 additions and 9 deletions
|
|
@ -856,29 +856,31 @@ static int update_time(struct state *state, uint64_t nsec, snd_pcm_sframes_t del
|
|||
snd_pcm_sframes_t target, bool follower)
|
||||
{
|
||||
double err, corr;
|
||||
int32_t diff;
|
||||
|
||||
if (state->stream == SND_PCM_STREAM_PLAYBACK)
|
||||
err = delay - target;
|
||||
else
|
||||
err = target - delay;
|
||||
|
||||
err = SPA_CLAMP(err, -state->max_error, state->max_error);
|
||||
|
||||
if (SPA_UNLIKELY(state->dll.bw == 0.0)) {
|
||||
spa_dll_set_bw(&state->dll, SPA_DLL_BW_MAX, state->threshold, state->rate);
|
||||
state->next_time = nsec;
|
||||
state->base_time = nsec;
|
||||
}
|
||||
corr = spa_dll_update(&state->dll, err);
|
||||
diff = (int32_t) (state->last_threshold - state->threshold);
|
||||
|
||||
if (SPA_UNLIKELY(state->last_threshold != state->threshold)) {
|
||||
int32_t diff = (int32_t) (state->last_threshold - state->threshold);
|
||||
spa_log_trace(state->log, NAME" %p: follower:%d quantum change %d -> %d (%d)",
|
||||
state, follower, state->last_threshold, state->threshold, diff);
|
||||
if (diff < 0)
|
||||
state->next_time += diff / corr * 1e9 / state->rate;
|
||||
if (SPA_UNLIKELY(diff != 0)) {
|
||||
err -= diff;
|
||||
spa_log_trace(state->log, NAME" %p: follower:%d quantum change %d -> %d (%d) %f",
|
||||
state, follower, state->last_threshold, state->threshold, diff, err);
|
||||
state->last_threshold = state->threshold;
|
||||
}
|
||||
err = SPA_CLAMP(err, -state->max_error, state->max_error);
|
||||
corr = spa_dll_update(&state->dll, err);
|
||||
|
||||
if (diff < 0)
|
||||
state->next_time += diff / corr * 1e9 / state->rate;
|
||||
|
||||
if (SPA_UNLIKELY((state->next_time - state->base_time) > BW_PERIOD)) {
|
||||
state->base_time = state->next_time;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue