alsa: add start-delay parameters to sink

The start-delay adds extra silence to the buffer before starting the
playback. The idea is to have more time to adapt to the device
startup and set the timer more accurately.

See #983, #431
This commit is contained in:
Wim Taymans 2021-03-29 13:20:14 +02:00
parent fda565864c
commit 80ce2c94ac
4 changed files with 10 additions and 5 deletions

View file

@ -801,6 +801,8 @@ impl_init(const struct spa_handle_factory *factory,
this->default_period_size = atoi(s);
} else if (!strcmp(k, "api.alsa.headroom")) {
this->default_headroom = atoi(s);
} else if (!strcmp(k, "api.alsa.start-delay")) {
this->default_start_delay = atoi(s);
} else if (!strcmp(k, "api.alsa.disable-mmap")) {
this->disable_mmap = (strcmp(s, "true") == 0 || atoi(s) == 1);
} else if (!strcmp(k, "api.alsa.disable-batch")) {

View file

@ -628,20 +628,21 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_
state->headroom += period_size;
state->headroom = SPA_MIN(state->headroom, state->buffer_frames);
state->start_delay = state->default_start_delay;
state->period_frames = period_size;
periods = state->buffer_frames / state->period_frames;
spa_log_info(state->log, NAME" %s (%s): format:%s access:%s-%s rate:%d channels:%d "
"buffer frames %lu, period frames %lu, periods %u, frame_size %zd "
"headroom %u",
"headroom %u start-delay:%u",
state->props.device,
state->stream == SND_PCM_STREAM_CAPTURE ? "capture" : "playback",
snd_pcm_format_name(state->format),
state->use_mmap ? "mmap" : "rw",
planar ? "planar" : "interleaved",
state->rate, state->channels, state->buffer_frames, state->period_frames,
periods, state->frame_size, state->headroom);
periods, state->frame_size, state->headroom, state->start_delay);
/* write the parameters to device */
CHECK(snd_pcm_hw_params(hndl, params), "set_hw_params");
@ -807,7 +808,7 @@ recover:
state->alsa_started = false;
if (state->stream == SND_PCM_STREAM_PLAYBACK)
spa_alsa_silence(state, state->last_threshold * 2 + state->headroom);
spa_alsa_silence(state, state->start_delay + state->threshold * 2 + state->headroom);
return do_start(state);
}
@ -829,7 +830,6 @@ static int get_status(struct state *state, snd_pcm_uframes_t *delay, snd_pcm_ufr
state->alsa_recovering = false;
}
*target = state->threshold + state->headroom;
if (state->resample && state->rate_match) {
@ -1481,7 +1481,7 @@ int spa_alsa_start(struct state *state)
state->alsa_started = false;
if (state->stream == SND_PCM_STREAM_PLAYBACK)
spa_alsa_silence(state, state->threshold * 2 + state->headroom);
spa_alsa_silence(state, state->start_delay + state->threshold * 2 + state->headroom);
if ((err = do_start(state)) < 0)
return err;

View file

@ -113,6 +113,7 @@ struct state {
uint32_t default_period_size;
uint32_t default_headroom;
uint32_t default_start_delay;
uint32_t default_format;
unsigned int default_channels;
unsigned int default_rate;
@ -153,6 +154,7 @@ struct state {
uint32_t threshold;
uint32_t last_threshold;
uint32_t headroom;
uint32_t start_delay;
uint32_t duration;
uint32_t last_duration;

View file

@ -97,6 +97,7 @@ rules = [
#audio.position = "FL,FR"
#api.alsa.period-size = 1024
#api.alsa.headroom = 0
#api.alsa.start-delay = 0
#api.alsa.disable-mmap = false
#api.alsa.disable-batch = false
#api.alsa.use-chmap = false