#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"
using namespace Gtk;
IOSelector::IOSelector (Gtk::Window* p, ARDOUR::Session* session, boost::shared_ptr<ARDOUR::IO> io)
- : PortMatrix (p, session, io->default_type())
+ : PortMatrix (p, session, DataType::NIL)
, _io (io)
{
+ setup_type ();
+
/* signal flow from 0 to 1 */
_find_inputs_for_io_outputs = (_io->direction() == IO::Output);
_port_group.reset (new PortGroup (io->name()));
_ports[_ours].add_group (_port_group);
+ io->changed.connect (_io_connection, invalidator (*this), boost::bind (&IOSelector::io_changed_proxy, this), gui_context ());
+
setup_all_ports ();
init ();
}
+void
+IOSelector::setup_type ()
+{
+ /* set type according to what's in the IO */
+
+ int N = 0;
+ DataType type_with_ports = DataType::NIL;
+ for (DataType::iterator i = DataType::begin(); i != DataType::end(); ++i) {
+ if (_io->ports().num_ports (*i)) {
+ type_with_ports = *i;
+ ++N;
+ }
+ }
+
+ if (N <= 1) {
+ set_type (type_with_ports);
+ } else {
+ set_type (DataType::NIL);
+ }
+}
+
+void
+IOSelector::io_changed_proxy ()
+{
+ /* The IO's changed signal is emitted from code that holds its route's processor lock,
+ so we can't call setup_all_ports (which results in a call to Route::foreach_processor)
+ without a deadlock unless we break things up with this idle handler.
+ */
+
+ Glib::signal_idle().connect_once (sigc::mem_fun (*this, &IOSelector::io_changed));
+}
+
+void
+IOSelector::io_changed ()
+{
+ setup_type ();
+ setup_all_ports ();
+}
+
void
IOSelector::setup_ports (int dim)
{
if (!_session) {
return;
}
-
+
_ports[dim].suspend_signals ();
if (dim == _other) {
- _ports[_other].gather (_session, _find_inputs_for_io_outputs, false);
+ _ports[_other].gather (_session, type(), _find_inputs_for_io_outputs, false);
} else {
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)
{
}
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 ()
{
{
set_name ("IOSelectorWindow");
- string title = _("ardour: ");
+ string title = _("Port Insert ");
title += pi->name();
set_title (title);
signal_delete_event().connect (sigc::mem_fun (*this, &PortInsertWindow::wm_delete), false);
- pi->DropReferences.connect (going_away_connection, boost::bind (&PortInsertWindow::plugin_going_away, this), gui_context());
+ pi->DropReferences.connect (going_away_connection, invalidator (*this), boost::bind (&PortInsertWindow::plugin_going_away, this), gui_context());
}
bool