| @@ -373,9 +373,11 @@ class PianoRoll(QGraphicsScene): | |||||
| # ------------------------------------------------------------------------- | # ------------------------------------------------------------------------- | ||||
| # Callbacks | # Callbacks | ||||
| def movePlayHead(self, t): | |||||
| total_duration = 1920 * self.time_sig[0] * self.num_measures | |||||
| pos = t['bar']*1920*self.time_sig[0] + t['beat']*1920 + t['tick'] | |||||
| def movePlayHead(self, transport_info): | |||||
| # TODO: need conversion between frames and PPQ | |||||
| x = 105. # works for 120bpm | |||||
| total_duration = self.time_sig[0] * self.num_measures * x | |||||
| pos = transport_info['frame'] / x | |||||
| frac = (pos % total_duration) / total_duration | frac = (pos % total_duration) / total_duration | ||||
| self.play_head.setPos(QPointF(frac * self.grid_width, 0)) | self.play_head.setPos(QPointF(frac * self.grid_width, 0)) | ||||
| @@ -703,10 +705,14 @@ class PianoRoll(QGraphicsScene): | |||||
| for note in self.notes[:]: | for note in self.notes[:]: | ||||
| if note.note[1] >= (self.num_measures * self.time_sig[0]): | if note.note[1] >= (self.num_measures * self.time_sig[0]): | ||||
| self.notes.remove(note) | self.notes.remove(note) | ||||
| self.midievent.emit(["midievent-remove", note.note[0], note.note[1], note.note[2], note.note[3]]) | |||||
| elif note.note[2] > self.max_note_length: | elif note.note[2] > self.max_note_length: | ||||
| new_note = note.note | |||||
| new_note = note.note[:] | |||||
| new_note[2] = self.max_note_length | |||||
| self.notes.remove(note) | self.notes.remove(note) | ||||
| self.drawNote(new_note[0], new_note[1], self.max_note_length, new_note[3], False) | self.drawNote(new_note[0], new_note[1], self.max_note_length, new_note[3], False) | ||||
| self.midievent.emit(["midievent-remove", note.note[0], note.note[1], note.note[2], note.note[3]]) | |||||
| self.midievent.emit(["midievent-add", new_note[0], new_note[1], new_note[2], new_note[3]]) | |||||
| list(map(self.addItem, self.notes)) | list(map(self.addItem, self.notes)) | ||||
| if self.views(): | if self.views(): | ||||
| self.views()[0].setSceneRect(self.itemsBoundingRect()) | self.views()[0].setSceneRect(self.itemsBoundingRect()) | ||||
| @@ -904,6 +910,8 @@ class MainWindow(ExternalUI, QWidget): | |||||
| "sigDenom": 4.0 | "sigDenom": 4.0 | ||||
| } | } | ||||
| self.PPQ = 48. | |||||
| self.initUI() | self.initUI() | ||||
| self.piano.midievent.connect(self.sendMsg) | self.piano.midievent.connect(self.sendMsg) | ||||
| self.piano.measureupdate.connect(self.updateMeasureBox) | self.piano.measureupdate.connect(self.updateMeasureBox) | ||||
| @@ -1057,15 +1065,15 @@ class MainWindow(ExternalUI, QWidget): | |||||
| msg = data[0] | msg = data[0] | ||||
| if msg == "midievent-remove": | if msg == "midievent-remove": | ||||
| note, start, length, vel = data[1:5] | note, start, length, vel = data[1:5] | ||||
| note_start = start * 60. / self.fTransportInfo["bpm"] * 4. / self.fTransportInfo["sigDenom"] * self.getSampleRate() | |||||
| note_stop = note_start + length * 60. / self.fTransportInfo["bpm"] * 4. * self.fTransportInfo["sigNum"] / self.fTransportInfo["sigDenom"] * self.getSampleRate() | |||||
| note_start = start * 60. / self.fTransportInfo["bpm"] * 4. / self.fTransportInfo["sigDenom"] * self.PPQ | |||||
| note_stop = note_start + length * 60. / self.fTransportInfo["bpm"] * 4. * self.fTransportInfo["sigNum"] / self.fTransportInfo["sigDenom"] * self.PPQ | |||||
| self.send([msg, note_start, 3, MIDI_STATUS_NOTE_ON, note, vel]) | self.send([msg, note_start, 3, MIDI_STATUS_NOTE_ON, note, vel]) | ||||
| self.send([msg, note_stop, 3, MIDI_STATUS_NOTE_OFF, note, vel]) | self.send([msg, note_stop, 3, MIDI_STATUS_NOTE_OFF, note, vel]) | ||||
| elif msg == "midievent-add": | elif msg == "midievent-add": | ||||
| note, start, length, vel = data[1:5] | note, start, length, vel = data[1:5] | ||||
| note_start = start * 60. / self.fTransportInfo["bpm"] * self.getSampleRate() | |||||
| note_stop = note_start + length * 60. / self.fTransportInfo["bpm"] * 4. * self.fTransportInfo["sigNum"] / self.fTransportInfo["sigDenom"] * self.getSampleRate() | |||||
| note_start = start * 60. / self.fTransportInfo["bpm"] * self.PPQ | |||||
| note_stop = note_start + length * 60. / self.fTransportInfo["bpm"] * 4. * self.fTransportInfo["sigNum"] / self.fTransportInfo["sigDenom"] * self.PPQ | |||||
| self.send([msg, note_start, 3, MIDI_STATUS_NOTE_ON, note, vel]) | self.send([msg, note_start, 3, MIDI_STATUS_NOTE_ON, note, vel]) | ||||
| self.send([msg, note_stop, 3, MIDI_STATUS_NOTE_OFF, note, vel]) | self.send([msg, note_stop, 3, MIDI_STATUS_NOTE_OFF, note, vel]) | ||||
| @@ -1102,6 +1110,8 @@ class MainWindow(ExternalUI, QWidget): | |||||
| if beat != self.fTransportInfo["beat"]: | if beat != self.fTransportInfo["beat"]: | ||||
| print(beat) | print(beat) | ||||
| old_frame = self.fTransportInfo['frame'] | |||||
| self.fTransportInfo = { | self.fTransportInfo = { | ||||
| "playing": playing, | "playing": playing, | ||||
| "frame": frame, | "frame": frame, | ||||
| @@ -1113,7 +1123,8 @@ class MainWindow(ExternalUI, QWidget): | |||||
| "sigDenom": sigDenom | "sigDenom": sigDenom | ||||
| } | } | ||||
| #self.piano.movePlayHead(self.fTransportInfo) | |||||
| if old_frame != frame: | |||||
| self.piano.movePlayHead(self.fTransportInfo) | |||||
| elif msg == "show": | elif msg == "show": | ||||
| @@ -1146,7 +1157,7 @@ class MainWindow(ExternalUI, QWidget): | |||||
| # we'll convert it to a smaller value for now (seconds) | # we'll convert it to a smaller value for now (seconds) | ||||
| # later on we can have time as PPQ or similar | # later on we can have time as PPQ or similar | ||||
| time /= self.getSampleRate() | |||||
| time /= self.PPQ | |||||
| status = MIDI_GET_STATUS_FROM_DATA(data) | status = MIDI_GET_STATUS_FROM_DATA(data) | ||||
| channel = MIDI_GET_CHANNEL_FROM_DATA(data) | channel = MIDI_GET_CHANNEL_FROM_DATA(data) | ||||