m8_file_parser/instruments/modulator/
mod.rs1use crate::{reader::*, writer::Writer};
2
3use super::Version;
4
5mod adsr_env;
6mod ahd_env;
7mod drum_env;
8mod lfo;
9mod tracking_env;
10mod trig_env;
11
12pub use adsr_env::*;
13pub use ahd_env::*;
14pub use drum_env::*;
15pub use lfo::*;
16pub use tracking_env::*;
17pub use trig_env::*;
18
19#[derive(PartialEq, Debug, Clone)]
20pub enum Mod {
21 AHDEnv(AHDEnv),
22 ADSREnv(ADSREnv),
23 DrumEnv(DrumEnv),
24 LFO(LFO),
25 TrigEnv(TrigEnv),
26 TrackingEnv(TrackingEnv),
27}
28
29impl Mod {
30 const SIZE: usize = 6;
32
33 pub const COMMAND_PER_MOD: usize = 5;
35
36 pub fn command_name(&self, ver: Version, mod_id: usize) -> &'static [&'static str] {
37 match self {
38 Mod::AHDEnv(_) => AHDEnv::command_names(ver, mod_id),
39 Mod::ADSREnv(_) => ADSREnv::command_name(ver, mod_id),
40 Mod::DrumEnv(_) => DrumEnv::command_names(ver, mod_id),
41 Mod::LFO(_) => LFO::command_name(ver, mod_id),
42 Mod::TrigEnv(_) => TrigEnv::command_name(ver, mod_id),
43 Mod::TrackingEnv(_) => TrackingEnv::command_name(ver, mod_id),
44 }
45 }
46
47 pub fn from_reader(reader: &mut Reader) -> M8Result<Self> {
48 let start_pos = reader.pos();
49 let first_byte = reader.read();
50 let ty = first_byte >> 4;
51 let dest = first_byte & 0x0F;
52
53 let r = match ty {
55 0 => Mod::AHDEnv(AHDEnv::from_reader3(reader, dest)?),
56 1 => Mod::ADSREnv(ADSREnv::from_reader(reader, dest)?),
57 2 => Mod::DrumEnv(DrumEnv::from_reader(reader, dest)?),
58 3 => Mod::LFO(LFO::from_reader3(reader, dest)?),
59 4 => Mod::TrigEnv(TrigEnv::from_reader(reader, dest)?),
60 5 => Mod::TrackingEnv(TrackingEnv::from_reader(reader, dest)?),
61 x => return Err(ParseError(format!("Unknown mod type {}", x))),
62 };
63
64 reader.set_pos(start_pos + Self::SIZE);
65 Ok(r)
66 }
67
68 pub fn write(&self, w: &mut Writer) {
69 let start = w.pos();
70
71 match self {
72 Mod::AHDEnv(env) => {
73 w.write(env.dest);
74 env.write(w);
75 }
76 Mod::ADSREnv(env) => {
77 w.write(1 << 4 | env.dest);
78 env.write(w);
79 }
80 Mod::DrumEnv(env) => {
81 w.write(2 << 4 | env.dest);
82 env.write(w);
83 }
84 Mod::LFO(lfo) => {
85 w.write(3 << 4 | lfo.dest);
86 lfo.write(w);
87 }
88 Mod::TrigEnv(env) => {
89 w.write(4 << 4 | env.dest);
90 env.write(w);
91 }
92 Mod::TrackingEnv(env) => {
93 w.write(5 << 4 | env.dest);
94 env.write(w);
95 }
96 }
97
98 w.seek(start + Self::SIZE);
99 }
100}