forked from Keelrleek/SoulStream
fix: preview crossfade no longer strands the main volume (silent playback)
Clicking a track could play silently: the store showed status=playing with the position advancing and no error, but the sink was at volume 0. The open/close crossfade ramped the main player's USER VOLUME as its fade channel and left it at 0 on an ack timeout (or when a track change suppressed the close resume). User volume persists across tracks and a new Play doesn't reset it, so every later click played at 0 while the slider still read 0.7. Give the main player a separate fade_gain channel (Cmd::SetFadeGain, sink = volume * norm * fade_gain), reset to 1 by every Play/Stop. The open/close fades ramp fade_gain instead of set_volume (their volume arg is gone, JS callers too), so the user volume is never touched -- store and backend can't desync -- and a clicked track always resets fade_gain to 1, so it can never be stranded silent. fade_resume lands exactly at 1. Player::fade_gain() mirrors it into a report atomic; debug overlay shows main fade + this proved the fix live (open 1->0, close 0->1, new track 1.0, volume steady at 0.7). 39 app + 12 player + 85 JS tests pass.
This commit is contained in:
1 parent
28aba3a3b3
commit
86e0d86604
7 files changed
+98
-45
No files matched your search
+4
-4
@@ -138,10 +138,10 @@ export const streamWaveform = (username, path, size, buckets) =>
|
||||
export const previewResolve = (trackId) => invoke("preview_resolve", { trackId });
|
||||
export const previewLoad = (leaseId, startPaused, crossfadeMs = 0, startAtSecs = null) =>
|
||||
invoke("preview_load", { leaseId, startPaused, crossfadeMs, startAtSecs });
|
||||
export const playerFadePauseAcked = (fadeMs, volume) =>
|
||||
invoke("player_fade_pause_acked", { fadeMs, volume });
|
||||
export const playerFadeResume = (fadeMs, volume) =>
|
||||
invoke("player_fade_resume", { fadeMs, volume });
|
||||
export const playerFadePauseAcked = (fadeMs) =>
|
||||
invoke("player_fade_pause_acked", { fadeMs });
|
||||
export const playerFadeResume = (fadeMs) =>
|
||||
invoke("player_fade_resume", { fadeMs });
|
||||
export const debugStats = () => invoke("debug_stats");
|
||||
export const previewControl = (action, value = null) =>
|
||||
invoke("preview_control", { action, value });
|
||||
|
||||
Reference in new issue
Block a user