From 05ca59ed48643c3e12d3f8512bd17d386592870a Mon Sep 17 00:00:00 2001 From: Chris Spencer Date: Sun, 30 Jan 2022 13:53:46 +0000 Subject: [PATCH] [client] audio/pw: increase startup latency PipeWire startup latency varies wildly depending on what else is, or was last using the audio device. In the worst case, PipeWire can request two full buffers within a very short period of time immediately at the start of playback, so make sure we've got enough data in the buffer to support this. --- client/audiodevs/PipeWire/pipewire.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/client/audiodevs/PipeWire/pipewire.c b/client/audiodevs/PipeWire/pipewire.c index 90b757e2..d8b36720 100644 --- a/client/audiodevs/PipeWire/pipewire.c +++ b/client/audiodevs/PipeWire/pipewire.c @@ -51,7 +51,7 @@ struct PipeWire int sampleRate; int stride; LG_AudioPullFn pullFn; - int startFrames; + int maxPeriodFrames; StreamState state; } @@ -196,7 +196,7 @@ static void pipewire_playbackSetup(int channels, int sampleRate, pw.playback.channels == channels && pw.playback.sampleRate == sampleRate) { - *maxPeriodFrames = pw.playback.startFrames; + *maxPeriodFrames = pw.playback.maxPeriodFrames; return; } @@ -253,12 +253,12 @@ static void pipewire_playbackSetup(int channels, int sampleRate, pw_stream_update_properties(pw.playback.stream, &SPA_DICT_INIT_ARRAY(items)); - pw.playback.startFrames = defaultLatencyFrames; + pw.playback.maxPeriodFrames = defaultLatencyFrames; } else - pw.playback.startFrames = num; + pw.playback.maxPeriodFrames = num; - *maxPeriodFrames = pw.playback.startFrames; + *maxPeriodFrames = pw.playback.maxPeriodFrames; if (!pw.playback.stream) { @@ -301,8 +301,12 @@ static bool pipewire_playbackStart(int framesBuffered) switch (pw.playback.state) { case STREAM_STATE_INACTIVE: - if (framesBuffered >= max(pw.playback.startFrames, - pw.playback.sampleRate / 20)) //50ms + // PipeWire startup latency varies wildly depending on what else is, or + // was last using the audio device. In the worst case, PipeWire can + // request two full buffers within a very short period of time + // immediately at the start of playback, so make sure we've got enough + // data in the buffer to support this + if (framesBuffered >= pw.playback.maxPeriodFrames * 2) { pw_stream_set_active(pw.playback.stream, true); pw.playback.state = STREAM_STATE_ACTIVE;