示例#1
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
    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
示例#3
0
    def remap_chord(self, hc):
        from tonalmodel.interval import Interval as TonalInterval
        chord = hc.chord

        if not isinstance(chord, SecondaryChord):
            f = self.__hc_flip_map[hc] if hc in self.__hc_flip_map.keys() else \
                ChromaticPitchReflectionFunction(hc.tonality, self.cue_pitch, self.domain_pitch_range)
            # FlipOnTonality(hc.tonality, self.cue_pitch, self.domain_pitch_range)
            new_chord_tones = [f.tonal_function[t[0]] for t in chord.tones]
            chords = ChordClassifier.classify_all_roots(
                new_chord_tones, f.range_tonality)
            if chords is not None and len(chords) > 0:
                return chords[0]
            else:
                raise Exception(
                    'Cannot remap/classify chord {0} based on chord.'.format(
                        ', '.join(
                            str(t.diatonic_symbol) for t in new_chord_tones)))
        else:
            if hc in self.__hc_flip_map.keys():
                secondary_function = self.__hc_flip_map[hc].tonal_function
            else:
                secondary_function = self._build_secondary_flip_function(
                    hc).tonal_function

            base_f = self._build_chromatic_reflection(hc)
            root_mapped_tonality = base_f.range_tonality
            mapped_denominator = TonalInterval.calculate_tone_interval(
                root_mapped_tonality.root_tone, secondary_function.
                range_tonality.root_tone).diatonic_distance + 1

            # Alternatively, in the else part, we could have done:
            #   secondary_function = f.tonal_function.create_adapted_function(secondary_tonality, secondary_tonality)
            # but to be consistent within the logic, we go for the reflection_tests constructiobn of
            # the secondary function
            # as embodied in tFlip._build_secondary_flip_function()

            new_chord_tones = [secondary_function[t[0]] for t in chord.tones]
            secondary_tonality = secondary_function.range_tonality
            chords = ChordClassifier.classify_all_roots(
                new_chord_tones, secondary_tonality)

            if chords is not None and len(chords) > 0:
                new_chord = chords[0]
            else:
                raise Exception(
                    'Cannot remap/classify chord {0} based on chord.'.format(
                        ', '.join(
                            str(t.diatonic_symbol) for t in new_chord_tones)))

            # mapped_numerator = TonalInterval.calculate_tone_interval(
            #    new_chord.root_tone,
            #    secondary_function.range_tonality.root_tone).diatonic_distance + 1
            secondary_chord_template = SecondaryChordTemplate(
                new_chord.chord_template, mapped_denominator,
                secondary_tonality.modality.modality_type)
            secondary_chord = SecondaryChord(secondary_chord_template,
                                             root_mapped_tonality,
                                             secondary_function.range_tonality)
            return secondary_chord
    def test_standards(self):
        diatonic_tonality = Tonality.create(ModalityType.Major,
                                            DiatonicTone("G"))

        template = SecondaryChordTemplate.parse('V/ii')
        print(template)
        t_chord = template.create_chord(diatonic_tonality)
        print(t_chord)

        s = ', '.join(str(tone[0].diatonic_symbol) for tone in t_chord.tones)
        print(s)
        assert s == 'E, G#, B'

        template = SecondaryChordTemplate.parse('V/IV')
        print(template)
        t_chord = template.create_chord(diatonic_tonality)
        print(t_chord)

        s = ', '.join(str(tone[0].diatonic_symbol) for tone in t_chord.tones)
        print(s)
        assert s == 'G, B, D'

        diatonic_tonality = Tonality.create(ModalityType.Major,
                                            DiatonicTone("G"))
        template = SecondaryChordTemplate.parse('V/ii')
        print(template)
        t_chord = template.create_chord(diatonic_tonality)
        print(t_chord)

        s = ', '.join(str(tone[0].diatonic_symbol) for tone in t_chord.tones)
        print(s)
        assert s == 'E, G#, B'

        diatonic_tonality = Tonality.create(ModalityType.Major,
                                            DiatonicTone("Bb"))
        template = SecondaryChordTemplate.parse('VI/ii')
        print(template)
        t_chord = template.create_chord(diatonic_tonality)
        print(t_chord)

        s = ', '.join(str(tone[0].diatonic_symbol) for tone in t_chord.tones)
        print(s)
        assert s == 'A, C, Eb'
    def test_interesting(self):
        diatonic_tonality = Tonality.create(ModalityType.Major,
                                            DiatonicTone("F"))

        template = SecondaryChordTemplate.parse('V/V[NaturalMinor]')
        print(template)
        t_chord = template.create_chord(diatonic_tonality)
        print(t_chord)

        s = ', '.join(str(tone[0].diatonic_symbol) for tone in t_chord.tones)
        print(s)
        assert s == 'G, Bb, D'
    def test_sample(self):
        diatonic_tonality = Tonality.create(ModalityType.Major,
                                            DiatonicTone("C"))

        template = SecondaryChordTemplate.parse('qVIPPaa/iv[Major]')
        print(template)
        t_chord = template.create_chord(diatonic_tonality)
        print(t_chord)

        s = ', '.join(str(tone[0].diatonic_symbol) for tone in t_chord.tones)
        print(s)
        assert s == 'D, G, C, F#, B#'

        template = SecondaryChordTemplate.parse('qIIIPPaa/V[MelodicMinor]')
        print(template)
        t_chord = template.create_chord(diatonic_tonality)
        print(t_chord)

        s = ', '.join(str(tone[0].diatonic_symbol) for tone in t_chord.tones)
        print(s)
        assert s == 'Bb, Eb, Ab, D, G#'
    def test_book_examples(self):
        diatonic_tonality = Tonality.create(ModalityType.Major,
                                            DiatonicTone("A"))

        template = SecondaryChordTemplate.parse('V/V')
        if template:
            print('succeeded')
            chord = template.create_chord(diatonic_tonality)
            print(chord)
        else:
            print("failed")

        template = SecondaryChordTemplate.parse('III/II')
        chord = template.create_chord(diatonic_tonality)
        print(chord)

        template = SecondaryChordTemplate.parse('CMaj7/II')
        chord = template.create_chord(diatonic_tonality)
        print(chord)

        template = SecondaryChordTemplate.parse('V/V[NaturalMinor]')
        chord = template.create_chord(diatonic_tonality)
        print(chord)

        template = SecondaryChordTemplate.parse('V/V[Phrygian]')
        chord = template.create_chord(diatonic_tonality)
        print(chord)

        template = SecondaryChordTemplate.parse('QVIPPAP@2/V')
        chord = template.create_chord(diatonic_tonality)
        print(chord)
示例#8
0
    def construct_secondary_chord_template(self, primary_template, secondary_numeral_str, secondary_modality):
        numeral = LineConstructor.NUMERAL_MAP[secondary_numeral_str]

        if secondary_modality is not None:
            if secondary_modality in LineConstructor.MODALITY_SHORT_NAME_MAP:
                modality = LineConstructor.MODALITY_SHORT_NAME_MAP[secondary_modality]
            elif secondary_modality[0] == '!':
                modality = ModalityType(secondary_modality[1:])
            else:
                modality = ModalityType(secondary_modality)
        else:
            modality = None

        return SecondaryChordTemplate(primary_template, numeral, modality)
    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)
示例#10
0
    def remap_chord(self, hc):

        chord = hc.chord
        chord_tonality = hc.tonality

        if not isinstance(chord, SecondaryChord):
            f = self.hc_flip_map[hc] if hc in self.hc_flip_map.keys() else \
                DiatonicPitchReflectionFunction(hc.tonality, self.cue_pitch, self.domain_pitch_range)
            new_chord_tones = [f.tonal_function[t[0]] for t in chord.tones]
            chords = ChordClassifier.classify_all_roots(
                new_chord_tones, chord_tonality)
            if chords is not None and len(chords) > 0:
                return chords[0]
            else:
                raise Exception(
                    'Cannot remap/classify chord {0} based on chord.'.format(
                        ', '.join(str(t) for t in new_chord_tones)))
        else:
            secondary_tonality = chord.secondary_tonality
            if hc in self.hc_flip_map.keys():
                secondary_function = self.hc_flip_map[hc].tonal_function
            else:
                secondary_function = self._build_secondary_flip_function(
                    hc).tonal_function

            # Alternatively, in the else part, we could have done:
            #   secondary_function = f.tonal_function.create_adapted_function(secondary_tonality, secondary_tonality)
            # but to be consistent within the logic, we go for the reflection_tests constructiobn
            # of the secondary function
            # as embodied in tFlip._build_secondary_flip_function()

            new_chord_tones = [secondary_function[t[0]] for t in chord.tones]
            chords = ChordClassifier.classify_all_roots(
                new_chord_tones, secondary_tonality)

            if chords is not None and len(chords) > 0:
                new_chord = chords[0]
            else:
                raise Exception(
                    'Cannot remap/classify chord {0} based on chord.'.format(
                        ', '.join(str(t) for t in new_chord_tones)))

            secondary_chord_template = SecondaryChordTemplate(
                new_chord.chord_template,
                chord.chord_template.secondary_scale_degree,
                secondary_tonality.modality.modality_type)
            secondary_chord = SecondaryChord(secondary_chord_template,
                                             chord_tonality)
            return secondary_chord
示例#11
0
    def remap_chord(self, hc, new_tonality):

        chord = hc.chord
        chord_tonality = new_tonality

        f, _ = self._build_shift_function(hc)

        if not isinstance(chord, SecondaryChord):
            new_chord_tones = [f.tonal_function[t[0]] for t in chord.tones]
            chords = ChordClassifier.classify_all_roots(
                new_chord_tones, chord_tonality)
            if chords is not None and len(chords) > 0:
                return chords[0]
            else:
                raise Exception(
                    'Cannot remap/classify chord {0} based on chord.'.format(
                        ', '.join(t.diatonic_symbol for t in new_chord_tones)))
        else:
            new_chord_tones = [f.tonal_function[t[0]] for t in chord.tones]
            chords = ChordClassifier.classify_all_roots(
                new_chord_tones, f.range_tonality)
            if chords is not None and len(chords) > 0:
                new_chord = chords[0]
            else:
                raise Exception(
                    'Cannot remap/classify chord {0} based on chord.'.format(
                        ', '.join(str(t) for t in new_chord_tones)))

            temp_range_tonality = Tonality.create(self.range_modality_type if self.range_modality_type is not None
                                                  else hc.tonality.modality_type,
                                                  self.root_shift_interval.get_end_tone(hc.tonality.diatonic_tone),
                                                  self.modal_index if self.modal_index is not None
                                                  else hc.tonality.modal_index) if self.root_shift_interval else \
                hc.tonality

            secondary_chord_template = SecondaryChordTemplate(
                new_chord.chord_template,
                chord.chord_template.secondary_scale_degree,
                chord.secondary_tonality.modality.modality_type)
            secondary_chord = SecondaryChord(secondary_chord_template,
                                             temp_range_tonality)
            return secondary_chord
示例#12
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