A short experiment with p5 and midi

In addition to installing p5, I also had to install mido and python-rtmidi on my system:

python -m pip install mido python -m pip install python-rtmidi

This is an adaption of the example at https://github.com/p5py/p5
With mido, we can open midi input and output ports.
We can then check for incoming midi messages in the draw cycle of the p5 sketch.
The size and color of the circles in the p5 sketch are affected by the incoming midi notes.
Circle size is related to note velocity and color is related to note pitch.
Circles are only drawn if there are pending midi notes in that draw cycle and the mouse is pressed.
I used Rosegarden to play a midi file and send the midi to mido's input port.

In this first sketch, one midi message is polled per draw cycle.
If there's no available message, the poll will return None.
Note also that the message may not be a 'note on' so we'll filter the other types out:


from p5 import * import mido def setup(): size(640, 360) no_stroke() background(204) def draw(): # This method just polls the input port and receives # one midi message per draw cycle msg = inport.poll() if (not msg is None) and (msg.type == 'note_on'): note = msg.note vel = msg.velocity if mouse_is_pressed: fill(note*2, note*2, note*2, 127) circle_size = vel*2 circle((mouse_x, mouse_y), circle_size) def key_pressed(event): background(204) # open the midi input port inport = mido.open_input('mido-inport', virtual=True) run(renderer="vispy")





The next example processes all pending midi messages in each draw cycle. In addition, all the pending messages are sent to the output port so we can listen to the midi at the same time.
The last received 'note on' message (if there was one) affects the circle color and size (with a bit of randomness thrown in).
On my system, I used Rosegarden to play a midi file and send the midi to mido's input port.
I used Qsynth to receive and play midi from mido's output port.
One thing to bear in mind, is that a lot of midi messages could effectively go unused in this sketch.
I guess you could find the average values of the variables for all the messages, or use multiple messages for different things in the sketch.


from p5 import * import mido def setup(): size(640, 360) no_stroke() background(204) def draw(): note_on_rcvd = False # This method helps maintain the fidelity of the midi passed though # to the ouput port, by sending all the pending messages in this draw cycle, # but only retains the information from the final pending 'note_on' message # for setting the circle properties for msg in inport.iter_pending(): if msg.type == 'note_on': note = msg.note vel = msg.velocity note_on_rcvd = True outport.send(msg) if note_on_rcvd and mouse_is_pressed: fill(random_uniform(low=note, high=note*2), random_uniform(low=note, high=note*2), random_uniform(low=note, high=note*2), 127) circle_size = random_uniform(low=vel, high=vel*2) circle((mouse_x, mouse_y), circle_size) def key_pressed(event): background(204) # open the midi input and output ports inport = mido.open_input('mido-inport', virtual=True) outport = mido.open_output('mido-outport', virtual=True) run(renderer="vispy")