Ejemplo n.º 1
0
    def __create_chord_on_diatonic_tonality(self, diatonic_tone,
                                            diatonic_tonality):
        if not diatonic_tonality:
            raise Exception(
                "Cannot base secundal chord on tone {0} without tonality.".
                format(diatonic_tone.diatonic_symbol))
        # The tonality must include this tone.
        tone_scale = diatonic_tonality.annotation
        found_index = -1
        for i in range(0, len(tone_scale)):
            if diatonic_tone == tone_scale[i]:
                found_index = i
                break
        if found_index == -1:
            raise Exception(
                "For secundal chord based on tone {0}, tone must be in given tonality {1}"
                .format(diatonic_tone.diatonic_symbol, diatonic_tonality))
        self.chord_basis = []
        basis_tone = tone_scale[found_index]
        for i in range(0, 3):
            tone = tone_scale[(found_index + i) % (len(tone_scale) - 1)]
            pitch_a = DiatonicPitch(1, basis_tone.diatonic_symbol)
            b_octave = 2 if basis_tone.diatonic_index > tone.diatonic_index else 1
            pitch_b = DiatonicPitch(b_octave, tone.diatonic_symbol)
            interval = Interval.create_interval(pitch_a, pitch_b)
            # If for any reason, the interval is not perfect or augmented (we know it is a 4th), just adjust tone upward
            #    It is unknown if this can happen in a diatonic scale in practice.
            if interval.interval_type.value == IntervalType.Diminished:
                tone = DiatonicTone.alter_tone_by_augmentation(tone, 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))
            basis_tone = tone
Ejemplo n.º 2
0
 def test_various(self):
     dta = DiatonicPitch(2, 'B#')
     dtb = DiatonicPitch(3, 'C')
     interval = Interval.create_interval(dta, dtb)
     semitones = interval.semitones()
     print('Interval "{0}" based on {1} and {2} has {3} semitones'.format(interval, dta, dtb, semitones))
     
     # get a major 3rd pitch
     interval = Interval.create_interval(DiatonicPitch(2, 'E'), DiatonicPitch(2, 'G#'))
     end_pitch = interval.get_end_pitch(DiatonicPitch(4, 'E'))
     print(end_pitch)
     assert str(end_pitch) == 'G#:4'
Ejemplo n.º 3
0
 def calculate_interval(tone_1, tone_2, near_interval):
     """
     The purpose of this method is to find a transform interval close to 'near_interval'.  This is used
     to determine the transform interval for secondary chords, wherein the obvious jump does not match
     transform interval (e.g. major to minor scale), and as well must be adjusted for the number and sign of
     octaves nearest interval may have.  See test cases: test_modal_secondary_tonality where best_interval == d:4
     and near_interval == P:4 E-MM to Ab-MM using V/III chord.
     :param tone_1:
     :param tone_2:
     :param near_interval:
     :return:
     """
     sign = TShift._sign(near_interval.chromatic_distance)
     start, increment = (1, 1) if sign == 1 else (7, -1)
     p1 = DiatonicPitch(start, tone_1)
     oct_2 = start
     best = 100000
     best_interval = None
     while abs(oct_2) < 7:
         p2 = DiatonicPitch(oct_2, tone_2)
         i = TonalInterval.create_interval(p1, p2)
         if TShift._sign(i.chromatic_distance) != sign:
             oct_2 = oct_2 + sign
             continue
         diff = abs(near_interval.chromatic_distance - i.chromatic_distance)
         if diff < best:
             best = diff
             best_interval = i
         else:
             break
         oct_2 = oct_2 + sign
     return best_interval
Ejemplo n.º 4
0
    def _build_tunnel_constraints(self, source_to_target, tag_map):
        if tag_map is None or len(tag_map) == 0:
            return []

        one_id = next(iter(tag_map.keys()))
        source_note = self.source_line.get_all_notes()[one_id]
        target_pitch = tag_map[one_id]

        mvmt_interval = Interval.create_interval(source_note.diatonic_pitch,
                                                 target_pitch)

        constraints = list()
        note_annotations = self.source_analysis.note_annotation
        for annotation in note_annotations:
            if annotation.note.diatonic_pitch is None:
                continue
            target_note = source_to_target[annotation.note]

            dest_ctr_pitch = mvmt_interval.get_end_pitch(
                annotation.note.diatonic_pitch)
            low_pitch = self.tunnel_half_interval.get_start_pitch(
                dest_ctr_pitch)
            high_pitch = self.tunnel_half_interval.get_end_pitch(
                dest_ctr_pitch)
            p_range = PitchRange.create(low_pitch, high_pitch)

            constraint = PitchRangeConstraint([target_note], p_range)
            constraints.append(constraint)

        return constraints
Ejemplo n.º 5
0
 def test_all_g_same_octave_itervals(self):
     pitches = list('GABCDEF')
     octaves = [5, 5, 5, 6, 6, 6, 6]
     augs = ('bb', 'b', '',  '#', '##')
     example_count = 0
     exception_items = (1, 2, 5, 10, 15, 16, 20, 21, 25, 30, 31, 35)
     for i in range(0, 7):
         pitch = pitches[i]
         octave = octaves[i]
         for aug in augs:
             example_count += 1
             a = DiatonicPitch(5, 'G')
             b = DiatonicPitch(octave, pitch + aug)
             try:
                 interval = Interval.create_interval(a, b)
                 print('({0}): {1}, {2}) --> {3}'.format(example_count, a, b, interval))
                 
                 dist = b.diatonic_tone.diatonic_index - a.diatonic_tone.diatonic_index
                 if dist < 0:
                     dist += 7
                 assert dist == interval.diatonic_distance
                 assert b.chromatic_distance - a.chromatic_distance == interval.chromatic_distance
             except Exception as e:
                 print('Exception ({0}): ({1}, {2}) : {3}'.format(example_count, a, b, e))
                 assert example_count in exception_items, \
                     'ASSERT ERROR ({0}): ({1}, {2}) : {3}'.format(example_count, a, b, e)
Ejemplo n.º 6
0
    def __create_chord_on_diatonic_tonality(self, diatonic_tone,
                                            diatonic_tonality):
        if not diatonic_tonality:
            raise Exception(
                "Cannot base quartal chord on tone {0} without tonality.".
                format(diatonic_tone.diatonic_symbol))
        # The tonality must include this tone.
        tone_scale = diatonic_tonality.annotation
        found_index = -1
        for i in range(0, len(tone_scale)):
            if diatonic_tone == tone_scale[i]:
                found_index = i
                break
        if found_index == -1:
            raise Exception(
                "For quartal chord based on tone {0}, tone must be in given tonality {1}"
                .format(diatonic_tone.diatonic_symbol, diatonic_tonality))
        self.chord_basis = []
        basis_tone = tone_scale[found_index]
        for i in range(0, 3):
            tone = tone_scale[(found_index + 3 * i) % (len(tone_scale) - 1)]
            pitch_a = DiatonicPitch(1, basis_tone.diatonic_symbol)
            b_octave = 2 if basis_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))
            basis_tone = tone
Ejemplo n.º 7
0
    def test_book_examples(self):
        # Interval Creation
        interval = Interval(5, IntervalType.Perfect)
        print(interval)
        interval = Interval.parse("m:10")
        print(interval)
        interval = Interval.create_interval(DiatonicPitch.parse("a:3"), DiatonicPitch.parse("f#:4"))
        print(interval)

        # Interval Addition/Subtraction
        i1 = Interval(5, IntervalType.Perfect)
        i2 = Interval.parse("M:3")
        interval = i1 + i2
        print(interval)
        interval = i1 - i2
        print(interval)
        interval += i2
        print(interval)
        interval -= i2
        print(interval)

        # compute end and start
        interval = Interval(5, IntervalType.Perfect)
        pitch = interval.get_end_pitch(DiatonicPitch.parse("F#:5"))
        print(pitch)
        pitch = interval.get_start_pitch(DiatonicPitch.parse("C:5"))
        print(pitch)
Ejemplo n.º 8
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)
Ejemplo n.º 9
0
    def test_hct_simple_shift(self):
        print('----- test_hct_simple_shift -----')

        line_str = '{<C-Major: I> C:4 E F D <:IV> F A <:V> G D <:VI> a c b a}'
        lge = LineGrammarExecutor()
        target_line, target_hct = lge.parse(line_str)

        root_shift_interval = TonalInterval.create_interval('C:4', 'G:4')

        tshift = TShift(target_line, target_hct, root_shift_interval)

        temporal_extent = Interval(Fraction(1, 1), Fraction(2, 1))
        tshift.apply(temporal_extent, as_copy=False)
        TestTShift.print_notes(target_line)
        TestTShift.print_hct(target_hct)

        notes = target_line.get_all_notes()
        assert 12 == len(notes)
        assert 'C:5' == str(notes[4].diatonic_pitch)
        assert 'E:5' == str(notes[5].diatonic_pitch)
        assert 'D:5' == str(notes[6].diatonic_pitch)
        assert 'A:4' == str(notes[7].diatonic_pitch)

        hc_list = target_hct.hc_list()
        assert len(hc_list) == 4
        assert hc_list[1].chord.chord_template.scale_degree == 4
        assert {t[0].diatonic_symbol
                for t in hc_list[1].chord.tones} == {'C', 'E', 'G'}
        assert hc_list[1].chord.chord_template.inversion == 1
        assert hc_list[1].tonality.modal_index == 0
        assert hc_list[1].tonality.basis_tone.diatonic_symbol == 'G'
        assert hc_list[1].tonality.root_tone.diatonic_symbol == 'G'
        assert hc_list[1].tonality.modality_type == ModalityType.Major
        assert hc_list[1].chord.chord_type.value == TertianChordType.Maj
Ejemplo n.º 10
0
 def test_transpose(self):
     c = InstrumentCatalog.instance()
     instf = c.get_instruments("Clarinet")
     bflatclarinet = None
     for inst in instf:
         if inst.key == 'Bb':
             bflatclarinet = inst
             break
     assert bflatclarinet is not None
     interval = Interval.create_interval(bflatclarinet.sounding_high,
                                         bflatclarinet.written_high)
     assert interval.interval_type == IntervalType.Major
     assert interval.diatonic_distance == 1
Ejemplo n.º 11
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
Ejemplo n.º 12
0
    def test_create_interval(self):
        pitch_a = DiatonicPitch(4, 'C')
        pitch_b = DiatonicPitch(5, 'C')
        interval = Interval.create_interval(pitch_a, pitch_b)
        print(interval)
        assert interval.interval_type == IntervalType(IntervalType.Perfect)
        assert interval.diatonic_distance == 7
        
        pitch_a = DiatonicPitch(4, 'C')
        pitch_b = DiatonicPitch(5, 'Cb')
        interval = Interval.create_interval(pitch_a, pitch_b)
        print(interval)
        assert interval.interval_type == IntervalType(IntervalType.Diminished)
        assert interval.diatonic_distance == 7

        pitch_a = DiatonicPitch(4, 'C')
        pitch_b = DiatonicPitch(5, 'Dbb')        
        interval = Interval.create_interval(pitch_a, pitch_b)
        print(interval)
        assert interval.interval_type == IntervalType(IntervalType.Diminished)
        assert interval.diatonic_distance == 8
        
        pitch_a = DiatonicPitch(4, 'C')
        pitch_b = DiatonicPitch(5, 'Cb')        
        interval = Interval.create_interval(pitch_a, pitch_b)
        print(interval)
        assert interval.interval_type == IntervalType(IntervalType.Diminished)
        assert interval.diatonic_distance == 7
        
        pitch_a = DiatonicPitch(4, 'C')
        pitch_b = DiatonicPitch(4, 'B#')        
        interval = Interval.create_interval(pitch_a, pitch_b)
        print(interval)
        assert interval.interval_type == IntervalType(IntervalType.Augmented)
        assert interval.diatonic_distance == 6
        assert not interval.is_negative()

        pitch_a = DiatonicPitch(5, 'C')
        pitch_b = DiatonicPitch(4, 'Bb')
        interval = Interval.create_interval(pitch_a, pitch_b)
        print(interval)
        assert interval.interval_type == IntervalType(IntervalType.Major)
        assert interval.diatonic_distance == -1
        assert interval.is_negative()
        
        interval = Interval(9, IntervalType(IntervalType.Diminished))
        print(interval)
        assert interval.interval_type == IntervalType(IntervalType.Diminished)
        assert interval.diatonic_distance == 8
        
        interval = Interval(3, IntervalType(IntervalType.Minor))
        pitch = interval.get_start_pitch(DiatonicPitch(4, 'E'))
        print(pitch)
        assert str(pitch) == 'C#:4'
Ejemplo n.º 13
0
 def test_all_c_octave_up_itervals(self):
     pitches = list('CDEFGAB')
     augs = ('bb', 'b', '',  '#', '##')
     exception_items = (1, 5, 10, 15, 16, 20, 21, 25, 30, 35)
     example_count = 0
     for pitch in pitches:
         for aug in augs:
             example_count += 1
             a = DiatonicPitch(4, 'C')
             b = DiatonicPitch(5, pitch + aug)
             try:
                 interval = Interval.create_interval(a, b)
                 assert b.chromatic_distance - a.chromatic_distance == interval.chromatic_distance
                 print('({0}): {1}, {2}) --> {3}'.format(example_count, a, b, interval))
             except Exception as e:
                 print('Exception ({0}): ({1}, {2}) : {3}'.format(example_count, a, b, e))
                 assert example_count in exception_items, \
                     'Exception ({0}): ({1}, {2}) : {3}'.format(example_count, a, b, e)
Ejemplo n.º 14
0
def build_incremental_intervals(scale):
    from tonalmodel.diatonic_pitch import DiatonicPitch
    from tonalmodel.interval import Interval
    partition = 4
    iter_scale = iter(scale)
    first = next(iter_scale)
    prior_pitch = DiatonicPitch(partition, first)
    prior = TONES.index(first.diatonic_letter)
    intervals = [Interval.parse('P:1')]
    for dt in iter_scale:    
        if TONES.index(dt.diatonic_letter) - prior < 0:
            partition += 1
        prior = TONES.index(dt.diatonic_letter)
        current_pitch = DiatonicPitch(partition, dt)
        intervals.append(Interval.create_interval(prior_pitch, current_pitch))
        
        prior_pitch = current_pitch
        
    return intervals    
Ejemplo n.º 15
0
    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
Ejemplo n.º 16
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)
Ejemplo n.º 17
0
    def test_negative_intervals(self):
        interval = Interval(-3, IntervalType.Major)
        assert interval.diatonic_distance == -2
        assert interval.chromatic_distance == -4
        assert str(interval) == '-M:3'
        print(interval)
        
        interval = Interval.parse('-P:5')
        assert interval.diatonic_distance == -4
        assert interval.chromatic_distance == -7
        assert str(interval) == '-P:5'
        print(interval)
        
        pitch_a = DiatonicPitch(5, 'C')
        pitch_b = DiatonicPitch(4, 'C')
        interval = Interval.create_interval(pitch_a, pitch_b)
        print(interval)
        assert interval.interval_type == IntervalType(IntervalType.Perfect)
        assert interval.diatonic_distance == -7
        
        pitch_a = DiatonicPitch(5, 'C')
        pitch_b = DiatonicPitch(4, 'Cb')
        interval = Interval.create_interval(pitch_a, pitch_b)
        print(interval)
        assert interval.interval_type == IntervalType(IntervalType.Augmented)
        assert interval.diatonic_distance == -7
        assert str(interval) == '-A:8'
        
        pitch_a = DiatonicPitch(5, 'C')
        pitch_b = DiatonicPitch(4, 'C#')
        interval = Interval.create_interval(pitch_a, pitch_b)
        print(interval)
        assert interval.interval_type == IntervalType(IntervalType.Diminished)
        assert interval.diatonic_distance == -7
        assert str(interval) == '-d:8'

        pitch_a = DiatonicPitch(5, 'C')
        lower_pitches = [DiatonicPitch(4, i) for i in list('CDEFGAB')]
        answers = ['-P:8', '-m:7', '-m:6', '-P:5', '-P:4', '-m:3', '-m:2']
        for (p, a) in zip(lower_pitches, answers):
            interval = Interval.create_interval(pitch_a, p)
            assert str(interval) == a
          
        lower_pitches = [DiatonicPitch(4, i) for i in 'Cb,Db,Eb,Fb,Gb,Ab,Bb'.split(',')]
        answers = ['-A:8', '-M:7', '-M:6', '-A:5', '-A:4', '-M:3', '-M:2']
        for (p, a) in zip(lower_pitches, answers):
            interval = Interval.create_interval(pitch_a, p)
            assert str(interval) == a

        lower_pitches = [DiatonicPitch(4, i) for i in 'C#,D#,E#,F#,G#,A#,B#'.split(',')]
        answers = ['-d:8', '-d:7', '-d:6', '-d:5', '-d:4', '-d:3', '-d:2']
        for (p, a) in zip(lower_pitches, answers):
            interval = Interval.create_interval(pitch_a, p)
            assert str(interval) == a

        interval = Interval.parse('-M:3')
        p = DiatonicPitch(4, 'Ab')
        end_p = interval.get_end_pitch(p)
        print(end_p)
        assert str(end_p) == 'Fb:4'
        
        interval = Interval.parse('-P:5')
        p = DiatonicPitch(4, 'D')
        end_p = interval.get_end_pitch(p)
        print(end_p)
        assert str(end_p) == 'G:3'

        interval_strs = ['-P:1', '-M:2', '-M:3', '-P:4', '-P:5', '-M:6', '-M:7', '-P:8', '-M:9', '-M:10',
                         '-P:11', '-P:12', '-M:13', '-M:14', '-P:15']
        intervals = [Interval.parse(i) for i in interval_strs]
        p = DiatonicPitch(4, 'G')
        answers = ['G:4', 'F:4', 'Eb:4', 'D:4', 'C:4', 'Bb:3', 'Ab:3', 
                   'G:3', 'F:3', 'Eb:3', 'D:3', 'C:3', 'Bb:2', 'Ab:2',
                   'G:2'
                   ]
        end_ps = []
        for interval in intervals:
            end_p = interval.get_end_pitch(p)
            print(end_p)
            end_ps.append(end_p)
        for end_p, answer in zip(end_ps, answers):
            assert str(end_p) == answer
            
        # Negation tests
        interval_strs = ['P:1', 'M:2', 'M:3', 'P:4', 'P:5', 'M:6', 'M:7', 'P:8', 'M:9', 'M:10', 'P:11',
                         'P:12', 'M:13', 'M:14', 'P:15',
                         '-P:1', '-M:2', '-M:3', '-P:4', '-P:5', '-M:6', '-M:7', '-P:8', '-M:9', '-M:10', '-P:11',
                         '-P:12', '-M:13', '-M:14', '-P:15']
        intervals = [Interval.parse(i) for i in interval_strs]
        count = 1
        for interval, i_str in zip(intervals, interval_strs):
            neg_interval = interval.negation()
            if count <= 15:
                assert str(neg_interval) == ('-' if count > 1 else '') + i_str
            else:
                assert str(neg_interval) == i_str[1:]
            count += 1
            
        interval_strs = ['-P:1', '-M:2', '-M:3', '-P:4', '-P:5', '-M:6', '-M:7', '-P:8', '-M:9', '-M:10', '-P:11',
                         '-P:12', '-M:13', '-M:14', '-P:15']
        intervals = [Interval.parse(i) for i in interval_strs]
        p = DiatonicPitch(4, 'G')
        answers = ['G:4', 'A:4', 'B:4', 'C:5', 'D:5', 'E:5', 'F#:5', 
                   'G:5', 'A:5', 'B:5', 'C:6', 'D:6', 'E:6', 'F#:6',
                   'G:6'
                   ]
        end_ps = []
        print('+++++')
        for interval in intervals:
            end_p = interval.get_start_pitch(p)
            print(end_p)
            end_ps.append(end_p)
        print('-----')
        for end_p, answer in zip(end_ps, answers):
            assert str(end_p) == answer
Ejemplo n.º 18
0
 def test_diff_octaves(self):
     dta = DiatonicPitch(3, 'A')
     dtb = DiatonicPitch(4, 'D')
     interval = Interval.create_interval(dta, dtb)
     print(interval)
     assert interval.semitones() == 5, '{0} != 5'.format(interval.semitones())  
Ejemplo n.º 19
0
    def test_modal_secondary_tonality(self):
        print('----- test_modal_tonality_modal_index -----')
        # diatonic_modality is effectively Dorian
        diatonic_tonality = Tonality.create(ModalityType.Major,
                                            DiatonicTone('C'))

        chords = [('tI', 1), ('V/iii', (1, 2)), ('tiii', (1, 2)), ('tVI', 1)]
        hc_track = TestTShift.create_track(chords, diatonic_tonality)
        TestTShift.print_hct(hc_track)

        s_notes = [
            ('C:4', 'q'),
            ('E:4', 'q'),
            ('G:4', 'q'),
            ('A:4', 'q'),
            ('B:4', 'e'),
            ('C#5', 'e'),
            ('d#:5', 'e'),
            ('e:5', 'e'),
            ('b:4', 'q'),
            ('g:4', 'q'),
            ('a:4', 'q'),
            ('c:5', (1, 4)),
            ('b:5', (1, 4)),
            ('a:4', (1, 4)),
        ]

        line = TestTShift.create_line(s_notes)
        root_shift_interval = TonalInterval.create_interval('C:4', 'F:4')

        tshift = TShift(line,
                        hc_track,
                        root_shift_interval,
                        default_range_modality_type=ModalityType.MelodicMinor)

        temporal_extent = Interval(Fraction(0), Fraction(3, 1))
        score_line, score_hct = tshift.apply(
            temporal_extent,
            range_modality_type=ModalityType.MelodicMinor,
            as_copy=False)

        TestTShift.print_notes(score_line)
        TestTShift.print_hct(score_hct)

        notes = score_line.get_all_notes()
        assert 14 == len(notes)
        assert 'Eb:5' == str(notes[4].diatonic_pitch)
        assert 'F:5' == str(notes[5].diatonic_pitch)
        assert 'G:5' == str(notes[6].diatonic_pitch)
        assert 'Ab:5' == str(notes[7].diatonic_pitch)

        hc_list = score_hct.hc_list()
        assert len(hc_list) == 4
        assert hc_list[1].chord.chord_template.secondary_scale_degree == 3
        assert {t[0].diatonic_symbol
                for t in hc_list[1].chord.tones} == {'Eb', 'G', 'Bb'}
        assert hc_list[
            1].chord.chord_template.principal_chord_template.inversion == 1
        assert hc_list[1].tonality.modal_index == 0
        assert hc_list[1].tonality.basis_tone.diatonic_symbol == 'F'
        assert hc_list[1].tonality.root_tone.diatonic_symbol == 'F'
        assert hc_list[1].tonality.modality_type == ModalityType.MelodicMinor
        assert hc_list[1].chord.chord_type.value == TertianChordType.Maj