7322050d6a61716241b9efac74db24edc712508b
[ardour.git] / libs / surfaces / mackie / surface.cc
1 #include <sstream>
2 #include <iomanip>
3 #include <iostream>
4 #include <cstdio>
5
6 #include "ardour/debug.h"
7
8 #include "mackie_button_handler.h"
9 #include "surface_port.h"
10 #include "surface.h"
11
12 using namespace std;
13 using namespace PBD;
14 using namespace Mackie;
15
16 Surface::Surface (uint32_t max_strips, uint32_t unit_strips)
17         : _max_strips (max_strips)
18         , _unit_strips( unit_strips )
19 {
20 }
21
22 void Surface::init ()
23 {
24         DEBUG_TRACE (DEBUG::MackieControl, "Surface::init\n");
25
26         strips.resize (_max_strips);
27         init_controls ();
28         init_strips ();
29
30         DEBUG_TRACE (DEBUG::MackieControl, "Surface::init finish\n");
31 }
32
33 Surface::~Surface ()
34 {
35         // delete groups
36         for (Groups::iterator it = groups.begin(); it != groups.end(); ++it) {
37                 delete it->second;
38         }
39         
40         // delete controls
41         for (Controls::iterator it = controls.begin(); it != controls.end(); ++it) {
42                 delete *it;
43         }
44 }
45
46 static GlobalControlDefinition mackie_global_controls[] = {
47         { "jog", 0x3c, Jog::factory, "none" },
48         { "external", 0x2e, Pot::factory, "none" },
49         { "io", 0x28, Button::factory, "assignment" },
50         { "sends", 0x29, Button::factory, "assignment" },
51         { "pan", 0x2a, Button::factory, "assignment" },
52         { "plugin", 0x2b, Button::factory, "assignment" },
53         { "eq", 0x2c, Button::factory, "assignment" },
54         { "dyn", 0x2d, Button::factory, "assignment" },
55         { "left", 0x2e, Button::factory, "bank" },
56         { "right", 0x2f, Button::factory, "bank" },
57         { "channel_left", 0x30, Button::factory, "bank" },
58         { "channel_right", 0x31, Button::factory, "bank" },
59         { "flip", 0x32, Button::factory, "none" },
60         { "edit", 0x33, Button::factory, "none" },
61         { "name_value", 0x34, Button::factory, "display" },
62         { "timecode_beats", 0x35, Button::factory, "display" },
63         { "F1", 0x36, Button::factory, "none" },
64         { "F2", 0x37, Button::factory, "none" },
65         { "F3", 0x38, Button::factory, "none" },
66         { "F4", 0x39, Button::factory, "none" },
67         { "F5", 0x3a, Button::factory, "none" },
68         { "F6", 0x3b, Button::factory, "none" },
69         { "F7", 0x3c, Button::factory, "none" },
70         { "F8", 0x3d, Button::factory, "none" },
71         { "F9", 0x3e, Button::factory, "none" },
72         { "F10", 0x3f, Button::factory, "none" },
73         { "F11", 0x40, Button::factory, "none" },
74         { "F12", 0x41, Button::factory, "none" },
75         { "F13", 0x42, Button::factory, "none" },
76         { "F14", 0x43, Button::factory, "none" },
77         { "F15", 0x44, Button::factory, "none" },
78         { "F16", 0x45, Button::factory, "none" },
79         { "shift", 0x46, Button::factory, "modifiers" },
80         { "option", 0x47, Button::factory, "modifiers" },
81         { "control", 0x48, Button::factory, "modifiers" },
82         { "cmd_alt", 0x49, Button::factory, "modifiers" },
83         { "on", 0x4a, Button::factory, "automation" },
84         { "rec_ready", 0x4b, Button::factory, "automation" },
85         { "undo", 0x4c, Button::factory, "functions" },
86         { "snapshot", 0x4d, Button::factory, "automation" },
87         { "touch", 0x4e, Button::factory, "automation" },
88         { "redo", 0x4f, Button::factory, "functions" },
89         { "marker", 0x50, Button::factory, "functions" },
90         { "enter", 0x51, Button::factory, "functions" },
91         { "cancel", 0x52, Button::factory, "functions" },
92         { "mixer", 0x53, Button::factory, "functions" },
93         { "frm_left", 0x54, Button::factory, "transport" },
94         { "frm_right", 0x55, Button::factory, "transport" },
95         { "loop", 0x56, Button::factory, "transport" },
96         { "punch_in", 0x57, Button::factory, "transport" },
97         { "punch_out", 0x58, Button::factory, "transport" },
98         { "home", 0x59, Button::factory, "transport" },
99         { "end", 0x5a, Button::factory, "transport" },
100         { "rewind", 0x5b, Button::factory, "transport" },
101         { "ffwd", 0x5c, Button::factory, "transport" },
102         { "stop", 0x5d, Button::factory, "transport" },
103         { "play", 0x5e, Button::factory, "transport" },
104         { "record", 0x5f, Button::factory, "transport" },
105         { "cursor_up", 0x60, Button::factory, "cursor" },
106         { "cursor_down", 0x61, Button::factory, "cursor" },
107         { "cursor_left", 0x62, Button::factory, "cursor" },
108         { "cursor_right", 0x63, Button::factory, "cursor" },
109         { "zoom", 0x64, Button::factory, "none" },
110         { "scrub", 0x65, Button::factory, "none" },
111         { "user_a", 0x66, Button::factory, "user" },
112         { "user_b", 0x67, Button::factory, "user" },
113         { "fader_touch", 0x70, Led::factory, "master" },
114         { "timecode", 0x71, Led::factory, "none" },
115         { "beats", 0x72, Led::factory, "none" },
116         { "solo", 0x73, Led::factory, "none" },
117         { "relay_click", 0x73, Led::factory, "none" },
118         { "", 0, Button::factory, "" }
119 };
120         
121 void 
122 Surface::init_controls()
123 {
124         Group* group;
125
126         groups["assignment"] = new Group  ("assignment");
127         groups["automation"] = new Group  ("automation");
128         groups["bank"] = new Group  ("bank");
129         groups["cursor"] = new Group  ("cursor");
130         groups["display"] = new Group  ("display");
131         groups["functions"] = new Group  ("functions");
132         groups["modifiers"] = new Group  ("modifiers");
133         groups["none"] = new Group  ("none");
134         groups["transport"] = new Group  ("transport");
135         groups["user"] = new Group  ("user");
136
137         group = new MasterStrip  ("master", 0);
138         groups["master"] = group;
139         strips[0] = dynamic_cast<Strip*> (group);
140
141         for (uint32_t n = 0; mackie_global_controls[n].name[0]; ++n) {
142                 group = groups[mackie_global_controls[n].group_name];
143                 Control* control = mackie_global_controls[n].factory (*this, mackie_global_controls[n].id, 1, mackie_global_controls[n].name, *group);
144                 controls_by_name[mackie_global_controls[n].name] = control;
145                 group->add (*control);
146         }
147 }
148
149 static StripControlDefinition mackie_strip_controls[] = {
150         { "gain", Control::fader_base_id, Fader::factory, },
151         { "vpot", Control::pot_base_id, Pot::factory, },
152         { "recenable", Control::recenable_button_base_id, Button::factory, },
153         { "solo", Control::solo_button_base_id, Button::factory, },
154         { "mute", Control::mute_button_base_id, Button::factory, },
155         { "select", Control::select_button_base_id, Button::factory, },
156         { "vselect", Control::vselect_button_base_id, Button::factory, },
157         { "fader_touch", Control::fader_touch_button_base_id, Button::factory, },
158         { "", 0, Button::factory, }
159 };
160
161 void 
162 Surface::init_strips ()
163 {
164         for (uint32_t i = 0; i < _max_strips; ++i) {
165
166                 char name[32];
167                 
168                 uint32_t unit_index = i % _unit_strips;
169                 
170                 snprintf (name, sizeof (name), "strip_%d", unit_index+1);
171                 
172                 Strip* strip = new Strip (*this, name, i, unit_index, mackie_strip_controls);
173                 
174                 groups[name] = strip;
175                 strips[i] = strip;
176         }
177 }
178
179 void 
180 Surface::handle_button (MackieButtonHandler & mbh, ButtonState bs, Button & button)
181 {
182         if  (bs != press && bs != release) {
183                 mbh.update_led (button, none);
184                 return;
185         }
186         
187         LedState ls;
188         switch  (button.id()) {
189         case 0x9028: // io
190                 switch  (bs) {
191                 case press: ls = mbh.io_press (button); break;
192                 case release: ls = mbh.io_release (button); break;
193                 case neither: break;
194                 }
195                 break;
196                 
197         case 0x9029: // sends
198                 switch  (bs) {
199                 case press: ls = mbh.sends_press (button); break;
200                 case release: ls = mbh.sends_release (button); break;
201                 case neither: break;
202                 }
203                 break;
204                 
205         case 0x902a: // pan
206                 switch  (bs) {
207                 case press: ls = mbh.pan_press (button); break;
208                 case release: ls = mbh.pan_release (button); break;
209                 case neither: break;
210                 }
211                 break;
212                 
213         case 0x902b: // plugin
214                 switch  (bs) {
215                 case press: ls = mbh.plugin_press (button); break;
216                 case release: ls = mbh.plugin_release (button); break;
217                 case neither: break;
218                 }
219                 break;
220                 
221         case 0x902c: // eq
222                 switch  (bs) {
223                 case press: ls = mbh.eq_press (button); break;
224                 case release: ls = mbh.eq_release (button); break;
225                 case neither: break;
226                 }
227                 break;
228                 
229         case 0x902d: // dyn
230                 switch  (bs) {
231                 case press: ls = mbh.dyn_press (button); break;
232                 case release: ls = mbh.dyn_release (button); break;
233                 case neither: break;
234                 }
235                 break;
236                 
237         case 0x902e: // left
238                 switch  (bs) {
239                 case press: ls = mbh.left_press (button); break;
240                 case release: ls = mbh.left_release (button); break;
241                 case neither: break;
242                 }
243                 break;
244                 
245         case 0x902f: // right
246                 switch  (bs) {
247                 case press: ls = mbh.right_press (button); break;
248                 case release: ls = mbh.right_release (button); break;
249                 case neither: break;
250                 }
251                 break;
252                 
253         case 0x9030: // channel_left
254                 switch  (bs) {
255                 case press: ls = mbh.channel_left_press (button); break;
256                 case release: ls = mbh.channel_left_release (button); break;
257                 case neither: break;
258                 }
259                 break;
260                 
261         case 0x9031: // channel_right
262                 switch  (bs) {
263                 case press: ls = mbh.channel_right_press (button); break;
264                 case release: ls = mbh.channel_right_release (button); break;
265                 case neither: break;
266                 }
267                 break;
268                 
269         case 0x9032: // flip
270                 switch  (bs) {
271                 case press: ls = mbh.flip_press (button); break;
272                 case release: ls = mbh.flip_release (button); break;
273                 case neither: break;
274                 }
275                 break;
276
277         case 0x9033: // edit
278                 switch  (bs) {
279                 case press: ls = mbh.edit_press (button); break;
280                 case release: ls = mbh.edit_release (button); break;
281                 case neither: break;
282                 }
283                 break;
284
285         case 0x9034: // name_value
286                 switch  (bs) {
287                 case press: ls = mbh.name_value_press (button); break;
288                 case release: ls = mbh.name_value_release (button); break;
289                 case neither: break;
290                 }
291                 break;
292
293         case 0x9035: // timecode_beats
294                 switch  (bs) {
295                 case press: ls = mbh.timecode_beats_press (button); break;
296                 case release: ls = mbh.timecode_beats_release (button); break;
297                 case neither: break;
298                 }
299                 break;
300
301         case 0x9036: // F1
302                 switch  (bs) {
303                 case press: ls = mbh.F1_press (button); break;
304                 case release: ls = mbh.F1_release (button); break;
305                 case neither: break;
306                 }
307                 break;
308
309         case 0x9037: // F2
310                 switch  (bs) {
311                 case press: ls = mbh.F2_press (button); break;
312                 case release: ls = mbh.F2_release (button); break;
313                 case neither: break;
314                 }
315                 break;
316
317         case 0x9038: // F3
318                 switch  (bs) {
319                 case press: ls = mbh.F3_press (button); break;
320                 case release: ls = mbh.F3_release (button); break;
321                 case neither: break;
322                 }
323                 break;
324
325         case 0x9039: // F4
326                 switch  (bs) {
327                 case press: ls = mbh.F4_press (button); break;
328                 case release: ls = mbh.F4_release (button); break;
329                 case neither: break;
330                 }
331                 break;
332
333         case 0x903a: // F5
334                 switch  (bs) {
335                 case press: ls = mbh.F5_press (button); break;
336                 case release: ls = mbh.F5_release (button); break;
337                 case neither: break;
338                 }
339                 break;
340
341         case 0x903b: // F6
342                 switch  (bs) {
343                 case press: ls = mbh.F6_press (button); break;
344                 case release: ls = mbh.F6_release (button); break;
345                 case neither: break;
346                 }
347                 break;
348
349         case 0x903c: // F7
350                 switch  (bs) {
351                 case press: ls = mbh.F7_press (button); break;
352                 case release: ls = mbh.F7_release (button); break;
353                 case neither: break;
354                 }
355                 break;
356
357         case 0x903d: // F8
358                 switch  (bs) {
359                 case press: ls = mbh.F8_press (button); break;
360                 case release: ls = mbh.F8_release (button); break;
361                 case neither: break;
362                 }
363                 break;
364
365         case 0x903e: // F9
366                 switch  (bs) {
367                 case press: ls = mbh.F9_press (button); break;
368                 case release: ls = mbh.F9_release (button); break;
369                 case neither: break;
370                 }
371                 break;
372
373         case 0x903f: // F10
374                 switch  (bs) {
375                 case press: ls = mbh.F10_press (button); break;
376                 case release: ls = mbh.F10_release (button); break;
377                 case neither: break;
378                 }
379                 break;
380
381         case 0x9040: // F11
382                 switch  (bs) {
383                 case press: ls = mbh.F11_press (button); break;
384                 case release: ls = mbh.F11_release (button); break;
385                 case neither: break;
386                 }
387                 break;
388
389         case 0x9041: // F12
390                 switch  (bs) {
391                 case press: ls = mbh.F12_press (button); break;
392                 case release: ls = mbh.F12_release (button); break;
393                 case neither: break;
394                 }
395                 break;
396
397         case 0x9042: // F13
398                 switch  (bs) {
399                 case press: ls = mbh.F13_press (button); break;
400                 case release: ls = mbh.F13_release (button); break;
401                 case neither: break;
402                 }
403                 break;
404
405         case 0x9043: // F14
406                 switch  (bs) {
407                 case press: ls = mbh.F14_press (button); break;
408                 case release: ls = mbh.F14_release (button); break;
409                 case neither: break;
410                 }
411                 break;
412
413         case 0x9044: // F15
414                 switch  (bs) {
415                 case press: ls = mbh.F15_press (button); break;
416                 case release: ls = mbh.F15_release (button); break;
417                 case neither: break;
418                 }
419                 break;
420
421         case 0x9045: // F16
422                 switch  (bs) {
423                 case press: ls = mbh.F16_press (button); break;
424                 case release: ls = mbh.F16_release (button); break;
425                 case neither: break;
426                 }
427                 break;
428
429         case 0x9046: // shift
430                 switch  (bs) {
431                 case press: ls = mbh.shift_press (button); break;
432                 case release: ls = mbh.shift_release (button); break;
433                 case neither: break;
434                 }
435                 break;
436
437         case 0x9047: // option
438                 switch  (bs) {
439                 case press: ls = mbh.option_press (button); break;
440                 case release: ls = mbh.option_release (button); break;
441                 case neither: break;
442                 }
443                 break;
444
445         case 0x9048: // control
446                 switch  (bs) {
447                 case press: ls = mbh.control_press (button); break;
448                 case release: ls = mbh.control_release (button); break;
449                 case neither: break;
450                 }
451                 break;
452
453         case 0x9049: // cmd_alt
454                 switch  (bs) {
455                 case press: ls = mbh.cmd_alt_press (button); break;
456                 case release: ls = mbh.cmd_alt_release (button); break;
457                 case neither: break;
458                 }
459                 break;
460
461         case 0x904a: // on
462                 switch  (bs) {
463                 case press: ls = mbh.on_press (button); break;
464                 case release: ls = mbh.on_release (button); break;
465                 case neither: break;
466                 }
467                 break;
468
469         case 0x904b: // rec_ready
470                 switch  (bs) {
471                 case press: ls = mbh.rec_ready_press (button); break;
472                 case release: ls = mbh.rec_ready_release (button); break;
473                 case neither: break;
474                 }
475                 break;
476
477         case 0x904c: // undo
478                 switch  (bs) {
479                 case press: ls = mbh.undo_press (button); break;
480                 case release: ls = mbh.undo_release (button); break;
481                 case neither: break;
482                 }
483                 break;
484
485         case 0x904d: // snapshot
486                 switch  (bs) {
487                 case press: ls = mbh.snapshot_press (button); break;
488                 case release: ls = mbh.snapshot_release (button); break;
489                 case neither: break;
490                 }
491                 break;
492
493         case 0x904e: // touch
494                 switch  (bs) {
495                 case press: ls = mbh.touch_press (button); break;
496                 case release: ls = mbh.touch_release (button); break;
497                 case neither: break;
498                 }
499                 break;
500
501         case 0x904f: // redo
502                 switch  (bs) {
503                 case press: ls = mbh.redo_press (button); break;
504                 case release: ls = mbh.redo_release (button); break;
505                 case neither: break;
506                 }
507                 break;
508
509         case 0x9050: // marker
510                 switch  (bs) {
511                 case press: ls = mbh.marker_press (button); break;
512                 case release: ls = mbh.marker_release (button); break;
513                 case neither: break;
514                 }
515                 break;
516
517         case 0x9051: // enter
518                 switch  (bs) {
519                 case press: ls = mbh.enter_press (button); break;
520                 case release: ls = mbh.enter_release (button); break;
521                 case neither: break;
522                 }
523                 break;
524
525         case 0x9052: // cancel
526                 switch  (bs) {
527                 case press: ls = mbh.cancel_press (button); break;
528                 case release: ls = mbh.cancel_release (button); break;
529                 case neither: break;
530                 }
531                 break;
532
533         case 0x9053: // mixer
534                 switch  (bs) {
535                 case press: ls = mbh.mixer_press (button); break;
536                 case release: ls = mbh.mixer_release (button); break;
537                 case neither: break;
538                 }
539                 break;
540
541         case 0x9054: // frm_left
542                 switch  (bs) {
543                 case press: ls = mbh.frm_left_press (button); break;
544                 case release: ls = mbh.frm_left_release (button); break;
545                 case neither: break;
546                 }
547                 break;
548
549         case 0x9055: // frm_right
550                 switch  (bs) {
551                 case press: ls = mbh.frm_right_press (button); break;
552                 case release: ls = mbh.frm_right_release (button); break;
553                 case neither: break;
554                 }
555                 break;
556
557         case 0x9056: // loop
558                 switch  (bs) {
559                 case press: ls = mbh.loop_press (button); break;
560                 case release: ls = mbh.loop_release (button); break;
561                 case neither: break;
562                 }
563                 break;
564
565         case 0x9057: // punch_in
566                 switch  (bs) {
567                 case press: ls = mbh.punch_in_press (button); break;
568                 case release: ls = mbh.punch_in_release (button); break;
569                 case neither: break;
570                 }
571                 break;
572
573         case 0x9058: // punch_out
574                 switch  (bs) {
575                 case press: ls = mbh.punch_out_press (button); break;
576                 case release: ls = mbh.punch_out_release (button); break;
577                 case neither: break;
578                 }
579                 break;
580
581         case 0x9059: // home
582                 switch  (bs) {
583                 case press: ls = mbh.home_press (button); break;
584                 case release: ls = mbh.home_release (button); break;
585                 case neither: break;
586                 }
587                 break;
588
589         case 0x905a: // end
590                 switch  (bs) {
591                 case press: ls = mbh.end_press (button); break;
592                 case release: ls = mbh.end_release (button); break;
593                 case neither: break;
594                 }
595                 break;
596
597         case 0x905b: // rewind
598                 switch  (bs) {
599                 case press: ls = mbh.rewind_press (button); break;
600                 case release: ls = mbh.rewind_release (button); break;
601                 case neither: break;
602                 }
603                 break;
604
605         case 0x905c: // ffwd
606                 switch  (bs) {
607                 case press: ls = mbh.ffwd_press (button); break;
608                 case release: ls = mbh.ffwd_release (button); break;
609                 case neither: break;
610                 }
611                 break;
612
613         case 0x905d: // stop
614                 switch  (bs) {
615                 case press: ls = mbh.stop_press (button); break;
616                 case release: ls = mbh.stop_release (button); break;
617                 case neither: break;
618                 }
619                 break;
620
621         case 0x905e: // play
622                 switch  (bs) {
623                 case press: ls = mbh.play_press (button); break;
624                 case release: ls = mbh.play_release (button); break;
625                 case neither: break;
626                 }
627                 break;
628
629         case 0x905f: // record
630                 switch  (bs) {
631                 case press: ls = mbh.record_press (button); break;
632                 case release: ls = mbh.record_release (button); break;
633                 case neither: break;
634                 }
635                 break;
636
637         case 0x9060: // cursor_up
638                 switch  (bs) {
639                 case press: ls = mbh.cursor_up_press (button); break;
640                 case release: ls = mbh.cursor_up_release (button); break;
641                 case neither: break;
642                 }
643                 break;
644
645         case 0x9061: // cursor_down
646                 switch  (bs) {
647                 case press: ls = mbh.cursor_down_press (button); break;
648                 case release: ls = mbh.cursor_down_release (button); break;
649                 case neither: break;
650                 }
651                 break;
652
653         case 0x9062: // cursor_left
654                 switch  (bs) {
655                 case press: ls = mbh.cursor_left_press (button); break;
656                 case release: ls = mbh.cursor_left_release (button); break;
657                 case neither: break;
658                 }
659                 break;
660
661         case 0x9063: // cursor_right
662                 switch  (bs) {
663                 case press: ls = mbh.cursor_right_press (button); break;
664                 case release: ls = mbh.cursor_right_release (button); break;
665                 case neither: break;
666                 }
667                 break;
668
669         case 0x9064: // zoom
670                 switch  (bs) {
671                 case press: ls = mbh.zoom_press (button); break;
672                 case release: ls = mbh.zoom_release (button); break;
673                 case neither: break;
674                 }
675                 break;
676
677         case 0x9065: // scrub
678                 switch  (bs) {
679                 case press: ls = mbh.scrub_press (button); break;
680                 case release: ls = mbh.scrub_release (button); break;
681                 case neither: break;
682                 }
683                 break;
684
685         case 0x9066: // user_a
686                 switch  (bs) {
687                 case press: ls = mbh.user_a_press (button); break;
688                 case release: ls = mbh.user_a_release (button); break;
689                 case neither: break;
690                 }
691                 break;
692
693         case 0x9067: // user_b
694                 switch  (bs) {
695                 case press: ls = mbh.user_b_press (button); break;
696                 case release: ls = mbh.user_b_release (button); break;
697                 case neither: break;
698                 }
699                 break;
700
701         }
702         mbh.update_led (button, ls);
703 }