2 Copyright (C) 2006 Paul Davis
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.
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.
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.
25 #include <glibmm/fileutils.h>
26 #include <glibmm/miscutils.h>
28 #include "pbd/controllable_descriptor.h"
29 #include "pbd/error.h"
30 #include "pbd/failed_constructor.h"
31 #include "pbd/pathscanner.h"
32 #include "pbd/xml++.h"
34 #include "midi++/port.h"
36 #include "ardour/audioengine.h"
37 #include "ardour/filesystem_paths.h"
38 #include "ardour/session.h"
39 #include "ardour/route.h"
40 #include "ardour/midi_ui.h"
41 #include "ardour/rc_configuration.h"
42 #include "ardour/midiport_manager.h"
44 #include "generic_midi_control_protocol.h"
45 #include "midicontrollable.h"
46 #include "midifunction.h"
47 #include "midiaction.h"
49 using namespace ARDOUR;
55 #define midi_ui_context() MidiControlUI::instance() /* a UICallback-derived object that specifies the event loop for signal handling */
57 GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s)
58 : ControlProtocol (s, _("Generic MIDI"))
63 _input_port = s.midi_input_port ();
64 _output_port = s.midi_output_port ();
67 _feedback_interval = 10000; // microseconds
68 last_feedback_time = 0;
73 /* these signals are emitted by the MidiControlUI's event loop thread
74 * and we may as well handle them right there in the same the same
78 Controllable::StartLearning.connect_same_thread (*this, boost::bind (&GenericMidiControlProtocol::start_learning, this, _1));
79 Controllable::StopLearning.connect_same_thread (*this, boost::bind (&GenericMidiControlProtocol::stop_learning, this, _1));
80 Controllable::CreateBinding.connect_same_thread (*this, boost::bind (&GenericMidiControlProtocol::create_binding, this, _1, _2, _3));
81 Controllable::DeleteBinding.connect_same_thread (*this, boost::bind (&GenericMidiControlProtocol::delete_binding, this, _1));
83 Session::SendFeedback.connect (*this, MISSING_INVALIDATOR, boost::bind (&GenericMidiControlProtocol::send_feedback, this), midi_ui_context());;
85 /* XXXX SOMETHING GOES WRONG HERE (april 2012) - STILL DEBUGGING */
86 /* this signal is emitted by the process() callback, and if
87 * send_feedback() is going to do anything, it should do it in the
88 * context of the process() callback itself.
91 Session::SendFeedback.connect_same_thread (*this, boost::bind (&GenericMidiControlProtocol::send_feedback, this));
93 /* this one is cross-thread */
95 Route::RemoteControlIDChange.connect (*this, MISSING_INVALIDATOR, boost::bind (&GenericMidiControlProtocol::reset_controllables, this), midi_ui_context());
100 GenericMidiControlProtocol::~GenericMidiControlProtocol ()
106 static const char * const midimap_env_variable_name = "ARDOUR_MIDIMAPS_PATH";
107 static const char* const midi_map_dir_name = "midi_maps";
108 static const char* const midi_map_suffix = ".map";
111 system_midi_map_search_path ()
113 bool midimap_path_defined = false;
114 std::string spath_env (Glib::getenv (midimap_env_variable_name, midimap_path_defined));
116 if (midimap_path_defined) {
120 SearchPath spath (ardour_data_search_path());
121 spath.add_subdirectory_to_paths(midi_map_dir_name);
126 user_midi_map_directory ()
128 return Glib::build_filename (user_config_directory(), midi_map_dir_name);
132 midi_map_filter (const string &str, void */*arg*/)
134 return (str.length() > strlen(midi_map_suffix) &&
135 str.find (midi_map_suffix) == (str.length() - strlen (midi_map_suffix)));
139 GenericMidiControlProtocol::reload_maps ()
141 vector<string *> *midi_maps;
143 SearchPath spath (system_midi_map_search_path());
144 spath += user_midi_map_directory ();
146 midi_maps = scanner (spath.to_string(), midi_map_filter, 0, false, true);
149 cerr << "No MIDI maps found using " << spath.to_string() << endl;
153 for (vector<string*>::iterator i = midi_maps->begin(); i != midi_maps->end(); ++i) {
154 string fullpath = *(*i);
158 if (!tree.read (fullpath.c_str())) {
164 XMLProperty* prop = tree.root()->property ("name");
170 mi.name = prop->value ();
173 map_info.push_back (mi);
180 GenericMidiControlProtocol::drop_all ()
182 Glib::Threads::Mutex::Lock lm (pending_lock);
183 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
185 for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
188 controllables.clear ();
190 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
193 pending_controllables.clear ();
195 for (MIDIFunctions::iterator i = functions.begin(); i != functions.end(); ++i) {
200 for (MIDIActions::iterator i = actions.begin(); i != actions.end(); ++i) {
207 GenericMidiControlProtocol::drop_bindings ()
209 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
211 for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ) {
212 if (!(*i)->learned()) {
214 i = controllables.erase (i);
220 for (MIDIFunctions::iterator i = functions.begin(); i != functions.end(); ++i) {
225 _current_binding = "";
231 GenericMidiControlProtocol::set_active (bool /*yn*/)
233 /* start/stop delivery/outbound thread */
238 GenericMidiControlProtocol::set_feedback_interval (microseconds_t ms)
240 _feedback_interval = ms;
244 GenericMidiControlProtocol::send_feedback ()
246 /* This is executed in RT "process" context", so no blocking calls
253 microseconds_t now = get_microseconds ();
255 if (last_feedback_time != 0) {
256 if ((now - last_feedback_time) < _feedback_interval) {
263 last_feedback_time = now;
267 GenericMidiControlProtocol::_send_feedback ()
269 /* This is executed in RT "process" context", so no blocking calls
272 const int32_t bufsize = 16 * 1024; /* XXX too big */
273 MIDI::byte buf[bufsize];
274 int32_t bsize = bufsize;
276 /* XXX: due to bugs in some ALSA / JACK MIDI bridges, we have to do separate
277 writes for each controllable here; if we send more than one MIDI message
278 in a single jack_midi_event_write then some bridges will only pass the
282 Glib::Threads::Mutex::Lock lm (controllables_lock, Glib::Threads::TRY_LOCK);
287 for (MIDIControllables::iterator r = controllables.begin(); r != controllables.end(); ++r) {
288 MIDI::byte* end = (*r)->write_feedback (buf, bsize);
290 _output_port->write (buf, (int32_t) (end - buf), 0);
296 GenericMidiControlProtocol::start_learning (Controllable* c)
302 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
304 MIDIControllables::iterator tmp;
305 for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ) {
308 if ((*i)->get_controllable() == c) {
310 controllables.erase (i);
316 Glib::Threads::Mutex::Lock lm (pending_lock);
318 MIDIPendingControllables::iterator ptmp;
319 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ) {
322 if (((*i)->first)->get_controllable() == c) {
323 (*i)->second.disconnect();
326 pending_controllables.erase (i);
332 MIDIControllable* mc = 0;
334 for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
335 if ((*i)->get_controllable() && ((*i)->get_controllable()->id() == c->id())) {
342 mc = new MIDIControllable (this, *_input_port->parser(), *c, false);
346 Glib::Threads::Mutex::Lock lm (pending_lock);
348 MIDIPendingControllable* element = new MIDIPendingControllable;
350 c->LearningFinished.connect_same_thread (element->second, boost::bind (&GenericMidiControlProtocol::learning_stopped, this, mc));
352 pending_controllables.push_back (element);
355 mc->learn_about_external_control ();
360 GenericMidiControlProtocol::learning_stopped (MIDIControllable* mc)
362 Glib::Threads::Mutex::Lock lm (pending_lock);
363 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
365 MIDIPendingControllables::iterator tmp;
367 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ) {
371 if ( (*i)->first == mc) {
372 (*i)->second.disconnect();
374 pending_controllables.erase(i);
380 controllables.push_back (mc);
384 GenericMidiControlProtocol::stop_learning (Controllable* c)
386 Glib::Threads::Mutex::Lock lm (pending_lock);
387 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
388 MIDIControllable* dptr = 0;
390 /* learning timed out, and we've been told to consider this attempt to learn to be cancelled. find the
391 relevant MIDIControllable and remove it from the pending list.
394 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
395 if (((*i)->first)->get_controllable() == c) {
396 (*i)->first->stop_learning ();
398 (*i)->second.disconnect();
401 pending_controllables.erase (i);
410 GenericMidiControlProtocol::delete_binding (PBD::Controllable* control)
413 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
415 for (MIDIControllables::iterator iter = controllables.begin(); iter != controllables.end();) {
416 MIDIControllable* existingBinding = (*iter);
418 if (control == (existingBinding->get_controllable())) {
419 delete existingBinding;
420 iter = controllables.erase (iter);
430 GenericMidiControlProtocol::create_binding (PBD::Controllable* control, int pos, int control_number)
432 if (control != NULL) {
433 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
435 MIDI::channel_t channel = (pos & 0xf);
436 MIDI::byte value = control_number;
438 // Create a MIDIControllable
439 MIDIControllable* mc = new MIDIControllable (this, *_input_port->parser(), *control, false);
441 // Remove any old binding for this midi channel/type/value pair
442 // Note: can't use delete_binding() here because we don't know the specific controllable we want to remove, only the midi information
443 for (MIDIControllables::iterator iter = controllables.begin(); iter != controllables.end();) {
444 MIDIControllable* existingBinding = (*iter);
446 if ((existingBinding->get_control_channel() & 0xf ) == channel &&
447 existingBinding->get_control_additional() == value &&
448 (existingBinding->get_control_type() & 0xf0 ) == MIDI::controller) {
450 delete existingBinding;
451 iter = controllables.erase (iter);
458 // Update the MIDI Controllable based on the the pos param
459 // Here is where a table lookup for user mappings could go; for now we'll just wing it...
460 mc->bind_midi(channel, MIDI::controller, value);
462 controllables.push_back (mc);
467 GenericMidiControlProtocol::get_state ()
469 XMLNode* node = new XMLNode ("Protocol");
472 node->add_property (X_("name"), _name);
473 node->add_property (X_("feedback"), do_feedback ? "1" : "0");
474 snprintf (buf, sizeof (buf), "%" PRIu64, _feedback_interval);
475 node->add_property (X_("feedback_interval"), buf);
476 snprintf (buf, sizeof (buf), "%d", _threshold);
477 node->add_property (X_("threshold"), buf);
479 if (!_current_binding.empty()) {
480 node->add_property ("binding", _current_binding);
483 XMLNode* children = new XMLNode (X_("Controls"));
485 node->add_child_nocopy (*children);
487 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
488 for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
490 /* we don't care about bindings that come from a bindings map, because
491 they will all be reset/recreated when we load the relevant bindings
495 if ((*i)->get_controllable() && (*i)->learned()) {
496 children->add_child_nocopy ((*i)->get_state());
504 GenericMidiControlProtocol::set_state (const XMLNode& node, int version)
507 XMLNodeConstIterator niter;
508 const XMLProperty* prop;
510 if ((prop = node.property ("feedback")) != 0) {
511 do_feedback = (bool) atoi (prop->value().c_str());
516 if ((prop = node.property ("feedback_interval")) != 0) {
517 if (sscanf (prop->value().c_str(), "%" PRIu64, &_feedback_interval) != 1) {
518 _feedback_interval = 10000;
521 _feedback_interval = 10000;
524 if ((prop = node.property ("threshold")) != 0) {
525 if (sscanf (prop->value().c_str(), "%d", &_threshold) != 1) {
532 boost::shared_ptr<Controllable> c;
535 Glib::Threads::Mutex::Lock lm (pending_lock);
536 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
539 pending_controllables.clear ();
542 /* Load up specific bindings from the
543 * <Controls><MidiControllable>...</MidiControllable><Controls> section
547 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
548 controllables.clear ();
549 nlist = node.children(); // "Controls"
551 if (!nlist.empty()) {
552 nlist = nlist.front()->children(); // "MIDIControllable" ...
554 if (!nlist.empty()) {
555 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
557 if ((prop = (*niter)->property ("id")) != 0) {
559 ID id = prop->value ();
560 Controllable* c = Controllable::by_id (id);
563 MIDIControllable* mc = new MIDIControllable (this, *_input_port->parser(), *c, false);
565 if (mc->set_state (**niter, version) == 0) {
566 controllables.push_back (mc);
570 warning << string_compose (
571 _("Generic MIDI control: controllable %1 not found in session (ignored)"),
580 if ((prop = node.property ("binding")) != 0) {
581 for (list<MapInfo>::iterator x = map_info.begin(); x != map_info.end(); ++x) {
582 if (prop->value() == (*x).name) {
583 load_bindings ((*x).path);
593 GenericMidiControlProtocol::set_feedback (bool yn)
596 last_feedback_time = 0;
601 GenericMidiControlProtocol::get_feedback () const
607 GenericMidiControlProtocol::load_bindings (const string& xmlpath)
611 if (!state_tree.read (xmlpath.c_str())) {
612 error << string_compose(_("Could not understand MIDI bindings file %1"), xmlpath) << endmsg;
616 XMLNode* root = state_tree.root();
618 if (root->name() != X_("ArdourMIDIBindings")) {
619 error << string_compose (_("MIDI Bindings file %1 is not really a MIDI bindings file"), xmlpath) << endmsg;
623 const XMLProperty* prop;
625 if ((prop = root->property ("version")) == 0) {
632 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
633 Stateful::loading_state_version = (major * 1000) + minor;
636 const XMLNodeList& children (root->children());
637 XMLNodeConstIterator citer;
638 XMLNodeConstIterator gciter;
640 MIDIControllable* mc;
644 for (citer = children.begin(); citer != children.end(); ++citer) {
646 if ((*citer)->name() == "DeviceInfo") {
647 const XMLProperty* prop;
649 if ((prop = (*citer)->property ("bank-size")) != 0) {
650 _bank_size = atoi (prop->value());
654 if ((prop = (*citer)->property ("motorised")) != 0 || ((prop = (*citer)->property ("motorized")) != 0)) {
655 _motorised = string_is_affirmative (prop->value ());
660 if ((prop = (*citer)->property ("threshold")) != 0) {
661 _threshold = atoi (prop->value ());
668 if ((*citer)->name() == "Binding") {
669 const XMLNode* child = *citer;
671 if (child->property ("uri")) {
674 if ((mc = create_binding (*child)) != 0) {
675 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
676 controllables.push_back (mc);
679 } else if (child->property ("function")) {
684 if ((mf = create_function (*child)) != 0) {
685 functions.push_back (mf);
688 } else if (child->property ("action")) {
691 if ((ma = create_action (*child)) != 0) {
692 actions.push_back (ma);
698 if ((prop = root->property ("name")) != 0) {
699 _current_binding = prop->value ();
702 reset_controllables ();
708 GenericMidiControlProtocol::create_binding (const XMLNode& node)
710 const XMLProperty* prop;
712 MIDI::channel_t channel;
718 if ((prop = node.property (X_("ctl"))) != 0) {
719 ev = MIDI::controller;
720 } else if ((prop = node.property (X_("note"))) != 0) {
722 } else if ((prop = node.property (X_("pgm"))) != 0) {
724 } else if ((prop = node.property (X_("pb"))) != 0) {
725 ev = MIDI::pitchbend;
730 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
734 detail = (MIDI::byte) intval;
736 if ((prop = node.property (X_("channel"))) == 0) {
740 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
743 channel = (MIDI::channel_t) intval;
744 /* adjust channel to zero-based counting */
749 if ((prop = node.property (X_("momentary"))) != 0) {
750 momentary = string_is_affirmative (prop->value());
755 prop = node.property (X_("uri"));
758 MIDIControllable* mc = new MIDIControllable (this, *_input_port->parser(), momentary);
760 if (mc->init (uri)) {
765 mc->bind_midi (channel, ev, detail);
771 GenericMidiControlProtocol::reset_controllables ()
773 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
775 for (MIDIControllables::iterator iter = controllables.begin(); iter != controllables.end(); ) {
776 MIDIControllable* existingBinding = (*iter);
777 MIDIControllables::iterator next = iter;
780 if (!existingBinding->learned()) {
781 ControllableDescriptor& desc (existingBinding->descriptor());
784 desc.set_bank_offset (_current_bank * _bank_size);
787 /* its entirely possible that the session doesn't have
788 * the specified controllable (e.g. it has too few
789 * tracks). if we find this to be the case, we just leave
790 * the binding around, unbound, and it will do "late
791 * binding" (or "lazy binding") if/when any data arrives.
794 existingBinding->lookup_controllable ();
801 boost::shared_ptr<Controllable>
802 GenericMidiControlProtocol::lookup_controllable (const ControllableDescriptor& desc) const
804 return session->controllable_by_descriptor (desc);
808 GenericMidiControlProtocol::create_function (const XMLNode& node)
810 const XMLProperty* prop;
812 MIDI::byte detail = 0;
813 MIDI::channel_t channel = 0;
816 MIDI::byte* data = 0;
817 uint32_t data_size = 0;
820 if ((prop = node.property (X_("ctl"))) != 0) {
821 ev = MIDI::controller;
822 } else if ((prop = node.property (X_("note"))) != 0) {
824 } else if ((prop = node.property (X_("pgm"))) != 0) {
826 } else if ((prop = node.property (X_("sysex"))) != 0 || (prop = node.property (X_("msg"))) != 0) {
828 if (prop->name() == X_("sysex")) {
839 stringstream ss (prop->value());
851 data = new MIDI::byte[cnt];
855 stringstream ss (prop->value());
860 data[cnt++] = (MIDI::byte) val;
865 warning << "Binding ignored - unknown type" << endmsg;
869 if (data_size == 0) {
870 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
874 detail = (MIDI::byte) intval;
876 if ((prop = node.property (X_("channel"))) == 0) {
880 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
883 channel = (MIDI::channel_t) intval;
884 /* adjust channel to zero-based counting */
890 if ((prop = node.property (X_("arg"))) != 0 || (prop = node.property (X_("argument"))) != 0 || (prop = node.property (X_("arguments"))) != 0) {
891 argument = prop->value ();
894 prop = node.property (X_("function"));
896 MIDIFunction* mf = new MIDIFunction (*_input_port->parser());
898 if (mf->setup (*this, prop->value(), argument, data, data_size)) {
903 mf->bind_midi (channel, ev, detail);
909 GenericMidiControlProtocol::create_action (const XMLNode& node)
911 const XMLProperty* prop;
913 MIDI::byte detail = 0;
914 MIDI::channel_t channel = 0;
917 MIDI::byte* data = 0;
918 uint32_t data_size = 0;
920 if ((prop = node.property (X_("ctl"))) != 0) {
921 ev = MIDI::controller;
922 } else if ((prop = node.property (X_("note"))) != 0) {
924 } else if ((prop = node.property (X_("pgm"))) != 0) {
926 } else if ((prop = node.property (X_("sysex"))) != 0 || (prop = node.property (X_("msg"))) != 0) {
928 if (prop->name() == X_("sysex")) {
939 stringstream ss (prop->value());
951 data = new MIDI::byte[cnt];
955 stringstream ss (prop->value());
960 data[cnt++] = (MIDI::byte) val;
965 warning << "Binding ignored - unknown type" << endmsg;
969 if (data_size == 0) {
970 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
974 detail = (MIDI::byte) intval;
976 if ((prop = node.property (X_("channel"))) == 0) {
980 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
983 channel = (MIDI::channel_t) intval;
984 /* adjust channel to zero-based counting */
990 prop = node.property (X_("action"));
992 MIDIAction* ma = new MIDIAction (*_input_port->parser());
994 if (ma->init (*this, prop->value(), data, data_size)) {
999 ma->bind_midi (channel, ev, detail);
1005 GenericMidiControlProtocol::set_current_bank (uint32_t b)
1008 reset_controllables ();
1012 GenericMidiControlProtocol::next_bank ()
1015 reset_controllables ();
1019 GenericMidiControlProtocol::prev_bank()
1021 if (_current_bank) {
1023 reset_controllables ();
1028 GenericMidiControlProtocol::set_motorised (bool m)
1034 GenericMidiControlProtocol::set_threshold (int t)