m8_file_parser/instruments/
external_inst.rs1use super::common::SynthParams;
2use super::common::TranspEq;
3use super::dests;
4use super::midi::ControlChange;
5use super::params;
6use super::CommandPack;
7use super::Version;
8use crate::reader::*;
9use crate::writer::Writer;
10
11#[derive(PartialEq, Debug, Clone)]
12pub struct ExternalInst {
13 pub number: u8,
14 pub name: String,
15 pub transpose: bool,
16 pub table_tick: u8,
17 pub synth_params: SynthParams,
18
19 pub input: u8,
20 pub port: u8,
21 pub channel: u8,
22 pub bank: u8,
23 pub program: u8,
24 pub cca: ControlChange,
25 pub ccb: ControlChange,
26 pub ccc: ControlChange,
27 pub ccd: ControlChange,
28}
29
30#[rustfmt::skip] const EXTERNAL_INST_COMMANDS : [&'static str; CommandPack::BASE_INSTRUMENT_COMMAND_COUNT + 2] = [
32 "VOL",
33 "PIT",
34 "MPB",
35 "MPG",
36 "CCA",
37 "CCB",
38 "CCC",
39 "CCD",
40 "FLT",
41 "CUT",
42 "RES",
43 "AMP",
44 "LIM",
45 "PAN",
46 "DRY",
47
48 "SCH",
49 "SDL",
50 "SRV",
51
52 "ADD",
54 "CHD"
55];
56
57#[rustfmt::skip] const DESTINATIONS : [&'static str; 14] = [
59 dests::OFF,
60 dests::VOLUME,
61 dests::CUTOFF,
62 dests::RES,
63 dests::AMP,
64 dests::PAN,
65 params::CCA,
66 params::CCB,
67 params::CCC,
68 params::CCD,
69 dests::MOD_AMT,
70 dests::MOD_RATE,
71 dests::MOD_BOTH,
72 dests::MOD_BINV,
73];
74
75impl ExternalInst {
76 const MOD_OFFSET: usize = 22;
77
78 pub fn command_name(&self, _ver: Version) -> &'static [&'static str] {
79 &EXTERNAL_INST_COMMANDS
80 }
81
82 pub fn destination_names(&self, _ver: Version) -> &'static [&'static str] {
83 &DESTINATIONS
84 }
85
86 pub fn filter_types(&self, _ver: Version) -> &'static [&'static str] {
88 &super::common::COMMON_FILTER_TYPES
89 }
90
91 pub fn human_readable_port(&self) -> &'static str {
93 crate::instruments::midi::PORTS[self.port as usize]
94 }
95
96 pub fn write(&self, ver: Version, w: &mut Writer) {
97 w.write_string(&self.name, 12);
98 w.write(TranspEq::from(ver, self.transpose, self.synth_params.associated_eq).into());
99 w.write(self.table_tick);
100 w.write(self.synth_params.volume);
101 w.write(self.synth_params.pitch);
102 w.write(self.synth_params.fine_tune);
103
104 w.write(self.input);
105 w.write(self.port);
106 w.write(self.channel);
107 w.write(self.bank);
108 w.write(self.program);
109
110 self.cca.write(w);
111 self.ccb.write(w);
112 self.ccc.write(w);
113 self.ccd.write(w);
114
115 self.synth_params.write(ver, w, ExternalInst::MOD_OFFSET);
116 }
117
118 pub fn from_reader(ver: Version, reader: &mut Reader, number: u8) -> M8Result<Self> {
119 let name = reader.read_string(12);
120 let transp_eq = TranspEq::from_version(ver, reader.read());
121
122 let table_tick = reader.read();
123 let volume = reader.read();
124 let pitch = reader.read();
125 let fine_tune = reader.read();
126
127 let input = reader.read();
128 let port = reader.read();
129 let channel = reader.read();
130 let bank = reader.read();
131 let program = reader.read();
132 let cca = ControlChange::from_reader(reader)?;
133 let ccb = ControlChange::from_reader(reader)?;
134 let ccc = ControlChange::from_reader(reader)?;
135 let ccd = ControlChange::from_reader(reader)?;
136
137 let synth_params = SynthParams::from_reader3(
138 ver,
139 reader,
140 volume,
141 pitch,
142 fine_tune,
143 transp_eq.eq,
144 ExternalInst::MOD_OFFSET,
145 )?;
146
147 Ok(ExternalInst {
148 number,
149 name,
150 transpose: transp_eq.transpose,
151 table_tick,
152 synth_params,
153
154 input,
155 port,
156 channel,
157 bank,
158 program,
159 cca,
160 ccb,
161 ccc,
162 ccd,
163 })
164 }
165}