Skip to content

Instantly share code, notes, and snippets.

@raplin
Created June 5, 2021 02:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raplin/420273f0d1ce18b13f6bab6b41ff81a2 to your computer and use it in GitHub Desktop.
Save raplin/420273f0d1ce18b13f6bab6b41ff81a2 to your computer and use it in GitHub Desktop.
Simple light toy scratchpad for Midiplus Smartpad ~$50
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)
@raplin
Copy link
Author

raplin commented Jun 17, 2021

python 2, needs
import time,threading

@raplin
Copy link
Author

raplin commented Jun 17, 2021

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