static/js/main.js operates on multitrack directly, but on the default playback path the multitrack is silent and audioEngine owns the clock. Every interaction wired in that file is therefore broken.
Verified
engineMode() (static/js/player.js) returns "chunked" unless localStorage["stemdeck.audioEngine"] === "0". On that path the multitrack is mounted for visuals only and audioEngine is the transport. static/js/transport.js handles this correctly and consistently:
const tx = audioEngine ?? multitrack; // transport.js:74, :386, :423, :596
and its own comment at transport.js:391 confirms it: "The engine emits no play/pause events (the multitrack stays silent)".
static/js/main.js never references audioEngine at all. It imports only multitrack (line 2) and calls it bare.
The broken interactions
Footer scrub bar does nothing -- main.js:489-492:
function seekToX(clientX) {
if (!multitrack || !totalDuration) return;
...
multitrack.setTime(frac * totalDuration);
}
.footer-scrub is a full-size cursor: pointer overlay. Click or drag anywhere on it: the playhead does not move and audio does not seek. Nothing happens at all.
[ and ] (seek back/forward 5s) do nothing -- main.js:655-659, same cause.
I and O (set loop in/out at playhead) write wrong values -- main.js:669, :673:
setLoopStart(Math.min(multitrack.getCurrentTime(), loopEnd - 0.5));
multitrack.getCurrentTime() is stuck at 0 on the engine path, so "set loop in at playhead" always writes 0 regardless of where the playhead actually is, and "set loop out" always writes max(0, loopStart + 0.5).
Space (togglePlayPause) and ruler clicks work correctly because they live in transport.js.
Scope
Everyone on the default configuration. Only a user who has explicitly set localStorage["stemdeck.audioEngine"] = "0" gets a working scrub bar.
Fix
Use audioEngine ?? multitrack in main.js for all five call sites, matching transport.js. Better still, export a single accessor (e.g. transport()) from transport.js and use it everywhere, so this cannot drift again -- this is the same shape as the FFmpeg PATH duplication fixed in #506.
static/js/main.jsoperates onmultitrackdirectly, but on the default playback path the multitrack is silent andaudioEngineowns the clock. Every interaction wired in that file is therefore broken.Verified
engineMode()(static/js/player.js) returns"chunked"unlesslocalStorage["stemdeck.audioEngine"] === "0". On that path the multitrack is mounted for visuals only andaudioEngineis the transport.static/js/transport.jshandles this correctly and consistently:and its own comment at
transport.js:391confirms it: "The engine emits no play/pause events (the multitrack stays silent)".static/js/main.jsnever referencesaudioEngineat all. It imports onlymultitrack(line 2) and calls it bare.The broken interactions
Footer scrub bar does nothing --
main.js:489-492:.footer-scrubis a full-sizecursor: pointeroverlay. Click or drag anywhere on it: the playhead does not move and audio does not seek. Nothing happens at all.[and](seek back/forward 5s) do nothing --main.js:655-659, same cause.IandO(set loop in/out at playhead) write wrong values --main.js:669,:673:multitrack.getCurrentTime()is stuck at 0 on the engine path, so "set loop in at playhead" always writes 0 regardless of where the playhead actually is, and "set loop out" always writesmax(0, loopStart + 0.5).Space(togglePlayPause) and ruler clicks work correctly because they live intransport.js.Scope
Everyone on the default configuration. Only a user who has explicitly set
localStorage["stemdeck.audioEngine"] = "0"gets a working scrub bar.Fix
Use
audioEngine ?? multitrackinmain.jsfor all five call sites, matchingtransport.js. Better still, export a single accessor (e.g.transport()) fromtransport.jsand use it everywhere, so this cannot drift again -- this is the same shape as the FFmpeg PATH duplication fixed in #506.