def test_secondary_chord(self):
        print('----- test_secondary_tonality -----')
        diatonic_tonality = Tonality.create(ModalityType.Major,
                                            DiatonicTone("C"))
        chort_t_i = TertianChordTemplate.parse('tI')
        chord_i = chort_t_i.create_chord(diatonic_tonality)

        chord_v_ii = SecondaryChordTemplate.parse('V/ii').create_chord(
            diatonic_tonality)
        chord_vi_v = SecondaryChordTemplate.parse('vi/V').create_chord(
            diatonic_tonality)

        chord_t_ii = TertianChordTemplate.parse('tii')
        chord_ii = chord_t_ii.create_chord(diatonic_tonality)

        hc_track = HarmonicContextTrack()
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord_i, Duration(1)))
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord_v_ii, Duration(1)))
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord_vi_v, Duration(1)))
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord_ii, Duration(1)))
        TestTFlip.print_hct(hc_track)

        tune = [('C:5', (1, 1)), ('E:5', (1, 1)), ('E:5', (1, 1)),
                ('G:5', (1, 1))]
        line = TestTFlip.build_line(tune)

        cue = DiatonicPitch(5, 'd')

        tflip = TDiatonicReflection(line, hc_track, cue)

        temporal_extent = Interval(Fraction(0), Fraction(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) == 4
        assert str(notes[0].diatonic_pitch) == 'E:5'
        assert str(notes[1].diatonic_pitch) == 'C#:5'
        assert str(notes[2].diatonic_pitch) == 'C:5'
        assert str(notes[3].diatonic_pitch) == 'A:4'

        hc_list = score_hct.hc_list()
        assert len(hc_list) == 4
        assert hc_list[1].chord.primary_chord.chord_template.scale_degree == 7
        assert {t[0].diatonic_symbol
                for t in hc_list[1].chord.tones} == {'C#', 'E', 'G'}
        assert hc_list[1].chord.primary_chord.chord_template.inversion == 3

        assert hc_list[2].chord.primary_chord.chord_template.scale_degree == 7
        assert {t[0].diatonic_symbol
                for t in hc_list[2].chord.tones} == {'C', 'F#', 'A'}
        assert hc_list[2].chord.primary_chord.chord_template.inversion == 3
Esempio n. 2
0
    def find_tertian_chords(self):
        results = list()
        for chord_type, interval_list in TertianChordTemplate.TERTIAN_CHORD_TYPE_MAP.items(
        ):
            chord_tones = list()
            for interval in interval_list:
                chord_tones.append(interval.get_end_tone(self.root_tone))
            if set(chord_tones) <= set(self.chord_tones):
                if self.chord_tones[0] not in chord_tones:
                    continue
                ct = TertianChordType(chord_type)
                results.append((ct, chord_tones))

        results.sort(key=lambda x: len(x[1]), reverse=True)
        rr = [x for x in results if len(x[1]) == len(results[0][1])]
        chords = list()
        if len(rr):
            for answer in rr:
                # inversion computed - must be a chordal tone
                # if self.chord_tones[0] not in answer[1]:
                #    raise Exception('Inversion tone \'{0}\' must be a chord tone in [{1}]'.format(
                #        self.chord_tones[0], ', '.join(v.diatonic_symbol for v in answer[1])))
                inversion = answer[1].index(self.chord_tones[0]) + 1
                tensions = list()
                remainder = set(self.chord_tones) - set(answer[1])
                for r in remainder:
                    p1 = DiatonicPitch(4, self.root_tone)
                    p2 = DiatonicPitch(
                        5 if DiatonicPitch.crosses_c(self.root_tone, r) else 4,
                        r)
                    interval = Interval.create_interval(p1, p2)
                    if interval.diatonic_distance < 5:  # We don't want M:13 nor M:14
                        interval = Interval(interval.diatonic_distance + 8,
                                            interval.interval_type)
                    tensions.append(interval)

                if self.tonality is not None:
                    index = self.tonality.annotation.index(self.root_tone) \
                        if self.root_tone in self.tonality.annotation else None
                    if index is None:
                        continue
                        # raise Exception('Root tone {0} is not in tonality {1}'.format(self.root_tone, self.tonality))
                    template = TertianChordTemplate(None, index + 1, answer[0],
                                                    tensions, inversion)
                else:
                    template = TertianChordTemplate(self.root_tone, None,
                                                    answer[0], tensions,
                                                    inversion)
                chords.append(TertianChord(template, self.tonality))

        return chords
Esempio n. 3
0
    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)
Esempio n. 4
0
    def rebuild_secondary_chord(self, secondary_chord, base_tonality):
        if self.secondary_shift_type == SecondaryShiftType.Standard:
            orig_principal_chord_template = secondary_chord.chord_template.principal_chord_template
            if not isinstance(orig_principal_chord_template, TertianChordTemplate):
                raise Exception('Secondary chord requires TertianChordTemplate for this operation.')
            new_scale_degree = ((orig_principal_chord_template.scale_degree - 1) + self.step_increment) % 7 + 1
            new_principal_chord_template = TertianChordTemplate(orig_principal_chord_template.diatonic_basis,
                                                                new_scale_degree,
                                                                orig_principal_chord_template.chord_type,
                                                                orig_principal_chord_template.tension_intervals,
                                                                orig_principal_chord_template.inversion,
                                                                orig_principal_chord_template.inversion_interval)

            secondary_chord_template = SecondaryChordTemplate(new_principal_chord_template,
                                                              secondary_chord.chord_template.secondary_scale_degree,
                                                              secondary_chord.chord_template.secondary_modality)
            new_secondary_chord = SecondaryChord(secondary_chord_template, base_tonality)
            return new_secondary_chord
        else:
            orig_template = secondary_chord.chord_template
            new_degree = ((orig_template.secondary_scale_degree - 1) + self.step_increment) % 7 + 1
            secondary_chord_template = SecondaryChordTemplate(orig_template.principal_chord_template,
                                                              new_degree,
                                                              orig_template.secondary_modality)
            new_secondary_chord = SecondaryChord(secondary_chord_template, base_tonality)
            return new_secondary_chord
Esempio n. 5
0
    def __create_chord_on_diatonic_without_type(self, diatonic_tone):
        from tonalmodel.tonality import Tonality
        from tonalmodel.modality import ModalityType
        from harmonicmodel.tertian_chord_template import TertianChordTemplate
        diatonic_tonality = Tonality.create(ModalityType.Major, diatonic_tone)
        tone_scale = diatonic_tonality.annotation

        self.chord_basis = []
        base_tone = None
        for i in range(0, 3):
            tone = tone_scale[(2 * i) % (len(tone_scale) - 1)]
            if i == 0:
                base_tone = tone

            pitch_a = DiatonicPitch(1, diatonic_tone)
            b_octave = 2 if base_tone.diatonic_index > tone.diatonic_index else 1
            pitch_b = DiatonicPitch(b_octave, tone.diatonic_symbol)
            interval = Interval.create_interval(pitch_a, pitch_b)
            self.chord_basis.append(interval)

            self.__tones.append((tone, interval))
        self.__set_inversion()

        self.__chord_type = TertianChordTemplate.get_chord_type(
            self.chord_basis)
    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)
Esempio n. 7
0
 def test_triad_generation(self):
     diatonic_tonality = Tonality.create(ModalityType.Major, DiatonicTone("C"))
     ret_types = [TertianChordType.Maj, TertianChordType.Min, TertianChordType.Min, TertianChordType.Maj,
                  TertianChordType.Maj,
                  TertianChordType.Min, TertianChordType.Dim]
     for i in range(1, 8):
         chord = TertianChordTemplate.get_triad(diatonic_tonality, i)       
         print(chord)
         assert chord.chord_type.value == ret_types[i - 1]
Esempio n. 8
0
 def test_chord_parse(self):
     ltrs = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII']
     diatonic_tonality = Tonality.create(ModalityType.Major, DiatonicTone("C"))
     i = 1
     for t in ltrs:
         chord_t = TertianChordTemplate.parse('t' + t)
         assert chord_t.scale_degree == i, '{0} vs {1}'.format(chord_t.scale_degree, i)
         
         chord = chord_t.create_chord(diatonic_tonality)
         tones = chord.tones
         print('{0} {1}'.format(', '.join(tone[0].diatonic_symbol for tone in tones), chord.chord_type))
         
         i += 1
         
     ltrs = ['i', 'ii', 'iii', 'iv', 'v', 'vi', 'vii']
     i = 1
     for t in ltrs:
         chord_t = TertianChordTemplate.parse('T' + t)
         assert chord_t.scale_degree == i, '{0} vs {1}'.format(chord_t.scale_degree, i)
         
         chord = chord_t.create_chord(diatonic_tonality)
         tones = chord.tones
         print('{0} {1}'.format(', '.join(tone[0].diatonic_symbol for tone in tones), chord.chord_type))
         
         i += 1
         
     tones = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'ab', 'bb', 'cb', 'db', 'eb', 'fb', 'gb', 'a#', 'b#', 'c#', 'd#',
              'e#', 'f#', 'g#']
     for t in tones:
         chord_t = TertianChordTemplate.parse(t)
         print(chord_t)
         tone = chord_t.diatonic_basis
         cap_t = t[0:1].upper() + (t[1:2] if len(t) == 2 else '')
         assert cap_t == tone.diatonic_symbol
         
     torsions = ['+9+b11', '+2', '+b2', '+#2']
     for t in torsions:
         template = TertianChordTemplate.parse('TIII' + t)
         print(template)
         
     template = TertianChordTemplate.parse('IVMaj7+b9@3')
     assert template
     print(template)
     assert template.inversion == 3
Esempio n. 9
0
    def test_basic_setup(self):
        c = InstrumentCatalog.instance()
        violin = c.get_instrument("violin")

        # Add notes to the score
        vnote0 = Note(DiatonicPitch(4, 'a'), Duration(1, 8))
        vnote1 = Note(DiatonicPitch(4, 'b'), Duration(1, 8))
        vnote2 = Note(DiatonicPitch(4, 'c'), Duration(1, 8))
        vnote3 = Note(DiatonicPitch(4, 'd'), Duration(1, 8))
        vnote4 = Note(DiatonicPitch(4, 'e'), Duration(1, 8))
        vnote5 = Note(DiatonicPitch(4, 'f'), Duration(1, 8))

        # Set up a violin voice with 6 8th notes
        vline = Line([vnote0, vnote1, vnote2, vnote3, vnote4, vnote5])

        tempo_seq = TempoEventSequence()
        ts_seq = EventSequence()
        tempo_seq.add(TempoEvent(Tempo(60), Position(0)))
        ts_seq.add(
            TimeSignatureEvent(TimeSignature(3, Duration(1, 4), 'sww'),
                               Position(0)))

        hc_track = HarmonicContextTrack()
        diatonic_tonality = Tonality.create(ModalityType.Major,
                                            DiatonicTone("C"))
        chord_t = TertianChordTemplate.parse('tIV')
        chord = chord_t.create_chord(diatonic_tonality)
        hc_track.append(HarmonicContext(diatonic_tonality, chord, Duration(2)))

        score = LiteScore(vline, hc_track, violin, tempo_seq, ts_seq)

        bp = score.beat_position(Position(0))
        print(bp)
        assert bp.beat_number == 0

        bp = score.beat_position(Position(5, 8))
        print(bp)
        assert bp.measure_number == 0
        assert bp.beat_number == Fraction(5, 2)
        assert int(bp.beat_number) == 2
        assert bp.beat_number - bp.beat == Fraction(1, 2)

        tse = score.time_signature_sequence.floor_event(Position(5, 8))
        assert tse is not None
        print(tse.object.beat_type(bp.beat))
        assert tse.object.beat_type(bp.beat) == BeatType.Weak
        assert bp.beat_fraction == Fraction(1, 2)

        bp = score.beat_position(Position(1, 16))
        print(bp)
        tse = score.time_signature_sequence.floor_event(Position(1, 16))
        print(tse.object.beat_type(bp.beat))
        assert tse.object.beat_type(bp.beat) == BeatType.Strong
Esempio n. 10
0
 def test_duplicate(self):
     diatonic_tonality = Tonality.create(ModalityType.Major, DiatonicTone("Db"))
     template = TertianChordTemplate.parse('DbDom7+8')
     chord = template.create_chord(diatonic_tonality)
     print(chord)
     
     tones = chord.tones
     print(', '.join(tone[0].diatonic_symbol for tone in tones))
     assert TestTertianTemplateChord.verify(tones,
                                            ['Db', 'F', 'Ab', 'Cb', 'Db']), 'Fail #{0}, {1}'.format(
         'DbDom7+8', ', '.join(tone[0].diatonic_symbol for tone in tones))
     
     template = TertianChordTemplate.parse('DbDom7+8@4')
     chord = template.create_chord(diatonic_tonality)
     tones = chord.tones
     print(', '.join(tone[0].diatonic_symbol for tone in tones))
     assert TestTertianTemplateChord.verify(tones, ['Cb', 'Db', 'F', 'Ab', 'Db']), \
         'Fail #{0}, {1}'.format('DbDom7+8', ', '.join(tone[0].diatonic_symbol for tone in tones))
     
     tones = chord.sorted_tones()
     print(', '.join(tone[0].diatonic_symbol for tone in tones))
     assert TestTertianTemplateChord.verify(tones, ['Db', 'F', 'Ab', 'Cb', 'Db']), \
         'Fail #{0}, {1}'.format('DbDom7+8', ', '.join(tone[0].diatonic_symbol for tone in tones))
    def test_secondary_chord(self):
        print('----- test_secondary_tonality -----')
        diatonic_tonality = Tonality.create(ModalityType.Major,
                                            DiatonicFoundation.get_tone("C"))
        chort_t_i = TertianChordTemplate.parse('tI')
        chord_i = chort_t_i.create_chord(diatonic_tonality)

        chord_v_ii = SecondaryChordTemplate.parse('V/ii').create_chord(
            diatonic_tonality)
        chord_vi_v = SecondaryChordTemplate.parse('vi/V').create_chord(
            diatonic_tonality)

        chord_t_ii = TertianChordTemplate.parse('tii')
        chord_ii = chord_t_ii.create_chord(diatonic_tonality)

        hc_track = HarmonicContextTrack()
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord_i, Duration(1)))
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord_v_ii, Duration(1)))
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord_vi_v, Duration(1)))
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord_ii, Duration(1)))
        TestTChromaticFlip.print_hct(hc_track)

        tune = [('C:5', (1, 1)), ('E:5', (1, 1)), ('E:5', (1, 1)),
                ('G:5', (1, 1))]
        line = TestTChromaticFlip.build_line(tune)

        cue = DiatonicPitch(5, 'd')

        tflip = TChromaticReflection(line, hc_track, cue)

        score_line, score_hct = tflip.apply()
        TestTChromaticFlip.print_notes(score_line)
        TestTChromaticFlip.print_hct(score_hct)
    def test_append(self):
        diatonic_tonality = Tonality.create(ModalityType.Major,
                                            DiatonicTone("C"))
        chord_t = TertianChordTemplate.parse('tIV')
        chord1 = chord_t.create_chord(diatonic_tonality)
        chord_t = TertianChordTemplate.parse('tV')
        chord2 = chord_t.create_chord(diatonic_tonality)
        chord_t = TertianChordTemplate.parse('tVI')
        chord3 = chord_t.create_chord(diatonic_tonality)

        hc_track = HarmonicContextTrack()
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord1, Duration(1, 2)))
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord2, Duration(1, 4)))
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord3, Duration(1, 3)))

        assert len(hc_track) == 3
        assert hc_track[Position(0)].duration == Duration(1, 2)
        assert hc_track[Position(1, 2)].duration == Duration(1, 4)
        assert hc_track[Position(3, 4)].duration == Duration(1, 3)

        print(hc_track)
Esempio n. 13
0
 def test_inversion(self):
     ctype = 'ADom7'
     chords = {1: ['A', 'C#', 'E', 'G'],
               2: ['C#', 'A', 'E', 'G'],
               3: ['E', 'A', 'C#', 'G'],
               4: ['G', 'A', 'C#', 'E']}
     diatonic_tonality = Tonality.create(ModalityType.Major, DiatonicTone("C"))
     
     for i in range(1, 5):
         template = TertianChordTemplate.parse(ctype + '@' + str(i))
         chord = template.create_chord(diatonic_tonality)
         
         tones = chord.tones
         print(', '.join(tone[0].diatonic_symbol for tone in tones))
         assert TestTertianTemplateChord.verify(tones, chords[i]), \
             'Fail #{0}, {1}'.format(ctype + '@' + str(i), ', '.join(tone[0].diatonic_symbol for tone in tones))
Esempio n. 14
0
    def __init__(self,
                 secondary_chord_template,
                 diatonic_tonality,
                 secondary_tonality=None):
        """
        Constructor.
        :param secondary_chord_template: SecondaryChordTemplate
        :param diatonic_tonality: DiatonicTonality (used in scale degree chord formation)
        :param secondary_tonality: Used to represent denominator tonality
        Note: The means for determining the secondary tonality is not necessarily clean. The standard technique
        involves inferring the modality from the triad built on the i-th tone of the base modality. However,
        the actual technique to be used can be a variable. The secondary_tonality argument is meant for cases where
        the standard technique does not hold up - and provides a means for specifying the exact secondary tonality
        when the standard technique does not apply.
        """
        Chord.__init__(self, secondary_chord_template, diatonic_tonality)

        # Build the tonality upon which the primary chord is based
        diatonic_basis = self.diatonic_tonality.get_tone(
            self.chord_template.secondary_scale_degree - 1)

        # if no secondary modality specified?
        #  Use diatonic_tonality + secondary scale degree.  Determine the triad type of the natural triad there, and
        #  if major, use major modality.  If minor, use melodic minor modality.  Otherwise flag an error.
        if not self.chord_template.secondary_modality:
            triad = TertianChordTemplate.get_triad(
                diatonic_tonality, self.chord_template.secondary_scale_degree)
            if triad:
                modality = ModalityType.Major if triad.chord_type.value == TertianChordType.Maj or \
                                                 triad.chord_type.value == TertianChordType.Aug else \
                           ModalityType.MelodicMinor if triad.chord_type.value == TertianChordType.Min or \
                                                 triad.chord_type.value == TertianChordType.Dim else None
                if modality is None:
                    raise Exception(
                        'Illegal secondary modality for secondary chord')
            else:
                raise Exception(
                    'Cannot determine secondary modality for secondary chord')
        else:
            modality = self.chord_template.secondary_modality

        self.__secondary_tonality = Tonality.create(modality, diatonic_basis) \
            if not secondary_tonality else secondary_tonality

        # Create the principal chord
        self.__primary_chord = self.chord_template.principal_chord_template.create_chord(
            self.secondary_tonality)
    def test_append_first(self):
        diatonic_tonality = Tonality.create(ModalityType.Major,
                                            DiatonicTone("C"))
        chord_t = TertianChordTemplate.parse('tIV')
        chord = chord_t.create_chord(diatonic_tonality)

        hc_track = HarmonicContextTrack()
        hc_track.append_first(
            HarmonicContext(diatonic_tonality, chord, Duration(1, 2)))
        hc_track.append_first(
            HarmonicContext(diatonic_tonality, chord, Duration(1, 4)))
        hc_track.append_first(
            HarmonicContext(diatonic_tonality, chord, Duration(1, 3)))

        assert len(hc_track) == 3
        assert hc_track[Position(0)].duration == Duration(1, 3)
        assert hc_track[Position(1, 3)].duration == Duration(1, 4)
        assert hc_track[Position(7, 12)].duration == Duration(1, 2)
Esempio n. 16
0
def build_vst_midi_list():
    """

    :return:
    """
    c = InstrumentCatalog.instance()

    # Add notes to the score
    vnote0 = Note(DiatonicPitch(4, 'a'), Duration(1, 8))
    vnote1 = Note(DiatonicPitch(4, 'b'), Duration(1, 8))
    vnote2 = Note(DiatonicPitch(4, 'c'), Duration(1, 8))
    vnote3 = Note(DiatonicPitch(4, 'd'), Duration(1, 8))
    vnote4 = Note(DiatonicPitch(4, 'e'), Duration(1, 8))
    vnote5 = Note(DiatonicPitch(4, 'f'), Duration(1, 8))

    # Set up a violin voice with 6 8th notes
    vline = Line([vnote0, vnote1, vnote2, vnote3, vnote4, vnote5])

    tempo_seq = TempoEventSequence()
    ts_seq = EventSequence()
    tempo_seq.add(TempoEvent(Tempo(60), Position(0)))
    ts_seq.add(
        TimeSignatureEvent(TimeSignature(3, Duration(1, 4), 'sww'),
                           Position(0)))

    hc_track = HarmonicContextTrack()
    diatonic_tonality = Tonality.create(ModalityType.Major, DiatonicTone("C"))
    chord_t = TertianChordTemplate.parse('tIV')
    chord = chord_t.create_chord(diatonic_tonality)
    hc_track.append(HarmonicContext(diatonic_tonality, chord, Duration(2)))

    score = Score()

    score.tempo_sequence.add(TempoEvent(Tempo(60), Position(0)))
    score.time_signature_sequence.add(
        TimeSignatureEvent(TimeSignature(3, Duration(1, 4)), Position(0)))

    violin = c.get_instrument("violin")
    violin_instrument_voice = InstrumentVoice(violin, 1)
    score.add_instrument_voice(violin_instrument_voice)
    violin_instrument_voice.voice(0).pin(vline)

    return ScoreToVstMidiConverter.convert_score(score, {0: 0}), score
Esempio n. 17
0
    def test_stationary_diatonic_tone_chords(self):
        ltr = 'A'
        answers = {'Maj': ['A', 'C#', 'E'],
                   'MajSus2': ['A', 'B', 'E'],
                   'MajSus4': ['A', 'D', 'E'],
                   'MajSus': ['A', 'D', 'E'],
                   'Min': ['A', 'C', 'E'],
                   'Dim': ['A', 'C', 'Eb'],
                   'Aug': ['A', 'C#', 'E#'],
                   'Maj7': ['A', 'C#', 'E', 'G#'],
                   'Maj7Sus2': ['A', 'B', 'E', 'G#'],
                   'Maj7Sus4': ['A', 'D', 'E', 'G#'],
                   'Maj7Sus': ['A', 'D', 'E', 'G#'],
                   'Min7': ['A', 'C', 'E', 'G'],
                   'Dom7': ['A', 'C#', 'E', 'G'],
                   'Dom7Sus2': ['A', 'B', 'E', 'G'],
                   'Dom7Sus4': ['A', 'D', 'E', 'G'],
                   'Dom7Sus': ['A', 'D', 'E', 'G'],
                   'Dim7': ['A', 'C', 'Eb', 'Gb'],
                   'HalfDim7': ['A', 'C', 'Eb', 'G'],
                   'MinMaj7': ['A', 'C', 'E', 'G#'],
                   'AugMaj7': ['A', 'C#', 'E#', 'G#'],
                   'Aug7': ['A', 'C#', 'E#', 'G'],
                   'DimMaj7': ['A', 'C', 'Eb', 'G#'],
                   'Dom7Flat5': ['A', 'C#', 'Eb', 'G'],
                   'Maj6': ['A', 'C#', 'E', 'F#'],
                   'Min6': ['A', 'C', 'E', 'F#'],
                   'Fr': ['F##', 'A', 'B', 'D#'],
                   'Ger': ['F##', 'A', 'C', 'D#'],
                   'It': ['F', 'A', 'D#'],
                   'N6': ['F', 'Bb', 'D'],
                   }
        diatonic_tonality = Tonality.create(ModalityType.Major, DiatonicTone("C"))
 
        for ctype, value in list(answers.items()):
            template = TertianChordTemplate.parse(ltr + ctype)
            chord = template.create_chord(diatonic_tonality)
        
            tones = chord.tones
            print(', '.join(tone[0].diatonic_symbol for tone in tones))
            assert TestTertianTemplateChord.verify(tones, value), 'Fail #{0}, {1}'.format(
                ctype, ', '.join(tone[0].diatonic_symbol for tone in tones))
    def test_remove(self):
        diatonic_tonality = Tonality.create(ModalityType.Major,
                                            DiatonicTone("C"))
        chord_t = TertianChordTemplate.parse('tIV')
        chord = chord_t.create_chord(diatonic_tonality)

        hc_track = HarmonicContextTrack()
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord, Duration(1, 2)))
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord, Duration(1, 4)))
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord, Duration(1, 3)))

        remove_item = hc_track[Position(1, 2)]
        hc_track.remove(remove_item)

        assert len(hc_track) == 2
        assert hc_track[Position(0)].duration == Duration(1, 2)
        assert hc_track[Position(1, 2)].duration == Duration(1, 3)
Esempio n. 19
0
 def test_tensions(self):
     c_type = 'DbDom7'
     
     answers = {'+9': ['Db', 'F', 'Ab', 'Cb', 'Eb'],
                '+b9': ['Db', 'F', 'Ab', 'Cb', 'Ebb'],
                '+#9': ['Db', 'F', 'Ab', 'Cb', 'E'],
                '+bb9': ['Db', 'F', 'Ab', 'Cb', 'Ebbb'],
                '+9+11+13': ['Db', 'F', 'Ab', 'Cb', 'Eb', 'Gb', 'Bb'],
                '+b9+#13': ['Db', 'F', 'Ab', 'Cb', 'Ebb', 'B'],
                '+6': ['Db', 'F', 'Ab', 'Cb', 'Bb'],
                '+8': ['Db', 'F', 'Ab', 'Cb', 'Db'],
                }
     
     diatonic_tonality = Tonality.create(ModalityType.Major, DiatonicTone("Db"))
     for t, value in list(answers.items()):
         template = TertianChordTemplate.parse(c_type + t)
         chord = template.create_chord(diatonic_tonality)
     
         tones = chord.tones
         print(', '.join(tone[0].diatonic_symbol for tone in tones))
         assert TestTertianTemplateChord.verify(tones, value), \
             'Fail #{0}, {1}'.format(c_type + '+' + t, ', '.join(tone[0].diatonic_symbol for tone in tones))
Esempio n. 20
0
    def __create_chord_on_scale_degree(self):
        from harmonicmodel.tertian_chord_template import TertianChordTemplate
        root_index = self.chord_template.scale_degree - 1
        tone_scale = self.diatonic_tonality.annotation

        self.chord_basis = []
        base_tone = None
        for i in range(0, 3):
            tone = tone_scale[(root_index + 2 * i) % (len(tone_scale) - 1)]
            if i == 0:
                base_tone = tone

            pitch_a = DiatonicPitch(1, tone_scale[root_index].diatonic_symbol)
            b_octave = 2 if base_tone.diatonic_index > tone.diatonic_index else 1
            pitch_b = DiatonicPitch(b_octave, tone.diatonic_symbol)
            interval = Interval.create_interval(pitch_a, pitch_b)
            self.chord_basis.append(interval)

            self.__tones.append((tone, interval))
        self.__set_inversion()

        self.__chord_type = TertianChordTemplate.get_chord_type(
            self.chord_basis)
    def test_replace(self):
        diatonic_tonality = Tonality.create(ModalityType.Major,
                                            DiatonicTone("C"))
        chord_t = TertianChordTemplate.parse('tIV')
        chord = chord_t.create_chord(diatonic_tonality)

        hc_track = HarmonicContextTrack()
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord, Duration(1, 2)))
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord, Duration(1, 4)))
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord, Duration(1, 3)))

        hc_track.replace(
            Position(1, 2),
            HarmonicContext(diatonic_tonality, chord, Duration(1, 8)))

        assert len(hc_track) == 3
        assert hc_track.duration == Duration(23, 24)  # 1/2 + 1/8 + 1/3
        assert hc_track[Position(0)].duration == Duration(1, 2)
        assert hc_track[Position(1, 2)].duration == Duration(1, 8)
        assert hc_track[Position(5, 8)].duration == Duration(1, 3)
Esempio n. 22
0
    def generic_chord_template_parse(chord_txt):
        """
        Generic text parse into chord template.
        
        Args:
          chord_txt: String
        Returns:
          ChordTemplate or None if fails.
        """

        #  Try parsing chord text through known chord templates.
        #  If all fail, just return None.
        from harmonicmodel.secondary_chord_template import SecondaryChordTemplate, SecondaryChordException
        try:
            chord_template = SecondaryChordTemplate.parse(chord_txt)
            return chord_template
        except SecondaryChordException:
            pass
        from harmonicmodel.tertian_chord_template import TertianChordTemplate, TertianChordException
        try:
            chord_template = TertianChordTemplate.parse(chord_txt)
            return chord_template
        except TertianChordException:
            pass
        from harmonicmodel.secundal_chord_template import SecundalChordTemplate, SecundalChordException
        try:
            chord_template = SecundalChordTemplate.parse(chord_txt)
            return chord_template
        except SecundalChordException:
            pass
        from harmonicmodel.quartal_chord_template import QuartalChordTemplate
        try:
            chord_template = QuartalChordTemplate.parse(chord_txt)
            return chord_template
        except QuartalChordTemplate:
            return None     
Esempio n. 23
0
    def test_book_examples(self):
        template = TertianChordTemplate.parse('CN6')
        if template:
            print('succeeded')
            chord = template.create_chord()
            print(chord)
        else:
            print("failed")

        diatonic_tonality = Tonality.create(ModalityType.Major, DiatonicTone("F"))
        template = TertianChordTemplate.parse('IVDom7@2')
        chord = template.create_chord(diatonic_tonality)
        print(chord)

        template = TertianChordTemplate.parse('EbDimMaj7+9')
        chord = template.create_chord()
        print(chord)

        template = TertianChordTemplate.parse('EbDimMaj7+9@(9)')
        chord = template.create_chord()
        print(chord)

        template = TertianChordTemplate.parse('C')
        chord = template.create_chord()
        print(chord)

        template = TertianChordTemplate.parse('VI')
        chord = template.create_chord(diatonic_tonality)
        print(chord)

        # Create a template for CMajM9, with the M9 as root
        template = TertianChordTemplate.parse('CMaj+9@(9)')
        if template:
            print('succeeded')
            chord = template.create_chord()
            print(chord)  # CMajM:9@(M:9) [D, C, E, G]
    def test_simple_setup(self):
        print('--- test_simple_setup')

        line = Line()

        notes = [
            Note(DiatonicPitch.parse('a:4'), Duration(1, 4)),
            Note(DiatonicPitch.parse('b:4'), Duration(1, 4)),
            Note(DiatonicPitch.parse('c:4'), Duration(1, 4)),
            Note(DiatonicPitch.parse('d:4'), Duration(1, 4)),
            Note(DiatonicPitch.parse('e:4'), Duration(1, 2)),
            Note(DiatonicPitch.parse('f:4'), Duration(1, 2)),
        ]

        location = 0
        for note in notes:
            line.pin(note, Offset(location))
            location += note.duration.duration

        tempo_seq = TempoEventSequence()
        ts_seq = EventSequence()
        tempo_seq.add(TempoEvent(Tempo(60, Duration(1, 4)), Position(0)))
        ts_seq.add(
            TimeSignatureEvent(TimeSignature(3, Duration(1, 4), 'sww'),
                               Position(0)))

        diatonic_tonality = Tonality.create(ModalityType.Major,
                                            DiatonicTone("C"))
        chord_t = TertianChordTemplate.parse('tIV')
        chord = chord_t.create_chord(diatonic_tonality)

        hc_track = HarmonicContextTrack()
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord, Duration(1, 1)))
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord, Duration(1, 2)))
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord, Duration(1, 2)))

        c = InstrumentCatalog.instance()
        violin = c.get_instrument("violin")

        score = LiteScore(line, hc_track, violin, tempo_seq, ts_seq)

        constraints = [
            OnBeatConstraint(notes[1], BeatType.Strong),
            StepSequenceConstraint(notes, [1, 1, 1, -1, -1])
        ]

        solver = MelodicConstraintSolver.create(score, constraints)

        cheat = {notes[2]: DiatonicPitch.parse('E:5')}

        results = solver.solve(cheat)
        assert results is not None
        assert results.beat_results is not None
        assert results.pitch_results is not None

        print(len(results.beat_results))
        print(len(results.pitch_results))
        assert 1 == len(results.beat_results)
        assert 1 == len(results.pitch_results)

        new_line = results.apply(next(iter(results.beat_results)),
                                 next(iter(results.pitch_results)))
        assert new_line is not None

        print(new_line)
        all_notes = new_line.get_all_notes()
        assert 'C:5' == str(all_notes[0].diatonic_pitch)
        assert 'D:5' == str(all_notes[1].diatonic_pitch)
        assert 'E:5' == str(all_notes[2].diatonic_pitch)
        assert 'F:5' == str(all_notes[3].diatonic_pitch)
        assert 'E:5' == str(all_notes[4].diatonic_pitch)
        assert 'D:5' == str(all_notes[5].diatonic_pitch)

        assert Position(3, 4) == all_notes[1].get_absolute_position()
    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
    def test_mozart(self):
        print('----- Mozart -----')
        diatonic_tonality = Tonality.create(ModalityType.Major,
                                            DiatonicTone("C"))
        chort_t_i = TertianChordTemplate.parse('tI')
        chord_i = chort_t_i.create_chord(diatonic_tonality)

        chort_t_v = TertianChordTemplate.parse('tVMaj7')
        chord_v = chort_t_v.create_chord(diatonic_tonality)

        chord_t_i_1 = TertianChordTemplate.parse('tI')
        chord_i_1 = chord_t_i_1.create_chord(diatonic_tonality)

        hc_track = HarmonicContextTrack()
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord_i, Duration(1)))
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord_v, Duration(1, 2)))
        hc_track.append(
            HarmonicContext(diatonic_tonality, chord_i_1, Duration(1, 2)))
        TestTFlip.print_hct(hc_track)

        tune = [('C:5', (1, 2)), ('E:5', (1, 4)), ('G:5', (1, 4)),
                ('B:4', (3, 8)), ('C:5', (1, 16)), ('D:5', (1, 16)),
                ('C:5', (1, 4))]
        line = TestTFlip.build_line(tune)

        cue = DiatonicPitch(5, 'd')

        tflip = TDiatonicReflection(line, hc_track, cue)

        temporal_extent = Interval(Fraction(0), Fraction(2))
        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) == 7
        assert str(notes[0].diatonic_pitch) == 'E:5'
        assert str(notes[1].diatonic_pitch) == 'C:5'
        assert str(notes[2].diatonic_pitch) == 'A:4'
        assert str(notes[3].diatonic_pitch) == 'F:5'
        assert str(notes[4].diatonic_pitch) == 'E:5'
        assert str(notes[5].diatonic_pitch) == 'D:5'
        assert str(notes[6].diatonic_pitch) == 'E:5'

        hc_list = score_hct.hc_list()
        assert len(hc_list) == 3
        assert hc_list[0].chord.chord_template.scale_degree == 6
        assert {t[0].diatonic_symbol
                for t in hc_list[0].chord.tones} == {'E', 'A', 'C'}
        assert hc_list[0].chord.chord_template.inversion == 3

        assert hc_list[1].chord.chord_template.scale_degree == 2
        assert {t[0].diatonic_symbol
                for t in hc_list[1].chord.tones} == {'A', 'D', 'F', 'Bb'}
        assert hc_list[1].chord.chord_template.inversion == 3

        assert hc_list[2].chord.chord_template.scale_degree == 6
        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