m8_file_parser/
eq.rs

1use num_enum::{IntoPrimitive, TryFromPrimitive};
2
3use crate::{reader::*, writer::Writer};
4
5#[repr(u8)]
6#[derive(IntoPrimitive, TryFromPrimitive, PartialEq, Copy, Clone, Default, Debug)]
7pub enum EqType {
8    #[default]
9    LowCut = 0,
10    LowShelf = 1,
11    Bell = 2,
12    BandPass = 3,
13    HiShelf = 4,
14    HiCut = 5,
15    AllPass = 6,
16}
17
18#[rustfmt::skip] // Keep constants with important order vertical for maintenance
19const EQ_TYPE_STR : [&'static str; 7] = [
20    "LOWCUT",
21    "LOWSHELF",
22    "BELL",
23    "BANDPASS",
24    "HI.SHELF",
25    "HI.CUT",
26    "ALLPASS"
27];
28
29#[repr(u8)]
30#[derive(IntoPrimitive, TryFromPrimitive, PartialEq, Copy, Clone, Default, Debug)]
31pub enum EqMode {
32    #[default]
33    Stereo = 0,
34    Mid = 1,
35    Side = 2,
36    Left = 3,
37    Right = 4,
38}
39
40#[rustfmt::skip] // Keep constants with important order vertical for maintenance
41const EQ_MODE_STR : [&'static str; 5] = [
42    "STEREO",
43    "MID",
44    "SIDE",
45    "LEFT",
46    "RIGHT"
47];
48
49#[derive(PartialEq, Eq, Clone, Debug, Copy, Default)]
50pub struct EqModeType(pub u8);
51
52impl EqModeType {
53    pub fn new(ty: EqType, mode: EqMode) -> EqModeType {
54        EqModeType(ty as u8 | ((mode as u8) << 5))
55    }
56
57    pub fn eq_mode_hex(&self) -> u8 {
58        (self.0 >> 5) & 0x7
59    }
60
61    pub fn eq_type(&self) -> EqType {
62        EqType::try_from(self.eq_type_hex()).unwrap_or(EqType::Bell)
63    }
64
65    pub fn eq_type_hex(&self) -> u8 {
66        self.0 & 0x7
67    }
68
69    pub fn eq_mode(&self) -> EqMode {
70        EqMode::try_from(self.eq_mode_hex()).unwrap_or(EqMode::Stereo)
71    }
72
73    pub fn mode_str(&self) -> &'static str {
74        let index = self.eq_mode_hex() as usize;
75        EQ_MODE_STR.get(index).unwrap_or(&"")
76    }
77
78    pub fn type_str(&self) -> &'static str {
79        let index = self.eq_type_hex() as usize;
80        EQ_TYPE_STR.get(index).unwrap_or(&"")
81    }
82}
83
84#[derive(PartialEq, Clone, Debug, Default)]
85pub struct EqBand {
86    pub mode: EqModeType,
87
88    pub freq_fin: u8,
89    pub freq: u8,
90
91    pub level_fin: u8,
92    pub level: u8,
93
94    pub q: u8,
95}
96
97impl EqBand {
98    const V4_SIZE: usize = 6;
99
100    pub fn default_low() -> EqBand {
101        let freq = 100 as usize;
102        EqBand {
103            mode: EqModeType::new(EqType::LowShelf, EqMode::Stereo),
104            freq: (freq >> 8) as u8,
105            freq_fin: (freq & 0xFF) as u8,
106
107            level_fin: 0,
108            level: 0,
109
110            q: 50,
111        }
112    }
113
114    pub fn default_mid() -> EqBand {
115        let freq = 1000 as usize;
116        EqBand {
117            mode: EqModeType::new(EqType::Bell, EqMode::Stereo),
118            freq: (freq >> 8) as u8,
119            freq_fin: (freq & 0xFF) as u8,
120
121            level_fin: 0,
122            level: 0,
123
124            q: 50,
125        }
126    }
127
128    pub fn default_high() -> EqBand {
129        let freq = 5000 as usize;
130        EqBand {
131            mode: EqModeType::new(EqType::HiShelf, EqMode::Stereo),
132            freq: (freq >> 8) as u8,
133            freq_fin: (freq & 0xFF) as u8,
134
135            level_fin: 0,
136            level: 0,
137
138            q: 50,
139        }
140    }
141
142    pub fn is_empty(&self) -> bool {
143        self.level == 0 && self.level_fin == 0
144    }
145
146    pub fn gain(&self) -> f64 {
147        let int_gain = ((self.level as i16) << 8) | (self.level_fin as i16);
148        (int_gain as f64) / 100.0
149    }
150
151    pub fn frequency(&self) -> usize {
152        ((self.freq as usize) << 8) | self.freq_fin as usize
153    }
154
155    pub fn write(&self, w: &mut Writer) {
156        w.write(self.mode.0);
157        w.write(self.freq_fin);
158        w.write(self.freq);
159        w.write(self.level_fin);
160        w.write(self.level);
161        w.write(self.q);
162    }
163
164    pub fn from_reader(reader: &mut Reader) -> EqBand {
165        let mode = EqModeType(reader.read());
166        let freq_fin = reader.read();
167        let freq = reader.read();
168        let level_fin = reader.read();
169        let level = reader.read();
170        let q = reader.read();
171
172        Self {
173            level,
174            level_fin,
175            freq,
176            freq_fin,
177            mode,
178            q,
179        }
180    }
181}
182
183#[derive(PartialEq, Clone, Debug, Default)]
184pub struct Equ {
185    pub low: EqBand,
186    pub mid: EqBand,
187    pub high: EqBand,
188}
189
190impl Equ {
191    pub const V4_SIZE: usize = 3 * EqBand::V4_SIZE;
192
193    pub fn is_empty(&self) -> bool {
194        self.low == EqBand::default_low()
195            && self.mid == EqBand::default_mid()
196            && self.high == EqBand::default_high()
197    }
198
199    pub fn clear(&mut self) {
200        self.low = EqBand::default_low();
201        self.mid = EqBand::default_mid();
202        self.high = EqBand::default_high();
203    }
204
205    pub fn write(&self, w: &mut Writer) {
206        self.low.write(w);
207        self.mid.write(w);
208        self.high.write(w);
209    }
210
211    pub fn from_reader(reader: &mut Reader) -> Equ {
212        let low = EqBand::from_reader(reader);
213        let mid = EqBand::from_reader(reader);
214        let high = EqBand::from_reader(reader);
215        Self { low, mid, high }
216    }
217}