@@ -118,10 +118,29 @@ impl Scale {
118118 ] ,
119119 }
120120 }
121+ pub fn calc_key_index ( & self , key : Key ) -> usize {
122+ let offset = Semitones :: from ( key) - Semitones :: from ( self . get_keys ( ) [ 0 ] ) ;
123+ let offset_val = if offset. 0 >= 0 { offset. 0 % 12 } else { offset. 0 % 12 + 12 } ;
124+ match offset_val {
125+ 0 => 0 ,
126+ 1 => 7 ,
127+ 2 => 2 ,
128+ 3 => 9 ,
129+ 4 => 4 ,
130+ 5 => 11 ,
131+ 6 => 6 ,
132+ 7 => 1 ,
133+ 8 => 8 ,
134+ 9 => 3 ,
135+ 10 => 10 ,
136+ 11 => 5 ,
137+ _ => 0 ,
138+ }
139+ }
121140 //https://www.hooktheory.com/cheat-sheet
122- pub fn get_keys ( & self ) -> Vec < Key > {
141+ pub fn get_keys ( & self ) -> [ Key ; 12 ] {
123142 match self {
124- Scale :: Ionian => vec ! [
143+ Scale :: Ionian => [
125144 Key :: C ,
126145 Key :: G ,
127146 Key :: D ,
@@ -135,7 +154,7 @@ impl Scale {
135154 Key :: B_FLAT ,
136155 Key :: F ,
137156 ] ,
138- Scale :: Dorian => vec ! [
157+ Scale :: Dorian => [
139158 Key :: D ,
140159 Key :: A ,
141160 Key :: E ,
@@ -149,7 +168,7 @@ impl Scale {
149168 Key :: C ,
150169 Key :: G ,
151170 ] ,
152- Scale :: Phrygian => vec ! [
171+ Scale :: Phrygian => [
153172 Key :: E ,
154173 Key :: B ,
155174 Key :: F_SHARP ,
@@ -163,7 +182,7 @@ impl Scale {
163182 Key :: D ,
164183 Key :: A ,
165184 ] ,
166- Scale :: Lydian => vec ! [
185+ Scale :: Lydian => [
167186 Key :: F ,
168187 Key :: C ,
169188 Key :: G ,
@@ -177,7 +196,7 @@ impl Scale {
177196 Key :: E_FLAT ,
178197 Key :: B_FLAT ,
179198 ] ,
180- Scale :: Mixolydian => vec ! [
199+ Scale :: Mixolydian => [
181200 Key :: G ,
182201 Key :: D ,
183202 Key :: A ,
@@ -191,7 +210,7 @@ impl Scale {
191210 Key :: F ,
192211 Key :: C ,
193212 ] ,
194- Scale :: Aeolian => vec ! [
213+ Scale :: Aeolian => [
195214 Key :: A ,
196215 Key :: E ,
197216 Key :: B ,
@@ -205,7 +224,7 @@ impl Scale {
205224 Key :: G ,
206225 Key :: D ,
207226 ] ,
208- Scale :: Locrian => vec ! [
227+ Scale :: Locrian => [
209228 Key :: B ,
210229 Key :: F_SHARP ,
211230 Key :: C_SHARP ,
@@ -261,7 +280,21 @@ impl Scale {
261280 ( Semitones :: from ( * pitch) - self . calc_do_semitones ( key) ) . into ( )
262281 }
263282 pub fn calc_pitch ( & self , key : & Key , syllable : & Syllable ) -> Pitch {
264- ( Semitones :: from ( * syllable) + self . calc_do_semitones ( key) ) . into ( )
283+ let key_index = self . calc_key_index ( key. clone ( ) ) ;
284+ if let Some ( keys) = match syllable {
285+ Syllable :: Do => Some ( Scale :: Ionian . get_keys ( ) ) ,
286+ Syllable :: Re => Some ( Scale :: Dorian . get_keys ( ) ) ,
287+ Syllable :: Mi => Some ( Scale :: Phrygian . get_keys ( ) ) ,
288+ Syllable :: Fa => Some ( Scale :: Lydian . get_keys ( ) ) ,
289+ Syllable :: So => Some ( Scale :: Mixolydian . get_keys ( ) ) ,
290+ Syllable :: La => Some ( Scale :: Aeolian . get_keys ( ) ) ,
291+ Syllable :: Ti => Some ( Scale :: Locrian . get_keys ( ) ) ,
292+ _ => None ,
293+ } {
294+ keys[ key_index] . into ( )
295+ } else {
296+ ( Semitones :: from ( * syllable) + self . calc_do_semitones ( key) ) . into ( )
297+ }
265298 }
266299 pub fn calc_syllable_note ( & self , key : & Key , note : & Note ) -> SyllableNote {
267300 ( Semitones :: from ( * note) - self . calc_do_semitones ( key) ) . into ( )
0 commit comments