Take management should be per clip instance — deleting a take from one
half of a comped split shouldn't pull it out from under the other half.
That's cleanest if the takes themselves live on the instance rather than
the clip, so they do now.
AudioClipType::TakeFolder is gone entirely. A clip is plain Sampled/Midi
content again, and an instance with a non-empty `takes` list simply
OVERRIDES it with whichever take is active. Splitting already clones the
instance, so each half gets its own take list for free — no index
remapping across instances, no copy-on-write, no shared-state surprise —
and comping still works, because the halves can still each select a
different take. It collapsed machinery too: resolve() moved from the clip
to the instance, and owns_audio_pool_index went back to a one-liner.
Management (DeleteTakeAction, DeleteUnusedTakesAction, RenameTakeAction):
- Right-click a clip with more than one take: `Delete "<active take>"`
and "Delete Unused Takes". Deletion is named after the take that's
PLAYING rather than being a generic entry, so you pick the victim by
selecting it — one clear act instead of hunting a small trash icon in a
list (which is where this started, and it was fiddly).
- Double-click a take in the dropdown to rename it in place.
- What happens to the selection on delete is the subtle part, and there's
a test per case: deleting a take BELOW the active one shifts the
selection down so you keep hearing the same take; deleting the ACTIVE
take lands on whatever slid into its place (not silently back to take
1); deleting the LAST take steps back one. The only take can't be
deleted at all — the menu item isn't offered.
- Deleted takes' audio stays in the pool: undo has to put it back, and
the other half of a split may still be playing it.
Fixes:
- A recording that stopped before the loop came round wasn't joining an
existing take list — it landed as a separate overlapping clip. Trigger-
on-wrap is right for the FIRST recording, but once takes exist there,
a further run is plainly another take however short. The engine can't
know that (it's document state), so the editor passes `force_takes`
with the start-recording command and the run is cut and padded to the
region even with zero wraps. This forced cycle_loop_len and `wrapped`
apart on the MIDI side: the region length has to be known from the
start, but the clip should only pin to full-region length AFTER a pass
completes, or the bar jumps to full width the moment you hit record.
- Recording a second take left BOTH sounding. append_cycle_takes tore
down the recording's backend clip by looking it up in
clip_instance_to_backend_map — but on the audio path the recording
instance isn't in that map yet; it's only added during promotion, which
the append path skips. The event already carries the engine's clip id,
so it's handed over explicitly now.
- The take badge is hidden when there's only one take — no choice to make.
Completes the cycle-recording spec. Three related pieces:
MIDI separate takes (Preferences > Audio > "Cycle MIDI recording"):
- Each pass becomes its own MIDI clip, folded into a take folder — the same
shape audio always gets — instead of merging into one clip. Merge stays
the default.
- Notes are bucketed by the pass they were played in. The pass counter bumps
BETWEEN close_active_notes and the re-note_on at a wrap, so a key held
across the boundary has its sounding half filed under the pass that's
ending and its re-opened half under the pass that's beginning. Put the bump
on either side of that pair and the whole note lands in one pass; there's a
test named for exactly that.
- A silent INTERIOR pass still yields an empty take, so take N is always pass
N — otherwise the numbering silently shifts and "take 3" stops meaning "the
third time round". A TRAILING empty pass is dropped: that's what hitting
stop shortly after a wrap gives you, a stop artifact rather than a take you
played. (Audio already behaved this way via its short-final-take rule.)
- Still triggers on the wrap: stop inside the first pass and it's an ordinary
single recording, whatever the preference says.
Append to an existing take folder (AppendTakesAction):
- Cycle-recording over a region that already holds a take folder now ADDS to
that folder rather than dropping a second clip on top of it, which stranded
the new takes in an overlapping clip you couldn't audition against the old.
- "Same region" means same start AND same loop length: resize the cycle region
and you get a fresh folder, rather than takes of a different length appended
to an existing one, which would break the uniform-take invariant that
comping-via-split depends on.
- The recording's own clip/instance are throwaway scaffolding here (the takes
already live in the backend pools), so they're discarded; the single
AppendTakesAction is the whole undoable step.
Don't play the region you're recording over:
- While recording into a MIDI track, every clip on that track is silenced
EXCEPT the one being recorded into. A take folder already sitting in the
cycle region was otherwise playing its active take underneath you on every
pass, fighting the part you were trying to record.
- The recording clip itself is exempt, because in merge mode that's precisely
what you want to hear: the overdub you've been building up. Other tracks are
untouched.