Files
@ f5a75dbe96cd
Branch filter:
Location: light9/bcf2000.py - annotation
f5a75dbe96cd
4.0 KiB
text/x-python
bcf2000: *really* forget last slider values on reopen
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 f5a75dbe96cd c7478a778992 c7478a778992 c7478a778992 bd8a89743226 c7478a778992 c7478a778992 c7478a778992 c7478a778992 551f06733559 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 48af0ea86ff4 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 551f06733559 551f06733559 551f06733559 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 fc87327e29c4 c7478a778992 551f06733559 551f06733559 551f06733559 551f06733559 c7478a778992 c7478a778992 c7478a778992 c7478a778992 | #!/usr/bin/python
from __future__ import division
import math
import twisted.internet.fdesc
from twisted.internet import reactor
from twisted.internet.task import LoopingCall
class BCF2000(object):
control = {81 : "slider1", 82 : "slider2", 83 : "slider3", 84 : "slider4",
85 : "slider5", 86 : "slider6", 87 : "slider7", 88 : "slider8",
1 : "knob1", 2 : "knob2", 3 : "knob3", 4 : "knob4",
5 : "knob5", 6 : "knob6", 7 : "knob7", 8 : "knob8",
33 : "button-knob1", 34 : "button-knob2",
35 : "button-knob3", 36 : "button-knob4",
37 : "button-knob5", 38 : "button-knob6",
39 : "button-knob7", 40 : "button-knob8",
65 : "button-upper1", 66 : "button-upper2",
67 : "button-upper3", 68 : "button-upper4",
69 : "button-upper5", 70 : "button-upper6",
71 : "button-upper7", 72 : "button-upper8",
73 : "button-lower1", 74 : "button-lower2",
75 : "button-lower3", 76 : "button-lower4",
77 : "button-lower5", 78 : "button-lower6",
79 : "button-lower7", 80 : "button-lower8",
89 : "button-corner1", 90 : "button-corner2",
91 : "button-corner3", 92 : "button-corner4",
}
def __init__(self, dev="/dev/snd/midiC1D0"):
self.devPath = dev
self.dev = None
self.lastValue = {} # control name : value
self.reopen()
self.packet = ""
loop = LoopingCall(self.poll)
loop.start(.01)
def poll(self):
try:
bytes = self.dev.read(3)
except (IOError, AttributeError):
return
if len(bytes) == 0:
print "midi stall, reopen slider device"
self.reopen()
return
self.packet += bytes
if len(self.packet) == 3:
p = self.packet
self.packet = ""
self.packetReceived(p)
def packetReceived(self, packet):
b0, which, value = [ord(b) for b in packet]
if b0 != 0xb0:
return
if which in self.control:
name = self.control[which]
if name.startswith("button-"):
value = value > 0
self.lastValue[name] = value
self.valueIn(name, value)
else:
print "unknown control %s to %s" % (which, value)
def reopen(self):
if self.dev is not None:
try:
self.dev.close()
except IOError:
pass
self.lastValue.clear()
self.dev = open(self.devPath, "r+")
twisted.internet.fdesc.setNonBlocking(self.dev)
def valueIn(self, name, value):
"""override this with your handler for when events come in
from the hardware"""
print "slider %s to %s" % (name, value)
if name == 'slider1':
for x in range(2,8+1):
v2 = int(64 + 64 * math.sin(x / 3 + value / 10))
self.valueOut('slider%d' % x, v2)
for x in range(1,8+1):
self.valueOut('button-upper%s' % x, value > x*15)
self.valueOut('button-lower%s' % x, value > (x*15+7))
def valueOut(self, name, value):
"""call this to send an event to the hardware"""
if self.dev is None:
return
value = int(value)
if self.lastValue.get(name) == value:
return
self.lastValue[name] = value
which = [k for k,v in self.control.items() if v == name]
assert len(which) == 1, "unknown control name %r" % name
if isinstance(value, bool):
value = value * 127
#print "bcf: write %s %s" % (name, value)
self.dev.write(chr(0xb0) + chr(which[0]) + chr(int(value)))
def close(self):
self.dev.close()
self.dev = None
if __name__ == '__main__':
b = BCF2000()
reactor.run()
|