rstmt_core/freq/
impl_freq.rs1use super::{Frequency, RawFrequency};
6use crate::consts::A4_FREQUENCY;
7use crate::pitch::{PitchClass, RawAccidental, RawPitchClass};
8use crate::utils::{classify_freq_with_scale, compute_freq_of_pitch};
9use num_traits::{Float, FromPrimitive, ToPrimitive};
10use rstmt_traits::ClassifyBy;
11
12impl<T> Frequency<T>
13where
14 T: RawFrequency,
15{
16 pub const fn new(index: T) -> Self {
18 Frequency(index)
19 }
20 pub fn from_class_with_scale<N>(note: N, root: T) -> Self
26 where
27 N: ToPrimitive,
28 T: Float + FromPrimitive,
29 {
30 let class = note.to_isize().unwrap();
31 Self(compute_freq_of_pitch(class, root))
32 }
33 pub fn from_class_on_a4<N>(note: N) -> Self
36 where
37 N: ToPrimitive,
38 T: Float + FromPrimitive,
39 {
40 let root = <T>::from_f64(A4_FREQUENCY).unwrap();
41 Self::from_class_with_scale(note, root)
42 }
43 pub fn from_pitch_class<P, K>(class: PitchClass<P, K>, root: T) -> Self
45 where
46 P: RawPitchClass<Tag = K>,
47 K: RawAccidental,
48 T: RawFrequency + Float + FromPrimitive,
49 {
50 let semitones = class.get().index();
51 Self::from_class_with_scale(semitones, root)
52 }
53 pub fn init<F>(f: F) -> Self
55 where
56 F: FnOnce() -> T,
57 {
58 Frequency(f())
59 }
60 pub fn one() -> Self
62 where
63 T: num_traits::One,
64 {
65 Frequency::init(T::one)
66 }
67 pub fn zero() -> Self
69 where
70 T: num_traits::Zero,
71 {
72 Frequency::init(T::zero)
73 }
74 pub const fn as_ptr(&self) -> *const T {
76 core::ptr::from_ref(self.get())
77 }
78 pub const fn as_mut_ptr(&mut self) -> *mut T {
80 core::ptr::from_mut(self.get_mut())
81 }
82 #[inline]
83 pub fn value(self) -> T {
85 self.0
86 }
87 pub const fn get(&self) -> &T {
89 &self.0
90 }
91 pub const fn get_mut(&mut self) -> &mut T {
93 &mut self.0
94 }
95 #[inline]
96 pub fn map<U, F>(self, f: F) -> Frequency<U>
98 where
99 F: FnOnce(T) -> U,
100 {
101 Frequency(f(self.value()))
102 }
103 #[inline]
104 pub fn apply<U, F>(&self, mut f: F) -> Frequency<U>
107 where
108 F: FnMut(&T) -> U,
109 {
110 Frequency(f(self.get()))
111 }
112 pub fn apply_inplace<F>(&mut self, f: F) -> &mut Self
114 where
115 F: FnOnce(&mut T),
116 {
117 f(self.get_mut());
118 self
119 }
120 pub const fn replace(&mut self, index: T) -> T {
123 core::mem::replace(self.get_mut(), index)
124 }
125 #[inline]
126 pub fn set(&mut self, index: T) {
128 *self.get_mut() = index
129 }
130 pub const fn swap(&mut self, other: &mut Self) {
132 core::mem::swap(self.get_mut(), other.get_mut());
133 }
134 #[inline]
135 pub fn take(&mut self) -> T
138 where
139 T: Default,
140 {
141 core::mem::take(self.get_mut())
142 }
143 #[inline]
144 pub fn with<U>(self, other: U) -> Frequency<U> {
146 Frequency(other)
147 }
148 pub const fn view(&self) -> Frequency<&T> {
150 Frequency(self.get())
151 }
152 pub const fn view_mut(&mut self) -> Frequency<&mut T> {
154 Frequency(self.get_mut())
155 }
156 pub fn classify_by<Z>(&self, base: T) -> Z
162 where
163 Self: ClassifyBy<T, Output = Z>,
164 {
165 ClassifyBy::classify_by(self, base)
166 }
167 pub fn get_octave_with(&self, base: T) -> isize
169 where
170 T: Float + FromPrimitive,
171 {
172 self.classify_by(base) / 12
173 }
174 pub fn get_octave(&self) -> isize
176 where
177 T: Float + FromPrimitive,
178 {
179 let root = <T>::from_f64(A4_FREQUENCY).unwrap();
180 self.get_octave_with(root)
181 }
182}
183
184impl<T> ClassifyBy<T> for Frequency<T>
185where
186 T: RawFrequency + Float + FromPrimitive,
187{
188 type Output = isize;
189
190 fn classify_by(&self, base: T) -> Self::Output {
191 classify_freq_with_scale(self.value(), base).expect("failed to classify frequency")
192 }
193}