1#![allow(
5 clippy::cast_lossless,
6 clippy::cast_possible_truncation,
7 clippy::cast_sign_loss
8)]
9
10pub mod comp;
15pub mod delay;
17pub mod dist;
19pub mod lfo;
21pub mod retrig;
23pub mod reverb;
25pub mod types;
27pub(crate) mod unknown;
28
29use self::{
30 comp::FxCompressor, delay::FxDelay, dist::FxDistortion, lfo::FxLfo, reverb::FxReverb,
31 types::ControlInModTarget, unknown::KitUnknown,
32};
33use super::pattern::plock::ParameterLockPool;
34use crate::{
35 defaults::{default_perf_ctl_array, default_scene_ctl_array},
36 error::{ParameterError, RytmError, SysexConversionError},
37 impl_sysex_compatible,
38 object::types::ObjectName,
39 sysex::{SysexCompatible, SysexMeta, SysexType, KIT_SYSEX_SIZE},
40 util::{
41 assemble_u32_from_u8_array_be, break_u32_into_u8_array_be,
42 to_s_u16_t_union_b_from_u8_as_msb,
43 },
44 AnySysexType, Sound,
45};
46use derivative::Derivative;
47use parking_lot::Mutex;
48use rytm_rs_macro::parameter_range;
49use rytm_sys::{ar_kit_raw_to_syx, ar_kit_t, ar_sysex_meta_t};
50use serde::{Deserialize, Serialize};
51use serde_big_array::BigArray;
52use std::sync::Arc;
53
54impl_sysex_compatible!(
55 Kit,
56 ar_kit_t,
57 ar_kit_raw_to_syx,
58 SysexType::Kit,
59 KIT_SYSEX_SIZE
60);
61
62#[derive(Derivative, Clone, Serialize, Deserialize)]
66#[derivative(Debug)]
67pub struct Kit {
68 #[derivative(Debug = "ignore")]
69 sysex_meta: SysexMeta,
70 version: u32,
72 pub(crate) index: usize,
73
74 name: ObjectName,
76
77 #[derivative(Debug = "ignore")]
79 track_levels: [u8; 13],
80 #[derivative(Debug = "ignore")]
82 track_retrig_settings: [retrig::TrackRetrigMenu; 12],
83 #[derivative(Debug = "ignore")]
84 sounds: Vec<Sound>,
85
86 fx_delay: FxDelay,
87 fx_distortion: FxDistortion,
88 fx_reverb: FxReverb,
89 fx_compressor: FxCompressor,
90 fx_lfo: FxLfo,
91
92 control_in_1_mod_target_1: ControlInModTarget,
93 control_in_1_mod_target_2: ControlInModTarget,
94 control_in_1_mod_target_3: ControlInModTarget,
95 control_in_1_mod_target_4: ControlInModTarget,
96
97 control_in_2_mod_target_1: ControlInModTarget,
98 control_in_2_mod_target_2: ControlInModTarget,
99 control_in_2_mod_target_3: ControlInModTarget,
100 control_in_2_mod_target_4: ControlInModTarget,
101
102 control_in_1_mod_amt_1: i8,
103 control_in_1_mod_amt_2: i8,
104 control_in_1_mod_amt_3: i8,
105 control_in_1_mod_amt_4: i8,
106
107 control_in_2_mod_amt_1: i8,
108 control_in_2_mod_amt_2: i8,
109 control_in_2_mod_amt_3: i8,
110 control_in_2_mod_amt_4: i8,
111
112 #[derivative(Debug = "ignore")]
117 #[serde(with = "BigArray")]
118 pub(crate) perf_ctl: [u8; 48 * 4], #[derivative(Debug = "ignore")]
120 #[serde(with = "BigArray")]
121 pub(crate) scene_ctl: [u8; 48 * 4], #[derivative(Debug = "ignore")]
124 pub(crate) current_scene_id: u8, #[derivative(Debug = "ignore")]
128 pub(crate) __unknown: KitUnknown,
129}
130
131impl From<&Kit> for ar_kit_t {
132 fn from(kit: &Kit) -> Self {
133 let mut raw_kit = Self {
134 __unknown_arr1: break_u32_into_u8_array_be(kit.version),
136 name: kit.name.copy_inner(),
137 perf_ctl: kit.perf_ctl,
138 scene_ctl: kit.scene_ctl,
139 current_scene_id: kit.current_scene_id,
140
141 ctrl_in_mod_1_target_1: kit.control_in_1_mod_target_1.into(),
142 ctrl_in_mod_1_target_2: kit.control_in_1_mod_target_2.into(),
143 ctrl_in_mod_1_target_3: kit.control_in_1_mod_target_3.into(),
144 ctrl_in_mod_1_target_4: kit.control_in_1_mod_target_4.into(),
145
146 ctrl_in_mod_2_target_1: kit.control_in_2_mod_target_1.into(),
147 ctrl_in_mod_2__target_2: kit.control_in_2_mod_target_2.into(),
148 ctrl_in_mod_2_target_3: kit.control_in_2_mod_target_3.into(),
149 ctrl_in_mod_2_target_4: kit.control_in_2_mod_target_4.into(),
150
151 ctrl_in_mod_1_amt_1: kit.control_in_1_mod_amt_1 as u8,
152 ctrl_in_mod_1_amt_2: kit.control_in_1_mod_amt_2 as u8,
153 ctrl_in_mod_1_amt_3: kit.control_in_1_mod_amt_3 as u8,
154 ctrl_in_mod_1_amt_4: kit.control_in_1_mod_amt_4 as u8,
155
156 ctrl_in_mod_2_amt_1: kit.control_in_2_mod_amt_1 as u8,
157 ctrl_in_mod_2_amt_2: kit.control_in_2_mod_amt_2 as u8,
158 ctrl_in_mod_2_amt_3: kit.control_in_2_mod_amt_3 as u8,
159 ctrl_in_mod_2_amt_4: kit.control_in_2_mod_amt_4 as u8,
160
161 ..Default::default()
162 };
163
164 for (i, sound) in kit.sounds.iter().enumerate() {
165 raw_kit.tracks[i] = sound.into();
166 }
167
168 for (i, track_level) in kit.track_levels.iter().enumerate() {
169 raw_kit.track_levels[i] = to_s_u16_t_union_b_from_u8_as_msb(*track_level);
171 }
172
173 kit.fx_delay.apply_to_raw_kit(&mut raw_kit);
174 kit.fx_distortion.apply_to_raw_kit(&mut raw_kit);
175 kit.fx_reverb.apply_to_raw_kit(&mut raw_kit);
176 kit.fx_compressor.apply_to_raw_kit(&mut raw_kit);
177 kit.fx_lfo.apply_to_raw_kit(&mut raw_kit);
178
179 for retrig_settings in &kit.track_retrig_settings {
180 retrig_settings.apply_to_raw_kit(&mut raw_kit);
181 }
182
183 kit.__unknown.apply_to_raw_kit(&mut raw_kit);
184
185 raw_kit
186 }
187}
188
189impl Kit {
190 pub(crate) fn try_from_raw(
191 sysex_meta: SysexMeta,
192 raw_kit: &ar_kit_t,
193 ) -> Result<Self, RytmError> {
194 let kit_number = sysex_meta.get_normalized_object_index();
195
196 let name = ObjectName::from_u8_array(raw_kit.name);
197
198 let mut sounds = vec![
199 Sound::try_kit_default(0, kit_number, sysex_meta)?,
200 Sound::try_kit_default(1, kit_number, sysex_meta)?,
201 Sound::try_kit_default(2, kit_number, sysex_meta)?,
202 Sound::try_kit_default(3, kit_number, sysex_meta)?,
203 Sound::try_kit_default(4, kit_number, sysex_meta)?,
204 Sound::try_kit_default(5, kit_number, sysex_meta)?,
205 Sound::try_kit_default(6, kit_number, sysex_meta)?,
206 Sound::try_kit_default(7, kit_number, sysex_meta)?,
207 Sound::try_kit_default(8, kit_number, sysex_meta)?,
208 Sound::try_kit_default(9, kit_number, sysex_meta)?,
209 Sound::try_kit_default(10, kit_number, sysex_meta)?,
210 Sound::try_kit_default(11, kit_number, sysex_meta)?,
211 ];
212
213 for (i, sound) in raw_kit.tracks.iter().enumerate() {
214 sounds[i] = Sound::try_from_raw(sysex_meta, sound, Some((kit_number, i)))?;
215 }
216
217 let mut track_levels = [0; 13];
218 for (i, track_level) in raw_kit.track_levels.iter().enumerate() {
219 track_levels[i] = unsafe { track_level.b.hi };
221 }
222
223 #[allow(clippy::cast_possible_wrap)]
224 Ok(Self {
225 index: kit_number,
226 sysex_meta,
227 version: assemble_u32_from_u8_array_be(&raw_kit.__unknown_arr1),
228
229 name,
230
231 track_levels,
232 track_retrig_settings: retrig::TrackRetrigMenu::get_default_for_12_tracks(),
233 sounds,
234
235 fx_delay: raw_kit.try_into()?,
236 fx_distortion: raw_kit.try_into()?,
237 fx_reverb: raw_kit.try_into()?,
238 fx_compressor: raw_kit.try_into()?,
239 fx_lfo: raw_kit.try_into()?,
240
241 perf_ctl: raw_kit.perf_ctl,
242 scene_ctl: raw_kit.scene_ctl,
243 current_scene_id: raw_kit.current_scene_id,
244
245 control_in_1_mod_target_1: raw_kit.ctrl_in_mod_1_target_1.try_into()?,
246 control_in_1_mod_target_2: raw_kit.ctrl_in_mod_1_target_2.try_into()?,
247 control_in_1_mod_target_3: raw_kit.ctrl_in_mod_1_target_3.try_into()?,
248 control_in_1_mod_target_4: raw_kit.ctrl_in_mod_1_target_4.try_into()?,
249
250 control_in_2_mod_target_1: raw_kit.ctrl_in_mod_2_target_1.try_into()?,
251 control_in_2_mod_target_2: raw_kit.ctrl_in_mod_2__target_2.try_into()?,
252 control_in_2_mod_target_3: raw_kit.ctrl_in_mod_2_target_3.try_into()?,
253 control_in_2_mod_target_4: raw_kit.ctrl_in_mod_2_target_4.try_into()?,
254
255 control_in_1_mod_amt_1: raw_kit.ctrl_in_mod_1_amt_1 as i8,
256 control_in_1_mod_amt_2: raw_kit.ctrl_in_mod_1_amt_2 as i8,
257 control_in_1_mod_amt_3: raw_kit.ctrl_in_mod_1_amt_3 as i8,
258 control_in_1_mod_amt_4: raw_kit.ctrl_in_mod_1_amt_4 as i8,
259
260 control_in_2_mod_amt_1: raw_kit.ctrl_in_mod_2_amt_1 as i8,
261 control_in_2_mod_amt_2: raw_kit.ctrl_in_mod_2_amt_2 as i8,
262 control_in_2_mod_amt_3: raw_kit.ctrl_in_mod_2_amt_3 as i8,
263 control_in_2_mod_amt_4: raw_kit.ctrl_in_mod_2_amt_4 as i8,
264
265 __unknown: raw_kit.into(),
266 })
267 }
268
269 pub(crate) fn as_raw_parts(&self) -> (SysexMeta, ar_kit_t) {
270 (self.sysex_meta, self.into())
271 }
272
273 #[parameter_range(range = "index:0..=127")]
277 pub fn try_default(index: usize) -> Result<Self, RytmError> {
278 Self::try_default_with_device_id(index, 0)
279 }
280
281 #[parameter_range(range = "kit_index:0..=127", range = "device_id:0..=127")]
286 pub fn try_default_with_device_id(kit_index: usize, device_id: u8) -> Result<Self, RytmError> {
287 let meta = SysexMeta::try_default_for_kit(kit_index, Some(device_id))?;
304 Ok(Self {
305 index: kit_index,
306 sysex_meta: meta,
307 version: 6,
308
309 name: format!("KIT {kit_index}").try_into()?,
310
311 track_levels: [100; 13],
312 track_retrig_settings: retrig::TrackRetrigMenu::get_default_for_12_tracks(),
313
314 sounds: vec![
315 Sound::try_kit_default(0, kit_index, meta)?,
316 Sound::try_kit_default(1, kit_index, meta)?,
317 Sound::try_kit_default(2, kit_index, meta)?,
318 Sound::try_kit_default(3, kit_index, meta)?,
319 Sound::try_kit_default(4, kit_index, meta)?,
320 Sound::try_kit_default(5, kit_index, meta)?,
321 Sound::try_kit_default(6, kit_index, meta)?,
322 Sound::try_kit_default(7, kit_index, meta)?,
323 Sound::try_kit_default(8, kit_index, meta)?,
324 Sound::try_kit_default(9, kit_index, meta)?,
325 Sound::try_kit_default(10, kit_index, meta)?,
326 Sound::try_kit_default(11, kit_index, meta)?,
327 ],
328
329 fx_delay: FxDelay::default(),
330 fx_distortion: FxDistortion::default(),
331 fx_reverb: FxReverb::default(),
332 fx_compressor: FxCompressor::default(),
333 fx_lfo: FxLfo::default(),
334
335 perf_ctl: default_perf_ctl_array(),
336 scene_ctl: default_scene_ctl_array(),
337 current_scene_id: 0,
338
339 control_in_1_mod_target_1: ControlInModTarget::default(),
340 control_in_1_mod_target_2: ControlInModTarget::default(),
341 control_in_1_mod_target_3: ControlInModTarget::default(),
342 control_in_1_mod_target_4: ControlInModTarget::default(),
343
344 control_in_2_mod_target_1: ControlInModTarget::default(),
345 control_in_2_mod_target_2: ControlInModTarget::default(),
346 control_in_2_mod_target_3: ControlInModTarget::default(),
347 control_in_2_mod_target_4: ControlInModTarget::default(),
348
349 control_in_1_mod_amt_1: 0,
350 control_in_1_mod_amt_2: 0,
351 control_in_1_mod_amt_3: 0,
352 control_in_1_mod_amt_4: 0,
353
354 control_in_2_mod_amt_1: 0,
355 control_in_2_mod_amt_2: 0,
356 control_in_2_mod_amt_3: 0,
357 control_in_2_mod_amt_4: 0,
358
359 __unknown: KitUnknown::default(),
360 })
361 }
362
363 pub fn work_buffer_default() -> Self {
365 Self::work_buffer_default_with_device_id(0)
366 }
367
368 #[allow(clippy::missing_panics_doc)]
370 pub fn work_buffer_default_with_device_id(device_id: u8) -> Self {
371 Self {
372 index: 0,
373 sysex_meta: SysexMeta::default_for_kit_in_work_buffer(Some(device_id)),
374 version: 6,
375
376 name: "WB_KIT".try_into().unwrap(),
377
378 track_levels: [100; 13],
379 track_retrig_settings: retrig::TrackRetrigMenu::get_default_for_12_tracks(),
380
381 sounds: vec![
383 Sound::try_work_buffer_default_with_device_id(0, device_id).unwrap(),
384 Sound::try_work_buffer_default_with_device_id(1, device_id).unwrap(),
385 Sound::try_work_buffer_default_with_device_id(2, device_id).unwrap(),
386 Sound::try_work_buffer_default_with_device_id(3, device_id).unwrap(),
387 Sound::try_work_buffer_default_with_device_id(4, device_id).unwrap(),
388 Sound::try_work_buffer_default_with_device_id(5, device_id).unwrap(),
389 Sound::try_work_buffer_default_with_device_id(6, device_id).unwrap(),
390 Sound::try_work_buffer_default_with_device_id(7, device_id).unwrap(),
391 Sound::try_work_buffer_default_with_device_id(8, device_id).unwrap(),
392 Sound::try_work_buffer_default_with_device_id(9, device_id).unwrap(),
393 Sound::try_work_buffer_default_with_device_id(10, device_id).unwrap(),
394 Sound::try_work_buffer_default_with_device_id(11, device_id).unwrap(),
395 ],
396
397 fx_delay: FxDelay::default(),
398 fx_distortion: FxDistortion::default(),
399 fx_reverb: FxReverb::default(),
400 fx_compressor: FxCompressor::default(),
401 fx_lfo: FxLfo::default(),
402
403 perf_ctl: default_perf_ctl_array(),
404 scene_ctl: default_scene_ctl_array(),
405 current_scene_id: 0,
406
407 control_in_1_mod_target_1: ControlInModTarget::default(),
408 control_in_1_mod_target_2: ControlInModTarget::default(),
409 control_in_1_mod_target_3: ControlInModTarget::default(),
410 control_in_1_mod_target_4: ControlInModTarget::default(),
411
412 control_in_2_mod_target_1: ControlInModTarget::default(),
413 control_in_2_mod_target_2: ControlInModTarget::default(),
414 control_in_2_mod_target_3: ControlInModTarget::default(),
415 control_in_2_mod_target_4: ControlInModTarget::default(),
416
417 control_in_1_mod_amt_1: 0,
418 control_in_1_mod_amt_2: 0,
419 control_in_1_mod_amt_3: 0,
420 control_in_1_mod_amt_4: 0,
421
422 control_in_2_mod_amt_1: 0,
423 control_in_2_mod_amt_2: 0,
424 control_in_2_mod_amt_3: 0,
425 control_in_2_mod_amt_4: 0,
426
427 __unknown: KitUnknown::default(),
428 }
429 }
430
431 pub fn set_name(&mut self, name: &str) -> Result<(), RytmError> {
437 self.name = name.try_into()?;
438 Ok(())
439 }
440
441 pub fn name(&self) -> &str {
443 self.name.as_str()
444 }
445
446 pub fn sounds(&self) -> &[Sound] {
448 &self.sounds
449 }
450
451 pub fn sounds_mut(&mut self) -> &mut [Sound] {
453 &mut self.sounds
454 }
455
456 #[parameter_range(range = "track_index:0..=12", range = "level:0..=127")]
464 pub fn set_track_level(&mut self, track_index: usize, level: usize) -> Result<(), RytmError> {
465 self.track_levels[track_index] = level as u8;
466 Ok(())
467 }
468
469 #[parameter_range(range = "level:0..=127")]
473 pub fn set_all_track_levels(&mut self, level: usize) -> Result<(), RytmError> {
474 for track_level in &mut self.track_levels {
475 *track_level = level as u8;
476 }
477 Ok(())
478 }
479
480 #[parameter_range(range = "level:0..=127")]
488 pub fn set_a_range_of_track_levels(
489 &mut self,
490 range: std::ops::Range<usize>,
491 level: usize,
492 ) -> Result<(), RytmError> {
493 if range.end > 12 {
494 return Err(RytmError::Parameter(ParameterError::Range {
495 value: format!("{range:?}"),
496 parameter_name: "range".to_string(),
497 }));
498 }
499
500 for track_index in range {
501 self.set_track_level(track_index, level)?;
502 }
503
504 Ok(())
505 }
506
507 #[parameter_range(range = "track_index:0..=12")]
511 pub fn track_level(&self, track_index: usize) -> Result<usize, RytmError> {
512 Ok(self.track_levels[track_index] as usize)
513 }
514
515 pub fn track_levels(&self) -> Vec<usize> {
519 self.track_levels
520 .iter()
521 .map(|&l| l as usize)
522 .collect::<Vec<_>>()
523 }
524
525 pub fn range_of_track_levels(
537 &self,
538 range: std::ops::Range<usize>,
539 ) -> Result<Vec<usize>, RytmError> {
540 let mut levels = Vec::new();
541 for track_index in range {
542 levels.push(self.track_level(track_index)?);
543 }
544 Ok(levels)
545 }
546
547 pub const fn structure_version(&self) -> u32 {
549 self.version
550 }
551
552 #[parameter_range(range = "track_index:0..=12")]
558 pub fn track_retrig_settings(
559 &self,
560 track_index: usize,
561 ) -> Result<&retrig::TrackRetrigMenu, RytmError> {
562 Ok(&self.track_retrig_settings[track_index])
563 }
564
565 #[parameter_range(range = "track_index:0..=12")]
571 pub fn track_retrig_settings_mut(
572 &mut self,
573 track_index: usize,
574 ) -> Result<&mut retrig::TrackRetrigMenu, RytmError> {
575 Ok(&mut self.track_retrig_settings[track_index])
576 }
577
578 pub const fn fx_delay(&self) -> &FxDelay {
580 &self.fx_delay
581 }
582
583 pub fn fx_delay_mut(&mut self) -> &mut FxDelay {
585 &mut self.fx_delay
586 }
587
588 pub const fn fx_distortion(&self) -> &FxDistortion {
590 &self.fx_distortion
591 }
592
593 pub fn fx_distortion_mut(&mut self) -> &mut FxDistortion {
595 &mut self.fx_distortion
596 }
597
598 pub const fn fx_reverb(&self) -> &FxReverb {
600 &self.fx_reverb
601 }
602
603 pub fn fx_reverb_mut(&mut self) -> &mut FxReverb {
605 &mut self.fx_reverb
606 }
607
608 pub const fn fx_compressor(&self) -> &FxCompressor {
610 &self.fx_compressor
611 }
612
613 pub fn fx_compressor_mut(&mut self) -> &mut FxCompressor {
615 &mut self.fx_compressor
616 }
617
618 pub const fn fx_lfo(&self) -> &FxLfo {
620 &self.fx_lfo
621 }
622
623 pub fn fx_lfo_mut(&mut self) -> &mut FxLfo {
625 &mut self.fx_lfo
626 }
627
628 pub const fn index(&self) -> usize {
630 self.index
631 }
632
633 pub fn set_control_in_1_mod_target_1(&mut self, control_in_1_mod_target_1: ControlInModTarget) {
635 self.control_in_1_mod_target_1 = control_in_1_mod_target_1;
636 }
637
638 pub fn set_control_in_1_mod_target_2(&mut self, control_in_1_mod_target_2: ControlInModTarget) {
640 self.control_in_1_mod_target_2 = control_in_1_mod_target_2;
641 }
642
643 pub fn set_control_in_1_mod_target_3(&mut self, control_in_1_mod_target_3: ControlInModTarget) {
645 self.control_in_1_mod_target_3 = control_in_1_mod_target_3;
646 }
647
648 pub fn set_control_in_1_mod_target_4(&mut self, control_in_1_mod_target_4: ControlInModTarget) {
650 self.control_in_1_mod_target_4 = control_in_1_mod_target_4;
651 }
652
653 pub fn set_control_in_2_mod_target_1(&mut self, control_in_2_mod_target_1: ControlInModTarget) {
655 self.control_in_2_mod_target_1 = control_in_2_mod_target_1;
656 }
657
658 pub fn set_control_in_2_mod_target_2(&mut self, control_in_2_mod_target_2: ControlInModTarget) {
660 self.control_in_2_mod_target_2 = control_in_2_mod_target_2;
661 }
662
663 pub fn set_control_in_2_mod_target_3(&mut self, control_in_2_mod_target_3: ControlInModTarget) {
665 self.control_in_2_mod_target_3 = control_in_2_mod_target_3;
666 }
667
668 pub fn set_control_in_2_mod_target_4(&mut self, control_in_2_mod_target_4: ControlInModTarget) {
670 self.control_in_2_mod_target_4 = control_in_2_mod_target_4;
671 }
672
673 #[parameter_range(range = "control_in_1_mod_amt_1:-128..=127")]
677 pub fn set_control_in_1_mod_amt_1(
678 &mut self,
679 control_in_1_mod_amt_1: isize,
680 ) -> Result<(), RytmError> {
681 self.control_in_1_mod_amt_1 = control_in_1_mod_amt_1 as i8;
682 Ok(())
683 }
684
685 #[parameter_range(range = "control_in_1_mod_amt_2:-128..=127")]
689 pub fn set_control_in_1_mod_amt_2(
690 &mut self,
691 control_in_1_mod_amt_2: isize,
692 ) -> Result<(), RytmError> {
693 self.control_in_1_mod_amt_2 = control_in_1_mod_amt_2 as i8;
694 Ok(())
695 }
696
697 #[parameter_range(range = "control_in_1_mod_amt_3:-128..=127")]
701 pub fn set_control_in_1_mod_amt_3(
702 &mut self,
703 control_in_1_mod_amt_3: isize,
704 ) -> Result<(), RytmError> {
705 self.control_in_1_mod_amt_3 = control_in_1_mod_amt_3 as i8;
706 Ok(())
707 }
708
709 #[parameter_range(range = "control_in_1_mod_amt_4:-128..=127")]
713 pub fn set_control_in_1_mod_amt_4(
714 &mut self,
715 control_in_1_mod_amt_4: isize,
716 ) -> Result<(), RytmError> {
717 self.control_in_1_mod_amt_4 = control_in_1_mod_amt_4 as i8;
718 Ok(())
719 }
720
721 #[parameter_range(range = "control_in_2_mod_amt_1:-128..=127")]
725 pub fn set_control_in_2_mod_amt_1(
726 &mut self,
727 control_in_2_mod_amt_1: isize,
728 ) -> Result<(), RytmError> {
729 self.control_in_2_mod_amt_1 = control_in_2_mod_amt_1 as i8;
730 Ok(())
731 }
732
733 #[parameter_range(range = "control_in_2_mod_amt_2:-128..=127")]
737 pub fn set_control_in_2_mod_amt_2(
738 &mut self,
739 control_in_2_mod_amt_2: isize,
740 ) -> Result<(), RytmError> {
741 self.control_in_2_mod_amt_2 = control_in_2_mod_amt_2 as i8;
742 Ok(())
743 }
744
745 #[parameter_range(range = "control_in_2_mod_amt_3:-128..=127")]
749 pub fn set_control_in_2_mod_amt_3(
750 &mut self,
751 control_in_2_mod_amt_3: isize,
752 ) -> Result<(), RytmError> {
753 self.control_in_2_mod_amt_3 = control_in_2_mod_amt_3 as i8;
754 Ok(())
755 }
756
757 #[parameter_range(range = "control_in_2_mod_amt_4:-128..=127")]
761 pub fn set_control_in_2_mod_amt_4(
762 &mut self,
763 control_in_2_mod_amt_4: isize,
764 ) -> Result<(), RytmError> {
765 self.control_in_2_mod_amt_4 = control_in_2_mod_amt_4 as i8;
766 Ok(())
767 }
768
769 pub const fn control_in_1_mod_target_1(&self) -> ControlInModTarget {
771 self.control_in_1_mod_target_1
772 }
773
774 pub const fn control_in_1_mod_target_2(&self) -> ControlInModTarget {
776 self.control_in_1_mod_target_2
777 }
778
779 pub const fn control_in_1_mod_target_3(&self) -> ControlInModTarget {
781 self.control_in_1_mod_target_3
782 }
783
784 pub const fn control_in_1_mod_target_4(&self) -> ControlInModTarget {
786 self.control_in_1_mod_target_4
787 }
788
789 pub const fn control_in_2_mod_target_1(&self) -> ControlInModTarget {
791 self.control_in_2_mod_target_1
792 }
793
794 pub const fn control_in_2_mod_target_2(&self) -> ControlInModTarget {
796 self.control_in_2_mod_target_2
797 }
798
799 pub const fn control_in_2_mod_target_3(&self) -> ControlInModTarget {
801 self.control_in_2_mod_target_3
802 }
803
804 pub const fn control_in_2_mod_target_4(&self) -> ControlInModTarget {
806 self.control_in_2_mod_target_4
807 }
808
809 pub const fn control_in_1_mod_amt_1(&self) -> isize {
813 self.control_in_1_mod_amt_1 as isize
814 }
815
816 pub const fn control_in_1_mod_amt_2(&self) -> isize {
820 self.control_in_1_mod_amt_2 as isize
821 }
822
823 pub const fn control_in_1_mod_amt_3(&self) -> isize {
827 self.control_in_1_mod_amt_3 as isize
828 }
829
830 pub const fn control_in_1_mod_amt_4(&self) -> isize {
834 self.control_in_1_mod_amt_4 as isize
835 }
836
837 pub const fn control_in_2_mod_amt_1(&self) -> isize {
841 self.control_in_2_mod_amt_1 as isize
842 }
843
844 pub const fn control_in_2_mod_amt_2(&self) -> isize {
848 self.control_in_2_mod_amt_2 as isize
849 }
850
851 pub const fn control_in_2_mod_amt_3(&self) -> isize {
855 self.control_in_2_mod_amt_3 as isize
856 }
857
858 pub const fn control_in_2_mod_amt_4(&self) -> isize {
862 self.control_in_2_mod_amt_4 as isize
863 }
864
865 pub fn link_parameter_lock_pool(
873 &mut self,
874 parameter_lock_pool: &Arc<Mutex<ParameterLockPool>>,
875 ) -> Result<(), RytmError> {
876 for sound in self.sounds_mut() {
877 sound.link_parameter_lock_pool(parameter_lock_pool)?;
878 }
879
880 Ok(())
881 }
882
883 pub(crate) fn set_device_id(&mut self, device_id: u8) {
884 self.sysex_meta.set_device_id(device_id);
885 self.sounds_mut()
886 .iter_mut()
887 .for_each(|sound| sound.set_device_id(device_id));
888 }
889}