You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
On a live format renegotiation (FLAC 48 kHz/16-bit -> 192 kHz/24-bit) mid-session, the
output sink reconfigures to the new format but no codec header is ever processed for
it. The player then loses sync and fails to place audio chunks for the rest of that
stream. It does not self-recover: audio stayed audibly wrong until a manual pause/play,
which tore the stream down and started a new one that did process a codec header and
then played correctly.
Environment
sendspin-cli
0.1.4, commit 52d0f2c (release artifact linux-arm64, CI run 33119241602)
sendspin-cpp
v0.7.2
Host
Raspberry Pi 5, Debian 13 (trixie), aarch64, kernel 6.12.47
Built-in HDMI, s32le 2ch 48000Hz (so the graph resamples 4:1 from 192 kHz)
Server
Music Assistant
Timeline
I player: Stream started
I audio: pipewire: 'pipewire' open at 48000 Hz, 2 ch, 16-bit (4 bytes/frame, 19201-byte ring)
I sendspin.sync_task: Processed new codec header: flac, 48000 Hz, 2 ch, 16-bit
I metadata: Now playing: Ed Sheeran - Perfect
I player: Static delay set to 0 ms by the server
I player: Stream started
I audio: pipewire: 'pipewire' open at 192000 Hz, 2 ch, 24-bit (6 bytes/frame, 115201-byte ring)
W sendspin.sync_task: Lost sync (43890us off), reporting error
I sendspin.sync_task: Regained sync, reporting synchronized
W sendspin.sync_task: Lost sync (64710us off), reporting error
W sendspin.player: Failed to send audio chunk
... x76 ...
Then the manual pause/play:
I player: Stream ended
I player: Stream started
I audio: pipewire: 'pipewire' open at 192000 Hz, 2 ch, 24-bit (6 bytes/frame, 115201-byte ring)
I sendspin.sync_task: Processed new codec header: flac, 192000 Hz, 2 ch, 24-bit
No further warnings after that: the counter held at 76 across a 10 s window, through two
more 192 kHz stream opens and a track change.
The suspicious part
Three sink opens in one run, and only the broken one is missing its codec header:
Stream open
Sink opened at
Processed new codec header
1st
48 kHz / 16-bit
yes
2nd (broken)
192 kHz / 24-bit
absent
3rd, after pause/play
192 kHz / 24-bit
yes
So the sink was reconfigured to the new format while the decode path had never been told
about it. That is consistent with the symptom -- the two Lost sync figures (43.9 ms and
64.7 ms) are roughly what a 4x sample-rate mismatch would produce against a stream clock.
What it does not appear to be
Not sink starvation, and not ring mis-sizing. The ring was correct for both formats:
19201 bytes / 4 bytes-per-frame = 4800 frames = 100 ms at 48 kHz, and
115201 / 6 = 19200 frames = also 100 ms at 192 kHz. The quantum-starvation warning
added in Add native PulseAudio and PipeWire output backends #27 never fired.
Not an output-backend write failure. Every warning is tagged sendspin.player or sendspin.sync_task. Nothing logged under the audio: tag at all, so the sink never
reported a short write, a dead stream, or a recovery attempt.
Not volume or mute. The stream sat at 100% / 0.00 dB in the graph throughout, and
the player reported player volume: 100 (default; no server has set it).
That points at the stream-restart / codec-header path rather than the output backend. It
may well live in sendspin-cpp rather than in this repo -- filing here because this is
where it was observed and where -o pipewire lives, and the triage can move it.
Open questions
Does it reproduce on -o pulse and -o alsa? If so it is backend-independent, which
would confirm the diagnosis above.
Does it need the 4x rate jump specifically, or does any mid-session format change do it?
Is the codec header dropped in flight, never sent, or processed out of order relative to
the sink reconfigure?
The two Lost sync events precede the chunk failures. Cause or symptom?
Does the 4:1 resample matter? This host advertises rates up to 192 kHz because the
PipeWire node reports them, but the HDMI sink runs at 48 kHz, so every hi-res stream is
downsampled by the graph anyway. CPU went 0.6% -> 3.3% across the change.
Reproduction
Not yet reduced to reliable steps -- observed once, on a Music Assistant queue that moved
from a 48 kHz/16-bit track to a 192 kHz/24-bit track mid-session. Worth trying a queue
deliberately alternating sample rates.
Summary
On a live format renegotiation (FLAC 48 kHz/16-bit -> 192 kHz/24-bit) mid-session, the
output sink reconfigures to the new format but no codec header is ever processed for
it. The player then loses sync and fails to place audio chunks for the rest of that
stream. It does not self-recover: audio stayed audibly wrong until a manual pause/play,
which tore the stream down and started a new one that did process a codec header and
then played correctly.
Environment
linux-arm64, CI run 33119241602)-o pipewire(native backend), libpipewire 1.4.2 + wireplumbers32le 2ch 48000Hz(so the graph resamples 4:1 from 192 kHz)Timeline
Then the manual pause/play:
No further warnings after that: the counter held at 76 across a 10 s window, through two
more 192 kHz stream opens and a track change.
The suspicious part
Three sink opens in one run, and only the broken one is missing its codec header:
Processed new codec headerSo the sink was reconfigured to the new format while the decode path had never been told
about it. That is consistent with the symptom -- the two
Lost syncfigures (43.9 ms and64.7 ms) are roughly what a 4x sample-rate mismatch would produce against a stream clock.
What it does not appear to be
19201 bytes / 4 bytes-per-frame = 4800 frames = 100 ms at 48 kHz, and
115201 / 6 = 19200 frames = also 100 ms at 192 kHz. The quantum-starvation warning
added in Add native PulseAudio and PipeWire output backends #27 never fired.
sendspin.playerorsendspin.sync_task. Nothing logged under theaudio:tag at all, so the sink neverreported a short write, a dead stream, or a recovery attempt.
the player reported
player volume: 100 (default; no server has set it).That points at the stream-restart / codec-header path rather than the output backend. It
may well live in sendspin-cpp rather than in this repo -- filing here because this is
where it was observed and where
-o pipewirelives, and the triage can move it.Open questions
-o pulseand-o alsa? If so it is backend-independent, whichwould confirm the diagnosis above.
the sink reconfigure?
Lost syncevents precede the chunk failures. Cause or symptom?PipeWire node reports them, but the HDMI sink runs at 48 kHz, so every hi-res stream is
downsampled by the graph anyway. CPU went 0.6% -> 3.3% across the change.
Reproduction
Not yet reduced to reliable steps -- observed once, on a Music Assistant queue that moved
from a 48 kHz/16-bit track to a 192 kHz/24-bit track mid-session. Worth trying a queue
deliberately alternating sample rates.