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'))
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))
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
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()
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())
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()
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())
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)
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))
def press(self) -> None: self.setBrush(QtGui.QBrush(QtGui.QColor(0, 120, 255))) self._piano.noteOn.emit(value_types.Pitch(self._name))
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)