Skip to content

Instantly share code, notes, and snippets.

@Gadgetoid
Created March 12, 2018 16:10
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save Gadgetoid/7174f8b744e857936e431f7e912e7ca6 to your computer and use it in GitHub Desktop.
Unicorn HAT HD MIDI fiddling. Using raw MIDI read from Python.
import unicornhathd
import time
from threading import Thread
import colorsys
MIDI_NOTE_OFF = 0x80
MIDI_NOTE_ON = 0x90
MIDI_AFTERTOUCH = 0xA0
MIDI_CC = 0xB0
MIDI_PATCH = 0xC0
MIDI_PRESSURE = 0xD0
MIDI_PITCH = 0xE0
hues = [0 for _ in range(8)]
bars = [0 for _ in range(8)]
pads = [0 for _ in range(8)]
def display_update():
while running:
for x in range(16):
bar = x >> 1
hue = hues[bar]
r, g, b = [int(c * 255) for c in colorsys.hsv_to_rgb(hue, 1.0, 1.0)]
velocity = bars[bar] / 8.0
pad = pads[bar] / 8.0
for y in range(16):
if pad > y and x % 2 == 1:
if int(pad) == y:
br = pad - int(pad)
unicornhathd.set_pixel(x,y,r * br, g * br, b * br)
else:
unicornhathd.set_pixel(x,y,r, g, b)
elif velocity > y and x % 2 == 0:
if int(velocity) == y:
br = velocity - int(velocity)
unicornhathd.set_pixel(x,y,r * br, g * br, b * br)
else:
unicornhathd.set_pixel(x,y,r, g, b)
else:
unicornhathd.set_pixel(x, y, 0, 0, 0)
unicornhathd.show()
time.sleep(1.0 / 60)
for bar in range(8):
if pads[bar] > 0:
pads[bar] -= 1
running = True
_t = Thread(target=display_update)
_t.daemon = True
_t.start()
with open("/dev/midi1","rb") as midi:
while True:
command = midi.read(1)
command = ord(command)
if command == MIDI_NOTE_OFF:
key = ord(midi.read(1)) - 36
velocity = ord(midi.read(1))
print("NOTE OFF: {} {}".format(key, velocity))
continue
if command == MIDI_NOTE_ON:
key = ord(midi.read(1)) - 36
velocity = ord(midi.read(1))
pads[key] = velocity
print("NOTE ON: {} {}".format(key, velocity))
continue
if command == MIDI_CC:
cc = ord(midi.read(1))
value = ord(midi.read(1))
hues[cc - 1] = value / 127.0
bars[cc - 1] = value
print("CC: {} {}".format(cc, value))
running = False
_t.join()
@Gadgetoid
Copy link
Author

This is a quick and dirty script that just reads MIDI data from a raw device a byte at a time and decodes into the relevant control types/parameters. It only deals with a subset of MIDI at the moment, so weird things may happen if you use anything but keys/continuous controls.

There are much better ways to deal with MIDI than this, this example just demonstrates how simple the protocol is if you want to get down and dirty with it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment