Created
March 12, 2018 16:10
-
-
Save Gadgetoid/7174f8b744e857936e431f7e912e7ca6 to your computer and use it in GitHub Desktop.
Unicorn HAT HD MIDI fiddling. Using raw MIDI read from Python.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.