torque_tracker_engine/audio_processing/
mod.rs1use 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 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 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 unsafe { slice::from_raw_parts(ptr, len) }
100 }
101
102 pub fn from_ref<'a>(value: &'a [f32; 2]) -> &'a Self {
103 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 pub fn pan_constant_power(&mut self, angle: f32) {
125 self.0[0] *= angle.cos();
126 self.0[1] *= angle.sin();
127 }
128
129 }