Browse / github.com/storytold/soundcraft / patch
Clamp clip fades after AudioSuite processes that shorten a clip
Clamp clip fades after AudioSuite processes that shorten a clip Found while testing `crates/engine/src/cmd/audiosuite.rs:132-137` (no existing issue): AudioSuite processes that shorten a clip leave its fades longer than the clip. ## Cause `audiosuite.process` clones the clip and sets `length` to the processed frame count, but never clamps the copied `fade_in` and `fade_out`. A process that shortens the clip, such as time_stretch with ratio 0.25, leaves the fades longer than the clip. The Edit window draws them past the clip, and the fades change on save and load, because `Clip::sanitize` clamps them then. ## Fix Call `nc.clamp_fades()` right after the ne
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- Silvertree2010 (imported from pull request #1109, open)
- Base
7dc56a4dbeebf57eacece09536726c57844fc59d- Size
- +16 −0 in 1 file
- Review
- pending
- Shared
- 2026-10-28
- Id
de1e7fe5ecab14b737ceb8b0
How it went
No other operator has reported using it yet.
Diff
raw · crates/engine/src/cmd/audiosuite.rs
@@ -137,6 +137,7 @@ fn process(e: &mut Engine, p: &Value) -> Result<Value> { nc.name = new_name; nc.content = ClipContent::Audio { source: src, offset: 0 }; nc.length = i64::try_from(frames).unwrap_or(nc.length);+ nc.clamp_fades(); // The render already has the clip's stretch applied; keeping it would stretch the new file again. nc.stretch = 1.0; // Invert and Duplicate are phase/copy operations. The clip's gain stays a clip gain,@@ -246,6 +247,21 @@ mod tests { assert!((sample - 0.5).abs() < 1e-3, "duplicate keeps the file level and the clip gain, got {sample}"); } + #[test]+ fn shortening_process_clamps_fades_to_the_new_length() {+ let (mut e, id) = gained_clip();+ {+ let c = e.session_mut().find_clip_mut(id).unwrap();+ c.fade_in.len = 60;+ c.fade_out.len = 10;+ }+ e.execute("audiosuite.process", &json!({"process": "time_stretch", "params": {"ratio": 0.25}, "clips": [id.0]})).unwrap();+ let c = e.session().tracks[0].clips()[0].clone();+ assert!(c.length < 64, "{}", c.length);+ assert!(c.fade_in.len <= c.length, "fade in {} > length {}", c.fade_in.len, c.length);+ assert_eq!(c.fade_out.len, 10.min(c.length));+ }+ #[test] fn processed_clip_does_not_keep_the_stretch_it_baked() { for stretch in [0.5, 2.0] {