In merge mode every pass layers into the same clip, so a later pass has to PLAY BACK what earlier passes laid down — otherwise you overdub against silence, which defeats the point of merging (you can't put a hi-hat on a kick you can't hear). Two things stood in the way, and they turned out to be the same bug: - The captured notes only reached the backend's MIDI pool clip at STOP, so during the session the sequencer had nothing to schedule. The wrap now folds the notes captured so far into the pool clip. Their offsets drop straight in: a cycle MIDI recording is anchored at loop_start, so they're already region-relative. - The recording-progress block resizes the clip instance every audio buffer from `playhead - start_time`. The playhead jumps BACKWARDS at a wrap, so that duration collapsed to zero and grew again on every pass. It reset the clip bar to zero each pass (visible), and it shrank the clip instance back to nothing at each wrap (invisible) — so even once the notes were in the pool, the sequencer saw a zero-length instance and scheduled none of them. Fixed at the root: once the transport has wrapped, the recording spans the whole cycle region and STAYS there — it doesn't track the playhead at all. `cycle_loop_len` (set at the first wrap) pins it, which both holds the clip bar at full region length after pass one and keeps the instance stretched across the region so the merged notes get scheduled. Writing the events reuses the clip's existing Vec, so it's allocation-free after the first wrap; mutating the pool from the audio thread is what Command::UpdateMidiClipNotes already does. |
||
|---|---|---|
| .. | ||
| beamdsp | ||
| egui_node_graph2 | ||
| gpu-video-encoder | ||
| lightningbeam-core | ||
| lightningbeam-editor | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| build-static.sh | ||
| build-windows.bat | ||