public static ArrayList<PitchCandidate> melodicCheck( ArrayList<PitchCandidate> pitch_candidates, ModeModule my_mode_module, MelodicVoice alter_me, Integer pitch_center, int voice_pitch_count, Integer previous_cp_pitch, Integer previous_melodic_interval, Boolean is_accent) { // Melodic Checks // Evaluate each pitch candidate for (PitchCandidate myPC : pitch_candidates) { int cand_pitch = myPC.getPitch(); int melody_motion_to_cand = 0; System.out.println("melodicCheck evaluating pitch candidate " + cand_pitch); // Check if Dissonant with Root boolean root_interval_consonant = false; int root_interval = abs(cand_pitch - root_key) % 12; for (Integer consonance : root_consonances) { if (root_interval == consonance) root_interval_consonant = true; } if (root_interval_consonant) { System.out.println(cand_pitch + " root interval consonant"); } else { if (is_accent) { myPC.decrementRank(Decrements.dissonant_with_root); System.out.println(cand_pitch + " dissonant accent with root"); } else System.out.println("dissonant with root but note accent = " + is_accent); } // randomly decrement non-tonics if (cand_pitch % 12 != my_mode_module.getTonic() && roll.nextInt(2) == 1) { myPC.decrementRank(Decrements.is_not_tonic); System.out.println(cand_pitch + " is not tonic"); } // decrement illegal notes if (cand_pitch < 0 || cand_pitch > 127) { myPC.decrementRank(Decrements.illegal_note); System.out.println(cand_pitch + " is illegal note"); } // decrement motion outside of voice range if (cand_pitch < alter_me.getRangeMin() || cand_pitch > alter_me.getRangeMax()) { myPC.decrementRank(Decrements.outside_range); System.out.println( cand_pitch + " outside range " + alter_me.getRangeMin() + "-" + alter_me.getRangeMax()); } // decrement too far from pitch center if (abs(cand_pitch - pitch_center) > 16) { myPC.decrementRank(Decrements.remote_from_pitchcenter); System.out.println(cand_pitch + " too far from pitch center" + pitch_center); } if (voice_pitch_count > 0) { melody_motion_to_cand = cand_pitch - previous_cp_pitch; // The candidate has already followed the preceding note too often. (method created) // look for previous_cp_pitch in PitchCount // if it's there get_count // if the count is greater than samplesize // check if previous_cp_pitch and pitch_candidate in MOtion Counts // if so get count - then divide motion count by pitch count // get the percentage from mode module // if actual count is greater than mode module percentage decrement for (PitchCount my_pitch_count : pitch_counts) { if (my_pitch_count.getPitch() == previous_cp_pitch % 12) if (my_pitch_count.getCount() > sample_size) for (MotionCount my_motion_count : motion_counts) { // logger.log(Level.INFO, "Entering Motion Counts"); // System.out.println("pitch_count for " + previous_cp_pitch %12 + " = " + // my_pitch_count.getCount()); // System.out.println("motion count " + my_motion_count.getCount()); if (my_motion_count.getPreviousPitch() == previous_cp_pitch % 12 && my_motion_count.getSucceedingPitch() == cand_pitch % 12) { double actual = (double) my_motion_count.getCount() / (double) my_pitch_count.getCount(); System.out.println("actual = " + actual); double thresh = 0.20; if (my_mode_module.getMelodicMotionProbability( cand_pitch, previous_cp_pitch, key_transpose) != null) { thresh = my_mode_module.getMelodicMotionProbability( cand_pitch, previous_cp_pitch, key_transpose); System.out.println( "motion probability of " + previous_cp_pitch + " to " + cand_pitch + " = " + thresh); } else System.out.println( "motion probability of " + previous_cp_pitch + " to " + cand_pitch + " is NULL"); if (actual >= thresh) { myPC.decrementRank(Decrements.melodic_motion_quota_exceed); System.out.println( cand_pitch + " is approached too often from " + previous_cp_pitch); } } } } } if (voice_pitch_count > 1) { // Peak/Trough check // a melodic phrase should have no more than two peaks and two troughs // a peak is defined as a change in melodic direction // so when a candidate pitch wants to go in the opposite direction of // the previous melodic interval we want to increment the peak or trough count accordingly // and determine whether we have more than two peaks or more than two troughs // note that the melody can always go higher or lower than the previous peak or trough if (previous_melodic_interval < 0 && melody_motion_to_cand > 0) { // will there be a change in direction from - to + ie trough? if (previous_cp_pitch == trough) trough_count++; // will this trough = previous trough? then increment } if (previous_melodic_interval > 0 && melody_motion_to_cand < 0) { // will there be a trough? if (previous_cp_pitch == peak) peak_count++; // will this trough = previous trough? then increment } if (peak_count > 1 || trough_count > 1) { peak_count--; // remember to decrement these counts since we won't actually use this pitch trough_count--; myPC.decrementRank(Decrements.peak_trough_quota_exceed); System.out.println(cand_pitch + " duplicates previous peak or trough"); } // Motion after Leaps checks // First check if the melody does not go in opposite direction of leap // then check if there are two successive leaps in the same direction if (previous_melodic_interval > 4 && melody_motion_to_cand > 0) { myPC.decrementRank(Decrements.bad_motion_after_leap); System.out.println( melody_motion_to_cand + " to " + cand_pitch + " is bad motion after leap"); if (melody_motion_to_cand > 4) { myPC.decrementRank(Decrements.successive_leaps); System.out.println(cand_pitch + " is successive leap"); } } if (previous_melodic_interval < -4 && melody_motion_to_cand < 0) { myPC.decrementRank(Decrements.bad_motion_after_leap); System.out.println( melody_motion_to_cand + " to " + cand_pitch + " is bad motion after leap"); if (melody_motion_to_cand < -4) { myPC.decrementRank(Decrements.successive_leaps); System.out.println(cand_pitch + " is successive leap"); } } } // end melody checks } // next pitch candidate return pitch_candidates; }