62 lines
1.8 KiB
Rust
62 lines
1.8 KiB
Rust
use std::f64::consts::PI;
|
|
use std::ops::Neg;
|
|
|
|
use crate::map;
|
|
|
|
/// Represents a digital, sampled frequency
|
|
/// as radians per samples in [0; 2*pi[ range
|
|
/// mapped to the whole [0; usize::MAX] range
|
|
#[derive(Clone, Copy, PartialEq, PartialOrd)]
|
|
pub struct DigitalFrequency(pub usize);
|
|
|
|
/// Represents an absolute phase offset
|
|
/// as radians in [0; 2*pi[ range
|
|
/// mapped to the whole [0; usize::MAX] range
|
|
#[derive(Clone, Copy, PartialEq, PartialOrd)]
|
|
pub struct Phase(pub DigitalFrequency);
|
|
|
|
impl DigitalFrequency
|
|
{
|
|
/// Creates a DigitalFrequency from rads per samples
|
|
pub fn from_rad(radians_per_sample: f64) -> Self
|
|
{
|
|
// Frequnecy wraps arround : Going at 2 pi radians per second
|
|
// Is like not oscillating at all
|
|
let f = radians_per_sample.rem_euclid(2. * PI);
|
|
|
|
// Then we map the [0, 2*PI] range into the 0 to usize range
|
|
DigitalFrequency(map(f, 0., 2. * PI, 0., usize::MAX as f64).floor() as usize)
|
|
}
|
|
|
|
/// Creates a DigitalFrequency from a frequency given in hertz (s^(-1))
|
|
/// in the context of a sample rate also given in hertz
|
|
pub fn from_time_frequency(hertz: f64, sample_rate: f64) -> Self
|
|
{
|
|
Self::from_rad(map(hertz, 0., sample_rate, 0., 2. * PI))
|
|
}
|
|
|
|
/// Gets the frequency as radians per sample
|
|
pub fn as_rad(&self) -> f64
|
|
{
|
|
map(self.0 as f64, 0., usize::MAX as f64, 0., 2. * PI)
|
|
}
|
|
|
|
/// Gets the frequency as hertz in the context of a sample rate
|
|
/// also given in hert
|
|
pub fn as_time_frequency(&self, sample_rate: f64) -> f64
|
|
{
|
|
map(self.0 as f64, 0., usize::MAX as f64, 0., sample_rate)
|
|
}
|
|
}
|
|
|
|
impl Neg for DigitalFrequency
|
|
{
|
|
type Output = Self;
|
|
|
|
/// Returns the "negative frequency"
|
|
fn neg(self) -> Self::Output
|
|
{
|
|
DigitalFrequency(usize::MAX - self.0)
|
|
}
|
|
}
|