protected void ChooseFirstDegree() { ProbabilityChooser <int> firstDegreeChooser = new ProbabilityChooser <int>(); for (int i = 0; i < MusicalScale.AscendingNotes.Length; i++) { firstDegreeChooser .AddItem(i, 1); } AddPreviousChoice(firstDegreeChooser, FirstDegrees, CurrentChunkIndex, 5f); FirstDegrees[CurrentChunkIndex] = firstDegreeChooser .ChooseItem(); }
public Song ComposeSong(string root, int octave, float minNoteLength) { ProbabilityChooser <ScaleType> chooser = new ProbabilityChooser <ScaleType>(); chooser .AddItem(ScaleType.Major, 1f); chooser .AddItem(ScaleType.NaturalMinor, 1f); chooser .AddItem(ScaleType.Dorian, 1f); var mode = chooser .ChooseItem(); return(ComposeSong(root, octave, mode, minNoteLength)); }
protected int ChooseNextDegree(int degree) { ProbabilityChooser <int> nextDegreeChooser = new ProbabilityChooser <int>(); int d = GetScaleDegree(degree, 3); nextDegreeChooser .AddItem(d, 3); d = GetScaleDegree(degree, 1); nextDegreeChooser .AddItem(d, 1); d = GetScaleDegree(degree, -1); nextDegreeChooser .AddItem(d, 1); nextDegreeChooser .AddItem(99, 0.5f); int nextDegree = nextDegreeChooser .ChooseItem(); if (nextDegree == 99) { return(UnityEngine .Random .Range(0, 7)); } else { return(nextDegree); } }
protected void ChooseChunkStyle() { // SELECT HOW MANY MINIMUM NOTE LENGTHS // TO PLAY EACH NOTE FOR ProbabilityChooser <int> chordTicksChooser = new ProbabilityChooser <int>(); chordTicksChooser .AddItem(16, 0.05f); chordTicksChooser .AddItem(8, 0.4f); chordTicksChooser .AddItem(4, 0.1f); AddPreviousChoice(chordTicksChooser, ChordsTicksToHold, CurrentChunkIndex, 0.5f); ChordsTicksToHold[CurrentChunkIndex] = chordTicksChooser .ChooseItem(); // SELECT THE TIMBRE FOR THE CHORD VOICES ProbabilityChooser <NoteTimbre> chordTimbreChooser = new ProbabilityChooser <NoteTimbre>(); //chordTimbreChooser //.AddItem(NoteTimbre.Eh, 0.1f); chordTimbreChooser .AddItem(NoteTimbre.Ee, 0.1f); chordTimbreChooser .AddItem(NoteTimbre.Ah, 0.1f); chordTimbreChooser .AddItem(NoteTimbre.Oh, 0.3f); //chordTimbreChooser //.AddItem(NoteTimbre.Oo, 0.05f); AddPreviousChoice(chordTimbreChooser, ChordTimbres, CurrentChunkIndex, 0.6f); ChordTimbres[CurrentChunkIndex] = chordTimbreChooser .ChooseItem(); // SELECT THE CHORD STYLE ProbabilityChooser <ChordType> chordTypeChooser = new ProbabilityChooser <ChordType>(); chordTypeChooser .AddItem(ChordType.TriadForDegree, 1); chordTypeChooser .AddItem(ChordType.TetradForDegree, 1); AddPreviousChoice(chordTypeChooser, ChordTypes, CurrentChunkIndex, 0.6f); ChordTypes[CurrentChunkIndex] = chordTypeChooser .ChooseItem(); // SELECT THE TIMBRE FOR THE BASS VOICE ProbabilityChooser <NoteTimbre> bassTimbreChooser = new ProbabilityChooser <NoteTimbre>(); //bassTimbreChooser //.AddItem(NoteTimbre.Eh, 0.1f); bassTimbreChooser .AddItem(NoteTimbre.Ee, 0.1f); bassTimbreChooser .AddItem(NoteTimbre.Ah, 0.4f); bassTimbreChooser .AddItem(NoteTimbre.Oh, 0.05f); //bassTimbreChooser //.AddItem(NoteTimbre.Oo, 0.05f); AddPreviousChoice(bassTimbreChooser, BassTimbres, CurrentChunkIndex, 0.5f); BassTimbres[CurrentChunkIndex] = bassTimbreChooser .ChooseItem(); // SELECT THE BASS MELODIC STYLE ProbabilityChooser <BassMelodicStyle> bassMelodicStyleChooser = new ProbabilityChooser <BassMelodicStyle>(); bassMelodicStyleChooser .AddItem(BassMelodicStyle.SingleNote, 1f); bassMelodicStyleChooser .AddItem(BassMelodicStyle.AlternatingNotes, 2f); bassMelodicStyleChooser .AddItem(BassMelodicStyle.WalkingNotes, 1f); AddPreviousChoice(bassMelodicStyleChooser, BassMelodicStyles, CurrentChunkIndex, 4f); BassMelodicStyles[CurrentChunkIndex] = bassMelodicStyleChooser .ChooseItem(); // SELECT THE MELODIC STYLE ProbabilityChooser <MelodicStyle> melodicStyleChooser = new ProbabilityChooser <MelodicStyle>(); melodicStyleChooser .AddItem(MelodicStyle.UpTempo, 1f); melodicStyleChooser .AddItem(MelodicStyle.Ballad, 1f); melodicStyleChooser .AddItem(MelodicStyle.Medium, 1f); AddPreviousChoice(melodicStyleChooser, MelodicStyles, CurrentChunkIndex, 12f); MelodicStyles[CurrentChunkIndex] = melodicStyleChooser .ChooseItem(); // SELECT THE TIMBRE FOR THE MELODY ProbabilityChooser <NoteTimbre> melodyTimbreChooser = new ProbabilityChooser <NoteTimbre>(); //melodyTimbreChooser //.AddItem(NoteTimbre.Eh, 0.1f); melodyTimbreChooser .AddItem(NoteTimbre.Ee, 0.1f); melodyTimbreChooser .AddItem(NoteTimbre.Ah, 0.1f); melodyTimbreChooser .AddItem(NoteTimbre.Oh, 0.3f); //melodyTimbreChooser //.AddItem(NoteTimbre.Oo, 0.05f); AddPreviousChoice(melodyTimbreChooser, MelodyTimbres, CurrentChunkIndex, 1.5f); MelodyTimbres[CurrentChunkIndex] = melodyTimbreChooser .ChooseItem(); }
protected void WriteMelody() { var melodicStyle = MelodicStyles[CurrentChunkIndex]; var melodicTimbre = MelodyTimbres[CurrentChunkIndex]; int consecutiveTicksWithoutRest = 0; float melodyTime = CurrentChunkIndex * TICKS_PER_CHUNK * MinimumNoteLength; MusicalNote currentNote = null; float currentNoteEndTime = 0; MusicalChord currentChord = null; for (int tick = 0; tick < 8 * 4 * 4; tick++) { if (melodyTime < currentNoteEndTime) { melodyTime += MinimumNoteLength; continue; } // SHOULD WE REST? var restChooser = new ProbabilityChooser <bool>(); restChooser .AddItem(true, consecutiveTicksWithoutRest); restChooser .AddItem(false, 32); var shouldRest = restChooser .ChooseItem(); if (shouldRest) { consecutiveTicksWithoutRest = 0; var restLengthChooser = RestLengthChooserPerStyle[melodicStyle]; int ticksToRest = restLengthChooser .ChooseItem(); currentNoteEndTime = melodyTime + ticksToRest * MinimumNoteLength; currentNote = null; melodyTime += MinimumNoteLength; continue; } var chord = GetChordForTime(melodyTime); if (chord != null) { currentChord = chord; } var beatStrength = GetBeatStrength(melodyTime); int noteTicks = 0; bool stayOnOffBeat = StayOnOffBeatChooser[melodicStyle] .ChooseItem(); if (beatStrength == BeatStrength.Off16th && !stayOnOffBeat) { noteTicks = 1; } else if (beatStrength == BeatStrength.Off8th && !stayOnOffBeat) { noteTicks = 2; } else { var noteLengthChooser = NoteLengthChooserPerStyle[melodicStyle]; noteTicks = noteLengthChooser .ChooseItem(); } var melodyNoteInChordChooser = MelodyNoteIsInChordChoosers[beatStrength]; bool noteShouldBeInChord = melodyNoteInChordChooser .ChooseItem(); var melodyNoteInScaleChooser = MelodyNoteIsInScaleChoosers[beatStrength]; bool noteShouldBeInScale = melodyNoteInScaleChooser .ChooseItem(); int melodicInterval = MelodicIntervalChooser .ChooseItem(); int currentDegree = -1; if (currentNote != null) { currentDegree = MusicalScale .GetDegree(currentNote.Name); } int nextDegree = 0; if (noteShouldBeInChord) { if (currentNote != null) { int closestDegree = 0; int minDistance = int.MaxValue; foreach (var note in currentChord.Notes) { int ndg = MusicalScale .GetDegree(note.Name); int d = Mathf .Abs(currentDegree - ndg); if (d < minDistance) { minDistance = d; closestDegree = ndg; } } nextDegree = closestDegree; } else { var noteIndex = UnityEngine .Random .Range(0, currentChord.Notes.Length); var note = currentChord.Notes[noteIndex]; nextDegree = MusicalScale .GetDegree(note.Name); } } else { if (currentNote != null) { nextDegree = GetScaleDegree(currentDegree, melodicInterval); } else { nextDegree = GetScaleDegree(0, melodicInterval); } } int octaveChange = 0; if (melodicInterval > 7) { octaveChange++; } if (melodicInterval < -7) { octaveChange--; } if (currentNote != null) { if (melodicInterval > 0 && nextDegree < currentDegree) { octaveChange++; } if (melodicInterval < 0 && nextDegree > currentDegree) { octaveChange--; } } currentNote = MusicalScale .AscendingNotes[nextDegree]; if (currentNote.Octave - octaveChange <= 0) { octaveChange = 0; } if (currentNote.Octave + octaveChange >= 7) { octaveChange = 0; } Composer .AddNoteToSong(Song, melodyTime, MELODY_VOICE, 1f, currentNote, melodicTimbre, octaveChange); consecutiveTicksWithoutRest++; currentNoteEndTime = melodyTime + noteTicks * MinimumNoteLength; melodyTime += MinimumNoteLength; } }
protected void WriteBaseLine() { var chordTicksToHold = ChordsTicksToHold[CurrentChunkIndex]; var bassTimbre = BassTimbres[CurrentChunkIndex]; var bassmelodicStyle = BassMelodicStyles[CurrentChunkIndex]; var walkingBassLineApproachChooser = new ProbabilityChooser <int>(); walkingBassLineApproachChooser.AddItem(-2, 1); walkingBassLineApproachChooser.AddItem(-1, 1); var walkingBassLineExitChooser = new ProbabilityChooser <int>(); walkingBassLineExitChooser.AddItem(2, 1); walkingBassLineExitChooser.AddItem(1, 1); // GET THE CHORD EVENTS var chordEvents = Song.Voices[1].Events; // WRITE THE BASS LINE int octaveChange; int baseNoteTicksToHold = chordTicksToHold; switch (bassmelodicStyle) { case BassMelodicStyle.SingleNote: foreach (var chordEvent in chordEvents) { octaveChange = -1; if (chordEvent.Note.Octave <= 1) { octaveChange = 0; } // BASS IS VOICE 0 Composer .AddNoteToSong(Song, chordEvent.OccursAt, BASS_VOICE, 0.75f, chordEvent.Note, bassTimbre, octaveChange); } break; case BassMelodicStyle.AlternatingNotes: baseNoteTicksToHold = chordTicksToHold / 2; foreach (var chordEvent in chordEvents) { octaveChange = -1; if (chordEvent.Note.Octave <= 1) { octaveChange = 0; } Composer .AddNoteToSong(Song, chordEvent.OccursAt, BASS_VOICE, 0.75f, chordEvent.Note, bassTimbre, octaveChange); var otherEvent = Song.Voices[3].Events.FirstOrDefault(o => o.OccursAt == chordEvent.OccursAt); float secondNoteOccurs = chordEvent.OccursAt + baseNoteTicksToHold * MinimumNoteLength; Composer .AddNoteToSong(Song, secondNoteOccurs, BASS_VOICE, 0.75f, otherEvent.Note, bassTimbre, octaveChange); } break; case BassMelodicStyle.WalkingNotes: baseNoteTicksToHold = chordTicksToHold / 4; foreach (var chordEvent in chordEvents) { var otherEvent = Song.Voices[3].Events.FirstOrDefault(o => o.OccursAt == chordEvent.OccursAt); octaveChange = -1; if (chordEvent.Note.Octave <= 1) { octaveChange = 0; } float time = chordEvent.OccursAt; Composer .AddNoteToSong(Song, time, BASS_VOICE, 0.75f, chordEvent.Note, bassTimbre, octaveChange); time += baseNoteTicksToHold * MinimumNoteLength; int secondNoteDegree = MusicalScale .GetDegree(otherEvent.Note.Name); int nextDegree = GetScaleDegree(secondNoteDegree, walkingBassLineApproachChooser .ChooseItem()); if (nextDegree > secondNoteDegree) { octaveChange = -1; } var nextNote = MusicalScale.AscendingNotes[nextDegree]; Composer .AddNoteToSong(Song, time, BASS_VOICE, 0.75f, nextNote, bassTimbre, octaveChange); time += baseNoteTicksToHold * MinimumNoteLength; octaveChange = -1; if (otherEvent.Note.Octave <= 1) { octaveChange = 0; } Composer .AddNoteToSong(Song, time, BASS_VOICE, 0.75f, otherEvent.Note, bassTimbre, octaveChange); nextDegree = GetScaleDegree(secondNoteDegree, walkingBassLineExitChooser .ChooseItem()); if (nextDegree < secondNoteDegree) { octaveChange = -1; } nextNote = MusicalScale.AscendingNotes[nextDegree]; time += baseNoteTicksToHold * MinimumNoteLength; Composer .AddNoteToSong(Song, time, BASS_VOICE, 0.75f, nextNote, bassTimbre, octaveChange); } break; } Song .SortEvents(); }