From 5fa47fd24984b487ea36a658f798acead3fe305d Mon Sep 17 00:00:00 2001 From: Casey Tucker Date: Sun, 24 Mar 2024 22:12:37 -0700 Subject: [PATCH] send is now mix in bridge --- bridge/bridge.py | 2 +- bridge/capture.py | 21 +++++--- bridge/control.py | 129 +++++++++++++++++++++++++--------------------- bridge/model.py | 2 +- bridge/view.py | 2 +- 5 files changed, 86 insertions(+), 70 deletions(-) diff --git a/bridge/bridge.py b/bridge/bridge.py index fcd9465..e39f50c 100755 --- a/bridge/bridge.py +++ b/bridge/bridge.py @@ -90,8 +90,8 @@ def check_connections(client, port): x = capture.listen() if control.ok: - control.sync() control.listen() + control.sync() # check for disconnect if capture.ok or control.ok: diff --git a/bridge/capture.py b/bridge/capture.py index 5097509..80df262 100644 --- a/bridge/capture.py +++ b/bridge/capture.py @@ -2,6 +2,9 @@ from view import log from bindings.capmix import capmix, Type +def addr_channel(addr): + return ((addr & 0x0f00) >> 8) + 1 + class Capture: def __init__(self, name='STUDIO-CAPTURE MIDI 2'): capmix.set_model(4) @@ -16,7 +19,7 @@ def listener(self, event): if 'input_monitor.' in addr: dirty = True if '.mute' in addr: - ch = ((event.addr & 0x0f00) >> 8) + 1 + ch = addr_channel(event.addr) mon = self.model.monitors[(event.addr & 0xf000) >> 12] mute = value.unpacked.discrete self.model.mutes[ch][mon] = mute @@ -25,13 +28,13 @@ def listener(self, event): # TODO may not be needed self.model.queue.put([int((ch-1)/2), 82, 0 if mute == 0 else 127]) elif '.stereo' in addr: - ch = ((event.addr & 0x0f00) >> 8) + 1 + ch = addr_channel(event.addr) self.model.stereo[ch] = value.unpacked.discrete elif '.pan' in addr: - ch = ((event.addr & 0x0f00) >> 8) + 1 + ch = addr_channel(event.addr) self.model.pans[ch] = value #capmix.format_type(Type.Pan, value.unpacked) #.unpacked.discrete >> 24 - #log("addr=%x=%s type=%s v=%s" % (event.addr, addr, event.type_name(), value)) + log("addr=%x=%s type=%s v=%s" % (event.addr, addr, event.type_name(), value)) def connect(self): self.ok = capmix.connect(self.listener) @@ -50,10 +53,14 @@ def disconnect(self): def listen(self): return capmix.listen() + def query(self, name): + capmix.get(capmix.parse_addr(name)) + def get_mixer_data(self): for ch in range(0,16,2): - capmix.get(capmix.parse_addr("input_monitor.a.channel.{}.stereo".format(ch+1))) + self.query("input_monitor.a.channel.{}.stereo".format(ch+1)) for ch in range(0,16): for mon in self.model.monitors: - capmix.get(capmix.parse_addr("input_monitor.{}.channel.{}.mute".format(mon, ch+1))) - capmix.get(capmix.parse_addr("input_monitor.a.channel.{}.pan".format(ch+1))) + self.query("input_monitor.{}.channel.{}.mute".format(mon, ch+1)) + self.query("input_monitor.a.channel.{}.pan".format(ch+1)) + diff --git a/bridge/control.py b/bridge/control.py index 3a79444..7f009a1 100644 --- a/bridge/control.py +++ b/bridge/control.py @@ -45,6 +45,9 @@ def listener(self, event): self.do_arm(event.value) elif k == 'mute': self.do_mute(event.value) + elif k == 'solo': + self.do_solo(event.value) + self.view.logged = True elif k == 'fader': self.do_fader(event.value) elif k == 'knob': @@ -57,50 +60,55 @@ def mixer_channel(self): def do_arm(self, down): ch = self.mixer_channel() - if down == 0: - return + if down == 0: return val = self.model.value('input_monitor.d.channel.%d.mute' % (ch)) if val.unpacked.discrete == 0: - self.model.send('input_monitor.%s.channel.%d.mute' % (self.last_monitor, ch), 0) - self.model.send('input_monitor.%s.channel.%d.mute' % ('d', ch), 1) + self.model.mix('input_monitor.%s.channel.%d.mute' % (self.last_monitor, ch), 0) + self.model.mix('input_monitor.%s.channel.%d.mute' % ('d', ch), 1) self.armed = True else: - self.model.send('input_monitor.%s.channel.%d.mute' % (self.last_monitor, ch), 1) - self.model.send('input_monitor.%s.channel.%d.mute' % ('d', ch), 0) + self.model.mix('input_monitor.%s.channel.%d.mute' % (self.last_monitor, ch), 1) + self.model.mix('input_monitor.%s.channel.%d.mute' % ('d', ch), 0) self.armed = False + + def do_solo(self, down): + ch = self.mixer_channel() + if down == 0: return + + val = self.model.value('input_monitor.a.channel.%d.solo' % (ch)) + v = 0 if val.unpacked.discrete == 1 else 1 + if self.armed: + self.model.mix('input_monitor.%s.channel.%d.solo' % (self.last_monitor, ch), v) + else: + self.model.mix('input_monitor.%s.channel.%d.solo' % ('d', ch), v) + self.soloed = (v == 1) def do_fader(self, val): ch = self.mixer_channel() if val == 127: - self.model.send('input_monitor.a.channel.%d.mute' % (ch), 0) - self.model.send('input_monitor.c.channel.%d.mute' % (ch), 1) + self.model.mix('input_monitor.a.channel.%d.mute' % (ch), 0) + self.model.mix('input_monitor.c.channel.%d.mute' % (ch), 1) self.last_monitor = 'a' elif val == 0: - self.model.send('input_monitor.a.channel.%d.mute' % (ch), 1) - self.model.send('input_monitor.c.channel.%d.mute' % (ch), 0) + self.model.mix('input_monitor.a.channel.%d.mute' % (ch), 1) + self.model.mix('input_monitor.c.channel.%d.mute' % (ch), 0) self.last_monitor = 'c' else: # TODO pass def do_mute(self, val): - ch = self.mixer_channel() - v = 0 if val == 0 else 1 - if self.armed: - self.model.send('input_monitor.%s.channel.%d.mute' % (self.last_monitor, ch), v) - else: - self.model.send('input_monitor.%s.channel.%d.mute' % ('d', ch), v) - self.muted = v == 1 + if val == 0: return - def do_solo(self, val): ch = self.mixer_channel() v = 0 if val == 0 else 1 if self.armed: - self.model.send('input_monitor.%s.channel.%d.solo' % (self.last_monitor, ch), v) + self.model.mix('input_monitor.%s.channel.%d.mute' % (self.last_monitor, ch), v) else: - self.model.send('input_monitor.%s.channel.%d.solo' % ('d', ch), v) - + self.model.mix('input_monitor.%s.channel.%d.mute' % ('d', ch), v) + self.muted = (v == 1) + def do_knob(self, val): if self.stop_held: if self.channel == 0: @@ -120,12 +128,12 @@ def do_knob(self, val): pan_l = Value.parse(Type.Pan, pan_l) pan_r = Value.parse(Type.Pan, pan_r) - self.model.send('input_monitor.a.channel.%d.pan' % (ch) , pan_l.unpacked) - self.model.send('input_monitor.a.channel.%d.pan' % (ch+1), pan_r.unpacked) - self.model.send('input_monitor.c.channel.%d.pan' % (ch) , pan_l.unpacked) - self.model.send('input_monitor.c.channel.%d.pan' % (ch+1), pan_r.unpacked) - self.model.send('input_monitor.d.channel.%d.pan' % (ch) , pan_l.unpacked) - self.model.send('input_monitor.d.channel.%d.pan' % (ch+1), pan_r.unpacked) + self.model.mix('input_monitor.a.channel.%d.pan' % (ch) , pan_l.unpacked) + self.model.mix('input_monitor.a.channel.%d.pan' % (ch+1), pan_r.unpacked) + self.model.mix('input_monitor.c.channel.%d.pan' % (ch) , pan_l.unpacked) + self.model.mix('input_monitor.c.channel.%d.pan' % (ch+1), pan_r.unpacked) + self.model.mix('input_monitor.d.channel.%d.pan' % (ch) , pan_l.unpacked) + self.model.mix('input_monitor.d.channel.%d.pan' % (ch+1), pan_r.unpacked) self.model.pans[ch] = pan_l self.model.pans[ch+1] = pan_r @@ -197,13 +205,14 @@ def listener(self, event): self.send('cycle', 127 if self.looping else 0) if self.left > 0 and self.right > 0 and k == 'stop' and prev_state == 'stop': - os.system("reset") + os.system('tmux select-window -t 1') if self.looping: - print("Rebooting") + os.system('wall Rebooting') + print("\033[2J\nRebooting") sleep(2) os.system('sudo systemctl reboot') else: - print("Shutting down") + print("\033[2J\nShutting down") sleep(2) os.system('sudo systemctl poweroff') exit(0) @@ -286,34 +295,6 @@ def send(self, name, val): if name in self.transport.cc_map: self.transport.send(name, val) - def dim(self): - self.send('stop', 0) - self.send('cycle', 0) - self.channels[0].send('mute', 0) - - def hello(self, delay=0.01): - def blink(ch, cc, val): - self.send_cc(ch, cc, val) - sleep(delay) - - def chase(val): - for i in range(0,8): - blink(i, 80, val) - blink(15, 87, val) - - for i in range(0,8): - blink(i, 81, val) - - for p in [111, 112, 113, 114, 115]: - blink(15, p, val) - for i in range(0,8): - blink(i, 82, val) - - chase(127) - chase(0) - - self.transport.ready() - def listen(self): event = self.client.event_input(timeout=0.01) while event: @@ -326,7 +307,7 @@ def listener(self, event): return elif isinstance(event, SysExEvent): self.ok = True - log(repr(event)) + #log(repr(event)) return if event.channel == 15: self.transport.listener(event) @@ -344,7 +325,7 @@ def sync_mutes(self): solos = self.model.solos mutes = self.model.mutes - chan.soloed = solos[ch]['a'] + solos[ch]['c'] + solos[ch]['d'] == 1 + chan.soloed = solos[ch]['a'] #+ solos[ch]['c'] + solos[ch]['d'] >= 1 chan.muted = mutes[ch]['a'] + mutes[ch]['c'] + mutes[ch]['d'] == 3 if not chan.muted: chan.armed = mutes[ch]['d'] @@ -366,3 +347,31 @@ def sync(self): except Empty: break + def hello(self, delay=0.01): + def blink(ch, cc, val): + self.send_cc(ch, cc, val) + sleep(delay) + + def chase(val): + for i in range(0,8): + blink(i, 80, val) + blink(15, 87, val) + + for i in range(0,8): + blink(i, 81, val) + + for p in [111, 112, 113, 114, 115]: + blink(15, p, val) + for i in range(0,8): + blink(i, 82, val) + + chase(127) + chase(0) + + self.transport.ready() + + def dim(self): + self.send('stop', 0) + self.send('cycle', 0) + self.channels[0].send('arm', 0) + diff --git a/bridge/model.py b/bridge/model.py index d8b4fa2..392c91d 100644 --- a/bridge/model.py +++ b/bridge/model.py @@ -20,7 +20,7 @@ def reset(self): self.solos[c+1][m] = 0 self.stereo[c+1] = 0 - def send(self, param, value): + def mix(self, param, value): self.capture_hash[capmix.parse_addr(param)] = value def flush(self): diff --git a/bridge/view.py b/bridge/view.py index 89f8d54..609b560 100644 --- a/bridge/view.py +++ b/bridge/view.py @@ -39,7 +39,7 @@ class View: enable_dimming = False def __init__(self, model): - self.compact = True + self.compact = False self.model = model size = lambda: None size.columns = 99