def tonal_modulation_CMinor_tonal_example(): print('----- Tonal Modulation C-Minor Tonal Example (Figure 22.7) -----') line_text = '{<C-MelodicMinor:I> (i, 2)[iC:5 Eb D] <:V/ii> c# b c# e <:ii> f d b:4 a}' lge = LineGrammarExecutor() source_instance_line, source_instance_hct = lge.parse(line_text) print_score('\n[0]: ', source_instance_line, source_instance_hct) trans = TStepShift(source_instance_line, source_instance_hct, SecondaryShiftType.Tonal) new_line, new_hct = trans.apply(1) print_score('\n[1]: ', new_line, new_hct) new_line, new_hct = trans.apply(2) print_score('\n[2]: ', new_line, new_hct)
def create_score(line_expression, instrument, ts): lge = LineGrammarExecutor() source_instance_line, source_instance_hct = lge.parse(line_expression) tempo_seq = TempoEventSequence() ts_seq = EventSequence() tempo_seq.add(TempoEvent(Tempo(60, Duration(1, 4)), Position(0))) ts_seq.add( TimeSignatureEvent(TimeSignature(ts[0], Duration(1, ts[1]), ts[2]), Position(0))) c = InstrumentCatalog.instance() instrument = c.get_instrument(instrument) return LiteScore(source_instance_line, source_instance_hct, instrument, tempo_seq, ts_seq)
def test_default_hct(self): print('----- test_default_hct -----') music_text_line = LineGrammarExecutor() s = '{qC:4 D:4 F}' line, hct = music_text_line.parse(s) print(line) print('-----') hclist = hct.hc_list() assert hclist is not None assert len(hclist) == 1 hc = hclist[0] assert 'C-Major' == str(hc.tonality) assert ['C', 'E', 'G'] == [t[0].diatonic_symbol for t in hc.chord.tones]
def test_user_defined_modality(self): print('----- test_user_defined_modality -----') modality_type = ModalityType('MyModality') incremental_interval_strs = [ 'P:1', 'm:2', 'M:3', 'm:2', 'm:2', 'M:2', 'A:2' ] modality_spec = ModalitySpec(modality_type, incremental_interval_strs) ModalityFactory.register_modality(modality_type, modality_spec) music_text_line = LineGrammarExecutor() s = '{<C-!MyModality: I> F#:4 A D}' line, hct = music_text_line.parse(s) print(line) print('-----')
def tonal_modulation_all_NaturalMinor_tonal_example(): print('----- Tonal Modulation C-NaturalMinor Tonal Example -----') line_text = '{<C-NaturalMinor:I> (i, 2)[iC:5 Eb D] <:V/ii-Natural> c:5 Bb:4 c:5 e <:ii> f d Bb:4 Ab}' lge = LineGrammarExecutor() source_instance_line, source_instance_hct = lge.parse(line_text) print_score('\n[0]: ', source_instance_line, source_instance_hct) trans = TStepShift(source_instance_line, source_instance_hct, SecondaryShiftType.Tonal) new_line, new_hct = trans.apply(1) print_score('\n[1]: ', new_line, new_hct) new_line, new_hct = trans.apply(2) print_score('\n[2]: ', new_line, new_hct)
def test_mozart(self): print('----- Mozart -----') line_str = '{<C-Major: I> hC:5 qE G <:VMaj7> q@b:4 sC:5 D <:I> hC}' lge = LineGrammarExecutor() target_line, target_hct = lge.parse(line_str) print('--- before transformation ---') TestTChromaticFlip.print_notes(target_line) TestTChromaticFlip.print_hct(target_hct) cue = DiatonicPitch(5, 'c') f = TChromaticReflection(target_line, target_hct, cue) score_line, score_hct = f.apply() print('--- after transformation ---') TestTChromaticFlip.print_notes(score_line) TestTChromaticFlip.print_hct(score_hct) print('--- transformation ---') TestTChromaticFlip.print_function(f, target_hct) notes = score_line.get_all_notes() assert 'C:5' == str(notes[0].diatonic_pitch) assert 'Ab:4' == str(notes[1].diatonic_pitch) assert 'F:4' == str(notes[2].diatonic_pitch) assert 'Db:5' == str(notes[3].diatonic_pitch) assert 'C:5' == str(notes[4].diatonic_pitch) assert 'Bb:4' == str(notes[5].diatonic_pitch) assert 'C:5' == str(notes[6].diatonic_pitch) hc_list = score_hct.hc_list() assert len(hc_list) == 3 assert hc_list[0].chord.chord_template.scale_degree == 4 assert {t[0].diatonic_symbol for t in hc_list[0].chord.tones} == {'C', 'F', 'Ab'} assert hc_list[0].chord.chord_template.inversion == 3 assert hc_list[1].chord.chord_template.scale_degree == 7 assert {t[0].diatonic_symbol for t in hc_list[1].chord.tones} == {'F', 'Bb', 'Db', 'Gb'} assert hc_list[1].chord.chord_template.inversion == 3 assert hc_list[2].chord.chord_template.scale_degree == 4 assert {t[0].diatonic_symbol for t in hc_list[2].chord.tones} == {'C', 'F', 'Ab'} assert hc_list[2].chord.chord_template.inversion == 3
def create(pattern_string): """ Constructor for MelodicSearch using a text string representation for the pattern. :param pattern_string: :return: """ line, hct = LineGrammarExecutor().parse(pattern_string) return MelodicSearch(line, hct)
def test_mozart(self): print('----- test mozart c-minor fantasy parse -----') source_instance_expression = '{<A-Major:i> qD:4 E F# <A-Melodic:iv> F# G# A}' lge = LineGrammarExecutor() source_instance_line, source_instance_hct = lge.parse(source_instance_expression) tpat_sub = TPatSub.create('{<C-Major:i> qC:4 D E <C-Melodic:iv> Eb F G}', '{<C-Natural: iv> q@C:4 iEb F# G <C-Natural: vi> Ab C <C-Melodic: V> iB:3}', ['@0-Natural:iv', '@1-Natural:vi', '@1-Melodic:V']) tag_map = {0: DiatonicPitch.parse('D:4')} results, target_instance_hct = tpat_sub.apply(source_instance_line, source_instance_hct, 'B:3', tag_map, tpat_sub.target_height + 5) self.print_results(results, tpat_sub.substitution_pattern.target_pattern_line)
def test_beam(self): print('----- test_beam -----') music_text_line = LineGrammarExecutor() s = '{qC:4 D:4 [E:3 F G A B:4]}' line, _ = music_text_line.parse(s) print(line) print('-----') notes = line.sub_notes assert len(notes) == 3 assert 'C:4' == str(notes[0].diatonic_pitch) assert 'D:4' == str(notes[1].diatonic_pitch) assert isinstance(notes[2], Beam) beam = notes[2] b_notes = beam.sub_notes assert len(b_notes) == 5 assert 'E:3' == str(b_notes[0].diatonic_pitch) assert 'F:3' == str(b_notes[1].diatonic_pitch) assert 'G:3' == str(b_notes[2].diatonic_pitch) assert 'A:3' == str(b_notes[3].diatonic_pitch) assert 'B:4' == str(b_notes[4].diatonic_pitch) s = '{C:4 [E:3 F [G:5 A B C] B]}' line, _ = music_text_line.parse(s) print(line) print('-----') notes = line.sub_notes assert len(notes) == 2 assert 'C:4' == str(notes[0].diatonic_pitch) assert isinstance(notes[1], Beam) beam = notes[1] b_notes = beam.sub_notes assert len(b_notes) == 4 assert 'E:3' == str(b_notes[0].diatonic_pitch) assert 'F:3' == str(b_notes[1].diatonic_pitch) assert isinstance(b_notes[2], Beam) assert 'B:3' == str(b_notes[3].diatonic_pitch) bb_notes = b_notes[2].sub_notes assert len(bb_notes) == 4 assert 'G:5' == str(bb_notes[0].diatonic_pitch) assert 'A:5' == str(bb_notes[1].diatonic_pitch) assert 'B:5' == str(bb_notes[2].diatonic_pitch) assert 'C:5' == str(bb_notes[3].diatonic_pitch)
def simple_sequence_example(): print('----- Simple Sequence Example (Figure 22.4) -----') line_text = '{<E-Major:I>iE:5 f# G# F# E f# }' lge = LineGrammarExecutor() source_instance_line, source_instance_hct = lge.parse(line_text) print_score('\n[0]: ', source_instance_line, source_instance_hct) trans = TStepShift(source_instance_line, source_instance_hct) new_line, new_hct = trans.apply(-1) print_score('\n[1]: ', new_line, new_hct) new_line, new_hct = trans.apply(-2) print_score('\n[2]: ', new_line, new_hct) new_line, new_hct = trans.apply(-3) print_score('\n[3]: ', new_line, new_hct)
def shift_modulating_sequence_example(): print('----- Shift sequence standard example (Figure 15.14) -----') source_expression = '{<C-Major: IV> sf:4 a b C:5 <:V/ii> sa:4 e:5 tc# b:4 sC#:5 <:ii> sd tc a:4 sb:4 a}' lge = LineGrammarExecutor() source_instance_line, source_instance_hct = lge.parse(source_expression) print_score('\n[0]: ', source_instance_line, source_instance_hct) t_shift = TShift.create(source_expression) target_line, target_hct = t_shift.apply(root_shift_interval=TonalInterval.parse('M:2'), range_modality_type=ModalityType.Major) print_score('\n[1]: ', target_line, target_hct) t_shift = TShift(target_line, target_hct) target_line, target_hct = t_shift.apply(root_shift_interval=TonalInterval.parse('M:2'), range_modality_type=ModalityType.Major) print_score('\n[2]: ', target_line, target_hct)
def test_using_syntax(self): line, hct = LineGrammarExecutor().parse( '{<C-Major:I> C:4 [E:5 F [G:4 A B A] B]}') lite_score = LiteScore( line, hct, InstrumentCatalog.instance().get_instrument("violin")) print(lite_score.line)
def test_embedded_harmonic_tag(self): print('----- embedded_harmonic_tag -----') music_text_line = LineGrammarExecutor() s = '{qC:4 D:4 [<E-Major: IV> F G A]}' line, hct = music_text_line.parse(s) print(line) print('-----') hclist = hct.hc_list() assert hclist is not None assert len(hclist) == 2 first = hclist[0] second = hclist[1] assert 'C-Major' == str(first.tonality) assert ['C', 'E', 'G'] == [t[0].diatonic_symbol for t in first.chord.tones] assert 'E-Major' == str(second.tonality) assert ['A', 'C#', 'E'] == [t[0].diatonic_symbol for t in second.chord.tones] assert Duration(1, 2) == first.duration assert Duration(3, 8) == second.duration s = '{qC:4 D:4 <E-Major: IV> [F G A]}' line, hct = music_text_line.parse(s) print(line) print('-----') hclist = hct.hc_list() assert hclist is not None assert len(hclist) == 2 first = hclist[0] second = hclist[1] assert 'C-Major' == str(first.tonality) assert ['C', 'E', 'G'] == [t[0].diatonic_symbol for t in first.chord.tones] assert 'E-Major' == str(second.tonality) assert ['A', 'C#', 'E'] == [t[0].diatonic_symbol for t in second.chord.tones] assert Duration(1, 2) == first.duration assert Duration(3, 8) == second.duration
def test_multi_hc_pattern_search(self): print('----- test_multi_hc_pattern_search -----') lge = LineGrammarExecutor() pattern = '{<C-Major: I> [iC:4 G F A] <G-Major: I> B:4 E:5 G C}' target = '{<F-Minor: v> qF:4 C:5 <C-Major: I> [iC:4 G F A] <G-Major: I> B:4 E:5 G C D}' target_line, target_hct = lge.parse(target) search = MelodicSearch.create(pattern) answers = search.search(target_line, target_hct, GlobalSearchOptions()) assert answers is not None print('test_multi_hc_pattern_search - test 1') for i, a in zip(range(1, len(answers) + 1), answers): print('[{0}] {1}'.format(i, a)) assert 1 == len(answers) assert Position(1, 2) == answers[0]
def test_single_hc_pattern_search(self): print('----- test_single_hc_pattern_search -----') lge = LineGrammarExecutor() pattern = '{<C-Major: I> qC:4 G iB E:5 C}' target = '{<F-Minor: v> qF:4 C:5 iE Ab:5 F C Db <D-Major: I> qD:3 A iC#:4 F#:6 D}' target_line, target_hct = lge.parse(target) search = MelodicSearch.create(pattern) answers = search.search(target_line, target_hct, GlobalSearchOptions()) assert answers is not None for i, a in zip(range(1, len(answers) + 1), answers): print('[{0}] {1}'.format(i, a)) assert 2 == len(answers) assert Position(0) == answers[0] assert Position(9, 8) == answers[1]
def test_entangled_harmonic_tag(self): music_text_line = LineGrammarExecutor() s = '{qC:4 D:4 [E:3 <F-Major: IV> F A C]}' line, hct = music_text_line.parse(s) print(line) print('-----') hclist = hct.hc_list() assert hclist is not None assert len(hclist) == 2 first = hclist[0] second = hclist[1] assert 'C-Major' == str(first.tonality) assert ['C', 'E', 'G'] == [t[0].diatonic_symbol for t in first.chord.tones] assert 'F-Major' == str(second.tonality) assert ['Bb', 'D', 'F'] == [t[0].diatonic_symbol for t in second.chord.tones] assert Duration(5, 8) == first.duration assert Duration(3, 8) == second.duration s = '{qC:4 D:4 (q, 3)[E:3 <F-Major: IV> F A C]}' line, hct = music_text_line.parse(s) print(line) print('-----') hclist = hct.hc_list() assert hclist is not None assert len(hclist) == 2 first = hclist[0] second = hclist[1] assert 'C-Major' == str(first.tonality) assert ['C', 'E', 'G'] == [t[0].diatonic_symbol for t in first.chord.tones] assert 'F-Major' == str(second.tonality) assert ['Bb', 'D', 'F'] == [t[0].diatonic_symbol for t in second.chord.tones] assert Duration(11, 16) == first.duration assert Duration(9, 16) == second.duration
def second_pattern_example(): print('----- test explanation pattern example -----') source_expression = '{<C-Major: i> iC:4 C E F hE <:v> iD:4 D G A hB <:VI> iC:5 C B:4 A <:IV> iA:4 A G F <:II> ' \ 'iF:4 F E D <:I> hC:4}' replacement_expression = '{<C-Major: i> q@C:4 iD qE <:iv> q@F:4 iG qA <:v> qG:4 D F ' \ '<G-Melodic:i> q@G:4 iA qBb <:V> qD:5 E F# ' \ '<G-Natural:IV> qG:5 Eb C <C-Major:V> q@B:4 iA qG <:VI> q@a iG qE <:IV> qC:4 F D <:I> h@C}' replacement_hc_expressions = [ '@0:i', '@0:iv', '@0:v', '(@0)P:5-Melodic:i', '(@0)P:5-Melodic:v', '(@0)P:5-Natural:iv', '@0:v', '@0:vi', '@0:iv', '@0:i', ] t_pat_sub = TPatSub.create(source_expression, replacement_expression, replacement_hc_expressions) source_instance_expression = '{<F-Major: i> iF:4 F G A hG <:VDom7> iG:4 G A Bb hC <:I> iF:5 F D C <:III> ' \ 'iC:5 C Bb:4 A <:I> iA:4 A G F <:VI> hD:4}' lge = LineGrammarExecutor() source_instance_line, source_instance_hct = lge.parse(source_instance_expression) tag_map = {0: DiatonicPitch.parse('F:4')} results, replacement_instance_hct = t_pat_sub.apply(source_instance_line, source_instance_hct, 'C:4', tag_map, t_pat_sub.target_height + 5, 300) mc_filter = MinContourFilter(t_pat_sub.substitution_pattern.target_pattern_line, results.pitch_results) scored_filtered_results = mc_filter.scored_results print_hct(replacement_instance_hct) print_results(scored_filtered_results)
def test_secondary_chord(self): print('----- test_secondary_chord -----') music_text_line = LineGrammarExecutor() s = '{<C-Major: V/V> F#:4 A D}' line, hct = music_text_line.parse(s) print(line) print('-----') hclist = hct.hc_list() assert hclist is not None assert len(hclist) == 1 first = hclist[0] assert 'C-Major' == str(first.tonality) assert isinstance(first.chord.chord_template, SecondaryChordTemplate) assert 5 == first.chord.chord_template.secondary_scale_degree assert 5 == first.chord.chord_template.principal_chord_template.scale_degree s = '{<F-Major: IIIDom7/V-Natural> F#:4 A D}' line, hct = music_text_line.parse(s) print(line) print('-----') hclist = hct.hc_list() assert hclist is not None assert len(hclist) == 1 first = hclist[0] assert 'F-Major' == str(first.tonality) assert isinstance(first.chord.chord_template, SecondaryChordTemplate) assert 5 == first.chord.chord_template.secondary_scale_degree assert 3 == first.chord.chord_template.principal_chord_template.scale_degree assert isinstance(first.chord.chord_template.principal_chord_template, TertianChordTemplate) assert TertianChordType( TertianChordType.Dom7 ) == first.chord.chord_template.principal_chord_template.chord_type assert 'C-NaturalMinor' == str(first.chord.secondary_tonality) assert {'Eb', 'G', 'Bb', 'Db'} == {t[0].diatonic_symbol for t in first.chord.tones}
def test_durations(self): print('----- test_durations -----') music_text_line = LineGrammarExecutor() s = '{wC:4 hD:4 qE:4 iF:4 sG:4 tA:4 xB:4}' line, _ = music_text_line.parse(s) print(line) print('-----') notes = line.get_all_notes() assert Duration(1) == notes[0].duration assert Duration(1, 2) == notes[1].duration assert Duration(1, 4) == notes[2].duration assert Duration(1, 8) == notes[3].duration assert Duration(1, 16) == notes[4].duration assert Duration(1, 32) == notes[5].duration assert Duration(1, 64) == notes[6].duration s = '{WC:4 HD:4 QE:4 IF:4 SG:4 TA:4 XB:4}' line, _ = music_text_line.parse(s) print(line) print('-----') notes = line.get_all_notes() assert Duration(1) == notes[0].duration assert Duration(1, 2) == notes[1].duration assert Duration(1, 4) == notes[2].duration assert Duration(1, 8) == notes[3].duration assert Duration(1, 16) == notes[4].duration assert Duration(1, 32) == notes[5].duration assert Duration(1, 64) == notes[6].duration s = '{(2:1)C:4 (3:2)D:4 (4:3)E:4}' line, _ = music_text_line.parse(s) print(line) print('-----') notes = line.get_all_notes() assert Duration(2, 1) == notes[0].duration assert Duration(3, 2) == notes[1].duration assert Duration(4, 3) == notes[2].duration
def create_score(line_text, instrument, tmpo, ts): """ :param line_text: :param instrument: :param tmpo: (bpm, tempo beat duration) :param ts: (num beats, ts beat duration) :return: """ lge = LineGrammarExecutor() source_instance_line, source_instance_hct = lge.parse(line_text) tempo_seq = TempoEventSequence() ts_seq = EventSequence() tempo_seq.add(TempoEvent(Tempo(tmpo[0], tmpo[1]), Position(0))) ts_seq.add(TimeSignatureEvent(TimeSignature(ts[0], ts[1]), Position(0))) c = InstrumentCatalog.instance() instrument = c.get_instrument(instrument) return LiteScore(source_instance_line, source_instance_hct, instrument, tempo_seq, ts_seq)
def test_note_match_non_scalar_to_scalar(self): print('----- test_note_match_non_scalar_to_scalar -----') lge = LineGrammarExecutor() pattern = '{<C-Major: I> [iC:4 Eb G B]}' target = '{<C-Minor: i> [iC:5 Eb:5 G B]}' target_line, target_hct = lge.parse(target) search = MelodicSearch.create(pattern) answers = search.search( target_line, target_hct, GlobalSearchOptions(note_match_non_scalar_to_scalar=False)) assert answers is not None assert 0 == len(answers) answers = search.search( target_line, target_hct, GlobalSearchOptions(note_match_non_scalar_to_scalar=True)) assert answers is not None assert 1 == len(answers)
def test_modality_setting(self): print('----- test_modality_setting -----') line_str = '{<C-Major: I> C:4 E G A <:IV> iF A B C:5 <:V> qG:4 D <:VI> a c:5 b:4 a}' lge = LineGrammarExecutor() target_line, target_hct = lge.parse(line_str) root_shift_interval = TonalInterval.create_interval('C:4', 'C#:4') tshift = TShift(target_line, target_hct, root_shift_interval, default_modal_index=2) temporal_extent = Interval(Fraction(0), Fraction(3, 1)) score_line, score_hct = tshift.apply( temporal_extent, range_modality_type=ModalityType.MelodicMinor) TestTShift.print_notes(score_line) TestTShift.print_hct(score_hct) notes = score_line.get_all_notes() assert 14 == len(notes) assert 'F##:4' == str(notes[4].diatonic_pitch) assert 'A#:4' == str(notes[5].diatonic_pitch) assert 'B#:4' == str(notes[6].diatonic_pitch) assert 'C#:5' == str(notes[7].diatonic_pitch) hc_list = score_hct.hc_list() assert len(hc_list) == 4 assert hc_list[0].chord.chord_template.scale_degree == 1 assert {t[0].diatonic_symbol for t in hc_list[0].chord.tones} == {'C#', 'E#', 'G##'} assert hc_list[0].chord.chord_template.inversion == 1 assert hc_list[0].tonality.modal_index == 2 assert hc_list[0].tonality.basis_tone.diatonic_symbol == 'A#' assert hc_list[0].tonality.root_tone.diatonic_symbol == 'C#' assert hc_list[0].tonality.modality_type == ModalityType.MelodicMinor assert hc_list[0].chord.chord_type.value == TertianChordType.Aug
def test_structural_match(self): print('----- test_structural_match -----') lge = LineGrammarExecutor() # Used in book pattern = '{<C-Major: I> [iC:4 G F A] <G-Major: I> qB:4 (I, 2)[iE:5 F# C]}' target = '{<F-Minor: v> qF:4 C:5 <F-Major: I> [iF:4 C:5 Bb:4 D:5] <C-Major: I> qE:5 (I, 2)[iA:5 C:6 F:5]}' target_line, target_hct = lge.parse(target) search = MelodicSearch.create(pattern) answers = search.search(target_line, target_hct, GlobalSearchOptions()) assert answers is not None print('test_multi_hc_pattern_search - test 2') for i, a in zip(range(1, len(answers) + 1), answers): print('[{0}] {1}'.format(i, a)) assert 1 == len(answers) assert Position(1, 2) == answers[0] # test for non-structural match pattern = '{<C-Major: I> iC:4 G F A <G-Major: I> qB:4 (1:12)E:5 G C}' target = '{<F-Minor: v> qF:4 C:5 <C-Major: I> [iC:4 G F A] <G-Major: I> qB:4 (I, 2)[E:5 G C]}' target_line, target_hct = lge.parse(target) search = MelodicSearch.create(pattern) answers = search.search(target_line, target_hct, GlobalSearchOptions(structural_match=False)) assert answers is not None assert 1 == len(answers) assert Position(1, 2) == answers[0] # test for illegal non-structural match answers = search.search(target_line, target_hct, GlobalSearchOptions(structural_match=True)) assert answers is not None assert 0 == len(answers)
def shift_sequence_tonal_example(): print('----- Shift sequence tonal example -----') source_expression = '{<C-Major: IV> qf:4 a b C:5 <:V/ii> a:4 e:5 id C# <:ii> qd c b:4 a}' lge = LineGrammarExecutor() source_instance_line, source_instance_hct = lge.parse(source_expression) print_score('\n[0]: ', source_instance_line, source_instance_hct) t_shift = TShift.create(source_expression) target_line, target_hct = t_shift.apply(root_shift_interval=TonalInterval.parse('M:2'), range_modality_type=ModalityType.MelodicMinor) print(target_line) print(target_hct) print() t_shift = TShift(target_line, target_hct) target_line, target_hct = t_shift.apply(root_shift_interval=TonalInterval.parse('M:2'), range_modality_type=ModalityType.MelodicMinor) print(target_line) print(target_hct) print()
def test_modal_tonality_modal_index(self): print('----- test_modal_tonality_modal_index -----') # diatonic_modality is effectively Dorian line_str = '{<D-Major(1): I> D:4 F A B <:IV> iG B C:5 D <:V> qA:4 E <:VI> qB D:5 C B}' lge = LineGrammarExecutor() target_line, target_hct = lge.parse(line_str) # shift whole score sot D being Phrygian in some major scale - scale being Bb-Major tshift = TShift(target_line, target_hct, default_root_shift_interval=None, default_modal_index=2) temporal_extent = Interval(Fraction(0), Fraction(3, 1)) score_line, score_hct = tshift.apply(temporal_extent) TestTShift.print_notes(score_line) TestTShift.print_hct(score_hct) notes = score_line.get_all_notes() assert 14 == len(notes) assert 'G:4' == str(notes[4].diatonic_pitch) assert 'B:4' == str(notes[5].diatonic_pitch) assert 'Cb:5' == str(notes[6].diatonic_pitch) assert 'D:5' == str(notes[7].diatonic_pitch) hc_list = score_hct.hc_list() assert len(hc_list) == 4 assert hc_list[0].chord.chord_template.scale_degree == 1 assert {t[0].diatonic_symbol for t in hc_list[0].chord.tones} == {'E', 'G', 'B'} assert hc_list[0].chord.chord_template.inversion == 1 assert hc_list[0].tonality.modal_index == 2 assert hc_list[0].tonality.basis_tone.diatonic_symbol == 'C' assert hc_list[0].tonality.root_tone.diatonic_symbol == 'E' assert hc_list[0].tonality.modality_type == ModalityType.Major assert hc_list[0].chord.chord_type.value == TertianChordType.Min
def test_simple_hct(self): print('----- test_simple_hct -----') music_text_line = LineGrammarExecutor() s = '{<Bb-Minor: ii>qC:4 D:4 <Cb-Major: IV> F G A}' line, hct = music_text_line.parse(s) print(line) print('-----') hclist = hct.hc_list() assert hclist is not None assert len(hclist) == 2 first = hclist[0] second = hclist[1] assert 'Bb-MelodicMinor' == str(first.tonality) assert ['C', 'Eb', 'G'] == [t[0].diatonic_symbol for t in first.chord.tones] assert 'Cb-Major' == str(second.tonality) assert ['Fb', 'Ab', 'Cb'] == [t[0].diatonic_symbol for t in second.chord.tones] assert Duration(1, 2) == first.duration assert Duration(3, 4) == second.duration
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 first_pattern_example(): print('----- test explanation pattern example -----') pattern_expression = '{<Bb-Major: i> qBb:3 Bb:4 ia sg eb qf <:iv> qEb:4 Eb:5 iD sEb F i@G sG <:iv> sF:5 ' \ 'Eb D C:4 D:5 C:4 G A <:i> hBb}' replacement_expression = '{<Bb-Major: i> qBb:4 Bb:3 <:vi> iD:4 sEb G qf <:v> qF:5 F:4 <:i> iF:5 sEb D i@Bb:4 ' \ 'sG:5 <:iv> sEb:4 Eb:5 D C Bb:4 A G F <:I> hBb:3}' replacement_hc_expressions = [ '@0:i', '@0:vi', '@0:v', '@0:i', '@0:iv', '@0:i', ] t_pat_sub = TPatSub.create(pattern_expression, replacement_expression, replacement_hc_expressions) source_instance_expression = '{<G-Major: i> D:4 D:5 ib:4 sa f qG <:v> qF#:4 F#:5 iB:4 sC:5 D i@F# sF# <:iii> ' \ 'sE D C B:4 C:5 B:4 G B <:V> hC:5}' lge = LineGrammarExecutor() replacement_instance_line, replacement_instance_hct = lge.parse(source_instance_expression) tag_map = {0: DiatonicPitch.parse('D:5')} results, replacement_instance_hct = t_pat_sub.apply(replacement_instance_line, replacement_instance_hct, 'C:4', tag_map, t_pat_sub.target_height, 200) mc_filter = MinContourFilter(t_pat_sub.substitution_pattern.target_pattern_line, results.pitch_results) scored_filtered_results = mc_filter.scored_results print_hct(replacement_instance_hct) print_results(scored_filtered_results)
def create(source_expression, cue_pitch, flip_type=FlipType.CenterTone): lge = LineGrammarExecutor() source_line, source_hct = lge.parse(source_expression) return TChromaticReflection(source_line, source_hct, cue_pitch, flip_type)
def test_hct_rebuild_imperfect_overlap(self): print('----- test_hct_rebuild_imperfect_overlap -----') diatonic_tonality = Tonality.create(ModalityType.Major, DiatonicTone("D")) chord_t_i = TertianChordTemplate.parse('tI') chord_i = chord_t_i.create_chord(diatonic_tonality) chord_t_iv = TertianChordTemplate.parse('tIV') chord_iv = chord_t_iv.create_chord(diatonic_tonality) chord_t_v = TertianChordTemplate.parse('tV') chord_v = chord_t_v.create_chord(diatonic_tonality) chord_t_vi = TertianChordTemplate.parse('tVI') chord_vi = chord_t_vi.create_chord(diatonic_tonality) hc_track = HarmonicContextTrack() hc_track.append( HarmonicContext(diatonic_tonality, chord_i, Duration(1, 2))) hc_track.append( HarmonicContext(diatonic_tonality, chord_iv, Duration(1))) hc_track.append( HarmonicContext(diatonic_tonality, chord_v, Duration(1, 2))) hc_track.append( HarmonicContext(diatonic_tonality, chord_vi, Duration(1))) TestTFlip.print_hct(hc_track) line_str = '{<D-Major: I> hA:5 <:IV> B C# <:V> qD E <:VI> hF# qG A}' lge = LineGrammarExecutor() target_line, target_hct = lge.parse(line_str) TestTFlip.print_hct(target_hct) cue = DiatonicPitch(5, 'f#') tflip = TDiatonicReflection(target_line, target_hct, cue) temporal_extent = Interval(Fraction(1, 4), Fraction(9, 4)) score_line, score_hct = tflip.apply(temporal_extent, cue) TestTFlip.print_notes(score_line) TestTFlip.print_hct(score_hct) notes = score_line.get_all_notes() assert len(notes) == 8 assert str(notes[0].diatonic_pitch) == 'A:5' assert str(notes[1].diatonic_pitch) == 'C#:5' assert str(notes[2].diatonic_pitch) == 'B:5' assert str(notes[3].diatonic_pitch) == 'A:5' assert str(notes[4].diatonic_pitch) == 'G:5' assert str(notes[5].diatonic_pitch) == 'F#:5' assert str(notes[6].diatonic_pitch) == 'G:5' assert str(notes[7].diatonic_pitch) == 'A:5' hc_list = score_hct.hc_list() assert len(hc_list) == 6 assert hc_list[0].chord.chord_template.scale_degree == 1 assert {t[0].diatonic_symbol for t in hc_list[0].chord.tones} == {'D', 'F#', 'A'} assert hc_list[0].chord.chord_template.inversion == 1 assert hc_list[1].chord.chord_template.scale_degree == 1 assert {t[0].diatonic_symbol for t in hc_list[1].chord.tones} == {'D', 'F#', 'A'} assert hc_list[1].chord.chord_template.inversion == 3 assert hc_list[2].chord.chord_template.scale_degree == 5 assert {t[0].diatonic_symbol for t in hc_list[2].chord.tones} == {'E', 'A', 'C#'} assert hc_list[2].chord.chord_template.inversion == 3 assert hc_list[3].chord.chord_template.scale_degree == 4 assert {t[0].diatonic_symbol for t in hc_list[3].chord.tones} == {'D', 'G', 'B'} assert hc_list[3].chord.chord_template.inversion == 3 assert hc_list[4].chord.chord_template.scale_degree == 3 assert {t[0].diatonic_symbol for t in hc_list[4].chord.tones} == {'C#', 'F#', 'A'} assert hc_list[4].chord.chord_template.inversion == 3 assert hc_list[5].chord.chord_template.scale_degree == 6 assert {t[0].diatonic_symbol for t in hc_list[5].chord.tones} == {'B', 'D', 'F#'} assert hc_list[5].chord.chord_template.inversion == 1