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/file_utils.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;
140 Searchpath spath (system_midi_map_search_path());
141 spath += user_midi_map_directory ();
143 find_files_matching_filter (midi_maps, spath, midi_map_filter, 0, false, true);
145 if (midi_maps.empty()) {
146 cerr << "No MIDI maps found using " << spath.to_string() << endl;
150 for (vector<string>::iterator i = midi_maps.begin(); i != midi_maps.end(); ++i) {
151 string fullpath = *i;
155 if (!tree.read (fullpath.c_str())) {
161 XMLProperty* prop = tree.root()->property ("name");
167 mi.name = prop->value ();
170 map_info.push_back (mi);
175 GenericMidiControlProtocol::drop_all ()
177 Glib::Threads::Mutex::Lock lm (pending_lock);
178 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
180 for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
183 controllables.clear ();
185 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
188 pending_controllables.clear ();
190 for (MIDIFunctions::iterator i = functions.begin(); i != functions.end(); ++i) {
195 for (MIDIActions::iterator i = actions.begin(); i != actions.end(); ++i) {
202 GenericMidiControlProtocol::drop_bindings ()
204 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
206 for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ) {
207 if (!(*i)->learned()) {
209 i = controllables.erase (i);
215 for (MIDIFunctions::iterator i = functions.begin(); i != functions.end(); ++i) {
220 _current_binding = "";
226 GenericMidiControlProtocol::set_active (bool /*yn*/)
228 /* start/stop delivery/outbound thread */
233 GenericMidiControlProtocol::set_feedback_interval (microseconds_t ms)
235 _feedback_interval = ms;
239 GenericMidiControlProtocol::send_feedback ()
241 /* This is executed in RT "process" context", so no blocking calls
248 microseconds_t now = get_microseconds ();
250 if (last_feedback_time != 0) {
251 if ((now - last_feedback_time) < _feedback_interval) {
258 last_feedback_time = now;
262 GenericMidiControlProtocol::_send_feedback ()
264 /* This is executed in RT "process" context", so no blocking calls
267 const int32_t bufsize = 16 * 1024; /* XXX too big */
268 MIDI::byte buf[bufsize];
269 int32_t bsize = bufsize;
271 /* XXX: due to bugs in some ALSA / JACK MIDI bridges, we have to do separate
272 writes for each controllable here; if we send more than one MIDI message
273 in a single jack_midi_event_write then some bridges will only pass the
277 Glib::Threads::Mutex::Lock lm (controllables_lock, Glib::Threads::TRY_LOCK);
282 for (MIDIControllables::iterator r = controllables.begin(); r != controllables.end(); ++r) {
283 MIDI::byte* end = (*r)->write_feedback (buf, bsize);
285 _output_port->write (buf, (int32_t) (end - buf), 0);
291 GenericMidiControlProtocol::start_learning (Controllable* c)
297 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
299 MIDIControllables::iterator tmp;
300 for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ) {
303 if ((*i)->get_controllable() == c) {
305 controllables.erase (i);
311 Glib::Threads::Mutex::Lock lm (pending_lock);
313 MIDIPendingControllables::iterator ptmp;
314 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ) {
317 if (((*i)->first)->get_controllable() == c) {
318 (*i)->second.disconnect();
321 pending_controllables.erase (i);
327 MIDIControllable* mc = 0;
329 for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
330 if ((*i)->get_controllable() && ((*i)->get_controllable()->id() == c->id())) {
337 mc = new MIDIControllable (this, *_input_port->parser(), *c, false);
341 Glib::Threads::Mutex::Lock lm (pending_lock);
343 MIDIPendingControllable* element = new MIDIPendingControllable;
345 c->LearningFinished.connect_same_thread (element->second, boost::bind (&GenericMidiControlProtocol::learning_stopped, this, mc));
347 pending_controllables.push_back (element);
350 mc->learn_about_external_control ();
355 GenericMidiControlProtocol::learning_stopped (MIDIControllable* mc)
357 Glib::Threads::Mutex::Lock lm (pending_lock);
358 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
360 MIDIPendingControllables::iterator tmp;
362 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ) {
366 if ( (*i)->first == mc) {
367 (*i)->second.disconnect();
369 pending_controllables.erase(i);
375 controllables.push_back (mc);
379 GenericMidiControlProtocol::stop_learning (Controllable* c)
381 Glib::Threads::Mutex::Lock lm (pending_lock);
382 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
383 MIDIControllable* dptr = 0;
385 /* learning timed out, and we've been told to consider this attempt to learn to be cancelled. find the
386 relevant MIDIControllable and remove it from the pending list.
389 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
390 if (((*i)->first)->get_controllable() == c) {
391 (*i)->first->stop_learning ();
393 (*i)->second.disconnect();
396 pending_controllables.erase (i);
405 GenericMidiControlProtocol::delete_binding (PBD::Controllable* control)
408 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
410 for (MIDIControllables::iterator iter = controllables.begin(); iter != controllables.end();) {
411 MIDIControllable* existingBinding = (*iter);
413 if (control == (existingBinding->get_controllable())) {
414 delete existingBinding;
415 iter = controllables.erase (iter);
425 GenericMidiControlProtocol::create_binding (PBD::Controllable* control, int pos, int control_number)
427 if (control != NULL) {
428 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
430 MIDI::channel_t channel = (pos & 0xf);
431 MIDI::byte value = control_number;
433 // Create a MIDIControllable
434 MIDIControllable* mc = new MIDIControllable (this, *_input_port->parser(), *control, false);
436 // Remove any old binding for this midi channel/type/value pair
437 // Note: can't use delete_binding() here because we don't know the specific controllable we want to remove, only the midi information
438 for (MIDIControllables::iterator iter = controllables.begin(); iter != controllables.end();) {
439 MIDIControllable* existingBinding = (*iter);
441 if ((existingBinding->get_control_channel() & 0xf ) == channel &&
442 existingBinding->get_control_additional() == value &&
443 (existingBinding->get_control_type() & 0xf0 ) == MIDI::controller) {
445 delete existingBinding;
446 iter = controllables.erase (iter);
453 // Update the MIDI Controllable based on the the pos param
454 // Here is where a table lookup for user mappings could go; for now we'll just wing it...
455 mc->bind_midi(channel, MIDI::controller, value);
457 controllables.push_back (mc);
462 GenericMidiControlProtocol::get_state ()
464 XMLNode& node (ControlProtocol::get_state());
467 node.add_property (X_("feedback"), do_feedback ? "1" : "0");
468 snprintf (buf, sizeof (buf), "%" PRIu64, _feedback_interval);
469 node.add_property (X_("feedback_interval"), buf);
470 snprintf (buf, sizeof (buf), "%d", _threshold);
471 node.add_property (X_("threshold"), buf);
473 if (!_current_binding.empty()) {
474 node.add_property ("binding", _current_binding);
477 XMLNode* children = new XMLNode (X_("Controls"));
479 node.add_child_nocopy (*children);
481 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
482 for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
484 /* we don't care about bindings that come from a bindings map, because
485 they will all be reset/recreated when we load the relevant bindings
489 if ((*i)->get_controllable() && (*i)->learned()) {
490 children->add_child_nocopy ((*i)->get_state());
498 GenericMidiControlProtocol::set_state (const XMLNode& node, int version)
501 XMLNodeConstIterator niter;
502 const XMLProperty* prop;
504 if ((prop = node.property ("feedback")) != 0) {
505 do_feedback = (bool) atoi (prop->value().c_str());
510 if ((prop = node.property ("feedback_interval")) != 0) {
511 if (sscanf (prop->value().c_str(), "%" PRIu64, &_feedback_interval) != 1) {
512 _feedback_interval = 10000;
515 _feedback_interval = 10000;
518 if ((prop = node.property ("threshold")) != 0) {
519 if (sscanf (prop->value().c_str(), "%d", &_threshold) != 1) {
526 boost::shared_ptr<Controllable> c;
529 Glib::Threads::Mutex::Lock lm (pending_lock);
530 for (MIDIPendingControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
533 pending_controllables.clear ();
536 /* Load up specific bindings from the
537 * <Controls><MidiControllable>...</MidiControllable><Controls> section
541 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
542 controllables.clear ();
543 nlist = node.children(); // "Controls"
545 if (!nlist.empty()) {
546 nlist = nlist.front()->children(); // "MIDIControllable" ...
548 if (!nlist.empty()) {
549 for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
551 if ((prop = (*niter)->property ("id")) != 0) {
553 ID id = prop->value ();
554 Controllable* c = Controllable::by_id (id);
557 MIDIControllable* mc = new MIDIControllable (this, *_input_port->parser(), *c, false);
559 if (mc->set_state (**niter, version) == 0) {
560 controllables.push_back (mc);
564 warning << string_compose (
565 _("Generic MIDI control: controllable %1 not found in session (ignored)"),
574 if ((prop = node.property ("binding")) != 0) {
575 for (list<MapInfo>::iterator x = map_info.begin(); x != map_info.end(); ++x) {
576 if (prop->value() == (*x).name) {
577 load_bindings ((*x).path);
587 GenericMidiControlProtocol::set_feedback (bool yn)
590 last_feedback_time = 0;
595 GenericMidiControlProtocol::get_feedback () const
601 GenericMidiControlProtocol::load_bindings (const string& xmlpath)
605 if (!state_tree.read (xmlpath.c_str())) {
606 error << string_compose(_("Could not understand MIDI bindings file %1"), xmlpath) << endmsg;
610 XMLNode* root = state_tree.root();
612 if (root->name() != X_("ArdourMIDIBindings")) {
613 error << string_compose (_("MIDI Bindings file %1 is not really a MIDI bindings file"), xmlpath) << endmsg;
617 const XMLProperty* prop;
619 if ((prop = root->property ("version")) == 0) {
626 sscanf (prop->value().c_str(), "%d.%d.%d", &major, &minor, µ);
627 Stateful::loading_state_version = (major * 1000) + minor;
630 const XMLNodeList& children (root->children());
631 XMLNodeConstIterator citer;
632 XMLNodeConstIterator gciter;
634 MIDIControllable* mc;
638 for (citer = children.begin(); citer != children.end(); ++citer) {
640 if ((*citer)->name() == "DeviceInfo") {
641 const XMLProperty* prop;
643 if ((prop = (*citer)->property ("bank-size")) != 0) {
644 _bank_size = atoi (prop->value());
648 if ((prop = (*citer)->property ("motorised")) != 0 || ((prop = (*citer)->property ("motorized")) != 0)) {
649 _motorised = string_is_affirmative (prop->value ());
654 if ((prop = (*citer)->property ("threshold")) != 0) {
655 _threshold = atoi (prop->value ());
662 if ((*citer)->name() == "Binding") {
663 const XMLNode* child = *citer;
665 if (child->property ("uri")) {
668 if ((mc = create_binding (*child)) != 0) {
669 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
670 controllables.push_back (mc);
673 } else if (child->property ("function")) {
678 if ((mf = create_function (*child)) != 0) {
679 functions.push_back (mf);
682 } else if (child->property ("action")) {
685 if ((ma = create_action (*child)) != 0) {
686 actions.push_back (ma);
692 if ((prop = root->property ("name")) != 0) {
693 _current_binding = prop->value ();
696 reset_controllables ();
702 GenericMidiControlProtocol::create_binding (const XMLNode& node)
704 const XMLProperty* prop;
706 MIDI::channel_t channel;
712 if ((prop = node.property (X_("ctl"))) != 0) {
713 ev = MIDI::controller;
714 } else if ((prop = node.property (X_("note"))) != 0) {
716 } else if ((prop = node.property (X_("pgm"))) != 0) {
718 } else if ((prop = node.property (X_("pb"))) != 0) {
719 ev = MIDI::pitchbend;
724 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
728 detail = (MIDI::byte) intval;
730 if ((prop = node.property (X_("channel"))) == 0) {
734 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
737 channel = (MIDI::channel_t) intval;
738 /* adjust channel to zero-based counting */
743 if ((prop = node.property (X_("momentary"))) != 0) {
744 momentary = string_is_affirmative (prop->value());
749 prop = node.property (X_("uri"));
752 MIDIControllable* mc = new MIDIControllable (this, *_input_port->parser(), momentary);
754 if (mc->init (uri)) {
759 mc->bind_midi (channel, ev, detail);
765 GenericMidiControlProtocol::reset_controllables ()
767 Glib::Threads::Mutex::Lock lm2 (controllables_lock);
769 for (MIDIControllables::iterator iter = controllables.begin(); iter != controllables.end(); ) {
770 MIDIControllable* existingBinding = (*iter);
771 MIDIControllables::iterator next = iter;
774 if (!existingBinding->learned()) {
775 ControllableDescriptor& desc (existingBinding->descriptor());
778 desc.set_bank_offset (_current_bank * _bank_size);
781 /* its entirely possible that the session doesn't have
782 * the specified controllable (e.g. it has too few
783 * tracks). if we find this to be the case, we just leave
784 * the binding around, unbound, and it will do "late
785 * binding" (or "lazy binding") if/when any data arrives.
788 existingBinding->lookup_controllable ();
795 boost::shared_ptr<Controllable>
796 GenericMidiControlProtocol::lookup_controllable (const ControllableDescriptor& desc) const
798 return session->controllable_by_descriptor (desc);
802 GenericMidiControlProtocol::create_function (const XMLNode& node)
804 const XMLProperty* prop;
806 MIDI::byte detail = 0;
807 MIDI::channel_t channel = 0;
810 MIDI::byte* data = 0;
811 uint32_t data_size = 0;
814 if ((prop = node.property (X_("ctl"))) != 0) {
815 ev = MIDI::controller;
816 } else if ((prop = node.property (X_("note"))) != 0) {
818 } else if ((prop = node.property (X_("pgm"))) != 0) {
820 } else if ((prop = node.property (X_("sysex"))) != 0 || (prop = node.property (X_("msg"))) != 0) {
822 if (prop->name() == X_("sysex")) {
833 stringstream ss (prop->value());
845 data = new MIDI::byte[cnt];
849 stringstream ss (prop->value());
854 data[cnt++] = (MIDI::byte) val;
859 warning << "Binding ignored - unknown type" << endmsg;
863 if (data_size == 0) {
864 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
868 detail = (MIDI::byte) intval;
870 if ((prop = node.property (X_("channel"))) == 0) {
874 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
877 channel = (MIDI::channel_t) intval;
878 /* adjust channel to zero-based counting */
884 if ((prop = node.property (X_("arg"))) != 0 || (prop = node.property (X_("argument"))) != 0 || (prop = node.property (X_("arguments"))) != 0) {
885 argument = prop->value ();
888 prop = node.property (X_("function"));
890 MIDIFunction* mf = new MIDIFunction (*_input_port->parser());
892 if (mf->setup (*this, prop->value(), argument, data, data_size)) {
897 mf->bind_midi (channel, ev, detail);
903 GenericMidiControlProtocol::create_action (const XMLNode& node)
905 const XMLProperty* prop;
907 MIDI::byte detail = 0;
908 MIDI::channel_t channel = 0;
911 MIDI::byte* data = 0;
912 uint32_t data_size = 0;
914 if ((prop = node.property (X_("ctl"))) != 0) {
915 ev = MIDI::controller;
916 } else if ((prop = node.property (X_("note"))) != 0) {
918 } else if ((prop = node.property (X_("pgm"))) != 0) {
920 } else if ((prop = node.property (X_("sysex"))) != 0 || (prop = node.property (X_("msg"))) != 0) {
922 if (prop->name() == X_("sysex")) {
933 stringstream ss (prop->value());
945 data = new MIDI::byte[cnt];
949 stringstream ss (prop->value());
954 data[cnt++] = (MIDI::byte) val;
959 warning << "Binding ignored - unknown type" << endmsg;
963 if (data_size == 0) {
964 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
968 detail = (MIDI::byte) intval;
970 if ((prop = node.property (X_("channel"))) == 0) {
974 if (sscanf (prop->value().c_str(), "%d", &intval) != 1) {
977 channel = (MIDI::channel_t) intval;
978 /* adjust channel to zero-based counting */
984 prop = node.property (X_("action"));
986 MIDIAction* ma = new MIDIAction (*_input_port->parser());
988 if (ma->init (*this, prop->value(), data, data_size)) {
993 ma->bind_midi (channel, ev, detail);
999 GenericMidiControlProtocol::set_current_bank (uint32_t b)
1002 reset_controllables ();
1006 GenericMidiControlProtocol::next_bank ()
1009 reset_controllables ();
1013 GenericMidiControlProtocol::prev_bank()
1015 if (_current_bank) {
1017 reset_controllables ();
1022 GenericMidiControlProtocol::set_motorised (bool m)
1028 GenericMidiControlProtocol::set_threshold (int t)