The timeline was the only place that reconstructed audio-layer clip instances from a backend snapshot (build_audio_clip_cache) instead of reading the document like every other layer type. But the document is the actual source of truth: clip actions mutate *Layer::clip_instances, it's what persists to .beam, and it drives the backend on load. The snapshot is downstream of it. That dual source caused the second-recording preview bug: a recording clip lives only in the document (its backend clip has a temporary pool index of 0, so the snapshot can't represent it). layer_clips() only fell back to the doc when the snapshot cache was *empty*, so the first recording previewed but the second — once the layer already had a finalized clip — was dropped and showed as zero-length until finalized. Fix: make layer_clips() read <layer>.clip_instances for audio too, and delete build_audio_clip_cache + the audio_cache plumbing threaded through ~7 methods and ~25 call sites. Recording clips grow via the existing RecordingProgress / MidiRecordingProgress mirror to the doc; finalized clips come from the actions; both states now live in one place. Root fix this exposed: get_clip_duration() wrapped every audio clip's duration as Seconds, but MIDI clips store their duration in BEATS (they share AudioClip with sampled clips). The snapshot had masked this by always forcing a MIDI clip's timeline_duration; reading from the doc requires the value to be right, so get_clip_duration now converts a MIDI clip's beats duration to seconds. Net -120 lines. Whole workspace compiles; 299 core tests pass. The piano roll still uses the snapshot for its own MIDI editor (separate pane, out of scope). |
||
|---|---|---|
| .. | ||
| beamdsp | ||
| egui_node_graph2 | ||
| gpu-video-encoder | ||
| lightningbeam-core | ||
| lightningbeam-editor | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| GPU_VIDEO_DECODE_PLAN.md | ||
| build-static.sh | ||
| build-windows.bat | ||