torque_tracker_engine/audio_processing/
mod.rs

1use core::slice;
2use std::{array, ops::IndexMut};
3
4use dasp::sample::ToSample;
5
6pub(crate) mod instrument;
7pub mod playback;
8pub(crate) mod sample;
9
10#[repr(transparent)]
11#[derive(Clone, Copy, Default, Debug, PartialEq)]
12pub struct Frame([f32; 2]);
13
14impl std::ops::AddAssign for Frame {
15    fn add_assign(&mut self, rhs: Self) {
16        *self = *self + rhs;
17    }
18}
19
20impl std::ops::Add for Frame {
21    type Output = Self;
22
23    fn add(self, rhs: Self) -> Self::Output {
24        Self([self.0[0] + rhs.0[0], self.0[1] + rhs.0[1]])
25    }
26}
27
28impl std::ops::Sub for Frame {
29    type Output = Self;
30
31    fn sub(self, rhs: Self) -> Self::Output {
32        Self([self.0[0] - rhs.0[0], self.0[1] - rhs.0[1]])
33    }
34}
35
36impl std::ops::SubAssign for Frame {
37    fn sub_assign(&mut self, rhs: Self) {
38        *self = *self - rhs;
39    }
40}
41
42impl std::ops::MulAssign<f32> for Frame {
43    fn mul_assign(&mut self, rhs: f32) {
44        *self.0.index_mut(0) *= rhs;
45        *self.0.index_mut(1) *= rhs;
46    }
47}
48
49impl std::ops::Mul<f32> for Frame {
50    type Output = Self;
51
52    fn mul(self, rhs: f32) -> Self::Output {
53        Self([self.0[0] * rhs, self.0[1] * rhs])
54    }
55}
56
57impl std::iter::Sum for Frame {
58    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
59        iter.reduce(|acc, x| acc + x).unwrap_or_default()
60    }
61}
62
63impl From<[f32; 2]> for Frame {
64    fn from(value: [f32; 2]) -> Self {
65        Self(value)
66    }
67}
68
69impl From<f32> for Frame {
70    fn from(value: f32) -> Self {
71        Self([value, value])
72    }
73}
74
75impl Frame {
76    // split into left and right.
77    pub fn split_array<const N: usize>(value: [Frame; N]) -> ([f32; N], [f32; N]) {
78        (
79            array::from_fn(|i| value[i].0[0]),
80            array::from_fn(|i| value[i].0[1]),
81        )
82    }
83
84    pub fn sum_to_mono(self) -> f32 {
85        self.0[0] + self.0[1]
86    }
87
88    pub fn from_mut<'a>(value: &'a mut [f32; 2]) -> &'a mut Self {
89        // SAFETY: lifetime is specified, both mut, Self is repr(transparent).
90        unsafe { std::mem::transmute::<&'a mut [f32; 2], &'a mut Self>(value) }
91    }
92
93    pub fn from_interleaved(value: &[f32]) -> &[Frame] {
94        debug_assert!(value.len().rem_euclid(2) == 0);
95        let len = value.len() / 2;
96        let ptr = value.as_ptr().cast();
97        // SAFETY: keeps the same lifetime and mutability.
98        // [f32; 2] is a valid frame
99        unsafe { slice::from_raw_parts(ptr, len) }
100    }
101
102    pub fn from_ref<'a>(value: &'a [f32; 2]) -> &'a Self {
103        // SAFETY: lifetime is specified, both not mut, Self is repr(transparent).
104        unsafe { std::mem::transmute::<&'a [f32; 2], &'a Self>(value) }
105    }
106
107    pub fn to_sample<S: dasp::sample::FromSample<f32>>(self) -> [S; 2] {
108        [self.0[0].to_sample_(), self.0[1].to_sample_()]
109    }
110
111    pub fn to_raw<'a>(into: &mut [Self]) -> &'a mut [[f32; 2]] {
112        unsafe { std::mem::transmute(into) }
113    }
114
115    // pan laws taken from: https://www.cs.cmu.edu/~music/icm-online/readings/panlaws/index.html
116
117    // /// angle in radians between 0 and 90°
118    // pub fn pan_linear(&mut self, angle: f32) {
119    //     self.0[0] *= (std::f32::consts::FRAC_PI_2 - angle) * std::f32::consts::FRAC_2_PI;
120    //     self.0[1] *= angle * std::f32::consts::FRAC_2_PI;
121    // }
122
123    /// angle in radians between 0 and 90°
124    pub fn pan_constant_power(&mut self, angle: f32) {
125        self.0[0] *= angle.cos();
126        self.0[1] *= angle.sin();
127    }
128
129    // /// angle in radians between 0 and 90°
130    // pub fn pan_compromise(&mut self, angle: f32) {
131    //     self.0[0] *= f32::sqrt(
132    //         (std::f32::consts::FRAC_PI_2 - angle) * std::f32::consts::FRAC_2_PI * angle.cos(),
133    //     );
134    //     self.0[1] *= f32::sqrt(angle * std::f32::consts::FRAC_2_PI * angle.sin());
135    // }
136}