From 5b9d3a8bb780305a608b187e0d975c18b43f08f7 Mon Sep 17 00:00:00 2001 From: Bel LaPointe <153096461+breel-render@users.noreply.github.com> Date: Fri, 13 Mar 2026 13:01:05 -0600 Subject: [PATCH] tone accepts T,t,f for majorThird, minorThird, perfectFifth lazily --- src/testdata/fifth_wheel.txt | 4 +- src/testdata/major_chord_progressions.txt | 19 ++++++++ src/testdata/major_third.txt | 16 +++---- src/testdata/minor_third.txt | 16 +++---- src/tone.rs | 53 ++++++++++++++++++++++- 5 files changed, 89 insertions(+), 19 deletions(-) create mode 100644 src/testdata/major_chord_progressions.txt diff --git a/src/testdata/fifth_wheel.txt b/src/testdata/fifth_wheel.txt index 78a25e1..ef23a3a 100644 --- a/src/testdata/fifth_wheel.txt +++ b/src/testdata/fifth_wheel.txt @@ -1,5 +1,5 @@ # fifth wheel = +7 semitones # f -> c -> g -> d -> a -> e -> b -f c g d a e b - +f c g d a e b +ff cf gf df af ef bf diff --git a/src/testdata/major_chord_progressions.txt b/src/testdata/major_chord_progressions.txt new file mode 100644 index 0000000..2a7d955 --- /dev/null +++ b/src/testdata/major_chord_progressions.txt @@ -0,0 +1,19 @@ +CM0 CM3 CM4 CM0 +CM0T CM3T CM4T CM0T +CM0f CM3f CM4f CM0f + +. +. +. + +CM1 CM4 CM0 +CM1T CM4T CM0T +CM1f CM4f CM0f + +. +. +. + +CM0 CM4 CM5 CM3 +CM0T CM4T CM5T CM3T +CM0f CM4f CM5f CM3f diff --git a/src/testdata/major_third.txt b/src/testdata/major_third.txt index 8bb8299..48582f7 100644 --- a/src/testdata/major_third.txt +++ b/src/testdata/major_third.txt @@ -2,17 +2,17 @@ # +2 letters (the third letter) with exactly 2 sharps between # c,e c+,f d,f+ -c c+ d -e f f+ +c c+ d +cT c+T dT # d+,g e,g+ f,a -d+ e f -g g+ a +d+ e f +d+T eT fT # f+,a+ g,b g+,c -f+ g g+ -a+ b c +f+ g g+ +f+T gT g+T # a,c+ a+,d b,d+ -a a+ b -c+ d d+ +a a+ b +aT a+T bT diff --git a/src/testdata/minor_third.txt b/src/testdata/minor_third.txt index ce695a8..8a47005 100644 --- a/src/testdata/minor_third.txt +++ b/src/testdata/minor_third.txt @@ -2,17 +2,17 @@ # +2 letters (the third letter) with exactly 1 half step between # c,e- c+,e d,f -c c+ d -e- e f +c c+ d +ct c+t dt # d+,f+ e,g f,g+ -d+ e f -f+ g g+ +d+ e f +d+t et ft # f+,a g,a+ g+,b -f+ g g+ -a a+ b +f+ g g+ +f+t gt g+t # a,c a+,c+ b,d -a a+ b -c c+ d +a a+ b +at a+t bt diff --git a/src/tone.rs b/src/tone.rs index 7e7f8d1..96756a5 100644 --- a/src/tone.rs +++ b/src/tone.rs @@ -8,7 +8,7 @@ pub fn new(s: S) -> Tone { impl Tone { fn new(s: String) -> Tone { - let re = regex::Regex::new(r"^(((?^[a-g])(?[+-]?)|(?[A-G]M[0-6])|(?[A-G]m[0-6]))(?[1-5]?)|(?[0-9]+)|(?[^a-gA-G0-9]))$").unwrap(); + let re = regex::Regex::new(r"^(((?^[a-g])(?[+-]?)|(?[A-G]M[0-6])|(?[A-G]m[0-6]))(?[1-5]?)((?T)|(?t)|(?f))?|(?[0-9]+)|(?[^a-gA-G0-9]))$").unwrap(); let captures = re .captures(&s) .expect(format!("tone '{}' does not match regex", s).as_ref()); @@ -65,6 +65,21 @@ impl Tone { None => 0, } as i32; + result += match captures.name("major_third") { + Some(_) => 4, // TODO not all are good + None => 0, + } as i32; + + result += match captures.name("minor_third") { + Some(_) => 3, // TODO not all are good + None => 0, + } as i32; + + result += match captures.name("fifth") { + Some(_) => 7, + None => 0, + } as i32; + result } }, @@ -144,6 +159,42 @@ mod test { assert_eq!(super::new("c+4").i32(), 60 + 12 + 1); } + #[test] + fn test_tone_new_major_third() { + assert_eq!(super::new("cT").i32(), 60 + 4); + assert_eq!(super::new("c1T").i32(), 60 + 4 - 24); + + assert_eq!(super::new("c+T").i32(), 60 + 1 + 4); + assert_eq!(super::new("c+1T").i32(), 60 + 1 + 4 - 24); + + assert_eq!(super::new("CM0T").i32(), 60 + 4); + assert_eq!(super::new("CM01T").i32(), 60 + 4 - 24); + } + + #[test] + fn test_tone_new_minor_third() { + assert_eq!(super::new("ct").i32(), 60 + 3); + assert_eq!(super::new("c1t").i32(), 60 + 3 - 24); + + assert_eq!(super::new("c+t").i32(), 60 + 1 + 3); + assert_eq!(super::new("c+1t").i32(), 60 + 1 + 3 - 24); + + assert_eq!(super::new("CM0t").i32(), 60 + 3); + assert_eq!(super::new("CM01t").i32(), 60 + 3 - 24); + } + + #[test] + fn test_tone_new_fifth() { + assert_eq!(super::new("cf").i32(), 60 + 7); + assert_eq!(super::new("c1f").i32(), 60 + 7 - 24); + + assert_eq!(super::new("c+f").i32(), 60 + 1 + 7); + assert_eq!(super::new("c+1f").i32(), 60 + 1 + 7 - 24); + + assert_eq!(super::new("CM0f").i32(), 60 + 7); + assert_eq!(super::new("CM01f").i32(), 60 + 7 - 24); + } + #[test] fn test_tone_c_major() { assert_eq!(super::new("CM0"), super::new("c"));