Skip to main content

music21_rs/scale/
mod.rs

1use std::{cmp::Ordering, collections::HashMap};
2
3use crate::{defaults::IntegerType, stepname::StepName};
4
5pub(crate) mod concretescale;
6/// Diatonic scale construction and harmonization helpers.
7pub mod diatonicscale;
8pub mod hexatonicblues;
9/// The named scales music21 exposes, realized from a tonic.
10pub mod scaletype;
11pub mod stepscale;
12
13pub use diatonicscale::DiatonicScale;
14pub use hexatonicblues::{BluesForm, WeightedHexatonicBlues};
15pub use scaletype::{Scale, ScaleType};
16pub use stepscale::StepScale;
17
18pub(crate) const FIFTHS_ORDER_SHARP: [StepName; 7] = [
19    StepName::F,
20    StepName::C,
21    StepName::G,
22    StepName::D,
23    StepName::A,
24    StepName::E,
25    StepName::B,
26];
27pub(crate) const FIFTHS_ORDER_FLAT: [StepName; 7] = [
28    StepName::B,
29    StepName::E,
30    StepName::A,
31    StepName::D,
32    StepName::G,
33    StepName::C,
34    StepName::F,
35];
36
37pub(crate) fn altered_steps_from_sharps(sharps: IntegerType) -> HashMap<StepName, IntegerType> {
38    let mut map = HashMap::new();
39    match sharps.cmp(&0) {
40        Ordering::Greater => {
41            for step in FIFTHS_ORDER_SHARP.iter().take(sharps as usize) {
42                *map.entry(*step).or_insert(0) += 1;
43            }
44        }
45        Ordering::Less => {
46            for step in FIFTHS_ORDER_FLAT.iter().take((-sharps) as usize) {
47                *map.entry(*step).or_insert(0) -= 1;
48            }
49        }
50        Ordering::Equal => {}
51    }
52    map
53}
54
55pub(crate) fn accidental_modifier_from_alter(alter: IntegerType) -> String {
56    match alter.cmp(&0) {
57        Ordering::Greater => "#".repeat(alter as usize),
58        Ordering::Less => "-".repeat((-alter) as usize),
59        Ordering::Equal => String::new(),
60    }
61}