summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/gain_meter.cc16
-rw-r--r--gtk2_ardour/level_meter.cc18
-rw-r--r--gtk2_ardour/level_meter.h2
-rw-r--r--gtk2_ardour/mixer_strip.cc56
-rw-r--r--gtk2_ardour/mixer_strip.h7
-rw-r--r--gtk2_ardour/panner_ui.cc19
-rw-r--r--gtk2_ardour/processor_box.cc14
-rw-r--r--gtk2_ardour/processor_box.h4
-rw-r--r--gtk2_ardour/route_params_ui.cc4
-rw-r--r--gtk2_ardour/route_ui.cc85
-rw-r--r--gtk2_ardour/route_ui.h11
-rw-r--r--libs/ardour/ardour/io.h2
-rw-r--r--libs/ardour/ardour/route.h7
-rw-r--r--libs/ardour/io.cc52
-rw-r--r--libs/ardour/route.cc52
15 files changed, 276 insertions, 73 deletions
diff --git a/gtk2_ardour/gain_meter.cc b/gtk2_ardour/gain_meter.cc
index f06597253c..597e2a2fbe 100644
--- a/gtk2_ardour/gain_meter.cc
+++ b/gtk2_ardour/gain_meter.cc
@@ -165,7 +165,13 @@ GainMeterBase::set_io (boost::shared_ptr<IO> io)
_io = io;
- level_meter->set_meter (_io->peak_meter());
+ if (!_io) {
+ level_meter->set_meter (0);
+ gain_slider->set_controllable (boost::shared_ptr<PBD::Controllable>());
+ return;
+ }
+
+ level_meter->set_meter (&_io->peak_meter());
gain_slider->set_controllable (_io->gain_control());
boost::shared_ptr<Route> r;
@@ -836,6 +842,14 @@ GainMeter::set_io (boost::shared_ptr<IO> io)
if (!r->is_hidden()) {
fader_vbox->pack_start (gain_automation_state_button, false, false, 0);
}
+
+ } else {
+
+ /* we're managing a non-Route IO (e.g. Send) */
+
+ gain_display_box.pack_end (peak_display, true, true);
+ hbox.pack_end (*level_meter, true, true);
+ fader_vbox->pack_start (gain_automation_state_button, false, false, 0);
}
}
diff --git a/gtk2_ardour/level_meter.cc b/gtk2_ardour/level_meter.cc
index 1f6cecb74d..f6d41c3312 100644
--- a/gtk2_ardour/level_meter.cc
+++ b/gtk2_ardour/level_meter.cc
@@ -80,12 +80,14 @@ LevelMeter::~LevelMeter ()
}
void
-LevelMeter::set_meter (PeakMeter& meter)
+LevelMeter::set_meter (PeakMeter* meter)
{
_configuration_connection.disconnect();
- _meter = &meter;
- _configuration_connection = _meter->ConfigurationChanged.connect(
+ _meter = meter;
+ if (_meter) {
+ _configuration_connection = _meter->ConfigurationChanged.connect(
mem_fun(*this, &LevelMeter::configuration_changed));
+ }
}
float
@@ -94,6 +96,10 @@ LevelMeter::update_meters ()
vector<MeterInfo>::iterator i;
uint32_t n;
float peak, mpeak;
+
+ if (!_meter) {
+ return 0.0f;
+ }
for (n = 0, i = meters.begin(); i != meters.end(); ++i, ++n) {
if ((*i).packed) {
@@ -149,8 +155,10 @@ LevelMeter::hide_all_meters ()
void
LevelMeter::setup_meters (int len, int initial_width)
{
+ hide_all_meters ();
+
if (!_meter) {
- return; /* do it later */
+ return; /* do it later or never */
}
int32_t nmidi = _meter->input_streams().n_midi();
@@ -160,8 +168,6 @@ LevelMeter::setup_meters (int len, int initial_width)
guint16 width;
- hide_all_meters ();
-
if (nmeters == 0) {
return;
}
diff --git a/gtk2_ardour/level_meter.h b/gtk2_ardour/level_meter.h
index 100ce21353..a2bbd5f4a1 100644
--- a/gtk2_ardour/level_meter.h
+++ b/gtk2_ardour/level_meter.h
@@ -55,7 +55,7 @@ class LevelMeter : public Gtk::HBox
LevelMeter (ARDOUR::Session&);
~LevelMeter ();
- virtual void set_meter (ARDOUR::PeakMeter& meter);
+ virtual void set_meter (ARDOUR::PeakMeter* meter);
void update_gain_sensitive ();
diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc
index 8a00eb88a2..5a8442dc44 100644
--- a/gtk2_ardour/mixer_strip.cc
+++ b/gtk2_ardour/mixer_strip.cc
@@ -67,6 +67,8 @@ using namespace Gtk;
using namespace Gtkmm2ext;
using namespace std;
+sigc::signal<void,boost::shared_ptr<Route> > MixerStrip::SwitchIO;
+
int MixerStrip::scrollbar_height = 0;
#ifdef VARISPEED_IN_MIXER_STRIP
@@ -88,8 +90,8 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, bool in_mixer)
, RouteUI (sess, _("Mute"), _("Solo"), _("Record"))
,_mixer(mx)
, _mixer_owned (in_mixer)
- , pre_processor_box (PreFader, sess, mx.plugin_selector(), mx.selection(), in_mixer)
- , post_processor_box (PostFader, sess, mx.plugin_selector(), mx.selection(), in_mixer)
+ , pre_processor_box (PreFader, sess, mx.plugin_selector(), mx.selection(), this, in_mixer)
+ , post_processor_box (PostFader, sess, mx.plugin_selector(), mx.selection(), this, in_mixer)
, gpm (sess)
, panners (sess)
, button_table (3, 2)
@@ -117,8 +119,8 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, boost::shared_ptr<Route> rt
, RouteUI (sess, _("Mute"), _("Solo"), _("Record"))
,_mixer(mx)
, _mixer_owned (in_mixer)
- , pre_processor_box (PreFader, sess, mx.plugin_selector(), mx.selection(), in_mixer)
- , post_processor_box (PostFader, sess, mx.plugin_selector(), mx.selection(), in_mixer)
+ , pre_processor_box (PreFader, sess, mx.plugin_selector(), mx.selection(), this, in_mixer)
+ , post_processor_box (PostFader, sess, mx.plugin_selector(), mx.selection(), this, in_mixer)
, gpm (sess)
, panners (sess)
, button_table (3, 2)
@@ -290,6 +292,12 @@ MixerStrip::init ()
rec_enable_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::rec_enable_press), false);
rec_enable_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::rec_enable_release));
+ /* ditto for this button and busses */
+
+ show_sends_button->set_name ("MixerRecordEnableButton");
+ show_sends_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::show_sends_press), false);
+ show_sends_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::show_sends_release));
+
name_button.signal_button_press_event().connect (mem_fun(*this, &MixerStrip::name_button_button_press), false);
group_button.signal_button_press_event().connect (mem_fun(*this, &MixerStrip::select_mix_group), false);
@@ -309,6 +317,9 @@ MixerStrip::init ()
set_name ("AudioTrackStripBase");
add_events (Gdk::BUTTON_RELEASE_MASK);
+
+ SwitchIO.connect (mem_fun (*this, &MixerStrip::switch_io));
+
}
MixerStrip::~MixerStrip ()
@@ -326,6 +337,10 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
button_table.remove (*rec_enable_button);
}
+ if (show_sends_button->get_parent()) {
+ button_table.remove (*show_sends_button);
+ }
+
#ifdef VARISPEED_IN_MIXER_STRIP
if (speed_frame->get_parent()) {
button_table.remove (*speed_frame);
@@ -384,6 +399,12 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
button_table.attach (*rec_enable_button, 0, 2, 2, 3);
rec_enable_button->show();
+
+ } else if (!is_track()) {
+ /* bus */
+
+ button_table.attach (*show_sends_button, 0, 2, 2, 3);
+ show_sends_button->show();
}
if (_route->phase_invert()) {
@@ -562,6 +583,9 @@ MixerStrip::set_width (Width w, void* owner)
if (rec_enable_button) {
((Gtk::Label*)rec_enable_button->get_child())->set_text (_("Record"));
}
+ if (show_sends_button) {
+ ((Gtk::Label*)show_sends_button->get_child())->set_text (_("Sends"));
+ }
((Gtk::Label*)mute_button->get_child())->set_text (_("Mute"));
((Gtk::Label*)solo_button->get_child())->set_text (_("Solo"));
@@ -593,6 +617,9 @@ MixerStrip::set_width (Width w, void* owner)
if (rec_enable_button) {
((Gtk::Label*)rec_enable_button->get_child())->set_text (_("Rec"));
}
+ if (show_sends_button) {
+ ((Gtk::Label*)show_sends_button->get_child())->set_text (_("Snd"));
+ }
((Gtk::Label*)mute_button->get_child())->set_text (_("M"));
((Gtk::Label*)solo_button->get_child())->set_text (_("S"));
@@ -1462,3 +1489,24 @@ MixerStrip::meter_changed (void *src)
set_width(_width, this);
}
+void
+MixerStrip::switch_io (boost::shared_ptr<Route> target)
+{
+ boost::shared_ptr<IO> to_display;
+
+ if (_route == target) {
+ /* don't change the display for the target */
+ return;
+ }
+
+ if (!target) {
+ to_display = _route;
+ } else {
+ to_display = _route->send_io_for (target);
+ }
+
+ gain_meter().set_io (to_display);
+ gain_meter().setup_meters ();
+ panner_ui().set_io (to_display);
+ panner_ui().setup_pan ();
+}
diff --git a/gtk2_ardour/mixer_strip.h b/gtk2_ardour/mixer_strip.h
index e2fa2e52d5..958bfc9422 100644
--- a/gtk2_ardour/mixer_strip.h
+++ b/gtk2_ardour/mixer_strip.h
@@ -88,6 +88,9 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
Width get_width() const { return _width; }
void* width_owner() const { return _width_owner; }
+ GainMeter& gain_meter() { return gpm; }
+ PannerUI& panner_ui() { return panners; }
+
void fast_update ();
void set_embedded (bool);
@@ -98,6 +101,8 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
sigc::signal<void> WidthChanged;
#endif
+ static sigc::signal<void,boost::shared_ptr<ARDOUR::Route> > SwitchIO;
+
protected:
friend class Mixer_UI;
void set_packed (bool yn);
@@ -257,6 +262,8 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
void engine_running();
void engine_stopped();
+ void switch_io (boost::shared_ptr<ARDOUR::Route>);
+
static int scrollbar_height;
};
diff --git a/gtk2_ardour/panner_ui.cc b/gtk2_ardour/panner_ui.cc
index c8c933348b..3ffec0ab05 100644
--- a/gtk2_ardour/panner_ui.cc
+++ b/gtk2_ardour/panner_ui.cc
@@ -133,7 +133,7 @@ PannerUI::PannerUI (Session& s)
void
PannerUI::set_io (boost::shared_ptr<IO> io)
{
- if (!io->panner()) {
+ if (io && !io->panner()) {
cerr << "PannerUI::set_io IO has no panners" << endl;
return;
}
@@ -148,15 +148,16 @@ PannerUI::set_io (boost::shared_ptr<IO> io)
_io = io;
- connections.push_back (_io->panner()->Changed.connect (
- mem_fun(*this, &PannerUI::panner_changed)));
- connections.push_back (_io->panner()->LinkStateChanged.connect (
- mem_fun(*this, &PannerUI::update_pan_linkage)));
- connections.push_back (_io->panner()->StateChanged.connect (
- mem_fun(*this, &PannerUI::update_pan_state)));
-
delete panner;
panner = 0;
+
+ if (!_io) {
+ return;
+ }
+
+ connections.push_back (_io->panner()->Changed.connect (mem_fun(*this, &PannerUI::panner_changed)));
+ connections.push_back (_io->panner()->LinkStateChanged.connect (mem_fun(*this, &PannerUI::update_pan_linkage)));
+ connections.push_back (_io->panner()->StateChanged.connect (mem_fun(*this, &PannerUI::update_pan_state)));
setup_pan ();
@@ -338,7 +339,7 @@ PannerUI::update_pan_state ()
void
PannerUI::setup_pan ()
{
- if (!_io->panner()) {
+ if (!_io || !_io->panner()) {
return;
}
diff --git a/gtk2_ardour/processor_box.cc b/gtk2_ardour/processor_box.cc
index 027d9df51e..f850582fec 100644
--- a/gtk2_ardour/processor_box.cc
+++ b/gtk2_ardour/processor_box.cc
@@ -59,6 +59,7 @@
#include "io_selector.h"
#include "keyboard.h"
#include "mixer_ui.h"
+#include "mixer_strip.h"
#include "plugin_selector.h"
#include "plugin_ui.h"
#include "processor_box.h"
@@ -89,8 +90,9 @@ Gdk::Color* ProcessorBox::active_processor_color;
Gdk::Color* ProcessorBox::inactive_processor_color;
ProcessorBox::ProcessorBox (Placement pcmnt, Session& sess, PluginSelector &plugsel,
- RouteRedirectSelection & rsel, bool owner_is_mixer)
+ RouteRedirectSelection & rsel, MixerStrip* parent, bool owner_is_mixer)
: _session(sess)
+ , _parent_strip (parent)
, _owner_is_mixer (owner_is_mixer)
, _placement(pcmnt)
, _plugin_selector(plugsel)
@@ -1193,12 +1195,10 @@ ProcessorBox::edit_processor (boost::shared_ptr<Processor> processor)
return;
}
- boost::shared_ptr<Send> send = boost::dynamic_pointer_cast<Send> (processor);
-
+#ifdef OLD_SEND_EDITING
SendUIWindow *send_ui;
if (send->get_gui() == 0) {
-
send_ui = new SendUIWindow (send, _session);
WindowTitle title(Glib::get_application_name());
@@ -1212,6 +1212,12 @@ ProcessorBox::edit_processor (boost::shared_ptr<Processor> processor)
}
gidget = send_ui;
+#else
+ if (_parent_strip) {
+ _parent_strip->gain_meter().set_io (send->io());
+ _parent_strip->panner_ui().set_io (send->io());
+ }
+#endif
} else if ((retrn = boost::dynamic_pointer_cast<Return> (processor)) != 0) {
diff --git a/gtk2_ardour/processor_box.h b/gtk2_ardour/processor_box.h
index a003ed8c5d..d53d05fe23 100644
--- a/gtk2_ardour/processor_box.h
+++ b/gtk2_ardour/processor_box.h
@@ -52,6 +52,7 @@ class MotionController;
class PluginSelector;
class PluginUIWindow;
class RouteRedirectSelection;
+class MixerStrip;
namespace ARDOUR {
class Connection;
@@ -68,7 +69,7 @@ namespace ARDOUR {
class ProcessorBox : public Gtk::HBox, public PluginInterestedObject
{
public:
- ProcessorBox (ARDOUR::Placement, ARDOUR::Session&, PluginSelector &, RouteRedirectSelection &, bool owner_is_mixer = false);
+ ProcessorBox (ARDOUR::Placement, ARDOUR::Session&, PluginSelector &, RouteRedirectSelection &, MixerStrip* parent, bool owner_is_mixer = false);
~ProcessorBox ();
void set_route (boost::shared_ptr<ARDOUR::Route>);
@@ -90,6 +91,7 @@ class ProcessorBox : public Gtk::HBox, public PluginInterestedObject
private:
boost::shared_ptr<ARDOUR::Route> _route;
ARDOUR::Session & _session;
+ MixerStrip* _parent_strip; // null if in RouteParamsUI
bool _owner_is_mixer;
bool ab_direction;
std::vector<sigc::connection> connections;
diff --git a/gtk2_ardour/route_params_ui.cc b/gtk2_ardour/route_params_ui.cc
index 33a99f6955..5c709d80bf 100644
--- a/gtk2_ardour/route_params_ui.cc
+++ b/gtk2_ardour/route_params_ui.cc
@@ -231,8 +231,8 @@ RouteParams_UI::setup_processor_boxes()
cleanup_processor_boxes();
// construct new redirect boxes
- pre_insert_box = new ProcessorBox(PreFader, *session, *_plugin_selector, _rr_selection);
- post_insert_box = new ProcessorBox(PostFader, *session, *_plugin_selector, _rr_selection);
+ pre_insert_box = new ProcessorBox(PreFader, *session, *_plugin_selector, _rr_selection, 0);
+ post_insert_box = new ProcessorBox(PostFader, *session, *_plugin_selector, _rr_selection, 0);
pre_insert_box->set_route (_route);
post_insert_box->set_route (_route);
diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc
index 40d0ae8da5..d050bc97fe 100644
--- a/gtk2_ardour/route_ui.cc
+++ b/gtk2_ardour/route_ui.cc
@@ -38,6 +38,7 @@
#include "gui_thread.h"
#include "ardour_dialog.h"
#include "latency_gui.h"
+#include "mixer_strip.h"
#include "automation_time_axis.h"
#include "ardour/route.h"
@@ -84,6 +85,7 @@ RouteUI::~RouteUI()
delete solo_menu;
delete mute_menu;
delete remote_control_menu;
+ delete sends_menu;
}
void
@@ -94,6 +96,7 @@ RouteUI::init ()
mute_menu = 0;
solo_menu = 0;
remote_control_menu = 0;
+ sends_menu = 0;
ignore_toggle = false;
wait_for_release = false;
route_active_menu_item = 0;
@@ -118,6 +121,11 @@ RouteUI::init ()
rec_enable_button->set_self_managed (true);
UI::instance()->set_tip (rec_enable_button, _("Enable recording on this track"), "");
+ show_sends_button = manage (new BindableToggleButton (""));
+ show_sends_button->set_name ("ShowSendsButton");
+ show_sends_button->set_self_managed (true);
+ UI::instance()->set_tip (show_sends_button, _("make mixer strips show sends to this bus"), "");
+
_session.SoloChanged.connect (mem_fun(*this, &RouteUI::solo_changed_so_update_mute));
}
@@ -498,6 +506,83 @@ RouteUI::rec_enable_release (GdkEventButton* ev)
}
void
+RouteUI::build_sends_menu ()
+{
+ using namespace Menu_Helpers;
+
+ sends_menu = new Menu;
+ sends_menu->set_name ("ArdourContextMenu");
+ MenuList& items = sends_menu->items();
+
+ items.push_back (MenuElem(_("Copy track gains to sends"), mem_fun (*this, &RouteUI::set_sends_gain_from_track)));
+ items.push_back (MenuElem(_("Set sends gain to -inf"), mem_fun (*this, &RouteUI::set_sends_gain_to_zero)));
+ items.push_back (MenuElem(_("Set sends gain to 0dB"), mem_fun (*this, &RouteUI::set_sends_gain_to_unity)));
+}
+
+void
+RouteUI::set_sends_gain_from_track ()
+{
+}
+
+void
+RouteUI::set_sends_gain_to_zero ()
+{
+}
+
+void
+RouteUI::set_sends_gain_to_unity ()
+{
+}
+
+bool
+RouteUI::show_sends_press(GdkEventButton* ev)
+{
+ if (ev->type == GDK_2BUTTON_PRESS || ev->type == GDK_3BUTTON_PRESS ) {
+ return true;
+ }
+
+ if (!ignore_toggle && !is_track() && show_sends_button) {
+
+ if (Keyboard::is_button2_event (ev) && Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) {
+
+ // do nothing on midi bind event
+ return false;
+
+ } else if (Keyboard::is_context_menu_event (ev)) {
+
+ if (sends_menu == 0) {
+ build_sends_menu ();
+ }
+
+ sends_menu->popup (0, ev->time);
+
+ } else {
+
+ /* change button state */
+
+ show_sends_button->set_active (!show_sends_button->get_active());
+
+ if (show_sends_button->get_active()) {
+ /* show sends to this bus */
+ MixerStrip::SwitchIO (_route);
+ } else {
+ /* everybody back to normal */
+ MixerStrip::SwitchIO (boost::shared_ptr<Route>());
+ }
+
+ }
+ }
+
+ return true;
+}
+
+bool
+RouteUI::show_sends_release (GdkEventButton* ev)
+{
+ return true;
+}
+
+void
RouteUI::solo_changed(void* src)
{
diff --git a/gtk2_ardour/route_ui.h b/gtk2_ardour/route_ui.h
index 4ec6fd3ce8..5a1933997d 100644
--- a/gtk2_ardour/route_ui.h
+++ b/gtk2_ardour/route_ui.h
@@ -81,7 +81,8 @@ class RouteUI : public virtual AxisView
BindableToggleButton* mute_button;
BindableToggleButton* solo_button;
- BindableToggleButton* rec_enable_button;
+ BindableToggleButton* rec_enable_button; /* audio tracks */
+ BindableToggleButton* show_sends_button; /* busses */
virtual std::string solo_button_name () const { return "SoloButton"; }
virtual std::string safe_solo_button_name () const { return "SafeSoloButton"; }
@@ -89,6 +90,7 @@ class RouteUI : public virtual AxisView
Gtk::Menu* mute_menu;
Gtk::Menu* solo_menu;
Gtk::Menu* remote_control_menu;
+ Gtk::Menu* sends_menu;
XMLNode *xml_node;
void ensure_xml_node ();
@@ -101,6 +103,13 @@ class RouteUI : public virtual AxisView
bool solo_release(GdkEventButton*);
bool rec_enable_press(GdkEventButton*);
bool rec_enable_release(GdkEventButton*);
+ bool show_sends_press(GdkEventButton*);
+ bool show_sends_release(GdkEventButton*);
+
+ void build_sends_menu ();
+ void set_sends_gain_from_track ();
+ void set_sends_gain_to_zero ();
+ void set_sends_gain_to_unity ();
void solo_changed(void*);
void solo_changed_so_update_mute ();
diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h
index 5c7d8d0f0f..23e4f576df 100644
--- a/libs/ardour/ardour/io.h
+++ b/libs/ardour/ardour/io.h
@@ -141,6 +141,8 @@ class IO : public SessionObject, public AutomatableControls, public Latent
int disconnect_inputs (void *src);
int disconnect_outputs (void *src);
+ bool connected_to (boost::shared_ptr<const IO>) const;
+
nframes_t signal_latency() const { return _own_latency; }
nframes_t output_latency() const;
nframes_t input_latency() const;
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index c498b1f04e..10aec0446e 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -91,7 +91,6 @@ class Route : public IO
/* these are the core of the API of a Route. see the protected sections as well */
-
virtual int roll (nframes_t nframes, sframes_t start_frame, sframes_t end_frame,
int declick, bool can_record, bool rec_monitors_input);
@@ -181,6 +180,8 @@ class Route : public IO
boost::shared_ptr<Delivery> control_outs() const { return _control_outs; }
boost::shared_ptr<Delivery> main_outs() const { return _main_outs; }
+
+ boost::shared_ptr<IO> send_io_for (boost::shared_ptr<const IO> target) const;
/** A record of the stream configuration at some point in the processor list.
* Used to return where and why an processor list configuration request failed.
@@ -248,7 +249,7 @@ class Route : public IO
int listen_via (boost::shared_ptr<IO>, const std::string& name);
void drop_listen (boost::shared_ptr<IO>);
- bool feeds (boost::shared_ptr<Route>);
+ bool feeds (boost::shared_ptr<IO>);
std::set<boost::shared_ptr<Route> > fed_by;
struct ToggleControllable : public PBD::Controllable {
@@ -314,7 +315,7 @@ class Route : public IO
nframes_t _initial_delay;
nframes_t _roll_delay;
ProcessorList _processors;
- Glib::RWLock _processor_lock;
+ mutable Glib::RWLock _processor_lock;
boost::shared_ptr<Delivery> _main_outs;
boost::shared_ptr<Delivery> _control_outs; // XXX to be removed/generalized by listen points
RouteGroup *_edit_group;
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index 52c2aa48cc..ba3d70c184 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -1596,25 +1596,28 @@ IO::get_port_counts (const XMLNode& node, ChanCount& in, ChanCount& out,
int
IO::create_ports (const XMLNode& node)
{
- ChanCount in;
- ChanCount out;
- boost::shared_ptr<Bundle> ic;
- boost::shared_ptr<Bundle> oc;
+ if (pending_state_node) {
- no_panner_reset = true;
-
- get_port_counts (*pending_state_node, in, out, ic, oc);
-
- if (ensure_io (in, out, true, this)) {
- error << string_compose(_("%1: cannot create I/O ports"), _name) << endmsg;
- return -1;
+ ChanCount in;
+ ChanCount out;
+ boost::shared_ptr<Bundle> ic;
+ boost::shared_ptr<Bundle> oc;
+
+ no_panner_reset = true;
+
+ get_port_counts (*pending_state_node, in, out, ic, oc);
+
+ if (ensure_io (in, out, true, this)) {
+ error << string_compose(_("%1: cannot create I/O ports"), _name) << endmsg;
+ return -1;
+ }
+
+ /* XXX use ic and oc if relevant */
+
+ no_panner_reset = false;
}
- /* XXX use ic and oc if relevant */
-
- no_panner_reset = false;
set_deferred_state ();
-
return 0;
}
@@ -2663,3 +2666,22 @@ IO::increment_output_offset (nframes_t n)
_output_offset += n;
}
+bool
+IO::connected_to (boost::shared_ptr<const IO> other) const
+{
+ uint32_t i, j;
+
+ uint32_t no = n_outputs().n_total();
+ uint32_t ni = other->n_inputs ().n_total();
+
+ for (i = 0; i < no; ++i) {
+ for (j = 0; j < ni; ++j) {
+ if (output(i)->connected_to (other->input(j)->name())) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 228a140d05..7fb063eae0 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -2112,39 +2112,21 @@ Route::set_comment (string cmt, void *src)
}
bool
-Route::feeds (boost::shared_ptr<Route> other)
+Route::feeds (boost::shared_ptr<IO> other)
{
- uint32_t i, j;
-
- IO& self = *this;
- uint32_t no = self.n_outputs().n_total();
- uint32_t ni = other->n_inputs ().n_total();
-
- for (i = 0; i < no; ++i) {
- for (j = 0; j < ni; ++j) {
- if (self.output(i)->connected_to (other->input(j)->name())) {
- return true;
- }
- }
+ if (connected_to (other)) {
+ return true;
}
/* check IOProcessors which may also interconnect Routes */
for (ProcessorList::iterator r = _processors.begin(); r != _processors.end(); r++) {
- boost::shared_ptr<IOProcessor> proc = boost::dynamic_pointer_cast<IOProcessor>(*r);
-
- if (!proc) {
- continue;
- }
-
- no = proc->io()->n_outputs().n_total();
-
- for (i = 0; i < no; ++i) {
- for (j = 0; j < ni; ++j) {
- if (proc->io()->output(i)->connected_to (other->input (j)->name())) {
- return true;
- }
+ boost::shared_ptr<IOProcessor> proc;
+
+ if ((proc = boost::dynamic_pointer_cast<IOProcessor>(*r)) != 0) {
+ if (proc->io()->connected_to (other)) {
+ return true;
}
}
}
@@ -2700,3 +2682,21 @@ Route::set_name (const string& str)
return ret;
}
+
+boost::shared_ptr<IO>
+Route::send_io_for (boost::shared_ptr<const IO> target) const
+{
+ Glib::RWLock::ReaderLock lm (_processor_lock);
+
+ for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) {
+ boost::shared_ptr<Send> send;
+
+ if ((send = boost::dynamic_pointer_cast<Send>(*i)) != 0) {
+ if (send->io()->connected_to (target)) {
+ return send->io();
+ }
+ }
+ }
+
+ return boost::shared_ptr<IO>();
+}