eurorack_oxide_utils/
voct.rs1use core::ops;
4#[allow(unused_imports)]
5use micromath::F32Ext;
6
7pub trait Voltage {
9 fn hz(&self) -> f32;
11
12 fn ms(&self) -> u32;
14
15 fn us(&self) -> u32;
17}
18
19#[derive(Debug)]
21pub struct VOct(pub f32);
22
23#[derive(Debug)]
25pub struct MvOct(pub f32);
26
27const C1_FREQ: f32 = 32.703;
28
29impl Voltage for VOct {
30 fn hz(&self) -> f32 {
32 C1_FREQ * 2_f32.powf(self.0 - 1.0)
33 }
34
35 fn ms(&self) -> u32 {
37 (1000.0 / self.hz()) as u32
38 }
39
40 fn us(&self) -> u32 {
42 (1000000.0 / self.hz()) as u32
43 }
44}
45
46impl Voltage for MvOct {
47 fn hz(&self) -> f32{
48 C1_FREQ * 2_f32.powf(self.0 / 1000.0 - 1.0)
49 }
50
51 fn ms(&self) -> u32{
52 (1000.0 / self.hz()) as u32
53 }
54
55 fn us(&self) -> u32{
56 (1000000.0 / self.hz()) as u32
57 }
58}
59
60impl From<MvOct> for VOct {
61 fn from(mv: MvOct) -> Self {
62 Self(mv.0 / 1000.0)
63 }
64}
65
66impl From<VOct> for MvOct {
67 fn from(mv: VOct) -> Self {
68 Self(mv.0 * 1000.0)
69 }
70}
71
72macro_rules! impl_arithmetic {
75 ($wrapper:ty, $wrapped:ty) => {
76 impl ops::Mul<$wrapped> for $wrapper {
77 type Output = Self;
78 fn mul(self, rhs: $wrapped) -> Self {
79 Self(self.0 * rhs)
80 }
81 }
82
83 impl ops::MulAssign<$wrapped> for $wrapper {
84 fn mul_assign(&mut self, rhs: $wrapped) {
85 self.0 *= rhs;
86 }
87 }
88
89 impl ops::Div<$wrapped> for $wrapper {
90 type Output = Self;
91 fn div(self, rhs: $wrapped) -> Self {
92 Self(self.0 / rhs)
93 }
94 }
95
96 impl ops::Div<$wrapper> for $wrapper {
97 type Output = $wrapped;
98 fn div(self, rhs: $wrapper) -> $wrapped {
99 self.0 / rhs.0
100 }
101 }
102
103 impl ops::DivAssign<$wrapped> for $wrapper {
104 fn div_assign(&mut self, rhs: $wrapped) {
105 self.0 /= rhs;
106 }
107 }
108
109 impl ops::Add<$wrapped> for $wrapper {
110 type Output = Self;
111 fn add(self, rhs: $wrapped) -> Self {
112 Self(self.0 + rhs)
113 }
114 }
115
116 impl ops::Sub<$wrapped> for $wrapper {
117 type Output = Self;
118 fn sub(self, rhs: $wrapped) -> Self {
119 Self(self.0 - rhs)
120 }
121 }
122
123 impl ops::AddAssign<$wrapped> for $wrapper {
124 fn add_assign(&mut self, rhs: $wrapped) {
125 self.0 += rhs;
126 }
127 }
128
129 impl ops::SubAssign<$wrapped> for $wrapper {
130 fn sub_assign(&mut self, rhs: $wrapped) {
131 self.0 -= rhs;
132 }
133 }
134 };
135}
136
137impl_arithmetic!(VOct, f32);
138impl_arithmetic!(MvOct, f32);