From: g0dil Date: Tue, 12 May 2009 08:00:40 +0000 (+0000) Subject: Audio/AudioControl: Lots of fixes X-Git-Url: http://g0dil.de/git?p=audiocontrol.git;a=commitdiff_plain;h=HEAD Audio/AudioControl: Lots of fixes --- diff --git a/.gitignore b/.gitignore index 9334190..b60b44b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,6 @@ *.pyc winmove +conf +loops +tm +songs diff --git a/Joyboard.py b/Joyboard.py index ef06b87..ab0621e 100644 --- a/Joyboard.py +++ b/Joyboard.py @@ -33,7 +33,7 @@ class JSEvent: TYPE_BUTTON = 0x01 TYPE_AXIS = 0x02 TYPE_INIT = 0x80 - + def __init__(self, data): self.time, self.value, self.type, self.number = struct.unpack(self.STRUCT,data) @@ -106,16 +106,86 @@ class Source(Events.EventSource): return [Events.ControlEvent(self.context(), 'p%d' % number, value)] return [] +# New Controller state machine: +# +# First, we work in two steps: The controller gets an internal +# controller value which is an integer between 0 and 100. All +# operations change this value which is then converted to the output +# value. +# +# The controller position is managed as a signed integer between -2 +# and 2. +# +# The current state is managed in a state variable. There are the +# following states: +# +# INIT In this state, the controller is waiting for the initial +# parameter value. +# +# RUNNING The value is currently being changed. The speed and +# direction are given by the controller position. If the +# current controller position changes to 0 or to the +# opposite sign, the state is switched to WAIT. +# +# WAIT The state machine waits for the controller to enter the +# center position. Only when the controller has been in the +# center position for some time, it will enter the IDLE +# state. It may however go to RUNNING, if the controller +# position is again changed to have the same sign t had +# before entering WAIT. On entering this state, the +# controller position is checked. If the position is 0 now +# or if it is changed to become 0, a timeout is started. If +# the controller is not changed within this timeout, we +# enter IDLE. Any change of the controlle value terminates +# thiw timeout. +# +# SWAIT Wait at a stop. The controller will stay in this state +# until the controller position is changed to 0 or the opposite +# sign. It then enters the WAIT state. +# +# IDLE In this state, nothing happens, however, if the controller +# position changes from 0, the state machine enters the +# running state. +# +# Events are: +# +# ev_controllerChanged The controller position changes +# +# ev_timeout The timeout handle got called +# +# The stop positions are handled by converting them to appropriate +# integer values. When such a value is reached or crossed, the value +# is set to the stop value and the state machine enters the SWAIT +# state. +# +# When converting the integer value to the return float value, we +# first check, wether the integer value is one of the stop values. In +# this case, the associated float value is returned otherweise ahe +# integer is scaled to the correct float range. class Controller(Views.View): + ######################################## + # external API + def __init__(self, context, name, x, y, dx, dy, keylist, dispatcher, controller, source, low, high): Views.View.__init__(self, context, name, x, y, dx, dy) + + # External value interface self._valueEvent = None self._setCommand = None self._valueCommand = None + + # Parameter information self._parameter = None + self._min = None + self._max = None + self._stops = None + self._rawStops = None + self._steps = 40 + + # Controller keymap stuff self._keylist = keylist self._keymap = Bindings.KeyMap() if source: @@ -125,19 +195,14 @@ class Controller(Views.View): self._keylist.prepend(self._keymap) if source: source.registerController(controller, low, high) + + # Working variables self._dispatcher = dispatcher - self._min = None - self._max = None - self._stops = None self._value = None + self._rawValue = None self._controlValue = None - - def updateView(self, bindings): - pass - - def init(self): - Views.View.init(self) - self._redraw() + self._controlSign = None + self._state = None def assign(self, parameter, setCommand, valueCommand, valueEvent, min, max, stops=[]): self._keylist.removeMap(self._keymap) @@ -150,79 +215,202 @@ class Controller(Views.View): self._min = min self._max = max self._stops = stops + self._rawStops = [ self._rawFromCooked(x) for x in self._stops ] if self._valueEvent: self._keymap.add( Bindings.Binding( self._valueEvent, '', Actions.Command('updateValue', self._updateValue)) ) self._keylist.prepend(self._keymap) self._value = None - if self._valueEvent: - self._valueCommand() - else: - self._value = self._valueCommand() + self._rawValue = 0 + self._controlValue = None + self._controlSign = None + self._state = self.S_INIT + self._redraw() + self._getValue() + + def stepValue(self, direction): + Logger.log('ctl','direction = %d' % direction) + self._rawValue += max(-1,min(1,direction)) + if self._rawValue > self._steps: + self._rawValue = self._steps + elif self._rawValue < 0: + self._rawValue = 0 + + Logger.log('ctl','rawValue = %d' % self._rawValue) + self._setValue(self._cookedFromRaw(self._rawValue)) + + return self._rawValue in self._rawStops + + ######################################## + # Base class interface implementation + + def updateView(self, bindings): + pass + + def init(self): + Views.View.init(self) self._redraw() + ######################################## + # External event callbacks + def _updateValue(self, binding): + # Called to return the value after executing the valueCommand + # (when valueCommand initiates an async value get like via + # osc) event = self._dispatcher.currentEvent() - self._value = event.value + self.__updateValue(event.value) + self._updateWindow() + + def __updateValue(self, value): + self._value = value + if self._state == self.S_INIT: + self._rawValue = self._rawFromCooked(self._value) + self._setState(self.S_SWAIT) self._redrawValue() + self._redrawState() + self._updateWindow() def _controllerChanged(self, binding): + # Called, whenever the controller position changes event = self._dispatcher.currentEvent() - Logger.log('ctl',"value = %d" % event.value) - self._controlValue = event.value - if self._controlValue >= 999 or self._controlValue <= 1: - self._dispatcher.setIdleCallback(self._changeValue,75) - elif self._controlValue >= 700 or self._controlValue <= 200: - self._dispatcher.setIdleCallback(self._changeValue,200) + if event.value >= 999: + newControlValue = 2 + elif event.value >= 700: + newControlValue = 1 + elif event.value >= 200: + newControlValue = 0 + elif event.value >= 1: + newControlValue = -1 else: - self._dispatcher.unsetIdleCallback() - self._redrawController() + newControlValue = -2 + Logger.log('ctl',"controlValue = %d" % newControlValue) + if self._controlValue is None or self._controlValue != newControlValue: + self._controlValue = newControlValue + self._ev_controllerChanged() - def _changeValue(self): - if self._value is None: return - if self._controlValue > 500: - self.stepValue(+1) - else: - self.stepValue(-1) + ######################################## + # Internal API - def stepValue(self, direction): - if direction > 0: - newValue = self._value + (self._max - self._min) / (3000/50) - crossed = [ x for x in self._stops if x > self._value*1.0001 and x <= newValue ] - elif direction < 0: - newValue = self._value - (self._max - self._min) / (3000/50) - crossed = [ x for x in self._stops if x < self._value/1.0001 and x >= newValue ] - if newValue >= self._max: - crossed = [ self._max ] - elif newValue <= self._min: - crossed = [ self._min ] - if crossed: - newValue = crossed[0] - self._dispatcher.unsetIdleCallback() - self._setCommand(newValue) - # Hmm ... why does value_command not work sometimes ?? - self._value = newValue - self._redrawValue() + def _setValue(self, value): + self._setCommand(value) + self._getValue() + + def _getValue(self): + if self._valueEvent: + self._valueCommand() else: - self._setCommand(newValue) - if self._valueEvent: - self._valueCommand() + self.__updateValue(self._valueCommand()) + + def _rawFromCooked(self, value): + return min(self._steps,max(0,int(float(self._steps)*(value-self._min)/(self._max-self._min)+.5))) + + def _cookedFromRaw(self, value): + try: + return self._stops[ self._rawStops.index(value) ] + except ValueError: + return (self._min*(self._steps-value) + self._max*value)/self._steps + + ######################################## + # State machine + + S_INIT = 0 + S_RUNNING = 1 + S_WAIT = 2 + S_SWAIT = 3 + S_IDLE = 4 + + def _setState(self, state): + self._state = state + self._redrawState() + + def _ev_controllerChanged(self): + self._redrawController() + + if self._state in (self.S_IDLE, self.S_RUNNING): + if abs(self._controlValue)==1: + self._dispatcher.setIdleCallback(self._ev_timeout,200) + self._setState(self.S_RUNNING) + elif self._controlValue != 0: + self._dispatcher.setIdleCallback(self._ev_timeout,75) + self._setState(self.S_RUNNING) + else: + self._dispatcher.unsetIdleCallback() + if self._state == self.S_RUNNING: + self._setState(self.S_WAIT) + self._ev_controllerChanged() + else: + self._setState(self.S_IDLE) + + elif self._state == self.S_SWAIT: + if self._controlValue == 0 or self._controlSign and self._controlSign*self._controlValue < 0: + self._setState(self.S_WAIT) + self._ev_controllerChanged() + + elif self._state == self.S_WAIT: + if self._controlValue == 0: + self._dispatcher.setIdleCallback(self._ev_timeout,300) + else: + self._dispatcher.unsetIdleCallback() + if self._controlSign and self._controlSign*self._controlValue > 0: + self._setState(self.S_RUNNING) + self._ev_controllerChanged() + + self._updateWindow() + + def _ev_timeout(self): + if self._state == self.S_RUNNING: + self._controlSign = max(-1, min(1, self._controlValue)) + if self._controlSign == 0: + # Cannot happen but ... + self._setState(self.S_IDLE) else: - self._value = self._valueCommand() - self._redrawValue() + if self.stepValue(self._controlSign): + self._setState(self.S_SWAIT) + + elif self._state == self.S_WAIT: + self._setState(self.S_IDLE) + self._dispatcher.unsetIdleCallback() + + self._updateWindow() + + ######################################## + # Drawing + + # +----------+ + # | Name | + # | - | + # | | | + # | |-1.234 | + # |-S| | + # | | | + # | | | + # | - | + # +----------+ + def _redraw(self): height, width = self.win().getmaxyx() if self._parameter is not None: self.win().addstr(1,2,self._parameter[:width-4].ljust(width-4), curses.A_BOLD) - self._redrawValue(False) + self.win().addch(3,3,curses.ACS_TTEE) + self.win().addch(height-3,3,curses.ACS_BTEE) + self.win().addch(height/2,1,'-') + self._redrawValue() + self._redrawController() + self._updateWindow() + + def _redrawState(self): self._redrawController() + def _updateWindow(self): + self.win().refresh() + def _flt(self, value, width): return ('%.3f' % value)[:width].ljust(width) - def _redrawValue(self, refresh=True): + def _redrawValue(self): height, width = self.win().getmaxyx() pos = None if self._value is not None: @@ -247,25 +435,17 @@ class Controller(Views.View): self.win().addstr(height-3, 5, "".ljust(width-7)) if self._min is not None: self.win().addstr(height-2,2,self._flt(self._min,width-7)) - - if refresh: - self.win().refresh() def _redrawController(self, refresh=True): + if self._controlValue is None: return height, width = self.win().getmaxyx() - 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 <= 200: - self.win().addch(height-3,3,curses.ACS_DARROW) - else: - self.win().addch(height-3,3,curses.ACS_BTEE) - - if refresh: - self.win().refresh() - - + pos = height - 3 - int( (self._controlValue + 2) * (height-6) / 4 + .5 ) + for row in range(3,height-2): + if row == pos: + self.win().addch(row,2,('N','R','W','S','I')[self._state]) + else: + self.win().addch(row,2,' ') + class StepController(Actions.Action): def __init__(self, name, controller, direction): @@ -275,7 +455,7 @@ class StepController(Actions.Action): def __call__(self, binding): self._controller.stepValue(self._direction) - + def register( viewmanager, dispatcher, diff --git a/Keyboard.py b/Keyboard.py index 3f1ff24..f3a8b79 100644 --- a/Keyboard.py +++ b/Keyboard.py @@ -13,9 +13,10 @@ class Source(Events.EventSource): class View(Views.View): - def __init__(self, context, label, x, y, dx, dy, size=9): - Views.View.__init__(self, context, label, x, y, dx, dy) + def __init__(self, context, label, x, y, dx, dy, size=9, ignore_keys = ()): + Views.View.__init__(self, context, label, x, y, dx, dy ) self._size = size + self._ignore_keys = ignore_keys def updateView(self, bindings): self.win().clear() @@ -32,6 +33,7 @@ class View(Views.View): keyname = '%sC-%s' % (keyname[:-2],keyname[-1:].lower()) if curses.ascii.isupper(ord(keyname[-1:])): keyname = '%sS-%s' % (keyname[:-1],keyname[-1:].lower()) + if keyname in self._ignore_keys : continue self.win().addstr(row, column, '%-6s %s' % (keyname, bindings[key].label[:self._size])) row += 1 @@ -50,6 +52,7 @@ def register( viewmanager, y, dx, dy, - size=9): - viewmanager.registerView( View(context, label, x,y,dx,dy,size) ) + size = 9, + ignore_keys = ()): + viewmanager.registerView( View(context, label, x,y,dx,dy,size,ignore_keys) ) dispatcher.registerSource( Source(context, viewmanager.win()) ) diff --git a/Logger.py b/Logger.py index 93bc12e..c0c7894 100644 --- a/Logger.py +++ b/Logger.py @@ -26,6 +26,7 @@ class Logger(object): text = '[%s] (%s) %s' % (time.strftime("%H:%M:%S",time.localtime()),src, msg) if self._logfile: self._logfile.write(text+"\n") + self._logfile.flush() lines = self._wrapper.wrap(text) lines = lines[max(0,len(lines)-self._textwin.getmaxyx()[0]):] self._textwin.scroll(len(lines)) diff --git a/Metronome.py b/Metronome.py index b527f4e..297e7e1 100644 --- a/Metronome.py +++ b/Metronome.py @@ -9,7 +9,7 @@ class Metronome(Views.View): 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('ao-add jack_auto,system') self._eci('cop-add -pn:metronome,120') self._eci('cop-add -ea:1') self._eci('engine-launch') diff --git a/config.py b/config.py index 76ea832..9196350 100644 --- a/config.py +++ b/config.py @@ -19,11 +19,9 @@ global_map = Bindings.KeyMap() # # Display size: 88x22 -#Logger.init(main.viewmanager, 38, 0, 37, 10, 'audiocontroller.log') -Logger.init(main.viewmanager, 0, 17, 65, 5) +#Logger.init(main.viewmanager, 0, 17, 88, 5, 'audiocontroller.log') +Logger.init(main.viewmanager, 0, 17, 88, 5) -jb = None -ctl = None jb = Joyboard.register( viewmanager = main.viewmanager, dispatcher = main.dispatcher, @@ -67,9 +65,10 @@ Keyboard.register( label = 'Key Bindings', x = 0, y = 0, - dx = 52, + dx = 25, dy = 10, - size = 7 + size = 11, + ignore_keys = ( '0','1','2','3','4','5','6','7','8','9','0','a','b','c','d','e' ) ) ########################################################################### @@ -137,13 +136,16 @@ looper_main_map.add ( Binding( Event('jb0',4), 'Redo', Action['looper_redo'] looper_main_map.add ( Binding( Event('jb0',5), 'Mute', Action['looper_mute'] ) ) looper_main_map.add ( Binding( Event('jb0',6), 'Trig', Action['looper_trigger'] ) ) looper_main_map.add ( Binding( Event('jb0',7), 'Once', Action['looper_oneshot'] ) ) -looper_main_map.add ( Binding( Event('jb0',8), 'Ins', Action['looper_insert'] ) ) -looper_main_map.add ( Binding( Event('jb0',9), 'Repl', Action['looper_replace'] ) ) +#looper_main_map.add ( Binding( Event('jb0',8), 'Ins', Action['looper_insert'] ) ) +#looper_main_map.add ( Binding( Event('jb0',9), 'Repl', Action['looper_replace'] ) ) +looper_main_map.add( Binding( Event('jb0',8), 'Ctl Up', Action['controller_increment'] ) ) +looper_main_map.add( Binding( Event('jb0',9), 'Ctl Dn', Action['controller_decrement'] ) ) looper_main_map.add ( Binding( Event('jb0',12), 'Undo A', Action['looper_undo_all'] ) ) looper_main_map.add ( Binding( Event('jb0',13), 'Redo A', Action['looper_redo_all'] ) ) looper_main_map.add ( Binding( Event('jb0',14), 'Subst', Action['looper_substitute'] ) ) + 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'] ) ) @@ -171,12 +173,15 @@ Action.register( Looper.AssignController( 'looper_parm_rate', looper, ctl, 'Rate 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',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',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',12), '(Gain)', Action['looper_parm_igain'] ) ) +looper_param_map.add( Binding( Event('jb0',13), '(Rec T)', Action['looper_parm_rec_thresh'] ) ) + looper_param_map.add( Binding( Event('jb0',11), '[Main]', Action['unset_this_map'] ) ) # Initialize looper: enable 'round' and set quantize to 'cycle' @@ -195,11 +200,11 @@ mixer = Mixer.register( oscserver = main.oscserver, context = 'mix', - label = 'Mixer', - x = 65, - y = 17, - dx = 23, - dy = 5, + label = 'Master', + x = 25, + y = 0, + dx = 25, + dy = 4, channels = ( 'Guitar', 'Voice' ), remote = ('127.0.0.1', 9901), @@ -210,27 +215,42 @@ gain = Mixer.register( oscserver = main.oscserver, context = 'gain', - label = 'Gain', - x = 52, - y = 7, - dx = 23, + label = 'Lead Gain', + x = 25, + y = 4, + dx = 25, dy = 3, channels = ( 'Guitar', ), remote = ('127.0.0.1', 9902), ) +monitor = Mixer.register( + viewmanager = main.viewmanager, + oscserver = main.oscserver, + + context = 'mix', + label = 'Monitor', + x = 50, + y = 0, + dx = 25, + dy = 4, + + channels = ( 'Guitar', 'Voice' ), + remote = ('127.0.0.1', 9903), +) + tm = TimeMachine.register( viewmanager = main.viewmanager, context = 'tm', name = 'TimeMachine', - x = 52, - y = 4, - dx = 23, + x = 25, + y = 7, + dx = 25, dy = 3, - ports = ('minimixer:out_left', 'minimixer:out_right'), + ports = ('master:out_left', 'master:out_left'), dir = 'tm', buffer = 1) @@ -240,19 +260,38 @@ metronome = Metronome.register( context = 'mt', label = 'Metronome', - x = 52, - y = 0, - dx = 23, - dy = 4, + x = 50, + y = 7, + dx = 25, + dy = 3, ) -Action.register( Mixer.AssignController ( 'mixer_guitar_level', mixer, ctl, 'Guitar', 1 ) ) -Action.register( Mixer.ToggleMuteChannel ( 'mixer_mute_guitar', mixer, 1 ) ) -Action.register( Mixer.AssignController ( 'mixer_voice_level', mixer, ctl, 'Voice', 2 ) ) -Action.register( Mixer.ToggleMuteChannel ( 'mixer_mute_voice', mixer, 2 ) ) -Action.register( Mixer.AssignController ( 'mixer_master_level', mixer, ctl, 'Master', 0 ) ) -Action.register( Mixer.ToggleMuteAll ( 'mixer_mute_all', mixer ) ) -Action.register( Mixer.CycleVolume ( 'mixer_cycle_gain', gain, 1, ( 0.0, 2.0, 4.0 ) ) ) +# Action.register( Mixer.AssignController ( 'mixer_master_level', mixer, ctl, 'Master', 0 ) ) +Action.register( Mixer.AssignController ( 'master_guitar_level', mixer, ctl, 'Mast Guit', 1 ) ) +Action.register( Mixer.AssignController ( 'master_voice_level', mixer, ctl, 'Mast Voc', 2 ) ) +Action.register( Mixer.ToggleMuteChannel ( 'mixer_mute_guitar', mixer, 1 ) ) +Action.register( Mixer.ToggleMuteChannel ( 'mixer_mute_voice', mixer, 2 ) ) +Action.register( Mixer.ToggleMuteAll ( 'mixer_mute_all', mixer ) ) + +Action.register( Mixer.CycleVolume ( 'mixer_cycle_gain', gain, 1, ( 0.0, 2.5, 5.0 ) ) ) + +Action.register( Mixer.AssignController ( 'monitor_guitar_level', monitor, ctl, 'Mon Guit.', 1 ) ) +Action.register( Mixer.AssignController ( 'monitor_voice_level', monitor, ctl, 'Mon Voc', 2, -6, 12, [ 0, 6 ] ) ) + +master_level_alt_map = Bindings.KeyMap() +Action.register( Actions.ChangeBindingsRelative( 'set_master_level_alt_map', 1, [master_level_alt_map] ) ) +Action.register( Actions.Macro( 'master_set_guitar_level', + [ 'master_guitar_level', 'set_master_level_alt_map' ] ) ) +Action.register( Actions.Macro( 'master_set_voice_level', + [ 'master_voice_level', 'unset_this_map' ] ) ) + +monitor_level_alt_map = Bindings.KeyMap() +Action.register( Actions.ChangeBindingsRelative( 'set_monitor_level_alt_map', 1, [monitor_level_alt_map] ) ) +Action.register( Actions.Macro( 'monitor_set_voice_level', + [ 'monitor_voice_level', 'set_monitor_level_alt_map' ] ) ) +Action.register( Actions.Macro( 'monitor_set_guitar_level', + [ 'monitor_guitar_level', 'unset_this_map' ] ) ) + Action.register( TimeMachine.ToggleRecord( 'tm_rec_toggle', tm ) ) @@ -264,12 +303,18 @@ mixer_map.add( Binding( Event('jb0',4), 'Redo', Action['looper_redo'] ) ) mixer_map.add( Binding( Event('jb0',5), 'Un All', Action['looper_undo_all'] ) ) mixer_map.add( Binding( Event('jb0',6), 'Lead', Action['mixer_cycle_gain'] ) ) -mixer_map.add( Binding( Event('jb0',7), 'Mute G', Action['mixer_mute_guitar'] ) ) -mixer_map.add( Binding( Event('jb0',8), 'Mute V', Action['mixer_mute_voice'] ) ) -mixer_map.add( Binding( Event('jb0',9), 'Mute', Action['mixer_mute_all'] ) ) +#mixer_map.add( Binding( Event('jb0',7), 'Mute G', Action['mixer_mute_guitar'] ) ) +#mixer_map.add( Binding( Event('jb0',8), 'Mute V', Action['mixer_mute_voice'] ) ) +#mixer_map.add( Binding( Event('jb0',9), 'Mute', Action['mixer_mute_all'] ) ) +mixer_map.add( Binding( Event('jb0',7), 'Mute', Action['mixer_mute_all'] ) ) +mixer_map.add( Binding( Event('jb0',8), 'Ctl Up', Action['controller_increment'] ) ) +mixer_map.add( Binding( Event('jb0',9), 'Ctl Dn', Action['controller_decrement'] ) ) -mixer_map.add( Binding( Event('jb0',13), '(Vol G)', Action['mixer_guitar_level'] ) ) -mixer_map.add( Binding( Event('jb0',14), '(Vol V)', Action['mixer_voice_level'] ) ) +mixer_map.add( Binding( Event('jb0',13), '(Mas G)', Action['master_set_guitar_level'] ) ) +master_level_alt_map.add( Binding( Event('jb0',13), '(Mas V)', Action['master_set_voice_level'] ) ) + +mixer_map.add( Binding( Event('jb0',14), '(Mon V)', Action['monitor_set_voice_level'] ) ) +monitor_level_alt_map.add( Binding( Event('jb0',14), '(Mon G)', Action['monitor_set_guitar_level'] ) ) mixer_map.add( Binding( Event('jb0',12), 'TM Rec', Action['tm_rec_toggle'] ) ) @@ -294,7 +339,8 @@ 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 ) +mixer.assignController( ctl, 'Mas Guit', 1 ) +monitor.set(2, 6) ########################################################################### # Jukebox @@ -330,12 +376,15 @@ Action.register( Actions.Macro( 'player_looper_cancel', Action.register( Actions.Macro( 'player_stop_loop', [ 'looper_undo_all', 'player_pause' ] ) ) -for i in range(7): +for i in range(5): 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+3), 'Tr %d' % (i+1), Action['player_set_track_%d' % i] ) ) +player_map.add( Binding( Event('jb0',8), 'Ctl Up', Action['controller_increment'] ) ) +player_map.add( Binding( Event('jb0',9), 'Ctl Dn', Action['controller_decrement'] ) ) + 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'] ) ) @@ -358,13 +407,13 @@ def player_queue_tm_recordings(binding): 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) + os.waitpid(subprocess.Popen(["sndfile-convert","-pcm16",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]: + for wav in wavs[:5]: player.add('tm/' + wav) player.stop() diff --git a/start.sh b/start.sh index 6a15566..6f98972 100755 --- a/start.sh +++ b/start.sh @@ -47,11 +47,15 @@ start() { move $x $y $w $h "$name" } +dcop amarok MainApplication-Interface quit +sleep 1 lsof -n | grep dev | grep -e snd -e dsp | awk '{print $2}' | xargs -r kill +sleep 1 # Make sure nothing is running -killall slgui +pidof -x -o $$ start.sh | xargs -r kill killall sooperlooper +killall slgui killall meterbridge killall qjackctl killall jack-rack @@ -61,16 +65,17 @@ killall jackd killall audiocontroller killall alsaplayer -amixer sset Master 100% on +amixer sset Master 67%,100% on amixer sset PCM 100% on amixer sset Capture 50% on -amixer sset 'Capture Mux' 0,1 +amixer sset 'Capture Mux' 1,0 start 0 25 496 100 "JACK Audio Connection Kit [(default)] Started." \ qjackctl sooperlooper -l 1 -c 2 -t 600 & clients="$clients $!" +sleep 1 cd loops start 582 25 794 210 "SooperLooper" \ @@ -82,40 +87,46 @@ start 0 153 496 428 "JACK Rack (voice) - voice.rack" \ jack-rack -c 1 -s voice voice.rack cd .. -start 88 609 408 98 "AlsaPlayer" \ +start 0 609 496 516 "AlsaPlayer" \ alsaplayer -r -l 0 -d sooperlooper:common_in_1,sooperlooper:common_in_2 clients="$clients $!" -move 0 735 496 390 "Queue" +#move 0 735 496 390 "Queue" alsaplayer --stop 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 + meterbridge -r 0 -t dpm -n meter alsa_pcm:capture_2 jack_rack_voice:out_1 x=`expr $offset + 1382` xterm -fn 6x12 -bg black -fg white -cr white -geometry 88x17+${x}+25 +sb -title Mixer \ -e alsamixer -V all & clients="$clients $!" -jackminimix -c 2 -p 9901 & +jackminimix -c 2 -p 9901 -n master & clients="$clients $!" +sleep 1 jackminimix -c 1 -p 9902 -n inputgain & clients="$clients $!" +sleep 1 +jackminimix -c 2 -p 9903 -n monitor & +clients="$clients $!" sleep 1 -jack_connect alsa_pcm:capture_1 inputgain:in1_left +jack_connect alsa_pcm:capture_2 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_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 -jack_connect minimixer:out_left alsa_pcm:playback_1 -jack_connect minimixer:out_right alsa_pcm:playback_2 +jack_connect sooperlooper:common_out_1 master:in1_left +jack_connect sooperlooper:common_out_2 master:in1_left +jack_connect sooperlooper:common_out_1 monitor:in1_left +jack_connect sooperlooper:common_out_2 monitor:in1_left +jack_connect alsa_pcm:capture_1 jack_rack_voice:in_1 +jack_connect jack_rack_voice:out_1 master:in2_left +jack_connect jack_rack_voice:out_1 monitor:in2_left +jack_connect master:out_left system:playback_2 +jack_connect monitor:out_left system:playback_1 x=`expr $offset + 502` xterm -fn '-dejavu-dejavu sans mono-medium-r-normal--*-260-75-75-m-0-iso10646-1' \