Use correct property name in generic MIDI surface
[ardour.git] / libs / surfaces / generic_midi / generic_midi_control_protocol.cc
1 /*
2     Copyright (C) 2006 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 <stdint.h>
21
22 #include <sstream>
23 #include <algorithm>
24
25 #include <glibmm/fileutils.h>
26 #include <glibmm/miscutils.h>
27
28 #include "pbd/error.h"
29 #include "pbd/failed_constructor.h"
30 #include "pbd/file_utils.h"
31 #include "pbd/types_convert.h"
32 #include "pbd/xml++.h"
33 #include "pbd/compose.h"
34
35 #include "midi++/port.h"
36
37 #include "ardour/async_midi_port.h"
38 #include "ardour/audioengine.h"
39 #include "ardour/audioengine.h"
40 #include "ardour/controllable_descriptor.h"
41 #include "ardour/filesystem_paths.h"
42 #include "ardour/session.h"
43 #include "ardour/midi_ui.h"
44 #include "ardour/rc_configuration.h"
45 #include "ardour/midiport_manager.h"
46 #include "ardour/debug.h"
47
48 #include "generic_midi_control_protocol.h"
49 #include "midicontrollable.h"
50 #include "midifunction.h"
51 #include "midiaction.h"
52
53 using namespace ARDOUR;
54 using namespace PBD;
55 using namespace std;
56
57 #include "pbd/i18n.h"
58
59 #define midi_ui_context() MidiControlUI::instance() /* a UICallback-derived object that specifies the event loop for signal handling */
60
61 GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s)
62         : ControlProtocol (s, _("Generic MIDI"))
63         , connection_state (ConnectionState (0))
64         , _motorised (false)
65         , _threshold (10)
66         , gui (0)
67 {
68         _input_port = boost::dynamic_pointer_cast<AsyncMIDIPort> (s.midi_input_port ());
69         _output_port = boost::dynamic_pointer_cast<AsyncMIDIPort> (s.midi_output_port ());
70
71         _input_bundle.reset (new ARDOUR::Bundle (_("Generic MIDI Control In"), true));
72         _output_bundle.reset (new ARDOUR::Bundle (_("Generic MIDI Control Out"), false));
73
74         _input_bundle->add_channel (
75                 boost::static_pointer_cast<MidiPort>(_input_port)->name(),
76                 ARDOUR::DataType::MIDI,
77                 session->engine().make_port_name_non_relative (boost::static_pointer_cast<MidiPort>(_input_port)->name())
78                 );
79
80         _output_bundle->add_channel (
81                 boost::static_pointer_cast<MidiPort>(_output_port)->name(),
82                 ARDOUR::DataType::MIDI,
83                 session->engine().make_port_name_non_relative (boost::static_pointer_cast<MidiPort>(_output_port)->name())
84                 );
85
86         session->BundleAddedOrRemoved ();
87
88         do_feedback = false;
89         _feedback_interval = 10000; // microseconds
90         last_feedback_time = 0;
91
92         _current_bank = 0;
93         _bank_size = 0;
94
95         /* these signals are emitted by the MidiControlUI's event loop thread
96          * and we may as well handle them right there in the same the same
97          * thread
98          */
99
100         Controllable::StartLearning.connect_same_thread (*this, boost::bind (&GenericMidiControlProtocol::start_learning, this, _1));
101         Controllable::StopLearning.connect_same_thread (*this, boost::bind (&GenericMidiControlProtocol::stop_learning, this, _1));
102         Controllable::CreateBinding.connect_same_thread (*this, boost::bind (&GenericMidiControlProtocol::create_binding, this, _1, _2, _3));
103         Controllable::DeleteBinding.connect_same_thread (*this, boost::bind (&GenericMidiControlProtocol::delete_binding, this, _1));
104
105         /* this signal is emitted by the process() callback, and if
106          * send_feedback() is going to do anything, it should do it in the
107          * context of the process() callback itself.
108          */
109
110         Session::SendFeedback.connect_same_thread (*this, boost::bind (&GenericMidiControlProtocol::send_feedback, this));
111         //Session::SendFeedback.connect (*this, MISSING_INVALIDATOR, boost::bind (&GenericMidiControlProtocol::send_feedback, this), midi_ui_context());;
112
113         /* this one is cross-thread */
114
115         PresentationInfo::Change.connect (*this, MISSING_INVALIDATOR, boost::bind (&GenericMidiControlProtocol::reset_controllables, this), midi_ui_context());
116
117         /* Catch port connections and disconnections (cross-thread) */
118         ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connection, MISSING_INVALIDATOR,
119                                                                               boost::bind (&GenericMidiControlProtocol::connection_handler, this, _1, _2, _3, _4, _5),
120                                                                               midi_ui_context());
121
122         reload_maps ();
123 }
124
125 GenericMidiControlProtocol::~GenericMidiControlProtocol ()
126 {
127         drop_all ();
128         tear_down_gui ();
129 }
130
131 list<boost::shared_ptr<ARDOUR::Bundle> >
132 GenericMidiControlProtocol::bundles ()
133 {
134         list<boost::shared_ptr<ARDOUR::Bundle> > b;
135
136         if (_input_bundle) {
137                 b.push_back (_input_bundle);
138                 b.push_back (_output_bundle);
139         }
140
141         return b;
142 }
143
144
145 static const char * const midimap_env_variable_name = "ARDOUR_MIDIMAPS_PATH";
146 static const char* const midi_map_dir_name = "midi_maps";
147 static const char* const midi_map_suffix = ".map";
148
149 Searchpath
150 system_midi_map_search_path ()
151 {
152         bool midimap_path_defined = false;
153         std::string spath_env (Glib::getenv (midimap_env_variable_name, midimap_path_defined));
154
155         if (midimap_path_defined) {
156                 return spath_env;
157         }
158
159         Searchpath spath (ardour_data_search_path());
160         spath.add_subdirectory_to_paths(midi_map_dir_name);
161         return spath;
162 }
163
164 static std::string
165 user_midi_map_directory ()
166 {
167         return Glib::build_filename (user_config_directory(), midi_map_dir_name);
168 }
169
170 static bool
171 midi_map_filter (const string &str, void* /*arg*/)
172 {
173         return (str.length() > strlen(midi_map_suffix) &&
174                 str.find (midi_map_suffix) == (str.length() - strlen (midi_map_suffix)));
175 }
176
177 void
178 GenericMidiControlProtocol::reload_maps ()
179 {
180         vector<string> midi_maps;
181         Searchpath spath (system_midi_map_search_path());
182         spath += user_midi_map_directory ();
183
184         find_files_matching_filter (midi_maps, spath, midi_map_filter, 0, false, true);
185
186         if (midi_maps.empty()) {
187                 cerr << "No MIDI maps found using " << spath.to_string() << endl;
188                 return;
189         }
190
191         for (vector<string>::iterator i = midi_maps.begin(); i != midi_maps.end(); ++i) {
192                 string fullpath = *i;
193
194                 XMLTree tree;
195
196                 if (!tree.read (fullpath.c_str())) {
197                         continue;
198                 }
199
200                 MapInfo mi;
201
202                 std::string str;
203                 if (!tree.root()->get_property ("name", str)) {
204                         continue;
205                 }
206
207                 mi.name = str;
208                 mi.path = fullpath;
209
210                 map_info.push_back (mi);
211         }
212 }
213
214 void
215 GenericMidiControlProtocol::drop_all ()
216 {
217         DEBUG_TRACE (DEBUG::GenericMidi, "Drop all bindings\n");
218         Glib::Threads::Mutex::Lock lm (pending_lock);
219         Glib::Threads::Mutex::Lock lm2 (controllables_lock);
220
221         for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
222                 delete *i;
223         }
224         controllables.clear ();
225
226         for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
227                 (*i)->connection.disconnect();
228                 if ((*i)->own_mc) {
229                         delete (*i)->mc;
230                 }
231                 delete *i;
232         }
233         pending_controllables.clear ();
234
235         for (MIDIFunctions::iterator i = functions.begin(); i != functions.end(); ++i) {
236                 delete *i;
237         }
238         functions.clear ();
239
240         for (MIDIActions::iterator i = actions.begin(); i != actions.end(); ++i) {
241                 delete *i;
242         }
243         actions.clear ();
244 }
245
246 void
247 GenericMidiControlProtocol::drop_bindings ()
248 {
249         DEBUG_TRACE (DEBUG::GenericMidi, "Drop bindings, leave learned\n");
250         Glib::Threads::Mutex::Lock lm2 (controllables_lock);
251
252         for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ) {
253                 if (!(*i)->learned()) {
254                         delete *i;
255                         i = controllables.erase (i);
256                 } else {
257                         ++i;
258                 }
259         }
260
261         for (MIDIFunctions::iterator i = functions.begin(); i != functions.end(); ++i) {
262                 delete *i;
263         }
264         functions.clear ();
265
266         _current_binding = "";
267         _bank_size = 0;
268         _current_bank = 0;
269 }
270
271 int
272 GenericMidiControlProtocol::set_active (bool /*yn*/)
273 {
274         /* nothing to do here: the MIDI UI thread in libardour handles all our
275            I/O needs.
276         */
277         return 0;
278 }
279
280 void
281 GenericMidiControlProtocol::set_feedback_interval (microseconds_t ms)
282 {
283         _feedback_interval = ms;
284 }
285
286 void
287 GenericMidiControlProtocol::send_feedback ()
288 {
289         /* This is executed in RT "process" context", so no blocking calls
290          */
291
292         if (!do_feedback) {
293                 return;
294         }
295
296         microseconds_t now = get_microseconds ();
297
298         if (last_feedback_time != 0) {
299                 if ((now - last_feedback_time) < _feedback_interval) {
300                         return;
301                 }
302         }
303
304         _send_feedback ();
305
306         last_feedback_time = now;
307 }
308
309 void
310 GenericMidiControlProtocol::_send_feedback ()
311 {
312         /* This is executed in RT "process" context", so no blocking calls
313          */
314
315         const int32_t bufsize = 16 * 1024; /* XXX too big */
316         MIDI::byte buf[bufsize];
317         int32_t bsize = bufsize;
318
319         /* XXX: due to bugs in some ALSA / JACK MIDI bridges, we have to do separate
320            writes for each controllable here; if we send more than one MIDI message
321            in a single jack_midi_event_write then some bridges will only pass the
322            first on to ALSA.
323         */
324
325         Glib::Threads::Mutex::Lock lm (controllables_lock, Glib::Threads::TRY_LOCK);
326         if (!lm.locked ()) {
327                 return;
328         }
329
330         for (MIDIControllables::iterator r = controllables.begin(); r != controllables.end(); ++r) {
331                 MIDI::byte* end = (*r)->write_feedback (buf, bsize);
332                 if (end != buf) {
333                         _output_port->write (buf, (int32_t) (end - buf), 0);
334                 }
335         }
336 }
337
338 bool
339 GenericMidiControlProtocol::start_learning (Controllable* c)
340 {
341         if (c == 0) {
342                 return false;
343         }
344
345         Glib::Threads::Mutex::Lock lm2 (controllables_lock);
346         DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("Learn binding: Controlable number: %1\n", c));
347
348         /* drop any existing mappings for the same controllable for which
349          * learning has just started.
350          */
351
352         MIDIControllables::iterator tmp;
353         for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ) {
354                 tmp = i;
355                 ++tmp;
356                 if ((*i)->get_controllable() == c) {
357                         delete (*i);
358                         controllables.erase (i);
359                 }
360                 i = tmp;
361         }
362
363         /* check pending controllables (those for which a learn is underway) to
364          * see if it is for the same one for which learning has just started.
365          */
366
367         {
368                 Glib::Threads::Mutex::Lock lm (pending_lock);
369
370                 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ) {
371                         if (((*i)->mc)->get_controllable() == c) {
372                                 (*i)->connection.disconnect();
373                                 if ((*i)->own_mc) {
374                                         delete (*i)->mc;
375                                 }
376                                 delete *i;
377                                 i = pending_controllables.erase (i);
378                         } else {
379                                 ++i;
380                         }
381                 }
382         }
383
384         MIDIControllable* mc = 0;
385         bool own_mc = false;
386
387         for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
388                 if ((*i)->get_controllable() && ((*i)->get_controllable()->id() == c->id())) {
389                         mc = *i;
390                         break;
391                 }
392         }
393
394         if (!mc) {
395                 mc = new MIDIControllable (this, *_input_port->parser(), *c, false);
396                 own_mc = true;
397         }
398
399         /* stuff the new controllable into pending */
400
401         {
402                 Glib::Threads::Mutex::Lock lm (pending_lock);
403
404                 MIDIPendingControllable* element = new MIDIPendingControllable (mc, own_mc);
405                 c->LearningFinished.connect_same_thread (element->connection, boost::bind (&GenericMidiControlProtocol::learning_stopped, this, mc));
406
407                 pending_controllables.push_back (element);
408         }
409         mc->learn_about_external_control ();
410         return true;
411 }
412
413 void
414 GenericMidiControlProtocol::learning_stopped (MIDIControllable* mc)
415 {
416         Glib::Threads::Mutex::Lock lm (pending_lock);
417         Glib::Threads::Mutex::Lock lm2 (controllables_lock);
418
419         for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ) {
420                 if ( (*i)->mc == mc) {
421                         (*i)->connection.disconnect();
422                         delete *i;
423                         i = pending_controllables.erase(i);
424                 } else {
425                         ++i;
426                 }
427         }
428
429         /* add the controllable for which learning stopped to our list of
430          * controllables
431          */
432
433         controllables.push_back (mc);
434 }
435
436 void
437 GenericMidiControlProtocol::stop_learning (Controllable* c)
438 {
439         Glib::Threads::Mutex::Lock lm (pending_lock);
440         Glib::Threads::Mutex::Lock lm2 (controllables_lock);
441         MIDIControllable* dptr = 0;
442
443         /* learning timed out, and we've been told to consider this attempt to learn to be cancelled. find the
444            relevant MIDIControllable and remove it from the pending list.
445         */
446
447         for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
448                 if (((*i)->mc)->get_controllable() == c) {
449                         (*i)->mc->stop_learning ();
450                         dptr = (*i)->mc;
451                         (*i)->connection.disconnect();
452
453                         delete *i;
454                         pending_controllables.erase (i);
455                         break;
456                 }
457         }
458
459         delete dptr;
460 }
461
462 void
463 GenericMidiControlProtocol::delete_binding (PBD::Controllable* control)
464 {
465         if (control != 0) {
466                 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
467
468                 for (MIDIControllables::iterator iter = controllables.begin(); iter != controllables.end();) {
469                         MIDIControllable* existingBinding = (*iter);
470
471                         if (control == (existingBinding->get_controllable())) {
472                                 delete existingBinding;
473                                 iter = controllables.erase (iter);
474                         } else {
475                                 ++iter;
476                         }
477
478                 }
479         }
480 }
481
482 // This next function seems unused
483 void
484 GenericMidiControlProtocol::create_binding (PBD::Controllable* control, int pos, int control_number)
485 {
486         if (control != NULL) {
487                 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
488
489                 MIDI::channel_t channel = (pos & 0xf);
490                 MIDI::byte value = control_number;
491
492                 // Create a MIDIControllable
493                 MIDIControllable* mc = new MIDIControllable (this, *_input_port->parser(), *control, false);
494
495                 // Remove any old binding for this midi channel/type/value pair
496                 // Note:  can't use delete_binding() here because we don't know the specific controllable we want to remove, only the midi information
497                 for (MIDIControllables::iterator iter = controllables.begin(); iter != controllables.end();) {
498                         MIDIControllable* existingBinding = (*iter);
499
500                         if ((existingBinding->get_control_channel() & 0xf ) == channel &&
501                             existingBinding->get_control_additional() == value &&
502                             (existingBinding->get_control_type() & 0xf0 ) == MIDI::controller) {
503
504                                 delete existingBinding;
505                                 iter = controllables.erase (iter);
506                         } else {
507                                 ++iter;
508                         }
509
510                 }
511
512                 // Update the MIDI Controllable based on the the pos param
513                 // Here is where a table lookup for user mappings could go; for now we'll just wing it...
514                 mc->bind_midi(channel, MIDI::controller, value);
515                 DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("Create binding: Channel: %1 Controller: %2 Value: %3 \n", channel, MIDI::controller, value));
516                 controllables.push_back (mc);
517         }
518 }
519
520 void
521 GenericMidiControlProtocol::check_used_event (int pos, int control_number)
522 {
523         Glib::Threads::Mutex::Lock lm2 (controllables_lock);
524
525         MIDI::channel_t channel = (pos & 0xf);
526         MIDI::byte value = control_number;
527
528         DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("checking for used event: Channel: %1 Controller: %2 value: %3\n", (int) channel, (pos & 0xf0), (int) value));
529
530         // Remove any old binding for this midi channel/type/value pair
531         // Note:  can't use delete_binding() here because we don't know the specific controllable we want to remove, only the midi information
532         for (MIDIControllables::iterator iter = controllables.begin(); iter != controllables.end();) {
533                 MIDIControllable* existingBinding = (*iter);
534                 if ( (existingBinding->get_control_type() & 0xf0 ) == (pos & 0xf0) && (existingBinding->get_control_channel() & 0xf ) == channel ) {
535                         if ( ((int) existingBinding->get_control_additional() == (int) value) || ((pos & 0xf0) == MIDI::pitchbend)) {
536                                 DEBUG_TRACE (DEBUG::GenericMidi, "checking: found match, delete old binding.\n");
537                                 delete existingBinding;
538                                 iter = controllables.erase (iter);
539                         } else {
540                                 ++iter;
541                         }
542                 } else {
543                         ++iter;
544                 }
545         }
546
547         for (MIDIFunctions::iterator iter = functions.begin(); iter != functions.end();) {
548                 MIDIFunction* existingBinding = (*iter);
549                 if ( (existingBinding->get_control_type() & 0xf0 ) == (pos & 0xf0) && (existingBinding->get_control_channel() & 0xf ) == channel ) {
550                         if ( ((int) existingBinding->get_control_additional() == (int) value) || ((pos & 0xf0) == MIDI::pitchbend)) {
551                                 DEBUG_TRACE (DEBUG::GenericMidi, "checking: found match, delete old binding.\n");
552                                 delete existingBinding;
553                                 iter = functions.erase (iter);
554                         } else {
555                                 ++iter;
556                         }
557                 } else {
558                         ++iter;
559                 }
560         }
561
562         for (MIDIActions::iterator iter = actions.begin(); iter != actions.end();) {
563                 MIDIAction* existingBinding = (*iter);
564                 if ( (existingBinding->get_control_type() & 0xf0 ) == (pos & 0xf0) && (existingBinding->get_control_channel() & 0xf ) == channel ) {
565                         if ( ((int) existingBinding->get_control_additional() == (int) value) || ((pos & 0xf0) == MIDI::pitchbend)) {
566                                 DEBUG_TRACE (DEBUG::GenericMidi, "checking: found match, delete old binding.\n");
567                                 delete existingBinding;
568                                 iter = actions.erase (iter);
569                         } else {
570                                 ++iter;
571                         }
572                 } else {
573                         ++iter;
574                 }
575         }
576
577 }
578
579 XMLNode&
580 GenericMidiControlProtocol::get_state ()
581 {
582         XMLNode& node (ControlProtocol::get_state());
583
584         node.set_property (X_("feedback-interval"), _feedback_interval);
585         node.set_property (X_("threshold"), _threshold);
586         node.set_property (X_("motorized"), _motorised);
587
588         if (!_current_binding.empty()) {
589                 node.set_property ("binding", _current_binding);
590         }
591
592         XMLNode* children = new XMLNode (X_("Controls"));
593
594         node.add_child_nocopy (*children);
595
596         Glib::Threads::Mutex::Lock lm2 (controllables_lock);
597         for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
598
599                 /* we don't care about bindings that come from a bindings map, because
600                    they will all be reset/recreated when we load the relevant bindings
601                    file.
602                 */
603
604                 if ((*i)->get_controllable() && (*i)->learned()) {
605                         children->add_child_nocopy ((*i)->get_state());
606                 }
607         }
608
609         return node;
610 }
611
612 int
613 GenericMidiControlProtocol::set_state (const XMLNode& node, int version)
614 {
615         XMLNodeList nlist;
616         XMLNodeConstIterator niter;
617
618         if (ControlProtocol::set_state (node, version)) {
619                 return -1;
620         }
621
622         if (!node.get_property ("feedback-interval", _feedback_interval)) {
623                 _feedback_interval = 10000;
624         }
625
626         if (!node.get_property ("threshold", _threshold)) {
627                 _threshold = 10;
628         }
629
630         if (!node.get_property ("motorized", _motorised)) {
631                 _motorised = false;
632         }
633
634         boost::shared_ptr<Controllable> c;
635
636         {
637                 Glib::Threads::Mutex::Lock lm (pending_lock);
638                 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
639                         (*i)->connection.disconnect();
640                         if ((*i)->own_mc) {
641                                 delete (*i)->mc;
642                         }
643                         delete *i;
644                 }
645                 pending_controllables.clear ();
646         }
647
648         std::string str;
649         // midi map has to be loaded first so learned binding can go on top
650         if (node.get_property ("binding", str)) {
651                 for (list<MapInfo>::iterator x = map_info.begin(); x != map_info.end(); ++x) {
652                         if (str == (*x).name) {
653                                 load_bindings ((*x).path);
654                                 break;
655                         }
656                 }
657         }
658
659         /* Load up specific bindings from the
660          * <Controls><MidiControllable>...</MidiControllable><Controls> section
661          */
662
663         {
664                 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
665                 nlist = node.children(); // "Controls"
666
667                 if (!nlist.empty()) {
668                         nlist = nlist.front()->children(); // "MIDIControllable" ...
669
670                         if (!nlist.empty()) {
671                                 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
672
673                                         PBD::ID id;
674                                         if ((*niter)->get_property ("id", id)) {
675
676                                                 DEBUG_TRACE (DEBUG::GenericMidi, string_compose ("Relearned binding for session: Control ID: %1\n", id.to_s()));
677                                                 Controllable* c = Controllable::by_id (id);
678
679                                                 if (c) {
680                                                         MIDIControllable* mc = new MIDIControllable (this, *_input_port->parser(), *c, false);
681
682                                                         if (mc->set_state (**niter, version) == 0) {
683                                                                 controllables.push_back (mc);
684                                                         } else {
685                                                                 warning << string_compose ("Generic MIDI control: Failed to set state for Control ID: %1\n", id.to_s());
686                                                                 delete mc;
687                                                         }
688
689                                                 } else {
690                                                         warning << string_compose (
691                                                                 _("Generic MIDI control: controllable %1 not found in session (ignored)"),
692                                                                 id.to_s()) << endmsg;
693                                                 }
694                                         }
695                                 }
696                         }
697                 }
698         }
699
700         return 0;
701 }
702
703 int
704 GenericMidiControlProtocol::set_feedback (bool yn)
705 {
706         do_feedback = yn;
707         last_feedback_time = 0;
708         return 0;
709 }
710
711 bool
712 GenericMidiControlProtocol::get_feedback () const
713 {
714         return do_feedback;
715 }
716
717 int
718 GenericMidiControlProtocol::load_bindings (const string& xmlpath)
719 {
720         DEBUG_TRACE (DEBUG::GenericMidi, "Load bindings: Reading midi map\n");
721         XMLTree state_tree;
722
723         if (!state_tree.read (xmlpath.c_str())) {
724                 error << string_compose(_("Could not understand MIDI bindings file %1"), xmlpath) << endmsg;
725                 return -1;
726         }
727
728         XMLNode* root = state_tree.root();
729
730         if (root->name() != X_("ArdourMIDIBindings")) {
731                 error << string_compose (_("MIDI Bindings file %1 is not really a MIDI bindings file"), xmlpath) << endmsg;
732                 return -1;
733         }
734
735         const XMLProperty* prop;
736
737         if ((prop = root->property ("version")) == 0) {
738                 return -1;
739         }
740
741         const XMLNodeList& children (root->children());
742         XMLNodeConstIterator citer;
743         XMLNodeConstIterator gciter;
744
745         MIDIControllable* mc;
746
747         drop_all ();
748
749         DEBUG_TRACE (DEBUG::GenericMidi, "Loading bindings\n");
750         for (citer = children.begin(); citer != children.end(); ++citer) {
751
752                 if ((*citer)->name() == "DeviceInfo") {
753
754                         if ((*citer)->get_property ("bank-size", _bank_size)) {
755                                 _current_bank = 0;
756                         }
757
758                         if (!(*citer)->get_property ("motorized", _motorised)) {
759                                 _motorised = false;
760                         }
761
762                         if (!(*citer)->get_property ("threshold", _threshold)) {
763                                 _threshold = 10;
764                         }
765                 }
766
767                 if ((*citer)->name() == "Binding") {
768                         const XMLNode* child = *citer;
769
770                         if (child->property ("uri")) {
771                                 /* controllable */
772
773                                 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
774                                 if ((mc = create_binding (*child)) != 0) {
775                                         controllables.push_back (mc);
776                                 }
777
778                         } else if (child->property ("function")) {
779
780                                 /* function */
781                                 MIDIFunction* mf;
782
783                                 if ((mf = create_function (*child)) != 0) {
784                                         functions.push_back (mf);
785                                 }
786
787                         } else if (child->property ("action")) {
788                                 MIDIAction* ma;
789
790                                 if ((ma = create_action (*child)) != 0) {
791                                         actions.push_back (ma);
792                                 }
793                         }
794                 }
795         }
796
797         if ((prop = root->property ("name")) != 0) {
798                 _current_binding = prop->value ();
799         }
800
801         reset_controllables ();
802
803         return 0;
804 }
805
806 MIDIControllable*
807 GenericMidiControlProtocol::create_binding (const XMLNode& node)
808 {
809         const XMLProperty* prop;
810         MIDI::byte detail;
811         MIDI::channel_t channel;
812         string uri;
813         MIDI::eventType ev;
814         int intval;
815         bool momentary;
816         MIDIControllable::Encoder encoder = MIDIControllable::No_enc;
817         bool rpn_value = false;
818         bool nrpn_value = false;
819         bool rpn_change = false;
820         bool nrpn_change = false;
821
822         if ((prop = node.property (X_("ctl"))) != 0) {
823                 ev = MIDI::controller;
824         } else if ((prop = node.property (X_("note"))) != 0) {
825                 ev = MIDI::on;
826         } else if ((prop = node.property (X_("pgm"))) != 0) {
827                 ev = MIDI::program;
828         } else if ((prop = node.property (X_("pb"))) != 0) {
829                 ev = MIDI::pitchbend;
830         } else if ((prop = node.property (X_("enc-l"))) != 0) {
831                 encoder = MIDIControllable::Enc_L;
832                 ev = MIDI::controller;
833         } else if ((prop = node.property (X_("enc-r"))) != 0) {
834                 encoder = MIDIControllable::Enc_R;
835                 ev = MIDI::controller;
836         } else if ((prop = node.property (X_("enc-2"))) != 0) {
837                 encoder = MIDIControllable::Enc_2;
838                 ev = MIDI::controller;
839         } else if ((prop = node.property (X_("enc-b"))) != 0) {
840                 encoder = MIDIControllable::Enc_B;
841                 ev = MIDI::controller;
842         } else if ((prop = node.property (X_("rpn"))) != 0) {
843                 rpn_value = true;
844         } else if ((prop = node.property (X_("nrpn"))) != 0) {
845                 nrpn_value = true;
846         } else if ((prop = node.property (X_("rpn-delta"))) != 0) {
847                 rpn_change = true;
848         } else if ((prop = node.property (X_("nrpn-delta"))) != 0) {
849                 nrpn_change = true;
850         } else {
851                 return 0;
852         }
853
854         if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
855                 return 0;
856         }
857
858         detail = (MIDI::byte) intval;
859
860         if ((prop = node.property (X_("channel"))) == 0) {
861                 return 0;
862         }
863
864         if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
865                 return 0;
866         }
867         channel = (MIDI::channel_t) intval;
868         /* adjust channel to zero-based counting */
869         if (channel > 0) {
870                 channel -= 1;
871         }
872
873         if ((prop = node.property (X_("momentary"))) != 0) {
874                 momentary = string_to<bool> (prop->value());
875         } else {
876                 momentary = false;
877         }
878
879         prop = node.property (X_("uri"));
880         uri = prop->value();
881
882         MIDIControllable* mc = new MIDIControllable (this, *_input_port->parser(), momentary);
883
884         if (mc->init (uri)) {
885                 delete mc;
886                 return 0;
887         }
888
889         if (rpn_value) {
890                 mc->bind_rpn_value (channel, detail);
891         } else if (nrpn_value) {
892                 mc->bind_nrpn_value (channel, detail);
893         } else if (rpn_change) {
894                 mc->bind_rpn_change (channel, detail);
895         } else if (nrpn_change) {
896                 mc->bind_nrpn_change (channel, detail);
897         } else {
898                 mc->set_encoder (encoder);
899                 mc->bind_midi (channel, ev, detail);
900         }
901
902         return mc;
903 }
904
905 void
906 GenericMidiControlProtocol::reset_controllables ()
907 {
908         Glib::Threads::Mutex::Lock lm2 (controllables_lock);
909
910         for (MIDIControllables::iterator iter = controllables.begin(); iter != controllables.end(); ) {
911                 MIDIControllable* existingBinding = (*iter);
912                 MIDIControllables::iterator next = iter;
913                 ++next;
914
915                 if (!existingBinding->learned()) {
916                         ControllableDescriptor& desc (existingBinding->descriptor());
917
918                         if (desc.banked()) {
919                                 desc.set_bank_offset (_current_bank * _bank_size);
920                         }
921
922                         /* its entirely possible that the session doesn't have
923                          * the specified controllable (e.g. it has too few
924                          * tracks). if we find this to be the case, we just leave
925                          * the binding around, unbound, and it will do "late
926                          * binding" (or "lazy binding") if/when any data arrives.
927                          */
928
929                         existingBinding->lookup_controllable ();
930                 }
931
932                 iter = next;
933         }
934 }
935
936 boost::shared_ptr<Controllable>
937 GenericMidiControlProtocol::lookup_controllable (const ControllableDescriptor& desc) const
938 {
939         return session->controllable_by_descriptor (desc);
940 }
941
942 MIDIFunction*
943 GenericMidiControlProtocol::create_function (const XMLNode& node)
944 {
945         const XMLProperty* prop;
946         int intval;
947         MIDI::byte detail = 0;
948         MIDI::channel_t channel = 0;
949         string uri;
950         MIDI::eventType ev;
951         MIDI::byte* data = 0;
952         uint32_t data_size = 0;
953         string argument;
954
955         if ((prop = node.property (X_("ctl"))) != 0) {
956                 ev = MIDI::controller;
957         } else if ((prop = node.property (X_("note"))) != 0) {
958                 ev = MIDI::on;
959         } else if ((prop = node.property (X_("pgm"))) != 0) {
960                 ev = MIDI::program;
961         } else if ((prop = node.property (X_("sysex"))) != 0 || (prop = node.property (X_("msg"))) != 0) {
962
963                 if (prop->name() == X_("sysex")) {
964                         ev = MIDI::sysex;
965                 } else {
966                         ev = MIDI::any;
967                 }
968
969                 int val;
970                 uint32_t cnt;
971
972                 {
973                         cnt = 0;
974                         stringstream ss (prop->value());
975                         ss << hex;
976
977                         while (ss >> val) {
978                                 cnt++;
979                         }
980                 }
981
982                 if (cnt == 0) {
983                         return 0;
984                 }
985
986                 data = new MIDI::byte[cnt];
987                 data_size = cnt;
988
989                 {
990                         stringstream ss (prop->value());
991                         ss << hex;
992                         cnt = 0;
993
994                         while (ss >> val) {
995                                 data[cnt++] = (MIDI::byte) val;
996                         }
997                 }
998
999         } else {
1000                 warning << "Binding ignored - unknown type" << endmsg;
1001                 return 0;
1002         }
1003
1004         if (data_size == 0) {
1005                 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
1006                         return 0;
1007                 }
1008
1009                 detail = (MIDI::byte) intval;
1010
1011                 if ((prop = node.property (X_("channel"))) == 0) {
1012                         return 0;
1013                 }
1014
1015                 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
1016                         return 0;
1017                 }
1018                 channel = (MIDI::channel_t) intval;
1019                 /* adjust channel to zero-based counting */
1020                 if (channel > 0) {
1021                         channel -= 1;
1022                 }
1023         }
1024
1025         if ((prop = node.property (X_("arg"))) != 0 || (prop = node.property (X_("argument"))) != 0 || (prop = node.property (X_("arguments"))) != 0) {
1026                 argument = prop->value ();
1027         }
1028
1029         prop = node.property (X_("function"));
1030
1031         MIDIFunction* mf = new MIDIFunction (*_input_port->parser());
1032
1033         if (mf->setup (*this, prop->value(), argument, data, data_size)) {
1034                 delete mf;
1035                 return 0;
1036         }
1037
1038         mf->bind_midi (channel, ev, detail);
1039
1040         return mf;
1041 }
1042
1043 MIDIAction*
1044 GenericMidiControlProtocol::create_action (const XMLNode& node)
1045 {
1046         const XMLProperty* prop;
1047         int intval;
1048         MIDI::byte detail = 0;
1049         MIDI::channel_t channel = 0;
1050         string uri;
1051         MIDI::eventType ev;
1052         MIDI::byte* data = 0;
1053         uint32_t data_size = 0;
1054
1055         if ((prop = node.property (X_("ctl"))) != 0) {
1056                 ev = MIDI::controller;
1057         } else if ((prop = node.property (X_("note"))) != 0) {
1058                 ev = MIDI::on;
1059         } else if ((prop = node.property (X_("pgm"))) != 0) {
1060                 ev = MIDI::program;
1061         } else if ((prop = node.property (X_("sysex"))) != 0 || (prop = node.property (X_("msg"))) != 0) {
1062
1063                 if (prop->name() == X_("sysex")) {
1064                         ev = MIDI::sysex;
1065                 } else {
1066                         ev = MIDI::any;
1067                 }
1068
1069                 int val;
1070                 uint32_t cnt;
1071
1072                 {
1073                         cnt = 0;
1074                         stringstream ss (prop->value());
1075                         ss << hex;
1076
1077                         while (ss >> val) {
1078                                 cnt++;
1079                         }
1080                 }
1081
1082                 if (cnt == 0) {
1083                         return 0;
1084                 }
1085
1086                 data = new MIDI::byte[cnt];
1087                 data_size = cnt;
1088
1089                 {
1090                         stringstream ss (prop->value());
1091                         ss << hex;
1092                         cnt = 0;
1093
1094                         while (ss >> val) {
1095                                 data[cnt++] = (MIDI::byte) val;
1096                         }
1097                 }
1098
1099         } else {
1100                 warning << "Binding ignored - unknown type" << endmsg;
1101                 return 0;
1102         }
1103
1104         if (data_size == 0) {
1105                 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
1106                         return 0;
1107                 }
1108
1109                 detail = (MIDI::byte) intval;
1110
1111                 if ((prop = node.property (X_("channel"))) == 0) {
1112                         return 0;
1113                 }
1114
1115                 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
1116                         return 0;
1117                 }
1118                 channel = (MIDI::channel_t) intval;
1119                 /* adjust channel to zero-based counting */
1120                 if (channel > 0) {
1121                         channel -= 1;
1122                 }
1123         }
1124
1125         prop = node.property (X_("action"));
1126
1127         MIDIAction* ma = new MIDIAction (*_input_port->parser());
1128
1129         if (ma->init (*this, prop->value(), data, data_size)) {
1130                 delete ma;
1131                 return 0;
1132         }
1133
1134         ma->bind_midi (channel, ev, detail);
1135
1136         return ma;
1137 }
1138
1139 void
1140 GenericMidiControlProtocol::set_current_bank (uint32_t b)
1141 {
1142         _current_bank = b;
1143         reset_controllables ();
1144 }
1145
1146 void
1147 GenericMidiControlProtocol::next_bank ()
1148 {
1149         _current_bank++;
1150         reset_controllables ();
1151 }
1152
1153 void
1154 GenericMidiControlProtocol::prev_bank()
1155 {
1156         if (_current_bank) {
1157                 _current_bank--;
1158                 reset_controllables ();
1159         }
1160 }
1161
1162 void
1163 GenericMidiControlProtocol::set_motorised (bool m)
1164 {
1165         _motorised = m;
1166 }
1167
1168 void
1169 GenericMidiControlProtocol::set_threshold (int t)
1170 {
1171         _threshold = t;
1172 }
1173
1174 bool
1175 GenericMidiControlProtocol::connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, boost::weak_ptr<ARDOUR::Port>, std::string name2, bool yn)
1176 {
1177         if (!_input_port || !_output_port) {
1178                 return false;
1179         }
1180
1181         string ni = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (boost::shared_ptr<ARDOUR::Port>(_input_port)->name());
1182         string no = ARDOUR::AudioEngine::instance()->make_port_name_non_relative (boost::shared_ptr<ARDOUR::Port>(_output_port)->name());
1183
1184         if (ni == name1 || ni == name2) {
1185                 if (yn) {
1186                         connection_state |= InputConnected;
1187                 } else {
1188                         connection_state &= ~InputConnected;
1189                 }
1190         } else if (no == name1 || no == name2) {
1191                 if (yn) {
1192                         connection_state |= OutputConnected;
1193                 } else {
1194                         connection_state &= ~OutputConnected;
1195                 }
1196         } else {
1197                 /* not our ports */
1198                 return false;
1199         }
1200
1201         if ((connection_state & (InputConnected|OutputConnected)) == (InputConnected|OutputConnected)) {
1202
1203                 /* XXX this is a horrible hack. Without a short sleep here,
1204                    something prevents the device wakeup messages from being
1205                    sent and/or the responses from being received.
1206                 */
1207
1208                 g_usleep (100000);
1209                 connected ();
1210
1211         } else {
1212
1213         }
1214
1215         ConnectionChange (); /* emit signal for our GUI */
1216
1217         return true; /* connection status changed */
1218 }
1219
1220 void
1221 GenericMidiControlProtocol::connected ()
1222 {
1223         cerr << "Now connected\n";
1224 }
1225
1226 boost::shared_ptr<Port>
1227 GenericMidiControlProtocol::output_port() const
1228 {
1229         return _output_port;
1230 }
1231
1232 boost::shared_ptr<Port>
1233 GenericMidiControlProtocol::input_port() const
1234 {
1235         return _input_port;
1236 }
1237
1238 void
1239 GenericMidiControlProtocol::maybe_start_touch (Controllable* controllable)
1240 {
1241         AutomationControl *actl = dynamic_cast<AutomationControl*> (controllable);
1242         if (actl) {
1243                 if (actl->automation_state() == Touch && !actl->touching()) {
1244                         actl->start_touch (session->audible_frame ());
1245                 }
1246         }
1247 }
1248