From: g0dil Date: Fri, 8 Feb 2008 10:14:05 +0000 (+0000) Subject: Audio/AudioControl: Add Metronome X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=e6382990f0d93407969f85b1d9cb9b23884979d3;p=audiocontrol.git Audio/AudioControl: Add Metronome Audio/Audiocontrol: Add alsaplayer 'skip' command Audio/AudioControl: Add binding to queue 'TM' recordings into alsaplayer Audio/AudioControl: Make Joyboard more robust (don't crash if input device does not exist) --- diff --git a/AlsaPlayer.py b/AlsaPlayer.py index 1c6f47a..6a40b21 100644 --- a/AlsaPlayer.py +++ b/AlsaPlayer.py @@ -26,6 +26,9 @@ class Player(object): else: self.speed(0.0) + def skip(self, distance): + self._command('--relative', str(distance)) + def stop(self): self._command('--stop') @@ -69,6 +72,7 @@ class Dispatcher(object): Play = Dispatcher('play') Pause = Dispatcher('pause') +Skip = Dispatcher('skip') Stop = Dispatcher('stop') Toggle = Dispatcher('toggle') Prev = Dispatcher('prev') diff --git a/Joyboard.py b/Joyboard.py index be8af89..ef06b87 100644 --- a/Joyboard.py +++ b/Joyboard.py @@ -118,11 +118,13 @@ class Controller(Views.View): self._parameter = None self._keylist = keylist self._keymap = Bindings.KeyMap() - self._keymap.add( Bindings.Binding(Events.Event(source.context(), 'p%d' % controller), '', - Actions.Command('controllerChanged', - self._controllerChanged)) ) + if source: + self._keymap.add( Bindings.Binding(Events.Event(source.context(), 'p%d' % controller), '', + Actions.Command('controllerChanged', + self._controllerChanged)) ) self._keylist.prepend(self._keymap) - source.registerController(controller, low, high) + if source: + source.registerController(controller, low, high) self._dispatcher = dispatcher self._min = None self._max = None @@ -148,12 +150,16 @@ class Controller(Views.View): self._min = min self._max = max self._stops = stops - self._keymap.add( Bindings.Binding( self._valueEvent, '', - Actions.Command('updateValue', - self._updateValue)) ) + if self._valueEvent: + self._keymap.add( Bindings.Binding( self._valueEvent, '', + Actions.Command('updateValue', + self._updateValue)) ) self._keylist.prepend(self._keymap) self._value = None - self._valueCommand() + if self._valueEvent: + self._valueCommand() + else: + self._value = self._valueCommand() self._redraw() def _updateValue(self, binding): @@ -166,16 +172,18 @@ class Controller(Views.View): Logger.log('ctl',"value = %d" % event.value) self._controlValue = event.value if self._controlValue >= 999 or self._controlValue <= 1: - self._dispatcher.setIdleCallback(self._changeValue,50) + self._dispatcher.setIdleCallback(self._changeValue,75) + elif self._controlValue >= 700 or self._controlValue <= 200: + self._dispatcher.setIdleCallback(self._changeValue,200) else: self._dispatcher.unsetIdleCallback() self._redrawController() def _changeValue(self): if self._value is None: return - if self._controlValue >= 999: + if self._controlValue > 500: self.stepValue(+1) - elif self._controlValue <= 1: + else: self.stepValue(-1) def stepValue(self, direction): @@ -198,7 +206,11 @@ class Controller(Views.View): self._redrawValue() else: self._setCommand(newValue) - self._valueCommand() + if self._valueEvent: + self._valueCommand() + else: + self._value = self._valueCommand() + self._redrawValue() def _redraw(self): height, width = self.win().getmaxyx() @@ -241,11 +253,11 @@ class Controller(Views.View): def _redrawController(self, refresh=True): height, width = self.win().getmaxyx() - if self._controlValue is not None and self._controlValue >= 999: + if self._controlValue is not None and self._controlValue >= 700: self.win().addch(3,3,curses.ACS_UARROW) else: self.win().addch(3,3,curses.ACS_TTEE) - if self._controlValue is not None and self._controlValue <= 1: + if self._controlValue is not None and self._controlValue <= 200: self.win().addch(height-3,3,curses.ACS_DARROW) else: self.win().addch(height-3,3,curses.ACS_BTEE) @@ -279,8 +291,10 @@ def register( viewmanager, bits = None, controllers = []): viewmanager.registerView( View(context, label, numeric_switches, alpha_switches, x, y, dx, size) ) - source = Source(device, context, bits) - dispatcher.registerSource( source ) + source = None + if device is not None: + source = Source(device, context, bits) + dispatcher.registerSource( source ) return source def registerController( viewmanager, dispatcher, keylist, source, context, name, x, y, dx, dy, diff --git a/Metronome.py b/Metronome.py new file mode 100644 index 0000000..b527f4e --- /dev/null +++ b/Metronome.py @@ -0,0 +1,195 @@ +import Actions, OSC, Events, Views, curses +import eci, time + +class Metronome(Views.View): + + def __init__(self, context, label, x, y, dx, dy, dispatcher): + Views.View.__init__(self, context, label, x, y, dx, dy) + self._dispatcher = dispatcher + self._eci = eci.ECI(1) + self._eci('-G:jack,metronome,notransport') + self._eci('ai-add null') + self._eci('ao-add jack_auto,alsa_pcm') + self._eci('cop-add -pn:metronome,120') + self._eci('cop-add -ea:1') + self._eci('engine-launch') + self._bpm = 120 + self._volume = 1 + self._running = False + self._tap = None + + def updateView(self, bindings): + pass + + def init(self): + Views.View.init(self) + self._redraw(0) + + def _redraw(self, refresh=1): + self.win().addstr(1,2,'%3d bpm' % self._bpm) + if self._running: + self.win().addstr(1,10,'Running',curses.A_BOLD) + else: + self.win().addstr(1,10,'Off ') + self.win().addstr(1,18,'%3.1f' % self._volume) + if refresh: + self.win().refresh() + + def toggle(self): + self._running = not self._running + if self._running: + self._eci('start') + else: + self._eci('stop') + self._redraw() + + def tap(self): + t = time.time() + if self._tap and self._tap < t and self._tap > t-2: + self.setBPM(60.0 / (t - self._tap)) + self._tap = t + + def setVolume(self, value): + self._volume = value + self._eci('cop-select 2') + self._eci('copp-select 1') + self._eci('copp-set', self._volume) + self._redraw() + + def setBPM(self, value): + self._bpm = int(value) + self._eci('cop-select 1') + self._eci('copp-select 1') + self._eci('copp-set', self._bpm) + self._redraw() + + def stepBPM(self, dir, min=30, max=360): + step = abs(dir) + bpm = self._bpm/step * step + if self._bpm == bpm: + bpm += dir + elif dir>0: + bpm += 5 + if bpmmax : bpm = max + self.setBPM(bpm) + + class VolumeSetter(object): + + def __init__(self, metronome): + self._metronome = metronome + + def __call__(self, value): + self._metronome.setVolume(value) + + class VolumeGetter(object): + + def __init__(self, metronome): + self._metronome = metronome + + def __call__(self): + return self._metronome._volume + + def assignVolumeController(self, controller, title, min, max, steps=[]): + controller.assign(title, + self.VolumeSetter(self), + self.VolumeGetter(self), + None, + min, max, steps) + + class BPMSetter(object): + + def __init__(self, metronome): + self._metronome = metronome + + def __call__(self, value): + self._metronome.setBPM(value) + + class BPMGetter(object): + + def __init__(self, metronome): + self._metronome = metronome + + def __call__(self): + return self._metronome._bpm + + def assignBPMController(self, controller, title, min, max, steps=[]): + controller.assign(title, + self.BPMSetter(self), + self.BPMGetter(self), + None, + min, max, steps) + + +class Toggle(Actions.Action): + + def __init__(self, name, m): + Actions.Action.__init__(self, name) + self._m = m + + def __call__(self, binding): + self._m.toggle() + +class Tap(Actions.Action): + + def __init__(self, name, m): + Actions.Action.__init__(self, name) + self._m = m + + def __call__(self, binding): + self._m.tap() + +class AssignVolumeController(Actions.Action): + + def __init__(self, name, metronome, controller, title, min, max, steps=[]): + Actions.Action.__init__(self, name) + self._metronome = metronome + self._controller = controller + self._title = title + self._min = min + self._max = max + self._steps = steps + + def __call__(self, binding): + self._metronome.assignVolumeController(self._controller, + self._title, + self._min, + self._max, + self._steps) + +class AssignBPMController(Actions.Action): + + def __init__(self, name, metronome, controller, title, min, max, steps=[]): + Actions.Action.__init__(self, name) + self._metronome = metronome + self._controller = controller + self._title = title + self._min = min + self._max = max + self._steps = steps + + def __call__(self, binding): + self._metronome.assignBPMController(self._controller, + self._title, + self._min, + self._max, + self._steps) + +class StepBPM(Actions.Action): + + def __init__(self, name, m, dir): + Actions.Action.__init__(self, name) + self._m = m + self._dir = dir + + def __call__(self, binding): + self._m.stepBPM(self._dir) + +def register( viewmanager, + dispatcher, + context, + label, + x, y, dx, dy ): + metronome = Metronome(context, label, x, y, dx, dy, dispatcher) + viewmanager.registerView( metronome ) + return metronome diff --git a/config.py b/config.py index 98abe27..76ea832 100644 --- a/config.py +++ b/config.py @@ -4,9 +4,9 @@ from Actions import Actions as Action, action from Views import EventWidget from Events import Event import main -import Joyboard, Keyboard, Process, TimeMachine, AlsaPlayer +import Joyboard, Keyboard, Process, TimeMachine, AlsaPlayer, Metronome import Looper, Mixer -import sys, curses, time, os +import sys, curses, time, os, os.path, subprocess from curses.ascii import alt, ctrl def shift(letter) : return ord(chr(letter).upper()) @@ -20,45 +20,44 @@ global_map = Bindings.KeyMap() # Display size: 88x22 #Logger.init(main.viewmanager, 38, 0, 37, 10, 'audiocontroller.log') -Logger.init(main.viewmanager, 0, 17, 88, 5) +Logger.init(main.viewmanager, 0, 17, 65, 5) jb = None ctl = None -if os.path.exists('/dev/input/js0'): - jb = Joyboard.register( - viewmanager = main.viewmanager, - dispatcher = main.dispatcher, - - context = 'jb0', - label = 'Foot Switch', - numeric_switches = 10, - alpha_switches = 5, - x = 0, - y = 10, - dx = 88, - size = 7, - - device = '/dev/input/js0', - bits = { 1:1, 3:2, 2:4, 0:8 }, - ) - - ctl = Joyboard.registerController( - viewmanager = main.viewmanager, - dispatcher = main.dispatcher, - keylist = main.keylist, - source = jb, - - context = 'c0', - name = 'Control', - x = 75, - y = 0, - dx = 13, - dy = 10, - - controller = 0, - low = -27200, - high = -32700, - ) +jb = Joyboard.register( + viewmanager = main.viewmanager, + dispatcher = main.dispatcher, + + context = 'jb0', + label = 'Foot Switch', + numeric_switches = 10, + alpha_switches = 5, + x = 0, + y = 10, + dx = 88, + size = 7, + + device = os.path.exists('/dev/input/js0') and '/dev/input/js0' or None, + bits = { 1:1, 3:2, 2:4, 0:8 }, +) + +ctl = Joyboard.registerController( + viewmanager = main.viewmanager, + dispatcher = main.dispatcher, + keylist = main.keylist, + source = jb, + + context = 'c0', + name = 'Control', + x = 75, + y = 0, + dx = 13, + dy = 10, + + controller = 0, + low = -27200, + high = -32700, +) Keyboard.register( viewmanager = main.viewmanager, @@ -91,12 +90,11 @@ for i,k in enumerate(('1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b' Action.register( Events.EmitEvent('key_%s' % k, main.dispatcher, Event('jb0', i)) ) global_map.add( Binding( Event('kbd',key(k)), 'Foot %s' % k.upper(), Action['key_%s' % k] ) ) -if ctl is not None: - Action.register( Joyboard.StepController( 'controller_increment', ctl, +1 ) ) - Action.register( Joyboard.StepController( 'controller_decrement', ctl, -1 ) ) +Action.register( Joyboard.StepController( 'controller_increment', ctl, +1 ) ) +Action.register( Joyboard.StepController( 'controller_decrement', ctl, -1 ) ) - global_map.add( Binding( Event('kbd', curses.KEY_UP), 'Increment', Action['controller_increment'] ) ) - global_map.add( Binding( Event('kbd', curses.KEY_DOWN), 'Decrement', Action['controller_decrement'] ) ) +global_map.add( Binding( Event('kbd', curses.KEY_UP), 'Increment', Action['controller_increment'] ) ) +global_map.add( Binding( Event('kbd', curses.KEY_DOWN), 'Decrement', Action['controller_decrement'] ) ) Action.register( Actions.ChangeBindingsRelative( 'unset_this_map', 0, [] ) ) @@ -127,6 +125,9 @@ Action.register( Looper.Command('looper_reverse', looper, 'reverse') ) Action.register( Looper.Command('looper_oneshot', looper, 'oneshot') ) Action.register( Looper.Command('looper_undo_all', looper, 'undo_all') ) Action.register( Looper.Command('looper_redo_all', looper, 'redo_all') ) +Action.register( Looper.Command('looper_mute_off', looper, 'mute_off') ) +Action.register( Actions.Macro( 'looper_trigger_unmute', + [ 'looper_trigger', 'looper_mute_off' ] ) ) looper_main_map.add ( Binding( Event('jb0',0), 'Rec', Action['looper_record'] ) ) looper_main_map.add ( Binding( Event('jb0',1), 'Over', Action['looper_overdub'] ) ) @@ -147,35 +148,34 @@ looper_param_map = Bindings.KeyMap( 'Parameters' ) Action.register( Actions.ChangeBindingsRelative('looper_set_param_map', 1, [looper_param_map] ) ) looper_main_map.add ( Binding( Event('jb0',11), '[Param]', Action['looper_set_param_map'] ) ) -if ctl is not None: - Action.register( Looper.AssignController( 'looper_parm_rec_thresh', looper, ctl, 'Rec.Thresh.', - 'rec_thresh', 0.0, 1.0 ) ) - Action.register( Looper.AssignController( 'looper_parm_feedback', looper, ctl, 'Feedback', - 'feedback', 0.0, 1.0 ) ) - Action.register( Looper.AssignController( 'looper_parm_dry', looper, ctl, 'Dry Level', - 'global_dry', 0.0, 1.0 ) ) - Action.register( Looper.AssignController( 'looper_parm_wet', looper, ctl, 'Wet Level', - 'global_wet', 0.0, 1.0 ) ) - Action.register( Looper.AssignController( 'looper_parm_igain', looper, ctl, 'In. Gain', - 'global_input_gain', 0.0, 1.0 ) ) - - steps = [ 1.0 ] - for i in range(6): - x = pow(2.0,2.0*(i+1)/12.0) - steps.append(x) - steps[0:0] = [1/x] - - Action.register( Looper.AssignController( 'looper_parm_rate', looper, ctl, 'Rate', - 'rate', 0.5, 2.0, steps ) ) - - looper_param_map.add( Binding( Event('jb0',5), '(Feedb)', Action['looper_parm_feedback'] ) ) - looper_param_map.add( Binding( Event('jb0',6), '(Dry)', Action['looper_parm_dry'] ) ) - looper_param_map.add( Binding( Event('jb0',7), '(Wet)', Action['looper_parm_wet'] ) ) - looper_param_map.add( Binding( Event('jb0',8), '(Gain)', Action['looper_parm_igain'] ) ) - looper_param_map.add( Binding( Event('jb0',9), '(Rec T)', Action['looper_parm_rec_thresh'] ) ) - looper_param_map.add( Binding( Event('jb0',12), '', Actions.Nop() ) ) - looper_param_map.add( Binding( Event('jb0',13), 'Rev', Action['looper_reverse'] ) ) - looper_param_map.add( Binding( Event('jb0',14), '(Rate)', Action['looper_parm_rate'] ) ) +Action.register( Looper.AssignController( 'looper_parm_rec_thresh', looper, ctl, 'Rec.Thresh.', + 'rec_thresh', 0.0, 1.0 ) ) +Action.register( Looper.AssignController( 'looper_parm_feedback', looper, ctl, 'Feedback', + 'feedback', 0.0, 1.0 ) ) +Action.register( Looper.AssignController( 'looper_parm_dry', looper, ctl, 'Dry Level', + 'global_dry', 0.0, 1.0 ) ) +Action.register( Looper.AssignController( 'looper_parm_wet', looper, ctl, 'Wet Level', + 'global_wet', 0.0, 1.0 ) ) +Action.register( Looper.AssignController( 'looper_parm_igain', looper, ctl, 'In. Gain', + 'global_input_gain', 0.0, 1.0 ) ) + +steps = [ 1.0 ] +for i in range(6): + x = pow(2.0,2.0*(i+1)/12.0) + steps.append(x) + steps[0:0] = [1/x] + +Action.register( Looper.AssignController( 'looper_parm_rate', looper, ctl, 'Rate', + 'rate', 0.5, 2.0, steps ) ) + +looper_param_map.add( Binding( Event('jb0',5), '(Feedb)', Action['looper_parm_feedback'] ) ) +looper_param_map.add( Binding( Event('jb0',6), '(Dry)', Action['looper_parm_dry'] ) ) +looper_param_map.add( Binding( Event('jb0',7), '(Wet)', Action['looper_parm_wet'] ) ) +looper_param_map.add( Binding( Event('jb0',8), '(Gain)', Action['looper_parm_igain'] ) ) +looper_param_map.add( Binding( Event('jb0',9), '(Rec T)', Action['looper_parm_rec_thresh'] ) ) +looper_param_map.add( Binding( Event('jb0',12), '', Actions.Nop() ) ) +looper_param_map.add( Binding( Event('jb0',13), 'Rev', Action['looper_reverse'] ) ) +looper_param_map.add( Binding( Event('jb0',14), '(Rate)', Action['looper_parm_rate'] ) ) looper_param_map.add( Binding( Event('jb0',11), '[Main]', Action['unset_this_map'] ) ) @@ -187,7 +187,7 @@ looper.set('sync',1) ########################################################################### # Mixer and effects -mixer_map = Bindings.KeyMap('Mixer & Effects') +mixer_map = Bindings.KeyMap('Master') Action.register( Actions.ChangeBindingsRelative( 'mode_mixer', 0, [ mixer_map ] ) ) mixer = Mixer.register( @@ -196,10 +196,10 @@ mixer = Mixer.register( context = 'mix', label = 'Mixer', - x = 52, - y = 0, + x = 65, + y = 17, dx = 23, - dy = 4, + dy = 5, channels = ( 'Guitar', 'Voice' ), remote = ('127.0.0.1', 9901), @@ -232,7 +232,19 @@ tm = TimeMachine.register( ports = ('minimixer:out_left', 'minimixer:out_right'), dir = 'tm', - buffer = 10) + buffer = 1) + +metronome = Metronome.register( + viewmanager = main.viewmanager, + dispatcher = main.dispatcher, + + context = 'mt', + label = 'Metronome', + x = 52, + y = 0, + dx = 23, + dy = 4, +) Action.register( Mixer.AssignController ( 'mixer_guitar_level', mixer, ctl, 'Guitar', 1 ) ) Action.register( Mixer.ToggleMuteChannel ( 'mixer_mute_guitar', mixer, 1 ) ) @@ -261,6 +273,26 @@ mixer_map.add( Binding( Event('jb0',14), '(Vol V)', Action['mixer_voice_level'] mixer_map.add( Binding( Event('jb0',12), 'TM Rec', Action['tm_rec_toggle'] ) ) +metronome_map = Bindings.KeyMap('Metronome') + +Action.register( Actions.ChangeBindingsRelative('set_metronome_map', 1, [metronome_map] ) ) +Action.register( Metronome.Toggle ( 'metronome_toggle', metronome ) ) +Action.register( Metronome.Tap ( 'metronome_tap', metronome ) ) +Action.register( Metronome.StepBPM ('metronome_bpm_inc', metronome, +5 ) ) +Action.register( Metronome.StepBPM ('metronome_bpm_dec', metronome, -5 ) ) +Action.register( Metronome.AssignVolumeController ( 'metronome_volume', metronome, ctl, + "Metr Vol", 0.5, 9.9 ) ) + +metronome_map.add( Binding( Event('jb0', 0), 'Tap', Action['metronome_tap'] ) ) +metronome_map.add( Binding( Event('jb0', 1), 'Toggle', Action['metronome_toggle'] ) ) +metronome_map.add( Binding( Event('jb0', 2), '(Vol)', Action['metronome_volume'] ) ) +metronome_map.add( Binding( Event('jb0', 3), 'bpm Dec', Action['metronome_bpm_dec'] ) ) +metronome_map.add( Binding( Event('jb0', 4), 'bpm Inc', Action['metronome_bpm_inc'] ) ) + +metronome_map.add( Binding( Event('jb0', 11), '[Main]', Action['unset_this_map'] ) ) + +mixer_map.add( Binding( Event('jb0', 11), '[Metr]', Action['set_metronome_map'] ) ) + mixer.mute(2) mixer.assignController( ctl, 'Guitar', 1 ) @@ -275,34 +307,74 @@ player = AlsaPlayer.Player() Action.register( AlsaPlayer.Play ( 'player_start', player ) ) Action.register( AlsaPlayer.Pause ( 'player_pause', player ) ) Action.register( AlsaPlayer.Stop ( 'player_stop', player ) ) -Action.register( AlsaPlayer.Prev ( 'player_prev', player ) ) -Action.register( AlsaPlayer.Next ( 'player_next', player ) ) +Action.register( AlsaPlayer.Skip ( 'player_skip_fwd', player, 5 ) ) +Action.register( AlsaPlayer.Skip ( 'player_skip_rev', player, -5 ) ) player_stop_map = Bindings.KeyMap() Action.register( Actions.ChangeBindingsRelative('player_set_stop_map', 1, [player_stop_map] ) ) - -Action.register( Actions.Macro( 'player_set_playing', [ 'player_start', 'player_set_stop_map' ] ) ) -Action.register( Actions.Macro( 'player_set_stop', [ 'player_stop', 'unset_this_map' ] ) ) - -for i in range(10): +Action.register( Actions.Macro( 'player_set_playing', + [ 'player_start', 'player_set_stop_map' ] ) ) +Action.register( Actions.Macro( 'player_set_stop', + [ 'player_stop', 'unset_this_map' ]) ) + +player_looper_map = Bindings.KeyMap() + +Action.register( Actions.ChangeBindingsRelative('player_set_looper_map', 1, [player_looper_map] ) ) +Action.register( Actions.Macro( 'player_start_loop_rec', + [ 'looper_record', 'player_set_looper_map' ] ) ) +Action.register( Actions.Macro( 'player_stop_loop_rec', + [ 'looper_record', 'player_pause', 'unset_this_map' ] ) ) +Action.register( Actions.Macro( 'player_looper_cancel', + [ 'looper_undo', 'unset_this_map' ] ) ) +Action.register( Actions.Macro( 'player_stop_loop', + [ 'looper_undo_all', 'player_pause' ] ) ) + +for i in range(7): Action.register( AlsaPlayer.Jump ( 'player_jump_%d' % i, player, i+1 ) ) Action.register( Actions.Macro( 'player_set_track_%d' % i, [ 'player_jump_%d' % i, 'player_set_stop_map' ] ) ) - player_map.add( Binding( Event('jb0',i), 'Tr %d' % (i+1), Action['player_set_track_%d' % i] ) ) + player_map.add( Binding( Event('jb0',i+3), 'Tr %d' % (i+1), Action['player_set_track_%d' % i] ) ) -player_map.add( Binding( Event('jb0', 11), 'Prev', Action['player_prev'] ) ) -player_map.add( Binding( Event('jb0', 12), 'Next', Action['player_next'] ) ) -player_map.add( Binding( Event('jb0', 13), 'Play', Action['player_set_playing'] ) ) -player_map.add( Binding( Event('jb0', 14), 'Pause', Action['player_pause'] ) ) +player_map.add( Binding( Event('jb0', 0), 'L Rec', Action['player_start_loop_rec'] ) ) +player_map.add( Binding( Event('jb0', 1), 'L Stp', Action['player_stop_loop'] ) ) +player_map.add( Binding( Event('jb0', 11), 'Back', Action['player_skip_rev'] ) ) +player_map.add( Binding( Event('jb0', 12), 'Fwd', Action['player_skip_fwd'] ) ) +player_map.add( Binding( Event('jb0', 13), 'Play', Action['player_set_playing'] ) ) +player_map.add( Binding( Event('jb0', 14), 'Pause', Action['player_pause'] ) ) player_stop_map.add( Binding( Event('jb0', 13), 'Stop', Action['player_set_stop'] ) ) +player_looper_map.add( Binding( Event('jb0', 0), 'L Rec', Action['player_stop_loop_rec'] ) ) +player_looper_map.add( Binding( Event('jb0', 1), 'L Can', Action['player_looper_cancel'] ) ) + +@action +def player_queue_tm_recordings(binding): + global player + player.clear() + player.stop() + wavs = [] + for f in os.listdir('tm'): + wav = os.path.splitext(f)[0] + '.wav' + if f.endswith('.w64'): + if not os.path.exists('tm/' + wav): + os.waitpid(subprocess.Popen(["sndfile-convert","-pcm32",f,wav],cwd='tm').pid,0) + wavs.append(wav) + elif f.endswith('.wav'): + wavs.append(f) + wavs.sort() + wavs.reverse() + for wav in wavs[:7]: + player.add('tm/' + wav) + player.stop() + +player_map.add( Binding( Event('jb0', 2), 'Add TM', Action['player_queue_tm_recordings'] ) ) + ########################################################################### -mixer_map.add ( Binding( Event('jb0',10), '[Loop]', Action['mode_looper'] ) ) -looper_main_map.add ( Binding( Event('jb0',10), '[JBox]', Action['mode_player'] ) ) -player_map.add ( Binding( Event('jb0',10), '[Mixer]', Action['mode_mixer'] ) ) +mixer_map.add ( Binding( Event('jb0',10), '[Loop]', Action['mode_looper'] ) ) +looper_main_map.add ( Binding( Event('jb0',10), '[JBox]', Action['mode_player'] ) ) +player_map.add ( Binding( Event('jb0',10), '[Mastr]', Action['mode_mixer'] ) ) main.keylist.append(global_map) main.keylist.append(mixer_map) diff --git a/start.sh b/start.sh index f90e336..6a15566 100755 --- a/start.sh +++ b/start.sh @@ -69,7 +69,7 @@ amixer sset 'Capture Mux' 0,1 start 0 25 496 100 "JACK Audio Connection Kit [(default)] Started." \ qjackctl -sooperlooper -l 1 -c 1 -t 300 & +sooperlooper -l 1 -c 2 -t 600 & clients="$clients $!" cd loops @@ -83,11 +83,12 @@ start 0 153 496 428 "JACK Rack (voice) - voice.rack" \ cd .. start 88 609 408 98 "AlsaPlayer" \ - alsaplayer -r -l 0 + alsaplayer -r -l 0 -d sooperlooper:common_in_1,sooperlooper:common_in_2 clients="$clients $!" move 0 735 496 390 "Queue" alsaplayer --stop -alsaplayer --volume 1 +alsaplayer --volume .25 + start 502 25 74 210 "dpm meter" \ meterbridge -r 0 -t dpm -n meter alsa_pcm:capture_1 jack_rack_voice:out_1 @@ -107,8 +108,9 @@ sleep 1 jack_connect alsa_pcm:capture_1 inputgain:in1_left jack_connect inputgain:out_left sooperlooper:common_in_1 +jack_connect inputgain:out_left sooperlooper:common_in_2 jack_connect sooperlooper:common_out_1 minimixer:in1_left -jack_connect sooperlooper:common_out_1 minimixer:in1_right +jack_connect sooperlooper:common_out_2 minimixer:in1_right jack_connect alsa_pcm:capture_2 jack_rack_voice:in_1 jack_connect jack_rack_voice:out_1 minimixer:in2_left jack_connect jack_rack_voice:out_1 minimixer:in2_right