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