Files
@ e92db17f3e7e
Branch filter:
Location: light9/bcf2000.py - annotation
e92db17f3e7e
4.0 KiB
text/x-python
effectSequencer can now also process some note-like values coming from the fade/ ui
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 116 117 118 | c7478a778992 f001d689b3e2 c7478a778992 c7478a778992 c7478a778992 c7478a778992 f001d689b3e2 c7478a778992 02eb0e99bba5 c7478a778992 c7478a778992 c7478a778992 c7478a778992 02eb0e99bba5 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 b2858c2d4a4d ff9c72cfb023 b2858c2d4a4d b2858c2d4a4d c7478a778992 c7478a778992 02eb0e99bba5 c7478a778992 0bb08e887166 c7478a778992 bd8a89743226 c7478a778992 c7478a778992 c7478a778992 0bb08e887166 551f06733559 c7478a778992 0bb08e887166 c7478a778992 0bb08e887166 c7478a778992 c7478a778992 0bb08e887166 c7478a778992 c7478a778992 c7478a778992 0bb08e887166 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 f001d689b3e2 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 c7478a778992 48af0ea86ff4 0bb08e887166 c7478a778992 02eb0e99bba5 c7478a778992 c7478a778992 c7478a778992 f001d689b3e2 c7478a778992 02eb0e99bba5 c7478a778992 c7478a778992 02eb0e99bba5 02eb0e99bba5 02eb0e99bba5 c7478a778992 c7478a778992 c7478a778992 551f06733559 551f06733559 551f06733559 c7478a778992 c7478a778992 c7478a778992 c7478a778992 02eb0e99bba5 c7478a778992 68e1655eaa2c c7478a778992 fc87327e29c4 0bb08e887166 551f06733559 551f06733559 551f06733559 551f06733559 c7478a778992 02eb0e99bba5 c7478a778992 c7478a778992 c7478a778992 | #!/usr/bin/python
import math
import twisted.internet.fdesc
from twisted.internet import reactor
from twisted.internet.task import LoopingCall
from typing import Dict
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/midiC2D0"):
"""device was usually /dev/snd/midiC1D0 but then it showed up
once as C0D0. It should be autodetected"""
self.devPath = dev
self.dev = None
self.lastValue: Dict[str, int] = {} # control name : value
self.reopen()
self.packet = b""
loop = LoopingCall(self.poll)
loop.start(.01)
def poll(self):
try:
newData = self.dev.read(3)
except (IOError, AttributeError):
return
if newData is None:
return
self.packet += newData
if len(self.packet) == 3:
p = self.packet
self.packet = b""
self.packetReceived(p)
def packetReceived(self, packet):
b0, which, value = 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, "rb+", buffering=0)
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 list(self.control.items()) if v == name]
assert len(which) == 1, "unknown control name %r" % name
if name.startswith('button-'):
value = value * 127
#print "bcf: write %s %s" % (name, value)
self.dev.write(bytes([0xb0, which[0], int(value)]))
def close(self):
self.dev.close()
self.dev = None
if __name__ == '__main__':
b = BCF2000()
reactor.run()
|