def test__ChordProgression_root_in_bass(self): root_in_bass = chords.parse('C') root_not_in_bass = chords.parse('C/G') root_not_in_bass.root_in_bass() self.assertTrue(root_in_bass.root_in_bass()) self.assertFalse(root_not_in_bass.root_in_bass())
def test_ArpeggialTransform_is_applicable(self): fileloader.load(constants.TEST_MIDI + 'arpeggial.mid', False) sequence = sequences.soprano config.chord_progression[0] = chords.parse('C') config.chord_progression[5 * config.resolution] = chords.parse('A-') ks_detector.detect_and_set_key_signatures() self.assertTrue(transforms.ArpeggialTransform.applicable_at(0, sequence)) self.assertTrue( transforms.ArpeggialTransform.applicable_at(4 * config.resolution, sequence))
def test_ApproachTransform_intermediate_pitch(self): fileloader.load(constants.TEST_MIDI + 'approach.mid', False) sequence = sequences.soprano config.chord_progression[0] = chords.parse('A') config.chord_progression[config.resolution] = chords.parse('D') ks_detector.detect_and_set_key_signatures() trans = transforms.ApproachTransform(0, sequence) c_sharp_below = sequence[0].midi() - 8 self.assertEqual(trans.intermediate_pitch, c_sharp_below)
def test_ArpeggialTransform_set_musicality(self): fileloader.load(constants.TEST_MIDI + 'arpeggial.mid', False) sequence = sequences.soprano config.chord_progression[0] = chords.parse('C') config.chord_progression[5 * config.resolution] = chords.parse('A-') ks_detector.detect_and_set_key_signatures() weaker_trans = transforms.ArpeggialTransform(0, sequence) stronger_trans = transforms.ArpeggialTransform(config.resolution * 4, sequence) self.assertEqual(weaker_trans.intrinsic_musicality, vars.ARPEGGIAL_SAME_CHORD) self.assertEqual(stronger_trans.intrinsic_musicality, vars.ARPEGGIAL_NEW_CHORD)
def test_ApproachTransform_is_applicable(self): fileloader.load(constants.TEST_MIDI + 'approach.mid', False) sequence = sequences.soprano config.chord_progression[0] = chords.parse('A') config.chord_progression[config.resolution] = chords.parse('D') config.chord_progression[config.resolution * 4] = chords.parse('E') config.chord_progression[config.resolution * 5] = chords.parse('F') config.chord_progression[config.resolution * 6] = chords.parse('A') ks_detector.detect_and_set_key_signatures() self.assertTrue(transforms.ApproachTransform.applicable_at(0, sequence)) self.assertTrue( transforms.ApproachTransform.applicable_at(4 * config.resolution, sequence)) self.assertFalse( transforms.ApproachTransform.applicable_at(6 * config.resolution, sequence))
def test_MinorChord_indicates_subdominant(self): chord = chords.parse('C-') self.assertTrue( chord.indicates_subdominant(MIDI_VALUES['D0'], MIDI_VALUES['F0'])) self.assertFalse( chord.indicates_subdominant(MIDI_VALUES['D0'], MIDI_VALUES['B0'], MIDI_VALUES['F0']))
def test_MajorChord_indicates_dominant(self): chord = chords.parse('C') self.assertTrue( chord.indicates_dominant(MIDI_VALUES['D0'], MIDI_VALUES['G0'])) self.assertFalse( chord.indicates_dominant(MIDI_VALUES['D0'], MIDI_VALUES['G0'], MIDI_VALUES['C0']))
def test_ApproachTransform_set_musicality(self): fileloader.load(constants.TEST_MIDI + 'approach.mid', False) sequence = sequences.soprano config.chord_progression[0] = chords.parse('A') config.chord_progression[config.resolution] = chords.parse('D') config.chord_progression[config.resolution * 5] = chords.parse('F') config.chord_progression[config.resolution * 6] = chords.parse('A') ks_detector.detect_and_set_key_signatures() ks = config.key_signatures weaker_trans = transforms.ApproachTransform(11 * config.resolution, sequence) stronger_trans = transforms.ApproachTransform(0, sequence) strong_trans = transforms.ApproachTransform(4 * config.resolution, sequence) self.assertEqual(vars.APPROACH_DEFAULT_MUSICALITY, weaker_trans.intrinsic_musicality) self.assertEqual(vars.APPROACH_NEW_CHORD_ROOT, stronger_trans.intrinsic_musicality) self.assertEqual(vars.APPROACH_KEY_CHANGE, strong_trans.intrinsic_musicality)
def test_MinorThirdScalarTransform_is_applicable(self): fileloader.load(constants.TEST_MIDI + 'min3_scalar.mid', False) sequence = sequences.soprano config.chord_progression[0] = chords.parse('C-') ks_detector.detect_and_set_key_signatures() self.assertTrue(transforms.MinorThirdScalarTransform.applicable_at(0, sequence)) self.assertFalse(transforms.MinorThirdScalarTransform.applicable_at(2, sequence))
def test__pitch_set_for_directions(self): bounded_pitches = [i for i in range(60, 73) if i in chords.parse('C').scale()] start = pitches.MIDI_VALUES['G5'] target = pitches.MIDI_VALUES['E5'] one_direction = [1] two_directions = [-1, 1] self.assertEqual(3, len(transforms.pitch_sets_for_directions(bounded_pitches, start, target, one_direction))) self.assertEqual(22, len(transforms.pitch_sets_for_directions(bounded_pitches, start, target, two_directions)))
def test_MajorThird_set_musicality(self): fileloader.load(constants.TEST_MIDI + 'linear_motion.mid', False) sequence = sequences.soprano config.chord_progression[0] = chords.parse('C') ks_detector.detect_and_set_key_signatures() trans = transforms.MajorThirdScalarTransform(6 * config.resolution, sequence) self.assertEqual(trans.intrinsic_musicality, vars.MAJOR_THIRD_SCALAR_CONTINUES_LINEARITY)
def test_WholeStepNeighborTransform_is_applicable(self): fileloader.load(constants.TEST_MIDI + 'neighbor.mid', False) sequence = sequences.soprano config.chord_progression[0] = chords.parse('C') ks_detector.detect_and_set_key_signatures() self.assertTrue(transforms.WholeStepNeighborTransform.applicable_at(0, sequence)) self.assertTrue( transforms.WholeStepNeighborTransform.applicable_at(2 * config.resolution, sequence))
def test_WholeStepNeighborTransform_intermediate_pitch(self): fileloader.load(constants.TEST_MIDI + 'neighbor.mid', False) sequence = sequences.soprano config.chord_progression[0] = chords.parse('C') ks_detector.detect_and_set_key_signatures() trans = transforms.WholeStepNeighborTransform(0, sequence) whole_step_above = sequence[0].midi() + 2 self.assertEqual(trans.intermediate_pitch, whole_step_above)
def test_ArpeggialTransform_intermediate_pitch(self): fileloader.load(constants.TEST_MIDI + 'arpeggial.mid', False) sequence = sequences.soprano config.chord_progression[0] = chords.parse('C') ks_detector.detect_and_set_key_signatures() trans = transforms.ArpeggialTransform(0, sequence) major_third_above = sequence[0].midi() + 4 self.assertEqual(trans.intermediate_pitch, major_third_above)
def test_MajorThirdScalarTransform_intermediate_pitch(self): fileloader.load(constants.TEST_MIDI + 'maj3_scalar.mid', False) sequence = sequences.soprano config.chord_progression[0] = chords.parse('C') ks_detector.detect_and_set_key_signatures() trans = transforms.MajorThirdScalarTransform(0, sequence) pitch_should_be = sequence[0].midi() + 2 self.assertEqual(trans.intermediate_pitch, pitch_should_be)
def test__JoinTransform_crosses_bar_line(self): fileloader.load(constants.TEST_MIDI + '2beat_join.mid', False) sequence = sequences.soprano config.chord_progression[0] = chords.parse('C') ks_detector.detect_and_set_key_signatures() over_bar_line = transforms.JoinTransform(2, config.resolution * 3, sequence) inside_bar = transforms.JoinTransform(2, config.resolution * 2, sequence) self.assertTrue(over_bar_line.crosses_bar_line()) self.assertFalse(inside_bar.crosses_bar_line())
def test__is_syncopation(self): fileloader.load(constants.TEST_MIDI + '2beat_join.mid', False) sequence = sequences.soprano config.chord_progression[0] = chords.parse('C') ks_detector.detect_and_set_key_signatures() syncopation = transforms.JoinTransform(2, config.resolution, sequence) nonsyncopated = transforms.JoinTransform(2, 0, sequence) self.assertTrue(syncopation.is_syncopation()) self.assertFalse(nonsyncopated.is_syncopation())
def test_MajorThirdScalarTransform_Neighbor_synergy(self): fileloader.load(constants.TEST_MIDI + 'neighbor.mid', False) sequence = sequences.soprano scalar_sequence = sequences.RootSequence(read_pattern(constants.TEST_MIDI + 'maj3_scalar.mid')[0]) config.chord_progression[0] = chords.parse('C') ks_detector.detect_and_set_key_signatures() scalar_trans = transforms.MajorThirdScalarTransform(0, scalar_sequence) dom_neighbor_trans = transforms.HalfStepNeighborTransform(0, sequence) subdom_neighbor_trans = transforms.HalfStepNeighborTransform(config.resolution * 4, sequence) self.assertEqual(scalar_trans.synergy(dom_neighbor_trans), vars.EIGHTH_NOTE_DOMINANT) self.assertEqual(scalar_trans.synergy(subdom_neighbor_trans), vars.EIGHTH_NOTE_SUBDOMINANT)
def __manual_enter_chords(sequence): chord_progression = chords.ChordProgression() enter = 'y' while enter == 'y': enter = raw_input('Would you like to enter a chord? y/n ') if enter == 'y': chord = chords.parse(raw_input('Enter chord: ')) measure = int(raw_input('Enter measure number: ')) beat = int(raw_input('Enter beat number: ')) chord_progression[sequence.measure(measure - 1).start() + (beat - 1) * config.resolution] = chord return chord_progression
def test_MajorThirdScalarTransform_Scalar_synergy(self): fileloader.load(constants.TEST_MIDI + 'maj3_scalar.mid', False) sequence = sequences.soprano config.chord_progression[0] = chords.parse('C') ks_detector.detect_and_set_key_signatures() scalar_trans = transforms.MajorThirdScalarTransform(0, sequence) same_trans = transforms.MajorThirdScalarTransform(0, sequence) join = transforms.JoinTransform(2, 0, sequence) join3 = transforms.JoinTransform(3, 0, sequence) self.assertEqual(scalar_trans.synergy(same_trans), vars.EIGHTH_NOTE_SAME) self.assertEqual(scalar_trans.synergy(join), 0.0) self.assertEqual(join.synergy(join), vars.JOIN_SAME) self.assertEqual(join.synergy(join3), 0.0)
def test__functional_relevance(self): major = ks.MajorKeySignature('C') minor = ks.MinorKeySignature('C') c_major = chords.parse('C') d_minor = chords.parse('D-') f_major = chords.parse('F') g_major = chords.parse('G') g_seven = chords.parse('G7') ab_major = chords.parse('Ab') a_minor = chords.parse('A-') b_dimin = chords.parse('Bdim') DOM_FIVE = vars.DOMINANT_FIVE_IN_FUNCTIONAL_RELEVANCE # shortening ;) FIVE = vars.MAJOR_FIVE_IN_FUNCTIONAL_RELEVANCE # shortening ;) self.assertEqual(DOM_FIVE + vars.FIVE_ONE_FUNCTIONALITY, major.functional_relevance(g_seven, c_major)) self.assertEqual(FIVE + vars.FIVE_ONE_FUNCTIONALITY, major.functional_relevance(g_major, c_major)) self.assertEqual(vars.SEVEN_ONE_FUNCTIONALITY, major.functional_relevance(b_dimin, c_major)) self.assertEqual(DOM_FIVE + vars.TWO_FIVE_FUNCTIONALITY, major.functional_relevance(d_minor, g_seven)) self.assertEqual(FIVE + vars.TWO_FIVE_FUNCTIONALITY, major.functional_relevance(d_minor, g_major)) self.assertEqual(DOM_FIVE + vars.FOUR_FIVE_FUNCTIONALITY, major.functional_relevance(f_major, g_seven)) self.assertEqual(FIVE + vars.FOUR_FIVE_FUNCTIONALITY, major.functional_relevance(f_major, g_major)) self.assertEqual(FIVE + vars.FIVE_SIX_FUNCTIONALITY, major.functional_relevance(g_major, a_minor)) self.assertEqual(DOM_FIVE + vars.FIVE_SIX_FUNCTIONALITY, major.functional_relevance(g_seven, a_minor)) self.assertEqual(FIVE + vars.FIVE_SIX_FUNCTIONALITY, minor.functional_relevance(g_major, ab_major)) self.assertEqual(DOM_FIVE + vars.FIVE_SIX_FUNCTIONALITY, minor.functional_relevance(g_seven, ab_major))
def test__EighthNoteTransform_causes_flickering(self): fileloader.load(constants.TEST_MIDI + 'flicker.mid', False) sequence = sequences.soprano c = config config.chord_progression[0] = chords.parse('C') ks_detector.detect_and_set_key_signatures() transform1 = transforms.WholeStepNeighborTransform((1 * config.resolution * 4) + (1 * config.resolution), sequence) transform2 = transforms.HalfStepNeighborTransform((2 * config.resolution * 4) + (1 * config.resolution), sequence) transform3 = transforms.HalfStepNeighborTransform((2 * config.resolution * 4) + (1 * config.resolution), sequence) self.assertTrue(transform1.causes_flickering()) self.assertTrue(transform2.causes_flickering()) self.assertTrue(transform3.causes_flickering())
def test__harmonic_relevance(self): major = ks.MajorKeySignature('C') minor = ks.MinorKeySignature('C') c_major = chords.parse('C') c_minor = chords.parse('C-') d_minor = chords.parse('D-') d_dimin = chords.parse('Ddim') e_minor = chords.parse('E-') eb_major = chords.parse('Eb') f_major = chords.parse('F') f_minor = chords.parse('F-') g_major = chords.parse('G') g_seven = chords.parse('G7') ab_major = chords.parse('Ab') a_minor = chords.parse('A-') b_dimin = chords.parse('Bdim') self.assertEqual(vars.ONE_CHORD_HARMONY, major.harmonic_relevance(c_major)) self.assertEqual(vars.TWO_CHORD_HARMONY, major.harmonic_relevance(d_minor)) self.assertEqual(vars.THREE_CHORD_HARMONY, major.harmonic_relevance(e_minor)) self.assertEqual(vars.FOUR_CHORD_HARMONY, major.harmonic_relevance(f_major)) self.assertEqual(vars.FIVE_DOMINANT_HARMONY, major.harmonic_relevance(g_seven)) self.assertEqual(vars.FIVE_MAJOR_HARMONY, major.harmonic_relevance(g_major)) self.assertEqual(vars.SIX_CHORD_HARMONY, major.harmonic_relevance(a_minor)) self.assertEqual(vars.MAJOR_SEVEN_DIMINISHED_HARMONY, major.harmonic_relevance(b_dimin)) self.assertEqual(vars.ONE_CHORD_HARMONY, minor.harmonic_relevance(c_minor)) self.assertEqual(vars.TWO_CHORD_HARMONY, minor.harmonic_relevance(d_dimin)) self.assertEqual(vars.THREE_CHORD_HARMONY, minor.harmonic_relevance(eb_major)) self.assertEqual(vars.FOUR_CHORD_HARMONY, minor.harmonic_relevance(f_minor)) self.assertEqual(vars.FIVE_MAJOR_HARMONY, minor.harmonic_relevance(g_major)) self.assertEqual(vars.FIVE_DOMINANT_HARMONY, minor.harmonic_relevance(g_seven)) self.assertEqual(vars.SIX_CHORD_HARMONY, minor.harmonic_relevance(ab_major)) self.assertEqual(vars.MAJOR_SEVEN_DIMINISHED_HARMONY, minor.harmonic_relevance(b_dimin)) self.assertEqual(0, minor.harmonic_relevance(c_major)) self.assertEqual(0, minor.harmonic_relevance(d_minor)) self.assertEqual(0, minor.harmonic_relevance(e_minor)) self.assertEqual(0, minor.harmonic_relevance(f_major)) self.assertEqual(0, minor.harmonic_relevance(a_minor))