rubato/
sample.rs

1use crate::sinc_interpolator::{AvxSample, NeonSample, SseSample};
2
3#[cfg(feature = "fft_resampler")]
4use realfft::FftNum;
5
6#[cfg(not(feature = "fft_resampler"))]
7use num_traits::{FromPrimitive, Signed};
8#[cfg(not(feature = "fft_resampler"))]
9use std::fmt::Debug;
10
11#[cfg(not(feature = "fft_resampler"))]
12pub trait FftNum: Copy + FromPrimitive + Signed + Sync + Send + Debug + 'static {}
13
14#[cfg(not(feature = "fft_resampler"))]
15impl<T> FftNum for T where T: Copy + FromPrimitive + Signed + Sync + Send + Debug + 'static {}
16
17/// The trait governing a single sample.
18///
19/// There are two types which implements this trait so far:
20/// * [f32]
21/// * [f64]
22pub trait Sample
23where
24    Self: Copy
25        + CoerceFrom<usize>
26        + CoerceFrom<f64>
27        + CoerceFrom<f32>
28        + FftNum
29        + std::ops::Mul
30        + std::ops::Div
31        + std::ops::Add
32        + std::ops::Sub
33        + std::ops::MulAssign
34        + std::ops::RemAssign
35        + std::ops::DivAssign
36        + std::ops::SubAssign
37        + std::ops::AddAssign
38        + AvxSample
39        + SseSample
40        + NeonSample
41        + Send,
42{
43    const PI: Self;
44
45    /// Calculate the sine of `self`.
46    fn sin(self) -> Self;
47
48    /// Calculate the cosine of `self`.
49    fn cos(self) -> Self;
50
51    /// Coerce `value` into the current type.
52    ///
53    /// Coercions are governed through the private `CoerceFrom` trait.
54    fn coerce<T>(value: T) -> Self
55    where
56        Self: CoerceFrom<T>,
57    {
58        Self::coerce_from(value)
59    }
60}
61
62impl Sample for f32 {
63    const PI: Self = std::f32::consts::PI;
64
65    fn sin(self) -> Self {
66        f32::sin(self)
67    }
68
69    fn cos(self) -> Self {
70        f32::cos(self)
71    }
72}
73
74impl Sample for f64 {
75    const PI: Self = std::f64::consts::PI;
76
77    fn sin(self) -> Self {
78        f64::sin(self)
79    }
80
81    fn cos(self) -> Self {
82        f64::cos(self)
83    }
84}
85
86/// The trait used to coerce a value infallibly from one type to another.
87///
88/// This is similar to doing `value as T` where `T` is a floating point type.
89/// Loss of precision may happen during coercions if the coerced from value
90/// doesn't fit fully within the target type.
91pub trait CoerceFrom<T> {
92    /// Perform a coercion from `value` into the current type.
93    fn coerce_from(value: T) -> Self;
94}
95
96impl CoerceFrom<usize> for f32 {
97    fn coerce_from(value: usize) -> Self {
98        value as f32
99    }
100}
101
102impl CoerceFrom<usize> for f64 {
103    fn coerce_from(value: usize) -> Self {
104        value as f64
105    }
106}
107
108impl CoerceFrom<f64> for f32 {
109    fn coerce_from(value: f64) -> Self {
110        value as f32
111    }
112}
113
114impl CoerceFrom<f64> for f64 {
115    fn coerce_from(value: f64) -> Self {
116        value
117    }
118}
119
120impl CoerceFrom<f32> for f32 {
121    fn coerce_from(value: f32) -> Self {
122        value
123    }
124}
125
126impl CoerceFrom<f32> for f64 {
127    fn coerce_from(value: f32) -> Self {
128        value as f64
129    }
130}