def _get_global_parameter(parameter): """ /get s:param s:return_url s:retpath""" OSCClient.send_message( '/get', type=',sss', args=[parameter, return_url, f'/global/parameter/{parameter}']) SLClient.selection_evt.wait(timeout)
def test_ping(self): OSCServer.start(port=8852) OSCClient.start(port=8852, client_name='test') OSCServer.register_handler('/test', self.handler) OSCClient.send_message('/test', type=',s', args=['hello']) time.sleep(0.5) self.assertEqual(self.ping, 'hello')
def save_loop(file, loop_number=-3, format='wav', endian='big'): """/sl/#/save_loop s:filename s:format s:endian s:return_url s:error_path saves current loop to given filename, may return error to error_path format and endian currently ignored, always uses 32 bit IEEE float WAV""" OSCClient.send_message( f'/sl/{loop_number}/save_loop', args=[file, format, endian, return_url, '/save_loop_error'])
def exit(cls): logging.info(f'Shutting down') if cls.sooperlooper: cls.sooperlooper.kill() PeerClient.exit() OSCClient.exit() for i in BuTTTruck.scheduled_tasks.queue: cls.scheduled_tasks.cancel(i) cls.pool.shutdown(cancel_futures=True, wait=False) logging.info(f'Goddbye!')
def get_parameter(control, loop, return_path=None): """/sl/#/get s:control s:return_url s: return_path Which returns an OSC message to the given return url and path with the arguments: i: loop_index s: control f: value Where control is one of the above or: state::""" return_path = (f'/parameter/{loop}/{control}' if return_path is None else return_path) OSCClient.send_message(f'/sl/{loop}/get', [control, return_url, return_path]) SLClient.parameter_evt.wait(timeout)
def ping(): """"PING Engine /ping s:return_url s:return_path If engine is there, it will respond with to the given URL and PATH with an OSC message with arguments: s:hosturl s:version i:loopcount""" OSCClient.send_message('/ping', [return_url, '/pingrecieved']) SLClient.ping_evt.wait(timeout=timeout) return SLClient.loops
def test_loop_index(self): OSCServer.start(port=9952) t = threading.Thread(target=OSCClient.start(client_name='test'), daemon=True) t.start() SLClient.ping() #time.sleep(0.3) TTTruck._delete_all_loops() self.assertEqual(0, SLClient.loops) self.assertFalse(TTTruck.loop_index) # one loop TTTruck.loop_add() #time.sleep(1) self.assertEqual(0, TTTruck.get_number_of_loops()) self.assertTrue(TTTruck.loop_index) first_loop = TTTruck.loop_index[0] #print(first_loop) # second loop TTTruck.loop_add() second_loop = TTTruck.loop_index[1] #print(second_loop) #time.sleep(1) self.assertEqual(1, TTTruck.get_number_of_loops()) # third loop TTTruck.loop_add() #time.sleep(1) self.assertEqual(2, TTTruck.get_number_of_loops()) third_loop = TTTruck.loop_index[2] TTTruck.select_loop(1) #time.sleep(1) TTTruck.loop_reverse() #time.sleep(1) self.assertEqual(1, TTTruck.changes[second_loop]['reverse']) #time.sleep(1) TTTruck.loop_reverse() #time.sleep(1) self.assertEqual(0, TTTruck.changes[second_loop]['reverse']) TTTruck.delete_loop() #time.sleep(1) #print(OSCServer.selected_loop, 's') # third loop should now be the second of two loops self.assertEqual(1, TTTruck.get_number_of_loops()) self.assertEqual(third_loop, TTTruck.loop_index[1]) # delete second loop again and ensure first loop is all that's left TTTruck.delete_loop() #time.sleep(1) self.assertEqual(0, TTTruck.get_number_of_loops()) self.assertEqual(first_loop, TTTruck.loop_index[0])
def quit(): """/quit shutdown engine""" OSCClient.send_message('/quit')
def loop_del(index=-3): """/loop_del i:loopindex a value of -1 for loopindex removes last loop, and is the only value currently recommended.""" OSCClient.send_message('/loop_del', type=',i', args=[index])
def loop_add(channels=2, length=60): """/loop_add i:#channels f:min_length_seconds adds a new loop with # channels and a minimum loop memory""" OSCClient.send_message('/loop_add', type=',if', args=[channels, length])
def register_global_auto_update(control, return_path, interval=10): """ /register_auto_update s:ctrl i:ms_interval s:returl s:retpath""" OSCClient.send_message('/register_auto_update', [control, interval, return_url, return_path])
def load_loop(loop_number, file): """/sl/#/load_loop s:filename s:return_url s:error_path loads a given filename into loop, may return error to error_path""" OSCClient.send_message(f'/sl/{loop_number}/load_loop', args=[file, return_url, '/load_loop_error'])
def hit(command, loop): """""/sl/#/hit s:cmdname A single hit only, no press-release action""" OSCClient.send_message(f'/sl/{loop}/hit', [command]) SLClient.state_change.wait(timeout=timeout) return SLClient.state
def set_parameter(value, loop): OSCClient.send_message(f'/sl/{loop}/set', value) return SLClient.get_parameter(value[0], loop)
def register_auto_update(control, return_path, loop, interval=10): """/sl/#/register_auto_update s:ctrl i:ms_interval s:returl s:retpath""" OSCClient.send_message(f'/sl/{loop}/register_auto_update', [control, interval, return_url, return_path])
def unregister_auto_update(control, return_path, loop): """/sl/#/unregister_auto_update s:ctrl s:returl s:retpath""" OSCClient.send_message(f'/sl/{loop}/unregister_auto_update', [control, return_url, return_path])
def save_session(file): """/save_session s:filename s:return_url s:error_path saves current session description to filename.""" OSCClient.send_message('/save_session', args=[file, return_url, '/save_session_error'])
def unregister_global_auto_update(control, return_path): """/unregister_auto_update s:ctrl s:returl s:retpath""" OSCClient.send_message('/unregister_auto_update', [control, return_url, return_path])
def load_session(file): """/load_session s:filename s:return_url s:error_path loads and replaces the current session from filename.""" OSCClient.send_message('/load_session', args=[file, return_url, '/load_session_error'])
def _set_global_parameter(parameter, value): """/set s:param f:value""" OSCClient.send_message('/set', type=',sf', args=[parameter, float(value)]) SLClient._get_global_parameter(parameter)
def main(config=None): logging.basicConfig( filename='log_file.log', encoding='utf-8', level=logging.DEBUG, filemode='w+', format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', force=True) sl_host = '127.0.0.1' sl_port = 9951 server_host = '192.168.0.38' server_port = 9999 debug = False peers = None if config is not None: if config.sooperlooper_host is not None: sl_host = config.sooperlooper_host if config.sooperlooper_port is not None: sl_port = config.sooperlooper_port if config.server_host is not None: server_host = config.server_host if config.server_port is not None: server_port = config.server_port if config.peers is not None: peers = config.peers import subprocess BuTTTruck.sooperlooper = subprocess.Popen(['sooperlooper', '-l', '0']) # TODO: scheduled tasks won't reschedule if they take longer than the reschedule period BuTTTruck.scheduled_tasks.enter( 0, 1, periodic, (BuTTTruck.scheduled_tasks, 0.05, process_incoming)) BuTTTruck.scheduled_tasks.enter( 10, 2, periodic, (BuTTTruck.scheduled_tasks, 5, process_loops)) BuTTTruck.scheduled_tasks.enter( 1, 2, periodic, (BuTTTruck.scheduled_tasks, 10, resend_missing_chunks)) if peers is not None: peer_list = peers.strip('\'').split(',') for i in peer_list: logging.info(f'Adding peer: {i}') ip, port = i.split(':') PeerClient.add_peer((ip, int(port)), server=False) else: logging.info(f'Adding server: {server_host}:{server_port}') PeerClient.add_peer((server_host, server_port), server=True) BuTTTruck.pool.submit( OSCClient.start(host=sl_host, port=sl_port, debug=debug)) BuTTTruck.pool.submit(BuTTTruck.scheduled_tasks.run) BuTTTruck.pool.submit(PeerClient.run) BuTTTruck.pool.submit(midi.run) OSCServer.start() import jack with jack.Client('TTTruck') as jack_client: capture = jack_client.get_ports(is_physical=True, is_output=True) output = jack_client.get_ports(is_physical=True, is_input=True) sooperlooper_common_in = jack_client.get_ports( name_pattern='sooperlooper.*common.*in') sooperlooper_common_out = jack_client.get_ports( name_pattern='sooperlooper.*common.*out') for src, dest in zip(sooperlooper_common_out, output): logging.debug(f'Connecting {src} to: {dest}') jack_client.connect(src, dest) for src, dest in zip(capture, sooperlooper_common_in): logging.debug(f'Connecting {src} to: {dest}') jack_client.connect(src, dest)