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