major minor scales

This commit is contained in:
breel
2026-03-11 23:05:37 -06:00
parent faca56e9df
commit 5cde54faeb
2 changed files with 86 additions and 13 deletions

View File

@@ -8,7 +8,7 @@ pub fn new<S: ToString>(s: S) -> Tone {
impl Tone {
fn new(s: String) -> Tone {
let re = regex::Regex::new(r"^((?<letter>^[a-g])(?<sharpness>[+-]?)(?<octave>[1-5]?)|(?<numeric>[0-9]+)|(?<rest>[^a-zA-Z0-9]))$").unwrap();
let re = regex::Regex::new(r"^(((?<letter>^[a-g])(?<sharpness>[+-]?)|(?<major>[A-G]M[0-6])|(?<minor>[A-G]m[0-6]))(?<octave>[1-5]?)|(?<numeric>[0-9]+)|(?<rest>[^a-gA-G0-9]))$").unwrap();
let captures = re
.captures(&s)
.expect(format!("tone '{}' does not match regex", s).as_ref());
@@ -17,14 +17,31 @@ impl Tone {
None => match captures.name("rest") {
Some(_) => 0,
_ => {
let mut result = match captures.name("letter").unwrap().as_str() {
"a" => 57,
"b" => 59,
"c" => 60,
"d" => 62,
"e" => 64,
"f" => 65,
_ => 67,
let mut result = match captures.name("letter") {
Some(letter) => Tone::char_to_middle_i32(letter.as_str()),
None => match captures.name("major") {
Some(major) => Tone::char_to_middle_i32(&major.as_str()[..1]) + match &major.as_str()[2..] {
"0" => 0,
"1" => 2,
"2" => 4,
"3" => 5,
"4" => 7,
"5" => 9,
_ => 11,
},
None => {
let minor = captures.name("minor").unwrap();
Tone::char_to_middle_i32(&minor.as_str()[..1]) + match &minor.as_str()[2..] {
"0" => 0,
"1" => 2,
"2" => 3,
"3" => 5,
"4" => 7,
"5" => 8,
_ => 10,
}
},
},
} as i32;
result += match captures.name("sharpness") {
@@ -50,6 +67,18 @@ impl Tone {
})
}
fn char_to_middle_i32(c: &str) -> i32 {
match c.to_lowercase().as_str() {
"a" => 57,
"b" => 59,
"c" => 60,
"d" => 62,
"e" => 64,
"f" => 65,
_ => 67,
}
}
pub fn i32(&self) -> i32 {
self.0
}
@@ -82,4 +111,48 @@ mod test {
eprintln!("alpha mod octave");
assert_eq!(super::new("c+4").i32(), 60 + 12 + 1);
}
#[test]
fn test_tone_c_major() {
assert_eq!(super::new("CM0"), super::new("c"));
assert_eq!(super::new("CM1"), super::new("d"));
assert_eq!(super::new("CM2"), super::new("e"));
assert_eq!(super::new("CM3"), super::new("f"));
assert_eq!(super::new("CM4"), super::new("g"));
assert_eq!(super::new("CM5"), super::new("a4"));
assert_eq!(super::new("CM6"), super::new("b4"));
}
#[test]
fn test_tone_c_minor() {
assert_eq!(super::new("Cm0"), super::new("c"));
assert_eq!(super::new("Cm1"), super::new("d"));
assert_eq!(super::new("Cm2"), super::new("e-"));
assert_eq!(super::new("Cm3"), super::new("f"));
assert_eq!(super::new("Cm4"), super::new("g"));
assert_eq!(super::new("Cm5"), super::new("a-4"));
assert_eq!(super::new("Cm6"), super::new("b-4"));
}
#[test]
fn test_tone_a_major() {
assert_eq!(super::new("AM0"), super::new("a"));
assert_eq!(super::new("AM1"), super::new("b"));
assert_eq!(super::new("AM2"), super::new("c+"));
assert_eq!(super::new("AM3"), super::new("d"));
assert_eq!(super::new("AM4"), super::new("e"));
assert_eq!(super::new("AM5"), super::new("f+"));
assert_eq!(super::new("AM6"), super::new("g+"));
}
#[test]
fn test_tone_a_minor() {
assert_eq!(super::new("Am0"), super::new("a"));
assert_eq!(super::new("Am1"), super::new("b"));
assert_eq!(super::new("Am2"), super::new("c"));
assert_eq!(super::new("Am3"), super::new("d"));
assert_eq!(super::new("Am4"), super::new("e"));
assert_eq!(super::new("Am5"), super::new("f"));
assert_eq!(super::new("Am6"), super::new("g"));
}
}

View File

@@ -1,9 +1,9 @@
todo:
- can output .wav
- can output .midi
scheduled: []
done:
- change define offset instead of only c==60
- change change offset instead of only c==60 in file
- can choose minor/major/other scale
- can change minor/major/other scale in file
- can output .wav
- can output .midi
scheduled: []
done: []