ot_tools_io/projects/settings/control_menu.rs
1/*
2SPDX-License-Identifier: GPL-3.0-or-later
3Copyright © 2024 Mike Robeson [dijksterhuis]
4*/
5
6//! Data structures for the Octatrack Project Settings 'Control Menu'.
7
8use crate::RBoxErr;
9use serde::{Deserialize, Serialize};
10use std::collections::HashMap;
11
12use crate::projects::settings::MidiChannel;
13use crate::projects::{parse_hashmap_string_value, parse_hashmap_string_value_bool, FromHashMap};
14use crate::OptionEnumValueConvert;
15
16/// Convenience struct for all data related to the Octatrack Project Settings 'Control' Menu.
17
18#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
19pub struct ControlMenu {
20 /// 'Audio' page
21 pub audio: AudioControlPage,
22
23 /// 'Input' page
24 pub input: InputControlPage,
25
26 /// 'Sequencer' page
27 pub sequencer: SequencerControlPage,
28
29 /// 'MIDI Sequencer' page
30 // TODO?!?!?!??!
31 pub midi_sequencer: MidiSequencerControlPage,
32
33 /// 'Memory' page
34 pub memory: MemoryControlPage,
35
36 /// 'Metronome' page
37 pub metronome: MetronomeControlPage,
38
39 /// 'Midi' sub menu
40 pub midi: MidiSubMenu,
41}
42
43impl FromHashMap for ControlMenu {
44 type A = String;
45 type B = String;
46 type T = Self;
47
48 fn from_hashmap(hmap: &HashMap<String, String>) -> RBoxErr<Self> {
49 let audio = AudioControlPage::from_hashmap(hmap)?;
50 let input = InputControlPage::from_hashmap(hmap)?;
51 let sequencer = SequencerControlPage::from_hashmap(hmap)?;
52 let midi_sequencer = MidiSequencerControlPage {};
53 let memory = MemoryControlPage::from_hashmap(hmap)?;
54 let metronome = MetronomeControlPage::from_hashmap(hmap)?;
55 let midi = MidiSubMenu::from_hashmap(hmap)?;
56
57 Ok(Self {
58 audio,
59 input,
60 sequencer,
61 midi_sequencer,
62 memory,
63 metronome,
64 midi,
65 })
66 }
67}
68
69/// Convenience struct for all data related to the 'MIDI' sub-menu
70/// within the Octatrack Project Settings 'Control' Menu.
71
72#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
73pub struct MidiSubMenu {
74 pub control: MidiControlMidiPage,
75 pub sync: MidiSyncMidiPage,
76 pub channels: MidiChannelsMidiPage,
77 // TODO?!?!
78 // control_midi_turbo: todo!(),
79}
80
81impl FromHashMap for MidiSubMenu {
82 type A = String;
83 type B = String;
84 type T = Self;
85
86 fn from_hashmap(hmap: &HashMap<String, String>) -> RBoxErr<Self> {
87 let control = MidiControlMidiPage::from_hashmap(hmap)?;
88 let sync = MidiSyncMidiPage::from_hashmap(hmap)?;
89 let channels = MidiChannelsMidiPage::from_hashmap(hmap)?;
90 Ok(Self {
91 control,
92 sync,
93 channels,
94 })
95 }
96}
97
98/// `PROJECT` -> `CONTROL` -> `AUDIO` UI menu.
99
100#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
101pub struct AudioControlPage {
102 /// `TRACK 8` setting. Whether Track 8 is a master audio track or not:
103 /// - **NORMAL**: `false`
104 /// - **MASTER**: `true`
105 pub master_track: bool,
106
107 /// `CUE CFG` setting. Behaviour for audio routing to CUE outputs.
108 /// - **NORMAL** -> **CUE+TRACK** button combo sends audio to CUE out.
109 /// - **STUDIO** -> Individual track volume controls for CUE out (unable to **CUE+TRACK**).
110 pub cue_studio_mode: bool,
111}
112
113impl FromHashMap for AudioControlPage {
114 type A = String;
115 type B = String;
116 type T = Self;
117
118 fn from_hashmap(hmap: &HashMap<String, String>) -> RBoxErr<Self> {
119 Ok(Self {
120 master_track: parse_hashmap_string_value_bool(hmap, "master_track", None)?,
121 cue_studio_mode: parse_hashmap_string_value_bool(hmap, "cue_studio_mode", None)?,
122 })
123 }
124}
125
126/// `PROJECT` -> `CONTROL` -> `INPUT` UI menu.
127
128#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
129pub struct InputControlPage {
130 /// dB level of noise gate for the AB external audio inputs.
131 /// See Manual section 8.8 MIXER MENU
132 pub gate_ab: u8, // 127 is default so i assume this is u8? midpoint?
133
134 /// dB level of noise gate for the CD external audio inputs.
135 /// See Manual section 8.8 MIXER MENU
136 pub gate_cd: u8, // 127 is default so i assume this is u8? midpoint?
137
138 /// See Manual section 8.6.2. INPUT.
139 /// Adds a delay to incoming external audio signals. Controlled by the DIR setting on the MIXER page.
140 pub input_delay_compensation: bool,
141}
142
143impl FromHashMap for InputControlPage {
144 type A = String;
145 type B = String;
146 type T = Self;
147
148 fn from_hashmap(hmap: &HashMap<String, String>) -> RBoxErr<Self> {
149 Ok(Self {
150 gate_ab: parse_hashmap_string_value::<u8>(hmap, "gate_ab", None)?,
151 gate_cd: parse_hashmap_string_value::<u8>(hmap, "gate_cd", None)?,
152 input_delay_compensation: parse_hashmap_string_value_bool(
153 hmap,
154 "input_delay_compensation",
155 None,
156 )?,
157 })
158 }
159}
160
161/// `PROJECT` -> `CONTROL` -> `SEQUENCER` UI menu.
162
163#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
164pub struct SequencerControlPage {
165 /// `CHAIN AFTER` setting.
166 /// When chained patterns start playing once the pattern is chosen.
167 /// This is the global project level setting, but can be overidden for each pattern.
168 /// Default setting is "PATTERN LENGTH".
169 /// See Manual section 8.6.3. SEQUENCER.
170 pub pattern_change_chain_behaviour: u8, // bool?
171
172 /// `SILENCE TRACKS` setting
173 /// Silence tracks when switching to a new pattern.
174 /// See Manual section 8.6.3. SEQUENCER.
175 pub pattern_change_auto_silence_tracks: bool,
176
177 /// `LFO AUTO CHANGE` setting.
178 /// Whether to retrigger LFOs when swtiching to a new pattern
179 /// See Manual section 8.6.3. SEQUENCER.
180 pub pattern_change_auto_trig_lfos: bool,
181}
182
183impl FromHashMap for SequencerControlPage {
184 type A = String;
185 type B = String;
186 type T = Self;
187
188 fn from_hashmap(hmap: &HashMap<String, String>) -> RBoxErr<Self> {
189 Ok(Self {
190 pattern_change_chain_behaviour: parse_hashmap_string_value::<u8>(
191 hmap,
192 "pattern_change_chain_behavior",
193 None,
194 )?,
195 pattern_change_auto_silence_tracks: parse_hashmap_string_value_bool(
196 hmap,
197 "pattern_change_auto_trig_lfos",
198 None,
199 )?,
200 pattern_change_auto_trig_lfos: parse_hashmap_string_value_bool(
201 hmap,
202 "pattern_change_auto_trig_lfos",
203 None,
204 )?,
205 })
206 }
207}
208
209/// `PROJECT` -> `CONTROL` -> `MIDI SEQUENCER` UI menu.
210// TODO: ?!?!?!?! Where is the value for this??!?!?!
211#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
212pub struct MidiSequencerControlPage {}
213
214/// `PROJECT` -> `CONTROL` -> `MEMORY` UI menu.
215
216#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
217pub struct MemoryControlPage {
218 /// Whether samples can be loaded in 24-bit depth (16 bit depth samples are always oaded as 16 bit).
219 /// Setting this to false loads all samples as 16 bit depth.
220 /// See Manual section 8.6.5. MEMORY.
221 pub load_24bit_flex: bool,
222
223 /// Disabled forces all recorders to use track recorder memory (16 seconds per track).
224 /// When enabled, track recorders can use free Flex RAM memory.
225 /// See Manual section 8.6.5. MEMORY.
226 pub dynamic_recorders: bool,
227
228 /// Whether to record in 24 bit depth (`true`) or 16 bit depth (`false`).
229 /// See Manual section 8.6.5. MEMORY.
230 pub record_24bit: bool,
231
232 /// How many active track recorders are available in a project. Controls whether TR1 through to TR8 are enabled / disabled.
233 /// See Manual section 8.6.5. MEMORY.
234 pub reserved_recorder_count: u8,
235
236 /// How many 'sequencer steps' should be reserved for track recorders in RAM.
237 /// See Manual section 8.6.5. MEMORY.
238 pub reserved_recorder_length: u32,
239}
240
241impl FromHashMap for MemoryControlPage {
242 type A = String;
243 type B = String;
244 type T = Self;
245
246 fn from_hashmap(hmap: &HashMap<String, String>) -> RBoxErr<Self> {
247 Ok(Self {
248 load_24bit_flex: parse_hashmap_string_value_bool(hmap, "load_24bit_flex", None)?,
249 dynamic_recorders: parse_hashmap_string_value_bool(hmap, "dynamic_recorders", None)?,
250 record_24bit: parse_hashmap_string_value_bool(hmap, "record_24bit", None)?,
251 reserved_recorder_count: parse_hashmap_string_value::<u8>(
252 hmap,
253 "reserved_recorder_count",
254 None,
255 )?,
256 reserved_recorder_length: parse_hashmap_string_value::<u32>(
257 hmap,
258 "reserved_recorder_length",
259 None,
260 )?,
261 })
262 }
263}
264
265/// `PROJECT` -> `CONTROL` -> `METRONOME` UI menu.
266
267#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
268pub struct MetronomeControlPage {
269 /// `TIME SIG. NUMER` setting in `PROJECT` -> `CONTROL` -> `METRONOME` UI menu.
270 /// Controls the numerator for time signature (the 3 in 3/4).
271 /// See Manual section 8.6.6 METRONOME
272 pub metronome_time_signature: u8, // i'm guessing 3 is actually 4/4? 0-indexed
273
274 /// `TIME SIG. DENOM` setting in `PROJECT` -> `CONTROL` -> `METRONOME` UI menu.
275 /// Controls the numerator for time signature (the 3 in 3/4).
276 /// See Manual section 8.6.6 METRONOME
277 pub metronome_time_signature_denominator: u8, // i'm guessing 2 is actually 4/4? 0-indexed
278
279 /// `PREROLL` setting in `PROJECT` -> `CONTROL` -> `METRONOME` UI menu.
280 /// How many bars to prerolls with the metronome before playing a pattern.
281 /// See Manual section 8.6.6 METRONOME
282 pub metronome_preroll: u8, // what is the maximum for this?
283
284 /// How loud to play the metronome on CUE outputs. Default is 32.
285 /// See Manual section 8.6.6 METRONOME
286 pub metronome_cue_volume: u8,
287
288 /// How loud to play the metronome on MAIN outputs. Default is 0.
289 /// See Manual section 8.6.6 METRONOME
290 pub metronome_main_volume: u8,
291
292 /// Pitch of the metronome clicks. Default is 12.
293 /// See Manual section 8.6.6 METRONOME
294 pub metronome_pitch: u8,
295
296 /// Whether the metronome click has tonal characteristics or not. Default is `true` (enabled).
297 /// See Manual section 8.6.6 METRONOME
298 pub metronome_tonal: bool,
299
300 /// Whether the metronome is active. Default is `false`.
301 /// See Manual section 8.6.6 METRONOME
302 pub metronome_enabled: bool,
303}
304
305impl FromHashMap for MetronomeControlPage {
306 type A = String;
307 type B = String;
308 type T = Self;
309
310 fn from_hashmap(hmap: &HashMap<String, String>) -> RBoxErr<Self> {
311 Ok(Self {
312 metronome_time_signature: parse_hashmap_string_value::<u8>(
313 hmap,
314 "metronome_time_signature",
315 None,
316 )?,
317 metronome_time_signature_denominator: parse_hashmap_string_value::<u8>(
318 hmap,
319 "metronome_time_signature_denominator",
320 None,
321 )?,
322 metronome_preroll: parse_hashmap_string_value::<u8>(hmap, "metronome_preroll", None)?,
323 metronome_cue_volume: parse_hashmap_string_value::<u8>(
324 hmap,
325 "metronome_cue_volume",
326 None,
327 )?,
328 metronome_main_volume: parse_hashmap_string_value::<u8>(
329 hmap,
330 "metronome_main_volume",
331 None,
332 )?,
333 metronome_pitch: parse_hashmap_string_value::<u8>(hmap, "metronome_pitch", None)?,
334 metronome_tonal: parse_hashmap_string_value_bool(hmap, "metronome_tonal", None)?,
335 metronome_enabled: parse_hashmap_string_value_bool(hmap, "metronome_enabled", None)?,
336 })
337 }
338}
339
340/// `PROJECT` -> `CONTROL` -> `MIDI` -> `CONTROL` UI menu.
341
342#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
343pub struct MidiControlMidiPage {
344 /// Whether samples can be loaded in 24-bit depth (16 bit depth samples are always oaded as 16 bit).
345 /// `AUDIO CC IN` setting in `PROJECT` -> `CONTROL` -> `MIDI` -> `CONTROL` UI menu.
346 /// Whether audio tracks respond to MIDI CC IN messages.
347 ///
348 /// See manual section 8.7.1 CONTROL.
349 pub midi_audio_track_cc_in: bool,
350
351 /// `AUDIO CC OUT` setting in `PROJECT` -> `CONTROL` -> `MIDI` -> `CONTROL` UI menu.
352 /// Whether audio tracks send MIDI CC OUT messages.
353 /// Three options:
354 /// - `INT`: No messages sent, knobs only affect Octatrack settings.
355 /// - `EXT`: Sends CC OUT messages but they don't alter any Octatrack settings.
356 /// - `INT+EXT`: Simulataneously affects Octratack settings and sends CC OUT messages.
357 ///
358 /// See manual section 8.7.1 CONTROL.
359 pub midi_audio_track_cc_out: u8,
360
361 /// `AUDIO NOTE IN` setting in `PROJECT` -> `CONTROL` -> `MIDI` -> `CONTROL` UI menu.
362 /// Whether to receive MIDI NOTE IN messages on Audio tracks and how the audio tracks
363 /// respond to those MIDI NOTE IN messages.
364 /// - **OFF**: midi note has no effet.
365 /// - **STANDARD**: standard note mapping (default).
366 /// - **FOLLOW TM**: Track's current trig mode affects audio tracks (track/chromatic/slots).
367 /// - **MAP/TRACK**: Uses MIDI MAP configuration on a per track basis (track/chromatic/slots
368 /// disconnected from user trig mode of track).
369 pub midi_audio_track_note_in: u8,
370
371 /// `AUDIO NOTE OUT` setting in `PROJECT` -> `CONTROL` -> `MIDI` -> `CONTROL` UI menu.
372 /// Whether audio tracks send MIDI NOTE OUT messages. Three options:
373 /// - `INT`: No messages sent, knobs only affect Octatrack settings.
374 /// - `EXT`: Sends NOTE OUT messages but they don't alter any Octatrack settings.
375 /// - `INT+EXT`: Simulataneously affects Octratack settings and sends NOTE OUT messages.
376 ///
377 /// See manual section 8.7.1 CONTROL.
378 pub midi_audio_track_note_out: u8,
379
380 /// Unknown. MIDI channel to MIDI Track CC In messages n (1 - 16) ?
381 pub midi_midi_track_cc_in: u8,
382}
383
384impl FromHashMap for MidiControlMidiPage {
385 type A = String;
386 type B = String;
387 type T = Self;
388
389 fn from_hashmap(hmap: &HashMap<String, String>) -> RBoxErr<Self> {
390 Ok(Self {
391 midi_audio_track_cc_in: parse_hashmap_string_value_bool(
392 hmap,
393 "midi_audio_trk_cc_in",
394 None,
395 )?,
396 midi_audio_track_cc_out: parse_hashmap_string_value::<u8>(
397 hmap,
398 "midi_audio_trk_cc_out",
399 None,
400 )?,
401 midi_audio_track_note_in: parse_hashmap_string_value::<u8>(
402 hmap,
403 "midi_audio_trk_note_in",
404 None,
405 )?,
406 midi_audio_track_note_out: parse_hashmap_string_value::<u8>(
407 hmap,
408 "midi_audio_trk_note_out",
409 None,
410 )?,
411 midi_midi_track_cc_in: parse_hashmap_string_value::<u8>(
412 hmap,
413 "midi_midi_trk_cc_in",
414 None,
415 )?,
416 })
417 }
418}
419
420/// `PROJECT` -> `CONTROL` -> `MIDI` -> `SYNC` UI menu.
421
422#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
423pub struct MidiSyncMidiPage {
424 /// `CLOCK SEND` setting.
425 /// Whether MIDI clock sending is enabled/disabled
426 /// See manual section 8.7.2 SYNC.
427 pub midi_clock_send: bool,
428
429 /// `CLOCK RECV` setting.
430 /// Whether MIDI clock receiving is enabled/disabled
431 /// See manual section 8.7.2 SYNC.
432 pub midi_clock_receive: bool,
433
434 /// `TRANS SEND` setting.
435 /// Whether MIDI transport sending is enabled/disabled
436 /// See manual section 8.7.2 SYNC.
437 pub midi_transport_send: bool,
438
439 /// `TRANS RECV` setting.
440 /// Whether MIDI transport receiving is enabled/disabled
441 /// See manual section 8.7.2 SYNC.
442 pub midi_transport_receive: bool,
443
444 /// `PROG CH SEND` setting.
445 /// Whether MIDI Program Change sending is enabled/disabled
446 /// See manual section 8.7.2 SYNC.
447 pub midi_progchange_send: bool,
448
449 /// `CHANNEL` setting.
450 /// Channel to send MIDI Program Change messages on. (-1, or between 1 - 16).
451 /// **NOTE**: should be set to `-1` when `midi_progchange_send` is disabled.
452 /// See manual section 8.7.2 SYNC.
453 pub midi_progchange_send_channel: MidiChannel,
454
455 /// `PROG CH RECEIVE` setting.
456 /// Whether MIDI Program Change receiveing is enabled/disabled
457 /// See manual section 8.7.2 SYNC.
458 pub midi_progchange_receive: bool,
459
460 /// `CHANNEL` setting.
461 /// Channel to receive MIDI Program Change messages on (-1 or between 1 - 16).
462 /// **NOTE**: should be set to `-1` when `midi_progchange_receive` is disabled.
463 /// See manual section 8.7.2 SYNC.
464 pub midi_progchange_receive_channel: MidiChannel,
465}
466
467impl FromHashMap for MidiSyncMidiPage {
468 type A = String;
469 type B = String;
470 type T = Self;
471
472 fn from_hashmap(hmap: &HashMap<String, String>) -> RBoxErr<Self> {
473 Ok(Self {
474 /*
475 WONTFIX: older OS versions seem to use non-boolean values for boolean settings.
476
477 Some older projects seem to use different settings values for this.
478 I had an OS 1.25E project (`ROMANT_DELETING`) where `MIDI_CLOCK_SEND=2`.
479 But this is definitely boolean so `2` doesn't make sense here
480 (see manual p. 40 and/or settings menu page).
481
482 This probably applies to the other boolean values here. I probably won't fix
483 this as it's an OS patching issue which can easily be fixed by users.
484 */
485 midi_clock_send: parse_hashmap_string_value_bool(hmap, "midi_clock_send", None)?,
486 // See WONTFIX note above. Observed in an old 1.25E project.
487 midi_clock_receive: parse_hashmap_string_value_bool(hmap, "midi_clock_receive", None)?,
488 // See WONTFIX note above. Observed in an old 1.25E project.
489 midi_transport_send: parse_hashmap_string_value_bool(
490 hmap,
491 "midi_transport_send",
492 None,
493 )?,
494 // See WONTFIX note above. Observed in an old 1.25E project.
495 midi_transport_receive: parse_hashmap_string_value_bool(
496 hmap,
497 "midi_transport_receive",
498 None,
499 )?,
500 midi_progchange_send: parse_hashmap_string_value_bool(
501 hmap,
502 "midi_program_change_send",
503 None,
504 )?,
505 midi_progchange_send_channel: MidiChannel::from_value(&parse_hashmap_string_value::<
506 i8,
507 >(
508 hmap,
509 "midi_program_change_send_ch",
510 None,
511 )?)?,
512 midi_progchange_receive: parse_hashmap_string_value_bool(
513 hmap,
514 "midi_program_change_receive",
515 None,
516 )?,
517 midi_progchange_receive_channel: MidiChannel::from_value(
518 &parse_hashmap_string_value::<i8>(hmap, "midi_program_change_receive_ch", None)?,
519 )?,
520 })
521 }
522}
523
524/// `PROJECT` -> `CONTROL` -> `MIDI` -> `CHANNELS` UI menu.
525
526#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
527pub struct MidiChannelsMidiPage {
528 /// `TRIG CH 1` setting in `PROJECT` -> `CONTROL` -> `MIDI` -> `CHANNELS` UI menu.
529 /// MIDI Channel to send MIDI Trig 1 messages to (1 - 16)
530 /// See manual section 8.7.3 CHANNELS.
531 ///
532 /// NOTE: Can also be -1 for DISABLED
533 pub midi_trig_ch1: i8,
534
535 /// `TRIG CH 2` setting in `PROJECT` -> `CONTROL` -> `MIDI` -> `CHANNELS` UI menu.
536 /// MIDI Channel to send MIDI Trig 2 messages to (1 - 16)
537 /// See manual section 8.7.3 CHANNELS.
538 ///
539 /// NOTE: Can also be -1 for DISABLED
540 pub midi_trig_ch2: i8,
541
542 /// `TRIG CH 3` setting in `PROJECT` -> `CONTROL` -> `MIDI` -> `CHANNELS` UI menu.
543 /// MIDI Channel to send MIDI Trig 3 messages to (1 - 16)
544 /// See manual section 8.7.3 CHANNELS.
545 ///
546 /// NOTE: Can also be -1 for DISABLED
547 pub midi_trig_ch3: i8,
548
549 /// `TRIG CH 4` setting in `PROJECT` -> `CONTROL` -> `MIDI` -> `CHANNELS` UI menu.
550 /// MIDI Channel to send MIDI Trig 4 messages to (1 - 16)
551 /// See manual section 8.7.3 CHANNELS.
552 ///
553 /// NOTE: Can also be -1 for DISABLED
554 pub midi_trig_ch4: i8,
555
556 /// `TRIG CH 5` setting in `PROJECT` -> `CONTROL` -> `MIDI` -> `CHANNELS` UI menu.
557 /// MIDI Channel to send MIDI Trig 5 messages to (1 - 16)
558 /// See manual section 8.7.3 CHANNELS.
559 ///
560 /// NOTE: Can also be -1 for DISABLED
561 pub midi_trig_ch5: i8,
562
563 /// `TRIG CH 6` setting in `PROJECT` -> `CONTROL` -> `MIDI` -> `CHANNELS` UI menu.
564 /// MIDI Channel to send MIDI Trig 6 messages to (1 - 16)
565 /// See manual section 8.7.3 CHANNELS.
566 ///
567 /// NOTE: Can also be -1 for DISABLED
568 pub midi_trig_ch6: i8,
569
570 /// `TRIG CH 7` setting in `PROJECT` -> `CONTROL` -> `MIDI` -> `CHANNELS` UI menu.
571 /// MIDI Channel to send MIDI Trig 7 messages to (1 - 16)
572 /// See manual section 8.7.3 CHANNELS.
573 ///
574 /// NOTE: Can also be -1 for DISABLED
575 pub midi_trig_ch7: i8,
576
577 /// `TRIG CH 8` setting in `PROJECT` -> `CONTROL` -> `MIDI` -> `CHANNELS` UI menu.
578 /// MIDI Channel to send MIDI Trig 8 messages to (1 - 16)
579 /// See manual section 8.7.3 CHANNELS.
580 ///
581 /// NOTE: Can also be -1 for DISABLED
582 pub midi_trig_ch8: i8,
583
584 /// `AUTO CH` setting in `PROJECT` -> `CONTROL` -> `MIDI` -> `CHANNELS` UI menu.
585 /// Auto MIDI Channel (1 - 16)
586 /// See manual section 8.7.3 CHANNELS.
587 ///
588 /// NOTE: Can also be -1 for DISABLED
589 pub midi_auto_channel: i8,
590}
591
592impl FromHashMap for MidiChannelsMidiPage {
593 type A = String;
594 type B = String;
595 type T = Self;
596
597 fn from_hashmap(hmap: &HashMap<String, String>) -> RBoxErr<Self> {
598 let midi_trig_ch1 = parse_hashmap_string_value::<i8>(hmap, "midi_trig_ch1", None)?;
599 let midi_trig_ch2 = parse_hashmap_string_value::<i8>(hmap, "midi_trig_ch2", None)?;
600 let midi_trig_ch3 = parse_hashmap_string_value::<i8>(hmap, "midi_trig_ch3", None)?;
601 let midi_trig_ch4 = parse_hashmap_string_value::<i8>(hmap, "midi_trig_ch4", None)?;
602 let midi_trig_ch5 = parse_hashmap_string_value::<i8>(hmap, "midi_trig_ch5", None)?;
603 let midi_trig_ch6 = parse_hashmap_string_value::<i8>(hmap, "midi_trig_ch6", None)?;
604 let midi_trig_ch7 = parse_hashmap_string_value::<i8>(hmap, "midi_trig_ch7", None)?;
605 let midi_trig_ch8 = parse_hashmap_string_value::<i8>(hmap, "midi_trig_ch8", None)?;
606 let midi_auto_channel = parse_hashmap_string_value::<i8>(hmap, "midi_auto_channel", None)?;
607 Ok(Self {
608 midi_trig_ch1,
609 midi_trig_ch2,
610 midi_trig_ch3,
611 midi_trig_ch4,
612 midi_trig_ch5,
613 midi_trig_ch6,
614 midi_trig_ch7,
615 midi_trig_ch8,
616 midi_auto_channel,
617 })
618 }
619}