diff --git a/daw-backend/src/audio/engine.rs b/daw-backend/src/audio/engine.rs index a7dcab5..7581025 100644 --- a/daw-backend/src/audio/engine.rs +++ b/daw-backend/src/audio/engine.rs @@ -3607,10 +3607,10 @@ impl EngineController { } /// Create a new MIDI clip on a track - pub fn create_midi_clip(&mut self, track_id: TrackId, start_time: f64, duration: f64) -> MidiClipId { + pub fn create_midi_clip(&mut self, track_id: TrackId, start_time: Beats, duration: Beats) -> MidiClipId { // Peek at the next clip ID that will be used let clip_id = self.next_midi_clip_id.load(Ordering::Relaxed); - let _ = self.command_tx.push(Command::CreateMidiClip(track_id, start_time, duration)); + let _ = self.command_tx.push(Command::CreateMidiClip(track_id, start_time.beats_to_f64(), duration.beats_to_f64())); clip_id } @@ -3739,8 +3739,8 @@ impl EngineController { } /// Start recording on a track - pub fn start_recording(&mut self, track_id: TrackId, start_time: f64) { - let _ = self.command_tx.push(Command::StartRecording(track_id, Beats(start_time))); + pub fn start_recording(&mut self, track_id: TrackId, start_time: Beats) { + let _ = self.command_tx.push(Command::StartRecording(track_id, start_time)); } /// Stop the current recording @@ -3759,8 +3759,8 @@ impl EngineController { } /// Start MIDI recording on a track - pub fn start_midi_recording(&mut self, track_id: TrackId, clip_id: MidiClipId, start_time: f64) { - let _ = self.command_tx.push(Command::StartMidiRecording(track_id, clip_id, Beats(start_time))); + pub fn start_midi_recording(&mut self, track_id: TrackId, clip_id: MidiClipId, start_time: Beats) { + let _ = self.command_tx.push(Command::StartMidiRecording(track_id, clip_id, start_time)); } /// Stop the current MIDI recording diff --git a/daw-backend/src/tui/mod.rs b/daw-backend/src/tui/mod.rs index 3dc57bc..85d19bc 100644 --- a/daw-backend/src/tui/mod.rs +++ b/daw-backend/src/tui/mod.rs @@ -830,7 +830,7 @@ fn execute_command( app.next_clip_id += 1; app.add_clip(track_id, clip_id, start_time, duration, format!("Clip {}", clip_id), Vec::new()); - controller.create_midi_clip(track_id, start_time, duration); + controller.create_midi_clip(track_id, crate::Beats(start_time), crate::Beats(duration)); app.set_status(format!("Created MIDI clip on track {} at {:.2}s for {:.2}s", track_id, start_time, duration)); } "loadmidi" => { diff --git a/lightningbeam-ui/lightningbeam-editor/src/panes/timeline.rs b/lightningbeam-ui/lightningbeam-editor/src/panes/timeline.rs index b67ffe2..8274f1d 100644 --- a/lightningbeam-ui/lightningbeam-editor/src/panes/timeline.rs +++ b/lightningbeam-ui/lightningbeam-editor/src/panes/timeline.rs @@ -1127,6 +1127,9 @@ impl TimelinePane { shared.recording_layer_ids.clear(); + // The backend records in the beats domain; start_time is the seconds playhead. + let start_beats = shared.action_executor.document().tempo_map().seconds_to_beats(Seconds(start_time)); + // Step 4: Dispatch recording for each candidate for &(layer_id, ref cat, _) in &candidates { match cat { @@ -1150,7 +1153,7 @@ impl TimelinePane { } if let Some(controller_arc) = shared.audio_controller { let mut controller = controller_arc.lock().unwrap(); - controller.start_recording(track_id, start_time); + controller.start_recording(track_id, start_beats); println!("🎤 Started audio recording on track {:?} at {:.2}s", track_id, start_time); } shared.recording_layer_ids.push(layer_id); @@ -1162,8 +1165,8 @@ impl TimelinePane { if let Some(&track_id) = shared.layer_to_track_map.get(&layer_id) { if let Some(controller_arc) = shared.audio_controller { let mut controller = controller_arc.lock().unwrap(); - let clip_id = controller.create_midi_clip(track_id, start_time, 0.0); - controller.start_midi_recording(track_id, clip_id, start_time); + let clip_id = controller.create_midi_clip(track_id, start_beats, Beats::ZERO); + controller.start_midi_recording(track_id, clip_id, start_beats); shared.recording_clips.insert(layer_id, clip_id); println!("🎹 Started MIDI recording on track {:?} at {:.2}s, clip_id={}", track_id, start_time, clip_id); @@ -1174,8 +1177,6 @@ impl TimelinePane { *shared.recording_clips.get(&layer_id).unwrap_or(&0), daw_backend::Beats::ZERO); let doc_clip_id = shared.action_executor.document_mut().add_audio_clip(doc_clip); - let start_beats = shared.action_executor.document().tempo_map() - .seconds_to_beats(Seconds(start_time)); let clip_instance = ClipInstance::new(doc_clip_id) .with_timeline_start(start_beats);