infrastructure for MIDI-input-follows-selection
authorPaul Davis <paul@linuxaudiosystems.com>
Wed, 19 Oct 2016 21:17:30 +0000 (17:17 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Wed, 19 Oct 2016 21:49:35 +0000 (17:49 -0400)
libs/ardour/ardour/port_manager.h
libs/ardour/ardour/session.h
libs/ardour/port_manager.cc
libs/ardour/session_midi.cc
libs/ardour/session_state.cc

index 6433b1bd6d4ceab5b0bf518d51b1d88dac70490d..7cc1125bcc5fa76689365d31973bb60fb9cddcde 100644 (file)
@@ -134,6 +134,10 @@ class LIBARDOUR_API PortManager
        void add_to_midi_selection_ports (std::string const&);
        void remove_from_midi_selection_ports (std::string const&);
        void clear_midi_selection_ports ();
+       bool port_is_for_midi_selection (std::string const&);
+
+       /** Emitted if the list of ports to be used for MIDI selection tracking changes */
+       PBD::Signal0<void> MidiSelectionPortsChanged;
 
        /** Emitted if the backend notifies us of a graph order event */
        PBD::Signal0<void> GraphReordered;
index 4b17d7d8553cd74d699e934d2a322049c80c7c81..6d05af8beb7c9d071b61ec43fb09b255757a88f1 100644 (file)
@@ -2037,6 +2037,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
 
        void midi_track_presentation_info_changed (PBD::PropertyChange const &, boost::weak_ptr<MidiTrack>);
        void rewire_selected_midi (boost::shared_ptr<MidiTrack>);
+       void rewire_midi_selection_ports ();
        boost::weak_ptr<MidiTrack> current_midi_target;
 };
 
index d24c929930c25a5c0dcca746cdcff0c7342e8a2d..febef6aa4fcc0b35cadfa942f22ae5dee4e90dd7 100644 (file)
@@ -852,6 +852,13 @@ PortManager::port_is_control_only (std::string const& name)
        return regexec (&compiled_pattern, name.c_str(), 0, 0, 0) == 0;
 }
 
+bool
+PortManager::port_is_for_midi_selection (std::string const & name)
+{
+       Glib::Threads::Mutex::Lock lm (midi_selection_ports_mutex);
+       return find (_midi_selection_ports.begin(), _midi_selection_ports.end(), name) != _midi_selection_ports.end();
+}
+
 void
 PortManager::get_midi_selection_ports (MidiSelectionPorts& copy) const
 {
@@ -862,25 +869,47 @@ PortManager::get_midi_selection_ports (MidiSelectionPorts& copy) const
 void
 PortManager::add_to_midi_selection_ports (string const & port)
 {
-       Glib::Threads::Mutex::Lock lm (midi_selection_ports_mutex);
-       if (find (_midi_selection_ports.begin(), _midi_selection_ports.end(), port) == _midi_selection_ports.end()) {
-               _midi_selection_ports.push_back (port);
+       bool emit = false;
+
+       {
+               Glib::Threads::Mutex::Lock lm (midi_selection_ports_mutex);
+               if (find (_midi_selection_ports.begin(), _midi_selection_ports.end(), port) == _midi_selection_ports.end()) {
+                       _midi_selection_ports.push_back (port);
+                       emit = true;
+               }
+       }
+
+       if (emit) {
+               MidiSelectionPortsChanged (); /* EMIT SIGNAL */
        }
 }
 
 void
 PortManager::remove_from_midi_selection_ports (string const & port)
 {
-       Glib::Threads::Mutex::Lock lm (midi_selection_ports_mutex);
-       MidiSelectionPorts::iterator x = find (_midi_selection_ports.begin(), _midi_selection_ports.end(), port);
-       if (x != _midi_selection_ports.end()) {
-               _midi_selection_ports.erase (x);
+       bool emit = false;
+
+       {
+               Glib::Threads::Mutex::Lock lm (midi_selection_ports_mutex);
+               MidiSelectionPorts::iterator x = find (_midi_selection_ports.begin(), _midi_selection_ports.end(), port);
+               if (x != _midi_selection_ports.end()) {
+                       _midi_selection_ports.erase (x);
+                       emit = true;
+               }
+       }
+
+       if (emit) {
+               MidiSelectionPortsChanged (); /* EMIT SIGNAL */
        }
 }
 
 void
 PortManager::clear_midi_selection_ports ()
 {
-       Glib::Threads::Mutex::Lock lm (midi_selection_ports_mutex);
-       _midi_selection_ports.clear ();
+       {
+               Glib::Threads::Mutex::Lock lm (midi_selection_ports_mutex);
+               _midi_selection_ports.clear ();
+       }
+
+       MidiSelectionPortsChanged (); /* EMIT SIGNAL */
 }
index 5ed2b05e9a04a3062e2c5f4d6df35cc4062297a3..671e919c6d2338a058d2f872b58889122e5bc80f 100644 (file)
@@ -737,6 +737,7 @@ Session::midi_track_presentation_info_changed (PropertyChange const& what_change
        boost::shared_ptr<MidiTrack> new_midi_target (mt.lock ());
 
        if (new_midi_target->presentation_info().selected()) {
+               cerr << "Rewiring " << new_midi_target->name() << endl;
                rewire_selected_midi (new_midi_target);
        }
 }
@@ -755,22 +756,54 @@ Session::rewire_selected_midi (boost::shared_ptr<MidiTrack> new_midi_target)
        }
 
        PortManager::MidiSelectionPorts msp;
+       AudioEngine::instance()->get_midi_selection_ports (msp);
+
+       if (!msp.empty()) {
+               if (old_midi_target) {
+                       for (PortManager::MidiSelectionPorts::const_iterator p = msp.begin(); p != msp.end(); ++p) {
+                               old_midi_target->input()->disconnect (old_midi_target->input()->nth (0), (*p), this);
+                       }
+               }
+
+               for (PortManager::MidiSelectionPorts::const_iterator p = msp.begin(); p != msp.end(); ++p) {
+                       new_midi_target->input()->connect (new_midi_target->input()->nth(0), (*p), this);
+               }
+       }
 
+       current_midi_target = new_midi_target;
+}
+
+void
+Session::rewire_midi_selection_ports ()
+{
+       cerr << "RMSP\n";
+
+       if (!Config->get_midi_input_follows_selection()) {
+               cerr << "nope\n";
+               return;
+       }
+
+       boost::shared_ptr<MidiTrack> target = current_midi_target.lock();
+
+       if (!target) {
+               cerr << "no target\n";
+               return;
+       }
+
+       PortManager::MidiSelectionPorts msp;
        AudioEngine::instance()->get_midi_selection_ports (msp);
 
        if (msp.empty()) {
+               cerr << "no MSP\n";
                return;
        }
 
-       if (old_midi_target) {
-               for (PortManager::MidiSelectionPorts::const_iterator p = msp.begin(); p != msp.end(); ++p) {
-                       old_midi_target->input()->disconnect (old_midi_target->input()->nth (0), (*p), this);
-               }
-       }
+       cerr << "2. Rewiring " << target->name() << endl;
+
+       target->input()->disconnect (this);
 
        for (PortManager::MidiSelectionPorts::const_iterator p = msp.begin(); p != msp.end(); ++p) {
-               new_midi_target->input()->connect (new_midi_target->input()->nth(0), (*p), this);
+               cerr << "\tconnect to " << *p << endl;
+               target->input()->connect (target->input()->nth (0), (*p), this);
        }
-
-       current_midi_target = new_midi_target;
 }
index ba0474f741d1757fc1691bde04d332f70bdaf806..66eba307cded3c45f28a5371b67ce3502f23395c 100644 (file)
@@ -270,6 +270,7 @@ Session::post_engine_init ()
 
                SndFileSource::setup_standard_crossfades (*this, frame_rate());
                _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this));
+               _engine.MidiSelectionPortsChanged.connect_same_thread (*this, boost::bind (&Session::rewire_midi_selection_ports, this));
 
                AudioDiskstream::allocate_working_buffers();
                refresh_disk_space ();