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"
35 #include "midi++/manager.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"
43 #include "generic_midi_control_protocol.h"
44 #include "midicontrollable.h"
45 #include "midifunction.h"
46 #include "midiaction.h"
48 using namespace ARDOUR;
54 #define midi_ui_context() MidiControlUI::instance() /* a UICallback-derived object that specifies the event loop for signal handling */
56 GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s)
57 : ControlProtocol (s, _("Generic MIDI"))
62 _input_port = MIDI::Manager::instance()->midi_input_port ();
63 _output_port = MIDI::Manager::instance()->midi_output_port ();
66 _feedback_interval = 10000; // microseconds
67 last_feedback_time = 0;
72 /* these signals are emitted by the MidiControlUI's event loop thread
73 * and we may as well handle them right there in the same the same
77 Controllable::StartLearning.connect_same_thread (*this, boost::bind (&GenericMidiControlProtocol::start_learning, this, _1));
78 Controllable::StopLearning.connect_same_thread (*this, boost::bind (&GenericMidiControlProtocol::stop_learning, this, _1));
79 Controllable::CreateBinding.connect_same_thread (*this, boost::bind (&GenericMidiControlProtocol::create_binding, this, _1, _2, _3));
80 Controllable::DeleteBinding.connect_same_thread (*this, boost::bind (&GenericMidiControlProtocol::delete_binding, this, _1));
82 Session::SendFeedback.connect (*this, MISSING_INVALIDATOR, boost::bind (&GenericMidiControlProtocol::send_feedback, this), midi_ui_context());;
84 /* XXXX SOMETHING GOES WRONG HERE (april 2012) - STILL DEBUGGING */
85 /* this signal is emitted by the process() callback, and if
86 * send_feedback() is going to do anything, it should do it in the
87 * context of the process() callback itself.
90 Session::SendFeedback.connect_same_thread (*this, boost::bind (&GenericMidiControlProtocol::send_feedback, this));
92 /* this one is cross-thread */
94 Route::RemoteControlIDChange.connect (*this, MISSING_INVALIDATOR, boost::bind (&GenericMidiControlProtocol::reset_controllables, this), midi_ui_context());
99 GenericMidiControlProtocol::~GenericMidiControlProtocol ()
105 static const char * const midimap_env_variable_name = "ARDOUR_MIDIMAPS_PATH";
106 static const char* const midi_map_dir_name = "midi_maps";
107 static const char* const midi_map_suffix = ".map";
110 system_midi_map_search_path ()
112 bool midimap_path_defined = false;
113 std::string spath_env (Glib::getenv (midimap_env_variable_name, midimap_path_defined));
115 if (midimap_path_defined) {
119 SearchPath spath (ardour_data_search_path());
120 spath.add_subdirectory_to_paths(midi_map_dir_name);
125 user_midi_map_directory ()
127 return Glib::build_filename (user_config_directory(), midi_map_dir_name);
131 midi_map_filter (const string &str, void* /*arg*/)
133 return (str.length() > strlen(midi_map_suffix) &&
134 str.find (midi_map_suffix) == (str.length() - strlen (midi_map_suffix)));
138 GenericMidiControlProtocol::reload_maps ()
140 vector<string *> *midi_maps;
142 SearchPath spath (system_midi_map_search_path());
143 spath += user_midi_map_directory ();
145 midi_maps = scanner (spath.to_string(), midi_map_filter, 0, false, true);
148 cerr << "No MIDI maps found using " << spath.to_string() << endl;
152 for (vector<string*>::iterator i = midi_maps->begin(); i != midi_maps->end(); ++i) {
153 string fullpath = *(*i);
157 if (!tree.read (fullpath.c_str())) {
163 XMLProperty* prop = tree.root()->property ("name");
169 mi.name = prop->value ();
172 map_info.push_back (mi);
179 GenericMidiControlProtocol::drop_all ()
181 Glib::Threads::Mutex::Lock lm (pending_lock);
182 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
184 for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
187 controllables.clear ();
189 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
192 pending_controllables.clear ();
194 for (MIDIFunctions::iterator i = functions.begin(); i != functions.end(); ++i) {
199 for (MIDIActions::iterator i = actions.begin(); i != actions.end(); ++i) {
206 GenericMidiControlProtocol::drop_bindings ()
208 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
210 for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ) {
211 if (!(*i)->learned()) {
213 i = controllables.erase (i);
219 for (MIDIFunctions::iterator i = functions.begin(); i != functions.end(); ++i) {
224 _current_binding = "";
230 GenericMidiControlProtocol::set_active (bool /*yn*/)
232 /* start/stop delivery/outbound thread */
237 GenericMidiControlProtocol::set_feedback_interval (microseconds_t ms)
239 _feedback_interval = ms;
243 GenericMidiControlProtocol::send_feedback ()
245 /* This is executed in RT "process" context", so no blocking calls
252 microseconds_t now = get_microseconds ();
254 if (last_feedback_time != 0) {
255 if ((now - last_feedback_time) < _feedback_interval) {
262 last_feedback_time = now;
266 GenericMidiControlProtocol::_send_feedback ()
268 /* This is executed in RT "process" context", so no blocking calls
271 const int32_t bufsize = 16 * 1024; /* XXX too big */
272 MIDI::byte buf[bufsize];
273 int32_t bsize = bufsize;
275 /* XXX: due to bugs in some ALSA / JACK MIDI bridges, we have to do separate
276 writes for each controllable here; if we send more than one MIDI message
277 in a single jack_midi_event_write then some bridges will only pass the
281 Glib::Threads::Mutex::Lock lm (controllables_lock, Glib::Threads::TRY_LOCK);
286 for (MIDIControllables::iterator r = controllables.begin(); r != controllables.end(); ++r) {
287 MIDI::byte* end = (*r)->write_feedback (buf, bsize);
289 _output_port->write (buf, (int32_t) (end - buf), 0);
295 GenericMidiControlProtocol::start_learning (Controllable* c)
301 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
303 MIDIControllables::iterator tmp;
304 for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ) {
307 if ((*i)->get_controllable() == c) {
309 controllables.erase (i);
315 Glib::Threads::Mutex::Lock lm (pending_lock);
317 MIDIPendingControllables::iterator ptmp;
318 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ) {
321 if (((*i)->first)->get_controllable() == c) {
322 (*i)->second.disconnect();
325 pending_controllables.erase (i);
331 MIDIControllable* mc = 0;
333 for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
334 if ((*i)->get_controllable() && ((*i)->get_controllable()->id() == c->id())) {
341 mc = new MIDIControllable (this, *_input_port, *c, false);
345 Glib::Threads::Mutex::Lock lm (pending_lock);
347 MIDIPendingControllable* element = new MIDIPendingControllable;
349 c->LearningFinished.connect_same_thread (element->second, boost::bind (&GenericMidiControlProtocol::learning_stopped, this, mc));
351 pending_controllables.push_back (element);
354 mc->learn_about_external_control ();
359 GenericMidiControlProtocol::learning_stopped (MIDIControllable* mc)
361 Glib::Threads::Mutex::Lock lm (pending_lock);
362 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
364 MIDIPendingControllables::iterator tmp;
366 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ) {
370 if ( (*i)->first == mc) {
371 (*i)->second.disconnect();
373 pending_controllables.erase(i);
379 controllables.push_back (mc);
383 GenericMidiControlProtocol::stop_learning (Controllable* c)
385 Glib::Threads::Mutex::Lock lm (pending_lock);
386 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
387 MIDIControllable* dptr = 0;
389 /* learning timed out, and we've been told to consider this attempt to learn to be cancelled. find the
390 relevant MIDIControllable and remove it from the pending list.
393 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
394 if (((*i)->first)->get_controllable() == c) {
395 (*i)->first->stop_learning ();
397 (*i)->second.disconnect();
400 pending_controllables.erase (i);
409 GenericMidiControlProtocol::delete_binding (PBD::Controllable* control)
412 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
414 for (MIDIControllables::iterator iter = controllables.begin(); iter != controllables.end();) {
415 MIDIControllable* existingBinding = (*iter);
417 if (control == (existingBinding->get_controllable())) {
418 delete existingBinding;
419 iter = controllables.erase (iter);
429 GenericMidiControlProtocol::create_binding (PBD::Controllable* control, int pos, int control_number)
431 if (control != NULL) {
432 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
434 MIDI::channel_t channel = (pos & 0xf);
435 MIDI::byte value = control_number;
437 // Create a MIDIControllable
438 MIDIControllable* mc = new MIDIControllable (this, *_input_port, *control, false);
440 // Remove any old binding for this midi channel/type/value pair
441 // Note: can't use delete_binding() here because we don't know the specific controllable we want to remove, only the midi information
442 for (MIDIControllables::iterator iter = controllables.begin(); iter != controllables.end();) {
443 MIDIControllable* existingBinding = (*iter);
445 if ((existingBinding->get_control_channel() & 0xf ) == channel &&
446 existingBinding->get_control_additional() == value &&
447 (existingBinding->get_control_type() & 0xf0 ) == MIDI::controller) {
449 delete existingBinding;
450 iter = controllables.erase (iter);
457 // Update the MIDI Controllable based on the the pos param
458 // Here is where a table lookup for user mappings could go; for now we'll just wing it...
459 mc->bind_midi(channel, MIDI::controller, value);
461 controllables.push_back (mc);
466 GenericMidiControlProtocol::get_state ()
468 XMLNode* node = new XMLNode ("Protocol");
471 node->add_property (X_("name"), _name);
472 node->add_property (X_("feedback"), do_feedback ? "1" : "0");
473 snprintf (buf, sizeof (buf), "%" PRIu64, _feedback_interval);
474 node->add_property (X_("feedback_interval"), buf);
475 snprintf (buf, sizeof (buf), "%d", _threshold);
476 node->add_property (X_("threshold"), buf);
478 if (!_current_binding.empty()) {
479 node->add_property ("binding", _current_binding);
482 XMLNode* children = new XMLNode (X_("Controls"));
484 node->add_child_nocopy (*children);
486 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
487 for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
489 /* we don't care about bindings that come from a bindings map, because
490 they will all be reset/recreated when we load the relevant bindings
494 if ((*i)->get_controllable() && (*i)->learned()) {
495 children->add_child_nocopy ((*i)->get_state());
503 GenericMidiControlProtocol::set_state (const XMLNode& node, int version)
506 XMLNodeConstIterator niter;
507 const XMLProperty* prop;
509 if ((prop = node.property ("feedback")) != 0) {
510 do_feedback = (bool) atoi (prop->value().c_str());
515 if ((prop = node.property ("feedback_interval")) != 0) {
516 if (sscanf (prop->value().c_str(), "%" PRIu64, &_feedback_interval) != 1) {
517 _feedback_interval = 10000;
520 _feedback_interval = 10000;
523 if ((prop = node.property ("threshold")) != 0) {
524 if (sscanf (prop->value().c_str(), "%d", &_threshold) != 1) {
531 boost::shared_ptr<Controllable> c;
534 Glib::Threads::Mutex::Lock lm (pending_lock);
535 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
538 pending_controllables.clear ();
541 /* Load up specific bindings from the
542 * <Controls><MidiControllable>...</MidiControllable><Controls> section
546 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
547 controllables.clear ();
548 nlist = node.children(); // "Controls"
550 if (!nlist.empty()) {
551 nlist = nlist.front()->children(); // "MIDIControllable" ...
553 if (!nlist.empty()) {
554 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
556 if ((prop = (*niter)->property ("id")) != 0) {
558 ID id = prop->value ();
559 Controllable* c = Controllable::by_id (id);
562 MIDIControllable* mc = new MIDIControllable (this, *_input_port, *c, false);
564 if (mc->set_state (**niter, version) == 0) {
565 controllables.push_back (mc);
569 warning << string_compose (
570 _("Generic MIDI control: controllable %1 not found in session (ignored)"),
579 if ((prop = node.property ("binding")) != 0) {
580 for (list<MapInfo>::iterator x = map_info.begin(); x != map_info.end(); ++x) {
581 if (prop->value() == (*x).name) {
582 load_bindings ((*x).path);
592 GenericMidiControlProtocol::set_feedback (bool yn)
595 last_feedback_time = 0;
600 GenericMidiControlProtocol::get_feedback () const
606 GenericMidiControlProtocol::load_bindings (const string& xmlpath)
610 if (!state_tree.read (xmlpath.c_str())) {
611 error << string_compose(_("Could not understand MIDI bindings file %1"), xmlpath) << endmsg;
615 XMLNode* root = state_tree.root();
617 if (root->name() != X_("ArdourMIDIBindings")) {
618 error << string_compose (_("MIDI Bindings file %1 is not really a MIDI bindings file"), xmlpath) << endmsg;
622 const XMLProperty* prop;
624 if ((prop = root->property ("version")) == 0) {
631 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
632 Stateful::loading_state_version = (major * 1000) + minor;
635 const XMLNodeList& children (root->children());
636 XMLNodeConstIterator citer;
637 XMLNodeConstIterator gciter;
639 MIDIControllable* mc;
643 for (citer = children.begin(); citer != children.end(); ++citer) {
645 if ((*citer)->name() == "DeviceInfo") {
646 const XMLProperty* prop;
648 if ((prop = (*citer)->property ("bank-size")) != 0) {
649 _bank_size = atoi (prop->value());
653 if ((prop = (*citer)->property ("motorised")) != 0 || ((prop = (*citer)->property ("motorized")) != 0)) {
654 _motorised = string_is_affirmative (prop->value ());
659 if ((prop = (*citer)->property ("threshold")) != 0) {
660 _threshold = atoi (prop->value ());
667 if ((*citer)->name() == "Binding") {
668 const XMLNode* child = *citer;
670 if (child->property ("uri")) {
673 if ((mc = create_binding (*child)) != 0) {
674 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
675 controllables.push_back (mc);
678 } else if (child->property ("function")) {
683 if ((mf = create_function (*child)) != 0) {
684 functions.push_back (mf);
687 } else if (child->property ("action")) {
690 if ((ma = create_action (*child)) != 0) {
691 actions.push_back (ma);
697 if ((prop = root->property ("name")) != 0) {
698 _current_binding = prop->value ();
701 reset_controllables ();
707 GenericMidiControlProtocol::create_binding (const XMLNode& node)
709 const XMLProperty* prop;
711 MIDI::channel_t channel;
717 if ((prop = node.property (X_("ctl"))) != 0) {
718 ev = MIDI::controller;
719 } else if ((prop = node.property (X_("note"))) != 0) {
721 } else if ((prop = node.property (X_("pgm"))) != 0) {
723 } else if ((prop = node.property (X_("pb"))) != 0) {
724 ev = MIDI::pitchbend;
729 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
733 detail = (MIDI::byte) intval;
735 if ((prop = node.property (X_("channel"))) == 0) {
739 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
742 channel = (MIDI::channel_t) intval;
743 /* adjust channel to zero-based counting */
748 if ((prop = node.property (X_("momentary"))) != 0) {
749 momentary = string_is_affirmative (prop->value());
754 prop = node.property (X_("uri"));
757 MIDIControllable* mc = new MIDIControllable (this, *_input_port, momentary);
759 if (mc->init (uri)) {
764 mc->bind_midi (channel, ev, detail);
770 GenericMidiControlProtocol::reset_controllables ()
772 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
774 for (MIDIControllables::iterator iter = controllables.begin(); iter != controllables.end(); ) {
775 MIDIControllable* existingBinding = (*iter);
776 MIDIControllables::iterator next = iter;
779 if (!existingBinding->learned()) {
780 ControllableDescriptor& desc (existingBinding->descriptor());
783 desc.set_bank_offset (_current_bank * _bank_size);
786 /* its entirely possible that the session doesn't have
787 * the specified controllable (e.g. it has too few
788 * tracks). if we find this to be the case, we just leave
789 * the binding around, unbound, and it will do "late
790 * binding" (or "lazy binding") if/when any data arrives.
793 existingBinding->lookup_controllable ();
800 boost::shared_ptr<Controllable>
801 GenericMidiControlProtocol::lookup_controllable (const ControllableDescriptor& desc) const
803 return session->controllable_by_descriptor (desc);
807 GenericMidiControlProtocol::create_function (const XMLNode& node)
809 const XMLProperty* prop;
811 MIDI::byte detail = 0;
812 MIDI::channel_t channel = 0;
815 MIDI::byte* data = 0;
816 uint32_t data_size = 0;
819 if ((prop = node.property (X_("ctl"))) != 0) {
820 ev = MIDI::controller;
821 } else if ((prop = node.property (X_("note"))) != 0) {
823 } else if ((prop = node.property (X_("pgm"))) != 0) {
825 } else if ((prop = node.property (X_("sysex"))) != 0 || (prop = node.property (X_("msg"))) != 0) {
827 if (prop->name() == X_("sysex")) {
838 stringstream ss (prop->value());
850 data = new MIDI::byte[cnt];
854 stringstream ss (prop->value());
859 data[cnt++] = (MIDI::byte) val;
864 warning << "Binding ignored - unknown type" << endmsg;
868 if (data_size == 0) {
869 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
873 detail = (MIDI::byte) intval;
875 if ((prop = node.property (X_("channel"))) == 0) {
879 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
882 channel = (MIDI::channel_t) intval;
883 /* adjust channel to zero-based counting */
889 if ((prop = node.property (X_("arg"))) != 0 || (prop = node.property (X_("argument"))) != 0 || (prop = node.property (X_("arguments"))) != 0) {
890 argument = prop->value ();
893 prop = node.property (X_("function"));
895 MIDIFunction* mf = new MIDIFunction (*_input_port);
897 if (mf->setup (*this, prop->value(), argument, data, data_size)) {
902 mf->bind_midi (channel, ev, detail);
908 GenericMidiControlProtocol::create_action (const XMLNode& node)
910 const XMLProperty* prop;
912 MIDI::byte detail = 0;
913 MIDI::channel_t channel = 0;
916 MIDI::byte* data = 0;
917 uint32_t data_size = 0;
919 if ((prop = node.property (X_("ctl"))) != 0) {
920 ev = MIDI::controller;
921 } else if ((prop = node.property (X_("note"))) != 0) {
923 } else if ((prop = node.property (X_("pgm"))) != 0) {
925 } else if ((prop = node.property (X_("sysex"))) != 0 || (prop = node.property (X_("msg"))) != 0) {
927 if (prop->name() == X_("sysex")) {
938 stringstream ss (prop->value());
950 data = new MIDI::byte[cnt];
954 stringstream ss (prop->value());
959 data[cnt++] = (MIDI::byte) val;
964 warning << "Binding ignored - unknown type" << endmsg;
968 if (data_size == 0) {
969 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
973 detail = (MIDI::byte) intval;
975 if ((prop = node.property (X_("channel"))) == 0) {
979 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
982 channel = (MIDI::channel_t) intval;
983 /* adjust channel to zero-based counting */
989 prop = node.property (X_("action"));
991 MIDIAction* ma = new MIDIAction (*_input_port);
993 if (ma->init (*this, prop->value(), data, data_size)) {
998 ma->bind_midi (channel, ev, detail);
1004 GenericMidiControlProtocol::set_current_bank (uint32_t b)
1007 reset_controllables ();
1011 GenericMidiControlProtocol::next_bank ()
1014 reset_controllables ();
1018 GenericMidiControlProtocol::prev_bank()
1020 if (_current_bank) {
1022 reset_controllables ();
1027 GenericMidiControlProtocol::set_motorised (bool m)
1033 GenericMidiControlProtocol::set_threshold (int t)