ot_tools_io/
banks.rs

1/*
2SPDX-License-Identifier: GPL-3.0-or-later
3Copyright © 2024 Mike Robeson [dijksterhuis]
4*/
5
6//! Types for `bank??.*` binary data files.
7
8use crate::parts::Parts;
9use crate::patterns::Pattern;
10
11use crate::{
12    Defaults, HasChecksumField, HasFileVersionField, HasHeaderField, OctatrackFileIO,
13    OtToolsIoError,
14};
15use ot_tools_io_derive::{ArrayDefaults, BoxedBigArrayDefaults, IntegrityChecks, IsDefaultCheck};
16use serde::{Deserialize, Serialize};
17use serde_big_array::{Array, BigArray};
18use std::array::from_fn;
19
20/// Bank header data.
21/// ```text
22/// FORM....DPS1BANK.....
23/// 46 4f 52 4d 00 00 00 00 44 50 53 31 42 41 4e 4b 00 00 00 00 00
24/// [70 79 82 77 0 0 0 0 68 80 83 49 66 65 78 75 0 0 0 0 0]
25/// ```
26pub const BANK_HEADER: [u8; 21] = [
27    70, 79, 82, 77, 0, 0, 0, 0, 68, 80, 83, 49, 66, 65, 78, 75, 0, 0, 0, 0, 0,
28];
29
30/// Current/supported version of bank files.
31pub const BANK_FILE_VERSION: u8 = 23;
32
33/// An Octatrack Bank. Contains data related to Parts and Patterns.
34#[derive(
35    Debug,
36    Serialize,
37    Deserialize,
38    Clone,
39    PartialEq,
40    ArrayDefaults,
41    BoxedBigArrayDefaults,
42    IsDefaultCheck,
43    IntegrityChecks,
44)]
45pub struct BankFile {
46    /// Misc header data for Banks.
47    /// Always follows the same format.
48    #[serde(with = "BigArray")]
49    pub header: [u8; 21],
50
51    pub datatype_version: u8,
52
53    /// Pattern data for a Bank.
54    // note -- stack overflow if trying to use #[serde(with = "BigArray")]
55    pub patterns: Box<Array<Pattern, 16>>,
56
57    /// All part data for this bank, includes currently unsaved and previously saved state
58    pub parts: Parts,
59
60    /// Indicates which parts have previously saved state available for reloading.
61    #[serde(with = "BigArray")]
62    pub parts_saved_state: [u8; 4],
63
64    /// Bit mask indicating which parts are currently in an edited state.
65    /// ```text
66    /// parts
67    /// 1 2 3 4 | mask
68    /// --------|------
69    /// - - - - | 0
70    /// x - - - | 1
71    /// - x - - | 2
72    /// - - x - | 4
73    /// - - - x | 8
74    /// --------|------
75    /// x x - - | 3
76    /// x - x - | 5
77    /// - x x - | 6
78    /// x x x - | 7
79    /// x - - x | 9
80    /// - x - x | 10
81    /// x x - x | 11
82    /// - - x x | 12
83    /// - x x x | 14
84    /// x x x x | 15
85    /// ```
86    pub parts_edited_bitmask: u8,
87
88    /// Names for each Part within the Bank.
89    /// Maximum 7 character length.
90    #[serde(with = "BigArray")]
91    pub part_names: [[u8; 7]; 4],
92
93    /// checksum bytes
94    pub checksum: u16,
95}
96
97/// Default Part names (ONE, TWO, THREE, FOUR) converted to u8 for ease of use.
98const DEFAULT_PART_NAMES: [[u8; 7]; 4] = [
99    [0x4f, 0x4e, 0x45, 0x00, 0x00, 0x00, 0x00], // "ONE"
100    [0x54, 0x57, 0x4f, 0x00, 0x00, 0x00, 0x00], // "TWO"
101    [0x54, 0x48, 0x52, 0x45, 0x45, 0x00, 0x00], // "THREE"
102    [0x46, 0x4f, 0x55, 0x52, 0x00, 0x00, 0x00], // "FOUR"
103];
104
105impl OctatrackFileIO for BankFile {
106    fn encode(&self) -> Result<Vec<u8>, OtToolsIoError>
107    where
108        Self: Serialize,
109    {
110        let mut chkd = self.clone();
111        chkd.checksum = self.calculate_checksum()?;
112        let bytes = bincode::serialize(&chkd)?;
113        Ok(bytes)
114    }
115}
116
117impl Default for BankFile {
118    fn default() -> Self {
119        Self {
120            header: BANK_HEADER,
121            datatype_version: BANK_FILE_VERSION,
122            patterns: Pattern::defaults(),
123            parts: Parts::default(),
124            parts_saved_state: from_fn(|_| 0),
125            parts_edited_bitmask: 0,
126            part_names: DEFAULT_PART_NAMES,
127            // WARN: mutated during encode! do not calculate checksum in this
128            // method until i've refactored `get_checksum` to not use Bank::default()
129            // (end up with a never ending recursive loop of calling default)
130            // TODO: Hardcoded
131            checksum: 48022,
132        }
133    }
134}
135
136impl HasChecksumField for BankFile {
137    fn calculate_checksum(&self) -> Result<u16, OtToolsIoError> {
138        let bytes = bincode::serialize(&self)?;
139        let bytes_no_header_no_chk = &bytes[16..bytes.len() - 2];
140        let default_bytes = &bincode::serialize(&BankFile::default())?;
141        let def_important_bytes = &default_bytes[16..bytes.len() - 2];
142        let default_checksum: i32 = 48022;
143        let mut byte_diffs: i32 = 0;
144        for (byte, def_byte) in bytes_no_header_no_chk.iter().zip(def_important_bytes) {
145            let byte_diff = (*byte as i32) - (*def_byte as i32);
146            if byte_diff != 0 {
147                byte_diffs += byte_diff;
148            }
149        }
150        let check = byte_diffs * 256 + default_checksum;
151        let modded = check.rem_euclid(65535);
152        Ok(modded as u16)
153    }
154
155    fn check_checksum(&self) -> Result<bool, OtToolsIoError> {
156        Ok(self.checksum == self.calculate_checksum()?)
157    }
158}
159
160impl HasHeaderField for BankFile {
161    fn check_header(&self) -> Result<bool, OtToolsIoError> {
162        Ok(self.header == BANK_HEADER)
163    }
164}
165
166impl HasFileVersionField for BankFile {
167    fn check_file_version(&self) -> Result<bool, OtToolsIoError> {
168        Ok(BANK_FILE_VERSION == self.datatype_version)
169    }
170}
171
172#[cfg(test)]
173mod checksum {
174    use crate::banks::BankFile;
175    use crate::test_utils::{get_bank_dirpath, get_blank_proj_dirpath};
176    use crate::{HasChecksumField, OctatrackFileIO};
177    use std::path::Path;
178
179    fn helper_test_chksum(fp: &Path) {
180        let valid = BankFile::from_data_file(fp).unwrap();
181        let mut test = valid.clone();
182        test.checksum = 0;
183        let encoded = test.encode().unwrap();
184        let def_encoded = BankFile::default().encode().unwrap();
185
186        let r = test.calculate_checksum();
187
188        //let bytes = bincode::serialize(&test).unwrap();
189        //let r = get_checksum(&bytes);
190        assert!(r.is_ok());
191        let res = r.unwrap();
192
193        let s_attr_chk: u32 = encoded[16..encoded.len() - 2]
194            .iter()
195            .map(|x| *x as u32)
196            .sum::<u32>()
197            .rem_euclid(u16::MAX as u32 + 1);
198
199        let non_zero_bytes = encoded.iter().filter(|b| b > &&0).count();
200        let non_zero_sum = encoded
201            .iter()
202            .cloned()
203            .filter(|b| b > &0)
204            .map(|x| x as u32)
205            .sum::<u32>();
206
207        let default_byte_sum = def_encoded
208            .iter()
209            .cloned()
210            .filter(|b| b > &0)
211            .map(|x| x as u32)
212            .sum::<u32>();
213
214        println!(
215            "l: {} r: {} non_zero_bytes {} sum total: {} def sum: {}, s-attr {} diff {} (or {})",
216            res,
217            valid.checksum,
218            non_zero_bytes,
219            non_zero_sum,
220            default_byte_sum,
221            s_attr_chk,
222            res.wrapping_sub(valid.checksum),
223            valid.checksum.wrapping_sub(res)
224        );
225
226        assert_eq!(res, valid.checksum);
227    }
228
229    #[test]
230    fn default_bank1() {
231        helper_test_chksum(&get_blank_proj_dirpath().join("bank01.work"));
232    }
233
234    #[test]
235    fn default_bank2() {
236        helper_test_chksum(&get_blank_proj_dirpath().join("bank02.work"));
237    }
238
239    #[test]
240    fn one_scene_zero_val() {
241        // start value incremented by 127 (max) and len incremented by 127 (max) on the machine
242        helper_test_chksum(
243            &get_bank_dirpath()
244                .join("checksum")
245                .join("scene1-atrack1-lfo-dep1-zero.work"),
246        );
247    }
248
249    #[test]
250    fn one_scene_127_val() {
251        // start value incremented by 127 (max) and len incremented by 127 (max) on the machine
252        helper_test_chksum(
253            &get_bank_dirpath()
254                .join("checksum")
255                .join("scene1-atrack1-lfo-dep1-127.work"),
256        );
257    }
258
259    #[test]
260    fn scene_params_decr_lots() {
261        // all scenes have assignments on the LFO parameters for track 1 - sets everything tp 0
262        helper_test_chksum(
263            &get_bank_dirpath()
264                .join("checksum")
265                .join("all-scenes-lfo-params-zeroed.work"),
266        );
267    }
268
269    mod static_strt_only {
270        use crate::banks::checksum::helper_test_chksum;
271        use crate::test_utils::get_bank_dirpath;
272
273        #[test]
274        fn static_strt_1() {
275            // start value incremented by one on the machine
276            helper_test_chksum(
277                &get_bank_dirpath()
278                    .join("checksum")
279                    .join("static-strt-1.work"),
280            );
281        }
282
283        #[test]
284        fn static_strt_2() {
285            // start value incremented by two on the machine
286            helper_test_chksum(
287                &get_bank_dirpath()
288                    .join("checksum")
289                    .join("static-strt-2.work"),
290            );
291        }
292
293        #[test]
294        fn static_strt_10() {
295            // start value incremented by ten on the machine
296            helper_test_chksum(
297                &get_bank_dirpath()
298                    .join("checksum")
299                    .join("static-strt-10.work"),
300            );
301        }
302
303        // off by one?!
304        #[test]
305        fn static_strt_127() {
306            // start value incremented by 127 (max) on the machine
307            helper_test_chksum(
308                &get_bank_dirpath()
309                    .join("checksum")
310                    .join("static-strt-127.work"),
311            );
312        }
313
314        #[test]
315        fn static_strt_126() {
316            helper_test_chksum(
317                &get_bank_dirpath()
318                    .join("checksum")
319                    .join("static-strt-126.work"),
320            );
321        }
322
323        #[test]
324        fn static_strt_125() {
325            helper_test_chksum(
326                &get_bank_dirpath()
327                    .join("checksum")
328                    .join("static-strt-125.work"),
329            );
330        }
331
332        #[test]
333        fn static_strt_124() {
334            helper_test_chksum(
335                &get_bank_dirpath()
336                    .join("checksum")
337                    .join("static-strt-124.work"),
338            );
339        }
340
341        #[test]
342        fn static_strt_123() {
343            helper_test_chksum(
344                &get_bank_dirpath()
345                    .join("checksum")
346                    .join("static-strt-123.work"),
347            );
348        }
349
350        #[test]
351        fn static_strt_122() {
352            helper_test_chksum(
353                &get_bank_dirpath()
354                    .join("checksum")
355                    .join("static-strt-122.work"),
356            );
357        }
358
359        #[test]
360        fn static_strt_121() {
361            helper_test_chksum(
362                &get_bank_dirpath()
363                    .join("checksum")
364                    .join("static-strt-121.work"),
365            );
366        }
367
368        #[test]
369        fn static_strt_120() {
370            helper_test_chksum(
371                &get_bank_dirpath()
372                    .join("checksum")
373                    .join("static-strt-120.work"),
374            );
375        }
376
377        #[test]
378        fn static_strt_119() {
379            helper_test_chksum(
380                &get_bank_dirpath()
381                    .join("checksum")
382                    .join("static-strt-119.work"),
383            );
384        }
385
386        #[test]
387        fn static_strt_118() {
388            helper_test_chksum(
389                &get_bank_dirpath()
390                    .join("checksum")
391                    .join("static-strt-118.work"),
392            );
393        }
394
395        #[test]
396        fn static_strt_117() {
397            helper_test_chksum(
398                &get_bank_dirpath()
399                    .join("checksum")
400                    .join("static-strt-117.work"),
401            );
402        }
403
404        #[test]
405        fn static_strt_116() {
406            helper_test_chksum(
407                &get_bank_dirpath()
408                    .join("checksum")
409                    .join("static-strt-116.work"),
410            );
411        }
412
413        #[test]
414        fn static_strt_115() {
415            helper_test_chksum(
416                &get_bank_dirpath()
417                    .join("checksum")
418                    .join("static-strt-115.work"),
419            );
420        }
421
422        #[test]
423        fn static_strt_114() {
424            helper_test_chksum(
425                &get_bank_dirpath()
426                    .join("checksum")
427                    .join("static-strt-114.work"),
428            );
429        }
430
431        #[test]
432        fn static_strt_113() {
433            helper_test_chksum(
434                &get_bank_dirpath()
435                    .join("checksum")
436                    .join("static-strt-113.work"),
437            );
438        }
439
440        #[test]
441        fn static_strt_112() {
442            helper_test_chksum(
443                &get_bank_dirpath()
444                    .join("checksum")
445                    .join("static-strt-112.work"),
446            );
447        }
448
449        #[test]
450        fn static_strt_111() {
451            helper_test_chksum(
452                &get_bank_dirpath()
453                    .join("checksum")
454                    .join("static-strt-111.work"),
455            );
456        }
457
458        #[test]
459        fn static_strt_71() {
460            helper_test_chksum(
461                &get_bank_dirpath()
462                    .join("checksum")
463                    .join("static-strt-71.work"),
464            );
465        }
466
467        #[test]
468        fn static_strt_70() {
469            helper_test_chksum(
470                &get_bank_dirpath()
471                    .join("checksum")
472                    .join("static-strt-70.work"),
473            );
474        }
475
476        #[test]
477        fn static_strt_69() {
478            helper_test_chksum(
479                &get_bank_dirpath()
480                    .join("checksum")
481                    .join("static-strt-69.work"),
482            );
483        }
484
485        #[test]
486        fn static_strt_68() {
487            helper_test_chksum(
488                &get_bank_dirpath()
489                    .join("checksum")
490                    .join("static-strt-68.work"),
491            );
492        }
493
494        #[test]
495        fn static_strt_67() {
496            helper_test_chksum(
497                &get_bank_dirpath()
498                    .join("checksum")
499                    .join("static-strt-67.work"),
500            );
501        }
502
503        #[test]
504        fn static_strt_66() {
505            helper_test_chksum(
506                &get_bank_dirpath()
507                    .join("checksum")
508                    .join("static-strt-66.work"),
509            );
510        }
511
512        #[test]
513        fn static_strt_65() {
514            helper_test_chksum(
515                &get_bank_dirpath()
516                    .join("checksum")
517                    .join("static-strt-65.work"),
518            );
519        }
520
521        #[test]
522        fn static_strt_64() {
523            helper_test_chksum(
524                &get_bank_dirpath()
525                    .join("checksum")
526                    .join("static-strt-64.work"),
527            );
528        }
529
530        #[test]
531        fn static_strt_63() {
532            helper_test_chksum(
533                &get_bank_dirpath()
534                    .join("checksum")
535                    .join("static-strt-63.work"),
536            );
537        }
538
539        #[test]
540        fn static_strt_62() {
541            helper_test_chksum(
542                &get_bank_dirpath()
543                    .join("checksum")
544                    .join("static-strt-62.work"),
545            );
546        }
547
548        #[test]
549        fn static_strt_61() {
550            helper_test_chksum(
551                &get_bank_dirpath()
552                    .join("checksum")
553                    .join("static-strt-61.work"),
554            );
555        }
556
557        #[test]
558        fn static_strt_60() {
559            helper_test_chksum(
560                &get_bank_dirpath()
561                    .join("checksum")
562                    .join("static-strt-60.work"),
563            );
564        }
565
566        #[test]
567        fn static_strt_59() {
568            helper_test_chksum(
569                &get_bank_dirpath()
570                    .join("checksum")
571                    .join("static-strt-59.work"),
572            );
573        }
574
575        #[test]
576        fn static_strt_58() {
577            helper_test_chksum(
578                &get_bank_dirpath()
579                    .join("checksum")
580                    .join("static-strt-58.work"),
581            );
582        }
583
584        #[test]
585        fn static_strt_57() {
586            helper_test_chksum(
587                &get_bank_dirpath()
588                    .join("checksum")
589                    .join("static-strt-57.work"),
590            );
591        }
592
593        #[test]
594        fn static_strt_56() {
595            helper_test_chksum(
596                &get_bank_dirpath()
597                    .join("checksum")
598                    .join("static-strt-56.work"),
599            );
600        }
601    }
602
603    mod static_strt_mult {
604        use crate::banks::checksum::helper_test_chksum;
605        use crate::test_utils::get_bank_dirpath;
606
607        #[test]
608        fn static_strt_127_len_128() {
609            // start value incremented by 127 (max) and len incremented by 127 (max) on the machine
610            helper_test_chksum(
611                &get_bank_dirpath()
612                    .join("checksum")
613                    .join("static-strt-127-len-128.work"),
614            );
615        }
616
617        #[test]
618        fn static_strt_67_len_67() {
619            helper_test_chksum(
620                &get_bank_dirpath()
621                    .join("checksum")
622                    .join("static-strt-67-len-67.work"),
623            );
624        }
625
626        #[test]
627        fn static_strt_67_len_68() {
628            helper_test_chksum(
629                &get_bank_dirpath()
630                    .join("checksum")
631                    .join("static-strt-67-len-68.work"),
632            );
633        }
634
635        #[test]
636        fn static_strt_68_len_68() {
637            helper_test_chksum(
638                &get_bank_dirpath()
639                    .join("checksum")
640                    .join("static-strt-68-len-68.work"),
641            );
642        }
643
644        #[test]
645        fn static_strt_67_len_66() {
646            helper_test_chksum(
647                &get_bank_dirpath()
648                    .join("checksum")
649                    .join("static-strt-67-len-66.work"),
650            );
651        }
652
653        #[test]
654        fn static_strt_66_len_66() {
655            helper_test_chksum(
656                &get_bank_dirpath()
657                    .join("checksum")
658                    .join("static-strt-66-len-66.work"),
659            );
660        }
661
662        #[test]
663        fn static_strt_32_len_32() {
664            helper_test_chksum(
665                &get_bank_dirpath()
666                    .join("checksum")
667                    .join("static-strt-32-len-32.work"),
668            );
669        }
670
671        #[test]
672        fn static_strt_32_len_33() {
673            helper_test_chksum(
674                &get_bank_dirpath()
675                    .join("checksum")
676                    .join("static-strt-32-len-33.work"),
677            );
678        }
679
680        #[test]
681        fn static_strt_33_len_33() {
682            helper_test_chksum(
683                &get_bank_dirpath()
684                    .join("checksum")
685                    .join("static-strt-33-len-33.work"),
686            );
687        }
688
689        #[test]
690        fn static_strt_32_len_31() {
691            helper_test_chksum(
692                &get_bank_dirpath()
693                    .join("checksum")
694                    .join("static-strt-32-len-31.work"),
695            );
696        }
697
698        #[test]
699        fn static_strt_31_len_31() {
700            helper_test_chksum(
701                &get_bank_dirpath()
702                    .join("checksum")
703                    .join("static-strt-31-len-31.work"),
704            );
705        }
706
707        #[test]
708        fn static_strt_67_len_67_rtrg_68() {
709            helper_test_chksum(
710                &get_bank_dirpath()
711                    .join("checksum")
712                    .join("static-strt-67-len-67-rtrg-68.work"),
713            );
714        }
715
716        #[test]
717        fn static_strt_67_len_68_rtrg_68() {
718            helper_test_chksum(
719                &get_bank_dirpath()
720                    .join("checksum")
721                    .join("static-strt-67-len-68-rtrg-68.work"),
722            );
723        }
724
725        #[test]
726        fn static_strt_67_len_69_rtrg_68() {
727            helper_test_chksum(
728                &get_bank_dirpath()
729                    .join("checksum")
730                    .join("static-strt-67-len-69-rtrg-68.work"),
731            );
732        }
733
734        #[test]
735        fn static_strt_67_len_69_rtrg_69() {
736            helper_test_chksum(
737                &get_bank_dirpath()
738                    .join("checksum")
739                    .join("static-strt-67-len-69-rtrg-69.work"),
740            );
741        }
742
743        #[test]
744        fn static_strt_67_len_69_rtrg_67() {
745            helper_test_chksum(
746                &get_bank_dirpath()
747                    .join("checksum")
748                    .join("static-strt-67-len-69-rtrg-67.work"),
749            );
750        }
751
752        #[test]
753        fn static_strt_67_len_67_rtrg_67() {
754            helper_test_chksum(
755                &get_bank_dirpath()
756                    .join("checksum")
757                    .join("static-strt-67-len-67-rtrg-67.work"),
758            );
759        }
760    }
761
762    mod flex_strt {
763        use crate::banks::checksum::helper_test_chksum;
764        use crate::test_utils::get_bank_dirpath;
765
766        #[test]
767        fn flex_strt_126() {
768            helper_test_chksum(
769                &get_bank_dirpath()
770                    .join("checksum")
771                    .join("flex-strt-126.work"),
772            );
773        }
774
775        #[test]
776        fn flex_strt_125() {
777            helper_test_chksum(
778                &get_bank_dirpath()
779                    .join("checksum")
780                    .join("flex-strt-125.work"),
781            );
782        }
783
784        #[test]
785        fn flex_strt_124() {
786            helper_test_chksum(
787                &get_bank_dirpath()
788                    .join("checksum")
789                    .join("flex-strt-124.work"),
790            );
791        }
792
793        #[test]
794        fn flex_strt_123() {
795            helper_test_chksum(
796                &get_bank_dirpath()
797                    .join("checksum")
798                    .join("flex-strt-123.work"),
799            );
800        }
801
802        #[test]
803        fn flex_strt_122() {
804            helper_test_chksum(
805                &get_bank_dirpath()
806                    .join("checksum")
807                    .join("flex-strt-122.work"),
808            );
809        }
810
811        #[test]
812        fn flex_strt_121() {
813            helper_test_chksum(
814                &get_bank_dirpath()
815                    .join("checksum")
816                    .join("flex-strt-121.work"),
817            );
818        }
819
820        #[test]
821        fn flex_strt_120() {
822            helper_test_chksum(
823                &get_bank_dirpath()
824                    .join("checksum")
825                    .join("flex-strt-120.work"),
826            );
827        }
828
829        #[test]
830        fn flex_strt_119() {
831            helper_test_chksum(
832                &get_bank_dirpath()
833                    .join("checksum")
834                    .join("flex-strt-119.work"),
835            );
836        }
837
838        #[test]
839        fn flex_strt_118() {
840            helper_test_chksum(
841                &get_bank_dirpath()
842                    .join("checksum")
843                    .join("flex-strt-118.work"),
844            );
845        }
846
847        #[test]
848        fn flex_strt_117() {
849            helper_test_chksum(
850                &get_bank_dirpath()
851                    .join("checksum")
852                    .join("flex-strt-117.work"),
853            );
854        }
855
856        #[test]
857        fn flex_strt_116() {
858            helper_test_chksum(
859                &get_bank_dirpath()
860                    .join("checksum")
861                    .join("flex-strt-116.work"),
862            );
863        }
864
865        #[test]
866        fn flex_strt_115() {
867            helper_test_chksum(
868                &get_bank_dirpath()
869                    .join("checksum")
870                    .join("flex-strt-115.work"),
871            );
872        }
873
874        #[test]
875        fn flex_strt_114() {
876            helper_test_chksum(
877                &get_bank_dirpath()
878                    .join("checksum")
879                    .join("flex-strt-114.work"),
880            );
881        }
882
883        #[test]
884        fn flex_strt_113() {
885            helper_test_chksum(
886                &get_bank_dirpath()
887                    .join("checksum")
888                    .join("flex-strt-113.work"),
889            );
890        }
891
892        #[test]
893        fn flex_strt_112() {
894            helper_test_chksum(
895                &get_bank_dirpath()
896                    .join("checksum")
897                    .join("flex-strt-112.work"),
898            );
899        }
900
901        #[test]
902        fn flex_strt_111() {
903            helper_test_chksum(
904                &get_bank_dirpath()
905                    .join("checksum")
906                    .join("flex-strt-111.work"),
907            );
908        }
909    }
910
911    mod track_parameters {
912        use crate::banks::checksum::helper_test_chksum;
913        use crate::test_utils::get_bank_dirpath;
914
915        #[test]
916        fn track_params_attack_127() {
917            helper_test_chksum(
918                &get_bank_dirpath()
919                    .join("checksum")
920                    .join("tparams-attack-127.work"),
921            );
922        }
923
924        #[test]
925        fn track_params_hold_0() {
926            helper_test_chksum(
927                &get_bank_dirpath()
928                    .join("checksum")
929                    .join("tparams-hold-0.work"),
930            );
931        }
932
933        #[test]
934        fn track_params_release_0() {
935            helper_test_chksum(
936                &get_bank_dirpath()
937                    .join("checksum")
938                    .join("tparams-rel-0.work"),
939            );
940        }
941        #[test]
942        fn track_params_vol_neg64() {
943            helper_test_chksum(
944                &get_bank_dirpath()
945                    .join("checksum")
946                    .join("tparams-vol-neg64.work"),
947            );
948        }
949
950        #[test]
951        fn track_params_vol_pos63() {
952            helper_test_chksum(
953                &get_bank_dirpath()
954                    .join("checksum")
955                    .join("tparams-vol-pos63.work"),
956            );
957        }
958
959        #[test]
960        fn track_params_balance_neg64() {
961            helper_test_chksum(
962                &get_bank_dirpath()
963                    .join("checksum")
964                    .join("tparams-bal-neg64.work"),
965            );
966        }
967
968        #[test]
969        fn track_params_balance_pos63() {
970            helper_test_chksum(
971                &get_bank_dirpath()
972                    .join("checksum")
973                    .join("tparams-bal-pos63.work"),
974            );
975        }
976
977        #[test]
978        fn track_params_lfo1_spd_0() {
979            helper_test_chksum(
980                &get_bank_dirpath()
981                    .join("checksum")
982                    .join("tparams-lfo1-spd-0.work"),
983            );
984        }
985
986        #[test]
987        fn track_params_lfo1_spd_127() {
988            helper_test_chksum(
989                &get_bank_dirpath()
990                    .join("checksum")
991                    .join("tparams-lfo1-spd-127.work"),
992            );
993        }
994
995        #[test]
996        fn track_params_lfo1_amt_64() {
997            helper_test_chksum(
998                &get_bank_dirpath()
999                    .join("checksum")
1000                    .join("tparams-lfo1-amt-64.work"),
1001            );
1002        }
1003
1004        #[test]
1005        fn track_params_lfo1_amt_127() {
1006            helper_test_chksum(
1007                &get_bank_dirpath()
1008                    .join("checksum")
1009                    .join("tparams-lfo1-amt-127.work"),
1010            );
1011        }
1012
1013        #[test]
1014        fn track_params_fx1_filter_base_127() {
1015            helper_test_chksum(
1016                &get_bank_dirpath()
1017                    .join("checksum")
1018                    .join("tparams-fx1-filt-base-127.work"),
1019            );
1020        }
1021
1022        #[test]
1023        fn track_params_fx1_filter_width_0() {
1024            helper_test_chksum(
1025                &get_bank_dirpath()
1026                    .join("checksum")
1027                    .join("tparams-fx1-filt-wid-0.work"),
1028            );
1029        }
1030
1031        #[test]
1032        fn track_params_fx1_filter_q_127() {
1033            helper_test_chksum(
1034                &get_bank_dirpath()
1035                    .join("checksum")
1036                    .join("tparams-fx1-filt-q-127.work"),
1037            );
1038        }
1039
1040        #[test]
1041        fn track_params_fx1_filter_depth_neg64() {
1042            helper_test_chksum(
1043                &get_bank_dirpath()
1044                    .join("checksum")
1045                    .join("tparams-fx1-filt-dep-neg64.work"),
1046            );
1047        }
1048
1049        #[test]
1050        fn track_params_fx1_filter_depth_pos63() {
1051            helper_test_chksum(
1052                &get_bank_dirpath()
1053                    .join("checksum")
1054                    .join("tparams-fx1-filt-dep-pos63.work"),
1055            );
1056        }
1057
1058        #[test]
1059        fn track_params_fx2_delay_snd_127() {
1060            // start value incremented by 127 (max) and len incremented by 127 (max) on the machine
1061            helper_test_chksum(
1062                &get_bank_dirpath()
1063                    .join("checksum")
1064                    .join("atrack1-delay-snd-127.work"),
1065            );
1066        }
1067    }
1068
1069    mod lfo_designer {
1070        use crate::banks::checksum::helper_test_chksum;
1071        use crate::test_utils::get_bank_dirpath;
1072
1073        #[test]
1074        fn lfo_design_atr1_step1_pos64() {
1075            helper_test_chksum(
1076                &get_bank_dirpath()
1077                    .join("checksum")
1078                    .join("lfo-design-step1-64.work"),
1079            );
1080        }
1081
1082        #[test]
1083        fn lfo_design_atr1_step1_pos127() {
1084            helper_test_chksum(
1085                &get_bank_dirpath()
1086                    .join("checksum")
1087                    .join("lfo-design-step1-127.work"),
1088            );
1089        }
1090
1091        #[test]
1092        fn lfo_design_atr1_step1_neg64() {
1093            helper_test_chksum(
1094                &get_bank_dirpath()
1095                    .join("checksum")
1096                    .join("lfo-design-step1-neg64.work"),
1097            );
1098        }
1099
1100        #[test]
1101        fn lfo_design_atr1_step1_neg128() {
1102            helper_test_chksum(
1103                &get_bank_dirpath()
1104                    .join("checksum")
1105                    .join("lfo-design-step1-neg128.work"),
1106            );
1107        }
1108
1109        #[test]
1110        fn lfo_design_atr1_randomised() {
1111            helper_test_chksum(
1112                &get_bank_dirpath()
1113                    .join("checksum")
1114                    .join("lfo-design-randomised.work"),
1115            );
1116        }
1117    }
1118}