def test_motif_book_example(self): s = Beam() s.append(Note(DiatonicPitch.parse('C:4'), Duration(1, 8))) s.append(Note(DiatonicPitch.parse('D:4'), Duration(1, 8))) s.append(Note(DiatonicPitch.parse('C:4'), Duration(1, 8))) s.append(Note(DiatonicPitch.parse('F#:4'), Duration(1, 8))) notes = s.get_all_notes() c = [ EqualPitchConstraint([notes[0], notes[2]]), NotEqualPitchConstraint([notes[1], notes[3]]) ] m = Motif(s, c, 'A') cs = Beam() cs.append(Note(DiatonicPitch.parse('C:5'), Duration(1, 8))) cs.append(Note(DiatonicPitch.parse('D:5'), Duration(1, 8))) cs.append(Note(DiatonicPitch.parse('C:5'), Duration(1, 8))) cs.append(Note(DiatonicPitch.parse('F#:5'), Duration(1, 8))) c_motif = m.copy_to(cs.get_all_notes()[0]) assert 'A' == c_motif.name assert len(c_motif.actors) == len(notes) assert len(c_motif.constraints) == len(c) assert isinstance(c_motif.constraints[0], EqualPitchConstraint) assert c_motif.constraints[0].actors[0] == c_motif.actors[0] assert c_motif.constraints[0].actors[1] == c_motif.actors[2] assert isinstance(c_motif.constraints[1], NotEqualPitchConstraint) assert c_motif.constraints[1].actors[0] == c_motif.actors[1] assert c_motif.constraints[1].actors[1] == c_motif.actors[3]
def simple_reshape_no_pf(): print('----- test_simple_reshape_no_pf -----') line_str = '{<C-Major: I> iE:4 E E E E E E E <:IV> qE ie e <:V> qe ie e <:VI> qE E iE E E E}' score = create_score(line_str, 'violin', (3, 4, 'sww')) all_notes = score.line.get_all_notes() pitch_function = GenericUnivariatePitchFunction(sinasoidal, Position(0), Position(3)) time_range = Range(0, 3) # The first note should have one of 3 values, C:4, E:4, G:4 constraints = { ChordalPitchConstraint(all_notes[0]), ChordalPitchConstraint(all_notes[9]), PitchRangeConstraint([all_notes[0]], PitchRange.create('C:4', 'G:4')), } motif = Motif(score.line, constraints, 'A') melodic_form = MelodicForm([motif]) treshape = TReshape(score, pitch_function, time_range, melodic_form, False) results = treshape.apply() mc_filter = MinCurveFitFilter(pitch_function, results) print('{0} filtered results'.format(len(mc_filter.scored_results))) for index in range(0, min(5, len(mc_filter.scored_results))): result = mc_filter.scored_results[index] print('[{0}] {1} ({2})'.format(index, str_line(result[0].line), result[1]))
def test_simple_reshape(self): print('----- test_hct_simple_shift -----') s_notes = [ ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'h'), ('E:4', 'h'), ('E:4', 'q'), ('E:4', 'q'), ('E:4', 'q'), ('E:4', 'q'), ] chords = [('tI', 1), ('tIV', (1, 2)), ('tV', (1, 2)), ('tVI', 1)] score = TestTReshape.create_score(s_notes, ModalityType.Major, 'C', chords, 'violin', (3, 4, 'sww')) all_notes = score.line.get_all_notes() pitch_function = GenericUnivariatePitchFunction(TestTReshape.sinasoidal, Position(0), Position(3)) time_range = Range(0, 3) # The first note should have one of 3 values, C:4, E:4, G:4 constraints = { ChordalPitchConstraint(all_notes[0]), PitchRangeConstraint([all_notes[0]], PitchRange.create('C:4', 'G:4')), } motif = Motif(score.line, constraints, 'A') melodic_form = MelodicForm([motif]) treshape = TReshape(score, pitch_function, time_range, melodic_form, False) results = treshape.apply() assert results is not None assert len(results) == 3 for result in results: print('-----') print(result.line) first_pitch_set = {str(result.line.get_all_notes()[0].diatonic_pitch) for result in results} assert {'E:4', 'C:4', 'G:4'} == first_pitch_set assert abs(TestTReshape.sinasoidal(Fraction(1, 8)) - DiatonicPitch.parse('D:5').chromatic_distance) < 1
def motif_example(): print('----- motif_example (Fgure 17.25) -----') line_str = '{<C-Major: I> iC:4 D E D E E E E C D E D E E E E C D E D E E E E wE}' score = create_score(line_str, 'piano', (4, 4, 'swww')) tonality = score.hct.get_hc_by_position(0).tonality all_notes = score.line.get_all_notes() constraints = { StepSequenceConstraint( [all_notes[0], all_notes[1], all_notes[2], all_notes[3]], [1, 1, -1]) } motif = Motif([all_notes[0], all_notes[1], all_notes[2], all_notes[3]], constraints) motif1 = motif.copy_to(all_notes[8]) motif2 = motif.copy_to(all_notes[16]) form = MelodicForm([motif, motif1, motif2]) # 11 scalar notes to C:4 (0) to G:5 (11) with pitch unit 1/11 interpreter = ScalarRangeInterpreter(tonality, DiatonicPitch.parse('C:4'), 0, Fraction(1, 11)) pitch_function = GenericUnivariatePitchFunction(three_sin, Position(0), Position(3), False, interpreter) t_reshape = TReshape(score, pitch_function, Range(0, 3), form, True) results = t_reshape.apply() filters = MinCurveFitFilter(pitch_function, results) print('{0} filtered results'.format(len(filters.scored_results))) for index in range(0, min(5, len(filters.scored_results))): result = filters.scored_results[index] print('[{0}] {1} ({2})'.format(index, str_line(result[0].line), result[1]))
def test_book_example(self): line_str = '{<C-Major: I> iC:4 D C F F A G A iC:5 D C F f A G A}' lge = LineGrammarExecutor() target_line, _ = lge.parse(line_str) notes = target_line.get_all_notes() ca = [ EqualPitchConstraint([notes[0], notes[2]]), NotEqualPitchConstraint([notes[1], notes[3]]) ] cb = [ NotEqualPitchConstraint([notes[4], notes[5]]), EqualPitchConstraint([notes[5], notes[7]]) ] a = Motif([notes[0], notes[1], notes[2], notes[3]], ca, 'A') b = Motif([notes[4], notes[5], notes[6], notes[7]], cb, 'B') phrase_constraints = [ EqualPitchConstraint([notes[3], notes[4]]), ] phrase = Phrase([notes[2], notes[3], notes[4], notes[5]], phrase_constraints, 'P1') mf_constraints = [ NotEqualPitchConstraint([notes[2], notes[5]]), ] mf = MelodicForm([a, b], [phrase], mf_constraints, 'MF1') print('[{0}]'.format(','.join( [str(n.diatonic_pitch) for n in mf.actors]))) mf_dup = mf.copy_to(notes[8]) print('[{0}]'.format(','.join( [str(n.diatonic_pitch) for n in mf_dup.actors])))
def simple_reshape_cpf(): print('----- test_simple_reshape_cpf (Fgure 17.21) -----') line_str = '{<C-Major: I> iE:4 E E E E E E E <:IV> qE ie e <:V> qe ie e <:VI> qE E iE E E E}' score = create_score(line_str, 'violin', (3, 4, 'sww')) all_notes = score.line.get_all_notes() # 11 scalar notes to C:4 (0) to G:5 (1) with pitch unit 1/19 interpreter = ChromaticRangeInterpreter(DiatonicPitch.parse('C:4'), 0, Fraction(1, 19)) pitch_function = GenericUnivariatePitchFunction(three_sin, Position(0), Position(3), interp=interpreter) # The first note should have one of 3 values, C:4, E:4, G:4 constraints = { ChordalPitchConstraint(all_notes[0]), ChordalPitchConstraint(all_notes[8]), ChordalPitchConstraint(all_notes[11]), ChordalPitchConstraint(all_notes[14]), PitchRangeConstraint([all_notes[0]], PitchRange.create('C:4', 'E:4')), } # motif = Motif(score.line, constraints, 'A') motif = Motif([all_notes[0], all_notes[8], all_notes[11], all_notes[14]], constraints, 'A') melodic_form = MelodicForm([motif]) t_reshape = TReshape(score, pitch_function, Range(0, 3), melodic_form, True) results = t_reshape.apply() filters = MinCurveFitFilter(pitch_function, results) print('{0} filtered results'.format(len(filters.scored_results))) for index in range(0, min(5, len(filters.scored_results))): result = filters.scored_results[index] print('[{0}] {1} ({2})'.format(index, str_line(result[0].line), result[1])) print('Chords: {0}'.format(','.join([str(c) for c in score.hct.hc_list()])))
def reshape_to_scale(): print('----- test_reshape_to_scale (Fgure 17.24) -----') line_str = '{<C-Major: I> iE:4 E E E E E E E E E E E E E E E E E E E E E E E wE}' score = create_score(line_str, 'violin', (4, 4, 'swww')) tonality = score.hct.get_hc_by_position(0).tonality all_notes = score.line.get_all_notes() plf = PiecewiseLinearFunction([(0, 0), (1, 8), (Fraction(3, 2), 4), (2, 8), (3, 0)]) for i in range(0, 17): x = Fraction(1, 8) * i y = plf(x) print('({0}, {1})'.format(x, y)) time_range = Range(0, 3) interpreter = ScalarRangeInterpreter(tonality, DiatonicPitch.parse('C:4'), 0, 1) pitch_function = GenericUnivariatePitchFunction(plf, Position(0), Position(3), False, interpreter) constraints = { ChordalPitchConstraint(all_notes[0]), PitchRangeConstraint([all_notes[0]], PitchRange.create('C:4', 'G:4')), } motif = Motif([all_notes[0]], constraints, 'A') melodic_form = MelodicForm([motif]) t_reshape = TReshape(score, pitch_function, time_range, melodic_form, False) results = t_reshape.apply() filters = MinCurveFitFilter(pitch_function, results) print('{0} filtered results'.format(len(filters.scored_results))) for index in range(0, min(5, len(filters.scored_results))): result = filters.scored_results[index] print('[{0}] {1} ({2})'.format(index, str_line(result[0].line), result[1]))
def test_piecewise_linear_reshape(self): """ This is a very interesting test case. Although it uses a piecewise linear based reshape function, more importantly, the line's harmonic context track is in the key Bb-major, but the pitch function interprets pitches in E-major! The rule is to always use what the pitch function returns over the hct, except when the computed pitch has an enharmonic equivalent - in this case, the only case is Eb == D#, and Eb is preferred. :return: """ print('----- test_piecewise_linear_reshape -----') s_notes = [ ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ] chords = [('tI', 1), ('tIV', (1, 2)), ('tV', (1, 2)), ('tVI', 1)] score = TestTReshape.create_score(s_notes, ModalityType.Major, 'Bb', chords, 'violin', (4, 4, 'swww')) e_interp = ScalarRangeInterpreter(Tonality.create(ModalityType.Major, DiatonicToneCache.get_tone('E')), 'E:4', 0) array = [(0, 0), (Fraction(1, 2), 4), (Fraction(1), 0), (Fraction(2), 8)] f = PiecewiseLinearFunction(array) pitch_function = GenericUnivariatePitchFunction(f, Position(0), Position(2), False, e_interp) all_notes = score.line.get_all_notes() # The first note should have one of 2 values, Eb:4, G:4 constraints = { ChordalPitchConstraint(all_notes[0]), } motif = Motif(score.line, constraints, 'A') melodic_form = MelodicForm([motif]) time_range = Range(0, 3) treshape = TReshape(score, pitch_function, time_range, melodic_form, True) results = treshape.apply() assert results is not None for i in range(0, len(results)): print('--- result[{0}] ---'.format(i)) print(results[i].line) assert len(results) == 2 first_pitch_set = {str(result.line.get_all_notes()[0].diatonic_pitch) for result in results} assert {'D:4', 'F:4'} == first_pitch_set all_notes = results[0].line.get_all_notes() assert 'F#:4' == str(all_notes[1].diatonic_pitch) assert 'G#:4' == str(all_notes[2].diatonic_pitch) assert 'A:4' == str(all_notes[3].diatonic_pitch) assert 'B:4' == str(all_notes[4].diatonic_pitch) assert 'A:4' == str(all_notes[5].diatonic_pitch) assert 'G#:4' == str(all_notes[6].diatonic_pitch) assert 'F#:4' == str(all_notes[7].diatonic_pitch) assert 'E:4' == str(all_notes[8].diatonic_pitch) assert 'F#:4' == str(all_notes[9].diatonic_pitch) assert 'G#:4' == str(all_notes[10].diatonic_pitch) assert 'A:4' == str(all_notes[11].diatonic_pitch) assert 'B:4' == str(all_notes[12].diatonic_pitch) assert 'C#:5' == str(all_notes[13].diatonic_pitch) assert 'Eb:5' == str(all_notes[14].diatonic_pitch) all_notes = results[1].line.get_all_notes() assert 'F#:4' == str(all_notes[1].diatonic_pitch) assert 'G#:4' == str(all_notes[2].diatonic_pitch) assert 'A:4' == str(all_notes[3].diatonic_pitch) assert 'B:4' == str(all_notes[4].diatonic_pitch) assert 'A:4' == str(all_notes[5].diatonic_pitch) assert 'G#:4' == str(all_notes[6].diatonic_pitch) assert 'F#:4' == str(all_notes[7].diatonic_pitch) assert 'E:4' == str(all_notes[8].diatonic_pitch) assert 'F#:4' == str(all_notes[9].diatonic_pitch) assert 'G#:4' == str(all_notes[10].diatonic_pitch) assert 'A:4' == str(all_notes[11].diatonic_pitch) assert 'B:4' == str(all_notes[12].diatonic_pitch) assert 'C#:5' == str(all_notes[13].diatonic_pitch) assert 'Eb:5' == str(all_notes[14].diatonic_pitch)
def test_pitch_sequence_shape(self): print('----- test_pitch_sequence_shape -----') s_notes = [ ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ] chords = [('tI', 1), ('tIV', 1), ('tV', 1), ('tVI', 1)] score = TestTReshape.create_score(s_notes, ModalityType.Major, 'Bb', chords, 'violin', (4, 4, 'swww')) all_notes = score.line.get_all_notes() eflat_interp = ScalarRangeInterpreter(Tonality.create(ModalityType.Major, DiatonicToneCache.get_tone('Bb')), 'Bb:3', 0) pitch_function = GenericUnivariatePitchFunction(TestTReshape.e_flat_linear, Position(0), Position(1), False, eflat_interp) # The first note should have one of 2 values, Eb:4, G:4 constraints = { ChordalPitchConstraint(all_notes[0]), # You need this kind of constraint to limit possibilities. PitchRangeConstraint([all_notes[0]], PitchRange.create('Bb:3', 'A:4')), StepSequenceConstraint([all_notes[3], all_notes[4], all_notes[5], all_notes[6]], [-1, -1, -1]), } motif = Motif(score.line, constraints, 'A') melodic_form = MelodicForm([motif]) time_range = Range(0, 3) treshape = TReshape(score, pitch_function, time_range, melodic_form, True) results = treshape.apply() assert results is not None for i in range(0, len(results)): print('--- result[{0}] ---'.format(i)) print(results[i].line) for result in results: notes = result.line.get_all_notes() if str(notes[3].diatonic_pitch) == 'Eb:4': assert 'D:4' == str(notes[4].diatonic_pitch) assert 'C:4' == str(notes[5].diatonic_pitch) assert 'Bb:3' == str(notes[6].diatonic_pitch) else: assert 'D:4' == str(notes[3].diatonic_pitch) assert 'C:4' == str(notes[4].diatonic_pitch) assert 'Bb:3' == str(notes[5].diatonic_pitch) assert 'A:3' == str(notes[6].diatonic_pitch)
def test_onbeat_shape(self): print('----- test_onbeat_shape -----') s_notes = [ ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ] chords = [('tI', 1), ('tIV', (1, 2)), ('tV', (1, 2)), ('tVI', 1)] score = TestTReshape.create_score(s_notes, ModalityType.Major, 'Bb', chords, 'violin', (4, 4, 'swww')) all_notes = score.line.get_all_notes() # The first note should have one of 2 values, Eb:4, G:4 constraints = { ChordalPitchConstraint(all_notes[0]), OnBeatConstraint(all_notes[2], BeatType.Strong), # You need this kind of constraint to limit possibilities. PitchRangeConstraint([all_notes[0]], PitchRange.create('Bb:3', 'A:4')), } motif = Motif(score.line, constraints, 'A') melodic_form = MelodicForm([motif]) eflat_interp = ScalarRangeInterpreter(Tonality.create(ModalityType.Major, DiatonicToneCache.get_tone('Bb')), 'Bb:3', 0) pitch_function = GenericUnivariatePitchFunction(TestTReshape.e_flat_linear, Position(0), Position(1), False, eflat_interp) time_range = Range(0, 3) treshape = TReshape(score, pitch_function, time_range, melodic_form, False) results = treshape.apply() assert results is not None for i in range(0, len(results)): print('--- result[{0}] ---'.format(i)) print(results[i].line) first_pitch_set = {str(result.line.get_all_notes()[0].diatonic_pitch) for result in results} assert {'Bb:3', 'D:4', 'F:4'} == first_pitch_set all_notes = results[0].line.get_all_notes() assert 'C:4' == str(all_notes[1].diatonic_pitch) assert 'C:5' == str(all_notes[2].diatonic_pitch) assert 'D:5' == str(all_notes[3].diatonic_pitch) assert 'Eb:5' == str(all_notes[4].diatonic_pitch) assert 'F:5' == str(all_notes[5].diatonic_pitch) assert 'G:5' == str(all_notes[6].diatonic_pitch) assert 'A:5' == str(all_notes[7].diatonic_pitch) assert Position(1) == all_notes[2].get_absolute_position() all_notes = results[1].line.get_all_notes() assert 'C:4' == str(all_notes[1].diatonic_pitch) assert 'C:5' == str(all_notes[2].diatonic_pitch) assert 'D:5' == str(all_notes[3].diatonic_pitch) assert 'Eb:5' == str(all_notes[4].diatonic_pitch) assert 'F:5' == str(all_notes[5].diatonic_pitch) assert 'G:5' == str(all_notes[6].diatonic_pitch) assert 'A:5' == str(all_notes[7].diatonic_pitch) assert Position(1) == all_notes[2].get_absolute_position()
def test_linear_scale(self): print('----- test_linear_scale -----') s_notes = [ ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ('E:4', 'e'), ] chords = [('tI', 1), ('tIV', (1, 2)), ('tV', (1, 2)), ('tVI', 1)] score = TestTReshape.create_score(s_notes, ModalityType.Major, 'Eb', chords, 'violin', (3, 4, 'sww')) all_notes = score.line.get_all_notes() eflat_interp = ScalarRangeInterpreter(Tonality.create(ModalityType.Major, DiatonicToneCache.get_tone('Eb')), 'Eb:4', 0) pitch_function = GenericUnivariatePitchFunction(TestTReshape.e_flat_linear, Position(0), Position(1), False, eflat_interp) time_range = Range(0, 3) # The first note should have one of 2 values, Eb:4, G:4 constraints = { ChordalPitchConstraint(all_notes[0]), PitchRangeConstraint([all_notes[0]], PitchRange.create('C:4', 'G:4')), } motif = Motif(score.line, constraints, 'A') melodic_form = MelodicForm([motif]) treshape = TReshape(score, pitch_function, time_range, melodic_form) results = treshape.apply() assert results is not None assert len(results) == 2 for result in results: print('-----') print(result.line) first_pitch_set = {str(result.line.get_all_notes()[0].diatonic_pitch) for result in results} assert {'Eb:4', 'G:4'} == first_pitch_set all_notes = results[0].line.get_all_notes() assert 'F:4' == str(all_notes[1].diatonic_pitch) assert 'G:4' == str(all_notes[2].diatonic_pitch) assert 'Ab:4' == str(all_notes[3].diatonic_pitch) assert 'Bb:4' == str(all_notes[4].diatonic_pitch) assert 'C:5' == str(all_notes[5].diatonic_pitch) assert 'D:5' == str(all_notes[6].diatonic_pitch) assert 'Eb:5' == str(all_notes[7].diatonic_pitch) all_notes = results[1].line.get_all_notes() assert 'F:4' == str(all_notes[1].diatonic_pitch) assert 'G:4' == str(all_notes[2].diatonic_pitch) assert 'Ab:4' == str(all_notes[3].diatonic_pitch) assert 'Bb:4' == str(all_notes[4].diatonic_pitch) assert 'C:5' == str(all_notes[5].diatonic_pitch) assert 'D:5' == str(all_notes[6].diatonic_pitch) assert 'Eb:5' == str(all_notes[7].diatonic_pitch)
def test_richer_structure(self): line = Line() s = Beam() s.append(Note(DiatonicPitch.parse('C:4'), Duration(1, 8))) s.append(Note(DiatonicPitch.parse('D:4'), Duration(1, 8))) line.pin(s) q1 = Note(DiatonicPitch.parse('E:4'), Duration(1, 4)) line.pin(q1, Offset(1, 4)) q2 = Note(DiatonicPitch.parse('F#:4'), Duration(1, 4)) line.pin(q2, Offset(1, 2)) cs = Beam() first_note = Note(DiatonicPitch.parse('C:3'), Duration(1, 8)) cs.append(first_note) cs.append(Note(DiatonicPitch.parse('D:3'), Duration(1, 8))) line.pin(cs, Offset(2)) cq1 = Note(DiatonicPitch.parse('E:3'), Duration(1, 4)) line.pin(cq1, Offset(9, 4)) cq2 = Note(DiatonicPitch.parse('F#:3'), Duration(1, 4)) line.pin(cq2, Offset(5, 2)) notes = line.get_all_notes() c = [ EqualPitchConstraint([notes[0], notes[2]]), NotEqualPitchConstraint([notes[1], notes[3]]) ] m = Motif([s, q1, q2], c, 'A') print(m) actors = m.actors assert 'A' == m.name assert len(actors) == 4 cc = m.constraints assert len(cc) == len(c) assert isinstance(cc[0], EqualPitchConstraint) cc_a = cc[0].actors assert len(cc_a) == 2 assert cc_a[0] == actors[0] assert cc_a[1] == actors[2] assert isinstance(cc[1], NotEqualPitchConstraint) cc_b = cc[1].actors assert len(cc_a) == 2 assert cc_b[0] == actors[1] assert cc_b[1] == actors[3] assert 'F#:4' == str(actors[3].diatonic_pitch) c_motif = m.copy_to(first_note) assert c_motif is not None c_actors = c_motif.actors assert 'A' == c_motif.name assert len(c_actors) == 4 ccc = c_motif.constraints assert len(ccc) == len(c) assert isinstance(ccc[0], EqualPitchConstraint) ccc_a = ccc[0].actors assert len(ccc_a) == 2 assert ccc_a[0] == c_actors[0] assert ccc_a[1] == c_actors[2] assert isinstance(ccc[1], NotEqualPitchConstraint) ccc_b = ccc[1].actors assert len(ccc_a) == 2 assert ccc_b[0] == c_actors[1] assert ccc_b[1] == c_actors[3] assert 'F#:3' == str(c_actors[3].diatonic_pitch) print(c_motif)
def test_simple_motif(self): s = Beam() s.append(Note(DiatonicPitch.parse('C:4'), Duration(1, 8))) s.append(Note(DiatonicPitch.parse('D:4'), Duration(1, 8))) s.append(Note(DiatonicPitch.parse('E:4'), Duration(1, 8))) s.append(Note(DiatonicPitch.parse('F#:4'), Duration(1, 8))) notes = s.get_all_notes() c = [ EqualPitchConstraint([notes[0], notes[2]]), NotEqualPitchConstraint([notes[1], notes[3]]) ] m = Motif(s, c, 'A') actors = m.actors assert 'A' == m.name assert len(actors) == len(notes) cc = m.constraints assert len(cc) == len(c) assert isinstance(cc[0], EqualPitchConstraint) cc_a = cc[0].actors assert len(cc_a) == 2 assert cc_a[0] == actors[0] assert cc_a[1] == actors[2] assert isinstance(cc[1], NotEqualPitchConstraint) cc_b = cc[1].actors assert len(cc_a) == 2 assert cc_b[0] == actors[1] assert cc_b[1] == actors[3] assert 'F#:4' == str(actors[3].diatonic_pitch) print(m) cs = Beam() first_note = Note(DiatonicPitch.parse('C:3'), Duration(1, 8)) cs.append(first_note) cs.append(Note(DiatonicPitch.parse('D:3'), Duration(1, 8))) cs.append(Note(DiatonicPitch.parse('E:3'), Duration(1, 8))) cs.append(Note(DiatonicPitch.parse('F#:3'), Duration(1, 8))) c_motif = m.copy_to(first_note) c_actors = c_motif.actors assert 'A' == c_motif.name assert len(c_actors) == len(notes) ccc = c_motif.constraints assert len(ccc) == len(c) assert isinstance(ccc[0], EqualPitchConstraint) ccc_a = ccc[0].actors assert len(ccc_a) == 2 assert ccc_a[0] == c_actors[0] assert ccc_a[1] == c_actors[2] assert isinstance(ccc[1], NotEqualPitchConstraint) ccc_b = ccc[1].actors assert len(ccc_a) == 2 assert ccc_b[0] == c_actors[1] assert ccc_b[1] == c_actors[3] assert 'F#:3' == str(c_actors[3].diatonic_pitch) print(c_motif)
def reshape_with_spf(): print('----- test_reshape_with_spf (Fgure 17.22) -----') line_str = '{<C-Major: I> iE:4 E E E E q@E <:IV> qE ie e <:V> qe ie e <:VI> qE E iE E E E}' score = create_score(line_str, 'piano', (3, 4, 'sww')) tonality = score.hct.get_hc_by_position(0).tonality all_notes = score.line.get_all_notes() # 11 scalar notes to C:4 (0) to G:5 (11) with pitch unit 1/11 interpreter = ScalarRangeInterpreter(tonality, DiatonicPitch.parse('C:4'), 0, Fraction(1, 11)) pitch_function = GenericUnivariatePitchFunction(three_sin, Position(0), Position(3), False, interpreter) # The first note should have one of 3 values, C:4, E:4, G:4 constraints = { ChordalPitchConstraint(all_notes[0]), ChordalPitchConstraint(all_notes[6]), ChordalPitchConstraint(all_notes[9]), ChordalPitchConstraint(all_notes[12]), PitchRangeConstraint([all_notes[0]], PitchRange.create('C:4', 'E:4')), } motif = Motif([all_notes[0], all_notes[6], all_notes[9], all_notes[12]], constraints, 'A') melodic_form = MelodicForm([motif]) t_reshape = TReshape(score, pitch_function, Range(0, 3), melodic_form, True) results = t_reshape.apply() filters = MinCurveFitFilter(pitch_function, results) print('{0} filtered results'.format(len(filters.scored_results))) for index in range(0, min(5, len(filters.scored_results))): result = filters.scored_results[index] print('[{0}] {1} ({2})'.format(index, str_line(result[0].line), result[1])) constraints = { ChordalPitchConstraint(all_notes[0]), ChordalPitchConstraint(all_notes[4]), ChordalPitchConstraint(all_notes[6]), ChordalPitchConstraint(all_notes[8]), ChordalPitchConstraint(all_notes[12]), ChordalPitchConstraint(all_notes[14]), PitchRangeConstraint([all_notes[0]], PitchRange.create('C:4', 'G:4')), } motif = Motif(score.line, constraints, 'A') melodic_form = MelodicForm([motif]) t_reshape = TReshape(score, pitch_function, Range(0, 3), melodic_form, True) results = t_reshape.apply() filters = MinCurveFitFilter(pitch_function, results) print('{0} filtered results'.format(len(filters.scored_results))) for index in range(0, min(5, len(filters.scored_results))): result = filters.scored_results[index] print('[{0}] {1} ({2})'.format(index, str_line(result[0].line), result[1]))
def test_simple_form(self): line = Line() s = Beam() s.append(Note(DiatonicPitch.parse('C:4'), Duration(1, 8))) s.append(Note(DiatonicPitch.parse('D:4'), Duration(1, 8))) s.append(Note(DiatonicPitch.parse('E:4'), Duration(1, 8))) s.append(Note(DiatonicPitch.parse('F#:4'), Duration(1, 8))) line.pin(s) notes = s.get_all_notes() c = [ EqualPitchConstraint([notes[0], notes[2]]), NotEqualPitchConstraint([notes[1], notes[3]]) ] a = Motif(s, c, 'A') s1 = [ Note(DiatonicPitch(4, 'c'), Duration(1, 8)), Note(DiatonicPitch(4, 'd'), Duration(1, 8)), Note(DiatonicPitch(4, 'e'), Duration(1, 8)), ] tuplet = Tuplet(Duration(1, 8), 2, s1) line.pin(tuplet, Offset(1, 2)) notes = tuplet.get_all_notes() c1 = [ EqualPitchConstraint([notes[0], notes[2]]), RelativeScalarStepConstraint(notes[1], notes[2], -2, 2) ] b = Motif(tuplet, c1, 'B') f = Form([a, b]) print(f) constraints = [ EqualPitchConstraint([a.actors[0], b.actors[1]]) ] # Ensure a, b cloned for reliability - see comment in Form. ff = Form([a, b], constraints) print(ff) constr = ff.external_constraints assert len(constr) == 1 actors = ff.actors assert len(actors) == 7 assert isinstance(constr[0], EqualPitchConstraint) assert constr[0].actors[0] == actors[0] assert constr[0].actors[1] == actors[4 + 1] all_constr = ff.constraints assert len(all_constr) == 5 # Add more notes to clone ff as: s3 = Beam() first_note = Note(DiatonicPitch.parse('C:5'), Duration(1, 8)) s3.append(first_note) s3.append(Note(DiatonicPitch.parse('D:5'), Duration(1, 8))) s3.append(Note(DiatonicPitch.parse('E:5'), Duration(1, 8))) s3.append(Note(DiatonicPitch.parse('F#:5'), Duration(1, 8))) line.pin(s3, Offset(3)) s2 = [ Note(DiatonicPitch(5, 'c'), Duration(1, 8)), Note(DiatonicPitch(5, 'd'), Duration(1, 8)), Note(DiatonicPitch(5, 'e'), Duration(1, 8)), ] tuplet1 = Tuplet(Duration(1, 8), 2, s2) line.pin(tuplet1, Offset(7, 2)) fff = ff.copy_to(first_note) assert fff is not None print(fff) constr = fff.external_constraints assert len(constr) == 1 assert len(fff.constraints) == 5 actors = fff.actors assert len(actors) == 7 assert isinstance(constr[0], EqualPitchConstraint) assert constr[0].actors[0] == actors[0] assert constr[0].actors[1] == actors[4 + 1] all_constr = fff.constraints assert len(all_constr) == 5
def test_simple_form(self): line = Line() notes = [ Note(DiatonicPitch.parse('C:4'), Duration(1, 8)), Note(DiatonicPitch.parse('D:4'), Duration(1, 8)), Note(DiatonicPitch.parse('E:4'), Duration(1, 8)), Note(DiatonicPitch.parse('F:4'), Duration(1, 8)), Note(DiatonicPitch.parse('G:4'), Duration(1, 8)), Note(DiatonicPitch.parse('A:4'), Duration(1, 8)), Note(DiatonicPitch.parse('B:4'), Duration(1, 8)), Note(DiatonicPitch.parse('C:4'), Duration(1, 4)), Note(DiatonicPitch.parse('C:3'), Duration(1, 8)), Note(DiatonicPitch.parse('D:3'), Duration(1, 8)), Note(DiatonicPitch.parse('E:3'), Duration(1, 8)), Note(DiatonicPitch.parse('F:3'), Duration(1, 8)), Note(DiatonicPitch.parse('G:3'), Duration(1, 8)), Note(DiatonicPitch.parse('A:3'), Duration(1, 8)), Note(DiatonicPitch.parse('B:3'), Duration(1, 8)), Note(DiatonicPitch.parse('C:3'), Duration(1, 4)), ] f = Fraction(0) for n in notes: line.pin(n, Offset(f)) f = f + n.duration.duration ca = [ EqualPitchConstraint([notes[0], notes[2]]), NotEqualPitchConstraint([notes[1], notes[3]]) ] cb = [ NotEqualPitchConstraint([notes[4], notes[5]]), EqualPitchConstraint([notes[6], notes[7]]) ] a = Motif([notes[0], notes[1], notes[2], notes[3]], ca, 'A') b = Motif([notes[4], notes[5], notes[6], notes[7]], cb, 'B') p1_constraints = [ EqualPitchConstraint([notes[4], notes[5]]), ] p1 = Phrase([notes[2], notes[3], notes[4], notes[5]], p1_constraints, 'P1') mf_constraints = [ EqualPitchConstraint([notes[2], notes[5]]), ] mf = MelodicForm([a, b], [p1], mf_constraints, 'MF1') actors = mf.actors assert actors is not None assert len(actors) == 8 assert actors[0] == notes[0] motifs = mf.motifs assert motifs is not None assert len(motifs) == 2 assert motifs[0].name == 'A' assert motifs[1].name == 'B' p_constraints = mf.phrase_constraints assert p_constraints is not None assert len(p_constraints) == 1 assert type(p_constraints[0]) == EqualPitchConstraint p_actors = mf.phrase_actors assert p_actors is not None assert len(p_actors) == 4 mf1 = mf.copy_to(notes[8]) assert mf1 is not None actors = mf1.actors assert actors is not None assert len(actors) == 8 assert actors[0] == notes[8] motifs = mf1.motifs assert motifs is not None assert len(motifs) == 2 assert motifs[0].name == 'A' assert motifs[1].name == 'B' p_constraints = mf1.phrase_constraints assert p_constraints is not None assert len(p_constraints) == 1 assert type(p_constraints[0]) == EqualPitchConstraint p_actors = mf1.phrase_actors assert p_actors is not None assert len(p_actors) == 4 phs = mf1.phrases assert phs is not None assert len(phs) == 1 assert phs[0].actors[0] == notes[10]