Struct tune::scala::Scl

source ·
pub struct Scl { /* private fields */ }
Expand description

Scale format according to http://www.huygens-fokker.org/scala/scl_format.html.

The Scl format describes a periodic scale in relative pitches. You can access those pitches using Scl::relative_pitch_of. To retrieve absolute Pitch information, you need to pair the Scl struct with a Kbm or KbmRoot struct (see implementations of the Tuning or KeyboardMapping trait for more info).

Examples

use tune::tuning::Tuning;

let scl = scala::create_harmonics_scale(None, SegmentType::Otonal, 8, 8, None).unwrap();
let kbm = KbmRoot::from(Note::from_midi_number(43).at_pitch(Pitch::from_hz(100.0)));
let tuning = (scl, kbm);

assert_approx_eq!(tuning.pitch_of(PianoKey::from_midi_number(43)).as_hz(), 100.0);
assert_approx_eq!(tuning.pitch_of(PianoKey::from_midi_number(44)).as_hz(), 112.5);
assert_approx_eq!(tuning.pitch_of(PianoKey::from_midi_number(45)).as_hz(), 125.0);

Implementations§

source§

impl Scl

source

pub fn builder() -> SclBuilder

source

pub fn set_description(&mut self, description: impl Into<String>)

source

pub fn description(&self) -> &str

source

pub fn period(&self) -> Ratio

source

pub fn num_items(&self) -> u16

source

pub fn relative_pitch_of(&self, degree: i32) -> Ratio

Retrieves relative pitches without requiring any Kbm reference.

Examples
let scl = Scl::builder()
    .push_cents(100.0)
    .push_cents(50.0)
    .push_cents(175.0)
    .push_cents(150.0)
    .build().unwrap();

assert_approx_eq!(scl.period().as_cents(), 150.0);
assert_approx_eq!(scl.relative_pitch_of(-1).as_cents(), 25.0); // 25.0 = previous period + 175.0
assert_approx_eq!(scl.relative_pitch_of(0).as_cents(), 0.0);
assert_approx_eq!(scl.relative_pitch_of(1).as_cents(), 100.0);
assert_approx_eq!(scl.relative_pitch_of(2).as_cents(), 50.0);
assert_approx_eq!(scl.relative_pitch_of(3).as_cents(), 175.0);
assert_approx_eq!(scl.relative_pitch_of(4).as_cents(), 150.0);
assert_approx_eq!(scl.relative_pitch_of(5).as_cents(), 250.0); // 250.0 = next period + 100.0
source

pub fn sorted_relative_pitch_of(&self, degree: i32) -> Ratio

Retrieves relative pitches in ascending order without requiring any Kbm reference.

Examples
let scl = Scl::builder()
    .push_cents(100.0)
    .push_cents(50.0)
    .push_cents(175.0)
    .push_cents(150.0)
    .build().unwrap();

assert_approx_eq!(scl.period().as_cents(), 150.0);
assert_approx_eq!(scl.sorted_relative_pitch_of(-1).as_cents(), -50.0); // -50.0 = previous period + 100.0
assert_approx_eq!(scl.sorted_relative_pitch_of(0).as_cents(), 0.0);
assert_approx_eq!(scl.sorted_relative_pitch_of(1).as_cents(), 25.0); // 25.0 = previous period + 175.0
assert_approx_eq!(scl.sorted_relative_pitch_of(2).as_cents(), 50.0);
assert_approx_eq!(scl.sorted_relative_pitch_of(3).as_cents(), 100.0);
assert_approx_eq!(scl.sorted_relative_pitch_of(4).as_cents(), 150.0);
assert_approx_eq!(scl.sorted_relative_pitch_of(5).as_cents(), 175.0);
source

pub fn find_by_relative_pitch( &self, relative_pitch: Ratio ) -> Approximation<i32>

Finds the approximate degree of a relative pitch without requiring any Kbm reference.

Examples
let scl = Scl::builder()
    .push_cents(100.0)
    .push_cents(50.0)
    .push_cents(175.0)
    .push_cents(150.0)
    .build().unwrap();

assert_approx_eq!(scl.period().as_cents(), 150.0);
assert_eq!(scl.find_by_relative_pitch(Ratio::from_cents(0.0)).approx_value, 0);
assert_eq!(scl.find_by_relative_pitch(Ratio::from_cents(10.0)).approx_value, 0);
assert_eq!(scl.find_by_relative_pitch(Ratio::from_cents(20.0)).approx_value, -1); // 25.0 = previous period + 175.0
assert_eq!(scl.find_by_relative_pitch(Ratio::from_cents(30.0)).approx_value, -1); // 25.0 = previous period + 175.0
assert_eq!(scl.find_by_relative_pitch(Ratio::from_cents(40.0)).approx_value, 2);
assert_eq!(scl.find_by_relative_pitch(Ratio::from_cents(50.0)).approx_value, 2);
assert_eq!(scl.find_by_relative_pitch(Ratio::from_cents(60.0)).approx_value, 2);
assert_eq!(scl.find_by_relative_pitch(Ratio::from_cents(70.0)).approx_value, 2);
assert_eq!(scl.find_by_relative_pitch(Ratio::from_cents(80.0)).approx_value, 1);
assert_eq!(scl.find_by_relative_pitch(Ratio::from_cents(90.0)).approx_value, 1);
assert_eq!(scl.find_by_relative_pitch(Ratio::from_cents(100.0)).approx_value, 1);
assert_eq!(scl.find_by_relative_pitch(Ratio::from_cents(110.0)).approx_value, 1);
assert_eq!(scl.find_by_relative_pitch(Ratio::from_cents(120.0)).approx_value, 1);
assert_eq!(scl.find_by_relative_pitch(Ratio::from_cents(130.0)).approx_value, 4);
assert_eq!(scl.find_by_relative_pitch(Ratio::from_cents(140.0)).approx_value, 4);
assert_eq!(scl.find_by_relative_pitch(Ratio::from_cents(150.0)).approx_value, 4);
assert_eq!(scl.find_by_relative_pitch(Ratio::from_cents(160.0)).approx_value, 4);
assert_eq!(scl.find_by_relative_pitch(Ratio::from_cents(170.0)).approx_value, 3);
assert_eq!(scl.find_by_relative_pitch(Ratio::from_cents(180.0)).approx_value, 3);
assert_eq!(scl.find_by_relative_pitch(Ratio::from_cents(190.0)).approx_value, 6); // 200.0 = next period + 100.0
assert_eq!(scl.find_by_relative_pitch(Ratio::from_cents(200.0)).approx_value, 6); // 200.0 = next period + 100.0
source

pub fn find_by_relative_pitch_sorted( &self, relative_pitch: Ratio ) -> Approximation<i32>

Finds the approximate degree of a relative pitch in ascending order without requiring any Kbm reference.

Examples
let scl = Scl::builder()
    .push_cents(100.0)
    .push_cents(50.0)
    .push_cents(175.0)
    .push_cents(150.0)
    .build().unwrap();

assert_approx_eq!(scl.period().as_cents(), 150.0);
assert_eq!(scl.find_by_relative_pitch_sorted(Ratio::from_cents(0.0)).approx_value, 0);
assert_eq!(scl.find_by_relative_pitch_sorted(Ratio::from_cents(10.0)).approx_value, 0);
assert_eq!(scl.find_by_relative_pitch_sorted(Ratio::from_cents(20.0)).approx_value, 1); // 25.0 = previous period + 175.0
assert_eq!(scl.find_by_relative_pitch_sorted(Ratio::from_cents(30.0)).approx_value, 1); // 25.0 = previous period + 175.0
assert_eq!(scl.find_by_relative_pitch_sorted(Ratio::from_cents(40.0)).approx_value, 2);
assert_eq!(scl.find_by_relative_pitch_sorted(Ratio::from_cents(50.0)).approx_value, 2);
assert_eq!(scl.find_by_relative_pitch_sorted(Ratio::from_cents(60.0)).approx_value, 2);
assert_eq!(scl.find_by_relative_pitch_sorted(Ratio::from_cents(70.0)).approx_value, 2);
assert_eq!(scl.find_by_relative_pitch_sorted(Ratio::from_cents(80.0)).approx_value, 3);
assert_eq!(scl.find_by_relative_pitch_sorted(Ratio::from_cents(90.0)).approx_value, 3);
assert_eq!(scl.find_by_relative_pitch_sorted(Ratio::from_cents(100.0)).approx_value, 3);
assert_eq!(scl.find_by_relative_pitch_sorted(Ratio::from_cents(110.0)).approx_value, 3);
assert_eq!(scl.find_by_relative_pitch_sorted(Ratio::from_cents(120.0)).approx_value, 3);
assert_eq!(scl.find_by_relative_pitch_sorted(Ratio::from_cents(130.0)).approx_value, 4);
assert_eq!(scl.find_by_relative_pitch_sorted(Ratio::from_cents(140.0)).approx_value, 4);
assert_eq!(scl.find_by_relative_pitch_sorted(Ratio::from_cents(150.0)).approx_value, 4);
assert_eq!(scl.find_by_relative_pitch_sorted(Ratio::from_cents(160.0)).approx_value, 4);
assert_eq!(scl.find_by_relative_pitch_sorted(Ratio::from_cents(170.0)).approx_value, 5);
assert_eq!(scl.find_by_relative_pitch_sorted(Ratio::from_cents(180.0)).approx_value, 5);
assert_eq!(scl.find_by_relative_pitch_sorted(Ratio::from_cents(190.0)).approx_value, 6);
assert_eq!(scl.find_by_relative_pitch_sorted(Ratio::from_cents(200.0)).approx_value, 6); // 200.0 = next period + 50.0
source

pub fn import(reader: impl Read) -> Result<Self, SclImportError>

Imports the given file in SCL format.

let scl_file = [
    "!A comment",
    "  !An indented comment",
    "  Example scale  ",
    "7",
    "100.",
    "150.0 ignore text after first whitespace",
    "  ", // ignore blank line
    "!175.0 ignore whole line",
    "200.0 .ignore additional dots",
    "  6/5  ",
    "5/4 (ignore parentheses)",
    "3/2 /ignore additional slashes",
    "2",
];

let scl = Scl::import(scl_file.join("\n").as_bytes()).unwrap();

assert_eq!(scl.description(), "Example scale");
assert_eq!(scl.num_items(), 7);
assert_approx_eq!(scl.relative_pitch_of(0).as_cents(), 0.0);
assert_approx_eq!(scl.relative_pitch_of(1).as_cents(), 100.0);
assert_approx_eq!(scl.relative_pitch_of(2).as_cents(), 150.0);
assert_approx_eq!(scl.relative_pitch_of(3).as_cents(), 200.0);
assert_approx_eq!(scl.relative_pitch_of(4).as_float(), 6.0 / 5.0);
assert_approx_eq!(scl.relative_pitch_of(5).as_float(), 5.0 / 4.0);
assert_approx_eq!(scl.relative_pitch_of(6).as_float(), 3.0 / 2.0);
assert_approx_eq!(scl.relative_pitch_of(7).as_float(), 2.0);
assert_approx_eq!(scl.period().as_float(), 2.0);
source

pub fn export(&self) -> SclExport<'_>

Exports the current scale in SCL file format.

Examples
let scl = Scl::builder()
    .push_cents(100.0)
    .push_ratio("1:13:3".parse().unwrap())
    .push_fraction(4, 3)
    .push_int(2)
    .build_with_description("Example scale")
    .unwrap();

assert_eq!(
    format!("{}", scl.export()).lines().collect::<Vec<_>>(),
    ["Example scale", "4", "100.000", "146.304", "4/3", "2"]
);

Trait Implementations§

source§

impl Clone for Scl

source§

fn clone(&self) -> Scl

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Scl

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl RefUnwindSafe for Scl

§

impl Send for Scl

§

impl Sync for Scl

§

impl Unpin for Scl

§

impl UnwindSafe for Scl

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.