From: Carl Hetherington Date: Mon, 8 Oct 2007 23:47:35 +0000 (+0000) Subject: Various work on Bundles, especially dynamic ones so that you can, for example, pass... X-Git-Tag: 3.0-alpha5~4494 X-Git-Url: https://main.carlh.net/gitweb/?a=commitdiff_plain;h=4d66204f4eb96ca802e9b301293ff4bd922717d0;p=ardour.git Various work on Bundles, especially dynamic ones so that you can, for example, pass tracks to busses by selecting the buss name from the track's output menu. git-svn-id: svn://localhost/ardour2/trunk@2530 d708f5d6-7413-0410-9779-e7cbd77b26cf --- diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc index 3fd53c8633..dfe5a268fa 100644 --- a/gtk2_ardour/mixer_strip.cc +++ b/gtk2_ardour/mixer_strip.cc @@ -43,7 +43,6 @@ #include #include #include -#include #include "ardour_ui.h" #include "ardour_dialog.h" @@ -549,7 +548,9 @@ MixerStrip::output_press (GdkEventButton *ev) citems.push_back (MenuElem (_("Disconnect"), mem_fun (*(static_cast(this)), &RouteUI::disconnect_output))); citems.push_back (SeparatorElem()); - _session.foreach_bundle (this, &MixerStrip::add_bundle_to_output_menu); + _session.foreach_bundle ( + bind (mem_fun (*this, &MixerStrip::add_bundle_to_output_menu), _route->output_bundle ()) + ); output_menu.popup (1, ev->time); break; @@ -611,7 +612,9 @@ MixerStrip::input_press (GdkEventButton *ev) citems.push_back (MenuElem (_("Disconnect"), mem_fun (*(static_cast(this)), &RouteUI::disconnect_input))); citems.push_back (SeparatorElem()); - _session.foreach_bundle (this, &MixerStrip::add_bundle_to_input_menu); + _session.foreach_bundle ( + bind (mem_fun (*this, &MixerStrip::add_bundle_to_input_menu), _route->input_bundle ()) + ); input_menu.popup (1, ev->time); break; @@ -623,12 +626,12 @@ MixerStrip::input_press (GdkEventButton *ev) } void -MixerStrip::bundle_input_chosen (ARDOUR::Bundle *c) +MixerStrip::bundle_input_chosen (boost::shared_ptr c) { if (!ignore_toggle) { try { - _route->use_input_bundle (*c, this); + _route->connect_input_ports_to_bundle (c, this); } catch (AudioEngine::PortRegistrationFailure& err) { @@ -639,12 +642,12 @@ MixerStrip::bundle_input_chosen (ARDOUR::Bundle *c) } void -MixerStrip::bundle_output_chosen (ARDOUR::Bundle *c) +MixerStrip::bundle_output_chosen (boost::shared_ptr c) { if (!ignore_toggle) { try { - _route->use_output_bundle (*c, this); + _route->connect_output_ports_to_bundle (c, this); } catch (AudioEngine::PortRegistrationFailure& err) { @@ -655,23 +658,23 @@ MixerStrip::bundle_output_chosen (ARDOUR::Bundle *c) } void -MixerStrip::add_bundle_to_input_menu (ARDOUR::Bundle* c) +MixerStrip::add_bundle_to_input_menu (boost::shared_ptr b, boost::shared_ptr current) { using namespace Menu_Helpers; - if (dynamic_cast (c) == 0) { + /* the input menu needs to contain only output bundles (that we + can connect inputs to */ + if (boost::dynamic_pointer_cast (b) == 0) { return; } MenuList& citems = input_menu.items(); - if (c->nchannels() == _route->n_inputs().n_total()) { + if (b->nchannels() == _route->n_inputs().n_total()) { - citems.push_back (CheckMenuElem (c->name(), bind (mem_fun(*this, &MixerStrip::bundle_input_chosen), c))); + citems.push_back (CheckMenuElem (b->name(), bind (mem_fun(*this, &MixerStrip::bundle_input_chosen), b))); - ARDOUR::Bundle *current = _route->input_bundle(); - - if (current == c) { + if (current == b) { ignore_toggle = true; dynamic_cast (&citems.back())->set_active (true); ignore_toggle = false; @@ -680,22 +683,23 @@ MixerStrip::add_bundle_to_input_menu (ARDOUR::Bundle* c) } void -MixerStrip::add_bundle_to_output_menu (ARDOUR::Bundle* c) +MixerStrip::add_bundle_to_output_menu (boost::shared_ptr b, boost::shared_ptr current) { using namespace Menu_Helpers; - if (dynamic_cast (c) == 0) { + /* the output menu needs to contain only input bundles (that we + can connect outputs to */ + if (boost::dynamic_pointer_cast (b) == 0) { return; } - if (c->nchannels() == _route->n_outputs().n_total()) { + + if (b->nchannels() == _route->n_outputs().n_total()) { MenuList& citems = output_menu.items(); - citems.push_back (CheckMenuElem (c->name(), bind (mem_fun(*this, &MixerStrip::bundle_output_chosen), c))); - - ARDOUR::Bundle *current = _route->output_bundle(); + citems.push_back (CheckMenuElem (b->name(), bind (mem_fun(*this, &MixerStrip::bundle_output_chosen), b))); - if (current == c) { + if (current == b) { ignore_toggle = true; dynamic_cast (&citems.back())->set_active (true); ignore_toggle = false; @@ -748,7 +752,7 @@ MixerStrip::connect_to_pan () void MixerStrip::update_input_display () { - ARDOUR::Bundle *c; + boost::shared_ptr c; if ((c = _route->input_bundle()) != 0) { input_label.set_text (c->name()); @@ -768,7 +772,7 @@ MixerStrip::update_input_display () void MixerStrip::update_output_display () { - ARDOUR::Bundle *c; + boost::shared_ptr c; if ((c = _route->output_bundle()) != 0) { output_label.set_text (c->name()); diff --git a/gtk2_ardour/mixer_strip.h b/gtk2_ardour/mixer_strip.h index b7bd20cfbd..9702ea09d8 100644 --- a/gtk2_ardour/mixer_strip.h +++ b/gtk2_ardour/mixer_strip.h @@ -168,13 +168,13 @@ class MixerStrip : public RouteUI, public Gtk::EventBox gint output_press (GdkEventButton *); Gtk::Menu input_menu; - void add_bundle_to_input_menu (ARDOUR::Bundle *); + void add_bundle_to_input_menu (boost::shared_ptr, boost::shared_ptr); Gtk::Menu output_menu; - void add_bundle_to_output_menu (ARDOUR::Bundle *); + void add_bundle_to_output_menu (boost::shared_ptr, boost::shared_ptr); - void bundle_input_chosen (ARDOUR::Bundle *); - void bundle_output_chosen (ARDOUR::Bundle *); + void bundle_input_chosen (boost::shared_ptr); + void bundle_output_chosen (boost::shared_ptr); void edit_input_configuration (); void edit_output_configuration (); diff --git a/libs/ardour/ardour/bundle.h b/libs/ardour/ardour/bundle.h index 1ed285a118..9c5f3cb21a 100644 --- a/libs/ardour/ardour/bundle.h +++ b/libs/ardour/ardour/bundle.h @@ -121,6 +121,12 @@ class InputBundle : public Bundle { class OutputBundle : public Bundle { public: + /** + * OutputBundle constructor. + * \param name Name. + * \param dy true if this Bundle is `dynamic'; ie it is created on-the-fly + * and should not be written to the session file. + */ OutputBundle (string name, bool dy = false) : Bundle (name, dy) {} OutputBundle (const XMLNode&); }; diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h index 4ab99c5f12..2b0b0f7781 100644 --- a/libs/ardour/ardour/io.h +++ b/libs/ardour/ardour/io.h @@ -120,11 +120,11 @@ class IO : public Automatable, public Latent int ensure_io (ChanCount in, ChanCount out, bool clear, void *src); - int use_input_bundle (Bundle&, void *src); - int use_output_bundle (Bundle&, void *src); + int connect_input_ports_to_bundle (boost::shared_ptr, void *src); + int connect_output_ports_to_bundle (boost::shared_ptr, void *src); - Bundle *input_bundle() const { return _input_bundle; } - Bundle *output_bundle() const { return _output_bundle; } + boost::shared_ptr input_bundle(); + boost::shared_ptr output_bundle(); int add_input_port (string source, void *src, DataType type = DataType::NIL); int add_output_port (string destination, void *src, DataType type = DataType::NIL); @@ -179,6 +179,9 @@ class IO : public Automatable, public Latent void attach_buffers(ChanCount ignored); + boost::shared_ptr bundle_for_inputs () const { return _bundle_for_inputs; } + boost::shared_ptr bundle_for_outputs () const { return _bundle_for_outputs; } + sigc::signal input_changed; sigc::signal output_changed; @@ -268,8 +271,8 @@ class IO : public Automatable, public Latent PortSet _outputs; PortSet _inputs; PeakMeter* _meter; - Bundle* _input_bundle; - Bundle* _output_bundle; + boost::shared_ptr _input_bundle; ///< bundle connected to our inputs + boost::shared_ptr _output_bundle; ///< bundle connected to our outputs bool no_panner_reset; bool _phase_invert; bool _denormal_protection; @@ -326,6 +329,8 @@ class IO : public Automatable, public Latent ChanCount _output_minimum; ChanCount _output_maximum; + boost::shared_ptr _bundle_for_inputs; + boost::shared_ptr _bundle_for_outputs; static int parse_io_string (const string&, vector& chns); @@ -356,6 +361,9 @@ class IO : public Automatable, public Latent int32_t find_input_port_hole (); int32_t find_output_port_hole (); + + void create_bundles (); + void setup_bundles (); }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 540ad08011..94caf8a242 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -710,13 +710,14 @@ class Session : public PBD::StatefulDestructible /* I/O bundles */ - template void foreach_bundle (T *obj, void (T::*func)(Bundle *)); - void add_bundle (Bundle *); - void remove_bundle (Bundle *); - Bundle *bundle_by_name (string) const; + void foreach_bundle (sigc::slot >); + void add_bundle (boost::shared_ptr); + void remove_bundle (boost::shared_ptr); + boost::shared_ptr bundle_by_name (string) const; + boost::shared_ptr bundle_by_ports (vector const &) const; - sigc::signal BundleAdded; - sigc::signal BundleRemoved; + sigc::signal > BundleAdded; + sigc::signal > BundleRemoved; /* MIDI */ @@ -1558,9 +1559,9 @@ class Session : public PBD::StatefulDestructible /* I/O bundles */ - typedef list BundleList; + typedef list > BundleList; mutable Glib::Mutex bundle_lock; - BundleList _bundles; + BundleList _bundles; int load_bundles (const XMLNode&); void reverse_diskstream_buffers (); diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc index 84302b055f..bc2f0d9feb 100644 --- a/libs/ardour/audio_track.cc +++ b/libs/ardour/audio_track.cc @@ -135,7 +135,7 @@ AudioTrack::deprecated_use_diskstream_connections () } if ((prop = node.property ("input-connection")) != 0) { - Bundle* c = _session.bundle_by_name (prop->value()); + boost::shared_ptr c = _session.bundle_by_name (prop->value()); if (c == 0) { error << string_compose(_("Unknown bundle \"%1\" listed for input of %2"), prop->value(), _name) << endmsg; @@ -150,7 +150,7 @@ AudioTrack::deprecated_use_diskstream_connections () } } - use_input_bundle(*c, this); + connect_input_ports_to_bundle (c, this); } else if ((prop = node.property ("inputs")) != 0) { if (set_inputs (prop->value())) { diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index 29cc94ffe7..0c1ba32c74 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -126,8 +126,6 @@ IO::IO (Session& s, const string& name, _gain = 1.0; _desired_gain = 1.0; - _input_bundle = 0; - _output_bundle = 0; pending_state_node = 0; no_panner_reset = false; _phase_invert = false; @@ -154,6 +152,8 @@ IO::IO (Session& s, const string& name, IO::MoreChannels.connect (mem_fun (*this, &IO::attach_buffers)); _session.add_controllable (_gain_control); + + create_bundles (); } IO::IO (Session& s, const XMLNode& node, DataType dt) @@ -168,8 +168,6 @@ IO::IO (Session& s, const XMLNode& node, DataType dt) no_panner_reset = false; _desired_gain = 1.0; _gain = 1.0; - _input_bundle = 0; - _output_bundle = 0; apply_gain_automation = false; @@ -194,6 +192,8 @@ IO::IO (Session& s, const XMLNode& node, DataType dt) IO::MoreChannels.connect (mem_fun (*this, &IO::attach_buffers)); _session.add_controllable (_gain_control); + + create_bundles (); } IO::~IO () @@ -335,7 +335,7 @@ IO::just_meter_input (nframes_t start_frame, nframes_t end_frame, void IO::drop_input_bundle () { - _input_bundle = 0; + _input_bundle.reset (); input_bundle_configuration_connection.disconnect(); input_bundle_connection_connection.disconnect(); _session.set_dirty (); @@ -344,7 +344,7 @@ IO::drop_input_bundle () void IO::drop_output_bundle () { - _output_bundle = 0; + _output_bundle.reset (); output_bundle_configuration_connection.disconnect(); output_bundle_connection_connection.disconnect(); _session.set_dirty (); @@ -550,6 +550,10 @@ IO::remove_output_port (Port* port, void* src) } } + if (change == ConnectionsChanged) { + setup_bundles (); + } + if (change != NoChange) { output_changed (change, src); _session.set_dirty (); @@ -616,6 +620,7 @@ IO::add_output_port (string destination, void* src, DataType type) // pan_changed (src); /* EMIT SIGNAL */ output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */ + setup_bundles (); _session.set_dirty (); return 0; @@ -654,6 +659,10 @@ IO::remove_input_port (Port* port, void* src) } } + if (change == ConfigurationChanged) { + setup_bundles (); + } + if (change != NoChange) { input_changed (change, src); _session.set_dirty (); @@ -697,7 +706,7 @@ IO::add_input_port (string source, void* src, DataType type) } else { snprintf (name, sizeof (name), _("%s/in %u"), _name.c_str(), find_input_port_hole()); } - + if ((our_port = _session.engine().register_input_port (type, name)) == 0) { error << string_compose(_("IO: cannot register input port %1"), name) << endmsg; return -1; @@ -721,6 +730,7 @@ IO::add_input_port (string source, void* src, DataType type) // pan_changed (src); /* EMIT SIGNAL */ input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */ + setup_bundles (); _session.set_dirty (); return 0; @@ -1003,6 +1013,7 @@ IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src) if (in_changed || out_changed) { MoreChannels (max (n_outputs(), n_inputs())); /* EMIT SIGNAL */ + setup_bundles (); _session.set_dirty (); } @@ -1030,6 +1041,7 @@ IO::ensure_inputs (ChanCount count, bool clear, bool lockit, void* src) if (changed) { input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */ + setup_bundles (); _session.set_dirty (); } return 0; @@ -1127,6 +1139,7 @@ IO::ensure_outputs (ChanCount count, bool clear, bool lockit, void* src) if (changed) { output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */ + setup_bundles (); } return 0; @@ -1201,12 +1214,12 @@ IO::state (bool full_state) str = ""; - if (_input_bundle) { + if (_input_bundle && !_input_bundle->dynamic()) { node->add_property ("input-connection", _input_bundle->name()); need_ins = false; } - if (_output_bundle) { + if (_output_bundle && !_output_bundle->dynamic()) { node->add_property ("output-connection", _output_bundle->name()); need_outs = false; } @@ -1540,7 +1553,7 @@ IO::create_ports (const XMLNode& node) */ if ((prop = node.property ("input-connection")) != 0) { - Bundle* c = _session.bundle_by_name (prop->value()); + boost::shared_ptr c = _session.bundle_by_name (prop->value()); if (c == 0) { error << string_compose(_("Unknown bundle \"%1\" listed for input of %2"), prop->value(), _name) << endmsg; @@ -1563,7 +1576,7 @@ IO::create_ports (const XMLNode& node) } if ((prop = node.property ("output-connection")) != 0) { - Bundle* c = _session.bundle_by_name (prop->value()); + boost::shared_ptr c = _session.bundle_by_name (prop->value()); if (c == 0) { error << string_compose(_("Unknown bundle \"%1\" listed for output of %2"), prop->value(), _name) << endmsg; @@ -1607,7 +1620,7 @@ IO::make_connections (const XMLNode& node) const XMLProperty* prop; if ((prop = node.property ("input-connection")) != 0) { - Bundle* c = _session.bundle_by_name (prop->value()); + boost::shared_ptr c = _session.bundle_by_name (prop->value()); if (c == 0) { error << string_compose(_("Unknown connection \"%1\" listed for input of %2"), prop->value(), _name) << endmsg; @@ -1622,7 +1635,7 @@ IO::make_connections (const XMLNode& node) } } - use_input_bundle (*c, this); + connect_input_ports_to_bundle (c, this); } else if ((prop = node.property ("inputs")) != 0) { if (set_inputs (prop->value())) { @@ -1632,7 +1645,7 @@ IO::make_connections (const XMLNode& node) } if ((prop = node.property ("output-bundle")) != 0) { - Bundle* c = _session.bundle_by_name (prop->value()); + boost::shared_ptr c = _session.bundle_by_name (prop->value()); if (c == 0) { error << string_compose(_("Unknown bundle \"%1\" listed for output of %2"), prop->value(), _name) << endmsg; @@ -1647,7 +1660,7 @@ IO::make_connections (const XMLNode& node) } } - use_output_bundle (*c, this); + connect_output_ports_to_bundle (c, this); } else if ((prop = node.property ("outputs")) != 0) { if (set_outputs (prop->value())) { @@ -1834,7 +1847,11 @@ IO::set_name (const string& str) i->set_name (current_name); } - return SessionObject::set_name(name); + bool const r = SessionObject::set_name(name); + + setup_bundles (); + + return r; } void @@ -1910,7 +1927,7 @@ IO::input_latency () const } int -IO::use_input_bundle (Bundle& c, void* src) +IO::connect_input_ports_to_bundle (boost::shared_ptr c, void* src) { uint32_t limit; @@ -1918,7 +1935,7 @@ IO::use_input_bundle (Bundle& c, void* src) BLOCK_PROCESS_CALLBACK (); Glib::Mutex::Lock lm2 (io_lock); - limit = c.nchannels(); + limit = c->nchannels(); drop_input_bundle (); @@ -1932,7 +1949,7 @@ IO::use_input_bundle (Bundle& c, void* src) */ for (uint32_t n = 0; n < limit; ++n) { - const Bundle::PortList& pl = c.channel_ports (n); + const Bundle::PortList& pl = c->channel_ports (n); for (Bundle::PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) { @@ -1962,7 +1979,7 @@ IO::use_input_bundle (Bundle& c, void* src) /* second pass: connect all requested ports where necessary */ for (uint32_t n = 0; n < limit; ++n) { - const Bundle::PortList& pl = c.channel_ports (n); + const Bundle::PortList& pl = c->channel_ports (n); for (Bundle::PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) { @@ -1976,11 +1993,11 @@ IO::use_input_bundle (Bundle& c, void* src) } } - _input_bundle = &c; + _input_bundle = c; - input_bundle_configuration_connection = c.ConfigurationChanged.connect + input_bundle_configuration_connection = c->ConfigurationChanged.connect (mem_fun (*this, &IO::input_bundle_configuration_changed)); - input_bundle_connection_connection = c.PortsChanged.connect + input_bundle_connection_connection = c->PortsChanged.connect (mem_fun (*this, &IO::input_bundle_connection_changed)); } @@ -1989,7 +2006,7 @@ IO::use_input_bundle (Bundle& c, void* src) } int -IO::use_output_bundle (Bundle& c, void* src) +IO::connect_output_ports_to_bundle (boost::shared_ptr c, void* src) { uint32_t limit; @@ -1997,7 +2014,7 @@ IO::use_output_bundle (Bundle& c, void* src) BLOCK_PROCESS_CALLBACK (); Glib::Mutex::Lock lm2 (io_lock); - limit = c.nchannels(); + limit = c->nchannels(); drop_output_bundle (); @@ -2012,7 +2029,7 @@ IO::use_output_bundle (Bundle& c, void* src) for (uint32_t n = 0; n < limit; ++n) { - const Bundle::PortList& pl = c.channel_ports (n); + const Bundle::PortList& pl = c->channel_ports (n); for (Bundle::PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) { @@ -2042,7 +2059,7 @@ IO::use_output_bundle (Bundle& c, void* src) for (uint32_t n = 0; n < limit; ++n) { - const Bundle::PortList& pl = c.channel_ports (n); + const Bundle::PortList& pl = c->channel_ports (n); for (Bundle::PortList::const_iterator i = pl.begin(); i != pl.end(); ++i) { @@ -2055,11 +2072,11 @@ IO::use_output_bundle (Bundle& c, void* src) } } - _output_bundle = &c; + _output_bundle = c; - output_bundle_configuration_connection = c.ConfigurationChanged.connect + output_bundle_configuration_connection = c->ConfigurationChanged.connect (mem_fun (*this, &IO::output_bundle_configuration_changed)); - output_bundle_connection_connection = c.PortsChanged.connect + output_bundle_connection_connection = c->PortsChanged.connect (mem_fun (*this, &IO::output_bundle_connection_changed)); } @@ -2113,25 +2130,25 @@ IO::reset_panners () void IO::input_bundle_connection_changed (int ignored) { - use_input_bundle (*_input_bundle, this); + connect_input_ports_to_bundle (_input_bundle, this); } void IO::input_bundle_configuration_changed () { - use_input_bundle (*_input_bundle, this); + connect_input_ports_to_bundle (_input_bundle, this); } void IO::output_bundle_connection_changed (int ignored) { - use_output_bundle (*_output_bundle, this); + connect_output_ports_to_bundle (_output_bundle, this); } void IO::output_bundle_configuration_changed () { - use_output_bundle (*_output_bundle, this); + connect_output_ports_to_bundle (_output_bundle, this); } void @@ -2428,3 +2445,100 @@ IO::update_port_total_latencies () _session.engine().update_total_latency (*i); } } + + +/** + * Setup bundles that describe our inputs and outputs. + */ + +void +IO::setup_bundles () +{ + char buf[32]; + + snprintf(buf, sizeof (buf), _("%s in"), _name.c_str()); + _bundle_for_inputs->set_name (buf, 0); + int const ins = n_inputs().n_total(); + _bundle_for_inputs->set_nchannels (ins); + + for (int i = 0; i < ins; ++i) { + _bundle_for_inputs->add_port_to_channel (i, _inputs.port(i)->name ()); + } + + snprintf(buf, sizeof (buf), _("%s out"), _name.c_str()); + _bundle_for_outputs->set_name (buf, 0); + int const outs = n_outputs().n_total(); + _bundle_for_outputs->set_nchannels (outs); + + for (int i = 0; i < outs; ++i) { + _bundle_for_outputs->add_port_to_channel (i, _outputs.port(i)->name ()); + } +} + + +/** + * Create and setup bundles that describe our inputs and outputs. + */ + +void +IO::create_bundles () +{ + _bundle_for_inputs = boost::shared_ptr ( + new InputBundle ("", true) + ); + + _bundle_for_outputs = boost::shared_ptr ( + new OutputBundle ("", true) + ); + + setup_bundles (); +} + +boost::shared_ptr +IO::input_bundle() +{ + if (_input_bundle) { + return _input_bundle; + } + + /* XXX: will only report the first bundle found; should really return a list, I think */ + + /* check that _input_bundle is right wrt the connections that are currently made */ + + /* make a vector of the first output connected to each of our inputs */ + std::vector connected; + for (uint32_t i = 0; i < _inputs.num_ports(); ++i) { + const char** c = _inputs.port(i)->get_connections (); + if (c) { + connected.push_back (c[0]); + } + } + + _input_bundle = _session.bundle_by_ports (connected); + return _input_bundle; +} + + +boost::shared_ptr +IO::output_bundle() +{ + if (_output_bundle) { + return _output_bundle; + } + + /* XXX: will only report the first bundle found; should really return a list, I think */ + + /* check that _output_bundle is right wrt the connections that are currently made */ + + /* make a vector of the first input connected to each of our outputs */ + std::vector connected; + for (uint32_t i = 0; i < _outputs.num_ports(); ++i) { + const char** c = _outputs.port(i)->get_connections (); + if (c) { + connected.push_back (c[0]); + } + } + + _output_bundle = _session.bundle_by_ports (connected); + return _output_bundle; +} diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index ed696446ef..742b17af2c 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -487,20 +487,6 @@ Session::destroy () i = tmp; } -#ifdef TRACK_DESTRUCTION - cerr << "delete bundles\n"; -#endif /* TRACK_DESTRUCTION */ - for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ) { - BundleList::iterator tmp; - - tmp = i; - ++tmp; - - delete *i; - - i = tmp; - } - if (butler_mixdown_buffer) { delete [] butler_mixdown_buffer; } @@ -615,7 +601,7 @@ Session::when_engine_running () char buf[32]; snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1); - Bundle* c = new OutputBundle (buf, true); + shared_ptr c (new OutputBundle (buf, true)); c->set_nchannels (1); c->add_port_to_channel (0, _engine.get_nth_physical_output (DataType::AUDIO, np)); @@ -626,7 +612,7 @@ Session::when_engine_running () char buf[32]; snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1); - Bundle* c = new InputBundle (buf, true); + shared_ptr c (new InputBundle (buf, true)); c->set_nchannels (1); c->add_port_to_channel (0, _engine.get_nth_physical_input (DataType::AUDIO, np)); @@ -639,7 +625,7 @@ Session::when_engine_running () char buf[32]; snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2); - Bundle* c = new OutputBundle (buf, true); + shared_ptr c (new OutputBundle (buf, true)); c->set_nchannels (2); c->add_port_to_channel (0, _engine.get_nth_physical_output (DataType::AUDIO, np)); c->add_port_to_channel (1, _engine.get_nth_physical_output (DataType::AUDIO, np+1)); @@ -651,7 +637,7 @@ Session::when_engine_running () char buf[32]; snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2); - Bundle* c = new InputBundle (buf, true); + shared_ptr c (new InputBundle (buf, true)); c->set_nchannels (2); c->add_port_to_channel (0, _engine.get_nth_physical_input (DataType::AUDIO, np)); c->add_port_to_channel (1, _engine.get_nth_physical_input (DataType::AUDIO, np+1)); @@ -701,7 +687,7 @@ Session::when_engine_running () } - Bundle* c = new OutputBundle (_("Master Out"), true); + shared_ptr c (new OutputBundle (_("Master Out"), true)); c->set_nchannels (_master_out->n_inputs().n_total()); for (uint32_t n = 0; n < _master_out->n_inputs ().n_total(); ++n) { @@ -1902,7 +1888,10 @@ Session::add_routes (RouteList& new_routes, bool save) if ((*x)->is_control()) { _control_out = (*x); - } + } + + add_bundle ((*x)->bundle_for_inputs()); + add_bundle ((*x)->bundle_for_outputs()); } if (_control_out && IO::connecting_legal) { @@ -3609,7 +3598,7 @@ Session::available_capture_duration () } void -Session::add_bundle (ARDOUR::Bundle* bundle) +Session::add_bundle (shared_ptr bundle) { { Glib::Mutex::Lock guard (bundle_lock); @@ -3622,7 +3611,7 @@ Session::add_bundle (ARDOUR::Bundle* bundle) } void -Session::remove_bundle (ARDOUR::Bundle* bundle) +Session::remove_bundle (shared_ptr bundle) { bool removed = false; @@ -3643,7 +3632,7 @@ Session::remove_bundle (ARDOUR::Bundle* bundle) set_dirty(); } -ARDOUR::Bundle * +shared_ptr Session::bundle_by_name (string name) const { Glib::Mutex::Lock lm (bundle_lock); @@ -3654,7 +3643,36 @@ Session::bundle_by_name (string name) const } } - return 0; + return boost::shared_ptr (); +} + +boost::shared_ptr +Session::bundle_by_ports (std::vector const & wanted_ports) const +{ + Glib::Mutex::Lock lm (bundle_lock); + + for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) { + if ((*i)->nchannels() != wanted_ports.size()) { + continue; + } + + bool match = true; + for (uint32_t j = 0; j < (*i)->nchannels(); ++j) { + Bundle::PortList const p = (*i)->channel_ports (j); + if (p.empty() || p[0] != wanted_ports[j]) { + /* not this bundle */ + match = false; + break; + } + } + + if (match) { + /* matched bundle */ + return *i; + } + } + + return boost::shared_ptr (); } void @@ -4105,3 +4123,11 @@ Session::compute_initial_length () return _engine.frame_rate() * 60 * 5; } +void +Session::foreach_bundle (sigc::slot > sl) +{ + Glib::Mutex::Lock lm (bundle_lock); + for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) { + sl (*i); + } +} diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 21c0405f21..618660e98f 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -1881,9 +1881,9 @@ Session::load_bundles (const XMLNode& node) for (niter = nlist.begin(); niter != nlist.end(); ++niter) { if ((*niter)->name() == "InputConnection") { - add_bundle (new ARDOUR::InputBundle (**niter)); + add_bundle (boost::shared_ptr (new InputBundle (**niter))); } else if ((*niter)->name() == "OutputConnection") { - add_bundle (new ARDOUR::OutputBundle (**niter)); + add_bundle (boost::shared_ptr (new OutputBundle (**niter))); } else { error << string_compose(_("Unknown node \"%1\" found in Connections list from state file"), (*niter)->name()) << endmsg; return -1;