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