diff --git a/crates/engine/src/cmd/event.rs b/crates/engine/src/cmd/event.rs index 018209b6..5aeedd42 100644 --- a/crates/engine/src/cmd/event.rs +++ b/crates/engine/src/cmd/event.rs @@ -165,6 +165,11 @@ fn insert_time(e: &mut Engine, p: &Value) -> Result { m.end += r.len(); } } + for (at, _) in &mut s.key_signatures { + if *at >= r.start { + *at = at.saturating_add(r.len()); + } + } Ok(json!({"inserted": r.len()})) } @@ -192,6 +197,12 @@ fn cut_time(e: &mut Engine, p: &Value) -> Result { m.end -= r.len(); } } + s.key_signatures.retain(|(at, _)| !r.contains(*at)); + for (at, _) in &mut s.key_signatures { + if *at >= r.end { + *at -= r.len(); + } + } Ok(json!({"removed": r.len()})) } diff --git a/crates/engine/tests/it/main.rs b/crates/engine/tests/it/main.rs index 611c7266..9ff28eef 100644 --- a/crates/engine/tests/it/main.rs +++ b/crates/engine/tests/it/main.rs @@ -16,5 +16,6 @@ mod random_edits; mod recording; mod session_transport; mod split_into_mono; +mod time_key_signatures; mod track_name_collisions; mod trim_to_selection; diff --git a/crates/engine/tests/it/time_key_signatures.rs b/crates/engine/tests/it/time_key_signatures.rs new file mode 100644 index 00000000..8b1d5860 --- /dev/null +++ b/crates/engine/tests/it/time_key_signatures.rs @@ -0,0 +1,41 @@ +use serde_json::json; +use soundcraft_engine::Engine; +use soundcraft_model::{ChannelFormat, Session, TrackKind}; + +fn engine_with_keys() -> Engine { + let mut session = Session::default(); + session.add_track(TrackKind::Audio, ChannelFormat::Mono, None); + let mut engine = Engine::new(session); + for (at, key) in [(10, "C major"), (48000, "D major"), (100000, "E major")] { + engine.execute("event.add_key_change", &json!({"key": key, "at": at})).unwrap(); + } + engine +} + +fn keys(engine: &Engine) -> Vec<(u64, String)> { + engine.session().key_signatures.iter().map(|(at, k)| (*at as u64, k.clone())).collect() +} + +fn k(at: u64, key: &str) -> (u64, String) { + (at, key.to_string()) +} + +#[test] +fn insert_time_moves_key_signatures() { + let mut engine = engine_with_keys(); + let original = keys(&engine); + engine.execute("event.insert_time", &json!({"start": 48000, "length": 1000})).unwrap(); + assert_eq!(keys(&engine), vec![k(10, "C major"), k(49000, "D major"), k(101000, "E major")]); + engine.undo(); + assert_eq!(keys(&engine), original); +} + +#[test] +fn cut_time_removes_and_moves_key_signatures() { + let mut engine = engine_with_keys(); + let original = keys(&engine); + engine.execute("event.cut_time", &json!({"start": 20, "end": 60000})).unwrap(); + assert_eq!(keys(&engine), vec![k(10, "C major"), k(40020, "E major")]); + engine.undo(); + assert_eq!(keys(&engine), original); +}