rytm_rs/object/sound/
types.rs

1// All casts in this file are intended or safe within the context of this library.
2//
3// One can change `allow` to `warn` to review them if necessary.
4#![allow(
5    clippy::cast_lossless,
6    clippy::cast_possible_truncation,
7    clippy::cast_sign_loss
8)]
9#![allow(clippy::enum_glob_use)]
10use super::machine::MachineParameters;
11use crate::error::ConversionError;
12use serde::{Deserialize, Serialize};
13
14#[allow(unused)]
15mod machines {
16    use rytm_sys::{
17        sSI, AR_NUM_SOUND_MACHINES, AR_SOUND_MACHINE_BD_ACOUSTIC, AR_SOUND_MACHINE_BD_CLASSIC,
18        AR_SOUND_MACHINE_BD_FM, AR_SOUND_MACHINE_BD_HARD, AR_SOUND_MACHINE_BD_PLASTIC,
19        AR_SOUND_MACHINE_BD_SHARP, AR_SOUND_MACHINE_BD_SILKY, AR_SOUND_MACHINE_BT_CLASSIC,
20        AR_SOUND_MACHINE_CB_CLASSIC, AR_SOUND_MACHINE_CB_METALLIC, AR_SOUND_MACHINE_CH_CLASSIC,
21        AR_SOUND_MACHINE_CH_METALLIC, AR_SOUND_MACHINE_CP_CLASSIC, AR_SOUND_MACHINE_CY_CLASSIC,
22        AR_SOUND_MACHINE_CY_METALLIC, AR_SOUND_MACHINE_CY_RIDE, AR_SOUND_MACHINE_DISABLE,
23        AR_SOUND_MACHINE_HH_BASIC, AR_SOUND_MACHINE_HH_LAB, AR_SOUND_MACHINE_OH_CLASSIC,
24        AR_SOUND_MACHINE_OH_METALLIC, AR_SOUND_MACHINE_RS_CLASSIC, AR_SOUND_MACHINE_RS_HARD,
25        AR_SOUND_MACHINE_SD_ACOUSTIC, AR_SOUND_MACHINE_SD_CLASSIC, AR_SOUND_MACHINE_SD_FM,
26        AR_SOUND_MACHINE_SD_HARD, AR_SOUND_MACHINE_SD_NATURAL, AR_SOUND_MACHINE_SY_CHIP,
27        AR_SOUND_MACHINE_SY_DUAL_VCO, AR_SOUND_MACHINE_SY_RAW, AR_SOUND_MACHINE_UT_IMPULSE,
28        AR_SOUND_MACHINE_UT_NOISE, AR_SOUND_MACHINE_XT_CLASSIC,
29    };
30
31    pub const NUM_SOUND_MACHINES: u8 = AR_NUM_SOUND_MACHINES as u8;
32    pub const BD_ACOUSTIC: u8 = AR_SOUND_MACHINE_BD_ACOUSTIC as u8;
33    pub const BD_CLASSIC: u8 = AR_SOUND_MACHINE_BD_CLASSIC as u8;
34    pub const BD_FM: u8 = AR_SOUND_MACHINE_BD_FM as u8;
35    pub const BD_HARD: u8 = AR_SOUND_MACHINE_BD_HARD as u8;
36    pub const BD_PLASTIC: u8 = AR_SOUND_MACHINE_BD_PLASTIC as u8;
37    pub const BD_SHARP: u8 = AR_SOUND_MACHINE_BD_SHARP as u8;
38    pub const BD_SILKY: u8 = AR_SOUND_MACHINE_BD_SILKY as u8;
39    pub const BT_CLASSIC: u8 = AR_SOUND_MACHINE_BT_CLASSIC as u8;
40    pub const CB_CLASSIC: u8 = AR_SOUND_MACHINE_CB_CLASSIC as u8;
41    pub const CB_METALLIC: u8 = AR_SOUND_MACHINE_CB_METALLIC as u8;
42    pub const CH_CLASSIC: u8 = AR_SOUND_MACHINE_CH_CLASSIC as u8;
43    pub const CH_METALLIC: u8 = AR_SOUND_MACHINE_CH_METALLIC as u8;
44    pub const CP_CLASSIC: u8 = AR_SOUND_MACHINE_CP_CLASSIC as u8;
45    pub const CY_CLASSIC: u8 = AR_SOUND_MACHINE_CY_CLASSIC as u8;
46    pub const CY_METALLIC: u8 = AR_SOUND_MACHINE_CY_METALLIC as u8;
47    pub const CY_RIDE: u8 = AR_SOUND_MACHINE_CY_RIDE as u8;
48    pub const DISABLE: u8 = AR_SOUND_MACHINE_DISABLE as u8;
49    pub const HH_BASIC: u8 = AR_SOUND_MACHINE_HH_BASIC as u8;
50    pub const HH_LAB: u8 = AR_SOUND_MACHINE_HH_LAB as u8;
51    pub const OH_CLASSIC: u8 = AR_SOUND_MACHINE_OH_CLASSIC as u8;
52    pub const OH_METALLIC: u8 = AR_SOUND_MACHINE_OH_METALLIC as u8;
53    pub const RS_CLASSIC: u8 = AR_SOUND_MACHINE_RS_CLASSIC as u8;
54    pub const RS_HARD: u8 = AR_SOUND_MACHINE_RS_HARD as u8;
55    pub const SD_ACOUSTIC: u8 = AR_SOUND_MACHINE_SD_ACOUSTIC as u8;
56    pub const SD_CLASSIC: u8 = AR_SOUND_MACHINE_SD_CLASSIC as u8;
57    pub const SD_FM: u8 = AR_SOUND_MACHINE_SD_FM as u8;
58    pub const SD_HARD: u8 = AR_SOUND_MACHINE_SD_HARD as u8;
59    pub const SD_NATURAL: u8 = AR_SOUND_MACHINE_SD_NATURAL as u8;
60    pub const SY_CHIP: u8 = AR_SOUND_MACHINE_SY_CHIP as u8;
61    pub const SY_DUAL_VCO: u8 = AR_SOUND_MACHINE_SY_DUAL_VCO as u8;
62    pub const SY_RAW: u8 = AR_SOUND_MACHINE_SY_RAW as u8;
63    pub const UT_IMPULSE: u8 = AR_SOUND_MACHINE_UT_IMPULSE as u8;
64    pub const UT_NOISE: u8 = AR_SOUND_MACHINE_UT_NOISE as u8;
65    pub const XT_CLASSIC: u8 = AR_SOUND_MACHINE_XT_CLASSIC as u8;
66    pub const UNSET: u8 = 0xFF;
67}
68
69mod lfo_destination {
70    use rytm_sys::{
71        AR_SOUND_LFO_DEST_AMP_ACC, AR_SOUND_LFO_DEST_AMP_ATK, AR_SOUND_LFO_DEST_AMP_DEC,
72        AR_SOUND_LFO_DEST_AMP_DLY, AR_SOUND_LFO_DEST_AMP_HLD, AR_SOUND_LFO_DEST_AMP_OVR,
73        AR_SOUND_LFO_DEST_AMP_PAN, AR_SOUND_LFO_DEST_AMP_REV, AR_SOUND_LFO_DEST_AMP_VOL,
74        AR_SOUND_LFO_DEST_FLT_ATK, AR_SOUND_LFO_DEST_FLT_DEC, AR_SOUND_LFO_DEST_FLT_ENV,
75        AR_SOUND_LFO_DEST_FLT_FRQ, AR_SOUND_LFO_DEST_FLT_REL, AR_SOUND_LFO_DEST_FLT_RES,
76        AR_SOUND_LFO_DEST_FLT_SUS, AR_SOUND_LFO_DEST_NONE, AR_SOUND_LFO_DEST_SMP_BR,
77        AR_SOUND_LFO_DEST_SMP_END, AR_SOUND_LFO_DEST_SMP_FIN, AR_SOUND_LFO_DEST_SMP_LEV,
78        AR_SOUND_LFO_DEST_SMP_LOP, AR_SOUND_LFO_DEST_SMP_SMP, AR_SOUND_LFO_DEST_SMP_STA,
79        AR_SOUND_LFO_DEST_SMP_TUN, AR_SOUND_LFO_DEST_SYN_1, AR_SOUND_LFO_DEST_SYN_2,
80        AR_SOUND_LFO_DEST_SYN_3, AR_SOUND_LFO_DEST_SYN_4, AR_SOUND_LFO_DEST_SYN_5,
81        AR_SOUND_LFO_DEST_SYN_6, AR_SOUND_LFO_DEST_SYN_7, AR_SOUND_LFO_DEST_SYN_8,
82    };
83
84    pub const NONE: u8 = AR_SOUND_LFO_DEST_NONE as u8;
85    pub const SYN_1: u8 = AR_SOUND_LFO_DEST_SYN_1 as u8;
86    pub const SYN_2: u8 = AR_SOUND_LFO_DEST_SYN_2 as u8;
87    pub const SYN_3: u8 = AR_SOUND_LFO_DEST_SYN_3 as u8;
88    pub const SYN_4: u8 = AR_SOUND_LFO_DEST_SYN_4 as u8;
89    pub const SYN_5: u8 = AR_SOUND_LFO_DEST_SYN_5 as u8;
90    pub const SYN_6: u8 = AR_SOUND_LFO_DEST_SYN_6 as u8;
91    pub const SYN_7: u8 = AR_SOUND_LFO_DEST_SYN_7 as u8;
92    pub const SYN_8: u8 = AR_SOUND_LFO_DEST_SYN_8 as u8;
93    pub const SMP_TUN: u8 = AR_SOUND_LFO_DEST_SMP_TUN as u8;
94    pub const SMP_FIN: u8 = AR_SOUND_LFO_DEST_SMP_FIN as u8;
95    pub const SMP_SMP: u8 = AR_SOUND_LFO_DEST_SMP_SMP as u8;
96    pub const SMP_BR: u8 = AR_SOUND_LFO_DEST_SMP_BR as u8;
97    pub const SMP_STA: u8 = AR_SOUND_LFO_DEST_SMP_STA as u8;
98    pub const SMP_END: u8 = AR_SOUND_LFO_DEST_SMP_END as u8;
99    pub const SMP_LOP: u8 = AR_SOUND_LFO_DEST_SMP_LOP as u8;
100    pub const SMP_LEV: u8 = AR_SOUND_LFO_DEST_SMP_LEV as u8;
101    pub const FLT_ENV: u8 = AR_SOUND_LFO_DEST_FLT_ENV as u8;
102    pub const FLT_ATK: u8 = AR_SOUND_LFO_DEST_FLT_ATK as u8;
103    pub const FLT_DEC: u8 = AR_SOUND_LFO_DEST_FLT_DEC as u8;
104    pub const FLT_SUS: u8 = AR_SOUND_LFO_DEST_FLT_SUS as u8;
105    pub const FLT_REL: u8 = AR_SOUND_LFO_DEST_FLT_REL as u8;
106    pub const FLT_FRQ: u8 = AR_SOUND_LFO_DEST_FLT_FRQ as u8;
107    pub const FLT_RES: u8 = AR_SOUND_LFO_DEST_FLT_RES as u8;
108    pub const AMP_ATK: u8 = AR_SOUND_LFO_DEST_AMP_ATK as u8;
109    pub const AMP_HLD: u8 = AR_SOUND_LFO_DEST_AMP_HLD as u8;
110    pub const AMP_DEC: u8 = AR_SOUND_LFO_DEST_AMP_DEC as u8;
111    pub const AMP_OVR: u8 = AR_SOUND_LFO_DEST_AMP_OVR as u8;
112    pub const AMP_VOL: u8 = AR_SOUND_LFO_DEST_AMP_VOL as u8;
113    pub const AMP_PAN: u8 = AR_SOUND_LFO_DEST_AMP_PAN as u8;
114    pub const AMP_ACC: u8 = AR_SOUND_LFO_DEST_AMP_ACC as u8;
115    pub const AMP_DLY: u8 = AR_SOUND_LFO_DEST_AMP_DLY as u8;
116    pub const AMP_REV: u8 = AR_SOUND_LFO_DEST_AMP_REV as u8;
117}
118
119pub(crate) mod sound_mod_target {
120    use rytm_sys::{
121        AR_SOUND_MOD_DEST_AMP_ACC, AR_SOUND_MOD_DEST_AMP_ATK, AR_SOUND_MOD_DEST_AMP_DEC,
122        AR_SOUND_MOD_DEST_AMP_DLY, AR_SOUND_MOD_DEST_AMP_HLD, AR_SOUND_MOD_DEST_AMP_OVR,
123        AR_SOUND_MOD_DEST_AMP_PAN, AR_SOUND_MOD_DEST_AMP_REV, AR_SOUND_MOD_DEST_AMP_VOL,
124        AR_SOUND_MOD_DEST_FLT_ATK, AR_SOUND_MOD_DEST_FLT_DEC, AR_SOUND_MOD_DEST_FLT_ENV,
125        AR_SOUND_MOD_DEST_FLT_FRQ, AR_SOUND_MOD_DEST_FLT_REL, AR_SOUND_MOD_DEST_FLT_RES,
126        AR_SOUND_MOD_DEST_FLT_SUS, AR_SOUND_MOD_DEST_LFO_DEPTH, AR_SOUND_MOD_DEST_LFO_FADE,
127        AR_SOUND_MOD_DEST_LFO_MULTIPLIER, AR_SOUND_MOD_DEST_LFO_PHASE, AR_SOUND_MOD_DEST_LFO_SPEED,
128        AR_SOUND_MOD_DEST_LFO_TRIGMODE, AR_SOUND_MOD_DEST_LFO_WAVEFORM, AR_SOUND_MOD_DEST_NONE,
129        AR_SOUND_MOD_DEST_SMP_BR, AR_SOUND_MOD_DEST_SMP_END, AR_SOUND_MOD_DEST_SMP_FIN,
130        AR_SOUND_MOD_DEST_SMP_LEV, AR_SOUND_MOD_DEST_SMP_LOP, AR_SOUND_MOD_DEST_SMP_SMP,
131        AR_SOUND_MOD_DEST_SMP_STA, AR_SOUND_MOD_DEST_SMP_TUN, AR_SOUND_MOD_DEST_SYN_1,
132        AR_SOUND_MOD_DEST_SYN_2, AR_SOUND_MOD_DEST_SYN_3, AR_SOUND_MOD_DEST_SYN_4,
133        AR_SOUND_MOD_DEST_SYN_5, AR_SOUND_MOD_DEST_SYN_6, AR_SOUND_MOD_DEST_SYN_7,
134        AR_SOUND_MOD_DEST_SYN_8,
135    };
136
137    pub const NONE: u8 = AR_SOUND_MOD_DEST_NONE as u8;
138    pub const LFO_MULTIPLIER: u8 = AR_SOUND_MOD_DEST_LFO_MULTIPLIER as u8;
139    pub const LFO_WAVEFORM: u8 = AR_SOUND_MOD_DEST_LFO_WAVEFORM as u8;
140    pub const LFO_TRIGMODE: u8 = AR_SOUND_MOD_DEST_LFO_TRIGMODE as u8;
141    pub const LFO_SPEED: u8 = AR_SOUND_MOD_DEST_LFO_SPEED as u8;
142    pub const LFO_FADE: u8 = AR_SOUND_MOD_DEST_LFO_FADE as u8;
143    pub const LFO_PHASE: u8 = AR_SOUND_MOD_DEST_LFO_PHASE as u8;
144    pub const LFO_DEPTH: u8 = AR_SOUND_MOD_DEST_LFO_DEPTH as u8;
145    pub const SYN_1: u8 = AR_SOUND_MOD_DEST_SYN_1 as u8;
146    pub const SYN_2: u8 = AR_SOUND_MOD_DEST_SYN_2 as u8;
147    pub const SYN_3: u8 = AR_SOUND_MOD_DEST_SYN_3 as u8;
148    pub const SYN_4: u8 = AR_SOUND_MOD_DEST_SYN_4 as u8;
149    pub const SYN_5: u8 = AR_SOUND_MOD_DEST_SYN_5 as u8;
150    pub const SYN_6: u8 = AR_SOUND_MOD_DEST_SYN_6 as u8;
151    pub const SYN_7: u8 = AR_SOUND_MOD_DEST_SYN_7 as u8;
152    pub const SYN_8: u8 = AR_SOUND_MOD_DEST_SYN_8 as u8;
153    pub const SMP_TUN: u8 = AR_SOUND_MOD_DEST_SMP_TUN as u8;
154    pub const SMP_FIN: u8 = AR_SOUND_MOD_DEST_SMP_FIN as u8;
155    pub const SMP_SMP: u8 = AR_SOUND_MOD_DEST_SMP_SMP as u8;
156    pub const SMP_BR: u8 = AR_SOUND_MOD_DEST_SMP_BR as u8;
157    pub const SMP_STA: u8 = AR_SOUND_MOD_DEST_SMP_STA as u8;
158    pub const SMP_END: u8 = AR_SOUND_MOD_DEST_SMP_END as u8;
159    pub const SMP_LOP: u8 = AR_SOUND_MOD_DEST_SMP_LOP as u8;
160    pub const SMP_LEV: u8 = AR_SOUND_MOD_DEST_SMP_LEV as u8;
161    pub const FLT_ENV: u8 = AR_SOUND_MOD_DEST_FLT_ENV as u8;
162    pub const FLT_ATK: u8 = AR_SOUND_MOD_DEST_FLT_ATK as u8;
163    pub const FLT_DEC: u8 = AR_SOUND_MOD_DEST_FLT_DEC as u8;
164    pub const FLT_SUS: u8 = AR_SOUND_MOD_DEST_FLT_SUS as u8;
165    pub const FLT_REL: u8 = AR_SOUND_MOD_DEST_FLT_REL as u8;
166    pub const FLT_FRQ: u8 = AR_SOUND_MOD_DEST_FLT_FRQ as u8;
167    pub const FLT_RES: u8 = AR_SOUND_MOD_DEST_FLT_RES as u8;
168    pub const AMP_ATK: u8 = AR_SOUND_MOD_DEST_AMP_ATK as u8;
169    pub const AMP_HLD: u8 = AR_SOUND_MOD_DEST_AMP_HLD as u8;
170    pub const AMP_DEC: u8 = AR_SOUND_MOD_DEST_AMP_DEC as u8;
171    pub const AMP_OVR: u8 = AR_SOUND_MOD_DEST_AMP_OVR as u8;
172    pub const AMP_VOL: u8 = AR_SOUND_MOD_DEST_AMP_VOL as u8;
173    pub const AMP_PAN: u8 = AR_SOUND_MOD_DEST_AMP_PAN as u8;
174    pub const AMP_ACC: u8 = AR_SOUND_MOD_DEST_AMP_ACC as u8;
175    pub const AMP_DLY: u8 = AR_SOUND_MOD_DEST_AMP_DLY as u8;
176    pub const AMP_REV: u8 = AR_SOUND_MOD_DEST_AMP_REV as u8;
177}
178
179/// Machine type of a sound.
180#[derive(
181    Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
182)]
183pub enum MachineType {
184    BdHard,
185    BdClassic,
186    SdHard,
187    SdClassic,
188    RsHard,
189    RsClassic,
190    CpClassic,
191    BtClassic,
192    XtClassic,
193    ChClassic,
194    OhClassic,
195    CyClassic,
196    CbClassic,
197    BdFm,
198    SdFm,
199    UtNoise,
200    UtImpulse,
201    ChMetallic,
202    OhMetallic,
203    CyMetallic,
204    CbMetallic,
205    BdPlastic,
206    BdSilky,
207    SdNatural,
208    HhBasic,
209    CyRide,
210    BdSharp,
211    Disable,
212    SyDualVco,
213    SyChip,
214    BdAcoustic,
215    SdAcoustic,
216    SyRaw,
217    HhLab,
218    #[default]
219    Unset,
220}
221
222// bdhard, bdclassic, sdhard ..
223impl TryFrom<&str> for MachineType {
224    type Error = ConversionError;
225    fn try_from(machine: &str) -> Result<Self, Self::Error> {
226        use MachineType::*;
227        match machine {
228            "bdhard" => Ok(BdHard),
229            "bdclassic" => Ok(BdClassic),
230            "sdhard" => Ok(SdHard),
231            "sdclassic" => Ok(SdClassic),
232            "rshard" => Ok(RsHard),
233            "rsclassic" => Ok(RsClassic),
234            "cpclassic" => Ok(CpClassic),
235            "btclassic" => Ok(BtClassic),
236            "xtclassic" => Ok(XtClassic),
237            "chclassic" => Ok(ChClassic),
238            "ohclassic" => Ok(OhClassic),
239            "cyclassic" => Ok(CyClassic),
240            "cbclassic" => Ok(CbClassic),
241            "bdfm" => Ok(BdFm),
242            "sdfm" => Ok(SdFm),
243            "utnoise" => Ok(UtNoise),
244            "utimpulse" => Ok(UtImpulse),
245            "chmetallic" => Ok(ChMetallic),
246            "ohmetallic" => Ok(OhMetallic),
247            "cymetallic" => Ok(CyMetallic),
248            "cbmetallic" => Ok(CbMetallic),
249            "bdplastic" => Ok(BdPlastic),
250            "bdsilky" => Ok(BdSilky),
251            "sdnatural" => Ok(SdNatural),
252            "hhbasic" => Ok(HhBasic),
253            "cyride" => Ok(CyRide),
254            "bdsharp" => Ok(BdSharp),
255            "disable" => Ok(Disable),
256            "sydualvco" => Ok(SyDualVco),
257            "sychip" => Ok(SyChip),
258            "bdacoustic" => Ok(BdAcoustic),
259            "sdacoustic" => Ok(SdAcoustic),
260            "syraw" => Ok(SyRaw),
261            "hhlab" => Ok(HhLab),
262            "unset" => Ok(Unset),
263            _ => Err(ConversionError::Range {
264                value: machine.to_string(),
265                type_name: "Machine".to_string(),
266            }),
267        }
268    }
269}
270
271impl From<MachineType> for &str {
272    fn from(machine: MachineType) -> Self {
273        use MachineType::*;
274        match machine {
275            BdHard => "bdhard",
276            BdClassic => "bdclassic",
277            SdHard => "sdhard",
278            SdClassic => "sdclassic",
279            RsHard => "rshard",
280            RsClassic => "rsclassic",
281            CpClassic => "cpclassic",
282            BtClassic => "btclassic",
283            XtClassic => "xtclassic",
284            ChClassic => "chclassic",
285            OhClassic => "ohclassic",
286            CyClassic => "cyclassic",
287            CbClassic => "cbclassic",
288            BdFm => "bdfm",
289            SdFm => "sdfm",
290            UtNoise => "utnoise",
291            UtImpulse => "utimpulse",
292            ChMetallic => "chmetallic",
293            OhMetallic => "ohmetallic",
294            CyMetallic => "cymetallic",
295            CbMetallic => "cbmetallic",
296            BdPlastic => "bdplastic",
297            BdSilky => "bdsilky",
298            SdNatural => "sdnatural",
299            HhBasic => "hhbasic",
300            CyRide => "cyride",
301            BdSharp => "bdsharp",
302            Disable => "disable",
303            SyDualVco => "sydualvco",
304            SyChip => "sychip",
305            BdAcoustic => "bdacoustic",
306            SdAcoustic => "sdacoustic",
307            SyRaw => "syraw",
308            HhLab => "hhlab",
309            Unset => "unset",
310        }
311    }
312}
313
314impl std::fmt::Display for MachineType {
315    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
316        let machine = match self {
317            Self::BdHard => "BD_HARD",
318            Self::BdClassic => "BD_CLASSIC",
319            Self::SdHard => "SD_HARD",
320            Self::SdClassic => "SD_CLASSIC",
321            Self::RsHard => "RS_HARD",
322            Self::RsClassic => "RS_CLASSIC",
323            Self::CpClassic => "CP_CLASSIC",
324            Self::BtClassic => "BT_CLASSIC",
325            Self::XtClassic => "XT_CLASSIC",
326            Self::ChClassic => "CH_CLASSIC",
327            Self::OhClassic => "OH_CLASSIC",
328            Self::CyClassic => "CY_CLASSIC",
329            Self::CbClassic => "CB_CLASSIC",
330            Self::BdFm => "BD_FM",
331            Self::SdFm => "SD_FM",
332            Self::UtNoise => "UT_NOISE",
333            Self::UtImpulse => "UT_IMPULSE",
334            Self::ChMetallic => "CH_METALLIC",
335            Self::OhMetallic => "OH_METALLIC",
336            Self::CyMetallic => "CY_METALLIC",
337            Self::CbMetallic => "CB_METALLIC",
338            Self::BdPlastic => "BD_PLASTIC",
339            Self::BdSilky => "BD_SILKY",
340            Self::SdNatural => "SD_NATURAL",
341            Self::HhBasic => "HH_BASIC",
342            Self::CyRide => "CY_RIDE",
343            Self::BdSharp => "BD_SHARP",
344            Self::Disable => "DISABLE",
345            Self::SyDualVco => "SY_DUAL_VCO",
346            Self::SyChip => "SY_CHIP",
347            Self::BdAcoustic => "BD_ACOUSTIC",
348            Self::SdAcoustic => "SD_ACOUSTIC",
349            Self::SyRaw => "SY_RAW",
350            Self::HhLab => "HH_LAB",
351            Self::Unset => "UNSET",
352        };
353        write!(f, "{machine}")
354    }
355}
356
357impl TryFrom<u8> for MachineType {
358    type Error = ConversionError;
359    fn try_from(value: u8) -> Result<Self, Self::Error> {
360        use machines::*;
361        match value {
362            BD_HARD => Ok(Self::BdHard),
363            BD_CLASSIC => Ok(Self::BdClassic),
364            SD_HARD => Ok(Self::SdHard),
365            SD_CLASSIC => Ok(Self::SdClassic),
366            RS_HARD => Ok(Self::RsHard),
367            RS_CLASSIC => Ok(Self::RsClassic),
368            CP_CLASSIC => Ok(Self::CpClassic),
369            BT_CLASSIC => Ok(Self::BtClassic),
370            XT_CLASSIC => Ok(Self::XtClassic),
371            CH_CLASSIC => Ok(Self::ChClassic),
372            OH_CLASSIC => Ok(Self::OhClassic),
373            CY_CLASSIC => Ok(Self::CyClassic),
374            CB_CLASSIC => Ok(Self::CbClassic),
375            BD_FM => Ok(Self::BdFm),
376            SD_FM => Ok(Self::SdFm),
377            UT_NOISE => Ok(Self::UtNoise),
378            UT_IMPULSE => Ok(Self::UtImpulse),
379            CH_METALLIC => Ok(Self::ChMetallic),
380            OH_METALLIC => Ok(Self::OhMetallic),
381            CY_METALLIC => Ok(Self::CyMetallic),
382            CB_METALLIC => Ok(Self::CbMetallic),
383            BD_PLASTIC => Ok(Self::BdPlastic),
384            BD_SILKY => Ok(Self::BdSilky),
385            SD_NATURAL => Ok(Self::SdNatural),
386            HH_BASIC => Ok(Self::HhBasic),
387            CY_RIDE => Ok(Self::CyRide),
388            BD_SHARP => Ok(Self::BdSharp),
389            DISABLE => Ok(Self::Disable),
390            SY_DUAL_VCO => Ok(Self::SyDualVco),
391            SY_CHIP => Ok(Self::SyChip),
392            BD_ACOUSTIC => Ok(Self::BdAcoustic),
393            SD_ACOUSTIC => Ok(Self::SdAcoustic),
394            SY_RAW => Ok(Self::SyRaw),
395            HH_LAB => Ok(Self::HhLab),
396            UNSET => Ok(Self::Unset),
397            _ => Err(ConversionError::Range {
398                value: value.to_string(),
399                type_name: "Machine".to_string(),
400            }),
401        }
402    }
403}
404
405impl From<MachineType> for u8 {
406    fn from(value: MachineType) -> Self {
407        use machines::*;
408        match value {
409            MachineType::BdHard => BD_HARD,
410            MachineType::BdClassic => BD_CLASSIC,
411            MachineType::SdHard => SD_HARD,
412            MachineType::SdClassic => SD_CLASSIC,
413            MachineType::RsHard => RS_HARD,
414            MachineType::RsClassic => RS_CLASSIC,
415            MachineType::CpClassic => CP_CLASSIC,
416            MachineType::BtClassic => BT_CLASSIC,
417            MachineType::XtClassic => XT_CLASSIC,
418            MachineType::ChClassic => CH_CLASSIC,
419            MachineType::OhClassic => OH_CLASSIC,
420            MachineType::CyClassic => CY_CLASSIC,
421            MachineType::CbClassic => CB_CLASSIC,
422            MachineType::BdFm => BD_FM,
423            MachineType::SdFm => SD_FM,
424            MachineType::UtNoise => UT_NOISE,
425            MachineType::UtImpulse => UT_IMPULSE,
426            MachineType::ChMetallic => CH_METALLIC,
427            MachineType::OhMetallic => OH_METALLIC,
428            MachineType::CyMetallic => CY_METALLIC,
429            MachineType::CbMetallic => CB_METALLIC,
430            MachineType::BdPlastic => BD_PLASTIC,
431            MachineType::BdSilky => BD_SILKY,
432            MachineType::SdNatural => SD_NATURAL,
433            MachineType::HhBasic => HH_BASIC,
434            MachineType::CyRide => CY_RIDE,
435            MachineType::BdSharp => BD_SHARP,
436            MachineType::Disable => DISABLE,
437            MachineType::SyDualVco => SY_DUAL_VCO,
438            MachineType::SyChip => SY_CHIP,
439            MachineType::BdAcoustic => BD_ACOUSTIC,
440            MachineType::SdAcoustic => SD_ACOUSTIC,
441            MachineType::SyRaw => SY_RAW,
442            MachineType::HhLab => HH_LAB,
443            MachineType::Unset => UNSET,
444        }
445    }
446}
447
448impl From<MachineParameters> for MachineType {
449    fn from(machine: MachineParameters) -> Self {
450        use MachineParameters::*;
451        match machine {
452            BdHard(_) => Self::BdHard,
453            BdClassic(_) => Self::BdClassic,
454            SdHard(_) => Self::SdHard,
455            SdClassic(_) => Self::SdClassic,
456            RsHard(_) => Self::RsHard,
457            RsClassic(_) => Self::RsClassic,
458            CpClassic(_) => Self::CpClassic,
459            BtClassic(_) => Self::BtClassic,
460            XtClassic(_) => Self::XtClassic,
461            ChClassic(_) => Self::ChClassic,
462            OhClassic(_) => Self::OhClassic,
463            CyClassic(_) => Self::CyClassic,
464            CbClassic(_) => Self::CbClassic,
465            BdFm(_) => Self::BdFm,
466            SdFm(_) => Self::SdFm,
467            UtNoise(_) => Self::UtNoise,
468            UtImpulse(_) => Self::UtImpulse,
469            ChMetallic(_) => Self::ChMetallic,
470            OhMetallic(_) => Self::OhMetallic,
471            CyMetallic(_) => Self::CyMetallic,
472            CbMetallic(_) => Self::CbMetallic,
473            BdPlastic(_) => Self::BdPlastic,
474            BdSilky(_) => Self::BdSilky,
475            SdNatural(_) => Self::SdNatural,
476            HhBasic(_) => Self::HhBasic,
477            CyRide(_) => Self::CyRide,
478            BdSharp(_) => Self::BdSharp,
479            Disable => Self::Disable,
480            SyDualVco(_) => Self::SyDualVco,
481            SyChip(_) => Self::SyChip,
482            BdAcoustic(_) => Self::BdAcoustic,
483            SdAcoustic(_) => Self::SdAcoustic,
484            SyRaw(_) => Self::SyRaw,
485            HhLab(_) => Self::HhLab,
486            Unset => Self::Unset,
487        }
488    }
489}
490
491/// Destination of an LFO.
492#[derive(
493    Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
494)]
495pub enum LfoDestination {
496    #[default]
497    Unset,
498    Syn1,
499    Syn2,
500    Syn3,
501    Syn4,
502    Syn5,
503    Syn6,
504    Syn7,
505    Syn8,
506    SampleTune,
507    SampleFineTune,
508    SampleSlice,
509    SampleBitReduction,
510    SampleStart,
511    SampleEnd,
512    SampleLoop,
513    SampleLevel,
514    FilterEnvelope,
515    FilterAttack,
516    FilterDecay,
517    FilterSustain,
518    FilterRelease,
519    FilterFrequency,
520    FilterResonance,
521    AmpAttack,
522    AmpHold,
523    AmpDecay,
524    AmpOverdrive,
525    AmpVolume,
526    AmpPan,
527    AmpAccent,
528    AmpDelaySend,
529    AmpReverbSend,
530}
531
532impl TryFrom<&str> for LfoDestination {
533    type Error = ConversionError;
534    fn try_from(destination: &str) -> Result<Self, Self::Error> {
535        use LfoDestination::*;
536        match destination {
537            "syn1" => Ok(Syn1),
538            "syn2" => Ok(Syn2),
539            "syn3" => Ok(Syn3),
540            "syn4" => Ok(Syn4),
541            "syn5" => Ok(Syn5),
542            "syn6" => Ok(Syn6),
543            "syn7" => Ok(Syn7),
544            "syn8" => Ok(Syn8),
545            "sampletune" => Ok(SampleTune),
546            "samplefinetune" => Ok(SampleFineTune),
547            "sampleslice" => Ok(SampleSlice),
548            "samplebitreduction" => Ok(SampleBitReduction),
549            "samplestart" => Ok(SampleStart),
550            "sampleend" => Ok(SampleEnd),
551            "sampleloop" => Ok(SampleLoop),
552            "samplelevel" => Ok(SampleLevel),
553            "filterenvelope" => Ok(FilterEnvelope),
554            "filterattack" => Ok(FilterAttack),
555            "filterdecay" => Ok(FilterDecay),
556            "filtersustain" => Ok(FilterSustain),
557            "filterrelease" => Ok(FilterRelease),
558            "filterfrequency" => Ok(FilterFrequency),
559            "filterresonance" => Ok(FilterResonance),
560            "ampattack" => Ok(AmpAttack),
561            "amphold" => Ok(AmpHold),
562            "ampdecay" => Ok(AmpDecay),
563            "ampoverdrive" => Ok(AmpOverdrive),
564            "ampvolume" => Ok(AmpVolume),
565            "amppan" => Ok(AmpPan),
566            "ampaccent" => Ok(AmpAccent),
567            "ampdelaysend" => Ok(AmpDelaySend),
568            "ampreverb_send" => Ok(AmpReverbSend),
569            "unset" => Ok(Unset),
570            _ => Err(ConversionError::Range {
571                value: destination.to_string(),
572                type_name: "LfoDestination".to_string(),
573            }),
574        }
575    }
576}
577
578impl From<LfoDestination> for &str {
579    fn from(destination: LfoDestination) -> Self {
580        use LfoDestination::*;
581        match destination {
582            Syn1 => "syn1",
583            Syn2 => "syn2",
584            Syn3 => "syn3",
585            Syn4 => "syn4",
586            Syn5 => "syn5",
587            Syn6 => "syn6",
588            Syn7 => "syn7",
589            Syn8 => "syn8",
590            SampleTune => "sampletune",
591            SampleFineTune => "samplefinetune",
592            SampleSlice => "sampleslice",
593            SampleBitReduction => "samplebitreduction",
594            SampleStart => "samplestart",
595            SampleEnd => "sampleend",
596            SampleLoop => "sampleloop",
597            SampleLevel => "samplelevel",
598            FilterEnvelope => "filterenvelope",
599            FilterAttack => "filterattack",
600            FilterDecay => "filterdecay",
601            FilterSustain => "filtersustain",
602            FilterRelease => "filterrelease",
603            FilterFrequency => "filterfrequency",
604            FilterResonance => "filterresonance",
605            AmpAttack => "ampattack",
606            AmpHold => "amphold",
607            AmpDecay => "ampdecay",
608            AmpOverdrive => "ampoverdrive",
609            AmpVolume => "ampvolume",
610            AmpPan => "amppan",
611            AmpAccent => "ampaccent",
612            AmpDelaySend => "ampdelaysend",
613            AmpReverbSend => "ampreverb_send",
614            Unset => "unset",
615        }
616    }
617}
618
619impl TryFrom<u8> for LfoDestination {
620    type Error = ConversionError;
621    fn try_from(value: u8) -> Result<Self, Self::Error> {
622        use lfo_destination::*;
623        match value {
624            NONE => Ok(Self::Unset),
625            SYN_1 => Ok(Self::Syn1),
626            SYN_2 => Ok(Self::Syn2),
627            SYN_3 => Ok(Self::Syn3),
628            SYN_4 => Ok(Self::Syn4),
629            SYN_5 => Ok(Self::Syn5),
630            SYN_6 => Ok(Self::Syn6),
631            SYN_7 => Ok(Self::Syn7),
632            SYN_8 => Ok(Self::Syn8),
633            SMP_TUN => Ok(Self::SampleTune),
634            SMP_FIN => Ok(Self::SampleFineTune),
635            SMP_SMP => Ok(Self::SampleSlice),
636            SMP_BR => Ok(Self::SampleBitReduction),
637            SMP_STA => Ok(Self::SampleStart),
638            SMP_END => Ok(Self::SampleEnd),
639            SMP_LOP => Ok(Self::SampleLoop),
640            SMP_LEV => Ok(Self::SampleLevel),
641            FLT_ENV => Ok(Self::FilterEnvelope),
642            FLT_ATK => Ok(Self::FilterAttack),
643            FLT_DEC => Ok(Self::FilterDecay),
644            FLT_SUS => Ok(Self::FilterSustain),
645            FLT_REL => Ok(Self::FilterRelease),
646            FLT_FRQ => Ok(Self::FilterFrequency),
647            FLT_RES => Ok(Self::FilterResonance),
648            AMP_ATK => Ok(Self::AmpAttack),
649            AMP_HLD => Ok(Self::AmpHold),
650            AMP_DEC => Ok(Self::AmpDecay),
651            AMP_OVR => Ok(Self::AmpOverdrive),
652            AMP_VOL => Ok(Self::AmpVolume),
653            AMP_PAN => Ok(Self::AmpPan),
654            AMP_ACC => Ok(Self::AmpAccent),
655            AMP_DLY => Ok(Self::AmpDelaySend),
656            AMP_REV => Ok(Self::AmpReverbSend),
657            _ => Err(ConversionError::Range {
658                value: value.to_string(),
659                type_name: "LfoDestination".to_string(),
660            }),
661        }
662    }
663}
664
665impl From<LfoDestination> for u8 {
666    fn from(value: LfoDestination) -> Self {
667        use lfo_destination::*;
668        match value {
669            LfoDestination::Unset => NONE,
670            LfoDestination::Syn1 => SYN_1,
671            LfoDestination::Syn2 => SYN_2,
672            LfoDestination::Syn3 => SYN_3,
673            LfoDestination::Syn4 => SYN_4,
674            LfoDestination::Syn5 => SYN_5,
675            LfoDestination::Syn6 => SYN_6,
676            LfoDestination::Syn7 => SYN_7,
677            LfoDestination::Syn8 => SYN_8,
678            LfoDestination::SampleTune => SMP_TUN,
679            LfoDestination::SampleFineTune => SMP_FIN,
680            LfoDestination::SampleSlice => SMP_SMP,
681            LfoDestination::SampleBitReduction => SMP_BR,
682            LfoDestination::SampleStart => SMP_STA,
683            LfoDestination::SampleEnd => SMP_END,
684            LfoDestination::SampleLoop => SMP_LOP,
685            LfoDestination::SampleLevel => SMP_LEV,
686            LfoDestination::FilterEnvelope => FLT_ENV,
687            LfoDestination::FilterAttack => FLT_ATK,
688            LfoDestination::FilterDecay => FLT_DEC,
689            LfoDestination::FilterSustain => FLT_SUS,
690            LfoDestination::FilterRelease => FLT_REL,
691            LfoDestination::FilterFrequency => FLT_FRQ,
692            LfoDestination::FilterResonance => FLT_RES,
693            LfoDestination::AmpAttack => AMP_ATK,
694            LfoDestination::AmpHold => AMP_HLD,
695            LfoDestination::AmpDecay => AMP_DEC,
696            LfoDestination::AmpOverdrive => AMP_OVR,
697            LfoDestination::AmpVolume => AMP_VOL,
698            LfoDestination::AmpPan => AMP_PAN,
699            LfoDestination::AmpAccent => AMP_ACC,
700            LfoDestination::AmpDelaySend => AMP_DLY,
701            LfoDestination::AmpReverbSend => AMP_REV,
702        }
703    }
704}
705
706/// Targets for sound modulation.
707#[derive(
708    Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
709)]
710pub enum SoundModTarget {
711    /// No target.
712    #[default]
713    Unset,
714    /// LFO multiplier.
715    LfoMultiplier,
716    /// LFO waveform.
717    LfoWaveform,
718    /// LFO trigger mode.
719    LfoTrigMode,
720    /// LFO speed.
721    LfoSpeed,
722    /// LFO fade.
723    LfoFade,
724    /// LFO phase.
725    LfoPhase,
726    /// LFO depth.
727    LfoDepth,
728    /// Synth 1.
729    Syn1,
730    /// Synth 2.
731    Syn2,
732    /// Synth 3.
733    Syn3,
734    /// Synth 4.
735    Syn4,
736    /// Synth 5.
737    Syn5,
738    /// Synth 6.
739    Syn6,
740    /// Synth 7.
741    Syn7,
742    /// Synth 8.
743    Syn8,
744    /// Sample tune.
745    SampleTune,
746    /// Sample fine tune.
747    SampleFineTune,
748    /// Sample slice.
749    SampleSlice,
750    /// Sample bit reduction.
751    SampleBitReduction,
752    /// Sample start.
753    SampleStart,
754    /// Sample end.
755    SampleEnd,
756    /// Sample loop.
757    SampleLoop,
758    /// Sample level.
759    SampleLevel,
760    /// Filter envelope.
761    FilterEnvelope,
762    /// Filter attack.
763    FilterAttack,
764    /// Filter decay.
765    FilterDecay,
766    /// Filter sustain.
767    FilterSustain,
768    /// Filter release.
769    FilterRelease,
770    /// Filter frequency.
771    FilterFrequency,
772    /// Filter resonance.
773    FilterResonance,
774    /// Amp attack.
775    AmpAttack,
776    /// Amp hold.
777    AmpHold,
778    /// Amp decay.
779    AmpDecay,
780    /// Amp overdrive.
781    AmpOverdrive,
782    /// Amp volume.
783    AmpVolume,
784    /// Amp pan.
785    AmpPan,
786    /// Amp accent.
787    AmpAccent,
788    /// Amp delay send.
789    AmpDelaySend,
790    /// Amp reverb send.
791    AmpReverbSend,
792}
793
794impl TryFrom<&str> for SoundModTarget {
795    type Error = ConversionError;
796    fn try_from(target: &str) -> Result<Self, Self::Error> {
797        use SoundModTarget::*;
798        match target {
799            "unset" => Ok(Unset),
800            "lfomultiplier" => Ok(LfoMultiplier),
801            "lfowaveform" => Ok(LfoWaveform),
802            "lfotrigmode" => Ok(LfoTrigMode),
803            "lfospeed" => Ok(LfoSpeed),
804            "lfofade" => Ok(LfoFade),
805            "lfophase" => Ok(LfoPhase),
806            "lfodepth" => Ok(LfoDepth),
807            "syn1" => Ok(Syn1),
808            "syn2" => Ok(Syn2),
809            "syn3" => Ok(Syn3),
810            "syn4" => Ok(Syn4),
811            "syn5" => Ok(Syn5),
812            "syn6" => Ok(Syn6),
813            "syn7" => Ok(Syn7),
814            "syn8" => Ok(Syn8),
815            "sampletune" => Ok(SampleTune),
816            "samplefinetune" => Ok(SampleFineTune),
817            "sampleslice" => Ok(SampleSlice),
818            "samplebitreduction" => Ok(SampleBitReduction),
819            "samplestart" => Ok(SampleStart),
820            "sampleend" => Ok(SampleEnd),
821            "sampleloop" => Ok(SampleLoop),
822            "samplelevel" => Ok(SampleLevel),
823            "filterenvelope" => Ok(FilterEnvelope),
824            "filterattack" => Ok(FilterAttack),
825            "filterdecay" => Ok(FilterDecay),
826            "filtersustain" => Ok(FilterSustain),
827            "filterrelease" => Ok(FilterRelease),
828            "filterfrequency" => Ok(FilterFrequency),
829            "filterresonance" => Ok(FilterResonance),
830            "ampattack" => Ok(AmpAttack),
831            "amphold" => Ok(AmpHold),
832            "ampdecay" => Ok(AmpDecay),
833            "ampoverdrive" => Ok(AmpOverdrive),
834            "ampvolume" => Ok(AmpVolume),
835            "amppan" => Ok(AmpPan),
836            "ampaccent" => Ok(AmpAccent),
837            "ampdelaysend" => Ok(AmpDelaySend),
838            "ampreverbsend" => Ok(AmpReverbSend),
839            _ => Err(ConversionError::Range {
840                value: target.to_string(),
841                type_name: "SoundModTarget".to_string(),
842            }),
843        }
844    }
845}
846
847impl From<SoundModTarget> for &str {
848    fn from(target: SoundModTarget) -> Self {
849        use SoundModTarget::*;
850        match target {
851            Unset => "unset",
852            LfoMultiplier => "lfomultiplier",
853            LfoWaveform => "lfowaveform",
854            LfoTrigMode => "lfotrigmode",
855            LfoSpeed => "lfospeed",
856            LfoFade => "lfofade",
857            LfoPhase => "lfophase",
858            LfoDepth => "lfodepth",
859            Syn1 => "syn1",
860            Syn2 => "syn2",
861            Syn3 => "syn3",
862            Syn4 => "syn4",
863            Syn5 => "syn5",
864            Syn6 => "syn6",
865            Syn7 => "syn7",
866            Syn8 => "syn8",
867            SampleTune => "sampletune",
868            SampleFineTune => "samplefinetune",
869            SampleSlice => "sampleslice",
870            SampleBitReduction => "samplebitreduction",
871            SampleStart => "samplestart",
872            SampleEnd => "sampleend",
873            SampleLoop => "sampleloop",
874            SampleLevel => "samplelevel",
875            FilterEnvelope => "filterenvelope",
876            FilterAttack => "filterattack",
877            FilterDecay => "filterdecay",
878            FilterSustain => "filtersustain",
879            FilterRelease => "filterrelease",
880            FilterFrequency => "filterfrequency",
881            FilterResonance => "filterresonance",
882            AmpAttack => "ampattack",
883            AmpHold => "amphold",
884            AmpDecay => "ampdecay",
885            AmpOverdrive => "ampoverdrive",
886            AmpVolume => "ampvolume",
887            AmpPan => "amppan",
888            AmpAccent => "ampaccent",
889            AmpDelaySend => "ampdelaysend",
890            AmpReverbSend => "ampreverbsend",
891        }
892    }
893}
894
895impl TryFrom<u8> for SoundModTarget {
896    type Error = ConversionError;
897    fn try_from(value: u8) -> Result<Self, Self::Error> {
898        use sound_mod_target::*;
899        match value {
900            NONE => Ok(Self::Unset),
901            LFO_MULTIPLIER => Ok(Self::LfoMultiplier),
902            LFO_WAVEFORM => Ok(Self::LfoWaveform),
903            LFO_TRIGMODE => Ok(Self::LfoTrigMode),
904            LFO_SPEED => Ok(Self::LfoSpeed),
905            LFO_FADE => Ok(Self::LfoFade),
906            LFO_PHASE => Ok(Self::LfoPhase),
907            LFO_DEPTH => Ok(Self::LfoDepth),
908            SYN_1 => Ok(Self::Syn1),
909            SYN_2 => Ok(Self::Syn2),
910            SYN_3 => Ok(Self::Syn3),
911            SYN_4 => Ok(Self::Syn4),
912            SYN_5 => Ok(Self::Syn5),
913            SYN_6 => Ok(Self::Syn6),
914            SYN_7 => Ok(Self::Syn7),
915            SYN_8 => Ok(Self::Syn8),
916            SMP_TUN => Ok(Self::SampleTune),
917            SMP_FIN => Ok(Self::SampleFineTune),
918            SMP_SMP => Ok(Self::SampleSlice),
919            SMP_BR => Ok(Self::SampleBitReduction),
920            SMP_STA => Ok(Self::SampleStart),
921            SMP_END => Ok(Self::SampleEnd),
922            SMP_LOP => Ok(Self::SampleLoop),
923            SMP_LEV => Ok(Self::SampleLevel),
924            FLT_ENV => Ok(Self::FilterEnvelope),
925            FLT_ATK => Ok(Self::FilterAttack),
926            FLT_DEC => Ok(Self::FilterDecay),
927            FLT_SUS => Ok(Self::FilterSustain),
928            FLT_REL => Ok(Self::FilterRelease),
929            FLT_FRQ => Ok(Self::FilterFrequency),
930            FLT_RES => Ok(Self::FilterResonance),
931            AMP_ATK => Ok(Self::AmpAttack),
932            AMP_HLD => Ok(Self::AmpHold),
933            AMP_DEC => Ok(Self::AmpDecay),
934            AMP_OVR => Ok(Self::AmpOverdrive),
935            AMP_VOL => Ok(Self::AmpVolume),
936            AMP_PAN => Ok(Self::AmpPan),
937            AMP_ACC => Ok(Self::AmpAccent),
938            AMP_DLY => Ok(Self::AmpDelaySend),
939            AMP_REV => Ok(Self::AmpReverbSend),
940            _ => Err(ConversionError::Range {
941                value: value.to_string(),
942                type_name: "SoundModTarget".to_string(),
943            }),
944        }
945    }
946}
947
948impl From<SoundModTarget> for u8 {
949    fn from(value: SoundModTarget) -> Self {
950        use sound_mod_target::*;
951        match value {
952            SoundModTarget::Unset => NONE,
953            SoundModTarget::LfoMultiplier => LFO_MULTIPLIER,
954            SoundModTarget::LfoWaveform => LFO_WAVEFORM,
955            SoundModTarget::LfoTrigMode => LFO_TRIGMODE,
956            SoundModTarget::LfoSpeed => LFO_SPEED,
957            SoundModTarget::LfoFade => LFO_FADE,
958            SoundModTarget::LfoPhase => LFO_PHASE,
959            SoundModTarget::LfoDepth => LFO_DEPTH,
960            SoundModTarget::Syn1 => SYN_1,
961            SoundModTarget::Syn2 => SYN_2,
962            SoundModTarget::Syn3 => SYN_3,
963            SoundModTarget::Syn4 => SYN_4,
964            SoundModTarget::Syn5 => SYN_5,
965            SoundModTarget::Syn6 => SYN_6,
966            SoundModTarget::Syn7 => SYN_7,
967            SoundModTarget::Syn8 => SYN_8,
968            SoundModTarget::SampleTune => SMP_TUN,
969            SoundModTarget::SampleFineTune => SMP_FIN,
970            SoundModTarget::SampleSlice => SMP_SMP,
971            SoundModTarget::SampleBitReduction => SMP_BR,
972            SoundModTarget::SampleStart => SMP_STA,
973            SoundModTarget::SampleEnd => SMP_END,
974            SoundModTarget::SampleLoop => SMP_LOP,
975            SoundModTarget::SampleLevel => SMP_LEV,
976            SoundModTarget::FilterEnvelope => FLT_ENV,
977            SoundModTarget::FilterAttack => FLT_ATK,
978            SoundModTarget::FilterDecay => FLT_DEC,
979            SoundModTarget::FilterSustain => FLT_SUS,
980            SoundModTarget::FilterRelease => FLT_REL,
981            SoundModTarget::FilterFrequency => FLT_FRQ,
982            SoundModTarget::FilterResonance => FLT_RES,
983            SoundModTarget::AmpAttack => AMP_ATK,
984            SoundModTarget::AmpHold => AMP_HLD,
985            SoundModTarget::AmpDecay => AMP_DEC,
986            SoundModTarget::AmpOverdrive => AMP_OVR,
987            SoundModTarget::AmpVolume => AMP_VOL,
988            SoundModTarget::AmpPan => AMP_PAN,
989            SoundModTarget::AmpAccent => AMP_ACC,
990            SoundModTarget::AmpDelaySend => AMP_DLY,
991            SoundModTarget::AmpReverbSend => AMP_REV,
992        }
993    }
994}
995
996#[derive(
997    Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
998)]
999/// Filter type of a filter.
1000pub enum FilterType {
1001    #[default]
1002    Lp2,
1003    Lp1,
1004    Bp,
1005    Hp1,
1006    Hp2,
1007    Bs,
1008    Pk,
1009}
1010
1011impl TryFrom<&str> for FilterType {
1012    type Error = ConversionError;
1013    fn try_from(filter: &str) -> Result<Self, Self::Error> {
1014        use FilterType::*;
1015        match filter {
1016            "lp2" => Ok(Lp2),
1017            "lp1" => Ok(Lp1),
1018            "bp" => Ok(Bp),
1019            "hp1" => Ok(Hp1),
1020            "hp2" => Ok(Hp2),
1021            "bs" => Ok(Bs),
1022            "pk" => Ok(Pk),
1023            _ => Err(ConversionError::Range {
1024                value: filter.to_string(),
1025                type_name: "FilterType".to_string(),
1026            }),
1027        }
1028    }
1029}
1030
1031impl From<FilterType> for &str {
1032    fn from(filter: FilterType) -> Self {
1033        use FilterType::*;
1034        match filter {
1035            Lp2 => "lp2",
1036            Lp1 => "lp1",
1037            Bp => "bp",
1038            Hp1 => "hp1",
1039            Hp2 => "hp2",
1040            Bs => "bs",
1041            Pk => "pk",
1042        }
1043    }
1044}
1045
1046impl TryFrom<u8> for FilterType {
1047    type Error = ConversionError;
1048    fn try_from(value: u8) -> Result<Self, Self::Error> {
1049        match value {
1050            0 => Ok(Self::Lp2),
1051            1 => Ok(Self::Lp1),
1052            2 => Ok(Self::Bp),
1053            3 => Ok(Self::Hp1),
1054            4 => Ok(Self::Hp2),
1055            5 => Ok(Self::Bs),
1056            6 => Ok(Self::Pk),
1057            _ => Err(ConversionError::Range {
1058                value: value.to_string(),
1059                type_name: "FilterType".to_string(),
1060            }),
1061        }
1062    }
1063}
1064
1065impl From<FilterType> for u8 {
1066    fn from(value: FilterType) -> Self {
1067        match value {
1068            FilterType::Lp2 => 0,
1069            FilterType::Lp1 => 1,
1070            FilterType::Bp => 2,
1071            FilterType::Hp1 => 3,
1072            FilterType::Hp2 => 4,
1073            FilterType::Bs => 5,
1074            FilterType::Pk => 6,
1075        }
1076    }
1077}
1078
1079/// Multiplier for an LFO.
1080#[derive(
1081    Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
1082)]
1083pub enum LfoMultiplier {
1084    /// x1
1085    X1,
1086    /// x2
1087    X2,
1088    /// x4
1089    X4,
1090    /// x8
1091    X8,
1092    #[default]
1093    /// x16
1094    X16,
1095    /// x32
1096    X32,
1097    /// x64
1098    X64,
1099    /// x128
1100    X128,
1101    /// x256
1102    X256,
1103    /// x512
1104    X512,
1105    /// x1k
1106    X1k,
1107    /// x2k
1108    X2k,
1109    /// .1
1110    _D1,
1111    /// .2
1112    _D2,
1113    /// .4
1114    _D4,
1115    /// .8
1116    _D8,
1117    /// .16
1118    _D16,
1119    /// .32
1120    _D32,
1121    /// .64
1122    _D64,
1123    /// .128
1124    _D128,
1125    /// .256
1126    _D256,
1127    /// .512
1128    _D512,
1129    /// .1k
1130    _D1k,
1131    /// .2k
1132    _D2k,
1133}
1134
1135impl TryFrom<&str> for LfoMultiplier {
1136    type Error = ConversionError;
1137    fn try_from(multiplier: &str) -> Result<Self, Self::Error> {
1138        use LfoMultiplier::*;
1139        match multiplier {
1140            "x1" => Ok(X1),
1141            "x2" => Ok(X2),
1142            "x4" => Ok(X4),
1143            "x8" => Ok(X8),
1144            "x16" => Ok(X16),
1145            "x32" => Ok(X32),
1146            "x64" => Ok(X64),
1147            "x128" => Ok(X128),
1148            "x256" => Ok(X256),
1149            "x512" => Ok(X512),
1150            "x1k" => Ok(X1k),
1151            "x2k" => Ok(X2k),
1152            ".1" => Ok(_D1),
1153            ".2" => Ok(_D2),
1154            ".4" => Ok(_D4),
1155            ".8" => Ok(_D8),
1156            ".16" => Ok(_D16),
1157            ".32" => Ok(_D32),
1158            ".64" => Ok(_D64),
1159            ".128" => Ok(_D128),
1160            ".256" => Ok(_D256),
1161            ".512" => Ok(_D512),
1162            ".1k" => Ok(_D1k),
1163            ".2k" => Ok(_D2k),
1164            _ => Err(ConversionError::Range {
1165                value: multiplier.to_string(),
1166                type_name: "LfoMultiplier".to_string(),
1167            }),
1168        }
1169    }
1170}
1171
1172impl From<LfoMultiplier> for &str {
1173    fn from(multiplier: LfoMultiplier) -> Self {
1174        use LfoMultiplier::*;
1175        match multiplier {
1176            X1 => "x1",
1177            X2 => "x2",
1178            X4 => "x4",
1179            X8 => "x8",
1180            X16 => "x16",
1181            X32 => "x32",
1182            X64 => "x64",
1183            X128 => "x128",
1184            X256 => "x256",
1185            X512 => "x512",
1186            X1k => "x1k",
1187            X2k => "x2k",
1188            _D1 => ".1",
1189            _D2 => ".2",
1190            _D4 => ".4",
1191            _D8 => ".8",
1192            _D16 => ".16",
1193            _D32 => ".32",
1194            _D64 => ".64",
1195            _D128 => ".128",
1196            _D256 => ".256",
1197            _D512 => ".512",
1198            _D1k => ".1k",
1199            _D2k => ".2k",
1200        }
1201    }
1202}
1203
1204impl TryFrom<u8> for LfoMultiplier {
1205    type Error = ConversionError;
1206    fn try_from(value: u8) -> Result<Self, Self::Error> {
1207        match value {
1208            0 => Ok(Self::X1),
1209            1 => Ok(Self::X2),
1210            2 => Ok(Self::X4),
1211            3 => Ok(Self::X8),
1212            4 => Ok(Self::X16),
1213            5 => Ok(Self::X32),
1214            6 => Ok(Self::X64),
1215            7 => Ok(Self::X128),
1216            8 => Ok(Self::X256),
1217            9 => Ok(Self::X512),
1218            10 => Ok(Self::X1k),
1219            11 => Ok(Self::X2k),
1220            12 => Ok(Self::_D1),
1221            13 => Ok(Self::_D2),
1222            14 => Ok(Self::_D4),
1223            15 => Ok(Self::_D8),
1224            16 => Ok(Self::_D16),
1225            17 => Ok(Self::_D32),
1226            18 => Ok(Self::_D64),
1227            19 => Ok(Self::_D128),
1228            20 => Ok(Self::_D256),
1229            21 => Ok(Self::_D512),
1230            22 => Ok(Self::_D1k),
1231            23 => Ok(Self::_D2k),
1232            _ => Err(ConversionError::Range {
1233                value: value.to_string(),
1234                type_name: "LfoMultiplier".to_string(),
1235            }),
1236        }
1237    }
1238}
1239
1240impl From<LfoMultiplier> for u8 {
1241    fn from(value: LfoMultiplier) -> Self {
1242        match value {
1243            LfoMultiplier::X1 => 0,
1244            LfoMultiplier::X2 => 1,
1245            LfoMultiplier::X4 => 2,
1246            LfoMultiplier::X8 => 3,
1247            LfoMultiplier::X16 => 4,
1248            LfoMultiplier::X32 => 5,
1249            LfoMultiplier::X64 => 6,
1250            LfoMultiplier::X128 => 7,
1251            LfoMultiplier::X256 => 8,
1252            LfoMultiplier::X512 => 9,
1253            LfoMultiplier::X1k => 10,
1254            LfoMultiplier::X2k => 11,
1255            LfoMultiplier::_D1 => 12,
1256            LfoMultiplier::_D2 => 13,
1257            LfoMultiplier::_D4 => 14,
1258            LfoMultiplier::_D8 => 15,
1259            LfoMultiplier::_D16 => 16,
1260            LfoMultiplier::_D32 => 17,
1261            LfoMultiplier::_D64 => 18,
1262            LfoMultiplier::_D128 => 19,
1263            LfoMultiplier::_D256 => 20,
1264            LfoMultiplier::_D512 => 21,
1265            LfoMultiplier::_D1k => 22,
1266            LfoMultiplier::_D2k => 23,
1267        }
1268    }
1269}
1270
1271/// The shape of an LFO wave.
1272#[derive(
1273    Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
1274)]
1275pub enum LfoWaveform {
1276    #[default]
1277    Tri,
1278    Sin,
1279    Sqr,
1280    Saw,
1281    Exp,
1282    Rmp,
1283    Rnd,
1284}
1285
1286impl TryFrom<&str> for LfoWaveform {
1287    type Error = ConversionError;
1288    fn try_from(waveform: &str) -> Result<Self, Self::Error> {
1289        use LfoWaveform::*;
1290        match waveform {
1291            "tri" => Ok(Tri),
1292            "sin" => Ok(Sin),
1293            "sqr" => Ok(Sqr),
1294            "saw" => Ok(Saw),
1295            "exp" => Ok(Exp),
1296            "rmp" => Ok(Rmp),
1297            "rnd" => Ok(Rnd),
1298            _ => Err(ConversionError::Range {
1299                value: waveform.to_string(),
1300                type_name: "LfoWaveform".to_string(),
1301            }),
1302        }
1303    }
1304}
1305
1306impl From<LfoWaveform> for &str {
1307    fn from(waveform: LfoWaveform) -> Self {
1308        use LfoWaveform::*;
1309        match waveform {
1310            Tri => "tri",
1311            Sin => "sin",
1312            Sqr => "sqr",
1313            Saw => "saw",
1314            Exp => "exp",
1315            Rmp => "rmp",
1316            Rnd => "rnd",
1317        }
1318    }
1319}
1320
1321impl TryFrom<u8> for LfoWaveform {
1322    type Error = ConversionError;
1323    fn try_from(value: u8) -> Result<Self, Self::Error> {
1324        match value {
1325            0 => Ok(Self::Tri),
1326            1 => Ok(Self::Sin),
1327            2 => Ok(Self::Sqr),
1328            3 => Ok(Self::Saw),
1329            4 => Ok(Self::Exp),
1330            5 => Ok(Self::Rmp),
1331            6 => Ok(Self::Rnd),
1332            _ => Err(ConversionError::Range {
1333                value: value.to_string(),
1334                type_name: "LfoWaveform".to_string(),
1335            }),
1336        }
1337    }
1338}
1339
1340impl From<LfoWaveform> for u8 {
1341    fn from(value: LfoWaveform) -> Self {
1342        match value {
1343            LfoWaveform::Tri => 0,
1344            LfoWaveform::Sin => 1,
1345            LfoWaveform::Sqr => 2,
1346            LfoWaveform::Saw => 3,
1347            LfoWaveform::Exp => 4,
1348            LfoWaveform::Rmp => 5,
1349            LfoWaveform::Rnd => 6,
1350        }
1351    }
1352}
1353
1354/// The mode of an LFO.
1355#[derive(
1356    Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
1357)]
1358pub enum LfoMode {
1359    #[default]
1360    Free,
1361    Trig,
1362    Hold,
1363    One,
1364    Half,
1365}
1366
1367impl TryFrom<&str> for LfoMode {
1368    type Error = ConversionError;
1369    fn try_from(mode: &str) -> Result<Self, Self::Error> {
1370        use LfoMode::*;
1371        match mode {
1372            "free" => Ok(Free),
1373            "trig" => Ok(Trig),
1374            "hold" => Ok(Hold),
1375            "one" => Ok(One),
1376            "half" => Ok(Half),
1377            _ => Err(ConversionError::Range {
1378                value: mode.to_string(),
1379                type_name: "LfoMode".to_string(),
1380            }),
1381        }
1382    }
1383}
1384
1385impl From<LfoMode> for &str {
1386    fn from(mode: LfoMode) -> Self {
1387        use LfoMode::*;
1388        match mode {
1389            Free => "free",
1390            Trig => "trig",
1391            Hold => "hold",
1392            One => "one",
1393            Half => "half",
1394        }
1395    }
1396}
1397
1398impl TryFrom<u8> for LfoMode {
1399    type Error = ConversionError;
1400    fn try_from(value: u8) -> Result<Self, Self::Error> {
1401        match value {
1402            0 => Ok(Self::Free),
1403            1 => Ok(Self::Trig),
1404            2 => Ok(Self::Hold),
1405            3 => Ok(Self::One),
1406            4 => Ok(Self::Half),
1407            _ => Err(ConversionError::Range {
1408                value: value.to_string(),
1409                type_name: "LfoMode".to_string(),
1410            }),
1411        }
1412    }
1413}
1414
1415impl From<LfoMode> for u8 {
1416    fn from(value: LfoMode) -> Self {
1417        match value {
1418            LfoMode::Free => 0,
1419            LfoMode::Trig => 1,
1420            LfoMode::Hold => 2,
1421            LfoMode::One => 3,
1422            LfoMode::Half => 4,
1423        }
1424    }
1425}
1426
1427/// The chromatic mode of a sound.
1428#[derive(
1429    Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
1430)]
1431pub enum SoundSettingsChromaticMode {
1432    Off,
1433    Synth,
1434    Sample,
1435    #[default]
1436    SynthAndSample,
1437}
1438
1439impl TryFrom<&str> for SoundSettingsChromaticMode {
1440    type Error = ConversionError;
1441    fn try_from(mode: &str) -> Result<Self, Self::Error> {
1442        use SoundSettingsChromaticMode::*;
1443        // TODO: Double check naming
1444        match mode {
1445            "off" => Ok(Off),
1446            "syn" => Ok(Synth),
1447            "samp" => Ok(Sample),
1448            "syn+samp" => Ok(SynthAndSample),
1449            _ => Err(ConversionError::Range {
1450                value: mode.to_string(),
1451                type_name: "SoundSettingsChromaticMode".to_string(),
1452            }),
1453        }
1454    }
1455}
1456
1457impl From<SoundSettingsChromaticMode> for &str {
1458    fn from(mode: SoundSettingsChromaticMode) -> Self {
1459        use SoundSettingsChromaticMode::*;
1460        match mode {
1461            Off => "off",
1462            Synth => "syn",
1463            Sample => "samp",
1464            SynthAndSample => "syn+samp",
1465        }
1466    }
1467}
1468
1469impl TryFrom<u8> for SoundSettingsChromaticMode {
1470    type Error = ConversionError;
1471    fn try_from(value: u8) -> Result<Self, Self::Error> {
1472        match value {
1473            0 => Ok(Self::Off),
1474            1 => Ok(Self::Synth),
1475            2 => Ok(Self::Sample),
1476            3 => Ok(Self::SynthAndSample),
1477            _ => Err(ConversionError::Range {
1478                value: value.to_string(),
1479                type_name: "SoundSettingsChromaticMode".to_string(),
1480            }),
1481        }
1482    }
1483}
1484
1485impl From<SoundSettingsChromaticMode> for u8 {
1486    fn from(value: SoundSettingsChromaticMode) -> Self {
1487        match value {
1488            SoundSettingsChromaticMode::Off => 0,
1489            SoundSettingsChromaticMode::Synth => 1,
1490            SoundSettingsChromaticMode::Sample => 2,
1491            SoundSettingsChromaticMode::SynthAndSample => 3,
1492        }
1493    }
1494}