m8_file_parser/instruments/
hypersynth.rs1use super::common::SynthParams;
2use super::common::TranspEq;
3use super::common::COMMON_FILTER_TYPES;
4use super::dests;
5use super::CommandPack;
6use super::Version;
7use crate::reader::*;
8use crate::writer::Writer;
9use crate::FIRMWARE_6_0_SONG_VERSION;
10use crate::FIRMWARE_6_2_SONG_VERSION;
11use crate::SEND_COMMAND_NAMES;
12use crate::SEND_COMMAND_NAMES_6_2;
13
14use arr_macro::arr;
15use array_concat::concat_arrays;
16
17#[derive(PartialEq, Debug, Clone)]
18pub struct HyperSynth {
19 pub number: u8,
20 pub name: String,
21 pub transpose: bool,
22 pub table_tick: u8,
23 pub synth_params: SynthParams,
24
25 pub scale: u8,
26 pub default_chord: [u8; 7],
27 pub shift: u8,
28 pub swarm: u8,
29 pub width: u8,
30 pub subosc: u8,
31
32 pub chords: [[u8; 6]; 0x10],
33}
34
35#[rustfmt::skip] const HYPERSYNTH_COMMAND_NAMES_BASE : [&'static str; CommandPack::BASE_INSTRUMENT_COMMAND_COUNT - 3] = [
37 "VOL",
38 "PIT",
39 "FIN",
40 "CRD",
41 "SHF",
42 "SWM",
43 "WID",
44 "SUB",
45 "FLT",
46 "CUT",
47 "RES",
48 "AMP",
49 "LIM",
50 "PAN",
51 "DRY"
52];
53
54
55#[rustfmt::skip] const HYPERSYNTH_COMMAND_NAMES : [&'static str; CommandPack::BASE_INSTRUMENT_COMMAND_COUNT + 2] =
57 concat_arrays!(HYPERSYNTH_COMMAND_NAMES_BASE, SEND_COMMAND_NAMES, ["CVO", "SNC"]);
58
59#[rustfmt::skip] const HYPERSYNTH_COMMAND_NAMES_BASE_6 : [&'static str; CommandPack::BASE_INSTRUMENT_COMMAND_COUNT - 3] = [
61 "VOL",
62 "PIT",
63 "FIN",
64 "CRD",
65 "CVO",
66 "SWM",
67 "WID",
68 "SUB",
69 "FLT",
70 "CUT",
71 "RES",
72 "AMP",
73 "LIM",
74 "PAN",
75 "DRY"
76];
77
78
79#[rustfmt::skip] const HYPERSYNTH_COMMAND_NAMES_6 : [&'static str; CommandPack::BASE_INSTRUMENT_COMMAND_COUNT + 2] =
81 concat_arrays!(HYPERSYNTH_COMMAND_NAMES_BASE_6, SEND_COMMAND_NAMES, ["SNC", "ERR"]);
82
83#[rustfmt::skip] const HYPERSYNTH_COMMAND_NAMES_6_2 : [&'static str; CommandPack::BASE_INSTRUMENT_COMMAND_COUNT + 2] =
85 concat_arrays!(HYPERSYNTH_COMMAND_NAMES_BASE_6, SEND_COMMAND_NAMES_6_2, ["SNC", "ERR"]);
86
87#[rustfmt::skip] const DESTINATIONS : [&'static str; 15] = [
89 dests::OFF,
90 dests::VOLUME,
91 dests::PITCH,
92
93 "SHIFT",
94 "SWARM",
95 "WIDTH",
96 "SUBOSC",
97 dests::CUTOFF,
98 dests::RES,
99 dests::AMP,
100 dests::PAN,
101 dests::MOD_AMT,
102 dests::MOD_RATE,
103 dests::MOD_BOTH,
104 dests::MOD_BINV,
105];
106
107impl HyperSynth {
108 const MOD_OFFSET: usize = 23;
109
110 pub fn command_name(&self, ver: Version) -> &'static [&'static str] {
111 if ver.after(&FIRMWARE_6_2_SONG_VERSION) {
112 &HYPERSYNTH_COMMAND_NAMES_6_2
113 } else if ver.after(&FIRMWARE_6_0_SONG_VERSION) {
114 &HYPERSYNTH_COMMAND_NAMES_6
115 } else {
116 &HYPERSYNTH_COMMAND_NAMES
117 }
118 }
119
120 pub fn destination_names(&self, _ver: Version) -> &'static [&'static str] {
121 &DESTINATIONS
122 }
123
124 pub fn filter_types(&self, _ver: Version) -> &'static [&'static str] {
126 &super::common::COMMON_FILTER_TYPES
127 }
128
129 pub fn human_readable_filter(&self) -> &'static str {
130 COMMON_FILTER_TYPES[self.synth_params.filter_type as usize]
131 }
132
133 pub fn write(&self, ver: Version, w: &mut Writer) {
134 w.write_string(&self.name, 12);
135 w.write(TranspEq::from(ver, self.transpose, self.synth_params.associated_eq).into());
136 w.write(self.table_tick);
137 w.write(self.synth_params.volume);
138 w.write(self.synth_params.pitch);
139 w.write(self.synth_params.fine_tune);
140
141 for c in self.default_chord {
142 w.write(c);
143 }
144
145 w.write(self.scale);
146 w.write(self.shift);
147 w.write(self.swarm);
148 w.write(self.width);
149 w.write(self.subosc);
150
151 self.synth_params.write(ver, w, HyperSynth::MOD_OFFSET);
152
153 for chd in self.chords {
154 w.write(0xFF);
155 for k in chd {
156 w.write(k);
157 }
158 }
159 }
160
161 fn load_chord(reader: &mut Reader) -> [u8; 6] {
162 let _ = reader.read();
164 arr![reader.read(); 6]
165 }
166
167 pub fn from_reader(ver: Version, reader: &mut Reader, number: u8) -> M8Result<Self> {
168 let name = reader.read_string(12);
169 let transp_eq = TranspEq::from_version(ver, reader.read());
170 let table_tick = reader.read();
171 let volume = reader.read();
172 let pitch = reader.read();
173 let fine_tune = reader.read();
174
175 let default_chord = arr![reader.read(); 7];
176 let scale = reader.read();
177 let shift = reader.read();
178 let swarm = reader.read();
179 let width = reader.read();
180 let subosc = reader.read();
181 let synth_params = SynthParams::from_reader3(
182 ver,
183 reader,
184 volume,
185 pitch,
186 fine_tune,
187 transp_eq.eq,
188 HyperSynth::MOD_OFFSET,
189 )?;
190
191 let chords = arr![HyperSynth::load_chord(reader); 0x10];
192
193 Ok(HyperSynth {
194 number,
195 name,
196 transpose: transp_eq.transpose,
197 table_tick,
198 synth_params,
199
200 scale,
201 default_chord,
202 shift,
203 swarm,
204 width,
205 subosc,
206 chords,
207 })
208 }
209}