Playout change-detection hash omits activeTakeId (latent; will affect Multi-Take Recording)
What
In app/[locale]/compose/page.tsx, the hash that triggers rescheduling doesn't include activeTakeId:
return `${c.id}:${c.startBar}:${c.lengthBars}:${c.instrumentPreset || ''}:${noteHash}`;
That hash drives the useEffect which calls scheduleClips(). If a clip's activeTakeId changes but its position and length don't, the hash is unchanged, no reschedule happens, and playoutManager keeps the previously scheduled Tone.Player — which still holds the old take's audio buffer.
Not currently reproducible
I want to be upfront: I don't think any user action can trigger this today. All three writes to activeTakeId happen on a clip created immediately beforehand:
lib/audio/recording-manager.ts:303 (after addClip on :279)
components/compose/TrackList.tsx:1505 and :1569 (after addClip in the drop handlers)
In each case project.clips.length changes, which is a separate dependency of the same effect, so rescheduling happens anyway.
Why it seems worth fixing anyway
Multi-Take Recording ("record multiple takes and comp the best parts") is on the roadmap, and swapping the active take on an existing clip is exactly the operation this misses. The failure mode is unpleasant to debug: the timeline waveform and the waveform editor both read activeTakeId directly and show the new take, while playback continues producing the old one. Everything looks correct and sounds wrong.
I hit this in a fork where I regenerate audio into an existing clip, which is why I noticed it. Took a while to find, since audio disposal in playoutManager.unscheduleClip() is correct — the reschedule simply never gets requested.
Suggested fix
- return `${c.id}:${c.startBar}:${c.lengthBars}:${c.instrumentPreset || ''}:${noteHash}`;
+ return `${c.id}:${c.startBar}:${c.lengthBars}:${c.activeTakeId || ''}:${c.instrumentPreset || ''}:${noteHash}`;
Happy to open a PR, or leave it for whoever builds comping — entirely your call. Filing it mainly so it's written down somewhere before it costs someone an afternoon.
Playout change-detection hash omits
activeTakeId(latent; will affect Multi-Take Recording)What
In
app/[locale]/compose/page.tsx, the hash that triggers rescheduling doesn't includeactiveTakeId:That hash drives the
useEffectwhich callsscheduleClips(). If a clip'sactiveTakeIdchanges but its position and length don't, the hash is unchanged, no reschedule happens, andplayoutManagerkeeps the previously scheduledTone.Player— which still holds the old take's audio buffer.Not currently reproducible
I want to be upfront: I don't think any user action can trigger this today. All three writes to
activeTakeIdhappen on a clip created immediately beforehand:lib/audio/recording-manager.ts:303(afteraddClipon :279)components/compose/TrackList.tsx:1505and:1569(afteraddClipin the drop handlers)In each case
project.clips.lengthchanges, which is a separate dependency of the same effect, so rescheduling happens anyway.Why it seems worth fixing anyway
Multi-Take Recording ("record multiple takes and comp the best parts") is on the roadmap, and swapping the active take on an existing clip is exactly the operation this misses. The failure mode is unpleasant to debug: the timeline waveform and the waveform editor both read
activeTakeIddirectly and show the new take, while playback continues producing the old one. Everything looks correct and sounds wrong.I hit this in a fork where I regenerate audio into an existing clip, which is why I noticed it. Took a while to find, since audio disposal in
playoutManager.unscheduleClip()is correct — the reschedule simply never gets requested.Suggested fix
Happy to open a PR, or leave it for whoever builds comping — entirely your call. Filing it mainly so it's written down somewhere before it costs someone an afternoon.