diff options
author | Carl Hetherington <carl@carlh.net> | 2009-02-09 03:18:10 +0000 |
---|---|---|
committer | Carl Hetherington <carl@carlh.net> | 2009-02-09 03:18:10 +0000 |
commit | ee42a6dd97045253d1a9bb32fc2e571d235f9967 (patch) | |
tree | 1d4994d28477b659474075fdf82f7dbc9069bf7d /libs/ardour | |
parent | 91032b311ee44d7bcca65feb06aca077cc3671b5 (diff) |
Fixes to bundle manager to make it vaguely usable.
Rework signal handling for bundles so that all changes should now be noticed by port matrices.
git-svn-id: svn://localhost/ardour2/branches/3.0@4501 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/ardour/bundle.h | 46 | ||||
-rw-r--r-- | libs/ardour/ardour/io.h | 12 | ||||
-rw-r--r-- | libs/ardour/bundle.cc | 149 | ||||
-rw-r--r-- | libs/ardour/io.cc | 70 | ||||
-rw-r--r-- | libs/ardour/user_bundle.cc | 7 |
5 files changed, 207 insertions, 77 deletions
diff --git a/libs/ardour/ardour/bundle.h b/libs/ardour/ardour/bundle.h index 005e86842f..77d5e23196 100644 --- a/libs/ardour/ardour/bundle.h +++ b/libs/ardour/ardour/bundle.h @@ -57,24 +57,9 @@ class Bundle : public sigc::trackable PortList ports; }; - /** Construct an audio bundle. - * @param i true if ports are inputs, otherwise false. - */ - Bundle (bool i = true) : _type (DataType::AUDIO), _ports_are_inputs (i) {} - - /** Construct an audio bundle. - * @param n Name. - * @param i true if ports are inputs, otherwise false. - */ - Bundle (std::string const & n, bool i = true) : _name (n), _type (DataType::AUDIO), _ports_are_inputs (i) {} - - /** Construct a bundle. - * @param n Name. - * @param t Type. - * @param i true if ports are inputs, otherwise false. - */ - Bundle (std::string const & n, DataType t, bool i = true) : _name (n), _type (t), _ports_are_inputs (i) {} - + Bundle (bool i = true); + Bundle (std::string const &, bool i = true); + Bundle (std::string const &, DataType, bool i = true); Bundle (boost::shared_ptr<Bundle>); virtual ~Bundle() {} @@ -93,6 +78,8 @@ class Bundle : public sigc::trackable void add_port_to_channel (uint32_t, std::string); void set_port (uint32_t, std::string); void remove_port_from_channel (uint32_t, std::string); + void remove_ports_from_channel (uint32_t); + void remove_ports_from_channels (); bool port_attached_to_channel (uint32_t, std::string); bool uses_port (std::string) const; bool offers_port_alone (std::string) const; @@ -107,7 +94,7 @@ class Bundle : public sigc::trackable */ void set_name (std::string const & n) { _name = n; - NameChanged (); + Changed (NameChanged); } /** @return Bundle name */ @@ -126,14 +113,17 @@ class Bundle : public sigc::trackable bool ports_are_inputs () const { return _ports_are_inputs; } bool ports_are_outputs () const { return !_ports_are_inputs; } - bool operator== (Bundle const &) const; + void suspend_signals (); + void resume_signals (); + + /** Things that might change about this bundle */ + enum Change { + NameChanged = 0x1, ///< the bundle name or a channel name has changed + ConfigurationChanged = 0x2, ///< the number of channels has changed + PortsChanged = 0x4 ///< the port list associated with one of our channels has changed + }; - /** Emitted when the bundle name or a channel name has changed */ - sigc::signal<void> NameChanged; - /** The number of channels has changed */ - sigc::signal<void> ConfigurationChanged; - /** The port list associated with one of our channels has changed */ - sigc::signal<void, int> PortsChanged; + sigc::signal<void, Change> Changed; protected: @@ -145,10 +135,14 @@ class Bundle : public sigc::trackable private: int set_channels (std::string const &); int parse_io_string (std::string const &, std::vector<std::string> &); + void emit_changed (Change); std::string _name; DataType _type; bool _ports_are_inputs; + + bool _signals_suspended; + Change _pending_change; }; diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h index 5bb7a3f3b7..dd40e30837 100644 --- a/libs/ardour/ardour/io.h +++ b/libs/ardour/ardour/io.h @@ -43,6 +43,7 @@ #include <ardour/latent.h> #include <ardour/automation_control.h> #include <ardour/session_object.h> +#include <ardour/bundle.h> using std::string; using std::vector; @@ -53,8 +54,8 @@ namespace ARDOUR { class Session; class AudioEngine; -class Bundle; class UserBundle; +class Bundle; class Panner; class PeakMeter; class Port; @@ -62,7 +63,6 @@ class AudioPort; class MidiPort; class BufferSet; - /** A collection of input and output ports with connections. * * An IO can contain ports of varying types, making routes/inserts/etc with @@ -336,8 +336,7 @@ class IO : public SessionObject, public AutomatableControls, public Latent UserBundleInfo (IO*, boost::shared_ptr<UserBundle> b); boost::shared_ptr<UserBundle> bundle; - sigc::connection configuration_changed; - sigc::connection ports_changed; + sigc::connection changed; }; std::vector<UserBundleInfo> _bundles_connected_to_outputs; ///< user bundles connected to our outputs @@ -357,8 +356,7 @@ class IO : public SessionObject, public AutomatableControls, public Latent void check_bundles_connected_to_outputs (); void check_bundles (std::vector<UserBundleInfo>&, const PortSet&); - void bundle_configuration_changed (); - void bundle_ports_changed (int); + void bundle_changed (Bundle::Change); int create_ports (const XMLNode&); int make_connections (const XMLNode&); @@ -375,6 +373,8 @@ class IO : public SessionObject, public AutomatableControls, public Latent int32_t find_output_port_hole (const char* base); void setup_bundles_for_inputs_and_outputs (); + void setup_bundle_for_inputs (); + void setup_bundle_for_outputs (); std::string bundle_channel_name (uint32_t, uint32_t) const; }; diff --git a/libs/ardour/bundle.cc b/libs/ardour/bundle.cc index abf0bd07f9..f90b84ff25 100644 --- a/libs/ardour/bundle.cc +++ b/libs/ardour/bundle.cc @@ -30,11 +30,57 @@ using namespace ARDOUR; using namespace PBD; +/** Construct an audio bundle. + * @param i true if ports are inputs, otherwise false. + */ +Bundle::Bundle (bool i) + : _type (DataType::AUDIO), + _ports_are_inputs (i), + _signals_suspended (false), + _pending_change (Change (0)) +{ + +} + + +/** Construct an audio bundle. + * @param n Name. + * @param i true if ports are inputs, otherwise false. + */ +Bundle::Bundle (std::string const & n, bool i) + : _name (n), + _type (DataType::AUDIO), + _ports_are_inputs (i), + _signals_suspended (false), + _pending_change (Change (0)) +{ + +} + + +/** Construct a bundle. + * @param n Name. + * @param t Type. + * @param i true if ports are inputs, otherwise false. + */ +Bundle::Bundle (std::string const & n, DataType t, bool i) + : _name (n), + _type (t), + _ports_are_inputs (i), + _signals_suspended (false), + _pending_change (Change (0)) +{ + +} + + Bundle::Bundle (boost::shared_ptr<Bundle> other) : _channel (other->_channel), _name (other->_name), _type (other->_type), - _ports_are_inputs (other->_ports_are_inputs) + _ports_are_inputs (other->_ports_are_inputs), + _signals_suspended (other->_signals_suspended), + _pending_change (other->_pending_change) { } @@ -69,8 +115,8 @@ Bundle::add_port_to_channel (uint32_t ch, string portname) Glib::Mutex::Lock lm (_channel_mutex); _channel[ch].ports.push_back (portname); } - - PortsChanged (ch); /* EMIT SIGNAL */ + + emit_changed (PortsChanged); } /** Disassociate a port from one of our channels. @@ -96,20 +142,10 @@ Bundle::remove_port_from_channel (uint32_t ch, string portname) } if (changed) { - PortsChanged (ch); /* EMIT SIGNAL */ + emit_changed (PortsChanged); } } -/** operator== for Bundles; they are equal if their channels are the same. - * @param other Bundle to compare with this one. - */ -bool -Bundle::operator== (const Bundle& other) const -{ - return other._channel == _channel; -} - - /** Set a single port to be associated with a channel, removing any others. * @param ch Channel. * @param portname Full port name, including prefix. @@ -126,7 +162,7 @@ Bundle::set_port (uint32_t ch, string portname) _channel[ch].ports.push_back (portname); } - PortsChanged (ch); /* EMIT SIGNAL */ + emit_changed (PortsChanged); } /** @param n Channel name */ @@ -138,7 +174,7 @@ Bundle::add_channel (std::string const & n) _channel.push_back (Channel (n)); } - ConfigurationChanged (); /* EMIT SIGNAL */ + emit_changed (ConfigurationChanged); } bool @@ -150,6 +186,9 @@ Bundle::port_attached_to_channel (uint32_t ch, std::string portname) return (std::find (_channel[ch].ports.begin (), _channel[ch].ports.end (), portname) != _channel[ch].ports.end ()); } +/** Remove a channel. + * @param ch Channel. + */ void Bundle::remove_channel (uint32_t ch) { @@ -159,6 +198,7 @@ Bundle::remove_channel (uint32_t ch) _channel.erase (_channel.begin () + ch); } +/** Remove all channels */ void Bundle::remove_channels () { @@ -167,6 +207,9 @@ Bundle::remove_channels () _channel.clear (); } +/** @param p Port name. + * @return true if any channel is associated with p. + */ bool Bundle::uses_port (std::string p) const { @@ -200,6 +243,10 @@ Bundle::offers_port_alone (std::string p) const return false; } + +/** @param ch Channel. + * @return Channel name. + */ std::string Bundle::channel_name (uint32_t ch) const { @@ -209,6 +256,10 @@ Bundle::channel_name (uint32_t ch) const return _channel[ch].name; } +/** Set the name of a channel. + * @param ch Channel. + * @param n New name. + */ void Bundle::set_channel_name (uint32_t ch, std::string const & n) { @@ -219,7 +270,7 @@ Bundle::set_channel_name (uint32_t ch, std::string const & n) _channel[ch].name = n; } - NameChanged (); /* EMIT SIGNAL */ + emit_changed (NameChanged); } /** Take the channels from another bundle and add them to this bundle, @@ -245,6 +296,11 @@ Bundle::add_channels_from_bundle (boost::shared_ptr<Bundle> other) } } +/** Connect the ports associated with our channels to the ports associated + * with another bundle's channels. + * @param other Other bundle. + * @param engine AudioEngine to use to make the connections. + */ void Bundle::connect (boost::shared_ptr<Bundle> other, AudioEngine & engine) { @@ -280,3 +336,62 @@ Bundle::disconnect (boost::shared_ptr<Bundle> other, AudioEngine & engine) } } } + +/** Remove all ports from all channels */ +void +Bundle::remove_ports_from_channels () +{ + { + Glib::Mutex::Lock lm (_channel_mutex); + for (uint32_t c = 0; c < _channel.size(); ++c) { + _channel[c].ports.clear (); + } + + } + + emit_changed (PortsChanged); +} + +/** Remove all ports from a given channel. + * @param ch Channel. + */ +void +Bundle::remove_ports_from_channel (uint32_t ch) +{ + assert (ch < nchannels ()); + + { + Glib::Mutex::Lock lm (_channel_mutex); + _channel[ch].ports.clear (); + } + + emit_changed (PortsChanged); +} + +void +Bundle::suspend_signals () +{ + _signals_suspended = true; +} + +void +Bundle::resume_signals () +{ + if (_pending_change) { + Changed (_pending_change); + _pending_change = Change (0); + } + + _signals_suspended = false; +} + +void +Bundle::emit_changed (Change c) +{ + if (_signals_suspended) { + _pending_change = Change (int (_pending_change) | int (c)); + } else { + Changed (c); + } +} + diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index 00281d510f..1b130097e7 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -396,8 +396,7 @@ IO::check_bundles (std::vector<UserBundleInfo>& list, const PortSet& ports) if (ok) { new_list.push_back (*i); } else { - i->configuration_changed.disconnect (); - i->ports_changed.disconnect (); + i->changed.disconnect (); } } @@ -604,7 +603,7 @@ IO::remove_output_port (Port* port, void* src) } if (change == ConfigurationChanged) { - setup_bundles_for_inputs_and_outputs (); + setup_bundle_for_outputs (); } if (change != NoChange) { @@ -666,7 +665,7 @@ IO::add_output_port (string destination, void* src, DataType type) // pan_changed (src); /* EMIT SIGNAL */ output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */ - setup_bundles_for_inputs_and_outputs (); + setup_bundle_for_outputs (); _session.set_dirty (); return 0; @@ -708,7 +707,7 @@ IO::remove_input_port (Port* port, void* src) } if (change == ConfigurationChanged) { - setup_bundles_for_inputs_and_outputs (); + setup_bundle_for_inputs (); } if (change != NoChange) { @@ -771,7 +770,7 @@ IO::add_input_port (string source, void* src, DataType type) // pan_changed (src); /* EMIT SIGNAL */ input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */ - setup_bundles_for_inputs_and_outputs (); + setup_bundle_for_inputs (); _session.set_dirty (); return 0; @@ -1013,16 +1012,17 @@ IO::ensure_io (ChanCount in, ChanCount out, bool clear, void* src) if (out_changed) { check_bundles_connected_to_outputs (); output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */ + setup_bundle_for_outputs (); } if (in_changed) { check_bundles_connected_to_inputs (); input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */ + setup_bundle_for_inputs (); } if (in_changed || out_changed) { PortCountChanged (max (n_outputs(), n_inputs())); /* EMIT SIGNAL */ - setup_bundles_for_inputs_and_outputs (); _session.set_dirty (); } @@ -1050,7 +1050,7 @@ IO::ensure_inputs (ChanCount count, bool clear, bool lockit, void* src) if (changed) { input_changed (ConfigurationChanged, src); /* EMIT SIGNAL */ - setup_bundles_for_inputs_and_outputs (); + setup_bundle_for_inputs (); _session.set_dirty (); } return 0; @@ -1142,7 +1142,7 @@ IO::ensure_outputs (ChanCount count, bool clear, bool lockit, void* src) if (changed) { output_changed (ConfigurationChanged, src); /* EMIT SIGNAL */ - setup_bundles_for_inputs_and_outputs (); + setup_bundle_for_outputs (); } return 0; @@ -2220,20 +2220,13 @@ IO::reset_panners () } void -IO::bundle_configuration_changed () +IO::bundle_changed (Bundle::Change c) { //XXX // connect_input_ports_to_bundle (_input_bundle, this); } void -IO::bundle_ports_changed (int ignored) -{ - //XXX -// connect_output_ports_to_bundle (_output_bundle, this); -} - -void IO::GainControl::set_value (float val) { // max gain at about +6dB (10.0 ^ ( 6 dB * 0.05)) @@ -2615,18 +2608,24 @@ IO::update_port_total_latencies () void IO::setup_bundles_for_inputs_and_outputs () { + setup_bundle_for_inputs (); + setup_bundle_for_outputs (); +} + + +void +IO::setup_bundle_for_inputs () +{ char buf[32]; if (!_bundle_for_inputs) { _bundle_for_inputs.reset (new Bundle (true)); } - if (!_bundle_for_outputs) { - _bundle_for_outputs.reset (new Bundle (false)); - } + _bundle_for_inputs->suspend_signals (); + _bundle_for_inputs->remove_channels (); - _bundle_for_outputs->remove_channels (); - + snprintf(buf, sizeof (buf), _("%s in"), _name.c_str()); _bundle_for_inputs->set_name (buf); uint32_t const ni = inputs().num_ports(); @@ -2635,6 +2634,23 @@ IO::setup_bundles_for_inputs_and_outputs () _bundle_for_inputs->set_port (i, _session.engine().make_port_name_non_relative (inputs().port(i)->name())); } + _bundle_for_inputs->resume_signals (); +} + + +void +IO::setup_bundle_for_outputs () +{ + char buf[32]; + + if (!_bundle_for_outputs) { + _bundle_for_outputs.reset (new Bundle (false)); + } + + _bundle_for_outputs->suspend_signals (); + + _bundle_for_outputs->remove_channels (); + snprintf(buf, sizeof (buf), _("%s out"), _name.c_str()); _bundle_for_outputs->set_name (buf); uint32_t const no = outputs().num_ports(); @@ -2642,8 +2658,11 @@ IO::setup_bundles_for_inputs_and_outputs () _bundle_for_outputs->add_channel (bundle_channel_name (i, no)); _bundle_for_outputs->set_port (i, _session.engine().make_port_name_non_relative (outputs().port(i)->name())); } + + _bundle_for_outputs->resume_signals (); } + /** @return Bundles connected to our inputs */ BundleList IO::bundles_connected_to_inputs () @@ -2711,11 +2730,8 @@ IO::bundles_connected_to_outputs () IO::UserBundleInfo::UserBundleInfo (IO* io, boost::shared_ptr<UserBundle> b) { bundle = b; - configuration_changed = b->ConfigurationChanged.connect ( - sigc::mem_fun (*io, &IO::bundle_configuration_changed) - ); - ports_changed = b->PortsChanged.connect ( - sigc::mem_fun (*io, &IO::bundle_ports_changed) + changed = b->Changed.connect ( + sigc::mem_fun (*io, &IO::bundle_changed) ); } diff --git a/libs/ardour/user_bundle.cc b/libs/ardour/user_bundle.cc index 2dee0af01e..b20e79c69a 100644 --- a/libs/ardour/user_bundle.cc +++ b/libs/ardour/user_bundle.cc @@ -45,7 +45,12 @@ ARDOUR::UserBundle::set_state (XMLNode const & node) return -1; } - add_channel ("XXX"); + if ((name = (*i)->property ("name")) == 0) { + PBD::error << _("Node for Channel has no \"name\" property") << endmsg; + return -1; + } + + add_channel (name->value ()); XMLNodeList const ports = (*i)->children (); |