mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
alsa: scale the default period with the rate
The default period is based on the default rate and might be too small when using high samplerates. Scale the rate with the samplerate and make sure it's a power of 2 to avoid trouble. Fixes #3444
This commit is contained in:
parent
9f30e58ef2
commit
d2c29760e9
1 changed files with 17 additions and 3 deletions
|
|
@ -1349,6 +1349,17 @@ static int enum_dsd_formats(struct state *state, uint32_t index, uint32_t *next,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* find smaller power of 2 */
|
||||
static uint32_t flp2(uint32_t x)
|
||||
{
|
||||
x = x | (x >> 1);
|
||||
x = x | (x >> 2);
|
||||
x = x | (x >> 4);
|
||||
x = x | (x >> 8);
|
||||
x = x | (x >> 16);
|
||||
return x - (x >> 1);
|
||||
}
|
||||
|
||||
int
|
||||
spa_alsa_enum_format(struct state *state, int seq, uint32_t start, uint32_t num,
|
||||
const struct spa_pod *filter)
|
||||
|
|
@ -1426,6 +1437,7 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_
|
|||
unsigned int periods;
|
||||
bool match = true, planar = false, is_batch;
|
||||
char spdif_params[128] = "";
|
||||
uint32_t default_period;
|
||||
|
||||
spa_log_debug(state->log, "opened:%d format:%d started:%d", state->opened,
|
||||
state->have_format, state->started);
|
||||
|
|
@ -1651,12 +1663,14 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_
|
|||
period_size = state->default_period_size;
|
||||
is_batch = snd_pcm_hw_params_is_batch(params) && !state->disable_batch;
|
||||
|
||||
default_period = flp2(SPA_SCALE32_UP(DEFAULT_PERIOD, state->rate, DEFAULT_RATE));
|
||||
|
||||
/* no period size specified. If we are batch or not using timers,
|
||||
* use the graph duration as the period */
|
||||
if (period_size == 0 && (is_batch || state->disable_tsched))
|
||||
period_size = state->position ? state->position->clock.target_duration : DEFAULT_PERIOD;
|
||||
period_size = state->position ? state->position->clock.target_duration : default_period;
|
||||
if (period_size == 0)
|
||||
period_size = DEFAULT_PERIOD;
|
||||
period_size = default_period;
|
||||
|
||||
if (!state->disable_tsched) {
|
||||
if (is_batch) {
|
||||
|
|
@ -1664,7 +1678,7 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_
|
|||
* the period smaller and add one period of headroom. Limit the
|
||||
* period size to our default so that we don't create too much
|
||||
* headroom. */
|
||||
period_size = SPA_MIN(period_size, DEFAULT_PERIOD) / 2;
|
||||
period_size = SPA_MIN(period_size, default_period) / 2;
|
||||
} else {
|
||||
/* disable ALSA wakeups */
|
||||
if (snd_pcm_hw_params_can_disable_period_wakeup(params))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue