augmented_audio_volume/
lib.rs1use std::ops::Mul;
30
31#[cfg(not(feature = "f64"))]
32pub type Float = f32;
33
34#[cfg(feature = "f64")]
35pub type Float = f64;
36
37#[derive(Default, PartialEq, PartialOrd, Debug, Clone, Copy)]
39pub struct Decibels {
40 decibels: Float,
41}
42
43impl Decibels {
44 pub fn from_db(decibels: Float) -> Self {
46 Decibels { decibels }
47 }
48
49 pub fn from_amplitude(amplitude: Float, reference_amplitude: Float) -> Self {
51 Decibels::from_db(amplitude_to_db(amplitude, reference_amplitude))
52 }
53
54 pub fn set_amplitude(&mut self, amplitude: Float, reference_amplitude: Float) {
56 self.decibels = amplitude_to_db(amplitude, reference_amplitude)
57 }
58
59 pub fn set_db(&mut self, db: Float) {
61 self.decibels = db;
62 }
63
64 pub fn as_amplitude(&self, reference_amplitude: Float) -> Float {
66 db_to_amplitude(self.decibels, reference_amplitude)
67 }
68
69 pub fn as_db(&self) -> Float {
71 self.decibels
72 }
73
74 pub fn amplitude(&self, reference_amplitude: Float) -> Amplitude {
76 Amplitude::from_db(self.decibels, reference_amplitude)
77 }
78}
79
80impl From<Float> for Decibels {
81 fn from(db: Float) -> Self {
82 Self::from_db(db)
83 }
84}
85
86impl From<Decibels> for Float {
87 fn from(db: Decibels) -> Self {
88 db.as_db()
89 }
90}
91
92impl Mul for Decibels {
93 type Output = Self;
94
95 fn mul(self, rhs: Self) -> Self::Output {
96 Self::from_db(self.decibels * rhs.decibels)
97 }
98}
99
100#[derive(Default, PartialEq, PartialOrd, Debug, Clone, Copy)]
102pub struct Amplitude {
103 amplitude: Float,
104}
105
106impl Amplitude {
107 pub fn from_amplitude(amplitude: Float) -> Self {
109 Amplitude { amplitude }
110 }
111
112 pub fn from_db(db: Float, reference_amplitude: Float) -> Self {
114 Amplitude::from_amplitude(db_to_amplitude(db, reference_amplitude))
115 }
116
117 pub fn set_amplitude(&mut self, amplitude: Float) {
119 self.amplitude = amplitude;
120 }
121
122 pub fn set_db(&mut self, db: Float, reference_amplitude: Float) {
124 self.amplitude = db_to_amplitude(db, reference_amplitude);
125 }
126
127 pub fn as_amplitude(&self) -> Float {
129 self.amplitude
130 }
131
132 pub fn as_db(&self, reference_amplitude: Float) -> Float {
134 amplitude_to_db(self.amplitude, reference_amplitude)
135 }
136
137 pub fn decibels(&self, reference_amplitude: Float) -> Decibels {
139 Decibels::from_amplitude(self.amplitude, reference_amplitude)
140 }
141}
142
143impl From<Float> for Amplitude {
144 fn from(volume: Float) -> Self {
145 Self::from_amplitude(volume)
146 }
147}
148
149impl From<Amplitude> for Float {
150 fn from(amp: Amplitude) -> Self {
151 amp.as_amplitude()
152 }
153}
154
155impl Mul for Amplitude {
156 type Output = Self;
157
158 fn mul(self, rhs: Self) -> Self::Output {
159 Self::from_amplitude(self.amplitude * rhs.amplitude)
160 }
161}
162
163impl Mul<Float> for Amplitude {
164 type Output = Self;
165
166 fn mul(self, rhs: Float) -> Self::Output {
167 Self::from_amplitude(self.amplitude * rhs)
168 }
169}
170
171pub fn db_to_amplitude(db: Float, reference_amplitude: Float) -> Float {
173 Float::powf(10.0, db / 20.0) * reference_amplitude
174}
175
176pub fn amplitude_to_db(volume: Float, reference_amplitude: Float) -> Float {
178 20.0 * (volume / reference_amplitude).log10()
179}
180
181#[cfg(test)]
182mod tests {
183 use audio_processor_testing_helpers::assert_f_eq;
184
185 use super::*;
186
187 #[test]
188 fn test_decibels_can_be_created_from_db() {
189 let db = Decibels::from_db(0.0);
190 assert_eq!(db.as_db(), 0.0);
191 }
192
193 #[test]
194 fn test_decibels_set_db() {
195 let mut db = Decibels::from_db(0.0);
196 db.set_db(-0.1);
197 assert_eq!(db.as_db(), -0.1);
198 }
199
200 #[test]
201 fn test_decibels_set_amplitude() {
202 let mut db = Decibels::from_db(3.0);
203 db.set_amplitude(1.0, 1.0);
204 assert_eq!(db.as_db(), 0.0);
205 }
206
207 #[test]
208 fn test_decibels_as_amplitude() {
209 let db = Decibels::from_db(0.0);
210 let amp = db.as_amplitude(1.0);
211 assert_eq!(amp, 1.0);
212 }
213
214 #[test]
215 fn test_decibels_amplitude() {
216 let db = Decibels::from_db(0.0);
217 let amp = db.amplitude(1.0);
218 let amp = amp.as_amplitude();
219 assert_eq!(amp, 1.0);
220 }
221
222 #[test]
223 fn test_decibels_from_float() {
224 let db = Decibels::from(0.0);
225 let db = db.as_db();
226 assert_eq!(db, 0.0);
227 }
228
229 #[test]
230 fn test_amplitude_from_amplitude() {
231 let amp = Amplitude::from_amplitude(1.0);
232 assert_eq!(amp.as_amplitude(), 1.0);
233 }
234
235 #[test]
236 fn test_amplitude_from_db() {
237 let amp = Amplitude::from_db(0.0, 1.0);
238 assert_eq!(amp.as_amplitude(), 1.0);
239 }
240
241 #[test]
242 fn test_amplitude_set_amplitude() {
243 let mut amp = Amplitude::from_amplitude(10.0);
244 amp.set_amplitude(2.0);
245 assert_eq!(amp.as_amplitude(), 2.0);
246 }
247
248 #[test]
249 fn test_amplitude_set_db() {
250 let mut amp = Amplitude::from_amplitude(10.0);
251 amp.set_db(0.0, 1.0);
252 assert_eq!(amp.as_amplitude(), 1.0);
253 }
254
255 #[test]
256 fn test_amplitude_as_db() {
257 let amp = Amplitude::from_amplitude(10.0);
258 let db = amp.as_db(1.0);
259 assert_eq!(db, 20.0);
260 }
261
262 #[test]
263 fn test_amplitude_decibels() {
264 let amp = Amplitude::from_amplitude(1.0);
265 let db = amp.decibels(1.0);
266 assert_eq!(db.as_amplitude(1.0), 1.0);
267 }
268
269 #[test]
270 fn test_amplitude_roundtrip() {
271 let amp = Amplitude::from_amplitude(1.0);
272 let db = amp.decibels(1.0);
273 let amp2 = db.amplitude(1.0);
274 assert_eq!(amp, amp2);
275 }
276
277 #[test]
278 fn test_amplitude_from_float() {
279 let amp = Amplitude::from(1.0);
280 assert_eq!(amp.as_amplitude(), 1.0);
281 }
282
283 #[test]
284 fn test_float_from_amplitude() {
285 let amp: f32 = Amplitude::from(1.0).into();
286 assert_eq!(amp, 1.0);
287 }
288
289 #[test]
290 fn test_amplitude_mult() {
291 let amp1 = Amplitude::from(3.0);
292 let amp2 = Amplitude::from(2.0);
293 let amp = amp1 * amp2;
294 assert_eq!(amp.as_amplitude(), 6.0);
295 }
296
297 #[test]
298 fn test_amplitude_mult_float() {
299 let amp1 = Amplitude::from(3.0);
300 let amp2 = 2.0;
301 let amp = amp1 * amp2;
302 assert_eq!(amp.as_amplitude(), 6.0);
303 }
304
305 #[test]
306 fn test_it_can_be_created() {
307 let volume = Amplitude::from_amplitude(1.0);
308 assert_f_eq!(volume.as_amplitude(), 1.0);
309 }
310
311 #[test]
312 fn test_it_can_be_converted_to_db() {
313 let volume = Amplitude::from_amplitude(1.0);
314 let db = volume.decibels(1.0);
315 assert_f_eq!(db.as_db(), 0.0);
316 }
317}