/// <summary> /// Replaces a random concrete note pitch with a hold note. /// </summary> /// <param name="melody"> The candidate melody which contains the bar sequence to operate on. </param> /// <param name="barIndex"> An index of specific requested bar to operate on. </param> private protected virtual void ToggleToHoldNoteMutation(MelodyCandidate melody, int?barIndex) { // intialize random generator Random random = new Random(); // fetch the requested bar randomly select one if no specific bar is requested barIndex = barIndex ?? random.Next(melody.Bars.Count); IBar selectedBar = melody.Bars[(int)barIndex]; // fetch potential notes for the toggle (filter rest, hold & first notes in bar) IList <INote> relevantNotes = selectedBar.Notes.Where((note, noteIndex) => noteIndex > 0 && note.Pitch != NotePitch.RestNote && note.Pitch != NotePitch.HoldNote).ToList(); // assure at least one note as found if (!relevantNotes.Any()) { return; } // fetch a random note from the potential notes found int randomNoteIndex = random.Next(relevantNotes.Count); INote selectedNote = relevantNotes[randomNoteIndex]; // get original index of the selected note in the original sequence int originalNoteIndex = selectedBar.Notes.IndexOf(selectedNote); // replace selected note with a hold note INote holdNote = MusicTheoryFactory.CreateNote(NotePitch.HoldNote, selectedNote.Duration); selectedBar.Notes.RemoveAt(originalNoteIndex); selectedBar.Notes.Insert(originalNoteIndex, holdNote); }
/// <summary> /// Randomly selects two consecutive notes in the given bar, or in a randomly selected /// bar if <paramref name="barIndex"/> is null, and unifies the two consecutive notes /// into one note by removing the consecutive note entirely and adding it's /// duration length to the first note. /// </summary> /// <param name="melody"> The candidate melody to operate on.</param> /// <param name="barIndex"> Index of the bar to do the unification in. If no bar index supplied, then a random bar would be selected. </param> private protected virtual void DurationUnifyMutation(MelodyCandidate melody, int?barIndex = null) { // initialization INote note1, note2, newNote; IDuration newDuration; int note1Index, note2Index; Random random = new Random(); // if no specific bar has been requested then set it randomly int selectedBarIndex = barIndex ?? random.Next(melody.Bars.Count); IBar bar = melody.Bars[selectedBarIndex]; // assure selected bar contains at least two notes if (bar.Notes.Count < 2) { return; } // randomly select two consecutive notes from within the selected bar note1Index = random.Next(1, bar.Notes.Count); note2Index = note1Index - 1; note1 = bar.Notes[note1Index]; note2 = bar.Notes[note2Index]; /* create a new note with the pitch of the first note and overall duration * duration of the sum of the two notes durations */ newDuration = note1.Duration.Add(note2.Duration); newNote = MusicTheoryFactory.CreateNote(note1.Pitch, newDuration); // replace the two consecutive note with the new note bar.Notes.RemoveAt(note1Index); bar.Notes.Insert(note1Index, newNote); bar.Notes.RemoveAt(note2Index); }