protected void AddChordToSong(float time, float volume, int degree, NoteTimbre timbre, ChordType chordType) { var chord = AllChords[chordType][degree]; // CHORDS START WITH VOICE 1 int voice = CHORD_VOICE; for (int i = 0; i < chord.Notes.Length; i++) { float v = volume; if (i == 0) { v = 0; } Composer .AddNoteToSong(Song, time, voice, v, chord.Notes[i], timbre, 0); voice++; } }
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(); }