start tweaks to make Shift sticky; remove Shift-press combobox from gui since we...
[ardour.git] / libs / surfaces / faderport / faderport.cc
1 /*
2     Copyright (C) 2015 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <cstdlib>
21 #include <sstream>
22 #include <algorithm>
23
24 #include <stdint.h>
25
26 #include <glibmm/fileutils.h>
27 #include <glibmm/miscutils.h>
28
29 #include "pbd/controllable_descriptor.h"
30 #include "pbd/error.h"
31 #include "pbd/failed_constructor.h"
32 #include "pbd/file_utils.h"
33 #include "pbd/pthread_utils.h"
34 #include "pbd/compose.h"
35 #include "pbd/xml++.h"
36
37 #include "midi++/port.h"
38
39 #include "ardour/async_midi_port.h"
40 #include "ardour/audioengine.h"
41 #include "ardour/amp.h"
42 #include "ardour/debug.h"
43 #include "ardour/filesystem_paths.h"
44 #include "ardour/midi_port.h"
45 #include "ardour/midiport_manager.h"
46 #include "ardour/monitor_processor.h"
47 #include "ardour/profile.h"
48 #include "ardour/rc_configuration.h"
49 #include "ardour/route.h"
50 #include "ardour/session.h"
51 #include "ardour/track.h"
52
53 #include "faderport.h"
54
55 using namespace ARDOUR;
56 using namespace ArdourSurface;
57 using namespace PBD;
58 using namespace Glib;
59 using namespace std;
60
61 #include "i18n.h"
62
63 #include "pbd/abstract_ui.cc" // instantiate template
64
65 FaderPort::FaderPort (Session& s)
66         : ControlProtocol (s, _("Faderport"))
67         , AbstractUI<FaderPortRequest> ("faderport")
68         , gui (0)
69         , connection_state (ConnectionState (0))
70         , _device_active (false)
71         , fader_msb (0)
72         , fader_lsb (0)
73         , fader_is_touched (false)
74         , button_state (ButtonState (0))
75         , blink_state (false)
76 {
77         last_encoder_time = 0;
78
79         boost::shared_ptr<ARDOUR::Port> inp;
80         boost::shared_ptr<ARDOUR::Port> outp;
81
82         inp  = AudioEngine::instance()->register_input_port (DataType::MIDI, "Faderport Recv", true);
83         outp = AudioEngine::instance()->register_output_port (DataType::MIDI, "Faderport Send", true);
84
85         _input_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(inp);
86         _output_port = boost::dynamic_pointer_cast<AsyncMIDIPort>(outp);
87
88         if (_input_port == 0 || _output_port == 0) {
89                 throw failed_constructor();
90         }
91
92         TrackSelectionChanged.connect (selection_connection, MISSING_INVALIDATOR, boost::bind (&FaderPort::gui_track_selection_changed, this, _1), this);
93
94         /* Catch port connections and disconnections */
95         ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connection, MISSING_INVALIDATOR, boost::bind (&FaderPort::connection_handler, this, _1, _2, _3, _4, _5), this);
96
97         buttons.insert (std::make_pair (Mute, Button (*this, _("Mute"), Mute, 21)));
98         buttons.insert (std::make_pair (Solo, Button (*this, _("Solo"), Solo, 22)));
99         buttons.insert (std::make_pair (Rec, Button (*this, _("Rec"), Rec, 23)));
100         buttons.insert (std::make_pair (Left, Button (*this, _("Left"), Left, 20)));
101         buttons.insert (std::make_pair (Bank, Button (*this, _("Bank"), Bank, 19)));
102         buttons.insert (std::make_pair (Right, Button (*this, _("Right"), Right, 18)));
103         buttons.insert (std::make_pair (Output, Button (*this, _("Output"), Output, 17)));
104         buttons.insert (std::make_pair (FP_Read, Button (*this, _("Read"), FP_Read, 13)));
105         buttons.insert (std::make_pair (FP_Write, Button (*this, _("Write"), FP_Write, 14)));
106         buttons.insert (std::make_pair (FP_Touch, Button (*this, _("Touch"), FP_Touch, 15)));
107         buttons.insert (std::make_pair (FP_Off, Button (*this, _("Off"), FP_Off, 16)));
108         buttons.insert (std::make_pair (Mix, Button (*this, _("Mix"), Mix, 12)));
109         buttons.insert (std::make_pair (Proj, Button (*this, _("Proj"), Proj, 11)));
110         buttons.insert (std::make_pair (Trns, Button (*this, _("Trns"), Trns, 10)));
111         buttons.insert (std::make_pair (Undo, Button (*this, _("Undo"), Undo, 9)));
112         buttons.insert (std::make_pair (Shift, Button (*this, _("Shift"), Shift, 5)));
113         buttons.insert (std::make_pair (Punch, Button (*this, _("Punch"), Punch, 6)));
114         buttons.insert (std::make_pair (User, Button (*this, _("User"), User, 7)));
115         buttons.insert (std::make_pair (Loop, Button (*this, _("Loop"), Loop, 8)));
116         buttons.insert (std::make_pair (Rewind, Button (*this, _("Rewind"), Rewind, 4)));
117         buttons.insert (std::make_pair (Ffwd, Button (*this, _("Ffwd"), Ffwd, 3)));
118         buttons.insert (std::make_pair (Stop, Button (*this, _("Stop"), Stop, 2)));
119         buttons.insert (std::make_pair (Play, Button (*this, _("Play"), Play, 1)));
120         buttons.insert (std::make_pair (RecEnable, Button (*this, _("RecEnable"), RecEnable, 0)));
121         buttons.insert (std::make_pair (FaderTouch, Button (*this, _("Fader (touch)"), FaderTouch, -1)));
122
123         get_button (Shift).set_flash (true);
124         get_button (Mix).set_flash (true);
125         get_button (Proj).set_flash (true);
126         get_button (Trns).set_flash (true);
127         get_button (User).set_flash (true);
128
129         get_button (Left).set_action ( boost::bind (&FaderPort::left, this), true);
130         get_button (Right).set_action ( boost::bind (&FaderPort::right, this), true);
131
132         get_button (Undo).set_action (boost::bind (&FaderPort::undo, this), true);
133         get_button (Undo).set_action (boost::bind (&FaderPort::redo, this), true, ShiftDown);
134         get_button (Undo).set_flash (true);
135
136         get_button (FP_Read).set_action (boost::bind (&FaderPort::read, this), true);
137         get_button (FP_Write).set_action (boost::bind (&FaderPort::write, this), true);
138         get_button (FP_Touch).set_action (boost::bind (&FaderPort::touch, this), true);
139         get_button (FP_Off).set_action (boost::bind (&FaderPort::off, this), true);
140
141         get_button (Play).set_action (boost::bind (&BasicUI::transport_play, this, true), true);
142         get_button (RecEnable).set_action (boost::bind (&BasicUI::rec_enable_toggle, this), true);
143         /* Stop is a modifier, so we have to use its own button state to get
144            the default action (since StopDown will be set when looking for the
145            action to invoke.
146         */
147         get_button (Stop).set_action (boost::bind (&BasicUI::transport_stop, this), true, StopDown);
148         get_button (Ffwd).set_action (boost::bind (&BasicUI::ffwd, this), true);
149
150         /* See comments about Stop above .. */
151         get_button (Rewind).set_action (boost::bind (&BasicUI::rewind, this), true, RewindDown);
152         get_button (Rewind).set_action (boost::bind (&BasicUI::goto_zero, this), true, ButtonState (RewindDown|StopDown));
153         get_button (Rewind).set_action (boost::bind (&BasicUI::goto_start, this), true, ButtonState (RewindDown|ShiftDown));
154
155         get_button (Ffwd).set_action (boost::bind (&BasicUI::ffwd, this), true);
156         get_button (Ffwd).set_action (boost::bind (&BasicUI::goto_end, this), true, ShiftDown);
157
158         get_button (Punch).set_action (boost::bind (&FaderPort::punch, this), true);
159
160         get_button (Loop).set_action (boost::bind (&BasicUI::loop_toggle, this), true);
161         get_button (Loop).set_action (boost::bind (&BasicUI::add_marker, this, string()), true, ShiftDown);
162
163         get_button (Punch).set_action (boost::bind (&BasicUI::prev_marker, this), true, ShiftDown);
164         get_button (User).set_action (boost::bind (&BasicUI::next_marker, this), true, ShiftDown);
165
166         get_button (Mute).set_action (boost::bind (&FaderPort::mute, this), true);
167         get_button (Solo).set_action (boost::bind (&FaderPort::solo, this), true);
168         get_button (Rec).set_action (boost::bind (&FaderPort::rec_enable, this), true);
169
170         get_button (Output).set_action (boost::bind (&FaderPort::use_master, this), true);
171         get_button (Output).set_action (boost::bind (&FaderPort::use_monitor, this), true, ShiftDown);
172 }
173
174 FaderPort::~FaderPort ()
175 {
176         if (_input_port) {
177                 DEBUG_TRACE (DEBUG::FaderPort, string_compose ("unregistering input port %1\n", boost::shared_ptr<ARDOUR::Port>(_input_port)->name()));
178                 AudioEngine::instance()->unregister_port (_input_port);
179                 _input_port.reset ();
180         }
181
182         if (_output_port) {
183 //              _output_port->drain (10000);  //ToDo:  is this necessary?  It hangs the shutdown, for me
184                 DEBUG_TRACE (DEBUG::FaderPort, string_compose ("unregistering output port %1\n", boost::shared_ptr<ARDOUR::Port>(_output_port)->name()));
185                 AudioEngine::instance()->unregister_port (_output_port);
186                 _output_port.reset ();
187         }
188
189         tear_down_gui ();
190 }
191
192 void
193 FaderPort::start_midi_handling ()
194 {
195         /* handle device inquiry response */
196         _input_port->parser()->sysex.connect_same_thread (midi_connections, boost::bind (&FaderPort::sysex_handler, this, _1, _2, _3));
197         /* handle buttons */
198         _input_port->parser()->poly_pressure.connect_same_thread (midi_connections, boost::bind (&FaderPort::button_handler, this, _1, _2));
199         /* handle encoder */
200         _input_port->parser()->pitchbend.connect_same_thread (midi_connections, boost::bind (&FaderPort::encoder_handler, this, _1, _2));
201         /* handle fader */
202         _input_port->parser()->controller.connect_same_thread (midi_connections, boost::bind (&FaderPort::fader_handler, this, _1, _2));
203
204         /* This connection means that whenever data is ready from the input
205          * port, the relevant thread will invoke our ::midi_input_handler()
206          * method, which will read the data, and invoke the parser.
207          */
208
209         _input_port->xthread().set_receive_handler (sigc::bind (sigc::mem_fun (this, &FaderPort::midi_input_handler), _input_port));
210         _input_port->xthread().attach (main_loop()->get_context());
211 }
212
213 void
214 FaderPort::stop_midi_handling ()
215 {
216         midi_connections.drop_connections ();
217
218         /* Note: the input handler is still active at this point, but we're no
219          * longer connected to any of the parser signals
220          */
221 }
222
223 void
224 FaderPort::do_request (FaderPortRequest* req)
225 {
226         if (req->type == CallSlot) {
227
228                 call_slot (MISSING_INVALIDATOR, req->the_slot);
229
230         } else if (req->type == Quit) {
231
232                 stop ();
233         }
234 }
235
236 int
237 FaderPort::stop ()
238 {
239         BaseUI::quit ();
240
241         return 0;
242 }
243
244 void
245 FaderPort::thread_init ()
246 {
247         struct sched_param rtparam;
248
249         pthread_set_name (X_("FaderPort"));
250
251         PBD::notify_gui_about_thread_creation (X_("gui"), pthread_self(), X_("FaderPort"), 2048);
252         ARDOUR::SessionEvent::create_per_thread_pool (X_("FaderPort"), 128);
253
254         memset (&rtparam, 0, sizeof (rtparam));
255         rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
256
257         if (pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam) != 0) {
258                 // do we care? not particularly.
259         }
260 }
261
262 void
263 FaderPort::all_lights_out ()
264 {
265         for (ButtonMap::iterator b = buttons.begin(); b != buttons.end(); ++b) {
266                 b->second.set_led_state (_output_port, false, true);
267         }
268 }
269
270 FaderPort::Button&
271 FaderPort::get_button (ButtonID id) const
272 {
273         ButtonMap::const_iterator b = buttons.find (id);
274         assert (b != buttons.end());
275         return const_cast<Button&>(b->second);
276 }
277
278 bool
279 FaderPort::button_long_press_timeout (ButtonID id)
280 {
281         if (buttons_down.find (id) != buttons_down.end()) {
282                 get_button (id).invoke (ButtonState (LongPress|button_state), false);
283         } else {
284                 /* release happened and somehow we were not cancelled */
285         }
286
287         return false; /* don't get called again */
288 }
289
290 void
291 FaderPort::start_press_timeout (Button& button, ButtonID id)
292 {
293         Glib::RefPtr<Glib::TimeoutSource> timeout = Glib::TimeoutSource::create (500); // milliseconds
294         button.timeout_connection = timeout->connect (sigc::bind (sigc::mem_fun (*this, &FaderPort::button_long_press_timeout), id));
295         timeout->attach (main_loop()->get_context());
296 }
297
298 void
299 FaderPort::button_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb)
300 {
301         ButtonID id (ButtonID (tb->controller_number));
302         Button& button (get_button (id));
303
304         if (tb->value) {
305                 buttons_down.insert (id);
306         } else {
307                 buttons_down.erase (id);
308                 button.timeout_connection.disconnect ();
309         }
310
311         ButtonState bs (ButtonState (0));
312
313         switch (id) {
314         case Shift:
315                 bs = ShiftDown;
316                 break;
317         case Stop:
318                 bs = StopDown;
319                 break;
320         case Rewind:
321                 bs = RewindDown;
322                 break;
323         case User:
324                 bs = UserDown;
325                 break;
326         case FaderTouch:
327                 fader_is_touched = tb->value;
328                 if (_current_route) {
329                         boost::shared_ptr<AutomationControl> gain = _current_route->gain_control ();
330                         if (gain) {
331                                 framepos_t now = session->engine().sample_time();
332                                 if (tb->value) {
333                                         gain->start_touch (now);
334                                 } else {
335                                         gain->stop_touch (true, now);
336                                 }
337                         }
338                 }
339                 break;
340         default:
341                 if (tb->value) {
342                         start_press_timeout (button, id);
343                 }
344                 break;
345         }
346
347         if (bs) {
348                 button_state = (tb->value ? ButtonState (button_state|bs) : ButtonState (button_state&~bs));
349         }
350
351         if (button.uses_flash()) {
352                 button.set_led_state (_output_port, (int)tb->value);
353         }
354
355         button.invoke (button_state, tb->value ? true : false);
356 }
357
358 void
359 FaderPort::encoder_handler (MIDI::Parser &, MIDI::pitchbend_t pb)
360 {
361         int delta = 1;
362
363         if (pb >= 8192) {
364                 delta = -1;
365         }
366
367         //knob debouncing and hysteresis.  The presonus encoder often sends bursts of events, or goes the wrong direction
368         {
369                 last_last_encoder_delta = last_encoder_delta;
370                 last_encoder_delta = delta;
371                 microseconds_t now = get_microseconds ();
372                 if ((now - last_encoder_time) < 10*1000) { //require at least 10ms interval between changes, because the device sometimes sends multiple deltas
373                         return;
374                 }
375                 if ((now - last_encoder_time) < 100*1000) { //avoid directional changes while "spinning", 100ms window
376                         if ( (delta == last_encoder_delta) && (delta == last_last_encoder_delta) ) {
377                                 last_good_encoder_delta = delta;  //3 in a row, grudgingly accept this as the new direction
378                         }
379                         if (delta != last_good_encoder_delta) {  //otherwise ensure we keep going the same way
380                                 delta = last_good_encoder_delta;
381                         }
382                 } else {  //we aren't yet in a spin window, just assume this move is really what we want
383                         //NOTE:  if you are worried about where these get initialized, here it is.
384                         last_last_encoder_delta = delta;
385                         last_encoder_delta = delta;
386                 }
387                 last_encoder_time = now;
388                 last_good_encoder_delta = delta;
389         }
390
391         if (_current_route) {
392
393                 ButtonState trim_modifier;
394                 ButtonState width_modifier;
395
396                 if (Profile->get_mixbus()) {
397                         trim_modifier = ShiftDown;
398                         width_modifier = ButtonState (0);
399                 } else {
400                         trim_modifier = UserDown;
401                         width_modifier = ShiftDown;
402                 }
403
404                 if ((button_state & trim_modifier) == trim_modifier ) {    // mod+encoder = input trim
405                         boost::shared_ptr<AutomationControl> gain = _current_route->trim()->gain_control ();
406                         if (gain) {
407                                 float val = gain->get_user();  //for gain elements, the "user" value is in dB
408                                 val += delta;
409                                 gain->set_user(val);
410                         }
411                 } else if (width_modifier && ((button_state & width_modifier) == width_modifier)) {
412                         ardour_pan_width (delta);
413
414                 } else {  // pan/balance
415                         if (!Profile->get_mixbus()) {
416                                 ardour_pan_azimuth (delta);
417                         } else {
418                                 mixbus_pan (delta);
419                         }
420                 }
421         }
422 }
423
424 void
425 FaderPort::fader_handler (MIDI::Parser &, MIDI::EventTwoBytes* tb)
426 {
427         bool was_fader = false;
428
429         if (tb->controller_number == 0x0) {
430                 fader_msb = tb->value;
431                 was_fader = true;
432         } else if (tb->controller_number == 0x20) {
433                 fader_lsb = tb->value;
434                 was_fader = true;
435         }
436
437         if (was_fader) {
438                 if (_current_route) {
439                         boost::shared_ptr<AutomationControl> gain = _current_route->gain_control ();
440                         if (gain) {
441                                 int ival = (fader_msb << 7) | fader_lsb;
442                                 float val = gain->interface_to_internal (ival/16384.0);
443                                 _current_route->set_gain (val, this);
444                         }
445                 }
446         }
447 }
448
449 void
450 FaderPort::sysex_handler (MIDI::Parser &p, MIDI::byte *buf, size_t sz)
451 {
452         if (sz < 17) {
453                 return;
454         }
455
456         if (buf[2] != 0x7f ||
457             buf[3] != 0x06 ||
458             buf[4] != 0x02 ||
459             buf[5] != 0x0 ||
460             buf[6] != 0x1 ||
461             buf[7] != 0x06 ||
462             buf[8] != 0x02 ||
463             buf[9] != 0x0 ||
464             buf[10] != 0x01 ||
465             buf[11] != 0x0) {
466                 return;
467         }
468
469         _device_active = true;
470
471         DEBUG_TRACE (DEBUG::FaderPort, "FaderPort identified via MIDI Device Inquiry response\n");
472
473         /* put it into native mode */
474
475         MIDI::byte native[3];
476         native[0] = 0x91;
477         native[1] = 0x00;
478         native[2] = 0x64;
479
480         _output_port->write (native, 3, 0);
481
482         all_lights_out ();
483
484         /* catch up on state */
485
486         notify_transport_state_changed ();
487         notify_record_state_changed ();
488 }
489
490 int
491 FaderPort::set_active (bool yn)
492 {
493         DEBUG_TRACE (DEBUG::FaderPort, string_compose("MackieControlProtocol::set_active init with yn: '%1'\n", yn));
494
495         if (yn == active()) {
496                 return 0;
497         }
498
499         if (yn) {
500
501                 /* start event loop */
502
503                 BaseUI::run ();
504
505                 connect_session_signals ();
506
507                 Glib::RefPtr<Glib::TimeoutSource> blink_timeout = Glib::TimeoutSource::create (200); // milliseconds
508                 blink_connection = blink_timeout->connect (sigc::mem_fun (*this, &FaderPort::blink));
509                 blink_timeout->attach (main_loop()->get_context());
510
511         } else {
512
513                 BaseUI::quit ();
514                 close ();
515
516         }
517
518         ControlProtocol::set_active (yn);
519
520         DEBUG_TRACE (DEBUG::FaderPort, string_compose("MackieControlProtocol::set_active done with yn: '%1'\n", yn));
521
522         return 0;
523 }
524
525 bool
526 FaderPort::blink ()
527 {
528         blink_state = !blink_state;
529
530         for (Blinkers::iterator b = blinkers.begin(); b != blinkers.end(); b++) {
531                 get_button(*b).set_led_state (_output_port, blink_state);
532         }
533
534         return true;
535 }
536
537 void
538 FaderPort::close ()
539 {
540         all_lights_out ();
541
542         stop_midi_handling ();
543         session_connections.drop_connections ();
544         port_connection.disconnect ();
545         blink_connection.disconnect ();
546         selection_connection.disconnect ();
547         route_connections.drop_connections ();
548
549 #if 0
550         route_connections.drop_connections ();
551 #endif
552 }
553
554 void
555 FaderPort::notify_record_state_changed ()
556 {
557         switch (session->record_status()) {
558         case Session::Disabled:
559                 get_button (RecEnable).set_led_state (_output_port, false);
560                 blinkers.remove (RecEnable);
561                 break;
562         case Session::Enabled:
563                 get_button (RecEnable).set_led_state (_output_port, true);
564                 blinkers.push_back (RecEnable);
565                 break;
566         case Session::Recording:
567                 get_button (RecEnable).set_led_state (_output_port, true);
568                 blinkers.remove (RecEnable);
569                 break;
570         }
571 }
572
573 void
574 FaderPort::notify_transport_state_changed ()
575 {
576         get_button (Loop).set_led_state (_output_port, session->get_play_loop());
577         get_button (Play).set_led_state (_output_port, session->transport_speed() == 1.0);
578         get_button (Stop).set_led_state (_output_port, session->transport_stopped ());
579         get_button (Rewind).set_led_state (_output_port, session->transport_speed() < 0.0);
580         get_button (Ffwd).set_led_state (_output_port, session->transport_speed() > 1.0);
581 }
582
583 void
584 FaderPort::connect_session_signals()
585 {
586         session->RecordStateChanged.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::notify_record_state_changed, this), this);
587         session->TransportStateChange.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::notify_transport_state_changed, this), this);
588 }
589
590 bool
591 FaderPort::midi_input_handler (Glib::IOCondition ioc, boost::shared_ptr<ARDOUR::AsyncMIDIPort> port)
592 {
593         DEBUG_TRACE (DEBUG::FaderPort, string_compose ("something happend on  %1\n", boost::shared_ptr<MIDI::Port>(port)->name()));
594
595         if (ioc & ~IO_IN) {
596                 return false;
597         }
598
599         if (ioc & IO_IN) {
600
601                 if (port) {
602                         port->clear ();
603                 }
604
605                 DEBUG_TRACE (DEBUG::FaderPort, string_compose ("data available on %1\n", boost::shared_ptr<MIDI::Port>(port)->name()));
606                 framepos_t now = session->engine().sample_time();
607                 port->parse (now);
608         }
609
610         return true;
611 }
612
613
614 XMLNode&
615 FaderPort::get_state ()
616 {
617         XMLNode& node (ControlProtocol::get_state());
618
619         XMLNode* child;
620
621         child = new XMLNode (X_("Input"));
622         child->add_child_nocopy (boost::shared_ptr<ARDOUR::Port>(_input_port)->get_state());
623         node.add_child_nocopy (*child);
624
625
626         child = new XMLNode (X_("Output"));
627         child->add_child_nocopy (boost::shared_ptr<ARDOUR::Port>(_output_port)->get_state());
628         node.add_child_nocopy (*child);
629
630         /* Save action state for Mix, Proj, Trns and User buttons, since these
631          * are user controlled. We can only save named-action operations, since
632          * internal functions are just pointers to functions and hard to
633          * serialize without enumerating them all somewhere.
634          */
635
636         node.add_child_nocopy (get_button (Mix).get_state());
637         node.add_child_nocopy (get_button (Proj).get_state());
638         node.add_child_nocopy (get_button (Trns).get_state());
639         node.add_child_nocopy (get_button (User).get_state());
640
641         return node;
642 }
643
644 int
645 FaderPort::set_state (const XMLNode& node, int version)
646 {
647         XMLNodeList nlist;
648         XMLNodeConstIterator niter;
649         XMLNode const* child;
650
651         if (ControlProtocol::set_state (node, version)) {
652                 return -1;
653         }
654
655         if ((child = node.child (X_("Input"))) != 0) {
656                 XMLNode* portnode = child->child (Port::state_node_name.c_str());
657                 if (portnode) {
658                         boost::shared_ptr<ARDOUR::Port>(_input_port)->set_state (*portnode, version);
659                 }
660         }
661
662         if ((child = node.child (X_("Output"))) != 0) {
663                 XMLNode* portnode = child->child (Port::state_node_name.c_str());
664                 if (portnode) {
665                         boost::shared_ptr<ARDOUR::Port>(_output_port)->set_state (*portnode, version);
666                 }
667         }
668
669         for (XMLNodeList::const_iterator n = node.children().begin(); n != node.children().end(); ++n) {
670                 if ((*n)->name() == X_("Button")) {
671                         XMLProperty const * prop = (*n)->property (X_("id"));
672                         if (!prop) {
673                                 continue;
674                         }
675                         int xid = atoi (prop->value());
676                         ButtonMap::iterator b = buttons.find (ButtonID (xid));
677                         if (b == buttons.end()) {
678                                 continue;
679                         }
680                         b->second.set_state (**n);
681                 }
682         }
683
684         return 0;
685 }
686
687 bool
688 FaderPort::connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn)
689 {
690         if (!_input_port || !_output_port) {
691                 return false;
692         }
693
694         string ni = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (boost::shared_ptr<ARDOUR::Port>(_input_port)->name());
695         string no = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (boost::shared_ptr<ARDOUR::Port>(_output_port)->name());
696
697         if (ni == name1 || ni == name2) {
698                 if (yn) {
699                         connection_state |= InputConnected;
700                 } else {
701                         connection_state &= ~InputConnected;
702                 }
703         } else if (no == name1 || no == name2) {
704                 if (yn) {
705                         connection_state |= OutputConnected;
706                 } else {
707                         connection_state &= ~OutputConnected;
708                 }
709         } else {
710                 /* not our ports */
711                 return false;
712         }
713
714         if ((connection_state & (InputConnected|OutputConnected)) == (InputConnected|OutputConnected)) {
715
716                 /* XXX this is a horrible hack. Without a short sleep here,
717                    something prevents the device wakeup messages from being
718                    sent and/or the responses from being received.
719                 */
720
721                 g_usleep (100000);
722                 connected ();
723
724         } else {
725                 DEBUG_TRACE (DEBUG::FaderPort, "Device disconnected (input or output or both) or not yet fully connected\n");
726                 _device_active = false;
727         }
728
729         ConnectionChange (); /* emit signal for our GUI */
730
731         return true; /* connection status changed */
732 }
733
734 void
735 FaderPort::connected ()
736 {
737         DEBUG_TRACE (DEBUG::FaderPort, "connection status changed\n");
738
739         start_midi_handling ();
740
741         /* send device inquiry */
742
743         MIDI::byte buf[6];
744
745         buf[0] = 0xf0;
746         buf[1] = 0x7e;
747         buf[2] = 0x7f;
748         buf[3] = 0x06;
749         buf[4] = 0x01;
750         buf[5] = 0xf7;
751
752         _output_port->write (buf, 6, 0);
753 }
754
755 void
756 FaderPort::Button::invoke (FaderPort::ButtonState bs, bool press)
757 {
758         DEBUG_TRACE (DEBUG::FaderPort, string_compose ("invoke button %1 for %2 state %3%4%5\n", id, (press ? "press":"release"), hex, bs, dec));
759
760         ToDoMap::iterator x;
761
762         if (press) {
763                 if ((x = on_press.find (bs)) == on_press.end()) {
764                         DEBUG_TRACE (DEBUG::FaderPort, string_compose ("no press action for button %1 state %2%3\%4\n", id, hex, bs, dec));
765                         return;
766                 }
767         } else {
768                 if ((x = on_release.find (bs)) == on_release.end()) {
769                         DEBUG_TRACE (DEBUG::FaderPort, string_compose ("no release action for button %1 state %2%3\%4\n", id, hex, bs, dec));
770                         return;
771                 }
772         }
773
774         switch (x->second.type) {
775         case NamedAction:
776                 if (!x->second.action_name.empty()) {
777                         fp.access_action (x->second.action_name);
778                 }
779                 break;
780         case InternalFunction:
781                 if (x->second.function) {
782                         x->second.function ();
783                 }
784         }
785 }
786
787 void
788 FaderPort::Button::set_action (string const& name, bool when_pressed, FaderPort::ButtonState bs)
789 {
790         ToDo todo;
791
792         todo.type = NamedAction;
793
794         if (when_pressed) {
795                 if (name.empty()) {
796                         on_press.erase (bs);
797                 } else {
798                         DEBUG_TRACE (DEBUG::FaderPort, string_compose ("set button %1 to action %2 on press + %3%4%5\n", id, name, bs));
799                         todo.action_name = name;
800                         on_press[bs] = todo;
801                 }
802         } else {
803                 if (name.empty()) {
804                         on_release.erase (bs);
805                 } else {
806                         DEBUG_TRACE (DEBUG::FaderPort, string_compose ("set button %1 to action %2 on release + %3%4%5\n", id, name, bs));
807                         todo.action_name = name;
808                         on_release[bs] = todo;
809                 }
810         }
811 }
812
813 string
814 FaderPort::Button::get_action (bool press, FaderPort::ButtonState bs)
815 {
816         ToDoMap::iterator x;
817
818         if (press) {
819                 if ((x = on_press.find (bs)) == on_press.end()) {
820                         return string();
821                 }
822                 if (x->second.type != NamedAction) {
823                         return string ();
824                 }
825                 return x->second.action_name;
826         } else {
827                 if ((x = on_release.find (bs)) == on_release.end()) {
828                         return string();
829                 }
830                 if (x->second.type != NamedAction) {
831                         return string ();
832                 }
833                 return x->second.action_name;
834         }
835 }
836
837 void
838 FaderPort::Button::set_action (boost::function<void()> f, bool when_pressed, FaderPort::ButtonState bs)
839 {
840         ToDo todo;
841         todo.type = InternalFunction;
842
843         if (when_pressed) {
844                 todo.function = f;
845                 on_press[bs] = todo;
846         } else {
847                 todo.function = f;
848                 on_release[bs] = todo;
849         }
850 }
851
852 void
853 FaderPort::Button::set_led_state (boost::shared_ptr<MIDI::Port> port, int onoff, bool force)
854 {
855         if (!force && (led_on == (bool) onoff)) {
856                 /* nothing to do */
857                 return;
858         }
859
860         if (out < 0) {
861                 /* fader button ID - no LED */
862                 return;
863         }
864
865         MIDI::byte buf[3];
866         buf[0] = 0xa0;
867         buf[1] = out;
868         buf[2] = onoff ? 1 : 0;
869         port->write (buf, 3, 0);
870         led_on = (onoff ? true : false);
871 }
872
873 int
874 FaderPort::Button::set_state (XMLNode const& node)
875 {
876         const XMLProperty* prop = node.property ("id");
877         if (!prop) {
878                 return -1;
879         }
880
881         int xid = atoi (prop->value());
882         if (xid != id) {
883                 return -1;
884         }
885
886         typedef pair<string,FaderPort::ButtonState> state_pair_t;
887         vector<state_pair_t> state_pairs;
888
889         state_pairs.push_back (make_pair (string ("plain"), ButtonState (0)));
890         state_pairs.push_back (make_pair (string ("shift"), ShiftDown));
891         state_pairs.push_back (make_pair (string ("long"), LongPress));
892
893         on_press.clear ();
894         on_release.clear ();
895
896         for (vector<state_pair_t>::const_iterator sp = state_pairs.begin(); sp != state_pairs.end(); ++sp) {
897                 string propname;
898
899                 propname = sp->first + X_("-press");
900                 if ((prop = node.property (propname)) != 0) {
901                         set_action (prop->value(), true, sp->second);
902                 }
903
904                 propname = sp->first + X_("-release");
905                 if ((prop = node.property (propname)) != 0) {
906                         set_action (prop->value(), false, sp->second);
907                 }
908         }
909
910         return 0;
911 }
912
913 XMLNode&
914 FaderPort::Button::get_state () const
915 {
916         XMLNode* node = new XMLNode (X_("Button"));
917         char buf[16];
918         snprintf (buf, sizeof (buf), "%d", id);
919
920         node->add_property (X_("id"), buf);
921
922         ToDoMap::const_iterator x;
923         ToDo null;
924         null.type = NamedAction;
925
926         typedef pair<string,FaderPort::ButtonState> state_pair_t;
927         vector<state_pair_t> state_pairs;
928
929         state_pairs.push_back (make_pair (string ("plain"), ButtonState (0)));
930         state_pairs.push_back (make_pair (string ("shift"), ShiftDown));
931         state_pairs.push_back (make_pair (string ("long"), LongPress));
932
933         for (vector<state_pair_t>::const_iterator sp = state_pairs.begin(); sp != state_pairs.end(); ++sp) {
934                 if ((x = on_press.find (sp->second)) != on_press.end()) {
935                         if (x->second.type == NamedAction) {
936                                 node->add_property (string (sp->first + X_("-press")).c_str(), x->second.action_name);
937                         }
938                 }
939
940                 if ((x = on_release.find (sp->second)) != on_release.end()) {
941                         if (x->second.type == NamedAction) {
942                                 node->add_property (string (sp->first + X_("-release")).c_str(), x->second.action_name);
943                         }
944                 }
945         }
946
947         return *node;
948 }
949
950 void
951 FaderPort::gui_track_selection_changed (RouteNotificationListPtr routes)
952 {
953         boost::shared_ptr<Route> r;
954
955         if (!routes->empty()) {
956                 r = routes->front().lock();
957         }
958
959         set_current_route (r);
960 }
961
962 void
963 FaderPort::drop_current_route ()
964 {
965         if (_current_route) {
966                 if (_current_route == session->monitor_out()) {
967                         set_current_route (session->master_out());
968                 } else {
969                         set_current_route (boost::shared_ptr<Route>());
970                 }
971         }
972 }
973
974 void
975 FaderPort::set_current_route (boost::shared_ptr<Route> r)
976 {
977         route_connections.drop_connections ();
978
979         _current_route = r;
980
981         /* turn this off. It will be turned on back on in use_master() or
982            use_monitor() as appropriate.
983         */
984         get_button(Output).set_led_state (_output_port, false);
985
986         if (_current_route) {
987                 _current_route->DropReferences.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::drop_current_route, this), this);
988
989                 _current_route->mute_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::map_mute, this, _1), this);
990                 _current_route->solo_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::map_solo, this, _1, _2, _3), this);
991                 _current_route->listen_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::map_listen, this, _1, _2), this);
992
993                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (_current_route);
994                 if (t) {
995                         t->RecordEnableChanged.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::map_recenable, this), this);
996                 }
997
998                 boost::shared_ptr<AutomationControl> control = _current_route->gain_control ();
999                 if (control) {
1000                         control->Changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::map_gain, this), this);
1001                 }
1002
1003                 boost::shared_ptr<MonitorProcessor> mp = _current_route->monitor_control();
1004                 if (mp) {
1005                         mp->cut_control()->Changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::map_cut, this), this);
1006                 }
1007         }
1008
1009         //ToDo: subscribe to the fader automation modes so we can light the LEDs
1010
1011         map_route_state ();
1012 }
1013
1014 void
1015 FaderPort::map_cut ()
1016 {
1017         boost::shared_ptr<MonitorProcessor> mp = _current_route->monitor_control();
1018
1019         if (mp) {
1020                 bool yn = mp->cut_all ();
1021                 get_button (Mute).set_led_state (_output_port, yn);
1022                 if (yn) {
1023                         blinkers.push_back (Mute);
1024                 } else {
1025                         blinkers.remove (Mute);
1026                 }
1027         } else {
1028                 blinkers.remove (Mute);
1029         }
1030 }
1031
1032 void
1033 FaderPort::map_mute (void*)
1034 {
1035         get_button (Mute).set_led_state (_output_port, _current_route->muted());
1036 }
1037
1038 void
1039 FaderPort::map_solo (bool, void*, bool)
1040 {
1041         get_button (Solo).set_led_state (_output_port, _current_route->soloed() || _current_route->listening_via_monitor());
1042 }
1043
1044 void
1045 FaderPort::map_listen (void*, bool)
1046 {
1047         get_button (Solo).set_led_state (_output_port, _current_route->listening_via_monitor());
1048 }
1049
1050 void
1051 FaderPort::map_recenable ()
1052 {
1053         boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (_current_route);
1054         if (t) {
1055                 get_button (Rec).set_led_state (_output_port, t->record_enabled());
1056         } else {
1057                 get_button (Rec).set_led_state (_output_port, false);
1058         }
1059 }
1060
1061 void
1062 FaderPort::map_gain ()
1063 {
1064         if (fader_is_touched) {
1065                 /* Do not send fader moves while the user is touching the fader */
1066                 return;
1067         }
1068
1069         if (!_current_route) {
1070                 return;
1071         }
1072
1073         boost::shared_ptr<AutomationControl> control = _current_route->gain_control ();
1074         double val;
1075
1076         if (!control) {
1077                 val = 0.0;
1078         } else {
1079                 val = control->internal_to_interface (control->get_value ());
1080         }
1081
1082         /* Faderport sends fader position with range 0..16384 (though some of
1083          * the least-significant bits at the top end are missing - it may only
1084          * get to 1636X or so).
1085          *
1086          * But ... position must be sent in the range 0..1023.
1087          *
1088          * Thanks, Obama.
1089          */
1090
1091         int ival = (int) lrintf (val * 1023.0);
1092
1093         /* MIDI normalization requires that we send two separate messages here,
1094          * not one single 6 byte one.
1095          */
1096
1097         MIDI::byte buf[3];
1098
1099         buf[0] = 0xb0;
1100         buf[1] = 0x0;
1101         buf[2] = ival >> 7;
1102
1103         _output_port->write (buf, 3, 0);
1104
1105         buf[1] = 0x20;
1106         buf[2] = ival & 0x7f;
1107
1108         _output_port->write (buf, 3, 0);
1109 }
1110
1111 void
1112 FaderPort::map_route_state ()
1113 {
1114         if (!_current_route) {
1115                 get_button (Mute).set_led_state (_output_port, false);
1116                 get_button (Solo).set_led_state (_output_port, false);
1117                 get_button (Rec).set_led_state (_output_port, false);
1118                 blinkers.remove (Mute);
1119                 blinkers.remove (Solo);
1120         } else {
1121                 /* arguments to these map_*() methods are all ignored */
1122                 map_mute (0);
1123                 map_solo (false, 0, false);
1124                 map_recenable ();
1125                 map_gain ();
1126                 map_cut ();
1127         }
1128 }
1129
1130 boost::shared_ptr<Port>
1131 FaderPort::output_port()
1132 {
1133         return _output_port;
1134 }
1135
1136 boost::shared_ptr<Port>
1137 FaderPort::input_port()
1138 {
1139         return _input_port;
1140 }
1141
1142 void
1143 FaderPort::set_action (ButtonID id, std::string const& action_name, bool on_press, ButtonState bs)
1144 {
1145         get_button(id).set_action (action_name, on_press, bs);
1146 }
1147
1148 string
1149 FaderPort::get_action (ButtonID id, bool press, ButtonState bs)
1150 {
1151         return get_button(id).get_action (press, bs);
1152 }