Struct tune::temperament::Val
source · pub struct Val { /* private fields */ }
Expand description
A Val
is a step size and a sequence of step numbers that, multiplied component-wise, are to be considered equivalent to the prime number sequence [2, 3, 5, 7, …].
Treating a number of steps to be equivalent to a specific total ratio is the core idea of tempering. That said, a val is an irreducible representation of the arithmetic properties of a temperament’s generator.
Implementations§
source§impl Val
impl Val
sourcepub fn patent(step_size: Ratio, prime_limit: u8) -> Self
pub fn patent(step_size: Ratio, prime_limit: u8) -> Self
Calculates the patent Val
for the given step_size
.
The patent val is the sequence of steps which, multiplied by step_size
, provide the best approximation for the prime number ratios [2, 3, 5, 7, …, prime_limit
].
Examples
let val_of_12_edo = Val::patent(Ratio::octave().divided_into_equal_steps(12), 13);
assert_eq!(val_of_12_edo.values(), &[12, 19, 28, 34, 42, 44]);
let val_of_17_edo = Val::patent(Ratio::octave().divided_into_equal_steps(17), 11);
assert_eq!(val_of_17_edo.values(), &[17, 27, 39, 48, 59]);
let val_of_13_edt = Val::patent(Ratio::from_float(3.0).divided_into_equal_steps(13), 7);
assert_eq!(val_of_13_edt.values(), &[8, 13, 19, 23]);
sourcepub fn pick_alternative(&mut self, index: u8) -> bool
pub fn pick_alternative(&mut self, index: u8) -> bool
Calculates the alternative step size for the given Val
at the given index
.
Examples
let patent_val_of_18_edo = &[18, 29, 42, 51, 62, 67];
let patent_val_of_18b_edo = &[18, 28, 42, 51, 62, 67];
let mut val = Val::patent(Ratio::octave().divided_into_equal_steps(18), 13);
assert_eq!(val.values(), patent_val_of_18_edo);
let index_of_ratio_2 = 0;
let index_of_ratio_3 = 1;
// Octave is pure => Do not pick alternative
let alternative_picked = val.pick_alternative(index_of_ratio_2);
assert_eq!(alternative_picked, false);
assert_eq!(val.values(), patent_val_of_18_edo);
// Tritave is impure => Pick alternative
let alternative_picked = val.pick_alternative(index_of_ratio_3);
assert_eq!(alternative_picked, true);
assert_eq!(val.values(), patent_val_of_18b_edo);
// Tritave is impure => Pick original value again
let alternative_picked = val.pick_alternative(index_of_ratio_3);
assert_eq!(alternative_picked, true);
assert_eq!(val.values(), patent_val_of_18_edo);
sourcepub fn prime_limit(&self) -> u8
pub fn prime_limit(&self) -> u8
sourcepub fn errors(&self) -> impl Iterator<Item = Ratio> + '_
pub fn errors(&self) -> impl Iterator<Item = Ratio> + '_
Returns the current Val
s absolute errors i.e. the deviation from the prime number ratios.
Examples
let val_of_17_edo = Val::patent(Ratio::octave().divided_into_equal_steps(17), 11);
let errors = Vec::from_iter(val_of_17_edo.errors().map(Ratio::as_cents));
assert_eq!(errors.len(), 5);
assert_approx_eq!(errors[0], 0.0);
assert_approx_eq!(errors[1], 3.927352);
assert_approx_eq!(errors[2], -33.372537);
assert_approx_eq!(errors[3], 19.409388);
assert_approx_eq!(errors[4], 13.387940);
sourcepub fn errors_in_steps(&self) -> impl Iterator<Item = f64> + '_
pub fn errors_in_steps(&self) -> impl Iterator<Item = f64> + '_
Returns the current Val
’s errors where the unit of measurement is one step_size
.
Examples
let val_of_17_edo = Val::patent(Ratio::octave().divided_into_equal_steps(17), 11);
let errors_in_steps = Vec::from_iter(val_of_17_edo.errors_in_steps());
assert_eq!(errors_in_steps.len(), 5);
assert_approx_eq!(errors_in_steps[0] * 100.0, 0.0);
assert_approx_eq!(errors_in_steps[1] * 100.0, 5.563749);
assert_approx_eq!(errors_in_steps[2] * 100.0, -47.277761);
assert_approx_eq!(errors_in_steps[3] * 100.0, 27.496633);
assert_approx_eq!(errors_in_steps[4] * 100.0, 18.966248);
sourcepub fn te_simple_badness(&self) -> f64
pub fn te_simple_badness(&self) -> f64
Calculates the Tenney-Euclidean simple badness.
Example
let step_size_12_edo = Ratio::octave().divided_into_equal_steps(12);
assert_approx_eq!(Val::patent(step_size_12_edo, 11).te_simple_badness() * 1000.0, 35.760225);
let step_size_19_edo = Ratio::octave().divided_into_equal_steps(19);
assert_approx_eq!(Val::patent(step_size_19_edo, 11).te_simple_badness() * 1000.0, 28.495822);
sourcepub fn subgroup(&self, threshold: Ratio) -> impl IntoIterator<Item = u8> + '_
pub fn subgroup(&self, threshold: Ratio) -> impl IntoIterator<Item = u8> + '_
sourcepub fn map(&self, comma: &Comma) -> Option<i32>
pub fn map(&self, comma: &Comma) -> Option<i32>
Applies the temperament’s mapping function to the given Comma
.
Specifically, it calculates the scalar product of the values of self
and the values of the comma
if the prime limit of self
is at least the prime of comma
.
Examples
let fifth = Comma::new("fifth", &[-1, 1][..]);
assert_eq!(fifth.as_fraction(), Some((3, 2)));
// The 12-edo fifth is at 7 steps
let val_of_12edo = Val::patent(Ratio::octave().divided_into_equal_steps(12), 5);
assert_eq!(val_of_12edo.map(&fifth), Some(7));
// The 31-edo fifth is at 18 steps
let val_of_31edo = Val::patent(Ratio::octave().divided_into_equal_steps(31), 5);
assert_eq!(val_of_31edo.map(&fifth), Some(18));
// 7-limit intervals cannot be represented by a 5-limit val
let seventh = Comma::new("seventh", &[-2, 0, 0, 1][..]);
assert_eq!(seventh.as_fraction(), Some((7, 4)));
assert_eq!(val_of_12edo.map(&seventh), None);
sourcepub fn tempers_out(&self, comma: &Comma) -> bool
pub fn tempers_out(&self, comma: &Comma) -> bool
Checks whether the current Val
defines a rank-1 temperament which tempers out the given Comma
.
Examples
let diesis = Comma::new("diesis", &[7, 0, -3][..]);
assert_eq!(diesis.as_fraction(), Some((128, 125)));
// 12-edo tempers out the diesis
let val_of_12edo = Val::patent(Ratio::octave().divided_into_equal_steps(12), 5);
assert!(val_of_12edo.tempers_out(&diesis));
// 31-edo does not temper out the diesis
let val_of_31edo = Val::patent(Ratio::octave().divided_into_equal_steps(31), 5);
assert!(!val_of_31edo.tempers_out(&diesis));