Got seek_ppqn/seek_samples the other way around :-)
[calfbox.git] / drvjunk / miditest.py
bloba670167d6267f1781e1e6eb60962287d8ef58fb3
1 import array
2 import binascii
3 import usb.core
4 import usb.util
5 import time
7 class USBMIDIConfiguration:
8 def __init__(self, cfg, ifno, ifalt):
9 self.cfg = cfg
10 self.ifno = ifno
11 self.ifalt = ifalt
12 def __str__(self):
13 return "cfg=%d ifno=%d ifalt=%d" % (self.cfg, self.ifno, self.ifalt)
14 def __repr__(self):
15 return "USBMIDIConfiguration(%d,%d,%d)" % (self.cfg, self.ifno, self.ifalt)
17 class USBMIDIDeviceDescriptor:
18 def __init__(self, vendorID, productID, interfaces = None):
19 self.vendorID = vendorID
20 self.productID = productID
21 if interfaces is None:
22 self.interfaces = []
23 else:
24 self.interfaces = interfaces
25 def add_interface(self, config, ifno, ifalt):
26 self.interfaces.append(USBMIDIConfiguration(config, ifno, ifalt))
27 def has_interfaces(self):
28 return len(self.interfaces)
29 def __str__(self):
30 return "vid=%04x pid=%04x" % (self.vendorID, self.productID)
31 def __repr__(self):
32 return "USBMIDIDeviceDescriptor(0x%04x, 0x%04x, %s)" % (self.vendorID, self.productID, self.interfaces)
34 class USBMIDI:
35 cin_sizes = [None, None, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1]
36 def __init__(self, mididev, midicfg, debug = False):
37 dev = usb.core.find(idVendor = mididev.vendorID, idProduct = mididev.productID)
38 self.dev = dev
39 intf = None
40 for cfgo in dev:
41 if cfgo.bConfigurationValue == midicfg.cfg:
42 cfgo.set()
43 intf = cfgo[(midicfg.ifno, midicfg.ifalt)]
44 if not intf:
45 raise ValueError, "Configuration %d not found" % midicfg.cfg
46 print intf.bNumEndpoints
47 self.epIn = None
48 self.epOut = None
49 for ep in intf:
50 if debug:
51 print "endpoint %x" % ep.bEndpointAddress
52 if ep.bEndpointAddress > 0x80:
53 if self.epIn is None:
54 self.epIn = ep
55 else:
56 if self.epOut is None:
57 self.epOut = ep
59 def read(self):
60 try:
61 data = self.epIn.read(self.epIn.wMaxPacketSize)
62 if data is None:
63 return None
64 return array.array('B', data)
65 except usb.core.USBError, e:
66 return None
68 def encode(self, port, msg):
69 a = array.array('B')
70 a.append(16 * port + (msg[0] >> 4))
71 a.fromlist(msg)
72 return a
74 def write(self, data):
75 self.epOut.write(data)
77 def parse(self, data):
78 i = 0
79 msgs = []
80 while i < len(data):
81 if data[i] == 0:
82 break
83 cin, cable_id = data[i] & 15, data[i] >> 4
84 msgs.append(data[i + 1 : i + 1 + KeyRig25.cin_sizes[cin]])
85 i += 4
86 return msgs
88 @staticmethod
89 def findall(vendorID = None, productID = None, debug = False):
90 dev_list = []
91 devices = usb.core.find(find_all = True)
92 for dev in devices:
93 if vendorID is not None and dev.idVendor != vendorID:
94 continue
95 if productID is not None and dev.idProduct != productID:
96 continue
97 thisdev = USBMIDIDeviceDescriptor(dev.idVendor, dev.idProduct)
98 if debug:
99 print "Device %04x:%04x, class %d" % (dev.idVendor, dev.idProduct, dev.bDeviceClass)
100 if dev.bDeviceClass == 0: # device defined at interface level
101 for cfg in dev:
102 if debug:
103 print "Configuration ", cfg.bConfigurationValue
104 for intf in cfg:
105 if debug:
106 print "Interface %d alternate-setting %d" % (intf.bInterfaceNumber, intf.bAlternateSetting)
107 print "Class %d subclass %d" % (intf.bInterfaceClass, intf.bInterfaceSubClass)
108 if intf.bInterfaceClass == 1 and intf.bInterfaceSubClass == 3:
109 if debug:
110 print "(%d,%d,%d): This is USB MIDI" % (cfg.bConfigurationValue, intf.bInterfaceNumber, intf.bAlternateSetting)
111 thisdev.add_interface(cfg.bConfigurationValue, intf.bInterfaceNumber, intf.bAlternateSetting)
112 if thisdev.has_interfaces():
113 dev_list.append(thisdev)
114 return dev_list
116 #print devices
118 class KnownUSBMIDI(USBMIDI):
119 def __init__(self, vendorID, productID):
120 devlist = USBMIDI.findall(vendorID, productID, debug = False)
121 if not devlist:
122 raise ValueError
123 USBMIDI.__init__(self, devlist[0], devlist[0].interfaces[0])
125 class KeyRig25(KnownUSBMIDI):
126 def __init__(self):
127 KnownUSBMIDI.__init__(self, vendorID = 0x763, productID = 0x115)
129 class XMidi2x2(KnownUSBMIDI):
130 def __init__(self):
131 KnownUSBMIDI.__init__(self, vendorID = 0x41e, productID = 0x3f08)
133 class LexiconOmega(KnownUSBMIDI):
134 def __init__(self):
135 KnownUSBMIDI.__init__(self, vendorID = 0x1210, productID = 2)
137 print USBMIDI.findall()
138 xmidi = XMidi2x2()
139 xmidi.write(xmidi.encode(1, [0x90, 36, 100]))
140 xmidi.write(xmidi.encode(1, [0x80, 36, 100]))
142 #krig = KeyRig25()
143 krig = LexiconOmega()
144 while True:
145 data = krig.read()
146 if data is not None:
147 decoded = krig.parse(data)
148 reencoded = array.array('B')
149 for msg in decoded:
150 reencoded.extend(xmidi.encode(1, list(msg)))
151 xmidi.write(reencoded)
152 print decoded