Package joy :: Module midi
[hide private]
[frames] | no frames]

Source Code for Module joy.midi

  1  import pygame.midi as pygm 
  2  import sys 
  3  from joy.events import MIDIEVENT, JoyEvent 
  4   
  5  DEV = None 
  6   
7 -class Channels(object):
8 - def __init__(self):
9 self._keys = set()
10
11 - def update( self, dic ):
12 self._keys.update(dic) 13 self.__dict__.update(dic)
14
15 -class MidiInput( object ):
16 BUF_SIZE = 1024 17
18 - def __init__(self,name,ID):
19 self.mi = pygm.Input(ID,MidiInput.BUF_SIZE) 20 self.name = name 21 self.ID = ID 22 self.at = Channels() 23 assert pygm.get_device_info(ID)[2], "Must be an input device"
24
25 - def rawEventIter(self):
26 while self.mi.poll(): 27 for evt in self.mi.read(MidiInput.BUF_SIZE): 28 yield evt 29 return
30
31 -class KorgNanoKontrol( MidiInput ):
32 N2C = { 33 (0,'rewind',0) : (176, 47), 34 (0,'play',0) : (176, 45), 35 (0,'forward',0) : (176, 48), 36 (0,'repeat',0) : (176, 49), 37 (0,'stop',0) : (176, 46), 38 (0,'record',0) : (176, 44), 39 (1,'btnU',1) : (176, 23), 40 (1,'btnL',1) : (176, 33), 41 (1,'slider',1) : (176, 2), 42 (1,'knob',1) : (176, 14), 43 (1,'btnU',2) : (176, 24), 44 (1,'btnL',2) : (176, 34), 45 (1,'slider',2) : (176, 3), 46 (1,'knob',2) : (176, 15), 47 (1,'btnU',3) : (176, 25), 48 (1,'btnL',3) : (176, 35), 49 (1,'slider',3) : (176, 4), 50 (1,'knob',3) : (176, 16), 51 (1,'btnU',4) : (176, 26), 52 (1,'btnL',4) : (176, 36), 53 (1,'slider',4) : (176, 5), 54 (1,'knob',4) : (176, 17), 55 (1,'btnU',5) : (176, 27), 56 (1,'btnL',5) : (176, 37), 57 (1,'slider',5) : (176, 6), 58 (1,'knob',5) : (176, 18), 59 (1,'btnU',6) : (176, 28), 60 (1,'btnL',6) : (176, 38), 61 (1,'slider',6) : (176, 8), 62 (1,'knob',6) : (176, 19), 63 (1,'btnU',7) : (176, 29), 64 (1,'btnL',7) : (176, 39), 65 (1,'slider',7) : (176, 9), 66 (1,'knob',7) : (176, 20), 67 (1,'btnU',8) : (176, 30), 68 (1,'btnL',8) : (176, 40), 69 (1,'slider',8) : (176, 12), 70 (1,'knob',8) : (176, 21), 71 (1,'btnU',9) : (176, 31), 72 (1,'btnL',9) : (176, 41), 73 (1,'slider',9) : (176, 13), 74 (1,'knob',9) : (176, 22), 75 (2,'btnU',1) : (176, 67), 76 (2,'btnL',1) : (176, 76), 77 (2,'slider',1) : (176, 42), 78 (2,'knob',1) : (176, 57), 79 (2,'btnU',2) : (176, 68), 80 (2,'btnL',2) : (176, 77), 81 (2,'slider',2) : (176, 43), 82 (2,'knob',2) : (176, 58), 83 (2,'btnU',3) : (176, 69), 84 (2,'btnL',3) : (176, 78), 85 (2,'slider',3) : (176, 50), 86 (2,'knob',3) : (176, 59), 87 (2,'btnU',4) : (176, 70), 88 (2,'btnL',4) : (176, 79), 89 (2,'slider',4) : (176, 51), 90 (2,'knob',4) : (176, 60), 91 (2,'btnU',5) : (176, 71), 92 (2,'btnL',5) : (176, 80), 93 (2,'slider',5) : (176, 52), 94 (2,'knob',5) : (176, 61), 95 (2,'btnU',6) : (176, 72), 96 (2,'btnL',6) : (176, 81), 97 (2,'slider',6) : (176, 53), 98 (2,'knob',6) : (176, 62), 99 (2,'btnU',7) : (176, 73), 100 (2,'btnL',7) : (176, 82), 101 (2,'slider',7) : (176, 54), 102 (2,'knob',7) : (176, 63), 103 (2,'btnU',8) : (176, 74), 104 (2,'btnL',8) : (176, 83), 105 (2,'slider',8) : (176, 55), 106 (2,'knob',8) : (176, 65), 107 (2,'btnU',9) : (176, 75), 108 (2,'btnL',9) : (176, 84), 109 (2,'slider',9) : (176, 56), 110 (2,'knob',9) : (176, 66), 111 (3,'btnU',1) : (176, 107), 112 (3,'btnL',1) : (176, 116), 113 (3,'slider',1) : (176, 85), 114 (3,'knob',1) : (176, 94), 115 (3,'btnU',2) : (176, 108), 116 (3,'btnL',2) : (176, 117), 117 (3,'slider',2) : (176, 86), 118 (3,'knob',2) : (176, 95), 119 (3,'btnU',3) : (176, 109), 120 (3,'btnL',3) : (176, 118), 121 (3,'slider',3) : (176, 87), 122 (3,'knob',3) : (176, 96), 123 (3,'btnU',4) : (176, 110), 124 (3,'btnL',4) : (176, 119), 125 (3,'slider',4) : (176, 88), 126 (3,'knob',4) : (176, 97), 127 (3,'btnU',5) : (176, 111), 128 (3,'btnL',5) : (176, 120), 129 (3,'slider',5) : (176, 89), 130 (3,'knob',5) : (176, 102), 131 (3,'btnU',6) : (176, 112), 132 (3,'btnL',6) : (176, 121), 133 (3,'slider',6) : (176, 90), 134 (3,'knob',6) : (176, 103), 135 (3,'btnU',7) : (176, 113), 136 (3,'btnL',7) : (176, 122), 137 (3,'slider',7) : (176, 91), 138 (3,'knob',7) : (176, 104), 139 (3,'btnU',8) : (176, 114), 140 (3,'btnL',8) : (176, 123), 141 (3,'slider',8) : (176, 92), 142 (3,'knob',8) : (176, 105), 143 (3,'btnU',9) : (176, 115), 144 (3,'btnL',9) : (176, 124), 145 (3,'slider',9) : (176, 93), 146 (3,'knob',9) : (176, 106), 147 #(4,'btnU',1) : (176, 16), 148 #(4,'btnL',1) : (176, 17), 149 #(4,'slider',1) : (176, 7), 150 #(4,'knob',1) : (176, 10), 151 (4,'btnU',2) : (177, 16), 152 (4,'btnL',2) : (177, 17), 153 (4,'slider',2) : (177, 7), 154 (4,'knob',2) : (177, 10), 155 (4,'btnU',3) : (178, 16), 156 (4,'btnL',3) : (178, 17), 157 (4,'slider',3) : (178, 7), 158 (4,'knob',3) : (178, 10), 159 (4,'btnU',4) : (179, 16), 160 (4,'btnL',4) : (179, 17), 161 (4,'slider',4) : (179, 7), 162 (4,'knob',4) : (179, 10), 163 (4,'btnU',5) : (180, 16), 164 (4,'btnL',5) : (180, 17), 165 (4,'slider',5) : (180, 7), 166 (4,'knob',5) : (180, 10), 167 (4,'btnU',6) : (181, 16), 168 (4,'btnL',6) : (181, 17), 169 (4,'slider',6) : (181, 7), 170 (4,'knob',6) : (181, 10), 171 (4,'btnU',7) : (182, 16), 172 (4,'btnL',7) : (182, 17), 173 (4,'slider',7) : (182, 7), 174 (4,'knob',7) : (182, 10), 175 (4,'btnU',8) : (183, 16), 176 (4,'btnL',8) : (183, 17), 177 (4,'slider',8) : (183, 7), 178 (4,'knob',8) : (183, 10), 179 (4,'btnU',9) : (184, 16), 180 (4,'btnL',9) : (184, 17), 181 (4,'slider',9) : (184, 7), 182 (4,'knob',9) : (184, 10), 183 } # ENDS: N2C 184 C2N = dict( [(x,y) for y,x in N2C.iteritems()] ) 185
186 - def __init__(self,*argv,**kw):
187 MidiInput.__init__(self,*argv,**kw)
188
189 - def eventIter( self ):
190 for (a,b,c,d),t in self.rawEventIter(): 191 dcr = self.C2N.get((a,b),None) 192 if dcr is None: 193 continue 194 if dcr[0]>0: 195 self.at.__dict__["sc%d_%s%d" % dcr] = c 196 else: 197 self.at.__dict__[dcr[1]] = c 198 yield dcr+(c,)
199 200
201 -def joyEventIter():
202 """(protected) generate all pending events as JoyApp events 203 This is used internally by JoyApp's event pump to collect midi events 204 """ 205 for k,dev in DEV.iteritems(): 206 for sc,kind,index,value in dev.eventIter(): 207 yield JoyEvent( MIDIEVENT, 208 dev=k,sc=sc,kind=kind,index=index,value=value 209 )
210 211 if 1: # function to help create an N2C dictionary 212 import time, sys
213 - def foo(f='rewind'):
214 nm = [ (0,k,0) for k in [ 215 'rewind', 216 'play', 217 'forward', 218 'repeat', 219 'stop', 220 'record' 221 ]] 222 for sc in xrange(1,5): 223 for k in xrange(1,10): 224 nm.append((sc,'btnU',k)) 225 nm.append((sc,'btnL',k)) 226 nm.append((sc,'slider',k)) 227 nm.append((sc,'knob',k)) 228 while nm and nm[0] != f: 229 nm.pop(0) 230 last = (None,None) 231 for k in nm: 232 print "(%d,'%s',%d)" % k, 233 sys.stdout.flush() 234 while True: 235 time.sleep(0.1) 236 l = list(DEV[3].rawEventIter()) 237 if not l: 238 continue 239 if l[-1][0][:2] != last[:2]: 240 break 241 last = l[-1][0] 242 print ": (%d,%d)," % (last[0],last[1]) 243 sys.stdout.flush()
244
245 -def init():
246 """ 247 Initialize the pygame midi interface and enumerate the devices in 248 the .DEV module variable 249 """ 250 global DEV 251 if DEV is not None: 252 return 253 DEV = {} 254 pygm.init() 255 for k in xrange(pygm.get_count()): 256 _,nm,inp,_,_ = pygm.get_device_info(k) 257 if not inp: 258 continue 259 cls = { 260 'nanoKONTROL MIDI 1' : KorgNanoKontrol, 261 }.get( nm, None ) 262 if cls: 263 DEV[k] = cls( nm, k )
264 265 if __name__=="__main__": 266 from time import sleep, time as now 267 from joy.events import describeEvt 268 from sys import stdout 269 print "Running test" 270 init() 271 t0 = now() 272 while True: 273 for evt in joyEventIter(): 274 print "\r%6.2f "%(now()-t0), 275 print describeEvt(evt), " ", 276 sys.stdout.flush() 277 sleep(0.05) 278