#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
pub struct Interval {
pub ratio: f64,
}
impl Default for Interval {
fn default() -> Self {
Self::UNISON
}
}
impl Interval {
pub const UNISON: Self = Self::new(1.0);
pub const MIN3: Self = Self::new(6.0 / 5.0);
pub const MAJ3: Self = Self::new(5.0 / 4.0);
pub const P4: Self = Self::new(4.0 / 3.0);
pub const P5: Self = Self::new(3.0 / 2.0);
pub const MIN6: Self = Self::new(8.0 / 5.0);
pub const MAJ6: Self = Self::new(5.0 / 3.0);
pub const H7: Self = Self::new(7.0 / 4.0);
pub const OCTAVE: Self = Self::new(2.0);
pub const TRITAVE: Self = Self::new(3.0);
pub const SEMITONE: Self = Self::new(1.059_463_094_359_295_3);
pub const TONE: Self = Self::new(1.122_462_048_309_373);
pub const TRITONE: Self = Self::new(std::f64::consts::SQRT_2);
pub const PHI: Self = Self::new(1.618_033_988_749_895);
#[must_use]
pub const fn new(ratio: f64) -> Self {
Self { ratio }
}
#[must_use]
pub fn edo_note(edo: u16, note: f64) -> Self {
Self::new(2f64.powf(note / f64::from(edo)))
}
#[must_use]
pub fn note(note: f64) -> Self {
Self::edo_note(12, note)
}
#[must_use]
pub fn inv(self) -> Self {
Self::new(1.0 / self.ratio)
}
#[must_use]
pub fn sqrt(self) -> Self {
Self::new(self.ratio.sqrt())
}
#[must_use]
pub fn powi(self, n: i32) -> Self {
Self::new(self.ratio.powi(n))
}
#[must_use]
pub fn powf(self, n: f64) -> Self {
Self::new(self.ratio.powf(n))
}
#[must_use]
pub fn octaves(oct: f64) -> Self {
Self::OCTAVE.powf(oct)
}
}
impl std::ops::Mul for Interval {
type Output = Self;
fn mul(self, rhs: Interval) -> Self {
Self::new(self.ratio * rhs.ratio)
}
}
impl std::ops::MulAssign for Interval {
fn mul_assign(&mut self, rhs: Self) {
self.ratio *= rhs.ratio;
}
}
impl std::ops::Div for Interval {
type Output = Self;
fn div(self, rhs: Interval) -> Self {
Self::new(self.ratio / rhs.ratio)
}
}
impl std::ops::DivAssign for Interval {
fn div_assign(&mut self, rhs: Self) {
self.ratio /= rhs.ratio;
}
}