Created
June 5, 2021 02:48
-
-
Save raplin/420273f0d1ce18b13f6bab6b41ff81a2 to your computer and use it in GitHub Desktop.
Simple light toy scratchpad for Midiplus Smartpad ~$50
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
class LED(object): | |
RED=0x61 | |
GREEN=0x51 | |
BLUE=0x41 | |
PURPLE=0x31 | |
CYAN=0x21 | |
YELLOW=0x11 | |
WHITE=0x1 | |
OFF=0 | |
def __init__(self,row,col,index,note): | |
self.index=index | |
self.row,self.col,self.note=row,col,note | |
self.color=-1 | |
self.colorTable=None | |
def getColor(self,timebase): | |
if not self.colorTable: | |
return self.color | |
#print timebase % len(self.colorTable),self.colorTable | |
return self.colorTable[timebase % len(self.colorTable) ] | |
class DeskControl(object): | |
LED_COUNT=64 | |
def __init__(self): | |
self.inf=open("/dev/midi2","rb") | |
self.info=open("/dev/midi2","wb") | |
self.t=threading.Thread(target=self.listen) | |
self.t.daemon=True | |
self.t.start() | |
self.startLEDs() | |
def startLEDs(self): | |
self.leds=[] | |
self.note2led=[0 for n in range(127)] | |
for row in range(8): | |
for col in range(8): | |
index=(row*8)+col | |
note=(row*16)+col | |
self.note2led[note]=index | |
self.leds.append( LED(row,col,index,note)) | |
self.lt=threading.Thread(target=self.ledThread) | |
self.lt.daemon=True | |
self.lt.start() | |
def ledThread(self): | |
while True: | |
self.updateLEDs() | |
time.sleep(0.1) | |
def updateLEDs(self): | |
ledTime=int(time.time()*10) | |
msgs=[] | |
for led in self.leds: | |
oldc=led.color | |
c=led.getColor(ledTime) | |
if c!=oldc: | |
#print led.index,c,led.color,led.note | |
led.color=c | |
#"Note: You need to change the LED color, you must send the MIDI OFF command to turn off the light before you can change the other color | |
msgs.append(chr(0x80)+chr(led.note)+chr(0)+chr(0x90)+chr(led.note)+chr(c)) | |
if msgs: | |
#print "SEND",len(msgs) | |
self.info.write("".join(msgs)) | |
self.info.flush() | |
def listen(self): | |
mb=[] | |
self.sideButton=0 | |
while True: | |
m=ord(self.inf.read(1)) | |
if not m&0x80: | |
#sync | |
continue | |
dat1=ord(self.inf.read(1)) | |
dat2=0 | |
ch=m&0xf | |
msg=m>>4 | |
if not (msg==0xc or msg==0xd): | |
dat2=ord(self.inf.read(1)) | |
if (dat1 | dat2) & 0x80: | |
print "Bad %x %x %x" % (m,dat1,dat2) | |
continue | |
print "%d: %d, %d, %d" % (ch,msg,dat1,dat2) | |
if msg==9: #note on | |
if ch==15: | |
#side buttons | |
sb=dat1-112 | |
if sb>=0 and sb<=8: | |
self.sideButton=sb | |
if dat1==120: | |
self.clearLEDs() | |
elif ch==0: | |
led=self.leds[ self.note2led[dat1] ] | |
if led.colorTable==None: | |
led.colorTable=[] | |
led.colorTable.append( self.sideButton<<4 ) # =[LED.WHITE,LED.OFF,LED.GREEN,LED.OFF,LED.BLUE,LED.BLUE,LED.OFF,LED.RED] | |
def clearLEDs(self): | |
for l in leds: | |
l.colorTable=None | |
l.color=COLOR.OFF | |
def tx(self,ch,msg,dat1,dat2=None): | |
m=ch|(msg<<4) | |
out=chr(m)+chr(dat1) | |
if dat2!=None: | |
out+=chr(dat2) | |
#for n in out: | |
# print "%02x" % ord(n) | |
self.info.write(out) | |
self.info.flush() | |
d=DeskControl() | |
while True: | |
time.sleep(1000) |
oh if you want to do this cross-platform, use 'pygame' which has midi that works on windows etc as well. API-wise It's a bit different (and slower updates to LEDs than the above code)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
python 2, needs
import time,threading