Exemple #1
0
 def rebuild_hc(self, hc, position, duration):
     chord = hc.chord
     if isinstance(chord, SecondaryChord):
         chord = self.rebuild_secondary_chord(chord, hc.tonality)
         return HarmonicContext(hc.tonality, chord, duration, position)
     else:
         return HarmonicContext(hc.tonality, self.remap_chord(hc), duration, position)
    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
Exemple #3
0
    def _rebuild_hct(self, orig_hct, as_copy):
        hc_list = orig_hct.hc_list()
        if not as_copy:
            orig_hct.clear()
        new_hct = HarmonicContextTrack() if as_copy else orig_hct
        next_index = 0
        position = Position(0)
        if self.pre_extent is not None:
            for hc in hc_list:
                intersect = hc.extent.intersection(self.pre_extent)
                if intersect is None:
                    break
                duration = Duration(
                    min(intersect.length(), hc.duration.duration))
                new_hc = HarmonicContext(hc.tonality, hc.chord, duration,
                                         hc.position)
                new_hct.append(new_hc)
                position += new_hc.duration
                if hc.extent.upper > self.pre_extent.upper:
                    break
                next_index += 1

        for hc in islice(hc_list, next_index, None):
            intersect = hc.extent.intersection(self.temporal_extent)
            if intersect is None:
                break
            duration = Duration(intersect.length())
            if self.keep_hct:
                new_hc = HarmonicContext(hc.tonality, hc.chord, duration,
                                         position)
            else:
                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)
                new_hc = HarmonicContext(f.range_tonality,
                                         self.remap_chord(hc), duration,
                                         position)
            new_hct.append(new_hc)
            position += new_hc.duration
            if hc.extent.upper > self.temporal_extent.upper:
                break
            next_index += 1

        if self.post_extent is not None:
            for hc in islice(hc_list, next_index, None):
                intersect = hc.extent.intersection(self.post_extent)
                if intersect is None:
                    break
                duration = Duration(intersect.length())
                new_hc = HarmonicContext(hc.tonality, hc.chord, duration,
                                         position)
                new_hct.append(new_hc)
                position += new_hc.duration

        return new_hct
Exemple #4
0
    def _rebuild_hct(self, orig_hct, as_copy):
        hc_list = orig_hct.hc_list()
        if not as_copy:
            orig_hct.clear()
        new_hct = HarmonicContextTrack() if as_copy else orig_hct
        next_index = 0
        position = Position(0)
        if self.pre_extent is not None:
            for hc in hc_list:
                intersect = hc.extent.intersection(self.pre_extent)
                if intersect is None:
                    break
                duration = Duration(
                    min(intersect.length(), hc.duration.duration))
                new_hc = HarmonicContext(hc.tonality, hc.chord, duration,
                                         hc.position)
                new_hct.append(new_hc)
                position += new_hc.duration
                if hc.extent.upper > self.pre_extent.upper:
                    break
                next_index += 1

        for hc in islice(hc_list, next_index, None):
            intersect = hc.extent.intersection(self.temporal_extent)
            if intersect is None:
                break
            duration = Duration(intersect.length())
            if self.keep_hct:
                new_hc = HarmonicContext(hc.tonality, hc.chord, duration,
                                         position)
            else:
                f, range_tonality = self._build_shift_function(hc)
                # TODO: the range tonality below is incorrect.
                new_hc = HarmonicContext(
                    range_tonality, self.remap_chord(hc, f.range_tonality),
                    duration, position)
            new_hct.append(new_hc)
            position += new_hc.duration
            if hc.extent.upper > self.temporal_extent.upper:
                break
            next_index += 1

        if self.post_extent is not None:
            for hc in islice(hc_list, next_index, None):
                intersect = hc.extent.intersection(self.post_extent)
                if intersect is None:
                    break
                duration = Duration(intersect.length())
                new_hc = HarmonicContext(hc.tonality, hc.chord, duration,
                                         position)
                new_hct.append(new_hc)
                position += new_hc.duration

        return new_hct
Exemple #5
0
    def _rebuild_hct(self, orig_hct):
        hc_list = orig_hct.hc_list()
        new_hct = HarmonicContextTrack()

        next_index = 0
        position = Position(0)
        if self.pre_extent is not None:
            for hc in hc_list:
                intersect = hc.extent.intersection(self.pre_extent)
                if intersect is None:
                    break
                duration = Duration(min(intersect.length(), hc.duration.duration))
                new_hc = HarmonicContext(hc.tonality, hc.chord, duration, hc.position)
                new_hct.append(new_hc)
                position += new_hc.duration
                if hc.extent.upper > self.pre_extent.upper:
                    break
                next_index += 1

        for hc in islice(hc_list, next_index, None):
            intersect = hc.extent.intersection(self.temporal_extent)
            if intersect is None:
                break
            duration = Duration(intersect.length())

            new_hc = self.rebuild_hc(hc, position, duration)
            new_hct.append(new_hc)

            # TODO: this has to be called, but not sure what side effects are necessary.
            self._build_step_shift_function(new_hc, hc)

            position += new_hc.duration
            if hc.extent.upper > self.temporal_extent.upper:
                break
            next_index += 1

        if self.post_extent is not None:
            for hc in islice(hc_list, next_index, None):
                intersect = hc.extent.intersection(self.post_extent)
                if intersect is None:
                    break
                duration = Duration(intersect.length())
                new_hc = HarmonicContext(hc.tonality, hc.chord, duration, position)
                new_hct.append(new_hc)
                position += new_hc.duration

        return new_hct
    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)
Exemple #7
0
 def create_track(chords, tonality):
     hc_track = HarmonicContextTrack()
     for c in chords:
         chord_t = ChordTemplate.generic_chord_template_parse(c[0])
         chord = chord_t.create_chord(tonality)
         duration = Duration(c[1]) if isinstance(c[1], int) else Duration(c[1][0], c[1][1])
         hc_track.append(HarmonicContext(tonality, chord, duration))
     return hc_track
    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)
Exemple #9
0
    def dilate_hct(self, hct):
        new_hct = HarmonicContextTrack()

        for hc in hct.hc_list():
            new_hc = HarmonicContext(
                hc.tonality, hc.chord, hc.duration *
                self.dilation_factor if self.apply_to_notes else hc.duration)
            new_hct.append(new_hc)

        return new_hct
Exemple #10
0
    def reverse(self):
        new_track = HarmonicContextTrack()

        offset = Position(0)
        for hc in reversed(self.hc_list()):
            hs_prime = HarmonicContext(hc.tonality, hc.chord, hc.duration,
                                       offset)
            new_track.append(hs_prime)
            offset = offset + hc.duration

        return new_track
    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)
Exemple #12
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
    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)
Exemple #14
0
    def build_hct(hc_expressed_list):
        parse_str = '{'
        for t in hc_expressed_list:
            parse_str += '<' + t[0] + '> qC:4 '
        parse_str += '}'

        lge = LineGrammarExecutor()

        _, hct = lge.parse(parse_str)
        new_hct = HarmonicContextTrack()
        for hc, t in zip(hct.hc_list(), hc_expressed_list):
            new_hc = HarmonicContext(hc.tonality, hc.chord, t[1])
            new_hct.append(new_hc)
        return new_hct
    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)
Exemple #16
0
    def build_harmonic_context_track(self):
        # Prune superfluous harmonic tags.
        new_tag_list = [tag for tag in self.harmonic_tag_list if tag.first_note is not None]
        self.harmonic_tag_list = new_tag_list

        hct = HarmonicContextTrack()
        for i in range(0, len(self.harmonic_tag_list)):
            harmonic_tag = self.harmonic_tag_list[i]
            duration = (self.harmonic_tag_list[i + 1].first_note.get_absolute_position()
                        if i < len(self.harmonic_tag_list) - 1 else Position(self.__line.duration)) - \
                       self.harmonic_tag_list[i].first_note.get_absolute_position()
            harmonic_context = HarmonicContext(harmonic_tag.tonality, harmonic_tag.chord, duration,
                                               harmonic_tag.first_note.get_absolute_position())
            hct.append(harmonic_context)
        return 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)
    def __init__(self, coverage_node_list, tempo_seq, ts_seq, hct, line):
        """
        Constructor
        :param coverage_node_list: List of note structures that are affected by on beat constraints.
        :param tempo_seq: TempoEventSequence
        :param ts_seq: EventSequence of TimeSignatures
        :param hct: HarmonicContextTrack
        :param line: Line
        """
        self.__coverage_node_list = coverage_node_list

        self.__coverage_node_aggregates = dict()
        self.__coverage_node_deltas = dict()

        # duplicate time signature event sequence
        new_ts_list = []
        for e in ts_seq.sequence_list:
            new_ts_list.append(
                TimeSignatureEvent(
                    TimeSignature(e.object.beats_per_measure,
                                  e.object.beat_duration,
                                  e.object.beat_pattern), e.time))
        self.__ts_event_sequence = EventSequence(new_ts_list)

        # duplicate tempo event sequence
        new_tempo_list = []
        for e in tempo_seq.sequence_list:
            new_tempo_list.append(
                TempoEvent(Tempo(e.object.tempo, e.object.beat_duration),
                           e.time))
        self.__tempo_event_sequence = TempoEventSequence(new_tempo_list)

        self.__line = line

        self.__hct = HarmonicContextTrack()
        for hc in hct.hc_list():
            self.__hct.append(
                HarmonicContext(hc.tonality, hc.chord, Duration(hc.duration),
                                Position(hc.position)))

        for n in self.coverage_node_list:
            self.__coverage_node_aggregates[n] = 0
            self.__coverage_node_deltas[n] = 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
Exemple #20
0
    def sub_hct(self, sub_track_interval=None):
        """
        Take a sub_track of this hct.
        :param sub_track_interval: NmericInterval.  If none, the entire hct.
        :return:
        """
        sub_track_interval = NumericInterval(Fraction(0), self.duration.duration) if sub_track_interval is None else \
            sub_track_interval

        new_track = HarmonicContextTrack()
        for hc in self.hc_list():
            hc_interval = NumericInterval(
                hc.position.position,
                hc.position.position + hc.duration.duration)
            hc_intersect = hc_interval.intersection(sub_track_interval)
            if hc_intersect is not None:
                new_hc = HarmonicContext(hc.tonality, hc.chord,
                                         Duration(hc_intersect.length()),
                                         Position(hc_intersect.lower))
                new_track.append(new_hc)

        return new_track
    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()
Exemple #22
0
    def interpret(self, hc_list, duration=Duration(1, 4)):
        """
        Give a list of HarmonicContext's, interpret the HCExpression into a HarmonicContext.
        :param hc_list:
        :param duration:
        :return: HarmonicContext
        """
        if isinstance(self.key, str):
            key_tone = DiatonicToneCache.get_tone(self.key)
        else:
            if self.key not in range(0, len(hc_list)):
                raise Exception('@{0} not in range.'.format(self.key))
            key_tone = hc_list[self.key].tonality.diatonic_tone

        if self.key_modifier is not None:
            key_tone = self.key_modifier.get_end_tone(key_tone)

        if self.modality_index:
            if isinstance(self.modality_index, str):
                modal_index = int(self.modality_index)
            else:
                if self.modality_index not in range(0, len(hc_list)):
                    raise Exception('@{0} not in range.'.format(
                        self.modality_index))
                modal_index = hc_list[self.modality_index].tonality.modal_index
        else:
            modal_index = 0

        if isinstance(self.key_modality, str):
            modality_type = ModalityType(self.key_modality)
        else:
            if self.key_modality not in range(0, len(hc_list)):
                raise Exception('@{0} not in range.'.format(self.key_modality))
            modality_type = hc_list[self.key_modality].tonality.modality_type

        #  Note: chord_numeral is origin 1
        if isinstance(self.chord_numeral, str):
            chord_numeral = ChordTemplate.SCALE_DEGREE_MAP[self.chord_numeral]
        else:
            if self.chord_numeral not in range(0, len(hc_list)):
                raise Exception('@{0} not in range.'.format(
                    self.chord_numeral))
            chord_numeral = hc_list[
                self.chord_numeral].chord.chord_template.scale_degree

        if self.chord_type:
            if isinstance(self.chord_type, str):
                chord_type = TertianChordType.to_type(self.chord_type)
            else:
                if self.chord_type not in range(0, len(hc_list)):
                    raise Exception('@{0} not in range.'.format(
                        self.chord_type))
                chord_type = hc_list[self.chord_type].chord.chord_type
        else:
            chord_type = None

        tonality = Tonality.create(modality_type, key_tone, modal_index)
        chord_template = ChordTemplate.generic_chord_template_parse(
            ChordTemplate.SCALE_DEGREE_REVERSE_MAP[chord_numeral] +
            (str(chord_type) if chord_type else ''))
        chord = chord_template.create_chord(tonality)

        hc = HarmonicContext(tonality, chord, duration)

        return hc
    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
    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