예제 #1
0
    async def test_note_set_pitch(self):
        track = await self._add_track()
        measure = track.measure_list[0].measure
        await self._fill_measure(measure)

        with self.project.apply_mutations('test'):
            measure.notes[0].set_pitch(value_types.Pitch('C2'))
        self.assertEqual(measure.notes[0].pitches[0], value_types.Pitch('C2'))
예제 #2
0
    async def test_create_note(self):
        track = await self._add_track()
        measure = track.measure_list[0].measure
        self.assertEqual(len(measure.notes), 0)

        with self.project.apply_mutations('test'):
            measure.create_note(0, value_types.Pitch('F2'),
                                audioproc.MusicalDuration(1, 4))
        self.assertEqual(len(measure.notes), 1)
        self.assertEqual(measure.notes[0].pitches[0], value_types.Pitch('F2'))
        self.assertEqual(measure.notes[0].base_duration,
                         audioproc.MusicalDuration(1, 4))
예제 #3
0
 def __pitchEdited(self) -> None:
     try:
         pitch = value_types.Pitch(self.__pitch.text())
     except ValueError:
         self.__pitch.setText(str(self.__track.pitch))
     else:
         if pitch != self.__track.pitch:
             with self.project.apply_mutations('%s: Change pitch' %
                                               self.__track.name):
                 self.__track.pitch = pitch
예제 #4
0
    def create(self,
               *,
               pitch: Optional[value_types.Pitch] = None,
               num_measures: int = 1,
               **kwargs: Any) -> None:
        super().create(**kwargs)

        if pitch is None:
            self.pitch = value_types.Pitch('B2')
        else:
            self.pitch = pitch

        for _ in range(num_measures):
            self.append_measure()
예제 #5
0
    def test_key_events(self):
        p = piano.PianoWidget(None)

        on_listener = mock.Mock()
        p.noteOn.connect(on_listener)

        off_listener = mock.Mock()
        p.noteOff.connect(off_listener)

        evt = QtGui.QKeyEvent(QtCore.QEvent.KeyPress, Qt.Key_R, Qt.NoModifier,
                              0x1b, 0, 0, "r")
        p.event(evt)
        self.assertEqual(on_listener.call_args_list,
                         [mock.call(value_types.Pitch('C5'))])

        evt = QtGui.QKeyEvent(QtCore.QEvent.KeyRelease, Qt.Key_R,
                              Qt.NoModifier, 0x1b, 0, 0, "r")
        p.event(evt)

        self.assertEqual(off_listener.call_args_list,
                         [mock.call(value_types.Pitch('C5'))])

        self.assertTrue(p.close())
예제 #6
0
    def test_foo(self):
        pr = demo_project.basic(self.pool,
                                project.BaseProject,
                                node_db=self.node_db)
        tr = pr.nodes[-1]

        messages = []  # type: List[str]

        connector = tr.create_node_connector(message_cb=messages.append,
                                             audioproc_client=None)
        try:
            messages.extend(connector.init())

            tr.insert_measure(1)
            m = tr.measure_list[1].measure
            m.notes.append(
                self.pool.create(model.Note,
                                 pitches=[value_types.Pitch('D#4')]))

            self.assertTrue(len(messages) > 0)

        finally:
            connector.cleanup()
예제 #7
0
    def paintBackground(self, painter: QtGui.QPainter) -> None:
        ymid = self.height() // 2

        painter.setPen(Qt.black)
        painter.setBrush(Qt.black)

        for l in range(-2, 3):
            painter.drawLine(0, ymid + 20 * l, self.width() - 1, ymid + 20 * l)

        if self.is_first:
            painter.fillRect(0, ymid - 40, 2, 20 * 4, Qt.black)

        painter.drawLine(self.width() - 1, ymid - 40,
                         self.width() - 1, ymid + 40)

        if not self.measure_reference.is_first:
            prev_sibling = down_cast(
                model.ScoreMeasure,
                self.measure_reference.prev_sibling.measure)
        else:
            prev_sibling = None

        base_stave_line = self.measure.clef.center_pitch.stave_line
        base_octave = self.measure.clef.base_octave
        x = 0

        paint_clef = prev_sibling is None or self.measure.clef != prev_sibling.clef

        if paint_clef and self.width() - x > 200:
            svg_symbol.paintSymbol(
                painter, 'clef-%s' % self.measure.clef.symbol,
                QtCore.QPoint(
                    x + 30, ymid - 10 *
                    (self.measure.clef.base_pitch.stave_line - base_stave_line)
                ))
            x += 60

        acc_map = {
            'C#': 'C%d' % (base_octave + 1),
            'D#': 'D%d' % (base_octave + 1),
            'E#': 'E%d' % (base_octave + 1),
            'F#': 'F%d' % (base_octave + 1),
            'G#': 'G%d' % (base_octave + 1),
            'A#': 'A%d' % base_octave,
            'B#': 'B%d' % base_octave,
            'Cb': 'C%d' % (base_octave + 1),
            'Db': 'D%d' % (base_octave + 1),
            'Eb': 'E%d' % (base_octave + 1),
            'Fb': 'F%d' % base_octave,
            'Gb': 'G%d' % base_octave,
            'Ab': 'A%d' % base_octave,
            'Bb': 'B%d' % base_octave,
        }

        paint_key_signature = (
            prev_sibling is None
            or self.measure.key_signature != prev_sibling.key_signature)

        if paint_key_signature and self.width() - x > 200:
            for acc in self.measure.key_signature.accidentals:
                value = acc_map[acc]
                stave_line = value_types.Pitch(
                    value).stave_line - base_stave_line

                svg_symbol.paintSymbol(
                    painter, self._accidental_map[acc[1:]],
                    QtCore.QPoint(x + 10, ymid - 10 * stave_line))

                x += 10

            if self.measure.key_signature.accidentals:
                x += 10

        paint_time_signature = (
            prev_sibling is None
            or self.measure.time_signature != prev_sibling.time_signature)

        if paint_time_signature and self.width() - x > 200:
            font = QtGui.QFont('FreeSerif', 30, QtGui.QFont.Black)
            font.setStretch(120)
            painter.setFont(font)

            painter.drawText(x, ymid - 5,
                             '%d' % self.measure.time_signature.upper)
            painter.drawText(x, ymid + 32,
                             '%d' % self.measure.time_signature.lower)

            x += 40

        if self.width() - x > 100:
            self._note_area = (x + 20, self.width() - x - 20)

        else:
            self._note_area = (0, self.width())
예제 #8
0
    def mousePressMeasureEvent(
            self, measure: measured_track_editor.BaseMeasureEditor,
            evt: QtGui.QMouseEvent) -> None:
        assert isinstance(measure, ScoreMeasureEditor), type(measure).__name__

        ymid = measure.height() // 2
        stave_line = (int(ymid + 5 - evt.pos().y()) // 10 +
                      measure.measure.clef.center_pitch.stave_line)

        if evt.button() == Qt.LeftButton and (
                evt.modifiers() & ~Qt.ShiftModifier) == Qt.NoModifier:
            if self.type.is_note:
                pitch = value_types.Pitch.name_from_stave_line(
                    stave_line, measure.measure.key_signature)
            else:
                pitch = 'r'

            duration = measure.durationForTool(self.type)

            idx, overwrite, _ = measure.getEditArea(evt.pos().x())
            if idx >= 0:
                if evt.modifiers() == Qt.ShiftModifier:
                    if overwrite:
                        if len(measure.measure.notes[idx].pitches) > 1:
                            for pitch_idx, p in enumerate(
                                    measure.measure.notes[idx].pitches):
                                if p.stave_line == stave_line:
                                    with self.project.apply_mutations(
                                            '%s: Change note' %
                                            measure.track.name):
                                        measure.measure.notes[
                                            idx].remove_pitch(pitch_idx)
                                    evt.accept()
                                    return

                        else:
                            with self.project.apply_mutations(
                                    '%s: Delete note' % measure.track.name):
                                measure.measure.delete_note(
                                    measure.measure.notes[idx])
                            evt.accept()
                            return

                else:
                    if overwrite:
                        for pitch_idx, p in enumerate(
                                measure.measure.notes[idx].pitches):
                            if p.stave_line == stave_line:
                                break
                        else:
                            with self.project.apply_mutations(
                                    '%s: Change note' % measure.track.name):
                                measure.measure.notes[idx].add_pitch(
                                    value_types.Pitch(pitch))
                            measure.track_editor.playNoteOn(
                                value_types.Pitch(pitch))
                            evt.accept()
                            return

                    else:
                        with self.project.apply_mutations('%s: Create note' %
                                                          measure.track.name):
                            measure.measure.create_note(
                                idx, value_types.Pitch(pitch), duration)
                        measure.track_editor.playNoteOn(
                            value_types.Pitch(pitch))
                        evt.accept()
                        return

        super().mousePressMeasureEvent(measure, evt)
예제 #9
0
 def release(self) -> None:
     if self._type == self.WHITE:
         self.setBrush(QtGui.QBrush(Qt.white))
     else:
         self.setBrush(QtGui.QBrush(Qt.black))
     self._piano.noteOff.emit(value_types.Pitch(self._name))
예제 #10
0
 def press(self) -> None:
     self.setBrush(QtGui.QBrush(QtGui.QColor(0, 120, 255)))
     self._piano.noteOn.emit(value_types.Pitch(self._name))
예제 #11
0
 async def _fill_measure(self, measure):
     with self.project.apply_mutations('test'):
         measure.create_note(0, value_types.Pitch('F2'),
                             audioproc.MusicalDuration(1, 4))
     self.assertEqual(len(measure.notes), 1)