private void Init() { // Set up all possible alphabets for this group: // Major (if key = C) // C major, D dorian, E phrygian, F lydian, G mixolydian, A aolian, B locrian // Minor: (if key = A minor) // A minor, TODO.... // Really, I just generate the major or minor scale and set the appropriate triad members as goal tonesvia stability. // equivalent to keeping the C major alphabet and changing the goal alphabet, but I'm using one alphabet with stability instead. if (Key.Mode == KeyMode.Major) { for (int i = 1; i <= 7; i++) { possibleGroupAlphabets.Add(Alphabet.GetMajorScaleAlphabetWithTriadOnDegree(Key, i)); } } else { // Add all 3 minor scale types. List <Alphabet> scales = new List <Alphabet>(); scales.Add(Alphabet.GetScaleAlphabet(Key, false, false)); scales.Add(Alphabet.GetScaleAlphabet(Key, true, false)); scales.Add(Alphabet.GetScaleAlphabet(Key, false, true)); foreach (Alphabet s in scales) { foreach (ScaleDegree sd in s) { possibleGroupAlphabets.Add(Alphabet.GetAlphabetFromScaleWithTriadOnDegree(Key, s, sd)); } } } }
public override void Run() { if (group == null) { group = workspace.PickRandomGroupByRecency(); } if (group == null) { return; } if (!workspace.groups.Contains(group)) { return; } // Add to attention history. workspace.RecordCodeletAttentionHistory(this, group.MinLocation); workspace.RecordCodeletAttentionHistory(this, group.MaxLocation); // Check the Larson expectedness vector. // Score is high when expectation was relatively high. double score; Key key = workspace.Key; Alphabet alphabet = group.Alphabet; if (alphabet == null) { alphabet = Alphabet.GetScaleAlphabet(key); } List <float> expectedness = group.GetNoteExpectednessLarson(key, alphabet); int num = expectedness.Count; if (num < 2) { return; } if (expectedness[num - 1] > expectedness[num - 2]) { score = Math.Min(100, 100 * (expectedness[num - 1] / Constants.MAX_LARSON_EXPECTEDNESS)); if (score > 25) { group.AddGroupReason(new GroupReasonEndMusicalForcesClosure(group, score)); } } }
/// <summary> /// Guesses the scale degree for this note given a key. /// </summary> /// <param name="k"></param> /// <returns></returns> public ScaleDegree GetScaleDegree(Key k) { Alphabet a = Alphabet.GetScaleAlphabet(k); foreach (ScaleDegree sd in a) { if (this.midi % 12 == k.GetScaleDegreePitch(sd, 0).MidiNumber % 12) { return(sd); } } return(null); }