fix(audio): frame-align gapless-off track-separation silence (#439)

* fix(audio): frame-align gapless-off track-separation silence

The 500 ms silence prepended between tracks when gapless playback is
disabled and the previous track ended naturally was built with
`Zero<f32>::new(ch, sr).take_duration(500ms)`. Rodio's `TakeDuration`
computes its sample count via integer-nanosecond division
(`1_000_000_000 / (sr * ch)`), which truncates: at 44.1 kHz / 2 ch
this emits 44103 samples = 22051.5 frames, half a frame short.

That half-frame leak shifts the next source's L/R parity in the
device frame stream. Multiple users have reported the next track
playing only on the right channel — exactly when gapless is OFF and
the previous track ended naturally (manual skip and album-first-play
bypass the silence prepend, which matches the reproducer report).

Replace with `SamplesBuffer::new(ch, sr, vec![0; frames * ch])`
where `frames = sr / 2`. Frame-aligned by construction, same
audible effect.

* docs(changelog): add #439 mono-channel fix entry

* chore(credits): add #439 to Psychotoxical contributions

* docs(changelog): strip @ from non-contributor mention in #435 entry

Plain-text 'zunoz on Discord' instead of '@zunoz' so GitHub does not
attribute the requester as a contributor on subsequent merges.
This commit is contained in:
Frank Stellmacher
2026-05-03 13:55:56 +02:00
committed by GitHub
parent 6019a253cd
commit dcec30166a
3 changed files with 18 additions and 5 deletions
+1
View File
@@ -348,6 +348,7 @@ const CONTRIBUTORS = [
'Preview: audio start sync, ring animation, download timeout (PR #423)',
'Statistics: shareable Top-Albums card export (PR #425)',
'Windows: playback stutter under GPU load — MMCSS Pro Audio promotion + animation pause + reduce-animations toggle (PR #426)',
'Audio: frame-align gapless-off track-separation silence (fixes mono-channel playback after natural track end) (PR #439)',
],
},
] as const;