Beispiel #1
0
    def apply(self, step_increment=0, temporal_extent=None, secondary_shift_type=None):
        """
        Do an apply action for this transform.
        :param step_increment: The number of scalar steps to do.
        :param secondary_shift_type: If not None, overrides the default setting of secondary_shift_type.
        :param temporal_extent: The temporal extent over which to transform
        :return: A new score line and new score hct reflecting the transform changes in the extent.
        """
        if step_increment is None or not isinstance(step_increment, int):
            raise Exception('Increment must be specified and be an integer.')
        self.step_increment = step_increment

        self.__secondary_shift_type = secondary_shift_type if secondary_shift_type is not None \
            else self.__default_secondary_shift_type

        # If temporal_extent is None, use the whole range of hct.
        self.temporal_extent = temporal_extent if temporal_extent is not None else \
            Interval(Fraction(0), self.source_hct.duration.duration)

        self.pre_extent = None if self.temporal_extent.lower == 0 else Interval(0, self.temporal_extent.lower)
        self.post_extent = None if self.temporal_extent.upper >= self.source_line.duration else \
            Interval(self.temporal_extent.upper, self.source_line.duration.duration)

        self.hc_step_pitch_function_map = dict()

        score_hct = self._rebuild_hct(self.source_hct)

        score_line = self._reset_pitches(score_hct)
        return score_line, score_hct
Beispiel #2
0
 def test_delete_node(self):
     print('Delete node test')
     tree = IntervalTree()
     for i in range(1, 4):
         tree.put(Interval(i, i + 3), MyObject(i))
     print(tree)
         
     result = tree.query_point(3.5)
     assert result
     assert len(result) == 3
     print(', '.join(('[' + str(w.value.idd) + '] ' + str(w) for w in result)))
     assert sum(x.value.idd for x in result) == 6
     
     print('Deleting [{0}] {1}'.format(result[0].value.idd, result[0]))
     tree.delete(result[0])       
     print(tree)
     
     result = tree.query_point(3.5)
     assert result
     assert len(result) == 2
     
     # single node delete test
     print('Single node delete test')
     tree = IntervalTree()
     tree.put(Interval(3, 5), MyObject(5))
     print(tree)
     
     result = tree.query_point(3)
     assert len(result) == 1
     tree.delete(result[0])
     print(tree)
     result = tree.query_point(3)
     assert len(result) == 0
Beispiel #3
0
    def apply(self,
              temporal_extent=None,
              cue_pitch=None,
              flip_type=None,
              as_copy=True):
        """
        Apply the TFlip transform to a tempoaral extent.

        :param temporal_extent: misc.Interval
        :param cue_pitch:  Possible override of the cue pitch.
        :param flip_type: Ref. FlipType on how cue pitch is used in reflection.
        :param as_copy: True means to return copys of line, hct as source_line, source_hct would be modified otherwise.
        :return: modified line and hct (as objects, the same as passed in.)
        """
        # If temporal_extent is None, use the whole range of hct.
        self.temporal_extent = temporal_extent if temporal_extent is not None else \
            Interval(Fraction(0), self.source_hct.duration.duration)

        self.cue_pitch = self.default_cue_pitch if cue_pitch is None else cue_pitch
        self.flip_type = self.default_flip_type if flip_type is None else flip_type
        self.pre_extent = None if self.temporal_extent.lower == 0 else Interval(
            0, self.temporal_extent.lower)
        self.post_extent = None if self.temporal_extent.upper >= self.source_line.duration else\
            Interval(self.temporal_extent.upper, self.source_line.duration.duration)

        score_line = self._reset_pitches(as_copy)

        score_hct = self._rebuild_hct(self.source_hct, as_copy)

        return score_line, score_hct
Beispiel #4
0
    def test_sub_line(self):
        print('----- test_sub_line -----')

        source_instance_expression = '{<C-Major:I> qC:4 D E F <:v> [iD:5 B:4 A G] qC:5 D <:I> G:4 iF E hC}'
        lge = LineGrammarExecutor()

        source_instance_line, source_instance_hct = lge.parse(
            source_instance_expression)

        sub_line, start, duration = source_instance_line.sub_line(
            Interval(Fraction(1, 2), Fraction(2)))

        print(str(source_instance_line))
        print(str(sub_line))

        notes = sub_line.get_all_notes()
        assert notes is not None
        assert len(notes) == 8
        assert 'E:4' == str(notes[0].diatonic_pitch)
        assert 'F:4' == str(notes[1].diatonic_pitch)

        with self.assertRaises(Exception) as context:
            source_instance_line.sub_line(Interval(Fraction(1), Fraction(5,
                                                                         4)))
            self.assertTrue('This is broken' in str(context.exception))

        sub_line, start, duration = source_instance_line.sub_line()

        print(str(source_instance_line))
        print(str(sub_line))

        assert sub_line.duration.duration == Fraction(3)
Beispiel #5
0
    def test_simple_equals(self):
        int_interval = Interval(5, 9)

        assert int_interval == Interval(5, 9)

        assert int_interval != Interval(5, 9, BoundaryPolicy.Closed)
        assert int_interval == Interval(5, 9, BoundaryPolicy.HI_Open)
        assert int_interval != Interval(4, 7)
Beispiel #6
0
    def test_overlap_vs_start(self):
        c = InstrumentCatalog.instance()
        violin = c.get_instrument("violin")

        note0 = Note(DiatonicPitch(4, 'a'), Duration(1, 8))
        note1 = Note(DiatonicPitch(4, 'b'), Duration(1, 8))
        note2 = Note(DiatonicPitch(4, 'c'), Duration(1, 8))
        note3 = Note(DiatonicPitch(4, 'd'), Duration(1, 8))

        line = Line()
        line.pin(note0, Offset(1, 4))
        line.pin(note1, Offset(3, 8))
        line.pin(note2, Offset(1, 2))
        line.pin(note3, Offset(5, 8))

        voice = Voice(violin)
        voice.pin(line, Offset(0))

        interval = Interval(Position(5, 16), Position(5, 8))

        notes = voice.get_notes_by_interval(interval)
        assert len(notes) == 3
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('A:4'))
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('B:4'))
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('C:4'))

        notes = voice.get_notes_starting_in_interval(interval)
        assert len(notes) == 2
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('B:4'))
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('C:4'))

        notee0 = Note(DiatonicPitch(5, 'a'), Duration(1, 2))
        notee1 = Note(DiatonicPitch(5, 'b'), Duration(1, 2))
        line1 = Line()
        line1.pin([notee0, notee1], Offset(0))

        voice.pin(line1, Offset(1, 4))

        notes = voice.get_notes_by_interval(interval)
        assert len(notes) == 4
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('A:4'))
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('B:4'))
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('C:4'))
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('A:5'))

        notes = voice.get_notes_by_interval(interval, line1)
        assert len(notes) == 1
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('A:5'))

        notes = voice.get_notes_starting_in_interval(interval)
        assert len(notes) == 2
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('B:4'))
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('C:4'))

        notes = voice.get_notes_starting_in_interval(
            Interval(Position(1, 8), Position(3, 8)), line1)
        assert len(notes) == 1
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('A:5'))
Beispiel #7
0
 def test_problem_interval(self):
     print('test problem interval')
     tree = IntervalTree()
     tree.put(Interval(0.0, .5),  MyObject(1))   
     print(tree)
     print('---')
     tree.put(Interval(.5, 1.0),  MyObject(1))
     print(tree)
     print('---')
     tree.put(Interval(1.0, 1.25),  MyObject(1))
     print('Tree for test problem interval')
     print(tree)
Beispiel #8
0
 def test_duplicate_interval(self):
     print('test duplicate interval')
     tree = IntervalTree()
     tree.put(Interval(4.0, 7.0),  MyObject(1))   
     tree.put(Interval(4.0, 7.0),  MyObject(1))
 
     # We want two results - same (equals) interval, two different objects.
     result = tree.query_point(5.9)
     assert result
     assert len(result) == 2
     assert result[0].interval == Interval(4.0, 7.0)
     assert result[1].interval == Interval(4.0, 7.0)
     assert result[0].value != result[1].value
     
     print(tree)
Beispiel #9
0
    def test_two_voices(self):
        print('test two voices')
        c = InstrumentCatalog.instance()
        violin = c.get_instrument("violin")

        note0 = Note(DiatonicPitch(4, 'a'), Duration(1, 8))
        note1 = Note(DiatonicPitch(4, 'b'), Duration(1, 8))
        note2 = Note(DiatonicPitch(4, 'c'), Duration(1, 8))
        tuplet = Tuplet(Duration(1, 8), 2, [note0, note1, note2])

        note3 = Note(DiatonicPitch(4, 'd'), Duration(1, 8))
        note4 = Note(DiatonicPitch(4, 'e'), Duration(1, 8))
        subbeam = Beam([note3, note4])
        beam = Beam(subbeam)
        line1 = Line([tuplet, beam])
        print(line1)

        notee0 = Note(DiatonicPitch(5, 'a'), Duration(1, 8))
        notee1 = Note(DiatonicPitch(5, 'b'), Duration(1, 8), 1)
        notee2 = Note(DiatonicPitch(5, 'c'), Duration(1, 8))
        notee3 = Note(DiatonicPitch(5, 'd'), Duration(1, 16))
        line2 = Line([notee0, notee1, notee2])
        line2.pin(notee3, Offset(1, 2))
        print(line2)

        voice = Voice(violin)
        voice.pin(line1, Offset(1, 4))
        voice.pin(line2, Offset(0, 1))

        print(voice)

        interval = Interval(Position(1, 2), Position(1))
        notes = voice.get_notes_by_interval(interval)

        assert len(notes) == 3
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('D:4'))
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('E:4'))
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('D:5'))

        interval = Interval(Position(1, 4), Position(7, 16))
        notes = voice.get_notes_by_interval(interval)

        assert len(notes) == 5
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('A:4'))
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('B:4'))
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('C:4'))
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('B:5'))
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('C:5'))
    def test_hct_rebuild_perfect_overlap(self):
        print('----- test_hct_rebuild_perfect_overlap -----')

        line_str = '{<C-Major: I> hA:5 <:IV> B  qC G <:VI> hD}'
        lge = LineGrammarExecutor()
        target_line, target_hct = lge.parse(line_str)

        print('--- before transformation ---')
        TestTChromaticFlip.print_notes(target_line)
        TestTChromaticFlip.print_hct(target_hct)

        cue = DiatonicPitch(5, 'c')

        f = TChromaticReflection(target_line, target_hct, cue)

        temporal_extent = Interval(Fraction(1, 2), Fraction(3, 2))
        score_line, score_hct = f.apply(temporal_extent, cue)
        print('--- after transformation ---')
        TestTChromaticFlip.print_notes(score_line)
        TestTChromaticFlip.print_hct(score_hct)

        print('--- transformation ---')
        TestTChromaticFlip.print_function(f, target_hct)

        notes = score_line.get_all_notes()
        assert 'Db:4' == str(notes[1].diatonic_pitch)
        assert 'C:5' == str(notes[2].diatonic_pitch)
        assert 'F:4' == str(notes[3].diatonic_pitch)

        hc_list = score_hct.hc_list()
        assert len(hc_list) == 3
        assert hc_list[1].chord.chord_template.scale_degree == 1
        assert {t[0].diatonic_symbol
                for t in hc_list[1].chord.tones} == {'G', 'C', 'Eb'}
        assert hc_list[1].chord.chord_template.inversion == 3
Beispiel #11
0
 def get_notes_by_bp_interval(self, interval):
     conversion = TimeConversion(self.tempo_sequence,
                                 self.time_signature_sequence,
                                 Position(self.duration.duration))
     wnt_interval = Interval(conversion.bp_to_position(interval.lower),
                             conversion.bp_to_position(interval.upper))
     return self.get_notes_by_wnt_interval(wnt_interval)
Beispiel #12
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
Beispiel #13
0
    def test_add_notes_to_line(self):
        c = InstrumentCatalog.instance()
        violin = c.get_instrument("violin")

        note0 = Note(DiatonicPitch(4, 'a'), Duration(1, 8))
        note1 = Note(DiatonicPitch(4, 'b'), Duration(1, 8))
        note2 = Note(DiatonicPitch(4, 'c'), Duration(1, 8))
        note3 = Note(DiatonicPitch(4, 'd'), Duration(1, 8))

        line = Line()
        line.pin(note0, Offset(1, 4))
        line.pin(note1, Offset(3, 8))
        line.pin(note2, Offset(1, 2))
        line.pin(note3, Offset(5, 8))

        voice = Voice(violin)
        voice.pin(line, Offset(0))

        notee0 = Note(DiatonicPitch(5, 'a'), Duration(1, 8))
        notee1 = Note(DiatonicPitch(5, 'b'), Duration(1, 8))
        line.pin([notee0, notee1], Offset(3, 4))

        notes = voice.get_notes_starting_in_interval(
            Interval(Position(5, 8), Position(2, 1)))
        assert len(notes) == 3
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('D:4'))
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('A:5'))
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('B:5'))
Beispiel #14
0
    def test_simple_interval(self):
        int_interval = Interval(5, 9)

        assert int_interval.contains(7)
        assert int_interval.contains(6)

        assert Interval.intersects(int_interval, Interval(7, 10))
        assert int_interval.intersection(Interval(7, 10)) == Interval(
            7, 9).intersection(int_interval)
    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
Beispiel #16
0
 def test_overlapping_stair(self):
     tree = IntervalTree()
     for i in range(1, 4):
         tree.put(Interval(i, i + 3), MyObject(i))
     print('Tree for test overlapping stair')
     print(tree)
     
     result = tree.query_point(1.5)
     assert result
     assert len(result) == 1
     assert sum(x.value.idd for x in result) == 1
     
     result = tree.query_point(2.5)
     assert result
     assert len(result) == 2
     assert sum(x.value.idd for x in result) == 3
     
     result = tree.query_point(3.5)
     assert result
     assert len(result) == 3
     assert sum(x.value.idd for x in result) == 6
     
     result = tree.query_point(4.5)
     assert result
     assert len(result) == 2
     assert sum(x.value.idd for x in result) == 5
     
     result = tree.query_point(5.5)
     assert result
     assert len(result) == 1
     assert sum(x.value.idd for x in result) == 3
     
     result = tree.query_point(6.5)
     assert len(result) == 0
     
     result = tree.query_interval(Interval(2, 3))
     assert len(result) == 2
     assert sum(w.value.idd for w in result) == 3
     print(', '.join((str(w) for w in result)))
     
     result = tree.query_interval(Interval(3, 4))
     assert len(result) == 3
     assert sum(w.value.idd for w in result) == 6
     print(', '.join((str(w) for w in result)))
Beispiel #17
0
    def apply(self,
              temporal_extent=None,
              root_shift_interval=None,
              modal_index=None,
              range_modality_type=None,
              as_copy=True):
        """
        Apply transform to a temporal extent.
        :param temporal_extent: numerical interval indicating start/end offsets on line to apply shift.
                                Interval from misc.interval
        :param root_shift_interval: root tone shift.
        :param modal_index: modal index for the new key.
        :param range_modality_type: modality type for the new key.
        :param as_copy: True means to return copys of line, hct as source_line, source_hct would be modified otherwise.
        :return: modified line and hct (as objects, the same as passed in.)
        """
        # If temporal_extent is None, use the whole range of hct.
        self.temporal_extent = temporal_extent if temporal_extent is not None else \
            Interval(Fraction(0), self.source_hct.duration.duration)

        self.pre_extent = None if self.temporal_extent.lower == 0 else Interval(
            0, self.temporal_extent.lower)
        self.post_extent = None if self.temporal_extent.upper >= self.source_line.duration else \
            Interval(self.temporal_extent.upper, self.source_line.duration.duration)

        self.root_shift_interval = self.default_root_shift_interval if root_shift_interval is None \
            else root_shift_interval
        self.modal_index = self.default_modal_index if modal_index is None else modal_index

        if range_modality_type is not None and isinstance(
                range_modality_type, int):
            range_modality_type = ModalityType(range_modality_type)
        self.range_modality_type = self.default_range_modality_type if range_modality_type is None \
            else range_modality_type

        self.hc_pitch_function_map = dict()

        score_line = self._reset_pitches(as_copy)

        score_hct = self._rebuild_hct(self.source_hct, as_copy)

        return score_line, score_hct
Beispiel #18
0
 def _add_notes_to_tree(self, notes):
     for note in notes:
         
         # check of note is in range of the voice's instrument..
         if note.diatonic_pitch.chromatic_distance < self.instrument.sounding_low.chromatic_distance or \
            note.diatonic_pitch.chromatic_distance > self.instrument.sounding_high.chromatic_distance:
             raise Exception('Note {0} not in instrument {1} sounding range'.format(note, self.instrument)) 
         
         interval = Interval(note.get_absolute_position(), 
                             note.get_absolute_position() + note.duration)
         self.interval_tree.put(interval, note)
Beispiel #19
0
 def get_notes_starting_in_bp_interval(self, interval):
     """
     Get all notes starting in the score by an interval based on beat position:  Return dict structure as follows:
         instrument_voice --> {voice_index --> [notes]}
     """
     conversion = TimeConversion(self.tempo_sequence,
                                 self.time_signature_sequence,
                                 Position(self.duration.duration))
     wnt_interval = Interval(conversion.bp_to_position(interval.lower),
                             conversion.bp_to_position(interval.upper))
     return self.get_notes_starting_in_wnt_interval(wnt_interval)
Beispiel #20
0
 def _remove_notes_from_tree(self, notes):
     # remove all intervals from the old line
     for note in notes:
         interval = Interval(note.get_absolute_position().position, 
                             note.get_absolute_position().position + note.duration.duration)
         result = self.interval_tree.find_exact_interval(interval)
         for interval_info in result:
             if interval_info.value == note:
                 self.interval_tree.delete(interval_info)  
                 
         if note in self.articulation_map:
             del self.articulation_map[note]      
Beispiel #21
0
    def test_delete_with_one_child(self):
        print('Test delete with one child')
        tree = IntervalTree()
        tree.put(Interval(15, 30), MyObject(1))
        tree.put(Interval(5, 10), MyObject(2))

        tree.put(Interval(16, 30), MyObject(3))
        tree.put(Interval(18, 25), MyObject(5))
        tree.put(Interval(20, 40), MyObject(4))
        tree.put(Interval(23, 50), MyObject(6))      
        
        # 20 should have a right node only
        print(tree)
        result = tree.query_point(20)
        f = None
        for r in result:
            if r.rb_node.key == 20:
                f = r
                break
        assert f
        assert f.rb_node.left == tree.nil
        assert f.rb_node.right != tree.nil
        
        tree.delete(f)
        print(tree)
        result = tree.query_point(20)
        f = None
        for r in result:
            if r.rb_node.key == 20:
                f = r
                break
        assert not f
Beispiel #22
0
    def test_delete_min_max(self):
        print('Test delete min max')
        tree = IntervalTree()
        tree.put(Interval(15, 30), MyObject(1))
        tree.put(Interval(5, 10), MyObject(2))

        tree.put(Interval(16, 30), MyObject(3))
        tree.put(Interval(18, 25), MyObject(5))
        tree.put(Interval(20, 40), MyObject(4))
        tree.put(Interval(23, 50), MyObject(6))      
        
        # 23 span is 23-50
        print(tree)
        result = tree.query_point(23)
        f = None
        for r in result:
            if r.rb_node.key == 23:
                f = r
                break
        assert f
        assert f.rb_node.key == 23
        
        tree.delete(f)
        print(tree)
        assert tree.root.max == 40
Beispiel #23
0
    def test_delete_with_two_child(self):
        print('Test delete with two children')
        tree = IntervalTree()
        tree.put(Interval(15, 30), MyObject(1))
        tree.put(Interval(5, 10), MyObject(2))

        tree.put(Interval(16, 30), MyObject(3))
        tree.put(Interval(18, 25), MyObject(5))
        tree.put(Interval(20, 40), MyObject(4))
        tree.put(Interval(23, 50), MyObject(6))      
        
        # 18 should have left and right
        print(tree)
        result = tree.query_point(18)
        f = None
        for r in result:
            if r.rb_node.key == 18:
                f = r
                break
        assert f
        assert f.rb_node.left != tree.nil
        assert f.rb_node.right != tree.nil
        
        tree.delete(f)
        print(tree)
        
        result = tree.query_point(18)
        f = None
        for r in result:
            if r.rb_node.key == 18:
                f = r
                break
        assert not f
Beispiel #24
0
 def get_notes(self, start_position, end_position, line=None):
     """
     Get all notes in explicit interval given as lower/upper bounds, [)
     
     Args:
       start_position: Position of the start of the interval (inclusive)
       end_position: Position of the end of the interval (non-inclusive)
       line: Optionsl Line to restrict search to:
       
     Returns:
       List of notes satisfying query
     """
     return self.get_notes_by_interval(Interval(start_position, end_position), line)
Beispiel #25
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
Beispiel #26
0
    def test_remove_notes(self):
        c = InstrumentCatalog.instance()
        violin = c.get_instrument("violin")

        note0 = Note(DiatonicPitch(4, 'a'), Duration(1, 8))
        note1 = Note(DiatonicPitch(4, 'b'), Duration(1, 8))
        note2 = Note(DiatonicPitch(4, 'c'), Duration(1, 8))
        note3 = Note(DiatonicPitch(4, 'd'), Duration(1, 8))

        line = Line()
        line.pin(note0, Offset(1, 4))
        line.pin(note1, Offset(3, 8))
        line.pin(note2, Offset(1, 2))
        line.pin(note3, Offset(5, 8))

        voice = Voice(violin)
        voice.pin(line, Offset(0))

        line.unpin([note1, note2])
        notes = voice.get_all_notes()
        assert len(notes) == 2
        assert note0 in notes
        assert note3 in notes
        assert note1 not in notes
        assert note2 not in notes

        notes = voice.get_notes_starting_in_interval(
            Interval(Position(0), Position(2, 1)))
        assert len(notes) == 2

        line.clear()
        notes = voice.get_all_notes()
        assert len(notes) == 0

        notes = voice.get_notes_starting_in_interval(
            Interval(Position(0), Position(2, 1)))
        assert len(notes) == 0
    def test_hct_rebuild_perfect_overlap(self):
        print('----- test_hct_rebuild_perfect_overlap -----')

        line_str = '{<C-Major: I> hA:5 <:IV> B  qC G <:VI> hD}'
        lge = LineGrammarExecutor()
        target_line, target_hct = lge.parse(line_str)
        TestTFlip.print_hct(target_hct)

        cue = DiatonicPitch(5, 'd')

        tflip = TDiatonicReflection(target_line, target_hct, cue)

        temporal_extent = Interval(Fraction(1, 2), Fraction(3, 2))
        score_line, score_hct = tflip.apply(temporal_extent, cue)
        TestTFlip.print_notes(score_line)
        TestTFlip.print_hct(score_hct)

        hc_list = score_hct.hc_list()
        assert hc_list[0].position == Position(0)
        assert hc_list[0].duration == Duration(1, 2)
        assert hc_list[0].chord.chord_type == TertianChordType(
            TertianChordType.Maj)
        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[1].position == Position(1, 2)
        assert hc_list[1].duration == Duration(1)
        assert hc_list[1].chord.chord_type == TertianChordType(
            TertianChordType.Min)
        assert hc_list[1].chord.chord_template.scale_degree == 3
        assert {t[0].diatonic_symbol
                for t in hc_list[1].chord.tones} == {'G', 'B', 'E'}
        assert hc_list[1].chord.chord_template.inversion == 3

        assert hc_list[2].position == Position(3, 2)
        assert hc_list[2].duration == Duration(1, 2)
        assert hc_list[2].chord.chord_type == TertianChordType(
            TertianChordType.Min)
        assert hc_list[2].chord.chord_template.scale_degree == 6
        assert {t[0].diatonic_symbol
                for t in hc_list[2].chord.tones} == {'A', 'C', 'E'}
        assert hc_list[2].chord.chord_template.inversion == 1

        notes = score_line.get_all_notes()
        assert str(notes[1].diatonic_pitch) == "F:4"
        assert str(notes[2].diatonic_pitch) == "E:5"
        assert str(notes[3].diatonic_pitch) == "A:4"
Beispiel #28
0
    def test_access(self):
        mock = MagicMock(spec=IntervalTree)
        interval = Interval(2, 4)
        value = Fraction(2, 5)
        node = RBNode(interval, value, mock)

        assert node.interval == interval
        assert node.key == interval.lower
        assert node.value == value
        assert node.min == 2
        assert node.max == 4

        assert not node.parent
        assert node.left == node.nil
        assert node.right == node.nil
Beispiel #29
0
    def test_match_interval_book(self):
        print('Test match interval - book')

        tree = IntervalTree()
        tree.put(Interval(15, 30), MyObject(1))
        tree.put(Interval(16, 30), MyObject(3))
        tree.put(Interval(18, 25), MyObject(5))
        tree.put(Interval(20, 40), MyObject(4))
        tree.put(Interval(23, 50), MyObject(6))
        tree.put(Interval(5, 10), MyObject(2))

        result = tree.find_exact_interval(Interval(16, 30))
        assert result is not None
        assert len(result) == 1

        assert result[0].interval == Interval(16, 30)

        print(tree)
Beispiel #30
0
    def test_book_example(self):
        # Default is HI_Open
        f_interval = Interval(Fraction(1, 4), Fraction(3, 5))
        print(f_interval)
        assert f_interval.contains(Fraction(1, 4))
        assert not f_interval.contains(Fraction(3, 5))

        # Intervals can be constructed with integer ranges. Note the resulting boundary policy.
        interval = Interval(1, 5, BoundaryPolicy.Closed).intersection(
            Interval(4, 6, BoundaryPolicy.Open))
        assert interval.policy == BoundaryPolicy.LO_Open
        print(interval)