예제 #1
0
    def test_simple_tuplet_reverse(self):
        print('test simple tuplet reverse')
        a = Note(DiatonicPitch(3, 'a'), Duration(1, 8))
        b = Note(DiatonicPitch(3, 'b'), Duration(1, 8))
        c = Note(DiatonicPitch(3, 'c'), Duration(1, 8))
        d = Note(DiatonicPitch(3, 'd'), Duration(1, 8))
        tuplet = Tuplet(Duration(1, 8), 3, [a, b, c, d])

        print(tuplet)

        tuplet.reverse()

        print(tuplet)

        notes = tuplet.get_all_notes()
        assert notes is not None
        assert len(notes) == 4
        assert notes[0].diatonic_pitch == DiatonicPitch(3, 'd')
        assert notes[1].diatonic_pitch == DiatonicPitch(3, 'c')
        assert notes[2].diatonic_pitch == DiatonicPitch(3, 'b')
        assert notes[3].diatonic_pitch == DiatonicPitch(3, 'a')

        assert notes[0].relative_position == Offset(0)
        assert notes[1].relative_position == Offset(3, 32)
        assert notes[2].relative_position == Offset(3, 16)
        assert notes[3].relative_position == Offset(9, 32)
예제 #2
0
    def test_line_structures(self):
        print('----- test line structures -----')
        source_instance_expression = '{<C-Major:I> iC:4 D E F G A B C:5 D E F G} }'
        lge = LineGrammarExecutor()
        source_instance_line, source_instance_hct = lge.parse(source_instance_expression)
        notes = source_instance_line.get_all_notes()

        line = Line()
        line.pin(notes[0], Offset(Fraction(1, 2)))
        line.pin(notes[1], Offset(Fraction(3, 4)))

        line1 = Line()
        line1.pin(notes[3], Offset(Fraction(1, 4)))
        line1.pin(notes[4], Offset(Fraction(1, 2)))
        line.pin(line1, Offset(Fraction(2)))

        lite_score = TestTDilation.create_score_1(line, source_instance_hct, 'piano', (4, 4, 'swww'))

        trans = TDilation(lite_score)
        new_score = trans.apply(Fraction(2), False, True)
        all_notes = new_score.line.get_all_notes()
        assert all_notes[2].get_absolute_position().position == Fraction(9, 2)

        print(line)
        print(new_score.line)
예제 #3
0
    def test_add_note_at_lower_level(self):
        print('start test_add_note_at_lower_level')
        sub_beam = Beam([
            Note(DiatonicPitch(2, 'c'), Duration(1, 8)),
            Note(DiatonicPitch(2, 'd'), Duration(1, 8))
        ])
        beam = Beam([
            Note(DiatonicPitch(3, 'c'), Duration(1, 8)), sub_beam,
            Note(DiatonicPitch(3, 'd'), Duration(1, 8))
        ])

        AbstractNote.print_structure(beam)

        notes = beam.get_all_notes()
        assert len(notes) == 4

        assert beam.sub_notes[1].duration == Duration(1, 8)
        assert beam.sub_notes[1].relative_position == Offset(1, 8)
        assert beam.sub_notes[1].sub_notes[1].duration == Duration(1, 16)
        assert beam.sub_notes[1].sub_notes[1].relative_position == Offset(
            1, 16)

        sub_beam.add(Note(DiatonicPitch(2, 'c'), Duration(1, 8)), 1)
        AbstractNote.print_structure(beam)

        assert beam.sub_notes[1].duration == Duration(3, 16)
        assert beam.sub_notes[1].relative_position == Offset(1, 8)
        assert beam.sub_notes[1].sub_notes[1].duration == Duration(1, 16)
        assert beam.sub_notes[1].sub_notes[1].relative_position == Offset(
            1, 16)
예제 #4
0
    def test_book_example(self):
        print('----- book_example -----')

        voice_line = Line()
        melody_line = Line()

        melody_1 = Line(
            [Note(DiatonicPitch(4, y), Duration(1, 8)) for y in 'aceg'])
        melody_2 = Line(
            [Note(DiatonicPitch(4, y), Duration(1, 8)) for y in 'cadg'])
        base_line = Line(
            [Note(DiatonicPitch(4, y), Duration(1, 4)) for y in 'dddddddd'])

        melody_line.pin(melody_1, Offset(1, 8))
        melody_line.pin(melody_2, Offset(1, 4))
        voice_line.pin(melody_line)
        voice_line.pin(base_line)

        print(voice_line)

        all_notes = voice_line.get_all_notes()
        print('... pinned notes ...')
        for n in all_notes:
            print('({0}) : {1}'.format(n.get_absolute_position(),
                                       n.diatonic_pitch))
        print('... end pinned notes ...')

        print('End test_pin')
예제 #5
0
    def test_simple_beam_reverse(self):
        print('test simple beam reverse')
        a = Note(DiatonicPitch(3, 'a'), Duration(1, 8))
        b = Note(DiatonicPitch(3, 'b'), Duration(1, 8))
        c = Note(DiatonicPitch(3, 'c'), Duration(1, 8))
        d = Note(DiatonicPitch(3, 'd'), Duration(1, 8))
        beam = Beam([a, b, c, d])

        print(beam)

        beam.reverse()

        print(beam)

        notes = beam.get_all_notes()
        assert notes is not None
        assert len(notes) == 4
        assert notes[0].diatonic_pitch == DiatonicPitch(3, 'd')
        assert notes[1].diatonic_pitch == DiatonicPitch(3, 'c')
        assert notes[2].diatonic_pitch == DiatonicPitch(3, 'b')
        assert notes[3].diatonic_pitch == DiatonicPitch(3, 'a')

        assert notes[0].relative_position == Offset(0)
        assert notes[1].relative_position == Offset(1, 8)
        assert notes[2].relative_position == Offset(1, 4)
        assert notes[3].relative_position == Offset(3, 8)
예제 #6
0
    def test_nested_notes(self):
        note1 = Note(DiatonicPitch(4, 'c'), Duration(1, 8))
        note2 = Note(DiatonicPitch(4, 'd'), Duration(1, 8))
        note3 = Note(DiatonicPitch(4, 'e'), Duration(1, 16))
        sub_beam = Beam([note1, note2, note3])

        beam = Beam()
        beam.append(Note(DiatonicPitch(4, 'f'), Duration(1, 8)))
        beam.append(sub_beam)
        beam.append(Note(DiatonicPitch(4, 'g'), Duration(1, 8)))

        print(beam)

        notes = beam.get_all_notes()
        assert len(notes) == 5
        assert notes[0].diatonic_pitch == DiatonicPitch(4, 'f')
        assert notes[1].diatonic_pitch == DiatonicPitch(4, 'c')
        assert notes[2].diatonic_pitch == DiatonicPitch(4, 'd')
        assert notes[3].diatonic_pitch == DiatonicPitch(4, 'e')
        assert notes[4].diatonic_pitch == DiatonicPitch(4, 'g')

        assert notes[0].relative_position == Offset(0)
        assert notes[1].relative_position == Offset(0)
        assert notes[2].relative_position == Offset(1, 16)
        assert notes[3].relative_position == Offset(1, 8)
        assert notes[4].relative_position == Offset(9, 32)
        TestBeam.print_all_notes(notes)

        notes = sub_beam.get_all_notes()
        TestBeam.print_all_notes(notes)

        b = Beam()
        b.append(beam)

        notes = sub_beam.get_all_notes()
        TestBeam.print_all_notes(notes)
        assert notes[0].duration == Duration(1, 32)
        assert str(notes[0].diatonic_pitch) == 'C:4'

        sub_beam_prime = sub_beam.clone()
        notes = sub_beam_prime.get_all_notes()
        TestBeam.print_all_notes(notes)
        assert notes[0].duration == Duration(1, 8)
        assert str(notes[0].diatonic_pitch) == 'C:4'

        beam_prime = beam.clone()
        notes = beam_prime.get_all_notes()
        TestBeam.print_all_notes(notes)
        assert notes[0].duration == Duration(1, 8)
        assert str(notes[0].diatonic_pitch) == 'F:4'

        b_prime = b.clone()
        notes = b_prime.get_all_notes()
        TestBeam.print_all_notes(notes)
        assert notes[0].duration == Duration(1, 16)
        assert str(notes[0].diatonic_pitch) == 'F:4'
예제 #7
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 convert_line(line,
                     tempo=Tempo(60, Duration(1, 4)),
                     time_signature=TimeSignature(4, Duration(1, 4)),
                     channel_assignments=None,
                     fps=42100):
        """
        Static method to convert a Line to a midi file

        Args:
          :param line: Class Line object
          :param tempo: Tempo for playback, default is 60 BPM tempo beat = quarter note
          :param time_signature: TimeSiganture on playback, default is 4 quarter notes
          :param channel_assignments:
          :param fps: frames per second setting

        """
        score = Score()
        tempo_sequence = score.tempo_sequence
        tempo_sequence.add(TempoEvent(tempo, Position(0)))

        ts_sequence = score.time_signature_sequence
        ts_sequence.add(TimeSignatureEvent(time_signature, Position(0)))

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

        piano_instrument_voice = InstrumentVoice(piano, 1)
        piano_voice = piano_instrument_voice.voice(0)

        piano_voice.pin(line, Offset(0))

        score.add_instrument_voice(piano_instrument_voice)
        return ScoreToVstMidiConverter.convert_score(score,
                                                     channel_assignments, fps)
예제 #9
0
파일: line.py 프로젝트: dpazel/music_rep
    def pin(self, note_structure, offset=Offset(0)):
        """
        Given a note_structure (Line, Note, Tuplet, Beam), make it an immediate child to this line.
        If it is a list, the members are added in note sequence, with offset being adjusted appropriately.
        
        Args:
          note_structure: (List of Line, Note, Tuplet, Beam) to add
          offset:  (Offset), of the first in list or given structure.
        """

        if not isinstance(offset, Offset):
            raise Exception(
                'Offset parameter in pin() must be of type Offset, not \'{0}\'.'
                .format(type(offset)))
        if isinstance(note_structure, list):
            for n in note_structure:
                self._append_note(n, offset)
                offset += n.duration
        else:
            self._append_note(note_structure, offset)

        # sort by relative offset    Pins can happen any where, this helps maintains some sequential order to the line
        sorted(self.sub_notes, key=lambda n1: n1.relative_position)

        self.update(Line.LINE_NOTES_ADDED_EVENT, None, note_structure)
예제 #10
0
    def upward_forward_reloc_layout(self, abstract_note):
        """
        Called by Beam on Beam content alteration, it climbs the tree upward and to the right.
        making relative position adjustments along the way.  It stops when it hits either a null parent
        or a tuplet.  Since tuplets will not change size, there is no need to proceed higher up the tree.
        However, at that top tuplet level, it is appropriate to call Tuplet.rescale() as the lower contents
        have changed and can affect the tuplet's rescaling factor.
        
        Args:
          abstract_note: the affected child note of self.sub_notes which causes the relocataion layout.
        """
        from structure.tuplet import Tuplet
        try:
            index = self.sub_notes.index(abstract_note)
        except ValueError:
            raise Exception('Could note location index for {0} in {1}'.format(
                abstract_note, type(self)))

        current_position = Offset(0) if index == 0 else \
            self.sub_notes[index - 1].relative_position + self.sub_notes[index - 1].duration
        for i in range(index, len(self.sub_notes)):
            self.sub_notes[i].relative_position = current_position
            current_position += self.sub_notes[i].duration

        # Once size no longer changes, no need to propagate
        if self.parent is not None and not isinstance(self.parent, Tuplet):
            self.parent.upward_forward_reloc_layout(self)

        if self.parent is not None and isinstance(self.parent, Tuplet):
            self.parent.rescale()
예제 #11
0
    def test_pin(self):
        print('----- test_pin -----')

        l1_notes = [Note(DiatonicPitch(4, y), Duration(1, 8)) for y in 'abcd']
        l2_notes = [Note(DiatonicPitch(4, y), Duration(1, 8)) for y in 'efgab']
        line = Line()
        line.pin(Line(l1_notes), Offset(1, 8))
        line.pin(Line(l2_notes), Offset(1, 4))

        all_notes = line.get_all_notes()
        print('... pinned notes ...')
        for n in all_notes:
            print('({0}) : {1}'.format(n.get_absolute_position(),
                                       n.diatonic_pitch))
        print('... end pinned notes ...')

        print('End test_pin')
예제 #12
0
    def test_multi_notes(self):
        note0 = Note(DiatonicPitch(4, 'c'), Duration(1, 8))
        note1 = Note(DiatonicPitch(4, 'd'), Duration(1, 8), 1)
        note2 = Note(DiatonicPitch(4, 'e'), Duration(1, 16))
        beam = Beam([note0, note1, note2])
        print(beam)
        assert beam.cardinality() == 3
        notes = beam.get_all_notes()
        assert notes[0].diatonic_pitch == DiatonicPitch(4, 'c')
        assert notes[1].diatonic_pitch == DiatonicPitch(4, 'd')
        assert notes[2].diatonic_pitch == DiatonicPitch(4, 'e')
        assert beam.duration == Duration(3, 8)
        assert notes[0].relative_position == Offset(0)
        assert notes[1].relative_position == Offset(1, 8)
        assert notes[2].relative_position == Offset(5, 16)

        assert len(notes) == 3
        TestBeam.print_all_notes(notes)
예제 #13
0
    def test_simple_motif(self):
        line = Line()
        notes = [
            Note(DiatonicPitch.parse('C:4'), Duration(1, 4)),
            Note(DiatonicPitch.parse('D:4'), Duration(1, 8)),
            Note(DiatonicPitch.parse('E:4'), Duration(1, 8)),
            Note(DiatonicPitch.parse('F#:4'), Duration(1, 2)),
        ]

        line.pin(notes)

        c = [
            EqualPitchConstraint([notes[0], notes[2]]),
            NotEqualPitchConstraint([notes[1], notes[3]])
        ]

        nm = Phrase(notes, c, 'B')

        print(nm)

        assert nm.name == 'B'
        actors = nm.actors

        assert len(actors) == 4

        cc = nm.constraints
        assert isinstance(cc[0], EqualPitchConstraint)
        cc_a = cc[0].actors
        assert len(cc_a) == 2
        assert cc_a[0] == actors[0]
        assert cc_a[1] == actors[2]

        assert isinstance(cc[1], NotEqualPitchConstraint)
        cc_b = cc[1].actors
        assert len(cc_a) == 2
        assert cc_b[0] == actors[1]
        assert cc_b[1] == actors[3]
        assert 'F#:4' == str(actors[3].diatonic_pitch)

        # More notes for copy to:
        first_note = Note(DiatonicPitch.parse('C:3'), Duration(1, 4))
        notes1 = [
            first_note,
            Note(DiatonicPitch.parse('D:3'), Duration(1, 8)),
            Note(DiatonicPitch.parse('E:3'), Duration(1, 8)),
            Note(DiatonicPitch.parse('F#:3'), Duration(1, 2)),
        ]
        line.pin(notes1, Offset(2))

        nm_clone = nm.copy_to(first_note)
        assert isinstance(nm_clone, Phrase)
        assert nm_clone.name == 'B'
        c_actors = nm_clone.actors

        assert len(c_actors) == 4
        assert 'F#:3' == str(c_actors[3].diatonic_pitch)
예제 #14
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'))
예제 #15
0
 def unpin(self, line):
     if not isinstance(line, Line):
         raise Exception('Voice can only unpin Line\'s, {0} received'.format(type(line)))
     if line not in self.__lines:
         raise Exception('Voice can only unpin lines it owns')
     self.__lines.remove(line)
     line.relative_position = Offset(0)
     line.deregister(self)
     
     self._remove_notes_from_tree(line.get_all_notes())
예제 #16
0
    def test_add_notes_to_tuplet(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))
        beam = Beam([note0, note1])

        line = Line()
        line.pin(beam, Offset(1, 2))

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

        tuplet = Tuplet(Duration(1, 8), 3, [note2, note3])
        beam.append(tuplet)

        notee0 = Note(DiatonicPitch(5, 'a'), Duration(1, 8))
        tuplet.append(notee0)

        print(voice)
        notes = voice.get_notes_starting_in_interval(
            Interval(Position(1, 2), Position(5, 4)))

        assert len(notes) == 5
        assert TestVoice.has_pitch(notes, DiatonicPitch.parse('A:5'))

        beam_prime = beam.clone()
        notes = beam_prime.get_all_notes()
        AbstractNote.print_structure(beam_prime)
        assert notes[0].duration == Duration(1, 8)
        assert str(notes[0].diatonic_pitch) == 'A:4'

        line_prime = line.clone()
        notes = line_prime.get_all_notes()
        AbstractNote.print_structure(line_prime)
        assert notes[0].duration == Duration(1, 8)
        assert str(notes[0].diatonic_pitch) == 'A:4'
        assert notes[2].duration == Duration(1, 8)
        assert str(notes[2].diatonic_pitch) == 'C:4'
예제 #17
0
    def test_tuplet_with_nested_beam(self):
        note1 = Note(DiatonicPitch(4, 'c'), Duration(1, 8))
        note2 = Note(DiatonicPitch(4, 'd'), Duration(1, 8))

        n_list = [
            Note(DiatonicPitch(3, 'c'), Duration(1, 8)),
            Note(DiatonicPitch(3, 'd'), Duration(1, 8))
        ]
        add_beam = Beam(n_list)

        tuplet = Tuplet(Duration(1, 8), 2, [note1, add_beam, note2])

        print(tuplet)
        AbstractNote.print_structure(tuplet)

        notes = tuplet.get_all_notes()
        assert len(notes) == 4

        assert tuplet.sub_notes[0].duration == Duration(1, 16)
        assert tuplet.sub_notes[0].relative_position == Offset(0)
        assert tuplet.sub_notes[1].duration == Duration(1, 8)
        assert tuplet.sub_notes[1].relative_position == Offset(1, 16)
        assert tuplet.sub_notes[2].duration == Duration(1, 16)
        assert tuplet.sub_notes[2].relative_position == Offset(3, 16)
        assert notes[1].duration == Duration(1, 16)
        assert notes[1].relative_position == Offset(0)
        assert notes[2].duration == Duration(1, 16)
        assert notes[2].relative_position == Offset(1, 16)

        add_beam_prime = add_beam.clone()
        notes = add_beam_prime.get_all_notes()
        AbstractNote.print_structure(add_beam_prime)
        assert notes[0].duration == Duration(1, 8)
        assert str(notes[0].diatonic_pitch) == 'C:3'

        tuplet_prime = tuplet.clone()
        notes = tuplet_prime.get_all_notes()
        AbstractNote.print_structure(tuplet_prime)
        assert notes[0].duration == Duration(1, 16)
        assert str(notes[0].diatonic_pitch) == 'C:4'
        assert notes[1].duration == Duration(1, 16)
예제 #18
0
 def tempo(self, position, next_event_position):
     """
     Compute the tempo at a given position (re: TempoEventSequence)
     
     Args:
       position: The absolute position (Position) to evaluate at
       next_event_position:  The position (Position) of the starting of the next event.  Can be None is none exists.
     Returns:
       tempo numeric as bpm based on tempo beat
     """
     return self.object.tempo(Offset(position.position - self.time.position),
                              next_event_position - self.time if next_event_position else Duration(1))
예제 #19
0
    def test_simple_tuplet(self):
        note1 = Note(DiatonicPitch(4, 'c'), Duration(1, 8))
        note2 = Note(DiatonicPitch(4, 'd'), Duration(1, 8))
        note3 = Note(DiatonicPitch(4, 'e'), Duration(1, 8))
        tuplet = Tuplet(Duration(1, 8), 2, [note1, note2, note3])

        print(tuplet)
        AbstractNote.print_structure(tuplet)

        notes = tuplet.get_all_notes()
        assert len(notes) == 3

        assert notes[0].diatonic_pitch == DiatonicPitch(4, 'c')
        assert notes[1].diatonic_pitch == DiatonicPitch(4, 'd')
        assert notes[2].diatonic_pitch == DiatonicPitch(4, 'e')
        assert notes[0].duration == Duration(1, 12)
        assert notes[1].duration == Duration(1, 12)
        assert notes[2].duration == Duration(1, 12)
        assert notes[0].relative_position == Offset(0)
        assert notes[1].relative_position == Offset(1, 12)
        assert notes[2].relative_position == Offset(1, 6)
예제 #20
0
 def velocity(self, position, next_event_position):
     """
     Compute the velocity at a given position (re: DynamicsEventSequence)
     
     Args:
       position: The absolute position (Position) to evaluate at
       next_event_position:  The position (Position) of the starting of the next event.  Can be None is none exists.
     Returns:
       velocity as numerics [0-127] typically
     """
     return self.object.velocity(Offset(position.position - self.time.position),
                                 next_event_position - self.time if next_event_position else Duration(1))
예제 #21
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'))
예제 #22
0
    def test_add_notes_to_two_level_line(self):
        score = Score()

        catalogue = InstrumentCatalog.instance()
        score.add_instrument_voice(
            InstrumentVoice(catalogue.get_instrument("violin")))

        #  1 beat == 1 sec, 3/4 TS + 60 beats per minute,
        score.tempo_sequence.add(TempoEvent(Tempo(60), Position(0)))
        score.time_signature_sequence.add(
            TimeSignatureEvent(TimeSignature(3, Duration(1, 4)), Position(0)))

        violin_voice = score.get_instrument_voice("violin")[0]
        top_line = Line(
            [Note(DiatonicPitch(4, y), Duration(1, 8)) for y in 'afdecd'])
        violin_voice.voice(0).pin(top_line, Offset(0))
        level1_line = Line(
            [Note(DiatonicPitch(5, y), Duration(1, 8)) for y in 'af'])
        top_line.pin(level1_line, Offset(2))
        level2_line = Line(
            [Note(DiatonicPitch(6, y), Duration(1, 8)) for y in 'de'])
        level1_line.pin(level2_line, Offset(1))
예제 #23
0
    def test_TBB_layers(self):
        print('start test_TBB_layers')
        sub_sub_beam = Beam([
            Note(DiatonicPitch(2, 'c'), Duration(1, 8)),
            Note(DiatonicPitch(2, 'd'), Duration(1, 8))
        ])
        sub_beam = Beam([
            Note(DiatonicPitch(3, 'c'), Duration(1, 8)), sub_sub_beam,
            Note(DiatonicPitch(3, 'd'), Duration(1, 8))
        ])

        AbstractNote.print_structure(sub_beam)

        note1 = Note(DiatonicPitch(4, 'c'), Duration(1, 8))
        note2 = Note(DiatonicPitch(4, 'd'), Duration(1, 8))
        print('-----------')
        tuplet = Tuplet(Duration(1, 8), 2, [note1, sub_beam, note2])
        AbstractNote.print_structure(tuplet)

        notes = tuplet.get_all_notes()
        assert len(notes) == 6

        assert tuplet.sub_notes[1].duration == Duration(3, 20)
        assert tuplet.sub_notes[1].relative_position == Offset(1, 20)
        assert tuplet.sub_notes[1].sub_notes[1].duration == Duration(1, 20)
        assert tuplet.sub_notes[1].sub_notes[1].relative_position == Offset(
            1, 20)

        sub_sub_beam.add(Note(DiatonicPitch(2, 'c'), Duration(1, 8)), 1)
        AbstractNote.print_structure(tuplet)

        assert tuplet.sub_notes[1].duration == Duration(7, 44)
        assert tuplet.sub_notes[1].relative_position == Offset(1, 22)
        assert tuplet.sub_notes[1].sub_notes[1].duration == Duration(3, 44)
        assert tuplet.sub_notes[1].sub_notes[1].relative_position == Offset(
            1, 22)

        print('end test_TBB_layers')
    def test_compute_with_minor_key(self):
        print('-- test_compute_with_minor_key ---')
        line = Line()

        f = GenericUnivariatePitchFunction(
            TestFitPitchToFunctionConstraint.sinasoidal, Position(0),
            Position(2))
        v_notes = [
            Note(DiatonicPitch.parse('A:4'), Duration(1, 16))
            for _ in range(0, 33)
        ]
        for i in range(0, 33):
            line.pin(v_notes[i], Offset(i, 16))

        constraint, lower_policy_context = \
            TestFitPitchToFunctionConstraint.build_simple_constraint(v_notes[0], f, ModalityType.NaturalMinor,
                                                                     'C', 'tV')
        constraints = list()
        constraints.append(constraint)
        for i in range(1, 33):
            c, _ = \
                TestFitPitchToFunctionConstraint.build_simple_constraint(v_notes[i], f, ModalityType.NaturalMinor,
                                                                         'C', 'tV')
            constraints.append(c)

        p_map = PMap()
        p_map[v_notes[0]] = ContextualNote(lower_policy_context)

        results = constraint.values(p_map, v_notes[0])
        assert results is not None
        assert len(results) == 1
        print(next(iter(results)).diatonic_pitch)
        assert 'C:4' == str(next(iter(results)).diatonic_pitch)

        result_pitches = []
        for i in range(0, 33):
            p_map = PMap()
            p_map[v_notes[i]] = ContextualNote(lower_policy_context)
            results = constraints[i].values(p_map, v_notes[i])
            result_pitches.append(next(iter(results)).diatonic_pitch)

        assert len(result_pitches) == 33
        for i in range(0, 33):
            print('[{0}] {1}'.format(i, str(result_pitches[i])))

        checks = [
            'C:4', 'G:4', 'D:5', 'F:5', 'G:5', 'F:5', 'D:5', 'G:4', 'C:4'
        ]
        for i in range(0, len(checks)):
            assert checks[i] == str(result_pitches[i])
예제 #25
0
    def test_multi_track(self):
        c = InstrumentCatalog.instance()

        score = Score()

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

        violin = c.get_instrument("violin")
        piano = c.get_instrument("piano")

        note0 = Note(DiatonicPitch(4, 'a'), Duration(1, 4))
        note1 = Note(DiatonicPitch(4, 'b'), Duration(1, 4))
        note2 = Note(DiatonicPitch(4, 'c'), Duration(1, 4))
        note3 = Note(DiatonicPitch(4, 'd'), Duration(1, 4))
        note4 = Note(DiatonicPitch(5, 'g'), Duration(1, 4))
        note5 = Note(DiatonicPitch(5, 'f'), Duration(1, 4))
        note6 = Note(DiatonicPitch(5, 'e'), Duration(1, 4))
        note7 = Note(DiatonicPitch(5, 'd'), Duration(1, 4))

        violin_instrument_voice = InstrumentVoice(violin, 1)
        violin_voice = violin_instrument_voice.voice(0)
        assert violin_voice

        vline = Line([note0, note1, note2, note3])
        violin_voice.pin(vline)

        score.add_instrument_voice(violin_instrument_voice)

        piano_instrument_voice = InstrumentVoice(piano, 1)
        piano_voice = piano_instrument_voice.voice(0)
        assert piano_voice

        pline = Line([note4, note5, note6, note7])
        piano_voice.pin(pline, Offset(1, 8))

        score.add_instrument_voice(piano_instrument_voice)

        violin_voice.dynamics_sequence.add(
            DynamicsEvent(Dynamics(Dynamics.F), Position(0)))
        piano_voice.dynamics_sequence.add(
            DynamicsEvent(Dynamics(Dynamics.P), Position(0)))

        smc = ScoreToMidiConverter(score)
        smc.create('score_multi_trackoutput_file.mid')

        TestScoreToMidiConverter.read_midi_file(
            'score_multi_trackoutput_file.mid')
예제 #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_compute_simple_function_tone(self):
        print('--- test_compute_simple_function_tone ---')
        line = Line()

        f = GenericUnivariatePitchFunction(
            TestFitPitchToFunctionConstraint.sinasoidal, Position(0),
            Position(2))
        v_note = Note(DiatonicPitch.parse('A:4'), Duration(1, 32))
        line.pin(v_note, Offset(0))

        constraint, lower_policy_context = TestFitPitchToFunctionConstraint.build_simple_constraint(
            v_note, f, ModalityType.Major, 'G', 'tV')
        p_map = PMap()
        p_map[v_note] = ContextualNote(lower_policy_context)

        results = constraint.values(p_map, v_note)
        assert results is not None
        assert len(results) == 1
        print(next(iter(results)).diatonic_pitch)
        assert 'C:4' == str(next(iter(results)).diatonic_pitch)

        v_note = Note(DiatonicPitch.parse('A:4'), Duration(1, 32))
        line.pin(v_note, Offset(1, 32))

        constraint, lower_policy_context = TestFitPitchToFunctionConstraint.build_simple_constraint(
            v_note, f, ModalityType.Major, 'G', 'tV')
        p_map = PMap()
        p_map[v_note] = ContextualNote(lower_policy_context)

        results = constraint.values(p_map, v_note)
        assert results is not None
        assert len(results) == 1
        print(next(iter(results)).diatonic_pitch)
        assert 'E:4' == str(next(iter(results)).diatonic_pitch)

        p_map[v_note].note = next(iter(results))
        assert constraint.verify(p_map)
예제 #28
0
파일: line.py 프로젝트: dpazel/music_rep
    def sub_line(self, sub_line_range=None):
        """
        Take a sub-range (time) of this line, and build a new line with notes that begins within that range
        :param sub_line_range: numeric interval to check for inclusion.
        :return: (sub-line, onset of original (Position), duration of sub-line)

        Note: The sub_line is not guaranteed to have the same length as the line, as sub_line is constructed only of
        the notes contained withing sub_line_range, starting with the first note found.
        """
        sub_line_range = Interval(
            Fraction(0), self.duration.duration
        ) if sub_line_range is None else sub_line_range

        new_line = Line(None, self.instrument)

        first_position = None
        for s in self.sub_notes:
            s_excluded = Line._all_start_in(s, sub_line_range)
            if s_excluded == 1:
                if first_position is not None:
                    offset = Offset(s.get_absolute_position().position -
                                    first_position)
                else:
                    first_position = s.get_absolute_position().position
                    offset = Offset(0)
                s_prime = s.clone()
                new_line.pin(s_prime, offset)
            else:
                if s_excluded == -1:
                    raise Exception(
                        "Line range {0} must fully enclose sub-structures: {1}."
                        .format(sub_line_range, s))

        return new_line, Position(
            first_position) if first_position is not None else Position(
                0), new_line.duration
예제 #29
0
    def test_insert_notes(self):
        print('test_insert_notes')
        # same as test_nested_notes
        note1 = Note(DiatonicPitch(4, 'c'), Duration(1, 8))
        note2 = Note(DiatonicPitch(4, 'd'), Duration(1, 8))
        note3 = Note(DiatonicPitch(4, 'e'), Duration(1, 16))
        sub_beam = Beam([note1, note2, note3])

        beam = Beam()
        beam.append(Note(DiatonicPitch(4, 'f'), Duration(1, 8)))
        beam.append(sub_beam)
        beam.append(Note(DiatonicPitch(4, 'g'), Duration(1, 8)))

        AbstractNote.print_structure(beam)

        # add a beam
        n_list = [
            Note(DiatonicPitch(3, 'c'), Duration(1, 8)),
            Note(DiatonicPitch(3, 'd'), Duration(1, 8))
        ]
        add_beam = Beam(n_list)
        sub_beam.add(add_beam, 1)

        print(beam)
        AbstractNote.print_structure(beam)

        notes = beam.get_all_notes()
        assert len(notes) == 7
        TestBeam.print_all_notes(notes)
        assert notes[0].diatonic_pitch == DiatonicPitch(4, 'f')
        assert notes[1].diatonic_pitch == DiatonicPitch(4, 'c')
        assert notes[2].diatonic_pitch == DiatonicPitch(3, 'c')
        assert notes[3].diatonic_pitch == DiatonicPitch(3, 'd')
        assert notes[4].diatonic_pitch == DiatonicPitch(4, 'd')
        assert notes[5].diatonic_pitch == DiatonicPitch(4, 'e')
        assert notes[6].diatonic_pitch == DiatonicPitch(4, 'g')

        assert notes[0].relative_position == Offset(0)
        assert notes[1].relative_position == Offset(0)
        assert notes[2].relative_position == Offset(0)
        assert notes[3].relative_position == Offset(1, 32)
        assert notes[4].relative_position == Offset(1, 8)
        assert notes[5].relative_position == Offset(3, 16)
        assert notes[6].relative_position == Offset(11, 32)
예제 #30
0
    def downward_refactor_layout(self, incremental_factor):
        """
        Called by Tuplet, this method applies the incremental factor down the tree, adjusting 
        note duration accordingly.  At a Note, it calls apply_factor to make durational adjustments.
        Otherwise, it calls recursively.
        The method also rescales the relative positions of abstract notes.
        
        Args:
          incremental_factor: the multiplicative factor to apply downward.
        """
        from structure.note import Note

        self.contextual_reduction_factor *= incremental_factor
        relpos = Offset(0)
        for n in self.sub_notes:
            if isinstance(n, Note):
                n.apply_factor(incremental_factor)
            else:
                n.downward_refactor_layout(incremental_factor)
            n.relative_position = relpos
            relpos += n.duration