/// <summary> /// Generates a Melody using the notes in this bar (lead) and a melody pattern /// </summary> private List <IMusicalValue> GetMelodyBar(List <IMusicalValue> bar, List <int?> pattern) { IMusicalValue barChord = bar[(int)Beat.One]; Note rootBarNote = CurrentMood.TonicNote; if (barChord is Chord) { rootBarNote = Theory.GetNote(((Chord)barChord).Notes[0]); } else if (barChord is Note) { rootBarNote = (Note)barChord; if (rootBarNote.Value == Tone.Rest) { rootBarNote = CurrentMood.TonicNote; } } else { Debug.Log("Cannot determine the root note or chord for this bar. Shouldnt happen."); } List <IMusicalValue> newMelodyBar = new List <IMusicalValue>(); for (int n = 0; n < pattern.Count; n++) { if (pattern[n] != null) { newMelodyBar.Add(Theory.GetNextNoteByInterval(rootBarNote, (int)pattern[n])); } else { newMelodyBar.Add(Theory.Rest); } } return(newMelodyBar); }
public void Generate() { GetMood(); CurrentLead.Clear(); CurrentMelody.Clear(); var progressionGraph = GetProgressionTypeForKey(CurrentMood.Key); //choose lead progression Numeral tonicNumeral = Numeral.I; if (!progressionGraph.ContainsKey(tonicNumeral)) { tonicNumeral = Numeral.i; //this is a minor key } ; List <Numeral> chosenProgression = new List <Numeral>() { tonicNumeral }; var node = progressionGraph[tonicNumeral]; int chordrange = UnityEngine.Random.Range(3, 6); for (int i = 0; i < chordrange; i++) { var nextChord = node.Next(); chosenProgression.Add((nextChord)); if (!progressionGraph.ContainsKey(nextChord)) { Debug.Log("Couldn't get " + nextChord + " in progressionGraph"); } node = progressionGraph[nextChord]; } List <IMusicalValue> generated = new List <IMusicalValue>(); BeatPattern = ChooseBeatPattern(); CurrentMelodyPatterns = GenerateMelodyPatterns(4); int currentChord = 0; //generate a phrase of 16 bars for (int i = 0; i < BarSize; i++) { var bar = GetBar(); foreach (var beat in BeatPattern) { //determine if we change chords on this beat if (ChangeOnBeat()) { //Debug.Log("Changing Chord.."); currentChord++; if (currentChord >= chosenProgression.Count) { currentChord = 0; } } Chord chord = Theory.GetChordOfKey(CurrentMood.Key, chosenProgression[currentChord]); //determine if we appregiate or not if (Appregiate()) { var x = (int)beat; //appregio pattern // 1 2 3 var pattern = UnityEngine.Random.value; if (pattern <= 0.8) { foreach (var note in chord.Notes) { bar[x] = Theory.GetNote(note); x++; } } else { // 1 3 2 bar[x] = Theory.GetNote(chord.Notes[0]); bar[x + 1] = Theory.GetNote(chord.Notes[2]); bar[x + 2] = Theory.GetNote(chord.Notes[1]); } } else { bar[(int)beat] = chord; } } generated.AddRange(bar); //pick a reuseable melody pattern for here var melodyPattern = Utils.ChooseList(CurrentMelodyPatterns); var melodyBar = GetMelodyBar(bar, melodyPattern); CurrentMelody.AddRange(melodyBar); } CurrentLead = generated; FirstPass = false; }