mod freq;
mod midi;
mod q_factor;
mod sample_rate;
mod time;
mod vol;
use std::ops::{Div, Mul};
pub use freq::{Freq, Interval, RawFreq};
pub use midi::MidiNote;
pub use q_factor::QFactor;
pub use sample_rate::SampleRate;
pub use time::{FracInt, RawTime, Time};
pub use vol::Vol;
const A4_MIDI: f64 = midi::MidiNote::A4.note as f64;
#[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd)]
pub struct Val(f64);
impl Val {
pub const ZERO: Self = Val(0.0);
pub const HALF: Self = Val(0.5);
pub const ONE: Self = Val(1.0);
#[must_use]
pub fn new(value: f64) -> Self {
debug_assert!((0.0..=1.0).contains(&value));
Self(value)
}
#[must_use]
pub const fn inner(&self) -> f64 {
self.0
}
#[must_use]
pub fn fract(value: f64) -> Self {
debug_assert!(value.is_sign_positive());
Self(value.fract())
}
pub fn advance_freq(&mut self, freq: Freq) {
*self = Self::fract(self.inner() + freq.samples);
}
}
impl From<Val> for f64 {
fn from(value: Val) -> Self {
value.inner()
}
}
impl std::fmt::Display for Val {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl rand::prelude::Distribution<Val> for rand::distributions::Standard {
fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> Val {
Val(rng.gen())
}
}
impl Mul<RawFreq> for RawTime {
type Output = f64;
fn mul(self, rhs: RawFreq) -> f64 {
self.seconds * rhs.hz
}
}
impl Mul<RawTime> for RawFreq {
type Output = f64;
fn mul(self, rhs: RawTime) -> f64 {
rhs * self
}
}
impl Mul<Freq> for Time {
type Output = f64;
fn mul(self, rhs: Freq) -> f64 {
self.samples.into_f64() * rhs.samples
}
}
impl Mul<Time> for Freq {
type Output = f64;
fn mul(self, rhs: Time) -> f64 {
rhs * self
}
}
impl RawTime {
#[must_use]
pub fn raw_freq(self) -> RawFreq {
RawFreq::new(1.0 / self.seconds)
}
}
impl RawFreq {
#[must_use]
pub fn raw_time(self) -> RawTime {
RawTime::new(1.0 / self.hz)
}
}
impl Time {
#[must_use]
pub fn freq(self) -> Freq {
Freq::new(1.0 / self.samples.into_f64())
}
}
impl Freq {
#[must_use]
pub fn time(self) -> Time {
Time::new(FracInt::from_f64(1.0 / self.samples))
}
}
impl Mul<RawTime> for SampleRate {
type Output = Time;
fn mul(self, rhs: RawTime) -> Time {
Time::new(FracInt::from_f64(f64::from(self.0) * rhs.seconds))
}
}
impl Mul<SampleRate> for RawTime {
type Output = Time;
fn mul(self, rhs: SampleRate) -> Time {
rhs * self
}
}
impl Div<SampleRate> for Time {
type Output = RawTime;
fn div(self, rhs: SampleRate) -> RawTime {
RawTime::new((self.samples / rhs.0).into_f64())
}
}
impl Mul<Freq> for SampleRate {
type Output = RawFreq;
fn mul(self, rhs: Freq) -> RawFreq {
RawFreq::new(f64::from(self.0) * rhs.samples)
}
}
impl Mul<SampleRate> for Freq {
type Output = RawFreq;
fn mul(self, rhs: SampleRate) -> RawFreq {
rhs * self
}
}
impl Div<SampleRate> for RawFreq {
type Output = Freq;
fn div(self, rhs: SampleRate) -> Freq {
Freq::new(self.hz / f64::from(rhs))
}
}