def test_inversion_pattern(self): ctxt = 'CMaj+9@(9)' template = TertianChordTemplate.parse(ctxt) if template: print('succeeded') chord = template.create_chord() print(chord) else: print("failed") # Another way to do the same from tonalmodel.interval import Interval, IntervalType from tonalmodel.diatonic_tone_cache import DiatonicToneCache template = TertianChordTemplate(DiatonicToneCache.get_cache().get_tone('C'), None, TertianChordType.to_type('Maj'), [Interval(9, IntervalType.Major)], None, Interval(9, IntervalType.Major)) chord = template.create_chord() print(chord) # reuse template = TertianChordTemplate.parse('IVMin') diatonic_tonality = Tonality.create(ModalityType.Major, DiatonicToneCache.get_cache().get_tone("Db")) chord = template.create_chord(diatonic_tonality) print(chord) diatonic_tonality = Tonality.create(ModalityType.Major, DiatonicToneCache.get_cache().get_tone("F")) chord = template.create_chord(diatonic_tonality) print(chord) diatonic_tonality = Tonality.create(ModalityType.HarmonicMinor, DiatonicToneCache.get_cache().get_tone("C")) chord = template.create_chord(diatonic_tonality) print(chord)
def alter_tone_by_augmentation(tone, augmentation_delta): """ Given a tone and a (int) change in augmentation, find the resulting DiatonicTone Args: tone: DiatonicTone augmentation_delta: (int) amount of change in augmentation. Returns: DiatonicTone for the altered tone. """ from tonalmodel.diatonic_tone_cache import DiatonicToneCache basic_symbol = tone.diatonic_letter augmentation = tone.augmentation_offset + augmentation_delta basic_symbol, augmentation = DiatonicTone.enharmonic_adjust( basic_symbol, augmentation) aug_symbol = DiatonicTone.augmentation(augmentation) return DiatonicToneCache.get_cache().get_tone(basic_symbol + aug_symbol)
class TestPitchConstraintSolver(unittest.TestCase): logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) tone_cache = DiatonicToneCache.get_cache() def setUp(self): pass def tearDown(self): pass def test_for_book_example_2(self): print('----- test for book example 2 -----') source_instance_expression = '{<A-Major:i> [sA:4 A A A] qA:4 [iA:4 A] <:iv> qA:4 [sA:4 A A A] qA:4}' target_instance_expression = '{<G-Major:i> wA:4 <:iv> wA:4}' lge = LineGrammarExecutor() source_instance_line, source_instance_hct = lge.parse( source_instance_expression) actors = source_instance_line.get_all_notes() for a in actors: print("{0}".format(a)) target_instance_line, target_instance_hct = lge.parse( target_instance_expression) target_hcs = target_instance_hct.hc_list() for hc in target_hcs: print("{0}".format(hc)) pitch_range = PitchRange( DiatonicPitch.parse('C:4').chromatic_distance, DiatonicPitch.parse('C:6').chromatic_distance) p_map = PMap.create(source_instance_expression, pitch_range, [('G-Major:I', Duration(3, 4)), ('G-Major:IV', Duration(3, 4))]) actors = p_map.actors policies = OrderedSet() policies.add( StepSequenceConstraint( [actors[0], actors[1], actors[2], actors[3]], [1, 1, 1])) policies.add(ChordalPitchConstraint(actors[0])) policies.add(ChordalPitchConstraint(actors[4])) policies.add(ChordalPitchConstraint(actors[8])) policies.add( StepSequenceConstraint( [actors[8], actors[9], actors[10], actors[11]], [1, -1, -1])) policies.add(EqualPitchConstraint([actors[0], actors[12]])) policies.add(EqualPitchConstraint([actors[4], actors[7]])) policies.add( RelativeDiatonicConstraint(actors[4], actors[5], Interval(3, IntervalType.Major), Interval(1, IntervalType.Perfect))) policies.add(StepSequenceConstraint([actors[5], actors[6]], [-1])) # policies.add(ChordalPitchConstraint(actors[7])) solver = PitchConstraintSolver(policies) full_results, partial_results = solver.solve(p_map) print('Results has {0} results.'.format(len(full_results))) for pm in full_results: if str(pm[actors[7]].note.diatonic_pitch) == 'D:4' and str( pm[actors[0]].note.diatonic_pitch) == 'G:4': print("{0}".format(pm)) def test_for_book_example_1(self): print('----- test for book example 1 -----') source_instance_expression = '{<C-Major:IV> [sC:5 B:4 A G] qF:4 [sA:4 B C:5 D] qD:5}' target_instance_expression = '{<G-Major:V> wA:4}' lge = LineGrammarExecutor() target_instance_line, target_instance_hct = lge.parse( target_instance_expression) target_hcs = target_instance_hct.hc_list() for hc in target_hcs: print("{0}".format(hc)) pitch_range = PitchRange.create('C:2', 'C:8') p_map = PMap.create(source_instance_expression, pitch_range, [('G-Major:V', 1)]) actors = p_map.actors for a in actors: print("{0}".format(a)) policies = set() policies.add( PitchStepConstraint(actors[0], actors[1], 1, PitchStepConstraint.Down)) policies.add( PitchStepConstraint(actors[1], actors[2], 1, PitchStepConstraint.Down)) policies.add( PitchStepConstraint(actors[2], actors[3], 1, PitchStepConstraint.Down)) policies.add( PitchStepConstraint(actors[5], actors[6], 1, PitchStepConstraint.UP)) policies.add( PitchStepConstraint(actors[6], actors[7], 1, PitchStepConstraint.UP)) policies.add( PitchStepConstraint(actors[7], actors[8], 1, PitchStepConstraint.UP)) policies.add(EqualPitchConstraint([actors[3], actors[4]])) policies.add(EqualPitchConstraint([actors[8], actors[9]])) policies.add( RelativeDiatonicConstraint(actors[4], actors[5], Interval(3, IntervalType.Major), Interval(1, IntervalType.Perfect))) policies.add( RelativeDiatonicConstraint(actors[3], actors[8], Interval(5, IntervalType.Perfect), Interval(1, IntervalType.Perfect))) policies.add(ChordalPitchConstraint(actors[4])) policies.add(ChordalPitchConstraint(actors[9])) solver = PitchConstraintSolver(policies) full_results, _ = solver.solve(p_map) print('Results has {0} results.'.format(len(full_results))) for pm in full_results: print("{0}".format(pm)) def test_for_debugging(self): logging.debug('Start test_for_debugging') p_map, policies = TestPitchConstraintSolver.generate_generic_sample( TestPitchConstraintSolver.example_2) solver = PitchConstraintSolver(policies) try: full_results, partial_results = solver.solve(p_map) if full_results is None: print("Full Results is None") else: print("Full Results is not None") if len(full_results) == 0: print("Results is empty") else: print('Results has {0} results.'.format(len(full_results))) # verify for pm in full_results: for p in policies: if not p.verify(pm.p_map): print('Policy failure: {0}'.format( type(p).__name__)) print(pm) continue for pm in full_results: print(pm) except Exception as e: print(e) # print >> sys.stderr, traceback.format_exc() traceback.print_exc() logging.debug('End test_for_debugging') example_1 = [[ ModalityType.Major, tone_cache.get_tone('C'), 'tIV', 'C:2', 'C:8' ], [ModalityType.Major, tone_cache.get_tone('G'), 'tV', 'C:2', 'C:8'], [['C:6', 'B:5', 'A:5', 'G:5'], ['e', 'e', 'e', 'e']], [[PitchStepConstraint, [0, 1], 1, PitchStepConstraint.Down], [PitchStepConstraint, [1, 2], 1, PitchStepConstraint.Down], [PitchStepConstraint, [2, 3], 1, PitchStepConstraint.Down], [PitchRangeConstraint, {3}, PitchRange.create('C:4', 'F:4')]]] example_2 = [[ ModalityType.Major, tone_cache.get_tone('C'), 'tIV', 'C:2', 'C:8' ], [ModalityType.Major, tone_cache.get_tone('G'), 'tV', 'C:2', 'C:8'], [[ 'C:5', 'B:4', 'A:4', 'G:4', 'F:4', 'A:4', 'B:4', 'C:5', 'D:5', 'D:5' ], ['s', 's', 's', 's', 'q', 's', 's', 's', 's', 'q']], [[PitchStepConstraint, [0, 1], 1, PitchStepConstraint.Down], [PitchStepConstraint, [1, 2], 1, PitchStepConstraint.Down], [PitchStepConstraint, [2, 3], 1, PitchStepConstraint.Down], [PitchStepConstraint, [5, 6], 1, PitchStepConstraint.UP], [PitchStepConstraint, [6, 7], 1, PitchStepConstraint.UP], [PitchStepConstraint, [7, 8], 1, PitchStepConstraint.UP], [EqualPitchConstraint, {3, 4}], [EqualPitchConstraint, {8, 9}], [ RelativeDiatonicConstraint, [4, 5], Interval(3, IntervalType.Major), Interval(1, IntervalType.Perfect) ], [ RelativeDiatonicConstraint, [3, 8], Interval(5, IntervalType.Perfect), Interval(1, IntervalType.Perfect) ], [ChordalPitchConstraint, [4]], [ChordalPitchConstraint, [9]]]] @staticmethod def generate_generic_sample(sample): lower_policy_context = TestPitchConstraintSolver.policy_creator( sample[1][0], sample[1][1], sample[1][2], sample[1][3], sample[0][4]) upper_notes = TestPitchConstraintSolver.create_plain_notes( sample[2][0], sample[2][1]) p_map = TestPitchConstraintSolver.create_pmap(upper_notes, lower_policy_context) policies = set() for i in range(0, len(sample[3])): spec = sample[3][i] args = [] if isinstance(spec[1], list): for j in range(0, len(spec[1])): args.append(upper_notes[spec[1][j]]) elif isinstance(spec[1], set): actors = list() for j in spec[1]: actors.append(upper_notes[j]) args.append(actors) for j in range(2, len(spec)): args.append(spec[j]) # args = [upper_notes[spec[1][0]], upper_notes[spec[1][1]], spec[2], spec[3]] policy = (spec[0])(*tuple(args)) policies.add(policy) return p_map, policies @staticmethod def generate_sample(): lower_policy_context = \ TestPitchConstraintSolver.policy_creator(ModalityType.Major, TestPitchConstraintSolver.tone_cache.get_tone('G'), 'tV', 'C:2', 'C:8') upper_notes = TestPitchConstraintSolver.create_plain_notes( ['C:6', 'B:5', 'A:5', 'G:5'], ['e', 'e', 'e', 'e']) p_map = TestPitchConstraintSolver.create_pmap(upper_notes, lower_policy_context) policies = set() for i in range(0, len(upper_notes) - 1): policies.add( PitchStepConstraint(upper_notes[i], upper_notes[i + 1], 1, PitchStepConstraint.Down)) return p_map, policies @staticmethod def create_pmap(upper_notes, lower_policy_context): p_map = OrderedDict() for s in upper_notes: lower_cn = ContextualNote(lower_policy_context) p_map[s] = lower_cn return p_map @staticmethod def create_contextual_notes(pitch_list, duration_list, policy_context): assert len(pitch_list) == len(duration_list) assert len(pitch_list) > 0 result = [] for pitch_str, duration_str in zip(pitch_list, duration_list): pitch = DiatonicPitch.parse(pitch_str) duration = TestPitchConstraintSolver.parse_duration(duration_str) note = Note(pitch, duration) cn = ContextualNote(policy_context, note) result.append(cn) return result @staticmethod def create_plain_notes(pitch_list, duration_list): assert len(pitch_list) == len(duration_list) assert len(pitch_list) > 0 result = [] for pitch_str, duration_str in zip(pitch_list, duration_list): pitch = DiatonicPitch.parse(pitch_str) duration = TestPitchConstraintSolver.parse_duration(duration_str) note = Note(pitch, duration) result.append(note) return result @staticmethod def parse_duration(txt): cap_txt = txt.upper() if cap_txt == 'W': return Duration(1) if cap_txt == 'H': return Duration(1, 2) if cap_txt == 'Q': return Duration(1, 4) if cap_txt == 'E': return Duration(1, 8) if cap_txt == 'S': return Duration(1, 16) raise Exception('Illegal duration text: {0}'.format(txt)) @staticmethod def policy_creator(modality_type, modality_tone, tertian_chord_txt, low_pitch_txt, hi_pitch_txt): diatonic_tonality = Tonality.create(modality_type, modality_tone) chord = TertianChordTemplate.parse(tertian_chord_txt).create_chord( diatonic_tonality) hc = HarmonicContext(diatonic_tonality, chord, Duration(1, 2)) pitch_range = PitchRange( DiatonicPitch.parse(low_pitch_txt).chromatic_distance, DiatonicPitch.parse(hi_pitch_txt).chromatic_distance) return PolicyContext(hc, pitch_range)