1pub mod menu;
2pub mod types;
3pub(crate) mod unknown;
4
5use self::unknown::GlobalUnknown;
6use crate::{
7 error::{ParameterError, RytmError, SysexConversionError},
8 impl_sysex_compatible,
9 sysex::{SysexCompatible, SysexMeta, SysexType, GLOBAL_SYSEX_SIZE},
10 util::{assemble_u32_from_u8_array_be, break_u32_into_u8_array_be},
11 AnySysexType,
12};
13use derivative::Derivative;
14use menu::*;
15use rytm_rs_macro::parameter_range;
16use rytm_sys::{ar_global_raw_to_syx, ar_global_t, ar_sysex_meta_t};
17use serde::{Deserialize, Serialize};
18
19impl_sysex_compatible!(
20 Global,
21 ar_global_t,
22 ar_global_raw_to_syx,
23 SysexType::Global,
24 GLOBAL_SYSEX_SIZE
25);
26
27#[derive(Derivative, Clone, Copy, Serialize, Deserialize)]
33#[derivative(Debug)]
34pub struct Global {
35 #[derivative(Debug = "ignore")]
36 sysex_meta: SysexMeta,
37 version: u32,
39
40 index: usize,
41
42 metronome_settings: MetronomeSettings,
43 midi_config: MidiConfig,
44 sequencer_config: SequencerConfig,
45 routing: Routing,
46
47 #[derivative(Debug = "ignore")]
48 __unknown: GlobalUnknown,
49}
50
51impl From<&Global> for ar_global_t {
52 fn from(global: &Global) -> Self {
53 let mut raw_global = Self {
54 version: break_u32_into_u8_array_be(global.version),
55 ..Default::default()
56 };
57
58 global
59 .metronome_settings
60 .apply_to_raw_global(&mut raw_global);
61 global.midi_config.apply_to_raw_global(&mut raw_global);
62 global.sequencer_config.apply_to_raw_global(&mut raw_global);
63 global.routing.apply_to_raw_global(&mut raw_global);
64
65 global.__unknown.apply_to_raw_global(&mut raw_global);
66
67 raw_global
68 }
69}
70
71impl Global {
72 pub(crate) fn as_raw_parts(&self) -> (SysexMeta, ar_global_t) {
73 (self.sysex_meta, self.into())
74 }
75
76 pub(crate) fn try_from_raw(
77 sysex_meta: SysexMeta,
78 raw_global: &ar_global_t,
79 ) -> Result<Self, RytmError> {
80 let slot_number = sysex_meta.get_normalized_object_index();
81
82 Ok(Self {
83 index: slot_number,
84 sysex_meta,
85 version: assemble_u32_from_u8_array_be(&raw_global.version),
86
87 metronome_settings: raw_global.try_into()?,
88 midi_config: raw_global.try_into()?,
89 sequencer_config: raw_global.try_into()?,
90 routing: raw_global.try_into()?,
91
92 __unknown: raw_global.into(),
93 })
94 }
95
96 #[parameter_range(range = "global_slot:0..=3")]
100 pub fn try_default(global_slot: usize) -> Result<Self, RytmError> {
101 Self::try_default_with_device_id(global_slot, 0)
102 }
103
104 #[parameter_range(range = "global_slot:0..=3", range = "device_id:0..=127")]
109 pub fn try_default_with_device_id(
110 global_slot: usize,
111 device_id: u8,
112 ) -> Result<Self, RytmError> {
113 Ok(Self {
114 index: global_slot,
115 sysex_meta: SysexMeta::try_default_for_global(global_slot, Some(device_id))?,
116 version: 2,
117
118 metronome_settings: MetronomeSettings::default(),
119 midi_config: MidiConfig::default(),
120 sequencer_config: SequencerConfig::default(),
121 routing: Routing::default(),
122
123 __unknown: GlobalUnknown::default(),
124 })
125 }
126
127 pub fn work_buffer_default() -> Self {
129 Self::work_buffer_default_with_device_id(0)
130 }
131
132 pub fn work_buffer_default_with_device_id(device_id: u8) -> Self {
134 Self {
135 index: 0,
136 sysex_meta: SysexMeta::default_for_global_in_work_buffer(Some(device_id)),
137 version: 2,
138
139 metronome_settings: MetronomeSettings::default(),
140 midi_config: MidiConfig::default(),
141 sequencer_config: SequencerConfig::default(),
142 routing: Routing::default(),
143
144 __unknown: GlobalUnknown::default(),
145 }
146 }
147
148 pub const fn structure_version(&self) -> u32 {
150 self.version
151 }
152
153 pub const fn is_work_buffer(&self) -> bool {
155 self.sysex_meta.is_targeting_work_buffer()
156 }
157
158 pub const fn index(&self) -> usize {
160 self.index
161 }
162
163 pub const fn metronome_settings(&self) -> &MetronomeSettings {
165 &self.metronome_settings
166 }
167
168 pub fn metronome_settings_mut(&mut self) -> &mut MetronomeSettings {
170 &mut self.metronome_settings
171 }
172
173 pub const fn midi_config(&self) -> &MidiConfig {
175 &self.midi_config
176 }
177
178 pub fn midi_config_mut(&mut self) -> &mut MidiConfig {
180 &mut self.midi_config
181 }
182
183 pub const fn sequencer_config(&self) -> &SequencerConfig {
185 &self.sequencer_config
186 }
187
188 pub fn sequencer_config_mut(&mut self) -> &mut SequencerConfig {
190 &mut self.sequencer_config
191 }
192
193 pub const fn routing(&self) -> &Routing {
195 &self.routing
196 }
197
198 pub fn routing_mut(&mut self) -> &mut Routing {
200 &mut self.routing
201 }
202
203 pub(crate) fn set_device_id(&mut self, device_id: u8) {
204 self.sysex_meta.set_device_id(device_id);
205 }
206}