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 /* this signal is emitted by the process() callback, and if
84 * send_feedback() is going to do anything, it should do it in the
85 * context of the process() callback itself.
88 Session::SendFeedback.connect_same_thread (*this, boost::bind (&GenericMidiControlProtocol::send_feedback, this));
89 //Session::SendFeedback.connect (*this, MISSING_INVALIDATOR, boost::bind (&GenericMidiControlProtocol::send_feedback, this), midi_ui_context());;
91 /* this one is cross-thread */
93 Route::RemoteControlIDChange.connect (*this, MISSING_INVALIDATOR, boost::bind (&GenericMidiControlProtocol::reset_controllables, this), midi_ui_context());
98 GenericMidiControlProtocol::~GenericMidiControlProtocol ()
104 static const char * const midimap_env_variable_name = "ARDOUR_MIDIMAPS_PATH";
105 static const char* const midi_map_dir_name = "midi_maps";
106 static const char* const midi_map_suffix = ".map";
109 system_midi_map_search_path ()
111 bool midimap_path_defined = false;
112 std::string spath_env (Glib::getenv (midimap_env_variable_name, midimap_path_defined));
114 if (midimap_path_defined) {
118 Searchpath spath (ardour_data_search_path());
119 spath.add_subdirectory_to_paths(midi_map_dir_name);
124 user_midi_map_directory ()
126 return Glib::build_filename (user_config_directory(), midi_map_dir_name);
130 midi_map_filter (const string &str, void* /*arg*/)
132 return (str.length() > strlen(midi_map_suffix) &&
133 str.find (midi_map_suffix) == (str.length() - strlen (midi_map_suffix)));
137 GenericMidiControlProtocol::reload_maps ()
139 vector<string> midi_maps;
141 Searchpath spath (system_midi_map_search_path());
142 spath += user_midi_map_directory ();
144 midi_maps = scanner (spath.to_string(), midi_map_filter, 0, false, true);
146 if (midi_maps.empty()) {
147 cerr << "No MIDI maps found using " << spath.to_string() << endl;
151 for (vector<string>::iterator i = midi_maps.begin(); i != midi_maps.end(); ++i) {
152 string fullpath = *i;
156 if (!tree.read (fullpath.c_str())) {
162 XMLProperty* prop = tree.root()->property ("name");
168 mi.name = prop->value ();
171 map_info.push_back (mi);
176 GenericMidiControlProtocol::drop_all ()
178 Glib::Threads::Mutex::Lock lm (pending_lock);
179 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
181 for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
184 controllables.clear ();
186 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
189 pending_controllables.clear ();
191 for (MIDIFunctions::iterator i = functions.begin(); i != functions.end(); ++i) {
196 for (MIDIActions::iterator i = actions.begin(); i != actions.end(); ++i) {
203 GenericMidiControlProtocol::drop_bindings ()
205 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
207 for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ) {
208 if (!(*i)->learned()) {
210 i = controllables.erase (i);
216 for (MIDIFunctions::iterator i = functions.begin(); i != functions.end(); ++i) {
221 _current_binding = "";
227 GenericMidiControlProtocol::set_active (bool /*yn*/)
229 /* start/stop delivery/outbound thread */
234 GenericMidiControlProtocol::set_feedback_interval (microseconds_t ms)
236 _feedback_interval = ms;
240 GenericMidiControlProtocol::send_feedback ()
242 /* This is executed in RT "process" context", so no blocking calls
249 microseconds_t now = get_microseconds ();
251 if (last_feedback_time != 0) {
252 if ((now - last_feedback_time) < _feedback_interval) {
259 last_feedback_time = now;
263 GenericMidiControlProtocol::_send_feedback ()
265 /* This is executed in RT "process" context", so no blocking calls
268 const int32_t bufsize = 16 * 1024; /* XXX too big */
269 MIDI::byte buf[bufsize];
270 int32_t bsize = bufsize;
272 /* XXX: due to bugs in some ALSA / JACK MIDI bridges, we have to do separate
273 writes for each controllable here; if we send more than one MIDI message
274 in a single jack_midi_event_write then some bridges will only pass the
278 Glib::Threads::Mutex::Lock lm (controllables_lock, Glib::Threads::TRY_LOCK);
283 for (MIDIControllables::iterator r = controllables.begin(); r != controllables.end(); ++r) {
284 MIDI::byte* end = (*r)->write_feedback (buf, bsize);
286 _output_port->write (buf, (int32_t) (end - buf), 0);
292 GenericMidiControlProtocol::start_learning (Controllable* c)
298 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
300 MIDIControllables::iterator tmp;
301 for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ) {
304 if ((*i)->get_controllable() == c) {
306 controllables.erase (i);
312 Glib::Threads::Mutex::Lock lm (pending_lock);
314 MIDIPendingControllables::iterator ptmp;
315 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ) {
318 if (((*i)->first)->get_controllable() == c) {
319 (*i)->second.disconnect();
322 pending_controllables.erase (i);
328 MIDIControllable* mc = 0;
330 for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
331 if ((*i)->get_controllable() && ((*i)->get_controllable()->id() == c->id())) {
338 mc = new MIDIControllable (this, *_input_port->parser(), *c, false);
342 Glib::Threads::Mutex::Lock lm (pending_lock);
344 MIDIPendingControllable* element = new MIDIPendingControllable;
346 c->LearningFinished.connect_same_thread (element->second, boost::bind (&GenericMidiControlProtocol::learning_stopped, this, mc));
348 pending_controllables.push_back (element);
351 mc->learn_about_external_control ();
356 GenericMidiControlProtocol::learning_stopped (MIDIControllable* mc)
358 Glib::Threads::Mutex::Lock lm (pending_lock);
359 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
361 MIDIPendingControllables::iterator tmp;
363 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ) {
367 if ( (*i)->first == mc) {
368 (*i)->second.disconnect();
370 pending_controllables.erase(i);
376 controllables.push_back (mc);
380 GenericMidiControlProtocol::stop_learning (Controllable* c)
382 Glib::Threads::Mutex::Lock lm (pending_lock);
383 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
384 MIDIControllable* dptr = 0;
386 /* learning timed out, and we've been told to consider this attempt to learn to be cancelled. find the
387 relevant MIDIControllable and remove it from the pending list.
390 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
391 if (((*i)->first)->get_controllable() == c) {
392 (*i)->first->stop_learning ();
394 (*i)->second.disconnect();
397 pending_controllables.erase (i);
406 GenericMidiControlProtocol::delete_binding (PBD::Controllable* control)
409 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
411 for (MIDIControllables::iterator iter = controllables.begin(); iter != controllables.end();) {
412 MIDIControllable* existingBinding = (*iter);
414 if (control == (existingBinding->get_controllable())) {
415 delete existingBinding;
416 iter = controllables.erase (iter);
426 GenericMidiControlProtocol::create_binding (PBD::Controllable* control, int pos, int control_number)
428 if (control != NULL) {
429 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
431 MIDI::channel_t channel = (pos & 0xf);
432 MIDI::byte value = control_number;
434 // Create a MIDIControllable
435 MIDIControllable* mc = new MIDIControllable (this, *_input_port->parser(), *control, false);
437 // Remove any old binding for this midi channel/type/value pair
438 // Note: can't use delete_binding() here because we don't know the specific controllable we want to remove, only the midi information
439 for (MIDIControllables::iterator iter = controllables.begin(); iter != controllables.end();) {
440 MIDIControllable* existingBinding = (*iter);
442 if ((existingBinding->get_control_channel() & 0xf ) == channel &&
443 existingBinding->get_control_additional() == value &&
444 (existingBinding->get_control_type() & 0xf0 ) == MIDI::controller) {
446 delete existingBinding;
447 iter = controllables.erase (iter);
454 // Update the MIDI Controllable based on the the pos param
455 // Here is where a table lookup for user mappings could go; for now we'll just wing it...
456 mc->bind_midi(channel, MIDI::controller, value);
458 controllables.push_back (mc);
463 GenericMidiControlProtocol::get_state ()
465 XMLNode& node (ControlProtocol::get_state());
468 node.add_property (X_("feedback"), do_feedback ? "1" : "0");
469 snprintf (buf, sizeof (buf), "%" PRIu64, _feedback_interval);
470 node.add_property (X_("feedback_interval"), buf);
471 snprintf (buf, sizeof (buf), "%d", _threshold);
472 node.add_property (X_("threshold"), buf);
474 if (!_current_binding.empty()) {
475 node.add_property ("binding", _current_binding);
478 XMLNode* children = new XMLNode (X_("Controls"));
480 node.add_child_nocopy (*children);
482 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
483 for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
485 /* we don't care about bindings that come from a bindings map, because
486 they will all be reset/recreated when we load the relevant bindings
490 if ((*i)->get_controllable() && (*i)->learned()) {
491 children->add_child_nocopy ((*i)->get_state());
499 GenericMidiControlProtocol::set_state (const XMLNode& node, int version)
502 XMLNodeConstIterator niter;
503 const XMLProperty* prop;
505 if ((prop = node.property ("feedback")) != 0) {
506 do_feedback = (bool) atoi (prop->value().c_str());
511 if ((prop = node.property ("feedback_interval")) != 0) {
512 if (sscanf (prop->value().c_str(), "%" PRIu64, &_feedback_interval) != 1) {
513 _feedback_interval = 10000;
516 _feedback_interval = 10000;
519 if ((prop = node.property ("threshold")) != 0) {
520 if (sscanf (prop->value().c_str(), "%d", &_threshold) != 1) {
527 boost::shared_ptr<Controllable> c;
530 Glib::Threads::Mutex::Lock lm (pending_lock);
531 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
534 pending_controllables.clear ();
537 /* Load up specific bindings from the
538 * <Controls><MidiControllable>...</MidiControllable><Controls> section
542 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
543 controllables.clear ();
544 nlist = node.children(); // "Controls"
546 if (!nlist.empty()) {
547 nlist = nlist.front()->children(); // "MIDIControllable" ...
549 if (!nlist.empty()) {
550 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
552 if ((prop = (*niter)->property ("id")) != 0) {
554 ID id = prop->value ();
555 Controllable* c = Controllable::by_id (id);
558 MIDIControllable* mc = new MIDIControllable (this, *_input_port->parser(), *c, false);
560 if (mc->set_state (**niter, version) == 0) {
561 controllables.push_back (mc);
565 warning << string_compose (
566 _("Generic MIDI control: controllable %1 not found in session (ignored)"),
575 if ((prop = node.property ("binding")) != 0) {
576 for (list<MapInfo>::iterator x = map_info.begin(); x != map_info.end(); ++x) {
577 if (prop->value() == (*x).name) {
578 load_bindings ((*x).path);
588 GenericMidiControlProtocol::set_feedback (bool yn)
591 last_feedback_time = 0;
596 GenericMidiControlProtocol::get_feedback () const
602 GenericMidiControlProtocol::load_bindings (const string& xmlpath)
606 if (!state_tree.read (xmlpath.c_str())) {
607 error << string_compose(_("Could not understand MIDI bindings file %1"), xmlpath) << endmsg;
611 XMLNode* root = state_tree.root();
613 if (root->name() != X_("ArdourMIDIBindings")) {
614 error << string_compose (_("MIDI Bindings file %1 is not really a MIDI bindings file"), xmlpath) << endmsg;
618 const XMLProperty* prop;
620 if ((prop = root->property ("version")) == 0) {
627 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
628 Stateful::loading_state_version = (major * 1000) + minor;
631 const XMLNodeList& children (root->children());
632 XMLNodeConstIterator citer;
633 XMLNodeConstIterator gciter;
635 MIDIControllable* mc;
639 for (citer = children.begin(); citer != children.end(); ++citer) {
641 if ((*citer)->name() == "DeviceInfo") {
642 const XMLProperty* prop;
644 if ((prop = (*citer)->property ("bank-size")) != 0) {
645 _bank_size = atoi (prop->value());
649 if ((prop = (*citer)->property ("motorised")) != 0 || ((prop = (*citer)->property ("motorized")) != 0)) {
650 _motorised = string_is_affirmative (prop->value ());
655 if ((prop = (*citer)->property ("threshold")) != 0) {
656 _threshold = atoi (prop->value ());
663 if ((*citer)->name() == "Binding") {
664 const XMLNode* child = *citer;
666 if (child->property ("uri")) {
669 if ((mc = create_binding (*child)) != 0) {
670 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
671 controllables.push_back (mc);
674 } else if (child->property ("function")) {
679 if ((mf = create_function (*child)) != 0) {
680 functions.push_back (mf);
683 } else if (child->property ("action")) {
686 if ((ma = create_action (*child)) != 0) {
687 actions.push_back (ma);
693 if ((prop = root->property ("name")) != 0) {
694 _current_binding = prop->value ();
697 reset_controllables ();
703 GenericMidiControlProtocol::create_binding (const XMLNode& node)
705 const XMLProperty* prop;
707 MIDI::channel_t channel;
713 if ((prop = node.property (X_("ctl"))) != 0) {
714 ev = MIDI::controller;
715 } else if ((prop = node.property (X_("note"))) != 0) {
717 } else if ((prop = node.property (X_("pgm"))) != 0) {
719 } else if ((prop = node.property (X_("pb"))) != 0) {
720 ev = MIDI::pitchbend;
725 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
729 detail = (MIDI::byte) intval;
731 if ((prop = node.property (X_("channel"))) == 0) {
735 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
738 channel = (MIDI::channel_t) intval;
739 /* adjust channel to zero-based counting */
744 if ((prop = node.property (X_("momentary"))) != 0) {
745 momentary = string_is_affirmative (prop->value());
750 prop = node.property (X_("uri"));
753 MIDIControllable* mc = new MIDIControllable (this, *_input_port->parser(), momentary);
755 if (mc->init (uri)) {
760 mc->bind_midi (channel, ev, detail);
766 GenericMidiControlProtocol::reset_controllables ()
768 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
770 for (MIDIControllables::iterator iter = controllables.begin(); iter != controllables.end(); ) {
771 MIDIControllable* existingBinding = (*iter);
772 MIDIControllables::iterator next = iter;
775 if (!existingBinding->learned()) {
776 ControllableDescriptor& desc (existingBinding->descriptor());
779 desc.set_bank_offset (_current_bank * _bank_size);
782 /* its entirely possible that the session doesn't have
783 * the specified controllable (e.g. it has too few
784 * tracks). if we find this to be the case, we just leave
785 * the binding around, unbound, and it will do "late
786 * binding" (or "lazy binding") if/when any data arrives.
789 existingBinding->lookup_controllable ();
796 boost::shared_ptr<Controllable>
797 GenericMidiControlProtocol::lookup_controllable (const ControllableDescriptor& desc) const
799 return session->controllable_by_descriptor (desc);
803 GenericMidiControlProtocol::create_function (const XMLNode& node)
805 const XMLProperty* prop;
807 MIDI::byte detail = 0;
808 MIDI::channel_t channel = 0;
811 MIDI::byte* data = 0;
812 uint32_t data_size = 0;
815 if ((prop = node.property (X_("ctl"))) != 0) {
816 ev = MIDI::controller;
817 } else if ((prop = node.property (X_("note"))) != 0) {
819 } else if ((prop = node.property (X_("pgm"))) != 0) {
821 } else if ((prop = node.property (X_("sysex"))) != 0 || (prop = node.property (X_("msg"))) != 0) {
823 if (prop->name() == X_("sysex")) {
834 stringstream ss (prop->value());
846 data = new MIDI::byte[cnt];
850 stringstream ss (prop->value());
855 data[cnt++] = (MIDI::byte) val;
860 warning << "Binding ignored - unknown type" << endmsg;
864 if (data_size == 0) {
865 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
869 detail = (MIDI::byte) intval;
871 if ((prop = node.property (X_("channel"))) == 0) {
875 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
878 channel = (MIDI::channel_t) intval;
879 /* adjust channel to zero-based counting */
885 if ((prop = node.property (X_("arg"))) != 0 || (prop = node.property (X_("argument"))) != 0 || (prop = node.property (X_("arguments"))) != 0) {
886 argument = prop->value ();
889 prop = node.property (X_("function"));
891 MIDIFunction* mf = new MIDIFunction (*_input_port->parser());
893 if (mf->setup (*this, prop->value(), argument, data, data_size)) {
898 mf->bind_midi (channel, ev, detail);
904 GenericMidiControlProtocol::create_action (const XMLNode& node)
906 const XMLProperty* prop;
908 MIDI::byte detail = 0;
909 MIDI::channel_t channel = 0;
912 MIDI::byte* data = 0;
913 uint32_t data_size = 0;
915 if ((prop = node.property (X_("ctl"))) != 0) {
916 ev = MIDI::controller;
917 } else if ((prop = node.property (X_("note"))) != 0) {
919 } else if ((prop = node.property (X_("pgm"))) != 0) {
921 } else if ((prop = node.property (X_("sysex"))) != 0 || (prop = node.property (X_("msg"))) != 0) {
923 if (prop->name() == X_("sysex")) {
934 stringstream ss (prop->value());
946 data = new MIDI::byte[cnt];
950 stringstream ss (prop->value());
955 data[cnt++] = (MIDI::byte) val;
960 warning << "Binding ignored - unknown type" << endmsg;
964 if (data_size == 0) {
965 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
969 detail = (MIDI::byte) intval;
971 if ((prop = node.property (X_("channel"))) == 0) {
975 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
978 channel = (MIDI::channel_t) intval;
979 /* adjust channel to zero-based counting */
985 prop = node.property (X_("action"));
987 MIDIAction* ma = new MIDIAction (*_input_port->parser());
989 if (ma->init (*this, prop->value(), data, data_size)) {
994 ma->bind_midi (channel, ev, detail);
1000 GenericMidiControlProtocol::set_current_bank (uint32_t b)
1003 reset_controllables ();
1007 GenericMidiControlProtocol::next_bank ()
1010 reset_controllables ();
1014 GenericMidiControlProtocol::prev_bank()
1016 if (_current_bank) {
1018 reset_controllables ();
1023 GenericMidiControlProtocol::set_motorised (bool m)
1029 GenericMidiControlProtocol::set_threshold (int t)