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