mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
alsa-pcm: add support for api.alsa.dll-bandwidth-max
In USB Audio Class 2 (UAC2) setups, pitch control is handled by feedback endpoints. The host adjusts its data rate accordingly. When pitch control is active (pitch_elem), applying the default delay-locked loop (DLL) bandwidth can lead to instability and oscillations around the target rate. This patch adds a new parameter, api.alsa.dll-bandwidth-max, to configure the maximum DLL bandwidth. It introduces a new field in the ALSA state to store this value. By default, it uses SPA_DLL_BW_MAX, but when pitch control is in use, setting it to a lower value (e.g. 0.02) helps ensure better stability, based on empirical testing.
This commit is contained in:
parent
deb7dddbef
commit
8aa836d588
3 changed files with 13 additions and 2 deletions
|
|
@ -778,6 +778,12 @@ Setting this to 0 makes htimestamp never get disabled.
|
|||
Disable timer-based scheduling, and use IRQ for scheduling instead.
|
||||
The "Pro Audio" profile will usually enable this setting, if it is expected it works on the hardware.
|
||||
|
||||
@PAR@ node-prop api.alsa.dll-bandwidth-max # double
|
||||
Sets the maximum bandwidth of the DLL (delay-locked loop) filter used to smooth out rate adjustments.
|
||||
The default value may be too responsive in some scenarios.
|
||||
For example, with UAC2 pitch control, the host reacts more slowly compared to local resampling,
|
||||
so using a lower bandwidth helps avoid oscillations or instability.
|
||||
|
||||
@PAR@ node-prop api.alsa.auto-link = false # boolean
|
||||
Link follower PCM devices to the driver PCM device when using IRQ-based scheduling.
|
||||
The "Pro Audio" profile will usually enable this setting, if it is expected it works on the hardware.
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
static struct spa_list cards = SPA_LIST_INIT(&cards);
|
||||
static struct spa_list states = SPA_LIST_INIT(&states);
|
||||
#define SPA_ALSA_DLL_BW_MIN 0.001
|
||||
|
||||
static struct card *find_card(uint32_t index)
|
||||
{
|
||||
|
|
@ -198,6 +199,9 @@ static int alsa_set_param(struct state *state, const char *k, const char *s)
|
|||
state->disable_batch = spa_atob(s);
|
||||
} else if (spa_streq(k, "api.alsa.disable-tsched")) {
|
||||
state->disable_tsched = spa_atob(s);
|
||||
} else if (spa_streq(k, "api.alsa.dll-bandwidth-max")) {
|
||||
state->dll_bw_max = SPA_CLAMPD(spa_strtod(s, NULL),
|
||||
SPA_ALSA_DLL_BW_MIN, SPA_DLL_BW_MAX);
|
||||
} else if (spa_streq(k, "api.alsa.use-chmap")) {
|
||||
state->props.use_chmap = spa_atob(s);
|
||||
} else if (spa_streq(k, "api.alsa.multi-rate")) {
|
||||
|
|
@ -2799,7 +2803,7 @@ static int update_time(struct state *state, uint64_t current_time, snd_pcm_sfram
|
|||
int32_t diff;
|
||||
|
||||
if (SPA_UNLIKELY(state->dll.bw == 0.0)) {
|
||||
spa_dll_set_bw(&state->dll, SPA_DLL_BW_MAX, state->threshold, state->rate);
|
||||
spa_dll_set_bw(&state->dll, state->dll_bw_max, state->threshold, state->rate);
|
||||
state->next_time = current_time;
|
||||
state->base_time = current_time;
|
||||
}
|
||||
|
|
@ -2862,7 +2866,7 @@ static int update_time(struct state *state, uint64_t current_time, snd_pcm_sfram
|
|||
err, state->max_error, state->max_resync, state->err_avg, state->err_var, bw);
|
||||
|
||||
spa_dll_set_bw(&state->dll,
|
||||
SPA_CLAMPD(bw, 0.001, SPA_DLL_BW_MAX),
|
||||
SPA_CLAMPD(bw, SPA_ALSA_DLL_BW_MIN, state->dll_bw_max),
|
||||
state->threshold, state->rate);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -244,6 +244,7 @@ struct state {
|
|||
uint64_t underrun;
|
||||
|
||||
struct spa_dll dll;
|
||||
double dll_bw_max;
|
||||
double max_error;
|
||||
double max_resync;
|
||||
double err_avg, err_var, err_wdw;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue