def test_operators(self): m1 = MidiMessage.noteOn(1, 100, 120) m2 = MidiMessage.noteOn(1, 100, 120) self.assertEqual(m1, m2) m3 = MidiMessage.noteOn(1, 101, 120) self.assertNotEqual(m1, m3)
def test_statics(self): ctls = [ "Bank Select", "Modulation Wheel (coarse)", "Breath controller (coarse)", "", "Foot Pedal (coarse)", "Portamento Time (coarse)", "Data Entry (coarse)", "Volume (coarse)", "Balance (coarse)", "", "Pan position (coarse)", "Expression (coarse)", "Effect Control 1 (coarse)", "Effect Control 2 (coarse)", "", "", "General Purpose Slider 1", "General Purpose Slider 2", "General Purpose Slider 3", "General Purpose Slider 4", "", "", "", "", "", "", "", "", "", "", "", "", "Bank Select (fine)", "Modulation Wheel (fine)", "Breath controller (fine)", "", "Foot Pedal (fine)", "Portamento Time (fine)", "Data Entry (fine)", "Volume (fine)", "Balance (fine)", "", "Pan position (fine)", "Expression (fine)", "Effect Control 1 (fine)", "Effect Control 2 (fine)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "Hold Pedal (on/off)", "Portamento (on/off)", "Sustenuto Pedal (on/off)", "Soft Pedal (on/off)", "Legato Pedal (on/off)", "Hold 2 Pedal (on/off)", "Sound Variation", "Sound Timbre", "Sound Release Time", "Sound Attack Time", "Sound Brightness", "Sound Control 6", "Sound Control 7", "Sound Control 8", "Sound Control 9", "Sound Control 10", "General Purpose Button 1 (on/off)", "General Purpose Button 2 (on/off)", "General Purpose Button 3 (on/off)", "General Purpose Button 4 (on/off)", "", "", "", "", "", "", "", "Reverb Level", "Tremolo Level", "Chorus Level", "Celeste Level", "Phaser Level", "Data Button increment", "Data Button decrement", "Non-registered Parameter (fine)", "Non-registered Parameter (coarse)", "Registered Parameter (fine)", "Registered Parameter (coarse)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "All Sound Off", "All Controllers Off", "Local Keyboard (on/off)", "All Notes Off", "Omni Mode Off", "Omni Mode On", "Mono Operation", "Poly Operation" ] for i, v in enumerate(ctls): self.assertEqual(MidiMessage.getControllerName(i), v) # crash test self.assertEqual(MidiMessage.getControllerName(-1), '') self.assertEqual(MidiMessage.getControllerName(128), '')
def from_data_matrix(mat, scaled=True): """Create gesture using data matrix respresentation""" g = Gesture() # gesture start time t_start = min(mat[:, 2]) for (n, v, t, l) in mat: # shift messages to start at time zero if they dont already t -= t_start if scaled: n = np.interp(n, [0, 1], [21, 108]) v = np.interp(v, [0, 1], [0, 127]) t = np.interp(t, [0, 1], [0, 20]) l = np.interp(l, [0, 1], [0.05, 10]) g.messages.append( MidiMessage.noteOn(1, int(n), int(v)) ) g.msg_times.append(t) g.messages.append( MidiMessage.noteOff(1, int(n)) ) g.msg_times.append(t + l) g.collect() return g
def from_dist_vec(vector): """Create gesture by drawing a random instance from the distribution vector representation""" starting_pitch, num_notes, vel_mean, vel_std, int_mean, int_std, \ diff_mean, diff_std, len_mean, len_std = vector g = Gesture() prev_nn = 0 # midi note number for previous note on prev_time = 0 # start time for previous note on # randomize number of notes using a poisson distribution num_notes = max(np.random.poisson(num_notes), 1) # random generate a similar gesture based on attribute normal distributions for i in range(num_notes): # if no messages have been written, use starting pitch if g.messages == []: g.messages.append( MidiMessage.noteOn(1, starting_pitch, int(round(normal(vel_mean, vel_std)))) ) g.msg_times.append(0.0) g.messages.append( MidiMessage.noteOff(1, starting_pitch) ) g.msg_times.append(normal(len_mean, len_std)) prev_nn = starting_pitch prev_time = 0.0 else: nn = prev_nn + int(round(normal(int_mean, int_std))) # if note is out of the keyboard's range, wrap it by octave into range if nn > 108: nn -= -((108-nn) // 12) * 12 if nn < 21: nn += -((nn-21) // 12) * 12 time = prev_time + normal(diff_mean, diff_std) g.messages.append( MidiMessage.noteOn(1, nn, int(round(normal(vel_mean, vel_std)))) ) g.msg_times.append(time) g.messages.append( MidiMessage.noteOff(1, nn) ) g.msg_times.append(time + normal(len_mean, len_std)) prev_nn = nn prev_time = time g.collect() return g
def test_raw(self): m1 = MidiMessage.noteOn(5, 123, 45) data = m1.getRawData() size = m1.getRawDataSize() self.assertEqual(size, len(data)) m2 = MidiMessage(data) self.assertEqual(m1, m2) # m1 = MidiMessage.controllerEvent(12, 123, 45) data = m1.getRawData() size = m1.getRawDataSize() self.assertEqual(size, len(data)) m2 = MidiMessage(data) self.assertEqual(m1, m2)
def updateValue(self): if not self.midimessage: return channel = self.channelBox.currentIndex() + 1 if self.typeBox.currentText() == util.ANY_TEXT: midi = MidiMessage.allNotesOff(0) elif self.typeBox.currentIndex() == 0: midi = MidiMessage.noteOn(channel, self.noteNumBox.currentIndex(), self.noteVelBox.currentIndex()+1) elif self.typeBox.currentIndex() == 1: midi = MidiMessage.noteOff(channel, self.noteNumBox.currentIndex()) elif self.typeBox.currentIndex() == 2: midi = MidiMessage.controllerEvent(channel, self.ccNumBox.currentIndex(), self.ccValueBox.currentIndex()) elif self.typeBox.currentIndex() == 3: midi = MidiMessage.aftertouchChange(channel, self.atNumBox.currentIndex(), self.atValueBox.currentIndex()) if self.portBox.currentIndex() == -1: portName = None else: portName = self.portBox.currentText() if not self.isInitting: self.midimessage.setWildcard('channel', self.channelBox.currentText() in [util.ANY_TEXT, util.ALL_TEXT], emit=False) self.midimessage.setWildcard('type', self.typeBox.currentText() in [util.ANY_TEXT, util.ALL_TEXT], emit=False) self.midimessage.setWildcard('noteNum', self.noteNumBox.currentText() in [util.ANY_TEXT, util.ALL_TEXT], emit=False) self.midimessage.setWildcard('noteVel', self.noteVelBox.currentText() in [util.ANY_TEXT, util.ALL_TEXT], emit=False) self.midimessage.setWildcard('ccNum', self.ccNumBox.currentText() in [util.ANY_TEXT, util.ALL_TEXT], emit=False) self.midimessage.setWildcard('ccValue', self.ccValueBox.currentText() in [util.ANY_TEXT, util.ALL_TEXT], emit=False) self.midimessage.setWildcard('atNum', self.atNumBox.currentText() in [util.ANY_TEXT, util.ALL_TEXT], emit=False) self.midimessage.setWildcard('atValue', self.atValueBox.currentText() in [util.ANY_TEXT, util.ALL_TEXT], emit=False) self.midimessage.setMidi(portName, midi)
def do_SenderProc(iq, oq, portName): DEBUG = 0 def wait_for(x): s = iq.get(block=True, timeout=2) if s != x: print("%s: OH SHIT (wait_for() %s != %s)" % (__name__, s, x)) device = RtMidiOut() if DEBUG: print('%s: OPENING %s' % (__name__, portName)) device.openVirtualPort(portName) oq.put('init') # the port is open wait_for('start') total = 0 # note on for i in range(128): for j in range(1, 128): if DEBUG: print("%s: Note %i %i" % (__name__, i, j)) m = MidiMessage.noteOn(1, i, j) device.sendMessage(m) wait_for('next') total += 1 # controller for i in range(128): for j in range(128): if DEBUG: print("%s: CC %i %i" % (__name__, i, j)) m = MidiMessage.controllerEvent(1, i, j) device.sendMessage(m) wait_for('next') total += 1 wait_for('done') print('%s: sent %i messages' % (__name__, total))
def sendNoteSignal(self, note, vel, wait=.1): m = MidiMessage.noteOn(self.channel, note, vel) self.output(m) time.sleep(wait) m = MidiMessage.noteOff(self.channel, note) self.output(m)
def test_noteOnChannel(self): """ https://github.com/patrickkidd/pyrtmidi/issues/13 """ m = MidiMessage.noteOn(10, 12, 13) self.assertEqual(m.getChannel(), 10) self.assertEqual(m.getNoteNumber(), 12) self.assertEqual(m.getVelocity(), 13)
def test_copy(self): m1 = MidiMessage.noteOn(5, 123, 45) m2 = MidiMessage(m1) self.assertEqual(m1, m2) self.assertEqual(m1.getChannel(), m2.getChannel())
def __init__(self, parent=None, any=False, all=False, portBox=False, input=True): QWidget.__init__(self, parent) self.any = any self.all = all self.input = input self.midimessage = None self.isInitting = False self.portBox = QComboBox() ports = input and inputs or outputs for name in ports().names(): self.portBox.addItem(name) ports().portAdded.connect(self.addPortName) ports().portRemoved.connect(self.removePortName) if any: self.portBox.addItem(util.ANY_TEXT) self.portBox.setCurrentIndex(self.portBox.count()) if all: self.portBox.addItem(util.ALL_TEXT) self.portBox.setCurrentIndex(self.portBox.count()) # self.portBox.addItem(util.NONE_TEXT) self.portBox.setMinimumWidth(100) self.portBox.currentTextChanged.connect(self.updateValue) if not portBox: self.portBox.hide() self.channelBox = QComboBox(self) for i in range(1, 17): self.channelBox.addItem('Channel %i' % i) if any: self.channelBox.addItem(util.ANY_TEXT) if all: self.channelBox.addItem(util.ALL_TEXT) self.channelBox.currentIndexChanged.connect(self.updateValue) self.typeBox = QComboBox(self) self.typeBox.addItem("Note On") self.typeBox.addItem("Note Off") self.typeBox.addItem("CC") self.typeBox.addItem("Aftertouch") if any: self.typeBox.addItem(util.ANY_TEXT) if all: self.typeBox.addItem(util.ALL_TEXT) self.typeBox.currentIndexChanged.connect(self.setType) self.ccNumBox = QComboBox(self) for i in range(128): name = MidiMessage.getControllerName(i) if name: name = ': (%s)' % name self.ccNumBox.addItem('%i %s' % (i, name)) if any: self.ccNumBox.addItem(util.ANY_TEXT) if all: self.ccNumBox.addItem(util.ALL_TEXT) self.ccNumBox.currentIndexChanged.connect(self.updateValue) self.ccValueBox = QComboBox(self) for i in range(128): self.ccValueBox.addItem(str(i)) if any: self.ccValueBox.addItem(util.ANY_TEXT) if all: self.ccValueBox.addItem(util.ALL_TEXT) self.ccValueBox.currentIndexChanged.connect(self.updateValue) self.noteNumBox = QComboBox(self) for i in range(128): self.noteNumBox.addItem('%i (%s)' % (i, MidiMessage.getMidiNoteName(i))) if any: self.noteNumBox.addItem(util.ANY_TEXT) if all: self.noteNumBox.addItem(util.ALL_TEXT) self.noteNumBox.currentIndexChanged.connect(self.updateValue) self.noteVelBox = QComboBox(self) for i in range(1, 128): self.noteVelBox.addItem(str(i)) if any: self.noteVelBox.addItem(util.ANY_TEXT) if all: self.noteVelBox.addItem(util.ALL_TEXT) self.noteVelBox.currentIndexChanged.connect(self.updateValue) self.atNumBox = QComboBox(self) for i in range(128): self.atNumBox.addItem('%i (%s)' % (i, MidiMessage.getMidiNoteName(i))) if any: self.atNumBox.addItem(util.ANY_TEXT) if all: self.atNumBox.addItem(util.ALL_TEXT) self.atNumBox.currentIndexChanged.connect(self.updateValue) self.atValueBox = QComboBox(self) for i in range(128): self.atValueBox.addItem(str(i)) if any: self.atValueBox.addItem(util.ANY_TEXT) if all: self.atValueBox.addItem(util.ALL_TEXT) self.atValueBox.currentIndexChanged.connect(self.updateValue) # hide these so the sizeHint doesn't get set too big when all are showing self.ccNumBox.hide() self.ccValueBox.hide() self.noteNumBox.hide() self.noteVelBox.hide() self.atNumBox.hide() self.atValueBox.hide() # keep long boxes from expanding too far boxes = self.findChildren(QComboBox, '', Qt.FindDirectChildrenOnly) for b in boxes: b.setMinimumWidth(100) for w in [self.portBox, self.typeBox, self.channelBox]: w.installEventFilter(self) Layout = QHBoxLayout() Layout.setContentsMargins(0, 0, 0, 0) Layout.addWidget(self.portBox) Layout.addWidget(self.channelBox) Layout.addWidget(self.typeBox) Layout.addWidget(self.ccNumBox) Layout.addWidget(self.ccValueBox) Layout.addWidget(self.noteNumBox) Layout.addWidget(self.noteVelBox) Layout.addWidget(self.atNumBox) Layout.addWidget(self.atValueBox) self.setLayout(Layout) # init self.typeMap = { util.MSG_NOTE_ON: [ # note on self.noteNumBox, self.noteVelBox ], util.MSG_NOTE_OFF: [ # note off self.noteNumBox ], util.MSG_CC: [ # cc self.ccNumBox, self.ccValueBox ], util.MSG_AFTERTOUCH: [ #aftertouch self.atNumBox, self.atValueBox ], util.MSG_ANY: [], util.MSG_ALL: [] } self.clear()
def test_eq(self): self.assertTrue(MidiMessage.noteOn(1, 0, 100) == MidiMessage.noteOn(1, 0, 100)) self.assertFalse(MidiMessage.noteOn(1, 1, 100) == MidiMessage.noteOn(1, 0, 100)) self.assertFalse(MidiMessage.pitchWheel(1, 1) == MidiMessage.noteOn(1, 64, 1)) self.assertTrue(MidiMessage.controllerEvent(1, 100, 1) == MidiMessage.controllerEvent(1, 100, 1)) self.assertTrue(MidiMessage.controllerEvent(1, 100, 2) == MidiMessage.controllerEvent(1, 100, 2)) self.assertTrue(MidiMessage.controllerEvent(1, 100, 3) == MidiMessage.controllerEvent(1, 100, 3)) self.assertFalse(MidiMessage.controllerEvent(1, 101, 1) == MidiMessage.controllerEvent(1, 100, 1)) self.assertFalse(MidiMessage.controllerEvent(1, 102, 2) == MidiMessage.controllerEvent(1, 100, 2)) self.assertFalse(MidiMessage.controllerEvent(1, 103, 3) == MidiMessage.controllerEvent(1, 100, 3))
def send_cc_raw(self, channel, cc, v, label=None): if label: print('[Virtual] send_cc_raw:', label) # see: https://github.com/patrickkidd/pyrtmidi/blob/master/rtmidi/randomout.py msg = MidiMessage.controllerEvent(channel, cc, v) self.device.sendMessage(msg)
def test_eq(self): self.assertTrue( MidiMessage.noteOn(1, 0, 100) == MidiMessage.noteOn(1, 0, 100)) self.assertFalse( MidiMessage.noteOn(1, 1, 100) == MidiMessage.noteOn(1, 0, 100)) self.assertFalse( MidiMessage.pitchWheel(1, 1) == MidiMessage.noteOn(1, 64, 1)) self.assertTrue( MidiMessage.controllerEvent(1, 100, 1) == MidiMessage.controllerEvent(1, 100, 1)) self.assertTrue( MidiMessage.controllerEvent(1, 100, 2) == MidiMessage.controllerEvent(1, 100, 2)) self.assertTrue( MidiMessage.controllerEvent(1, 100, 3) == MidiMessage.controllerEvent(1, 100, 3)) self.assertFalse( MidiMessage.controllerEvent(1, 101, 1) == MidiMessage.controllerEvent(1, 100, 1)) self.assertFalse( MidiMessage.controllerEvent(1, 102, 2) == MidiMessage.controllerEvent(1, 100, 2)) self.assertFalse( MidiMessage.controllerEvent(1, 103, 3) == MidiMessage.controllerEvent(1, 100, 3))
def on_message(midi: rtmidi.MidiMessage): if midi.isController() and midi.getControllerNumber() in [33, 35]: if midi.getControllerValue() == 65: mouse.scroll(0, -1) elif midi.getControllerValue() == 63: mouse.scroll(0, 1)