Audio/AudioControl: Lots of fixes
[audiocontrol.git] / config.py
1 import Bindings, Actions, Views, Events, Logger
2 from Bindings import Binding
3 from Actions import Actions as Action, action
4 from Views import EventWidget
5 from Events import Event
6 import main
7 import Joyboard, Keyboard, Process, TimeMachine, AlsaPlayer, Metronome
8 import Looper, Mixer
9 import sys, curses, time, os, os.path, subprocess
10 from curses.ascii import alt, ctrl
11
12 def shift(letter) : return ord(chr(letter).upper())
13 def key(letter) : return ord(letter.lower())
14
15 global_map = Bindings.KeyMap()
16
17 ###########################################################################
18 # Setup views and controllers
19 #
20 # Display size: 88x22
21
22 #Logger.init(main.viewmanager, 0, 17, 88, 5, 'audiocontroller.log')
23 Logger.init(main.viewmanager, 0, 17, 88, 5)
24
25 jb = Joyboard.register(
26     viewmanager = main.viewmanager,
27     dispatcher = main.dispatcher,
28     
29     context          = 'jb0',
30     label            = 'Foot Switch',
31     numeric_switches =  10,
32     alpha_switches   =   5,
33     x                =   0,
34     y                =  10,
35     dx               =  88,
36     size             =   7,
37     
38     device           = os.path.exists('/dev/input/js0') and '/dev/input/js0' or None,
39     bits             = { 1:1, 3:2, 2:4, 0:8 },
40 )
41
42 ctl = Joyboard.registerController(
43     viewmanager = main.viewmanager,
44     dispatcher = main.dispatcher,
45     keylist = main.keylist,
46     source = jb,
47     
48     context          = 'c0',
49     name             = 'Control',
50     x                = 75,
51     y                =  0,
52     dx               = 13,
53     dy               = 10,
54
55     controller       = 0,
56     low              = -27200,
57     high             = -32700,
58 )        
59
60 Keyboard.register(
61     viewmanager = main.viewmanager,
62     dispatcher = main.dispatcher,
63
64     context          = 'kbd',
65     label            = 'Key Bindings',
66     x                =  0,
67     y                =  0,
68     dx               = 25,
69     dy               = 10,
70     size             = 11,
71     ignore_keys      = ( '0','1','2','3','4','5','6','7','8','9','0','a','b','c','d','e' )
72 )
73
74 ###########################################################################
75 # Global keymap and auxilary actions
76
77 @action
78 def quit(binding):
79     sys.exit(1)
80
81 @action
82 def restart(binding):
83     sys.exit(0)
84
85 global_map.add( Binding( Event('kbd',key('q')), 'Quit', Action['quit'] ) )
86 global_map.add( Binding( Event('kbd',ctrl(key('r'))), 'Restart', Action['restart'] ) )
87
88 for i,k in enumerate(('1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e' )):
89     Action.register( Events.EmitEvent('key_%s' % k, main.dispatcher, Event('jb0', i)) )
90     global_map.add( Binding( Event('kbd',key(k)), 'Foot %s' % k.upper(), Action['key_%s' % k] ) )
91     
92 Action.register( Joyboard.StepController( 'controller_increment', ctl, +1 ) )
93 Action.register( Joyboard.StepController( 'controller_decrement', ctl, -1 ) )
94
95 global_map.add( Binding( Event('kbd', curses.KEY_UP), 'Increment', Action['controller_increment'] ) )
96 global_map.add( Binding( Event('kbd', curses.KEY_DOWN), 'Decrement', Action['controller_decrement'] ) )
97
98 Action.register( Actions.ChangeBindingsRelative( 'unset_this_map', 0, [] ) )
99
100 ###########################################################################
101 # Looper
102
103 looper_main_map = Bindings.KeyMap( 'Looper' )
104 Action.register( Actions.ChangeBindingsRelative( 'mode_looper', 0, [ looper_main_map ] ) )
105
106 looper = Looper.register(
107     oscserver = main.oscserver,
108
109     context = 'sl',
110     remote  = ('127.0.0.1',9951),
111 )
112
113 Action.register( Looper.Command('looper_record', looper, 'record') )
114 Action.register( Looper.Command('looper_overdub', looper, 'overdub') )
115 Action.register( Looper.Command('looper_multiply', looper, 'multiply') )
116 Action.register( Looper.Command('looper_mute', looper, 'mute') )
117 Action.register( Looper.Command('looper_undo', looper, 'undo') )
118 Action.register( Looper.Command('looper_redo', looper, 'redo') )
119 Action.register( Looper.Command('looper_trigger', looper, 'trigger') )
120 Action.register( Looper.Command('looper_insert', looper, 'insert') )
121 Action.register( Looper.Command('looper_replace', looper, 'replace') )
122 Action.register( Looper.Command('looper_substitute', looper, 'substitute') )
123 Action.register( Looper.Command('looper_reverse', looper, 'reverse') )
124 Action.register( Looper.Command('looper_oneshot', looper, 'oneshot') )
125 Action.register( Looper.Command('looper_undo_all', looper, 'undo_all') )
126 Action.register( Looper.Command('looper_redo_all', looper, 'redo_all') )
127 Action.register( Looper.Command('looper_mute_off', looper, 'mute_off') )
128 Action.register( Actions.Macro( 'looper_trigger_unmute',
129                                 [ 'looper_trigger', 'looper_mute_off' ] ) )
130
131 looper_main_map.add ( Binding( Event('jb0',0),  'Rec',    Action['looper_record'] ) )
132 looper_main_map.add ( Binding( Event('jb0',1),  'Over',   Action['looper_overdub'] ) )
133 looper_main_map.add ( Binding( Event('jb0',2),  'Mult',   Action['looper_multiply'] ) )
134 looper_main_map.add ( Binding( Event('jb0',3),  'Undo',   Action['looper_undo'] ) )
135 looper_main_map.add ( Binding( Event('jb0',4),  'Redo',   Action['looper_redo'] ) )
136 looper_main_map.add ( Binding( Event('jb0',5),  'Mute',   Action['looper_mute'] ) )
137 looper_main_map.add ( Binding( Event('jb0',6),  'Trig',   Action['looper_trigger'] ) )
138 looper_main_map.add ( Binding( Event('jb0',7),  'Once',   Action['looper_oneshot'] ) )
139 #looper_main_map.add ( Binding( Event('jb0',8),  'Ins',    Action['looper_insert'] ) )
140 #looper_main_map.add ( Binding( Event('jb0',9),  'Repl',   Action['looper_replace'] ) )
141 looper_main_map.add( Binding( Event('jb0',8), 'Ctl Up', Action['controller_increment'] ) )
142 looper_main_map.add( Binding( Event('jb0',9), 'Ctl Dn', Action['controller_decrement'] ) )
143 looper_main_map.add ( Binding( Event('jb0',12), 'Undo A', Action['looper_undo_all'] ) )
144 looper_main_map.add ( Binding( Event('jb0',13), 'Redo A', Action['looper_redo_all'] ) )
145 looper_main_map.add ( Binding( Event('jb0',14), 'Subst',  Action['looper_substitute'] ) )
146
147
148
149 looper_param_map = Bindings.KeyMap( 'Parameters' )
150 Action.register( Actions.ChangeBindingsRelative('looper_set_param_map', 1, [looper_param_map] ) )
151 looper_main_map.add ( Binding( Event('jb0',11), '[Param]', Action['looper_set_param_map'] ) )
152
153 Action.register( Looper.AssignController( 'looper_parm_rec_thresh', looper, ctl, 'Rec.Thresh.',
154                                           'rec_thresh', 0.0, 1.0 ) )
155 Action.register( Looper.AssignController( 'looper_parm_feedback', looper, ctl, 'Feedback',
156                                           'feedback', 0.0, 1.0 ) )
157 Action.register( Looper.AssignController( 'looper_parm_dry', looper, ctl, 'Dry Level',
158                                           'global_dry', 0.0, 1.0 ) )
159 Action.register( Looper.AssignController( 'looper_parm_wet', looper, ctl, 'Wet Level',
160                                           'global_wet', 0.0, 1.0 ) )
161 Action.register( Looper.AssignController( 'looper_parm_igain', looper, ctl, 'In. Gain',
162                                           'global_input_gain', 0.0, 1.0 ) )
163
164 steps = [ 1.0 ]
165 for i in range(6):
166     x = pow(2.0,2.0*(i+1)/12.0)
167     steps.append(x)
168     steps[0:0] = [1/x]
169
170 Action.register( Looper.AssignController( 'looper_parm_rate', looper, ctl, 'Rate',
171                                           'rate', 0.5, 2.0, steps ) )
172
173 looper_param_map.add( Binding( Event('jb0',5),  '(Feedb)', Action['looper_parm_feedback'] ) )
174 looper_param_map.add( Binding( Event('jb0',6),  '(Dry)',   Action['looper_parm_dry'] ) )
175 looper_param_map.add( Binding( Event('jb0',7),  '(Wet)',   Action['looper_parm_wet'] ) )
176 #looper_param_map.add( Binding( Event('jb0',8),  '(Gain)',  Action['looper_parm_igain'] ) )
177 #looper_param_map.add( Binding( Event('jb0',9),  '(Rec T)', Action['looper_parm_rec_thresh'] ) )
178 looper_param_map.add( Binding( Event('jb0',12), '',        Actions.Nop() ) )
179 #looper_param_map.add( Binding( Event('jb0',13), 'Rev',     Action['looper_reverse'] ) )
180 looper_param_map.add( Binding( Event('jb0',14), '(Rate)',  Action['looper_parm_rate'] ) )
181
182 looper_param_map.add( Binding( Event('jb0',12),  '(Gain)',  Action['looper_parm_igain'] ) )
183 looper_param_map.add( Binding( Event('jb0',13),  '(Rec T)', Action['looper_parm_rec_thresh'] ) )
184
185 looper_param_map.add( Binding( Event('jb0',11), '[Main]',    Action['unset_this_map'] ) )
186
187 # Initialize looper: enable 'round' and set quantize to 'cycle'
188 looper.set('quantize',1)
189 looper.set('round',1)
190 looper.set('sync',1)
191
192 ###########################################################################
193 # Mixer and effects
194
195 mixer_map = Bindings.KeyMap('Master')
196 Action.register( Actions.ChangeBindingsRelative( 'mode_mixer', 0, [ mixer_map ] ) )
197
198 mixer = Mixer.register(
199     viewmanager = main.viewmanager,
200     oscserver = main.oscserver,
201
202     context  = 'mix',
203     label    = 'Master',
204     x        = 25,
205     y        = 0,
206     dx       = 25,
207     dy       = 4,
208
209     channels = ( 'Guitar', 'Voice' ),
210     remote  = ('127.0.0.1', 9901),
211 )
212
213 gain = Mixer.register(
214     viewmanager = main.viewmanager,
215     oscserver = main.oscserver,
216
217     context  = 'gain',
218     label    = 'Lead Gain',
219     x        = 25,
220     y        =  4,
221     dx       = 25,
222     dy       = 3,
223
224     channels = ( 'Guitar', ),
225     remote  = ('127.0.0.1', 9902),
226 )
227
228 monitor = Mixer.register(
229     viewmanager = main.viewmanager,
230     oscserver = main.oscserver,
231
232     context  = 'mix',
233     label    = 'Monitor',
234     x        = 50,
235     y        = 0,
236     dx       = 25,
237     dy       = 4,
238
239     channels = ( 'Guitar', 'Voice' ),
240     remote  = ('127.0.0.1', 9903),
241 )
242
243 tm = TimeMachine.register(
244     viewmanager = main.viewmanager,
245
246     context = 'tm',
247     name    = 'TimeMachine',
248     x       = 25,
249     y       =  7,
250     dx      = 25,
251     dy      =  3,
252
253     ports   = ('master:out_left', 'master:out_left'),
254     dir     = 'tm',
255     buffer  =  1)
256
257 metronome = Metronome.register(
258     viewmanager = main.viewmanager,
259     dispatcher  = main.dispatcher,
260
261     context = 'mt',
262     label   = 'Metronome',
263     x       = 50,
264     y       = 7,
265     dx      = 25,
266     dy      = 3,
267 )
268
269 # Action.register( Mixer.AssignController  ( 'mixer_master_level', mixer, ctl, 'Master', 0 ) )
270 Action.register( Mixer.AssignController  ( 'master_guitar_level', mixer, ctl, 'Mast Guit', 1 ) )
271 Action.register( Mixer.AssignController  ( 'master_voice_level',  mixer, ctl, 'Mast Voc', 2 ) )
272 Action.register( Mixer.ToggleMuteChannel ( 'mixer_mute_guitar',   mixer, 1 ) )
273 Action.register( Mixer.ToggleMuteChannel ( 'mixer_mute_voice',    mixer, 2 ) )
274 Action.register( Mixer.ToggleMuteAll     ( 'mixer_mute_all',      mixer ) )
275
276 Action.register( Mixer.CycleVolume       ( 'mixer_cycle_gain',   gain, 1, ( 0.0, 2.5, 5.0 ) ) )
277
278 Action.register( Mixer.AssignController  ( 'monitor_guitar_level', monitor, ctl, 'Mon Guit.', 1 ) )
279 Action.register( Mixer.AssignController  ( 'monitor_voice_level',  monitor, ctl, 'Mon Voc', 2, -6, 12, [ 0, 6 ] ) )
280
281 master_level_alt_map = Bindings.KeyMap()
282 Action.register( Actions.ChangeBindingsRelative( 'set_master_level_alt_map', 1, [master_level_alt_map] ) )
283 Action.register( Actions.Macro( 'master_set_guitar_level',
284                                 [ 'master_guitar_level', 'set_master_level_alt_map' ] ) )
285 Action.register( Actions.Macro( 'master_set_voice_level',
286                                 [ 'master_voice_level', 'unset_this_map' ] ) )
287
288 monitor_level_alt_map = Bindings.KeyMap()
289 Action.register( Actions.ChangeBindingsRelative( 'set_monitor_level_alt_map', 1, [monitor_level_alt_map] ) )
290 Action.register( Actions.Macro( 'monitor_set_voice_level',
291                                 [ 'monitor_voice_level', 'set_monitor_level_alt_map' ] ) )
292 Action.register( Actions.Macro( 'monitor_set_guitar_level',
293                                 [ 'monitor_guitar_level', 'unset_this_map' ] ) )
294
295
296 Action.register( TimeMachine.ToggleRecord( 'tm_rec_toggle', tm ) )
297
298 mixer_map.add( Binding( Event('jb0',0),  'Rec',     Action['looper_record'] ) )
299 mixer_map.add( Binding( Event('jb0',1),  'Over',    Action['looper_overdub'] ) )
300 mixer_map.add( Binding( Event('jb0',2),  'Mult',    Action['looper_multiply'] ) )
301 mixer_map.add( Binding( Event('jb0',3),  'Undo',    Action['looper_undo'] ) )
302 mixer_map.add( Binding( Event('jb0',4),  'Redo',    Action['looper_redo'] ) )
303 mixer_map.add( Binding( Event('jb0',5),  'Un All',  Action['looper_undo_all'] ) )
304
305 mixer_map.add( Binding( Event('jb0',6), 'Lead',     Action['mixer_cycle_gain'] ) )
306 #mixer_map.add( Binding( Event('jb0',7), 'Mute G',   Action['mixer_mute_guitar'] ) )
307 #mixer_map.add( Binding( Event('jb0',8), 'Mute V',   Action['mixer_mute_voice'] ) )
308 #mixer_map.add( Binding( Event('jb0',9), 'Mute',     Action['mixer_mute_all'] ) )
309 mixer_map.add( Binding( Event('jb0',7), 'Mute',     Action['mixer_mute_all'] ) )
310 mixer_map.add( Binding( Event('jb0',8), 'Ctl Up', Action['controller_increment'] ) )
311 mixer_map.add( Binding( Event('jb0',9), 'Ctl Dn', Action['controller_decrement'] ) )
312
313 mixer_map.add( Binding( Event('jb0',13), '(Mas G)', Action['master_set_guitar_level'] ) )
314 master_level_alt_map.add( Binding( Event('jb0',13), '(Mas V)', Action['master_set_voice_level'] ) )
315
316 mixer_map.add( Binding( Event('jb0',14), '(Mon V)', Action['monitor_set_voice_level'] ) )
317 monitor_level_alt_map.add( Binding( Event('jb0',14), '(Mon G)', Action['monitor_set_guitar_level'] ) )
318
319 mixer_map.add( Binding( Event('jb0',12), 'TM Rec',  Action['tm_rec_toggle'] ) )
320
321 metronome_map = Bindings.KeyMap('Metronome')
322
323 Action.register( Actions.ChangeBindingsRelative('set_metronome_map', 1, [metronome_map] ) )
324 Action.register( Metronome.Toggle ( 'metronome_toggle', metronome ) )
325 Action.register( Metronome.Tap ( 'metronome_tap', metronome ) )
326 Action.register( Metronome.StepBPM ('metronome_bpm_inc', metronome, +5 ) )
327 Action.register( Metronome.StepBPM ('metronome_bpm_dec', metronome, -5 ) )
328 Action.register( Metronome.AssignVolumeController ( 'metronome_volume', metronome, ctl,
329                                                     "Metr Vol", 0.5, 9.9 ) )
330
331 metronome_map.add( Binding( Event('jb0', 0), 'Tap', Action['metronome_tap'] ) )
332 metronome_map.add( Binding( Event('jb0', 1), 'Toggle', Action['metronome_toggle'] ) )
333 metronome_map.add( Binding( Event('jb0', 2), '(Vol)', Action['metronome_volume'] ) )
334 metronome_map.add( Binding( Event('jb0', 3), 'bpm Dec', Action['metronome_bpm_dec'] ) )
335 metronome_map.add( Binding( Event('jb0', 4), 'bpm Inc', Action['metronome_bpm_inc'] ) )
336
337 metronome_map.add( Binding( Event('jb0', 11), '[Main]', Action['unset_this_map'] ) )
338
339 mixer_map.add( Binding( Event('jb0', 11), '[Metr]', Action['set_metronome_map'] ) )
340
341 mixer.mute(2)
342 mixer.assignController( ctl, 'Mas Guit', 1 )
343 monitor.set(2, 6)
344     
345 ###########################################################################
346 # Jukebox
347
348 player_map = Bindings.KeyMap('JukeBox')
349 Action.register( Actions.ChangeBindingsRelative( 'mode_player', 0, [ player_map ] ) )
350
351 player = AlsaPlayer.Player()
352
353 Action.register( AlsaPlayer.Play  ( 'player_start',  player ) )
354 Action.register( AlsaPlayer.Pause ( 'player_pause',  player ) )
355 Action.register( AlsaPlayer.Stop  ( 'player_stop',   player ) )
356 Action.register( AlsaPlayer.Skip  ( 'player_skip_fwd', player, 5 ) )
357 Action.register( AlsaPlayer.Skip  ( 'player_skip_rev', player, -5 ) )
358
359 player_stop_map = Bindings.KeyMap()
360
361 Action.register( Actions.ChangeBindingsRelative('player_set_stop_map', 1, [player_stop_map] ) )
362 Action.register( Actions.Macro( 'player_set_playing',
363                                 [ 'player_start', 'player_set_stop_map' ] ) )
364 Action.register( Actions.Macro( 'player_set_stop',
365                                 [ 'player_stop', 'unset_this_map' ]) )
366
367 player_looper_map = Bindings.KeyMap()
368
369 Action.register( Actions.ChangeBindingsRelative('player_set_looper_map', 1, [player_looper_map] ) )
370 Action.register( Actions.Macro( 'player_start_loop_rec',
371                                 [ 'looper_record', 'player_set_looper_map' ] ) )
372 Action.register( Actions.Macro( 'player_stop_loop_rec',
373                                 [ 'looper_record', 'player_pause', 'unset_this_map' ] ) )
374 Action.register( Actions.Macro( 'player_looper_cancel',
375                                 [ 'looper_undo', 'unset_this_map' ] ) )
376 Action.register( Actions.Macro( 'player_stop_loop',
377                                 [ 'looper_undo_all', 'player_pause' ] ) )
378
379 for i in range(5):
380     Action.register( AlsaPlayer.Jump  ( 'player_jump_%d' % i, player, i+1 ) )
381     Action.register( Actions.Macro( 'player_set_track_%d' % i,
382                                     [ 'player_jump_%d' % i, 'player_set_stop_map' ] ) )
383     player_map.add( Binding( Event('jb0',i+3), 'Tr %d' % (i+1), Action['player_set_track_%d' % i] ) )
384
385 player_map.add( Binding( Event('jb0',8), 'Ctl Up', Action['controller_increment'] ) )
386 player_map.add( Binding( Event('jb0',9), 'Ctl Dn', Action['controller_decrement'] ) )
387
388 player_map.add( Binding( Event('jb0',  0), 'L Rec', Action['player_start_loop_rec'] ) )
389 player_map.add( Binding( Event('jb0',  1), 'L Stp', Action['player_stop_loop'] ) )
390 player_map.add( Binding( Event('jb0', 11), 'Back', Action['player_skip_rev'] ) )
391 player_map.add( Binding( Event('jb0', 12), 'Fwd', Action['player_skip_fwd'] ) )
392 player_map.add( Binding( Event('jb0', 13), 'Play', Action['player_set_playing'] ) )
393 player_map.add( Binding( Event('jb0', 14), 'Pause', Action['player_pause'] ) )
394
395 player_stop_map.add( Binding( Event('jb0', 13), 'Stop', Action['player_set_stop'] ) )
396
397 player_looper_map.add( Binding( Event('jb0',  0), 'L Rec', Action['player_stop_loop_rec'] ) )
398 player_looper_map.add( Binding( Event('jb0',  1), 'L Can', Action['player_looper_cancel'] ) )
399
400 @action
401 def player_queue_tm_recordings(binding):
402     global player
403     player.clear()
404     player.stop()
405     wavs = []
406     for f in os.listdir('tm'):
407         wav = os.path.splitext(f)[0] + '.wav'
408         if f.endswith('.w64'):
409             if not os.path.exists('tm/' + wav):
410                 os.waitpid(subprocess.Popen(["sndfile-convert","-pcm16",f,wav],cwd='tm').pid,0)
411                 wavs.append(wav)
412         elif f.endswith('.wav'):
413             wavs.append(f)
414     wavs.sort()
415     wavs.reverse()
416     for wav in wavs[:5]:
417         player.add('tm/' + wav)
418         player.stop()
419
420 player_map.add( Binding( Event('jb0',  2), 'Add TM', Action['player_queue_tm_recordings'] ) )
421
422 ###########################################################################
423
424 mixer_map.add       ( Binding( Event('jb0',10), '[Loop]',  Action['mode_looper'] ) )
425 looper_main_map.add ( Binding( Event('jb0',10), '[JBox]',  Action['mode_player'] ) )
426 player_map.add      ( Binding( Event('jb0',10), '[Mastr]', Action['mode_mixer']  ) )
427
428 main.keylist.append(global_map)
429 main.keylist.append(mixer_map)