From dda9a4c0fd3d6bbecab0616254ace479b5d4d233 Mon Sep 17 00:00:00 2001 From: sbahling Date: Sun, 21 Oct 2018 15:10:29 +0200 Subject: continued refactoring --- buttons.py | 40 +++++------ console.py | 175 ++++++++++++++++++++++++++++++++++++----------- faders.py | 60 ++++++----------- fw-1884-buttons.py | 194 ----------------------------------------------------- fw_1884_buttons.py | 194 +++++++++++++++++++++++++++++++++++++++++++++++++++++ osc.py | 60 +++++++++++++++++ strips.py | 88 ++++++++++++++++++++++-- 7 files changed, 515 insertions(+), 296 deletions(-) delete mode 100644 fw-1884-buttons.py create mode 100644 fw_1884_buttons.py create mode 100644 osc.py diff --git a/buttons.py b/buttons.py index 89ae479..5f1ffbe 100644 --- a/buttons.py +++ b/buttons.py @@ -22,7 +22,7 @@ import re import pyautogui -from osc import osc +import osc keymap = {'CTRL': 'ctrl', @@ -90,7 +90,7 @@ class StripSelButton(Button): def __init__(self, console, name, strip): super().__init__(console, name) self.strip = strip - self.strip.select = self + self.strip.select_button = self def press(self): @@ -98,9 +98,9 @@ class StripSelButton(Button): print('handle_strip_sel', strip) if self.get('REC ENABLE', 0): if strip.recenable: - osc.send_message('/strip/recenable', (strip.num, 0)) + osc.client.sent_message('/strip/recenable', (strip.num, 0)) else: - osc.send_message('/strip/recenable', (strip.num, 1)) + osc.client.sent_message('/strip/recenable', (strip.num, 1)) super().press() @@ -108,17 +108,17 @@ class StripMuteButton(Button): def __init__(self, console, name, strip): super().__init__(console, name) self.strip = strip - self.strip.mute = self + self.strip.mute_button = self def press(self): strip = self.strip if strip.mute: strip.mute = False - osc.send_message('/strip/mute', (strip.num, 0)) + osc.client.sent_message('/strip/mute', (strip.num, 0)) else: strip.mute = True - osc.send_message('/strip/mute', (strip.num, 1)) + osc.client.sent_message('/strip/mute', (strip.num, 1)) super().press() @@ -126,17 +126,17 @@ class StripSoloButton(Button): def __init__(self, console, name, strip): super().__init__(console, name) self.strip = strip - self.strip.solo = self + self.strip.solo_button = self def press(self): strip = self.strip if strip.solo: strip.solo = False - osc.send_message('/strip/solo', (strip.num, 0)) + osc.client.sent_message('/strip/solo', (strip.num, 0)) else: strip.solo = True - osc.send_message('/strip/solo', (strip.num, 1)) + osc.client.sent_message('/strip/solo', (strip.num, 1)) super().press() @@ -175,7 +175,7 @@ class ComputerButton(Button): super().__init__(console, name) def press(self): - osc.send_message('/set_surface', (8, 7, 19, 1, 8, 11)) + osc.client.sent_message('/set_surface', (8, 7, 19, 1, 8, 11)) super().press() @@ -184,7 +184,7 @@ class ClrSoloButton(Button): super().__init__(console, name) def press(self): - osc.send_message('/cancel_all_solos', 1) + osc.client.sent_message('/cancel_all_solos', 1) super().press() @@ -195,10 +195,10 @@ class LoopButton(Button): def press(self, *args): if self.console.state.get('loop', 0): print('******* loop off') - osc.send_message('/loop_toggle', 0) + osc.client.sent_message('/loop_toggle', 0) else: print('******* loop on') - osc.send_message('/loop_toggle', 1) + osc.client.sent_message('/loop_toggle', 1) super().press() @@ -209,7 +209,7 @@ class TransportButton(Button): def press(self): addr = osc_addrs.get(self.name, None) if addr: - osc.send_message(addr, 1) + osc.client.sent_message(addr, 1) super().press() @@ -224,10 +224,10 @@ class BankSwitchButton(Button): print(direction, more_banks_up, more_banks_down) if direction > 0 and more_banks_up: print('calling /bank_up 1') - osc.send_message('/bank_up', 1) + osc.client.sent_message('/bank_up', 1) elif direction < 0 and more_banks_down: print('calling /bank_down 1') - osc.send_message('/bank_down', 1) + osc.client.sent_message('/bank_down', 1) super().press() @@ -240,7 +240,9 @@ class NudgeButton(Button): direction = self.direction print(direction) if direction > 0: - osc.send_message('/access_action', 'Common/nudge-next-forward') + osc.client.sent_message('/access_action', + 'Common/nudge-next-forward') else: - osc.send_message('/access_action', 'Common/nudge-next-backward') + osc.client.sent_message('/access_action', + 'Common/nudge-next-backward') super().press() diff --git a/console.py b/console.py index a06c5ee..c7f1d2c 100644 --- a/console.py +++ b/console.py @@ -26,6 +26,7 @@ import time import threading from pathlib import Path +import osc import strips import fw_1884_buttons @@ -38,13 +39,17 @@ from hinawa_utils.tscm.tscm_console_unit import TscmConsoleUnit # noqa: E402 bits32 = '{:032b}'.format -current_bank = 1 -more_banks_up = False -more_banks_down = False +class ConsoleStatus(): + def __init__(self, quadlets): + self.quadlets = quadlets -def check_bitR2L(data, bit): - return bool(data & (0b1 << bit)) + def field(self, quadlet, first_bit=0, last_bit=32): + bits = self.quadlets[quadlet] + + # reverse the bit order before slicing so the index '0' is the LSB + # and reverse back before converting to int + return int(bits32(bits)[::-1][first_bit:last_bit][::-1], 2) class RunningStatusThread(): @@ -53,13 +58,14 @@ class RunningStatusThread(): :type interval: int :param interval: Check interval, in seconds """ + self.console = console self.interval = interval + self.callbacks = set() + self.last_status = [] - thread = threading.Thread(target=self.run, args=(console)) + thread = threading.Thread(target=self.run) thread.daemon = True # Daemonize thread thread.start() # Start the execution - self.callbacks = set() - self.last_status = [] def add_callback(self, obj): self.callbacks.add(obj) @@ -67,36 +73,14 @@ class RunningStatusThread(): def remove_callback(self, obj): self.callbacks.remove(obj) - def fetch_status_values(self, quadlets=None, first_bit=0, last_bit=32): - if quadlets is None: - quadlets = [i for i in range(0, 16)] - - def getvalue(bits): - # reverse the bit order before slicing so the index '0' is the LSB - # and reverse back before converting to int - return int(bits32(bits)[::-1][first_bit:last_bit][::-1], 2) - - values = [getvalue(self.last_status[q]) for q in quadlets] - - if len(values) == 1: - return values[0] - - return values - - def run(self, console): + def run(self): """ Method that runs forever """ while True: - - if not self.callbacks: - continue - - try: - self.last_status = console.unit.get_status() - except Exception: - continue # we should emit warning or error here! - - for callback in self.callbacks: - callback.call(self.fetch_status_values(**callback.args)) + for obj in self.callbacks: + value = self.console.status.field(obj.status_quadlet, + **obj.status_bits, + ) + obj.status_callback(value) time.sleep(self.interval) @@ -111,19 +95,29 @@ class Console(): exit() self.state = {} - self.strips = strips.init_strips(self.unit) + self.current_bank = 1 + self.more_banks_up = False + self.more_banks_down = False + self.strips = strips.init_strips(self) self.buttons = fw_1884_buttons.init_buttons(self) self.unit.connect('control', self.handle_control) status_thread = RunningStatusThread(self) # noqa F841 + @property + def status(self): + try: + return ConsoleStatus(self.unit.get_status()) + except Exception as e: + raise e + def handle_bit_flags(self, index, before, after): changed = before ^ after for bit in [i for i, b in enumerate(bits32(changed)) if int(b)]: - high = check_bitR2L(after, bit) + high = bool(after & (0b1 << bit)) button = self.buttons[index][int(bit)] if button is None: print('unhandled control bit {}:{}'.format(index, bit)) @@ -146,6 +140,106 @@ class Console(): self.handle_encoder(index, before, after) return + def strip_fader_handler(self, addr, args, ssid, pos): + print('fader_handler', addr, ssid, pos) + strip = self.strips(int(ssid)) + if strip.name == ' ': + return + pos = pos * 1023 + strip.fader.position = pos + + def master_fader_handler(self, addr, args, pos): + print('master_fader_handler', pos) + self.strips[0].fader.position(1023 * pos) + + def default_handler(self, addr, *args): + print(addr, args) + + def strip_mute_handler(self, addr, args, ssid, state): + strip = self.strips(int(ssid)) + print('mute_handler', strip, state) + if strip.name == ' ': + return + if state: + strip.mute = True + else: + strip.mute = False + + def strip_solo_handler(self, addr, args, ssid, state): + strip = self.strips(int(ssid)) + print('solo_handler', strip, state) + if strip.name == ' ': + return + if state: + strip.solo = True + else: + strip.solo = False + + def strip_recenable_handler(self, addr, args, ssid, state): + strip = self.strips(int(ssid)) + print('recenable_handler', strip, state) + if strip.name == ' ': + return + if state: + strip.recenable = True + else: + strip.recenable = False + + def loop_toggle_handler(self, addr, state): + print(addr, state) + if state: + self.state['LOOP'] = 1 + self.unit.leds.loop.turn_on() + else: + self.state['LOOP'] = 0 + self.unit.leds.loop.turn_off() + + def transport_stop_handler(self, addr, args, state): + print(addr, args, state) + if state: + self.unit.leds.stop.turn_on() + else: + self.unit.leds.stop.turn_off() + + def transport_play_handler(self, addr, args, state): + print(addr, args, state) + if state: + self.unit.leds.play.turn_on() + else: + self.unit.leds.play.turn_off() + + def ffwd_handler(self, addr, args, state): + if state: + self.unit.leds.f_fwd.turn_on() + else: + self.unit.leds.f_fwd.turn_off() + + def rewind_handler(self, addr, args, state): + if state: + self.unit.leds.rew.turn_on() + else: + self.unit.leds.rew.turn_off() + + def rec_enable_toggle_handler(self, addr, args, state): + if state: + self.unit.leds.rec.turn_on() + else: + self.unit.leds.rec.turn_off() + + def pan_stereo_position_handler(self, addr, pos, pan): + self.strips[pos].recv_pan(pan) + + def strip_name_handler(self, addr, ssid, name): + self.strips[int(ssid)].name = name + + def bank_up_handler(self, addr, more_up): + print(addr, more_up) + self.more_banks_up = bool(more_up) + + def bank_down_handler(self, addr, more_down): + print(addr, more_down) + self.more_banks_down = bool(more_down) + def _check_hexadecimal(literal): if literal.find('0x') == 0: @@ -200,3 +294,8 @@ if __name__ == "__main__": args = parser.parse_args() console = Console(args.card) + osc.init_client(args.ip, args.port) + osc.init_server(args.listen_ip, args.listen_port, console) + + print("Serving on {}".format(osc.server.server_address)) + osc.server.serve_forever() diff --git a/faders.py b/faders.py index ed202c5..5d5fdde 100644 --- a/faders.py +++ b/faders.py @@ -21,7 +21,19 @@ """ from buttons import Button -from osc import osc +import osc + +status_quadlets = (4, 0, 0, 1, 1, 2, 2, 3, 3) +status_bits = ((1, 16), + (1, 16), + (17, 32), + (1, 16), + (17, 32), + (1, 16), + (17, 32), + (1, 16), + (17, 32), + ) class Fader(Button): @@ -31,20 +43,21 @@ class Fader(Button): self.strip = strip self.pos = 0 self.addr = '/strip/fader' - self.console_callback = self.send_pos - - @position.setter - def position(self, pos): - self.pos = pos - self.console.unit.strips - + self.status_quadlet = status_quadlets[self.strip.num] + self.status_bits = status_bits[self.strip.num] + self.status_callback = self.send_pos @property def position(self): return self.pos + @position.setter + def position(self, pos): + self.pos = pos + self.console.unit.strips[self.strip.num].set_position(pos) + def send_pos(self): - osc.send_message(self.addr, (self.strip, self.pos/1023)) + osc.client.sent_message(self.addr, (self.strip, self.pos/1023)) def handle_console_status(self, pos): if pos != self.pos: @@ -59,32 +72,3 @@ class Fader(Button): def release(self): self.console.status_thread.remove_callback(self) super().press() - - - - -def strip_fader_handler(addr, args, ssid, pos): - unit = args[0] - strip = int(ssid) - print('fader_handler', addr, ssid, pos) - pos = pos * 1023 - if strip_states[strip].name != ' ': - unit.strips[strip].fader.set_position(pos) - strip_states[strip].fader = pos - - strips[strip].fader.set_position(pos) - - - unit = args[0] - if state: - unit.leds.rew.turn_on() - else: - unit.leds.rew.turn_off() - - - -def master_fader_handler(addr, args, pos): - unit = args[0] - print('master_fader_handler', pos) - unit.master_fader.set_position(1023 * pos) - diff --git a/fw-1884-buttons.py b/fw-1884-buttons.py deleted file mode 100644 index b9486d5..0000000 --- a/fw-1884-buttons.py +++ /dev/null @@ -1,194 +0,0 @@ -#!/usr/bin/env python3 -""" - Open Sound Control send/recieve daemon for Tascam Firewire control surface - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - :copyright: Copyright (c) 2012-2014 Scott Bahling - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program (see the file COPYING); if not, write to the - Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - :license: GPL-2.0, see COPYING for details -""" - -import buttons.py - - -def init_buttons(console): - unit = console.unit - strips = console.strips - return {5: [None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - strips[1].fader, - strips[2].fader, - strips[3].fader, - strips[4].fader, - strips[5].fader, - strips[6].fader, - strips[7].fader, - strips[8].fader, - strips[0].fader, - None, - None, - None, - None, - None, - None, - None, - ], - 6: [None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - None, - buttons.StripSelButton(unit, 'Strip 1 Sel', strips[1]), - buttons.StripSelButton(unit, 'Strip 2 Sel', strips[2]), - buttons.StripSelButton(unit, 'Strip 3 Sel', strips[3]), - buttons.StripSelButton(unit, 'Strip 4 Sel', strips[4]), - buttons.StripSelButton(unit, 'Strip 5 Sel', strips[5]), - buttons.StripSelButton(unit, 'Strip 6 Sel', strips[6]), - buttons.StripSelButton(unit, 'Strip 7 Sel', strips[7]), - buttons.StripSelButton(unit, 'Strip 8 Sel', strips[8]), - buttons.StripSoloButton(unit, 'Strip 1 Solo', strips[1]), - buttons.StripSoloButton(unit, 'Strip 2 Solo', strips[2]), - buttons.StripSoloButton(unit, 'Strip 3 Solo', strips[3]), - buttons.StripSoloButton(unit, 'Strip 4 Solo', strips[4]), - buttons.StripSoloButton(unit, 'Strip 5 Solo', strips[5]), - buttons.StripSoloButton(unit, 'Strip 6 Solo', strips[6]), - buttons.StripSoloButton(unit, 'Strip 7 Solo', strips[7]), - buttons.StripSoloButton(unit, 'Strip 8 Solo', strips[8]), - ], - 7: [buttons.StripMuteButton(unit, 'Strip 1 Mute', strips[1]), - buttons.StripMuteButton(unit, 'Strip 2 Mute', strips[2]), - buttons.StripMuteButton(unit, 'Strip 3 Mute', strips[3]), - buttons.StripMuteButton(unit, 'Strip 4 Mute', strips[4]), - buttons.StripMuteButton(unit, 'Strip 5 Mute', strips[5]), - buttons.StripMuteButton(unit, 'Strip 6 Mute', strips[6]), - buttons.StripMuteButton(unit, 'Strip 7 Mute', strips[7]), - buttons.StripMuteButton(unit, 'Strip 8 Mute', strips[8]), - buttons.EncoderButton(unit, 'AUX5'), - buttons.EncoderButton(unit, 'AUX7'), - buttons.EncoderButton(unit, 'AUX6'), - buttons.EncoderButton(unit, 'AUX8'), - None, - None, - None, - None, - buttons.Button(unit, 'FLIP'), - buttons.EncoderButton(unit, 'AUX1'), - buttons.EncoderButton(unit, 'AUX3'), - buttons.EncoderButton(unit, 'PAN'), - buttons.EncoderButton(unit, 'AUX2'), - buttons.EncoderButton(unit, 'AUX4'), - None, - None, - buttons.Button(unit, 'Control Panel'), - buttons.Button(unit, 'F1'), - buttons.Button(unit, 'ALL SAFE'), - buttons.Button(unit, 'F5'), - buttons.Button(unit, 'CUT'), - buttons.Button(unit, 'COPY'), - buttons.ModButton(unit, 'ALT'), - buttons.ModButton(unit, 'SHIFT'), - ], - 8: [buttons.Button(unit, 'F2'), - buttons.ClrSoloButton(unit, 'CLR SOLO'), - buttons.LoopButton(unit, 'LOOP'), - buttons.Button(unit, 'DEL'), - buttons.Button(unit, 'PASTE'), - buttons.Button(unit, 'UNDO'), - buttons.ModButton(unit, 'CTRL'), - buttons.Button(unit, 'Foot Switch'), - buttons.Button(unit, 'Gain Enc A', None), - buttons.Button(unit, 'Gain Enc B', None), - buttons.Button(unit, 'Q Enc A', None), - buttons.Button(unit, 'Q Enc B', None), - None, - None, - None, - None, - buttons.Button(unit, 'Freq Enc A', None), - buttons.Button(unit, 'Freq Enc B', None), - None, - None, - None, - None, - None, - None, - None, - buttons.ComputerButton(unit, 'COMPUTER'), - None, - None, - buttons.Button(unit, 'CLOCK'), - buttons.Button(unit, 'ROUTE'), - None, - None, - ], - 9: [buttons.Button(unit, 'F7'), - buttons.Button(unit, 'F8'), - buttons.Button(unit, 'F9'), - buttons.Button(unit, 'F10'), - buttons.Button(unit, 'READ'), - buttons.Button(unit, 'WRT'), - buttons.Button(unit, 'TCH'), - buttons.Button(unit, 'LATCH'), - buttons.Button(unit, 'HIGH'), - buttons.Button(unit, 'HI-MID'), - buttons.Button(unit, 'LOW-MID'), - buttons.Button(unit, 'LOW'), - buttons.ArrowButton(unit, 'UP'), - buttons.ArrowButton(unit, 'LEFT'), - buttons.ArrowButton(unit, 'DOWN'), - buttons.ArrowButton(unit, 'RIGHT'), - buttons.Button(unit, 'REC ENABLE'), - buttons.NudgeButton(unit, 'NUDGE LEFT', -1), - buttons.NudgeButton(unit, 'NUDGE RIGHT', 1), - buttons.BankSwitchButton(unit, 'BANK LEFT', -1), - buttons.BankSwitchButton(unit, 'BANK RIGHT', 1), - buttons.Button(unit, 'LOCATE LEFT'), - buttons.Button(unit, 'LOCATE RIGHT'), - buttons.Button(unit, 'SHTL'), - buttons.Button(unit, 'SET'), - buttons.Button(unit, 'IN'), - buttons.Button(unit, 'OUT'), - buttons.TransportButton(unit, 'REW'), - buttons.TransportButton(unit, 'F.FWD'), - buttons.TransportButton(unit, 'STOP'), - buttons.TransportButton(unit, 'PLAY'), - buttons.TransportButton(unit, 'REC'), - ] - } diff --git a/fw_1884_buttons.py b/fw_1884_buttons.py new file mode 100644 index 0000000..e1ed548 --- /dev/null +++ b/fw_1884_buttons.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python3 +""" + Open Sound Control send/recieve daemon for Tascam Firewire control surface + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + :copyright: Copyright (c) 2012-2014 Scott Bahling + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program (see the file COPYING); if not, write to the + Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + :license: GPL-2.0, see COPYING for details +""" + +import buttons + + +def init_buttons(console): + unit = console.unit + strips = console.strips + return {5: [None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + strips[1].fader, + strips[2].fader, + strips[3].fader, + strips[4].fader, + strips[5].fader, + strips[6].fader, + strips[7].fader, + strips[8].fader, + strips[0].fader, + None, + None, + None, + None, + None, + None, + None, + ], + 6: [None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + buttons.StripSelButton(unit, 'Strip 1 Sel', strips[1]), + buttons.StripSelButton(unit, 'Strip 2 Sel', strips[2]), + buttons.StripSelButton(unit, 'Strip 3 Sel', strips[3]), + buttons.StripSelButton(unit, 'Strip 4 Sel', strips[4]), + buttons.StripSelButton(unit, 'Strip 5 Sel', strips[5]), + buttons.StripSelButton(unit, 'Strip 6 Sel', strips[6]), + buttons.StripSelButton(unit, 'Strip 7 Sel', strips[7]), + buttons.StripSelButton(unit, 'Strip 8 Sel', strips[8]), + buttons.StripSoloButton(unit, 'Strip 1 Solo', strips[1]), + buttons.StripSoloButton(unit, 'Strip 2 Solo', strips[2]), + buttons.StripSoloButton(unit, 'Strip 3 Solo', strips[3]), + buttons.StripSoloButton(unit, 'Strip 4 Solo', strips[4]), + buttons.StripSoloButton(unit, 'Strip 5 Solo', strips[5]), + buttons.StripSoloButton(unit, 'Strip 6 Solo', strips[6]), + buttons.StripSoloButton(unit, 'Strip 7 Solo', strips[7]), + buttons.StripSoloButton(unit, 'Strip 8 Solo', strips[8]), + ], + 7: [buttons.StripMuteButton(unit, 'Strip 1 Mute', strips[1]), + buttons.StripMuteButton(unit, 'Strip 2 Mute', strips[2]), + buttons.StripMuteButton(unit, 'Strip 3 Mute', strips[3]), + buttons.StripMuteButton(unit, 'Strip 4 Mute', strips[4]), + buttons.StripMuteButton(unit, 'Strip 5 Mute', strips[5]), + buttons.StripMuteButton(unit, 'Strip 6 Mute', strips[6]), + buttons.StripMuteButton(unit, 'Strip 7 Mute', strips[7]), + buttons.StripMuteButton(unit, 'Strip 8 Mute', strips[8]), + buttons.EncoderButton(unit, 'AUX5'), + buttons.EncoderButton(unit, 'AUX7'), + buttons.EncoderButton(unit, 'AUX6'), + buttons.EncoderButton(unit, 'AUX8'), + None, + None, + None, + None, + buttons.Button(unit, 'FLIP'), + buttons.EncoderButton(unit, 'AUX1'), + buttons.EncoderButton(unit, 'AUX3'), + buttons.EncoderButton(unit, 'PAN'), + buttons.EncoderButton(unit, 'AUX2'), + buttons.EncoderButton(unit, 'AUX4'), + None, + None, + buttons.Button(unit, 'Control Panel'), + buttons.Button(unit, 'F1'), + buttons.Button(unit, 'ALL SAFE'), + buttons.Button(unit, 'F5'), + buttons.Button(unit, 'CUT'), + buttons.Button(unit, 'COPY'), + buttons.ModButton(unit, 'ALT'), + buttons.ModButton(unit, 'SHIFT'), + ], + 8: [buttons.Button(unit, 'F2'), + buttons.ClrSoloButton(unit, 'CLR SOLO'), + buttons.LoopButton(unit, 'LOOP'), + buttons.Button(unit, 'DEL'), + buttons.Button(unit, 'PASTE'), + buttons.Button(unit, 'UNDO'), + buttons.ModButton(unit, 'CTRL'), + buttons.Button(unit, 'Foot Switch'), + buttons.Button(unit, 'Gain Enc A'), + buttons.Button(unit, 'Gain Enc B'), + buttons.Button(unit, 'Q Enc A'), + buttons.Button(unit, 'Q Enc B'), + None, + None, + None, + None, + buttons.Button(unit, 'Freq Enc A'), + buttons.Button(unit, 'Freq Enc B'), + None, + None, + None, + None, + None, + None, + None, + buttons.ComputerButton(unit, 'COMPUTER'), + None, + None, + buttons.Button(unit, 'CLOCK'), + buttons.Button(unit, 'ROUTE'), + None, + None, + ], + 9: [buttons.Button(unit, 'F7'), + buttons.Button(unit, 'F8'), + buttons.Button(unit, 'F9'), + buttons.Button(unit, 'F10'), + buttons.Button(unit, 'READ'), + buttons.Button(unit, 'WRT'), + buttons.Button(unit, 'TCH'), + buttons.Button(unit, 'LATCH'), + buttons.Button(unit, 'HIGH'), + buttons.Button(unit, 'HI-MID'), + buttons.Button(unit, 'LOW-MID'), + buttons.Button(unit, 'LOW'), + buttons.ArrowButton(unit, 'UP'), + buttons.ArrowButton(unit, 'LEFT'), + buttons.ArrowButton(unit, 'DOWN'), + buttons.ArrowButton(unit, 'RIGHT'), + buttons.Button(unit, 'REC ENABLE'), + buttons.NudgeButton(unit, 'NUDGE LEFT', -1), + buttons.NudgeButton(unit, 'NUDGE RIGHT', 1), + buttons.BankSwitchButton(unit, 'BANK LEFT', -1), + buttons.BankSwitchButton(unit, 'BANK RIGHT', 1), + buttons.Button(unit, 'LOCATE LEFT'), + buttons.Button(unit, 'LOCATE RIGHT'), + buttons.Button(unit, 'SHTL'), + buttons.Button(unit, 'SET'), + buttons.Button(unit, 'IN'), + buttons.Button(unit, 'OUT'), + buttons.TransportButton(unit, 'REW'), + buttons.TransportButton(unit, 'F.FWD'), + buttons.TransportButton(unit, 'STOP'), + buttons.TransportButton(unit, 'PLAY'), + buttons.TransportButton(unit, 'REC'), + ] + } diff --git a/osc.py b/osc.py new file mode 100644 index 0000000..e0957a7 --- /dev/null +++ b/osc.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +""" + Open Sound Control send/recieve daemon for Tascam Firewire control surface + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + :copyright: Copyright (c) 2012-2014 Scott Bahling + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program (see the file COPYING); if not, write to the + Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + :license: GPL-2.0, see COPYING for details +""" + +from pythonosc import dispatcher +from pythonosc import osc_server +from pythonosc import udp_client + +client = None +server = None +dispatcher = dispatcher.Dispatcher() + + +def init_dispatcher(console): + dispatcher.map("/loop_toggle", console.loop_toggle_handler) + dispatcher.map("/transport_stop", console.transport_stop_handler) + dispatcher.map("/transport_play", console.transport_play_handler) + dispatcher.map("/ffwd", console.ffwd_handler) + dispatcher.map("/rewind", console.rewind_handler) + dispatcher.map("/rec_enable_toggle", console.rec_enable_toggle_handler) + dispatcher.map('/strip/fader', console.strip_fader_handler) + dispatcher.map('/strip/mute', console.strip_mute_handler) + dispatcher.map('/strip/solo', console.strip_solo_handler) + dispatcher.map('/strip/recenable', console.strip_recenable_handler) + dispatcher.map('/master/fader', console.master_fader_handler) + dispatcher.map('/strip/pan_stereo_position', + console.pan_stereo_position_handler) + dispatcher.map('/strip/name', console.strip_name_handler) + dispatcher.map('/bank_up', console.bank_up_handler) + dispatcher.map('/bank_down', console.bank_down_handler) + dispatcher.set_default_handler(console.default_handler) + + +def init_client(ip, port): + global client + client = udp_client.SimpleUDPClient(ip, port) + + +def init_server(ip, port, console): + global server + init_dispatcher(console) + server = osc_server.ThreadingOSCUDPServer((ip, port), dispatcher) diff --git a/strips.py b/strips.py index da656d1..f92a556 100644 --- a/strips.py +++ b/strips.py @@ -21,19 +21,93 @@ """ from faders import Fader +import osc + class Strip(): - def __init__(self, unit, num): + def __init__(self, console, num): + self.console = console self.num = 0 - self.mute = None - self.solo = None - self.select = None - self.recenable = False + self.mute_button = None + self._mute = False + self.solo_button = None + self._solo = False + self.select_button = None + self._select = False + self._rec = False self.pan = 0.5 - self.fader = Fader(unit, self) + self.fader = Fader(self.console.unit, self) self.name = None + @property + def mute_led(self): + return self.console.unit.strips[self.num].mute_led + + @property + def solo_led(self): + return self.console.unit.strips[self.num].solo_led + + @property + def sel_led(self): + return self.console.unit.strips[self.num].sel_led + + @property + def rec_led(self): + return self.console.unit.strips[self.num].rec_led + + @property + def mute(self): + return self._mute + + @mute.setter + def mute(self, state): + state = bool(state) + self._mute = state + if state: + self.mute_led.turn_on() + else: + self.mute_led.turn_off() + + @property + def solo(self): + return self._solo + + @solo.setter + def solo(self, state): + state = bool(state) + self._solo = state + if state: + self.solo_led.turn_on() + else: + self.solo_led.turn_off() + + @property + def select(self): + return self._select + + @select.setter + def select(self, state): + state = bool(state) + self._select = state + if state: + self.sel_led.turn_on() + else: + self.sel_led.turn_off() + + @property + def rec(self): + return self._rec + + @rec.setter + def rec(self, state): + state = bool(state) + self._rec = state + if state: + self.rec_led.turn_on() + else: + self.rec_led.turn_off() + def send_pan(self, delta): addr = '/strip/pan_stereo_position' pan = self.pan + delta * 0.02 @@ -41,7 +115,7 @@ class Strip(): pan = 0 if pan > 1.0: pan = 1.0 - osc.send_message(addr, (self.num, pan)) + osc.client.send_message(addr, (self.num, pan)) def recv_pan(self, pan): print('Pan: {} {}'.format(self.num, pan)) -- cgit v1.2.3