Fix handling of the mapping between parameters and automation CheckMenuItems. Should...
[ardour.git] / gtk2_ardour / io_selector.cc
index 77f917d92b275bb4df93b6e6db303d81dd396fc3..913fa6dafe4c7629bda9c1cf6b70d93c6488f04a 100644 (file)
@@ -29,6 +29,7 @@
 #include "ardour/track.h"
 #include "ardour/audio_track.h"
 #include "ardour/midi_track.h"
+#include "ardour/mtdm.h"
 #include "ardour/data_type.h"
 #include "ardour/port.h"
 #include "ardour/bundle.h"
@@ -156,13 +157,27 @@ IOSelector::list_is_global (int dim) const
        return (dim == _other);
 }
 
+string
+IOSelector::disassociation_verb () const
+{
+       return _("Disconnect");
+}
+
+string
+IOSelector::channel_noun () const
+{
+       return _("port");
+}
+
 IOSelectorWindow::IOSelectorWindow (ARDOUR::Session* session, boost::shared_ptr<ARDOUR::IO> io, bool /*can_cancel*/)
        : _selector (this, session, io)
 {
        set_name ("IOSelectorWindow2");
        set_title (_("I/O selector"));
 
-       add (_selector);
+       Gtk::Alignment* alignment = manage(new Gtk::Alignment(0.5, 0.5, 0.0, 0.0));
+       alignment->add (_selector);
+       add (*alignment);
 
        set_position (Gtk::WIN_POS_MOUSE);
 
@@ -214,16 +229,88 @@ IOSelectorWindow::io_name_changed (void* src)
 }
 
 PortInsertUI::PortInsertUI (Gtk::Window* parent, ARDOUR::Session* sess, boost::shared_ptr<ARDOUR::PortInsert> pi)
-       : input_selector (parent, sess, pi->input())
-       , output_selector (parent, sess, pi->output())
+        : _pi (pi)
+        , latency_button (_("Measure Latency"))
+        , input_selector (parent, sess, pi->input())
+        , output_selector (parent, sess, pi->output())
 {
+        latency_hbox.pack_start (latency_button, false, false);
+        latency_hbox.pack_start (latency_display, false, false);
+        latency_frame.add (latency_hbox);
+        
        output_selector.set_min_height_divisor (2);
        input_selector.set_min_height_divisor (2);
-
+        
+        pack_start (latency_frame);
        pack_start (output_selector, true, true);
        pack_start (input_selector, true, true);
+
+        latency_button.signal_toggled().connect (mem_fun (*this, &PortInsertUI::latency_button_toggled));
 }
 
+bool
+PortInsertUI::check_latency_measurement ()
+{
+        MTDM* mtdm = _pi->mtdm ();
+
+        if (mtdm->resolve () < 0) {
+                latency_display.set_text (_("No signal detected"));
+                return true;
+        }
+
+        if (mtdm->err () > 0.3) {
+                mtdm->invert ();
+                mtdm->resolve ();
+        }
+
+        char buf[64];
+        nframes_t sample_rate = AudioEngine::instance()->frame_rate();
+
+        if (sample_rate == 0) {
+                latency_display.set_text (_("Disconnected from audio engine"));
+                _pi->stop_latency_detection ();
+                return false;
+        }
+
+        snprintf (buf, sizeof (buf), "%10.3lf frames %10.3lf ms", mtdm->del (), mtdm->del () * 1000.0f/sample_rate);
+
+        bool solid = true;
+
+        if (mtdm->err () > 0.2) {
+                strcat (buf, " ??");
+                solid = false;
+        }
+
+        if (mtdm->inv ()) {
+                strcat (buf, " (Inv)");
+                solid = false;
+        }
+
+        if (solid) {
+                _pi->set_measured_latency ((nframes_t) rint (mtdm->del()));
+                strcat (buf, " (set)");
+        }
+
+        latency_display.set_text (buf);
+        return true;
+}
+
+void
+PortInsertUI::latency_button_toggled ()
+{
+        if (latency_button.get_active ()) {
+
+                _pi->start_latency_detection ();
+                latency_display.set_text (_("Detecting ..."));
+                latency_timeout = Glib::signal_timeout().connect (mem_fun (*this, &PortInsertUI::check_latency_measurement), 250);
+
+        } else {
+                _pi->stop_latency_detection ();
+                latency_timeout.disconnect ();
+        }
+}
+
+
 void
 PortInsertUI::redisplay ()
 {
@@ -247,7 +334,7 @@ PortInsertWindow::PortInsertWindow (ARDOUR::Session* sess, boost::shared_ptr<ARD
 {
 
        set_name ("IOSelectorWindow");
-       string title = _("ardour: ");
+       string title = _("Port Insert ");
        title += pi->name();
        set_title (title);
 
@@ -272,7 +359,7 @@ PortInsertWindow::PortInsertWindow (ARDOUR::Session* sess, boost::shared_ptr<ARD
 
        signal_delete_event().connect (sigc::mem_fun (*this, &PortInsertWindow::wm_delete), false);
 
-       going_away_connection = pi->GoingAway.connect (sigc::mem_fun (*this, &PortInsertWindow::plugin_going_away));
+       pi->DropReferences.connect (going_away_connection, invalidator (*this), boost::bind (&PortInsertWindow::plugin_going_away, this), gui_context());
 }
 
 bool