pub struct Ratio { /* private fields */ }
Expand description
Struct representing the relative distance between two Pitch
es.
Mathematically, this distance can be interpreted as the factor between the two pitches in linear frequency space or as the offset between them in logarithmic frequency space.
The Ratio
struct offers both linear and logarithmic accessors to the encapsulated distance.
It is possible to convert between the different representations by using from_<repr1>
and as_<repr2>
in
combination where <reprN>
can be a linear (float
) or logarithmic (cents
, semitones
, octaves
) quantity.
Examples
assert_approx_eq!(Ratio::from_float(1.5).as_cents(), 701.955);
assert_approx_eq!(Ratio::from_cents(400.0).as_semitones(), 4.0);
assert_approx_eq!(Ratio::from_semitones(3.0).as_octaves(), 0.25);
assert_approx_eq!(Ratio::from_octaves(3.0).as_float(), 8.0);
Invalid Values
Ratio
can contain non-finite values if the linear value is not a finite positive number.
assert!(Ratio::from_cents(0.0).as_cents().is_finite());
assert!(Ratio::from_cents(-3.0).as_cents().is_finite());
assert!(Ratio::from_float(0.0).as_cents() == f64::NEG_INFINITY);
assert!(Ratio::from_float(-3.0).as_cents().is_nan());
Implementations§
source§impl Ratio
impl Ratio
pub fn from_float(float_value: impl Into<f64>) -> Self
pub fn from_cents(cents_value: f64) -> Self
pub fn from_semitones(semitones: impl Into<f64>) -> Self
pub fn from_octaves(octaves: impl Into<f64>) -> Self
pub fn octave() -> Self
sourcepub fn between_pitches(pitch_a: impl Pitched, pitch_b: impl Pitched) -> Self
pub fn between_pitches(pitch_a: impl Pitched, pitch_b: impl Pitched) -> Self
sourcepub fn stretched_by(self, stretch: Ratio) -> Ratio
pub fn stretched_by(self, stretch: Ratio) -> Ratio
Stretches self
by the provided stretch
.
This reverses Ratio::deviation_from
.
Examples
assert_approx_eq!(Ratio::octave().stretched_by(Ratio::from_cents(10.0)).as_cents(), 1210.0);
sourcepub fn deviation_from(self, reference: Ratio) -> Ratio
pub fn deviation_from(self, reference: Ratio) -> Ratio
Calculates the difference between the provided reference
and self
.
This reverses Ratio::stretched_by
.
Examples
assert_approx_eq!(Ratio::from_cents(1210.0).deviation_from(Ratio::octave()).as_cents(), 10.0);
sourcepub fn repeated(self, num_repetitions: impl Into<f64>) -> Ratio
pub fn repeated(self, num_repetitions: impl Into<f64>) -> Ratio
Creates a new Ratio
instance by applying self
num_repetitions
times.
This reverses Ratio::divided_into_equal_steps
or Ratio::num_equal_steps_of_size
.
Examples
assert_approx_eq!(Ratio::from_semitones(2.0).repeated(3).as_semitones(), 6.0);
sourcepub fn divided_into_equal_steps(self, num_steps: impl Into<f64>) -> Ratio
pub fn divided_into_equal_steps(self, num_steps: impl Into<f64>) -> Ratio
Returns the Ratio
resulting from dividing self
into num_steps
equal steps.
This reverses Ratio::repeated
.
Examples
assert_approx_eq!(Ratio::octave().divided_into_equal_steps(15).as_cents(), 80.0);
sourcepub fn num_equal_steps_of_size(self, step_size: Ratio) -> f64
pub fn num_equal_steps_of_size(self, step_size: Ratio) -> f64
Determines how many equal steps of size step_size
fit into self
.
This reverses Ratio::repeated
.
Examples
assert_approx_eq!(Ratio::octave().num_equal_steps_of_size(Ratio::from_cents(80.0)), 15.0);
pub fn as_float(self) -> f64
pub fn as_cents(self) -> f64
pub fn as_semitones(self) -> f64
pub fn as_octaves(self) -> f64
sourcepub fn inv(self) -> Ratio
pub fn inv(self) -> Ratio
assert_approx_eq!(Ratio::from_float(4.0).inv().as_float(), 0.25);
assert_approx_eq!(Ratio::from_cents(150.0).inv().as_cents(), -150.0);
sourcepub fn abs(self) -> Ratio
pub fn abs(self) -> Ratio
assert_eq!(Ratio::from_float(f64::INFINITY).abs().as_float(), f64::INFINITY);
assert_approx_eq!(Ratio::from_float(2.0).abs().as_float(), 2.0);
assert_approx_eq!(Ratio::from_float(1.0).abs().as_float(), 1.0);
assert_approx_eq!(Ratio::from_float(0.5).abs().as_float(), 2.0);
assert_eq!(Ratio::from_float(0.0).abs().as_float(), f64::INFINITY);
// Pathological cases, documented for completeness
assert_eq!(Ratio::from_float(-0.0).abs().as_float(), f64::NEG_INFINITY);
assert_approx_eq!(Ratio::from_float(-0.5).abs().as_float(), -2.0);
assert_approx_eq!(Ratio::from_float(-1.0).abs().as_float(), -1.0);
assert_approx_eq!(Ratio::from_float(-2.0).abs().as_float(), -2.0);
assert_eq!(Ratio::from_float(f64::NEG_INFINITY).abs().as_float(), f64::NEG_INFINITY);
assert!(Ratio::from_float(f64::NAN).abs().as_float().is_nan());
sourcepub fn is_negligible(self) -> bool
pub fn is_negligible(self) -> bool
Check whether the given Ratio
is negligible.
The threshold is around a 500th of a cent.
Examples
assert!(!Ratio::from_cents(0.002).is_negligible());
assert!(Ratio::from_cents(0.001).is_negligible());
assert!(Ratio::from_cents(0.000).is_negligible());
assert!(Ratio::from_cents(-0.001).is_negligible());
assert!(!Ratio::from_cents(-0.002).is_negligible());
sourcepub fn total_cmp(&self, other: &Self) -> Ordering
pub fn total_cmp(&self, other: &Self) -> Ordering
impl
stolen from https://doc.rust-lang.org/std/primitive.f64.html#method.total_cmp.
sourcepub fn nearest_fraction(self, odd_limit: u16) -> NearestFraction
pub fn nearest_fraction(self, odd_limit: u16) -> NearestFraction
Finds a rational number approximation of the current Ratio
instance.
The largest acceptable numerator or denominator can be controlled using the odd_limit
parameter.
Only odd factors are compared against the odd_limit
which means that 12 is 3, effectively, while 11 stays 11.
Read the documentation of math::odd_factors_u16
for more examples.
Examples
A minor seventh can be approximated by 16/9.
let minor_seventh = Ratio::from_semitones(10);
let odd_limit = 9;
let f = minor_seventh.nearest_fraction(odd_limit);
assert_eq!((f.numer, f.denom), (16, 9));
assert_eq!(f.num_octaves, 0);
assert_approx_eq!(f.deviation.as_cents(), 3.910002); // Quite good!
Reducing the odd_limit
saves computation time but may lead to a bad approximation.
let odd_limit = 5;
let f = minor_seventh.nearest_fraction(odd_limit);
assert_eq!((f.numer, f.denom), (5, 3));
assert_eq!(f.num_octaves, 0);
assert_approx_eq!(f.deviation.as_cents(), 115.641287); // Pretty bad!
The approximation is normalized to values within an octave. The number of octaves is reported separately.
let lower_than_an_octave = Ratio::from_float(3.0 / 4.0);
let odd_limit = 11;
let f = lower_than_an_octave.nearest_fraction(odd_limit);
assert_eq!((f.numer, f.denom), (3, 2));
assert_eq!(f.num_octaves, -1);
assert_approx_eq!(f.deviation.as_cents(), 0.0);
Trait Implementations§
source§impl Default for Ratio
impl Default for Ratio
source§impl Display for Ratio
impl Display for Ratio
Ratio
s can be formatted as float or cents.
Examples
// As float
assert_eq!(format!("{}", Ratio::from_float(1.5)), "1.5000");
assert_eq!(format!("{}", Ratio::from_float(1.0 / 1.5)), "0.6667");
assert_eq!(format!("{:.2}", Ratio::from_float(1.0 / 1.5)), "0.67");
// As cents
assert_eq!(format!("{:#}", Ratio::from_float(1.5)), "+702.0c");
assert_eq!(format!("{:#}", Ratio::from_float(1.0 / 1.5)), "-702.0c");
assert_eq!(format!("{:#.2}", Ratio::from_float(1.0 / 1.5)), "-701.96c");
// With padding
assert_eq!(format!("{:=^#14.2}", Ratio::from_float(1.5)), "===+701.96c===");
source§impl Div<Ratio> for Pitch
impl Div<Ratio> for Pitch
source§impl FromStr for Ratio
impl FromStr for Ratio
Ratio
s can be parsed using tune
’s built-in expression language.
Examples
assert_approx_eq!("1.5".parse::<Ratio>().unwrap().as_float(), 1.5);
assert_approx_eq!("3/2".parse::<Ratio>().unwrap().as_float(), 1.5);
assert_approx_eq!("7:12:2".parse::<Ratio>().unwrap().as_semitones(), 7.0);
assert_approx_eq!("702c".parse::<Ratio>().unwrap().as_cents(), 702.0);
assert_eq!("foo".parse::<Ratio>().unwrap_err(), "Invalid expression \'foo\': Must be a float (e.g. 1.5), fraction (e.g. 3/2), interval fraction (e.g. 7:12:2) or cents value (e.g. 702c)");
source§impl Mul<Ratio> for Pitch
impl Mul<Ratio> for Pitch
source§impl PartialEq for Ratio
impl PartialEq for Ratio
source§impl PartialOrd for Ratio
impl PartialOrd for Ratio
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
self
and other
) and is used by the <=
operator. Read more