rytm_rs/object/kit/
retrig.rs

1use crate::{
2    error::{ParameterError, RytmError},
3    object::pattern::{Length, RetrigRate},
4    util::{from_s_u16_t, to_s_u16_t_union_a},
5};
6use rytm_rs_macro::parameter_range;
7use rytm_sys::ar_kit_t;
8use serde::{Deserialize, Serialize};
9
10/// Represents the retrig settings for a track.
11#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
12pub struct TrackRetrigMenu {
13    track_index: usize,
14    rate: RetrigRate,
15    length: Length,
16    velocity_curve: i8,
17    always_on: bool,
18}
19
20impl TrackRetrigMenu {
21    pub(crate) fn get_default_for_12_tracks() -> [Self; 12] {
22        [
23            Self::try_default_for_track(0).unwrap(),
24            Self::try_default_for_track(1).unwrap(),
25            Self::try_default_for_track(2).unwrap(),
26            Self::try_default_for_track(3).unwrap(),
27            Self::try_default_for_track(4).unwrap(),
28            Self::try_default_for_track(5).unwrap(),
29            Self::try_default_for_track(6).unwrap(),
30            Self::try_default_for_track(7).unwrap(),
31            Self::try_default_for_track(8).unwrap(),
32            Self::try_default_for_track(9).unwrap(),
33            Self::try_default_for_track(10).unwrap(),
34            Self::try_default_for_track(11).unwrap(),
35            // Self::try_default_for_track(12).unwrap(),
36        ]
37    }
38
39    #[parameter_range(range = "track_index:0..=11")]
40    pub fn try_default_for_track(track_index: usize) -> Result<Self, RytmError> {
41        let rate = RetrigRate::default();
42        let length = Length::default();
43        let velocity_curve = 0;
44        let always_on = false;
45        Ok(Self {
46            track_index,
47            rate,
48            length,
49            velocity_curve,
50            always_on,
51        })
52    }
53
54    #[parameter_range(range = "track_index:0..=11")]
55    pub(crate) fn try_from_raw(track_index: usize, raw_kit: &ar_kit_t) -> Result<Self, RytmError> {
56        let flags = unsafe { from_s_u16_t(raw_kit.retrig_always_on) };
57        let always_on = flags & (1 << track_index) != 0;
58
59        let raw_retrig = raw_kit.retrig[track_index];
60        Ok(Self {
61            track_index,
62            rate: raw_retrig.retrig.try_into()?,
63            length: raw_retrig.length.try_into()?,
64            velocity_curve: raw_retrig.vel_curve,
65            always_on,
66        })
67    }
68
69    pub(crate) fn apply_to_raw_kit(&self, raw_kit: &mut ar_kit_t) {
70        let raw_retrig = &mut raw_kit.retrig[self.track_index];
71        raw_retrig.retrig = self.rate.into();
72        raw_retrig.length = self.length.into();
73        raw_retrig.vel_curve = self.velocity_curve;
74        let flags = unsafe { from_s_u16_t(raw_kit.retrig_always_on) };
75        let new_flags = if self.always_on {
76            flags | (1 << self.track_index)
77        } else {
78            flags & !(1 << self.track_index)
79        };
80        raw_kit.retrig_always_on = to_s_u16_t_union_a(new_flags);
81    }
82
83    /// Sets the retrig rate.
84    pub fn set_rate(&mut self, rate: RetrigRate) {
85        self.rate = rate;
86    }
87
88    /// Sets the retrig length.
89    pub fn set_length(&mut self, length: Length) {
90        self.length = length;
91    }
92
93    /// Sets the velocity curve.
94    ///
95    /// Range: `-128..=127`
96    #[parameter_range(range = "velocity_curve:-128..=127")]
97    pub fn set_velocity_curve(&mut self, velocity_curve: isize) -> Result<(), RytmError> {
98        self.velocity_curve = velocity_curve as i8;
99        Ok(())
100    }
101
102    /// Sets whether the retrig is always on.
103    ///
104    /// If `true`, the retrig is always on.
105    pub fn set_always_on(&mut self, always_on: bool) {
106        self.always_on = always_on;
107    }
108
109    /// Returns the track index. The track which this setting belongs to.
110    ///
111    /// Range: `0..=12`
112    pub const fn track_index(&self) -> usize {
113        self.track_index
114    }
115
116    /// Returns the retrig rate.
117    pub const fn rate(&self) -> RetrigRate {
118        self.rate
119    }
120
121    /// Returns the retrig length.
122    pub const fn length(&self) -> Length {
123        self.length
124    }
125
126    /// Returns the velocity curve.
127    ///
128    /// Range: `-128..=127`
129    pub const fn velocity_curve(&self) -> i8 {
130        self.velocity_curve
131    }
132
133    /// Returns whether the retrig is always on.
134    ///
135    /// If `true`, the retrig is always on.
136    pub const fn always_on(&self) -> bool {
137        self.always_on
138    }
139}