1use num_enum::{IntoPrimitive, TryFromPrimitive};
2
3use crate::{reader::*, Version};
4
5#[derive(PartialEq, Debug, Clone)]
6pub struct MidiSettings {
7 pub receive_sync: bool,
8 pub receive_transport: u8,
9 pub send_sync: bool,
10 pub send_transport: u8,
11 pub record_note_channel: u8,
12 pub record_note_velocity: bool,
13 pub record_note_delay_kill_commands: u8,
14 pub control_map_channel: u8,
15 pub song_row_cue_channel: u8,
16 pub track_input_channel: [u8; 8],
17 pub track_input_intrument: [u8; 8],
18 pub track_input_program_change: bool,
19 pub track_input_mode: u8,
20}
21
22impl TryFrom<&mut Reader> for MidiSettings {
23 type Error = ParseError;
24
25 fn try_from(reader: &mut Reader) -> M8Result<Self> {
26 Ok(Self {
27 receive_sync: reader.read_bool(),
28 receive_transport: reader.read(),
29 send_sync: reader.read_bool(),
30 send_transport: reader.read(),
31 record_note_channel: reader.read(),
32 record_note_velocity: reader.read_bool(),
33 record_note_delay_kill_commands: reader.read(),
34 control_map_channel: reader.read(),
35 song_row_cue_channel: reader.read(),
36 track_input_channel: reader.read_bytes(8).try_into().unwrap(),
37 track_input_intrument: reader.read_bytes(8).try_into().unwrap(),
38 track_input_program_change: reader.read_bool(),
39 track_input_mode: reader.read(),
40 })
41 }
42}
43
44#[derive(PartialEq, Debug, Clone)]
45pub struct LimiterParameter {
46 pub level: u8,
47 pub attack_release: Option<(u8, u8, bool)>
48}
49
50#[derive(PartialEq, Debug, Clone)]
51pub struct MixerSettings {
52 pub master_volume: u8,
53 pub track_volume: [u8; 8],
54 pub chorus_volume: u8,
55 pub delay_volume: u8,
56 pub reverb_volume: u8,
57 pub analog_input: AnalogInputSettings,
58 pub usb_input: InputMixerSettings,
59 pub dj_filter: u8,
60 pub dj_peak: u8,
61 pub dj_filter_type: u8,
62 pub limiter: LimiterParameter,
63 pub ott_level: Option<u8>
64}
65
66impl MixerSettings {
67 pub(crate) fn from_reader(reader: &mut Reader, ver: Version) -> M8Result<Self> {
68 let master_volume = reader.read();
69 let master_limit = reader.read();
70 let track_volume: [u8; 8] = reader.read_bytes(8).try_into().unwrap();
71 let chorus_volume = reader.read();
72 let delay_volume = reader.read();
73 let reverb_volume = reader.read();
74 let analog_input_volume = (reader.read(), reader.read());
75 let usb_input_volume = reader.read();
76
77 let analog_input_l =
78 InputMixerSettings::from_reader(reader, analog_input_volume.0);
79 let analog_input_r =
80 InputMixerSettings::from_reader(reader, analog_input_volume.0);
81 let usb_input_chorus = reader.read();
82 let usb_input_delay = reader.read();
83 let usb_input_reverb = reader.read();
84
85 let analog_input = if analog_input_volume.1 == 255 {
86 AnalogInputSettings::Stereo(analog_input_l)
87 } else {
88 AnalogInputSettings::DualMono((analog_input_l, analog_input_r))
89 };
90 let usb_input = InputMixerSettings {
91 volume: usb_input_volume,
92 mfx: usb_input_chorus,
93 delay: usb_input_delay,
94 reverb: usb_input_reverb,
95 };
96
97 let dj_filter = reader.read();
98 let dj_peak = reader.read();
99 let dj_filter_type = reader.read();
100
101 let limiter_conf = if !ver.at_least(6, 0) {
102 None
103 } else {
104 let limiter_attack = reader.read();
105 let limiter_release = reader.read();
106 let soft_clip = reader.read();
107 Some((limiter_attack, limiter_release, soft_clip != 0))
108 };
109
110 let ott_level = if ver.at_least(6, 1) {
111 Some(reader.read())
112 } else {
113 None
114 };
115
116 Ok(Self {
117 master_volume,
118 track_volume,
119 chorus_volume,
120 delay_volume,
121 reverb_volume,
122 analog_input,
123 usb_input,
124 dj_filter,
125 dj_peak,
126 dj_filter_type,
127 limiter: LimiterParameter {
128 level: master_limit,
129 attack_release: limiter_conf
130 },
131 ott_level
132 })
133 }
134}
135
136#[derive(PartialEq, Debug, Clone)]
137pub struct InputMixerSettings {
138 pub volume: u8,
139 pub mfx: u8,
140 pub delay: u8,
141 pub reverb: u8,
142}
143
144impl InputMixerSettings {
145 pub fn from_reader(reader: &mut Reader, volume: u8) -> Self {
146 let chorus = reader.read();
147 let delay = reader.read();
148 let reverb = reader.read();
149
150 Self {
151 volume, mfx: chorus, delay, reverb
152 }
153 }
154}
155
156#[derive(PartialEq, Debug, Clone)]
157pub enum AnalogInputSettings {
158 Stereo(InputMixerSettings),
159 DualMono((InputMixerSettings, InputMixerSettings)),
160}
161
162#[derive(PartialEq, Debug, Clone)]
165pub struct EffectFilter {
166 pub high_pass: u8,
167 pub low_pass: u8
168}
169
170impl EffectFilter {
171 fn from_reader(reader: &mut Reader) -> M8Result<Self> {
172 let high_pass = reader.read();
173 let low_pass = reader.read();
174 Ok(EffectFilter { high_pass, low_pass })
175 }
176}
177
178#[repr(u8)]
179#[allow(non_camel_case_types)]
180#[derive(IntoPrimitive, TryFromPrimitive, PartialEq, Copy, Clone, Default, Debug)]
181pub enum FxKind {
182 #[default]
183 Chorus,
184 Phaser,
185 Flanger
186}
187
188#[derive(PartialEq, Debug, Clone)]
189pub struct OttConfiguration {
190 pub time: u8,
191 pub color: u8
192}
193
194impl OttConfiguration {
195 pub(crate) fn from_reader(reader: &mut Reader, _version: Version) -> M8Result<Self> {
196 Ok(Self {
197 time: reader.read(),
198 color: reader.read()
199 })
200 }
201}
202
203#[derive(PartialEq, Debug, Clone)]
204pub struct EffectsSettings {
205 pub mfx_kind : Option<FxKind>,
206 pub chorus_mod_depth: u8,
207 pub chorus_mod_freq: u8,
208 pub chorus_width: u8,
209 pub chorus_reverb_send: u8,
210
211 pub delay_filter: Option<EffectFilter>,
212 pub delay_time_l: u8,
213 pub delay_time_r: u8,
214 pub delay_feedback: u8,
215 pub delay_width: u8,
216 pub delay_reverb_send: u8,
217
218 pub reverb_filter: Option<EffectFilter>,
219 pub reverb_size: u8,
220 pub reverb_damping: u8,
221 pub reverb_mod_depth: u8,
222 pub reverb_mod_freq: u8,
223 pub reverb_width: u8,
224 pub reverb_shimmer: Option<u8>,
225 pub ott_configuration: Option<OttConfiguration>
226}
227
228impl EffectsSettings {
229 pub(crate) fn from_reader(reader: &mut Reader, version: Version) -> M8Result<Self> {
230 let chorus_mod_depth = reader.read();
231 let chorus_mod_freq = reader.read();
232 let chorus_width = reader.read();
233 let chorus_reverb_send = reader.read();
234 reader.read_bytes(3); let delay_filter= EffectFilter::from_reader(reader)?;
237 let delay_filter = if version.at_least(4, 0) {
238 None
239 } else {
240 Some(delay_filter)
241 };
242
243 let delay_time_l = reader.read();
244 let delay_time_r = reader.read();
245 let delay_feedback = reader.read();
246 let delay_width = reader.read();
247 let delay_reverb_send = reader.read();
248 reader.read_bytes(1); let reverb_filter= EffectFilter::from_reader(reader)?;
251 let reverb_filter = if version.at_least(4, 0) {
252 None
253 } else {
254 Some(reverb_filter)
255 };
256
257 let reverb_size = reader.read();
258 let reverb_damping = reader.read();
259 let reverb_mod_depth = reader.read();
260 let reverb_mod_freq = reader.read();
261 let reverb_width = reader.read();
262 let (reverb_shimmer, ott_configuration, mfx_kind) =
263 if version.at_least(6, 1) {
264 let shimmer = Some(reader.read());
265 let ott = OttConfiguration::from_reader(reader, version)?;
266 let mfx = reader.read();
267 let kind =
268 mfx.try_into().map_err(| _| ParseError(format!("Unknown MFX kind {}", mfx)))?;
269 (shimmer, Some(ott), Some(kind))
270
271 } else {
272 (None, None, None)
273 };
274
275 Ok(Self {
276 mfx_kind,
277 chorus_mod_depth,
278 chorus_mod_freq,
279 chorus_width,
280 chorus_reverb_send,
281
282 delay_filter,
283 delay_time_l,
284 delay_time_r,
285 delay_feedback,
286 delay_width,
287 delay_reverb_send,
288
289 reverb_filter,
290 reverb_size,
291 reverb_damping,
292 reverb_mod_depth,
293 reverb_mod_freq,
294 reverb_width,
295 reverb_shimmer,
296 ott_configuration
297 })
298 }
299}
300
301#[derive(PartialEq, Debug, Clone)]
302pub struct MidiMapping {
303 pub channel: u8,
304 pub control_number: u8,
305 pub value: u8,
306 pub typ: u8,
307 pub param_index: u8,
308 pub min_value: u8,
309 pub max_value: u8,
310}
311
312impl MidiMapping {
313 pub(crate) fn from_reader(reader: &mut Reader) -> M8Result<Self> {
314 Ok(Self {
315 channel: reader.read(),
316 control_number: reader.read(),
317 value: reader.read(),
318 typ: reader.read(),
319 param_index: reader.read(),
320 min_value: reader.read(),
321 max_value: reader.read(),
322 })
323 }
324
325 pub fn empty(&self) -> bool {
326 self.channel == 0
327 }
328}