X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fardour%2Fbundle.h;h=ef2247f12b84338e609fa594f44e605853fac933;hb=94e0a15325278ec26dbeba4990a0e883db859338;hp=1ed285a1185c5373a9637a511ed0ec3135d2ca19;hpb=4b95621853072c44b1df698df8a96d7d9167319f;p=ardour.git diff --git a/libs/ardour/ardour/bundle.h b/libs/ardour/ardour/bundle.h index 1ed285a118..ef2247f12b 100644 --- a/libs/ardour/ardour/bundle.h +++ b/libs/ardour/ardour/bundle.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002 Paul Davis + Copyright (C) 2002-2007 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,112 +20,157 @@ #ifndef __ardour_bundle_h__ #define __ardour_bundle_h__ -#include #include -#include -#include -#include +#include +#include +#include -using std::vector; -using std::string; +#include "pbd/signals.h" + +#include "ardour/data_type.h" +#include "ardour/chan_count.h" namespace ARDOUR { -/** - * A set of `channels', each of which is associated with 0 or more - * JACK ports. - */ +class AudioEngine; -class Bundle : public PBD::Stateful, public sigc::trackable { +/** A set of `channels', each of which is associated with 0 or more ports. + * Each channel has a name which can be anything useful, and a data type. + * Intended for grouping things like, for example, a buss' outputs. + * `Channel' is a rather overloaded term but I can't think of a better + * one right now. + */ +class LIBARDOUR_API Bundle : public PBD::ScopedConnectionList +{ public: - /** - * Bundle constructor. - * @param name Name for this Bundle. - * @param dy true if this Bundle is `dynamic', ie it is created on-the-fly - * and should not be written to the session file. - */ - Bundle (string name, bool dy = false) : _name (name), _dynamic(dy) {} - ~Bundle() {} - /// A vector of JACK port names - typedef vector PortList; + /// List of ports associated with a channel. We can't use a + /// PortSet because we might want to involve non-Ardour ports + /// (ie those without a Port object) + typedef std::vector PortList; - void set_name (string name, void *src); + struct Channel { + Channel (std::string n, DataType t) : name (n), type (t) {} + Channel (std::string n, DataType t, PortList p) : name (n), type (t), ports (p) {} + Channel (std::string n, DataType t, std::string const & p) : name (n), type (t) { + ports.push_back (p); + } - /** - * @return name of this Bundle. - */ - string name() const { return _name; } + bool operator== (Channel const &o) const { + return name == o.name && type == o.type && ports == o.ports; + } - /** - * @return true if this Bundle is marked as `dynamic', meaning - * that it won't be written to the session file. - */ - bool dynamic() const { return _dynamic; } - - /** - * @return Number of channels that this Bundle has. - */ - uint32_t nchannels () const { return _channels.size(); } - const PortList& channel_ports (int ch) const; + std::string name; + DataType type; + PortList ports; + }; - void set_nchannels (int n); + Bundle (bool i = true); + Bundle (std::string const &, bool i = true); + Bundle (boost::shared_ptr); - void add_port_to_channel (int ch, string portname); - void remove_port_from_channel (int ch, string portname); + virtual ~Bundle() {} - /// Our name changed - sigc::signal NameChanged; - /// The number of channels changed - sigc::signal ConfigurationChanged; - /// The ports associated with one of our channels changed - sigc::signal PortsChanged; + /** @return Number of channels that this Bundle has */ + ChanCount nchannels () const; - bool operator==(const Bundle& other) const; - - XMLNode& get_state (void); - int set_state (const XMLNode&); + /** @param Channel index. + * @return Ports associated with this channel. + */ + PortList const & channel_ports (uint32_t) const; + + void add_channel (std::string const &, DataType); + void add_channel (std::string const &, DataType, std::string const &); + void add_channel (std::string const &, DataType, PortList); + std::string channel_name (uint32_t) const; + DataType channel_type (uint32_t) const; + void set_channel_name (uint32_t, std::string const &); + 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 offers_port (std::string) const; + bool offers_port_alone (std::string) const; + void remove_channel (uint32_t); + void remove_channels (); + void add_channels_from_bundle (boost::shared_ptr); + void connect (boost::shared_ptr, AudioEngine &); + void disconnect (boost::shared_ptr, AudioEngine &); + bool connected_to (boost::shared_ptr, AudioEngine &); + bool connected_to_anything (AudioEngine &); + bool has_same_ports (boost::shared_ptr) const; + uint32_t type_channel_to_overall (DataType, uint32_t) const; + uint32_t overall_channel_to_type (DataType, uint32_t) const; + + void set_name (std::string const &); + + /** @return Bundle name */ + std::string name () const { return _name; } + + void set_ports_are_inputs (); + void set_ports_are_outputs (); + bool ports_are_inputs () const { return _ports_are_inputs; } + bool ports_are_outputs () const { return !_ports_are_inputs; } + + void suspend_signals (); + void resume_signals (); + + bool operator== (Bundle const & other); + + /** 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 + TypeChanged = 0x8, ///< the data type has changed + DirectionChanged = 0x10 ///< the direction (whether ports are inputs or outputs) has changed + }; + + PBD::Signal1 Changed; protected: - Bundle (const XMLNode&); + + /// mutex for _channel_ports and _channel_names + /// XXX: is this necessary? + mutable Glib::Threads::Mutex _channel_mutex; + std::vector _channel; private: - mutable Glib::Mutex channels_lock; ///< mutex for _channels - vector _channels; ///< list of JACK ports associated with each of our channels - string _name; ///< name - bool _dynamic; ///< true if `dynamic', ie not to be written to the session file + int set_channels (std::string const &); + int parse_io_string (std::string const &, std::vector &); + void emit_changed (Change); - int set_channels (const string& str); - int parse_io_string (const string& str, vector& ports); -}; + std::string _name; + bool _ports_are_inputs; -/** - * Bundle in which the JACK ports are inputs. - */ - -class InputBundle : public Bundle { - public: - /** - * InputBundle 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. - */ - InputBundle (string name, bool dy = false) : Bundle (name, dy) {} - InputBundle (const XMLNode&); + bool _signals_suspended; + Change _pending_change; }; -/** - * Bundle in which the JACK ports are outputs. - */ - -class OutputBundle : public Bundle { - public: - OutputBundle (string name, bool dy = false) : Bundle (name, dy) {} - OutputBundle (const XMLNode&); +class LIBARDOUR_API BundleChannel +{ +public: + BundleChannel () : channel (-1) {} + + BundleChannel (boost::shared_ptr b, int c) + : bundle (b), channel (c) {} + + bool operator== (BundleChannel const& other) const { + return bundle == other.bundle && channel == other.channel; + } + + bool operator!= (BundleChannel const& other) const { + return bundle != other.bundle || channel != other.channel; + } + + boost::shared_ptr bundle; + int channel; ///< channel index, or -1 for "all" }; } -#endif /* __ardour_bundle_h__ */ +std::ostream & operator<< (std::ostream & o, ARDOUR::Bundle const &); +#endif /* __ardour_bundle_h__ */