Skip to main content

max / audiofiles

2.4 KB · 85 lines History Blame Raw
1 //! Trim operation: extract a frame range from sample data.
2
3 use crate::error::CoreError;
4
5 /// Trim samples to the given frame range (inclusive start, exclusive end).
6 ///
7 /// Operates on interleaved sample data. `start_frame` and `end_frame` are in
8 /// frame units (not sample units), so channel count is accounted for.
9 pub fn apply_trim(
10 samples: &mut Vec<f32>,
11 channels: u16,
12 start_frame: usize,
13 end_frame: usize,
14 ) -> Result<(), CoreError> {
15 let ch = channels as usize;
16 if ch == 0 {
17 return Err(CoreError::Internal("trim: channels must be > 0".to_string()));
18 }
19 let total_frames = samples.len() / ch;
20
21 if start_frame >= end_frame {
22 return Err(CoreError::Internal(
23 "trim: start_frame must be less than end_frame".to_string(),
24 ));
25 }
26 if end_frame > total_frames {
27 return Err(CoreError::Internal(format!(
28 "trim: end_frame ({end_frame}) exceeds total frames ({total_frames})"
29 )));
30 }
31
32 let start_sample = start_frame * ch;
33 let end_sample = end_frame * ch;
34 samples.drain(end_sample..);
35 samples.drain(..start_sample);
36 Ok(())
37 }
38
39 #[cfg(test)]
40 mod tests {
41 use super::*;
42
43 #[test]
44 fn trim_mono() {
45 let mut samples = vec![0.1, 0.2, 0.3, 0.4, 0.5];
46 apply_trim(&mut samples, 1, 1, 4).unwrap();
47 assert_eq!(samples, vec![0.2, 0.3, 0.4]);
48 }
49
50 #[test]
51 fn trim_stereo() {
52 // 4 frames of stereo: [L0,R0, L1,R1, L2,R2, L3,R3]
53 let mut samples = vec![0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8];
54 apply_trim(&mut samples, 2, 1, 3).unwrap();
55 // Should keep frames 1 and 2: [L1,R1, L2,R2]
56 assert_eq!(samples, vec![0.3, 0.4, 0.5, 0.6]);
57 }
58
59 #[test]
60 fn trim_full_range_is_noop() {
61 let mut samples = vec![0.1, 0.2, 0.3];
62 apply_trim(&mut samples, 1, 0, 3).unwrap();
63 assert_eq!(samples, vec![0.1, 0.2, 0.3]);
64 }
65
66 #[test]
67 fn trim_invalid_range() {
68 let mut samples = vec![0.1, 0.2, 0.3];
69 assert!(apply_trim(&mut samples, 1, 2, 1).is_err());
70 }
71
72 #[test]
73 fn trim_out_of_bounds() {
74 let mut samples = vec![0.1, 0.2, 0.3];
75 assert!(apply_trim(&mut samples, 1, 0, 10).is_err());
76 }
77
78 #[test]
79 fn trim_single_frame() {
80 let mut samples = vec![0.1, 0.2, 0.3, 0.4, 0.5];
81 apply_trim(&mut samples, 1, 2, 3).unwrap();
82 assert_eq!(samples, vec![0.3]);
83 }
84 }
85