1use crate::RBoxErr;
9use crate::{
10 samples::options::SampleAttributeLoopMode, samples::SampleAttributes, OptionEnumValueConvert,
11};
12
13#[derive(PartialEq, Debug, Clone, Copy)]
16pub struct SampleTrimConfig {
17 pub start: u32,
19 pub end: u32,
21 pub length: u32,
24}
25
26impl SampleTrimConfig {
27 pub fn from_decoded(decoded: &SampleAttributes) -> RBoxErr<Self> {
28 let new = SampleTrimConfig {
29 start: decoded.trim_start,
30 end: decoded.trim_end,
31 length: decoded.trim_len,
32 };
33 Ok(new)
34 }
35}
36
37#[derive(PartialEq, Debug, Clone, Copy)]
40pub struct SampleLoopConfig {
41 pub start: u32,
43
44 pub length: u32,
46
47 pub mode: SampleAttributeLoopMode,
49}
50
51impl SampleLoopConfig {
52 pub fn new(start: u32, length: u32, mode: SampleAttributeLoopMode) -> RBoxErr<Self> {
53 Ok(Self {
54 start,
55 length,
56 mode,
57 })
58 }
59
60 pub fn from_decoded(decoded: &SampleAttributes) -> RBoxErr<Self> {
61 Self::new(
62 decoded.loop_start,
63 decoded.loop_len,
64 SampleAttributeLoopMode::from_value(&decoded.loop_mode)
65 .unwrap_or(SampleAttributeLoopMode::Off),
66 )
67 }
68}
69
70#[cfg(test)]
71#[allow(unused_imports)]
72mod tests {
73
74 mod test_sample_loop_config {
75 mod test_new {
76
77 use crate::samples::configs::{SampleAttributeLoopMode, SampleLoopConfig};
78
79 #[test]
80 fn test_new_sample_loop_config_loop_off() {
81 assert_eq!(
82 SampleLoopConfig::new(0, 10, SampleAttributeLoopMode::Off).unwrap(),
83 SampleLoopConfig {
84 start: 0,
85 length: 10,
86 mode: SampleAttributeLoopMode::Off
87 }
88 );
89 }
90
91 #[test]
92 fn test_new_sample_loop_config_umin_start_umax_length() {
93 assert_eq!(
94 SampleLoopConfig::new(u32::MIN, u32::MAX, SampleAttributeLoopMode::Off)
95 .unwrap(),
96 SampleLoopConfig {
97 start: u32::MIN,
98 length: u32::MAX,
99 mode: SampleAttributeLoopMode::Off
100 }
101 );
102 }
103
104 #[test]
105 fn test_new_sample_loop_config_loop_normal() {
106 assert_eq!(
107 SampleLoopConfig::new(0, 10, SampleAttributeLoopMode::Normal).unwrap(),
108 SampleLoopConfig {
109 start: 0,
110 length: 10,
111 mode: SampleAttributeLoopMode::Normal
112 }
113 );
114 }
115
116 #[test]
117 fn test_new_sample_loop_config_loop_pingpong() {
118 assert_eq!(
119 SampleLoopConfig::new(0, 10, SampleAttributeLoopMode::PingPong).unwrap(),
120 SampleLoopConfig {
121 start: 0,
122 length: 10,
123 mode: SampleAttributeLoopMode::PingPong
124 }
125 );
126 }
127 }
128 }
129
130 mod test_from_decoded {
131
132 use crate::{
133 samples::{
134 configs::{SampleAttributeLoopMode, SampleLoopConfig},
135 slices::Slice,
136 SampleAttributes, SAMPLES_FILE_VERSION, SAMPLES_HEADER,
137 },
138 OptionEnumValueConvert,
139 };
140
141 #[test]
142 fn test_umin_start_umax_len() {
143 let decoded = SampleAttributes {
144 header: SAMPLES_HEADER,
145 datatype_version: SAMPLES_FILE_VERSION,
146 unknown: 0,
147 tempo: 128000,
148 trim_len: 0,
149 loop_len: u32::MAX,
150 stretch: 0,
151 loop_mode: SampleAttributeLoopMode::Off.value().unwrap(),
152 gain: 0,
153 quantization: 0,
154 trim_start: 0,
155 trim_end: 0,
156 loop_start: u32::MIN,
157 slices: [Slice {
158 trim_start: 0,
159 trim_end: 0,
160 loop_start: 0,
161 }; 64],
162 slices_len: 0,
163 checksum: 0,
164 };
165
166 assert_eq!(
167 SampleLoopConfig::from_decoded(&decoded).unwrap(),
168 SampleLoopConfig {
169 start: u32::MIN,
170 length: u32::MAX,
171 mode: SampleAttributeLoopMode::Off
172 }
173 );
174 }
175
176 #[test]
177 fn test_loop_off() {
178 let decoded = SampleAttributes {
179 header: SAMPLES_HEADER,
180 datatype_version: SAMPLES_FILE_VERSION,
181 unknown: 0,
182 tempo: 128000,
183 trim_len: 0,
184 loop_len: 10,
185 stretch: 0,
186 loop_mode: SampleAttributeLoopMode::Off.value().unwrap(),
187 gain: 0,
188 quantization: 0,
189 trim_start: 0,
190 trim_end: 0,
191 loop_start: 0,
192 slices: [Slice {
193 trim_start: 0,
194 trim_end: 0,
195 loop_start: 0,
196 }; 64],
197 slices_len: 0,
198 checksum: 0,
199 };
200
201 assert_eq!(
202 SampleLoopConfig::from_decoded(&decoded).unwrap(),
203 SampleLoopConfig {
204 start: 0,
205 length: 10,
206 mode: SampleAttributeLoopMode::Off
207 }
208 );
209 }
210
211 #[test]
212 fn test_loop_normal() {
213 let decoded = SampleAttributes {
214 header: SAMPLES_HEADER,
215 datatype_version: SAMPLES_FILE_VERSION,
216 unknown: 0,
217 tempo: 128000,
218 trim_len: 0,
219 loop_len: 10,
220 stretch: 0,
221 loop_mode: SampleAttributeLoopMode::Normal.value().unwrap(),
222 gain: 0,
223 quantization: 0,
224 trim_start: 0,
225 trim_end: 0,
226 loop_start: 0,
227 slices: [Slice {
228 trim_start: 0,
229 trim_end: 0,
230 loop_start: 0,
231 }; 64],
232 slices_len: 0,
233 checksum: 0,
234 };
235
236 assert_eq!(
237 SampleLoopConfig::from_decoded(&decoded).unwrap(),
238 SampleLoopConfig {
239 start: 0,
240 length: 10,
241 mode: SampleAttributeLoopMode::Normal
242 }
243 );
244 }
245
246 #[test]
247 fn test_loop_pingpong() {
248 let decoded = SampleAttributes {
249 header: SAMPLES_HEADER,
250 datatype_version: SAMPLES_FILE_VERSION,
251 unknown: 0,
252 tempo: 128000,
253 trim_len: 0,
254 loop_len: 10,
255 stretch: 0,
256 loop_mode: SampleAttributeLoopMode::PingPong.value().unwrap(),
257 gain: 0,
258 quantization: 0,
259 trim_start: 0,
260 trim_end: 0,
261 loop_start: 0,
262 slices: [Slice {
263 trim_start: 0,
264 trim_end: 0,
265 loop_start: 0,
266 }; 64],
267 slices_len: 0,
268 checksum: 0,
269 };
270
271 assert_eq!(
272 SampleLoopConfig::from_decoded(&decoded).unwrap(),
273 SampleLoopConfig {
274 start: 0,
275 length: 10,
276 mode: SampleAttributeLoopMode::PingPong
277 }
278 );
279 }
280 }
281}