summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2009-10-05 17:17:44 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2009-10-05 17:17:44 +0000
commitb96d96f3f97b3fdbc541ff83d29b339a4a85f92d (patch)
treef2c2f37ee3d396402e2ffc0801d06cb93267c9f6
parentd31649b4b4d2ef9a4d638abffdf39f09ee5058fc (diff)
provide jdelay-based hardware/port insert latency measurement
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@5729 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/io_selector.cc83
-rw-r--r--gtk2_ardour/io_selector.h15
-rw-r--r--libs/ardour/SConscript1
-rw-r--r--libs/ardour/ardour/insert.h13
-rw-r--r--libs/ardour/insert.cc83
5 files changed, 180 insertions, 15 deletions
diff --git a/gtk2_ardour/io_selector.cc b/gtk2_ardour/io_selector.cc
index 0f877206f7..30c50e9252 100644
--- a/gtk2_ardour/io_selector.cc
+++ b/gtk2_ardour/io_selector.cc
@@ -30,6 +30,7 @@
#include <ardour/route.h>
#include <ardour/audioengine.h>
#include <ardour/port.h>
+#include <ardour/mtdm.h>
#include <ardour/insert.h>
#include <ardour/session.h>
#include <ardour/audio_diskstream.h>
@@ -141,8 +142,8 @@ IOSelector::IOSelector (Session& sess, boost::shared_ptr<IO> ior, bool input)
io (ior),
for_input (input),
port_frame (for_input? _("Inputs") : _("Outputs")),
- add_port_button (for_input? _("Add Input") : _("Add Output")),
- remove_port_button (for_input? _("Remove Input") : _("Remove Output")),
+ add_port_button (for_input? _("Add") : _("Add")),
+ remove_port_button (for_input? _("Remove") : _("Remove")),
clear_connections_button (_("Disconnect All"))
{
selected_port = 0;
@@ -717,20 +718,92 @@ IOSelector::redisplay ()
}
PortInsertUI::PortInsertUI (Session& sess, boost::shared_ptr<PortInsert> pi)
- : input_selector (sess, pi, true),
- output_selector (sess, pi, false)
+ : _pi (pi)
+ , latency_button (_("Measure Latency"))
+ , input_selector (sess, pi, true)
+ , output_selector (sess, pi, false)
{
+ latency_hbox.pack_start (latency_button, false, false);
+ latency_hbox.pack_start (latency_display, false, false);
+ latency_frame.add (latency_hbox);
+
hbox.pack_start (output_selector, true, true);
hbox.pack_start (input_selector, true, true);
+ set_spacing (6);
+ set_border_width (12);
+ pack_start (latency_frame);
pack_start (hbox);
+
+ 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 = input_selector.session.engine().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::redisplay()
+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()
+{
input_selector.redisplay();
output_selector.redisplay();
}
diff --git a/gtk2_ardour/io_selector.h b/gtk2_ardour/io_selector.h
index 957db11a2b..5880b74202 100644
--- a/gtk2_ardour/io_selector.h
+++ b/gtk2_ardour/io_selector.h
@@ -34,6 +34,7 @@ using __gnu_cxx::slist;
#include <gtkmm/box.h>
#include <gtkmm/frame.h>
#include <gtkmm/button.h>
+#include <gtkmm/togglebutton.h>
#include <gtkmm/scrolledwindow.h>
#include <gtkmm/notebook.h>
#include <gtkmm/treeview.h>
@@ -64,7 +65,6 @@ class IOSelector : public Gtk::VBox {
sigc::signal<void,Result> Finished;
- protected:
ARDOUR::Session& session;
private:
@@ -157,7 +157,6 @@ class IOSelectorWindow : public ArdourDialog
void accept ();
};
-
class PortInsertUI : public Gtk::VBox
{
public:
@@ -167,11 +166,19 @@ class PortInsertUI : public Gtk::VBox
void finished (IOSelector::Result);
private:
-
+ boost::shared_ptr<ARDOUR::PortInsert> _pi;
+
+ Gtk::ToggleButton latency_button;
+ Gtk::Label latency_display;
+ Gtk::Frame latency_frame;
+ Gtk::HBox latency_hbox;
+ sigc::connection latency_timeout;
+ bool check_latency_measurement ();
+ void latency_button_toggled ();
+
Gtk::HBox hbox;
IOSelector input_selector;
IOSelector output_selector;
-
};
class PortInsertWindow : public ArdourDialog
diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript
index 6dfc62ecbc..1d96fd0777 100644
--- a/libs/ardour/SConscript
+++ b/libs/ardour/SConscript
@@ -65,6 +65,7 @@ ladspa_plugin.cc
location.cc
mix.cc
mtc_slave.cc
+mtdm.cc
named_selection.cc
onset_detector.cc
panner.cc
diff --git a/libs/ardour/ardour/insert.h b/libs/ardour/ardour/insert.h
index c401a2062e..7baebe401c 100644
--- a/libs/ardour/ardour/insert.h
+++ b/libs/ardour/ardour/insert.h
@@ -30,6 +30,7 @@
#include <ardour/types.h>
class XMLNode;
+class MTDM;
namespace MIDI {
class Port;
@@ -81,8 +82,18 @@ class PortInsert : public Insert
int32_t configure_io (int32_t magic, int32_t in, int32_t out);
uint32_t bit_slot() const { return bitslot; }
+ void start_latency_detection ();
+ void stop_latency_detection ();
+
+ MTDM* mtdm () const { return _mtdm; }
+ void set_measured_latency (nframes_t);
+
private:
- uint32_t bitslot;
+ uint32_t bitslot;
+ MTDM* _mtdm;
+ bool _latency_detect;
+ nframes_t _latency_flush_frames;
+ nframes_t _measured_latency;
};
class PluginInsert : public Insert
diff --git a/libs/ardour/insert.cc b/libs/ardour/insert.cc
index 3214182c4f..721c61f593 100644
--- a/libs/ardour/insert.cc
+++ b/libs/ardour/insert.cc
@@ -26,6 +26,7 @@
#include <pbd/stacktrace.h>
#include <ardour/insert.h>
+#include <ardour/mtdm.h>
#include <ardour/plugin.h>
#include <ardour/port.h>
#include <ardour/route.h>
@@ -905,12 +906,19 @@ PortInsert::PortInsert (const PortInsert& other)
void
PortInsert::init ()
{
+ _mtdm = 0;
+ _latency_detect = false;
+ _latency_flush_frames = false;
+ _measured_latency = 0;
}
PortInsert::PortInsert (Session& s, const XMLNode& node)
: Insert (s, "will change", PreFader)
{
+ init ();
+
bitslot = 0xffffffff;
+
if (set_state (node)) {
throw failed_constructor();
}
@@ -920,33 +928,94 @@ PortInsert::PortInsert (Session& s, const XMLNode& node)
PortInsert::~PortInsert ()
{
+ delete _mtdm;
GoingAway ();
}
void
+PortInsert::start_latency_detection ()
+{
+ if (_mtdm != 0) {
+ delete _mtdm;
+ }
+
+ _mtdm = new MTDM;
+ _latency_flush_frames = false;
+ _latency_detect = true;
+ _measured_latency = 0;
+}
+
+void
+PortInsert::stop_latency_detection ()
+{
+ _latency_flush_frames = latency() + _session.engine().frames_per_cycle();
+ _latency_detect = false;
+}
+
+void
+PortInsert::set_measured_latency (nframes_t n)
+{
+ _measured_latency = n;
+}
+
+void
PortInsert::run (vector<Sample *>& bufs, uint32_t nbufs, nframes_t nframes)
{
if (n_outputs() == 0) {
return;
}
+ vector<Port*>::iterator o;
+
+ if (_latency_detect) {
+
+ if (n_inputs() != 0) {
+ Sample* in = get_input_buffer (0, nframes);
+ Sample* out = get_output_buffer (0, nframes);
+
+ _mtdm->process (nframes, in, out);
+
+ for (o = _outputs.begin(); o != _outputs.end(); ++o) {
+ (*o)->mark_silence (false);
+ }
+ }
+
+ return;
+
+ } else if (_latency_flush_frames) {
+
+ /* wait for the entire input buffer to drain before picking up input again so that we can't
+ hear the remnants of whatever MTDM pumped into the pipeline.
+ */
+
+ silence (nframes);
+
+ if (_latency_flush_frames > nframes) {
+ _latency_flush_frames -= nframes;
+ } else {
+ _latency_flush_frames = 0;
+ }
+
+ return;
+ }
+
if (!active()) {
/* deliver silence */
silence (nframes);
return;
}
- uint32_t n;
- vector<Port*>::iterator o;
- vector<Port*>::iterator i;
-
/* deliver output */
+ uint32_t n;
+
for (o = _outputs.begin(), n = 0; o != _outputs.end(); ++o, ++n) {
memcpy (get_output_buffer (n, nframes), bufs[min(nbufs,n)], sizeof (Sample) * nframes);
(*o)->mark_silence (false);
}
+ vector<Port*>::iterator i;
+
/* collect input */
for (i = _inputs.begin(), n = 0; i != _inputs.end(); ++i, ++n) {
@@ -1027,7 +1096,11 @@ PortInsert::latency()
need to take that into account too.
*/
- return _session.engine().frames_per_cycle() + input_latency();
+ if (_measured_latency == 0) {
+ return _session.engine().frames_per_cycle() + input_latency();
+ } else {
+ return _measured_latency;
+ }
}
int32_t