m8_files/instruments/
external_inst.rs

1use 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] // Keep constats with important order vertical for maintenance
31const 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    // EXTRA
53    "ADD",
54    "CHD"
55];
56
57#[rustfmt::skip] // Keep constats with important order vertical for maintenance
58const 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
75/// Ports name of the external instrument
76#[rustfmt::skip] // Keep constats with important order vertical for maintenance
77const PORT : [&'static str; 4] = [
78    "NONE",
79    "MIDI+USB",
80    "MIDI",
81    "USB"
82];
83
84impl ExternalInst {
85    const MOD_OFFSET: usize = 22;
86
87    pub fn command_name(&self, _ver: Version) -> &'static [&'static str] {
88        &EXTERNAL_INST_COMMANDS
89    }
90
91    pub fn destination_names(&self, _ver: Version) -> &'static [&'static str] {
92        &DESTINATIONS
93    }
94
95    /// Return human readable name of the port.
96    pub fn human_readable_port(&self) -> &'static str {
97        PORT[self.port as usize]
98    }
99
100    pub fn write(&self, ver: Version, w: &mut Writer) {
101        w.write_string(&self.name, 12);
102        w.write(TranspEq::from(ver, self.transpose, self.synth_params.associated_eq).into());
103        w.write(self.table_tick);
104        w.write(self.synth_params.volume);
105        w.write(self.synth_params.pitch);
106        w.write(self.synth_params.fine_tune);
107
108        w.write(self.input);
109        w.write(self.port);
110        w.write(self.channel);
111        w.write(self.bank);
112        w.write(self.program);
113
114        self.cca.write(w);
115        self.ccb.write(w);
116        self.ccc.write(w);
117        self.ccd.write(w);
118
119        self.synth_params.write(ver, w, ExternalInst::MOD_OFFSET);
120    }
121
122    pub fn from_reader(ver: Version, reader: &mut Reader, number: u8) -> M8Result<Self> {
123        let name = reader.read_string(12);
124        let transp_eq = TranspEq::from_version(ver, reader.read());
125
126        let table_tick = reader.read();
127        let volume = reader.read();
128        let pitch = reader.read();
129        let fine_tune = reader.read();
130
131        let input = reader.read();
132        let port = reader.read();
133        let channel = reader.read();
134        let bank = reader.read();
135        let program = reader.read();
136        let cca = ControlChange::from_reader(reader)?;
137        let ccb = ControlChange::from_reader(reader)?;
138        let ccc = ControlChange::from_reader(reader)?;
139        let ccd = ControlChange::from_reader(reader)?;
140
141        let synth_params = SynthParams::from_reader3(
142            ver,
143            reader,
144            volume,
145            pitch,
146            fine_tune,
147            transp_eq.eq,
148            ExternalInst::MOD_OFFSET,
149        )?;
150
151        Ok(ExternalInst {
152            number,
153            name,
154            transpose: transp_eq.transpose,
155            table_tick,
156            synth_params,
157
158            input,
159            port,
160            channel,
161            bank,
162            program,
163            cca,
164            ccb,
165            ccc,
166            ccd,
167        })
168    }
169}