1use crate::OtToolsIoError;
8use crate::{Defaults, HasHeaderField};
9use ot_tools_io_derive::{ArrayDefaults, BoxedBigArrayDefaults};
10use serde::{Deserialize, Serialize};
11use serde_big_array::{Array, BigArray};
12use std::array::from_fn;
13
14const PART_HEADER: [u8; 4] = [0x50, 0x41, 0x52, 0x54];
17
18#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
19pub enum OnOrOff {
20 On = 1,
21 Off = 0,
22}
23
24#[derive(
27 Debug, Serialize, Deserialize, Clone, PartialEq, Copy, ArrayDefaults, BoxedBigArrayDefaults,
28)]
29pub struct AudioTrackVolume {
30 pub main: u8,
31 pub cue: u8,
32}
33
34impl Default for AudioTrackVolume {
36 fn default() -> Self {
37 Self {
38 main: 0x6c, cue: 0x6c, }
41 }
42}
43
44#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
47pub struct ActiveScenes {
48 pub scene_a: u8,
49 pub scene_b: u8,
50}
51
52impl Default for ActiveScenes {
53 fn default() -> Self {
54 Self {
55 scene_a: 0,
56 scene_b: 8,
57 }
58 }
59}
60
61#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
63pub struct AudioTrackMachineParamsSetupStd {
64 pub xloop: u8,
65 pub slic: u8,
66 pub len: u8,
67 pub rate: u8,
68 pub tstr: u8,
69 pub tsns: u8,
70}
71
72#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
74pub struct AudioTrackMachineParamsSetupThru {
75 pub unused_1: u8,
76 pub unused_2: u8,
77 pub unused_3: u8,
78 pub unused_4: u8,
79 pub unused_5: u8,
80 pub unused_6: u8,
81}
82
83#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
85pub struct AudioTrackMachineParamsSetupNeighbor {
86 pub unused_1: u8,
87 pub unused_2: u8,
88 pub unused_3: u8,
89 pub unused_4: u8,
90 pub unused_5: u8,
91 pub unused_6: u8,
92}
93
94#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
96pub struct AudioTrackMachineParamsSetupPickup {
97 pub unused_1: u8,
98 pub unused_2: u8,
99 pub unused_3: u8,
100 pub unused_4: u8,
101 pub tstr: u8,
102 pub tsns: u8,
103}
104
105#[derive(
109 Debug, Serialize, Deserialize, Clone, PartialEq, Copy, ArrayDefaults, BoxedBigArrayDefaults,
110)]
111pub struct AudioTrackMachinesParamsSetup {
112 pub static_machine: AudioTrackMachineParamsSetupStd,
113 pub flex_machine: AudioTrackMachineParamsSetupStd,
114 pub thru_machine: AudioTrackMachineParamsSetupThru,
115 pub neighbor_machine: AudioTrackMachineParamsSetupNeighbor,
116 pub pickup_machine: AudioTrackMachineParamsSetupPickup,
117}
118
119impl Default for AudioTrackMachinesParamsSetup {
120 fn default() -> Self {
121 Self {
122 static_machine: AudioTrackMachineParamsSetupStd {
123 xloop: 1,
124 slic: 0,
125 len: 0,
126 rate: 0,
127 tstr: 1,
128 tsns: 64,
129 },
130 flex_machine: AudioTrackMachineParamsSetupStd {
131 xloop: 1,
132 slic: 0,
133 len: 0,
134 rate: 0,
135 tstr: 1,
136 tsns: 64,
137 },
138 thru_machine: AudioTrackMachineParamsSetupThru {
139 unused_1: 0,
140 unused_2: 0,
141 unused_3: 0,
142 unused_4: 0,
143 unused_5: 0,
144 unused_6: 0,
145 },
146 neighbor_machine: AudioTrackMachineParamsSetupNeighbor {
147 unused_1: 0,
148 unused_2: 0,
149 unused_3: 0,
150 unused_4: 0,
151 unused_5: 0,
152 unused_6: 0,
153 },
154 pickup_machine: AudioTrackMachineParamsSetupPickup {
155 unused_1: 0,
156 unused_2: 0,
157 unused_3: 0,
158 unused_4: 0,
159 tstr: 1,
160 tsns: 64,
161 },
162 }
163 }
164}
165
166#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, BoxedBigArrayDefaults)]
170pub struct AudioTrackMachineSlot {
171 pub static_slot_id: u8,
172 pub flex_slot_id: u8,
173 pub unused_1: u8,
174 pub unused_2: u8,
175 pub recorder_slot_id: u8,
176}
177
178impl Default for AudioTrackMachineSlot {
179 fn default() -> Self {
180 Self {
181 static_slot_id: 0,
182 flex_slot_id: 0,
183 unused_1: 0,
184 unused_2: 0,
185 recorder_slot_id: 128,
186 }
187 }
188}
189
190impl<const N: usize> Defaults<[Self; N]> for AudioTrackMachineSlot {
192 fn defaults() -> [Self; N]
193 where
194 Self: Default,
195 {
196 from_fn(|i| Self {
197 static_slot_id: i as u8,
198 flex_slot_id: i as u8,
199 recorder_slot_id: 128 + i as u8,
200 ..Default::default()
201 })
202 }
203}
204
205#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
207pub struct AudioTrackMachineParamsValuesStd {
208 pub ptch: u8,
209 pub strt: u8,
210 pub len: u8,
211 pub rate: u8,
212 pub rtrg: u8,
213 pub rtim: u8,
214}
215
216#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
218pub struct AudioTrackMachineParamsValuesThru {
219 pub in_ab: u8,
220 pub vol_ab: u8,
221 pub unused_1: u8,
222 pub in_cd: u8,
223 pub vol_cd: u8,
224 pub unused_2: u8,
225}
226
227#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
229pub struct AudioTrackMachineParamsValuesNeighbor {
230 pub unused_1: u8,
231 pub unused_2: u8,
232 pub unused_3: u8,
233 pub unused_4: u8,
234 pub unused_5: u8,
235 pub unused_6: u8,
236}
237
238#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
240pub struct AudioTrackMachineParamsValuesPickup {
241 pub ptch: u8,
242 pub dir: u8,
243 pub len: u8,
244 pub unused_1: u8,
245 pub gain: u8,
246 pub op: u8,
247}
248
249#[derive(
253 Debug, Serialize, Deserialize, Clone, PartialEq, Copy, ArrayDefaults, BoxedBigArrayDefaults,
254)]
255pub struct AudioTrackMachinesParamsValues {
256 pub static_machine: AudioTrackMachineParamsValuesStd,
257 pub flex_machine: AudioTrackMachineParamsValuesStd,
258 pub thru_machine: AudioTrackMachineParamsValuesThru,
259 pub neighbor_machine: AudioTrackMachineParamsValuesNeighbor,
260 pub pickup_machine: AudioTrackMachineParamsValuesPickup,
261}
262
263impl Default for AudioTrackMachinesParamsValues {
264 fn default() -> Self {
265 Self {
266 static_machine: AudioTrackMachineParamsValuesStd {
267 ptch: 64,
268 strt: 0,
269 len: 0,
270 rate: 127,
271 rtrg: 0,
272 rtim: 79,
273 },
274 flex_machine: AudioTrackMachineParamsValuesStd {
275 ptch: 64,
276 strt: 0,
277 len: 0,
278 rate: 127,
279 rtrg: 0,
280 rtim: 79,
281 },
282 thru_machine: AudioTrackMachineParamsValuesThru {
283 in_ab: 0,
284 vol_ab: 64,
285 unused_1: 0,
286 in_cd: 0,
287 vol_cd: 64,
288 unused_2: 0,
289 },
290 neighbor_machine: AudioTrackMachineParamsValuesNeighbor {
291 unused_1: 0,
292 unused_2: 0,
293 unused_3: 0,
294 unused_4: 0,
295 unused_5: 0,
296 unused_6: 0,
297 },
298 pickup_machine: AudioTrackMachineParamsValuesPickup {
299 ptch: 64,
300 dir: 2,
301 len: 1,
302 unused_1: 127,
303 gain: 64,
304 op: 1,
305 },
306 }
307 }
308}
309
310#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
313pub struct LfoParamsValues {
314 pub spd1: u8,
315 pub spd2: u8,
316 pub spd3: u8,
317 pub dep1: u8,
318 pub dep2: u8,
319 pub dep3: u8,
320}
321
322#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
324pub struct AudioTrackAmpParamsValues {
325 pub atk: u8,
326 pub hold: u8,
327 pub rel: u8,
328 pub vol: u8,
329 pub bal: u8,
330 pub f: u8,
332}
333
334#[allow(clippy::derivable_impls)]
338impl Default for AudioTrackAmpParamsValues {
339 fn default() -> Self {
340 Self {
341 atk: 0,
342 hold: 127,
343 rel: 127,
344 vol: 64,
345 bal: 64,
346 f: 127,
347 }
348 }
349}
350
351#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
353pub struct AudioTrackFxParamsValues {
354 pub param_1: u8,
355 pub param_2: u8,
356 pub param_3: u8,
357 pub param_4: u8,
358 pub param_5: u8,
359 pub param_6: u8,
360}
361
362#[derive(
364 Debug, Serialize, Deserialize, Clone, PartialEq, Copy, ArrayDefaults, BoxedBigArrayDefaults,
365)]
366pub struct AudioTrackParamsValues {
367 pub lfo: LfoParamsValues,
368 pub amp: AudioTrackAmpParamsValues,
369 pub fx1: AudioTrackFxParamsValues,
370 pub fx2: AudioTrackFxParamsValues,
371}
372
373impl Default for AudioTrackParamsValues {
374 fn default() -> Self {
375 Self {
376 lfo: LfoParamsValues {
377 spd1: 32,
378 spd2: 32,
379 spd3: 32,
380 dep1: 0,
381 dep2: 0,
382 dep3: 0,
383 },
384 amp: AudioTrackAmpParamsValues::default(),
385 fx1: AudioTrackFxParamsValues {
386 param_1: 0,
387 param_2: 127,
388 param_3: 0,
389 param_4: 64,
390 param_5: 0,
391 param_6: 64,
392 },
393 fx2: AudioTrackFxParamsValues {
394 param_1: 47,
395 param_2: 0,
396 param_3: 127,
397 param_4: 0,
398 param_5: 127,
399 param_6: 0,
400 },
401 }
402 }
403}
404
405#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
407pub struct LfoParamsSetup1 {
408 pub lfo1_pmtr: u8,
409 pub lfo2_pmtr: u8,
410 pub lfo3_pmtr: u8,
411 pub lfo1_wave: u8,
412 pub lfo2_wave: u8,
413 pub lfo3_wave: u8,
414}
415
416#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
418pub struct LfoParamsSetup2 {
419 pub lfo1_mult: u8,
420 pub lfo2_mult: u8,
421 pub lfo3_mult: u8,
422 pub lfo1_trig: u8,
423 pub lfo2_trig: u8,
424 pub lfo3_trig: u8,
425}
426
427#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
429pub struct AudioTrackAmpParamsSetup {
430 pub amp: u8,
431 pub sync: u8,
432 pub atck: u8,
433 pub fx1: u8,
434 pub fx2: u8,
435 pub unused: u8,
437}
438
439#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
441pub struct AudioTrackFxParamsSetup {
442 pub setting1: u8,
443 pub setting2: u8,
444 pub setting3: u8,
445 pub setting4: u8,
446 pub setting5: u8,
447 pub setting6: u8,
448}
449
450#[derive(
452 Debug, Serialize, Deserialize, Clone, PartialEq, Copy, ArrayDefaults, BoxedBigArrayDefaults,
453)]
454pub struct AudioTrackParamsSetup {
455 pub lfo_setup_1: LfoParamsSetup1,
457 pub amp: AudioTrackAmpParamsSetup,
459 pub fx1: AudioTrackFxParamsSetup,
461 pub fx2: AudioTrackFxParamsSetup,
463 pub lfo_setup_2: LfoParamsSetup2,
465}
466
467impl Default for AudioTrackParamsSetup {
468 fn default() -> Self {
469 Self {
470 lfo_setup_1: LfoParamsSetup1 {
471 lfo1_pmtr: 0,
472 lfo2_pmtr: 0,
473 lfo3_pmtr: 0,
474 lfo1_wave: 0,
475 lfo2_wave: 0,
476 lfo3_wave: 0,
477 },
478 amp: AudioTrackAmpParamsSetup {
479 amp: 1,
480 sync: 1,
481 atck: 0,
482 fx1: 0,
483 fx2: 0,
484 unused: 0,
485 },
486 fx1: AudioTrackFxParamsSetup {
487 setting1: 0,
488 setting2: 0,
489 setting3: 1,
490 setting4: 0,
491 setting5: 3,
492 setting6: 0,
493 },
494 fx2: AudioTrackFxParamsSetup {
495 setting1: 0,
496 setting2: 1,
497 setting3: 127,
498 setting4: 1,
499 setting5: 0,
500 setting6: 0,
501 },
502 lfo_setup_2: LfoParamsSetup2 {
503 lfo1_mult: 0,
504 lfo2_mult: 0,
505 lfo3_mult: 0,
506 lfo1_trig: 0,
507 lfo2_trig: 0,
508 lfo3_trig: 0,
509 },
510 }
511 }
512}
513
514#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
516pub struct MidiTrackMidiParamsValues {
517 pub note: u8,
518 pub vel: u8,
519 pub len: u8,
520 pub not2: u8,
521 pub not3: u8,
522 pub not4: u8,
523}
524
525#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
527pub struct MidiTrackArpParamsValues {
528 pub tran: u8,
529 pub leg: u8,
530 pub mode: u8,
531 pub spd: u8,
532 pub rnge: u8,
533 pub nlen: u8,
534}
535
536#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
538pub struct MidiTrackCc1ParamsValues {
539 pub pb: u8,
540 pub at: u8,
541 pub cc1: u8,
542 pub cc2: u8,
543 pub cc3: u8,
544 pub cc4: u8,
545}
546
547#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
549pub struct MidiTrackCc2ParamsValues {
550 pub cc5: u8,
551 pub cc6: u8,
552 pub cc7: u8,
553 pub cc8: u8,
554 pub cc9: u8,
555 pub cc10: u8,
556}
557
558#[derive(
571 Debug, Serialize, Deserialize, Clone, PartialEq, Copy, ArrayDefaults, BoxedBigArrayDefaults,
572)]
573pub struct MidiTrackParamsValues {
574 pub midi: MidiTrackMidiParamsValues,
575 pub lfo: LfoParamsValues,
576 pub arp: MidiTrackArpParamsValues,
577 pub ctrl1: MidiTrackCc1ParamsValues,
578 pub ctrl2: MidiTrackCc2ParamsValues,
579 #[serde(with = "BigArray")]
580 pub unknown: [u8; 2],
581}
582
583impl Default for MidiTrackParamsValues {
584 fn default() -> Self {
585 Self {
586 midi: MidiTrackMidiParamsValues {
587 note: 48,
588 vel: 100,
589 len: 6,
590 not2: 64,
591 not3: 64,
592 not4: 64,
593 },
594 lfo: LfoParamsValues {
595 spd1: 32,
596 spd2: 32,
597 spd3: 32,
598 dep1: 0,
599 dep2: 0,
600 dep3: 0,
601 },
602 arp: MidiTrackArpParamsValues {
603 tran: 64,
604 leg: 0,
605 mode: 0,
606 spd: 5,
607 rnge: 0,
608 nlen: 6,
609 },
610 ctrl1: MidiTrackCc1ParamsValues {
611 pb: 64,
612 at: 0,
613 cc1: 127,
614 cc2: 0,
615 cc3: 0,
616 cc4: 64,
617 },
618 ctrl2: MidiTrackCc2ParamsValues {
619 cc5: 0,
620 cc6: 0,
621 cc7: 0,
622 cc8: 0,
623 cc9: 0,
624 cc10: 0,
625 },
626 unknown: [0, 0],
627 }
628 }
629}
630
631#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
633pub struct MidiTrackNoteParamsSetup {
634 pub chan: u8,
635 pub bank: u8,
636 pub prog: u8,
637 pub unused_1: u8,
638 pub sbank: u8,
639 pub unused_2: u8,
640}
641
642#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
644pub struct MidiTrackArpParamsSetup {
645 pub unused_1: u8,
646 pub unused_2: u8,
647 pub len: u8,
649 pub unused_3: u8,
650 pub unused_4: u8,
651 pub key: u8,
654}
655
656#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
658pub struct MidiTrackCc1ParamsSetup {
659 pub unused_1: u8,
660 pub unused_2: u8,
661 pub cc1: u8,
662 pub cc2: u8,
663 pub cc3: u8,
664 pub cc4: u8,
665}
666
667#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
669pub struct MidiTrackCc2ParamsSetup {
670 pub cc5: u8,
671 pub cc6: u8,
672 pub cc7: u8,
673 pub cc8: u8,
674 pub cc9: u8,
675 pub cc10: u8,
676}
677
678#[derive(
680 Debug, Serialize, Deserialize, Clone, PartialEq, Copy, ArrayDefaults, BoxedBigArrayDefaults,
681)]
682pub struct MidiTrackParamsSetup {
683 pub note: MidiTrackNoteParamsSetup,
684 pub lfo1: LfoParamsSetup1,
685 pub arp: MidiTrackArpParamsSetup,
686 pub ctrl1: MidiTrackCc1ParamsSetup,
687 pub ctrl2: MidiTrackCc2ParamsSetup,
688 pub lfo2: LfoParamsSetup2,
689}
690
691impl Default for MidiTrackParamsSetup {
692 fn default() -> Self {
693 Self {
694 note: MidiTrackNoteParamsSetup {
695 chan: 0,
696 bank: 128,
697 prog: 128,
698 unused_1: 0,
699 sbank: 128,
700 unused_2: 0,
701 },
702 lfo1: LfoParamsSetup1 {
703 lfo1_pmtr: 0,
704 lfo2_pmtr: 0,
705 lfo3_pmtr: 0,
706 lfo1_wave: 0,
707 lfo2_wave: 0,
708 lfo3_wave: 0,
709 },
710 arp: MidiTrackArpParamsSetup {
711 unused_1: 0,
712 unused_2: 0,
713 len: 7,
714 unused_3: 0,
715 unused_4: 0,
716 key: 0,
717 },
718 ctrl1: MidiTrackCc1ParamsSetup {
719 unused_1: 0,
720 unused_2: 0,
721 cc1: 7,
722 cc2: 1,
723 cc3: 2,
724 cc4: 10,
725 },
726 ctrl2: MidiTrackCc2ParamsSetup {
727 cc5: 71,
728 cc6: 72,
729 cc7: 73,
730 cc8: 74,
731 cc9: 75,
732 cc10: 76,
733 },
734 lfo2: LfoParamsSetup2 {
735 lfo1_mult: 0,
736 lfo2_mult: 0,
737 lfo3_mult: 0,
738 lfo1_trig: 0,
739 lfo2_trig: 0,
740 lfo3_trig: 0,
741 },
742 }
743 }
744}
745
746#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ArrayDefaults, BoxedBigArrayDefaults)]
750pub struct CustomLfoDesign(pub [u8; 16]);
751
752impl Default for CustomLfoDesign {
754 fn default() -> Self {
755 Self(from_fn(|_| 0))
756 }
757}
758
759#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ArrayDefaults, BoxedBigArrayDefaults)]
763pub struct CustomLfoInterpolationMask(pub [u8; 2]);
764
765impl Default for CustomLfoInterpolationMask {
766 fn default() -> Self {
767 Self(from_fn(|_| 0))
768 }
769}
770
771#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
773pub struct RecorderSetupSources {
774 pub in_ab: u8,
775 pub in_cd: u8,
776 pub rlen: u8,
778 pub trig: u8,
779 pub src3: u8,
781 pub xloop: u8,
782}
783
784#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
786pub struct RecorderSetupProcessing {
787 pub fin: u8,
788 pub fout: u8,
789 pub ab: u8,
790 pub qrec: u8,
791 pub qpl: u8,
792 pub cd: u8,
793}
794
795#[derive(
797 Debug, Serialize, Deserialize, Clone, PartialEq, Copy, ArrayDefaults, BoxedBigArrayDefaults,
798)]
799pub struct RecorderSetup {
800 pub src: RecorderSetupSources,
801 pub proc: RecorderSetupProcessing,
802}
803
804impl Default for RecorderSetup {
805 fn default() -> Self {
806 Self {
807 src: RecorderSetupSources {
808 in_ab: 1,
809 in_cd: 1,
810 rlen: 64,
811 trig: 0,
812 src3: 0,
813 xloop: 1,
814 },
815 proc: RecorderSetupProcessing {
816 fin: 0,
817 fout: 0,
818 ab: 0,
819 qrec: 255,
820 qpl: 255,
821 cd: 0,
822 },
823 }
824 }
825}
826
827#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Copy)]
830pub struct AudioTrackSceneLockPlayback {
831 pub param1: u8,
832 pub param2: u8,
833 pub param3: u8,
834 pub param4: u8,
835 pub param5: u8,
836 pub param6: u8,
837}
838
839#[derive(
846 Debug, Serialize, Deserialize, Clone, PartialEq, Copy, ArrayDefaults, BoxedBigArrayDefaults,
847)]
848pub struct AudioTrackScenesParamsAssignments {
849 pub machine: AudioTrackSceneLockPlayback,
851 pub lfo: LfoParamsValues,
853 pub amp: AudioTrackAmpParamsValues,
855 pub fx1: AudioTrackFxParamsValues,
857 pub fx2: AudioTrackFxParamsValues,
859 pub unknown_1: u8,
863 pub unknown_2: u8,
867}
868
869impl Default for AudioTrackScenesParamsAssignments {
870 fn default() -> Self {
871 Self {
872 machine: AudioTrackSceneLockPlayback {
873 param1: 255,
874 param2: 255,
875 param3: 255,
876 param4: 255,
877 param5: 255,
878 param6: 255,
879 },
880 lfo: LfoParamsValues {
881 spd1: 255,
882 spd2: 255,
883 spd3: 255,
884 dep1: 255,
885 dep2: 255,
886 dep3: 255,
887 },
888 amp: AudioTrackAmpParamsValues {
889 atk: 255,
890 hold: 255,
891 rel: 255,
892 vol: 255,
893 bal: 255,
894 f: 255,
895 },
896 fx1: AudioTrackFxParamsValues {
897 param_1: 255,
898 param_2: 255,
899 param_3: 255,
900 param_4: 255,
901 param_5: 255,
902 param_6: 255,
903 },
904 fx2: AudioTrackFxParamsValues {
905 param_1: 255,
906 param_2: 255,
907 param_3: 255,
908 param_4: 255,
909 param_5: 255,
910 param_6: 255,
911 },
912 unknown_1: 255,
913 unknown_2: 255,
914 }
915 }
916}
917
918#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ArrayDefaults, BoxedBigArrayDefaults)]
920pub struct SceneParams(pub [AudioTrackScenesParamsAssignments; 8]);
921
922impl Default for SceneParams {
923 fn default() -> Self {
924 Self(from_fn(|_| AudioTrackScenesParamsAssignments::default()))
925 }
926}
927
928#[derive(
931 Debug, Serialize, Deserialize, Clone, PartialEq, Copy, ArrayDefaults, BoxedBigArrayDefaults,
932)]
933pub struct SceneXlvAssignments {
934 #[serde(with = "BigArray")]
938 pub track_xlvs: [u8; 8],
939
940 #[serde(with = "BigArray")]
944 pub unknown: [u8; 2],
945}
946
947impl Default for SceneXlvAssignments {
948 fn default() -> Self {
949 Self {
950 track_xlvs: from_fn(|_| 255),
951 unknown: from_fn(|_| 255),
952 }
953 }
954}
955
956#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ArrayDefaults, BoxedBigArrayDefaults)]
960pub struct MidiArpSequence(pub [u8; 16]);
961
962impl Default for MidiArpSequence {
963 fn default() -> Self {
964 Self(from_fn(|_| 0))
965 }
966}
967
968#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, BoxedBigArrayDefaults)]
970pub struct Part {
971 #[serde(with = "BigArray")]
972 pub header: [u8; 4],
973
974 #[serde(with = "BigArray")]
976 pub data_block_1: [u8; 4],
977
978 pub part_id: u8,
980
981 #[serde(with = "BigArray")]
996 pub audio_track_fx1: [u8; 8],
997
998 #[serde(with = "BigArray")]
1017 pub audio_track_fx2: [u8; 8],
1018
1019 pub active_scenes: ActiveScenes,
1021
1022 #[serde(with = "BigArray")]
1024 pub audio_track_volumes: [AudioTrackVolume; 8],
1025
1026 #[serde(with = "BigArray")]
1029 pub audio_track_machine_types: [u8; 8],
1030
1031 #[serde(with = "BigArray")]
1034 pub audio_track_machine_params: [AudioTrackMachinesParamsValues; 8],
1035
1036 #[serde(with = "BigArray")]
1039 pub audio_track_params_values: [AudioTrackParamsValues; 8],
1040
1041 #[serde(with = "BigArray")]
1044 pub audio_track_machine_setup: [AudioTrackMachinesParamsSetup; 8],
1045
1046 #[serde(with = "BigArray")]
1048 pub audio_track_machine_slots: [AudioTrackMachineSlot; 8],
1049
1050 #[serde(with = "BigArray")]
1053 pub audio_track_params_setup: [AudioTrackParamsSetup; 8],
1054
1055 #[serde(with = "BigArray")]
1058 pub midi_track_params_values: [MidiTrackParamsValues; 8],
1059
1060 #[serde(with = "BigArray")]
1063 pub midi_track_params_setup: [MidiTrackParamsSetup; 8],
1064
1065 #[serde(with = "BigArray")]
1067 pub recorder_setup: [RecorderSetup; 8],
1068
1069 #[serde(with = "BigArray")]
1073 pub scenes: [SceneParams; 16],
1074
1075 #[serde(with = "BigArray")]
1076 pub scene_xlvs: [SceneXlvAssignments; 16],
1077
1078 #[serde(with = "BigArray")]
1080 pub audio_tracks_custom_lfo_designs: [CustomLfoDesign; 8],
1081
1082 #[serde(with = "BigArray")]
1086 pub audio_tracks_custom_lfos_interpolation_masks: [CustomLfoInterpolationMask; 8],
1087
1088 #[serde(with = "BigArray")]
1090 pub midi_tracks_custom_lfos: [CustomLfoDesign; 8],
1091
1092 #[serde(with = "BigArray")]
1096 pub midi_tracks_custom_lfos_interpolation_masks: [CustomLfoInterpolationMask; 8],
1097
1098 #[serde(with = "BigArray")]
1102 pub midi_tracks_arp_mute_masks: [u8; 16],
1103
1104 pub midi_tracks_arp_seqs: [MidiArpSequence; 8],
1106}
1107
1108impl Default for Part {
1109 fn default() -> Self {
1110 Self {
1111 header: PART_HEADER,
1112 data_block_1: from_fn(|_| 0),
1113 part_id: 1,
1114 audio_track_fx1: from_fn(|_| 4),
1115 audio_track_fx2: from_fn(|_| 8),
1116 active_scenes: ActiveScenes::default(),
1117 audio_track_volumes: AudioTrackVolume::defaults(),
1118 audio_track_machine_types: from_fn(|_| 0),
1119 audio_track_machine_params: AudioTrackMachinesParamsValues::defaults(),
1120 audio_track_params_values: AudioTrackParamsValues::defaults(),
1121 audio_track_machine_setup: AudioTrackMachinesParamsSetup::defaults(),
1122 audio_track_machine_slots: AudioTrackMachineSlot::defaults(),
1123 audio_track_params_setup: AudioTrackParamsSetup::defaults(),
1124 midi_track_params_values: MidiTrackParamsValues::defaults(),
1125 midi_track_params_setup: MidiTrackParamsSetup::defaults(),
1126 recorder_setup: RecorderSetup::defaults(),
1127 scenes: SceneParams::defaults(),
1128 scene_xlvs: SceneXlvAssignments::defaults(),
1129 audio_tracks_custom_lfo_designs: CustomLfoDesign::defaults(),
1130 audio_tracks_custom_lfos_interpolation_masks: CustomLfoInterpolationMask::defaults(),
1131 midi_tracks_custom_lfos: CustomLfoDesign::defaults(),
1132 midi_tracks_custom_lfos_interpolation_masks: CustomLfoInterpolationMask::defaults(),
1133 midi_tracks_arp_mute_masks: from_fn(|_| 255),
1134 midi_tracks_arp_seqs: MidiArpSequence::defaults(),
1135 }
1136 }
1137}
1138
1139impl<const N: usize> Defaults<[Self; N]> for Part {
1141 fn defaults() -> [Self; N]
1142 where
1143 Self: Default,
1144 {
1145 from_fn(|i| Self {
1146 part_id: i as u8,
1147 ..Default::default()
1148 })
1149 }
1150}
1151
1152impl HasHeaderField for Part {
1153 fn check_header(&self) -> Result<bool, OtToolsIoError> {
1154 Ok(self.header == PART_HEADER)
1155 }
1156}
1157
1158#[cfg(test)]
1159mod part_header_field {
1160 use crate::{
1161 test_utils::get_blank_proj_dirpath, BankFile, HasHeaderField, OctatrackFileIO,
1162 OtToolsIoError,
1163 };
1164 #[test]
1165 fn valid() -> Result<(), OtToolsIoError> {
1166 let path = get_blank_proj_dirpath().join("bank01.work");
1167 let parts = BankFile::from_data_file(&path)?.parts.saved.clone();
1168 let part = parts[0].clone();
1169 assert!(part.check_header()?);
1170 Ok(())
1171 }
1172
1173 #[test]
1174 fn invalid() -> Result<(), OtToolsIoError> {
1175 let path = get_blank_proj_dirpath().join("bank01.work");
1176 let parts = BankFile::from_data_file(&path)?.parts.saved.clone();
1177 let mut part = parts[0].clone();
1178
1179 part.header[0] = 255;
1180 part.header[1] = 255;
1181 part.header[2] = 255;
1182 part.header[3] = 255;
1183
1184 assert!(!part.check_header()?);
1185 Ok(())
1186 }
1187}
1188
1189#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
1191pub struct Parts {
1192 pub unsaved: Box<Array<Part, 4>>,
1196 pub saved: Box<Array<Part, 4>>,
1200}
1201
1202impl Default for Parts {
1203 fn default() -> Self {
1204 Self {
1205 unsaved: Part::defaults(),
1206 saved: Part::defaults(),
1207 }
1208 }
1209}
1210
1211impl HasHeaderField for Parts {
1212 fn check_header(&self) -> Result<bool, OtToolsIoError> {
1213 let unsaved = self
1214 .unsaved
1215 .iter()
1216 .all(|x| x.check_header().is_ok_and(|x| x));
1217 let saved = self.saved.iter().all(|x| x.check_header().is_ok_and(|x| x));
1218
1219 Ok(saved && unsaved)
1220 }
1221}
1222
1223#[cfg(test)]
1224mod parts_header_field {
1225 use crate::{
1226 test_utils::get_blank_proj_dirpath, BankFile, HasHeaderField, OctatrackFileIO,
1227 OtToolsIoError,
1228 };
1229 #[test]
1230 fn valid() -> Result<(), OtToolsIoError> {
1231 let path = get_blank_proj_dirpath().join("bank01.work");
1232 let parts = BankFile::from_data_file(&path)?.parts;
1233 assert!(parts.check_header()?);
1234 Ok(())
1235 }
1236
1237 #[test]
1238 fn invalid() -> Result<(), OtToolsIoError> {
1239 let path = get_blank_proj_dirpath().join("bank01.work");
1240 let mut parts = BankFile::from_data_file(&path)?.parts;
1241
1242 parts.saved[0].header[0] = 255;
1243 parts.saved[0].header[1] = 255;
1244 parts.saved[0].header[2] = 255;
1245 parts.saved[0].header[3] = 255;
1246
1247 assert!(!parts.check_header()?);
1248 Ok(())
1249 }
1250}