c0e7364a901948d936b18f7dbcfd96a2e60f1f6c
begin() only sets `started` after a fetch and a full decode, so anything that called it during that window saw started === false and started a second decode of the same track. both finished, both called startBuffer, and only one of the two sources ended up in `cur`. starting a queue from a paused player did this every time: the host commits a new queue and playing: true in one render, its queue effect calls load(autoplay) -> begin, and its playing effect then calls play() -> begin again, same generation. it compounds, which is why it sounded like three songs and not two. the twin keeps its own onended, so at the boundary advance() ran twice: the index jumped two tracks and a second source was promoted while the first was still sounding. three changes. begin() refuses re-entry for a generation it is already running. onended only advances the queue if the source that ended is the one in `cur`. and every source is registered in a `live` set, because cur/nxt is what the engine reasons about while `live` is what it is responsible for silencing — an untracked web audio node cannot be stopped by anything except closing the context. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Description
No description provided
42 MiB
Languages
TypeScript
90.9%
Shell
4.7%
JavaScript
4.1%
CSS
0.2%
HTML
0.1%