List<ToneType> firstToneTypes = new ArrayList<>();
boolean interMeasureChord = false;
double measureChordLength = 0;
boolean canHaveInterMeasureChords = ctx.getMetre()[0] > 3 && ctx.getMetre()[0] % 4 == 0;
Chord chord = null;
for (int i = 0; i < notes.length; i++) {
// shuffle every time, so that we don't always get the same chord for a given note
Collections.shuffle(scaleChords, random);
Collections.shuffle(scaleSeventhChords, random);
Collections.shuffle(scaleOtherChords, random);
Note currentNote = notes[i];
if (currentNote.getRhythmValue() == 0) {
continue; // rhythm value is 0 for the first notes of a (main-part) chord. So progress to the next
}
// inter-measure chords only for even-numbered, compound metres
if (canHaveInterMeasureChords && currentMeasureSize == 0) {
interMeasureChord = Chance.test(18);
}
double chordLength = interMeasureChord ? normalizedMeasureSize / 2 : normalizedMeasureSize;
boolean isHalfMeasure = currentMeasureSize == normalizedMeasureSize / 2;
if (currentNote.getPitch() == 0) {
logger.warn("Pitch is 0 in main part.");
continue;
}
if (!currentNote.isRest() && (currentMeasureSize == 0 || (interMeasureChord && isHalfMeasure))) {
boolean preferStable = ToneResolver.needsContrastingChord(firstToneTypes, ToneGroups.UNSTABLE);
boolean preferUnstable = ToneResolver.needsContrastingChord(firstToneTypes, ToneGroups.STABLE);
Chord previous = chord;
chord = ChordUtils.getChord(ctx, currentNote.getPitch(), previous, scaleChords, scaleSeventhChords, scaleOtherChords, preferStable, preferUnstable);
if (chord != null && Chance.test(90)) {
if (Chance.test(20)) { // change the special note type
if (Chance.test(60)) { // to a new value
specialNoteType = SpecialNoteType.values()[random.nextInt(SpecialNoteType.values().length)];