X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fardour%2Fio.h;h=b718cfa5c9aeeed5b22ef460892d481f929a7ff7;hb=aae367b63c9b619db1e40f27dc334c6987219481;hp=7c198bb72ab696dc669a1758db2f0ccde8414346;hpb=ca81401b14782b5d13905732778e6bf9b5f5f2ae;p=ardour.git diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h index 7c198bb72a..b718cfa5c9 100644 --- a/libs/ardour/ardour/io.h +++ b/libs/ardour/ardour/io.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2000 Paul Davis + Copyright (C) 2000 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 @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_io_h__ @@ -24,362 +23,200 @@ #include #include #include -#include #include #include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -using std::string; -using std::vector; +#include "pbd/fastlog.h" +#include "pbd/undo.h" +#include "pbd/statefuldestructible.h" +#include "pbd/controllable.h" + +#include "ardour/ardour.h" +#include "ardour/automatable_controls.h" +#include "ardour/automation_control.h" +#include "ardour/bundle.h" +#include "ardour/chan_count.h" +#include "ardour/data_type.h" +#include "ardour/latent.h" +#include "ardour/port_set.h" +#include "ardour/session_object.h" +#include "ardour/types.h" +#include "ardour/utils.h" class XMLNode; namespace ARDOUR { -class Session; +class Amp; class AudioEngine; +class AudioPort; +class BufferSet; +class Bundle; +class MidiPort; +class PeakMeter; class Port; -class Connection; -class Panner; +class Processor; +class Session; +class UserBundle; -/** A collection of input and output ports with connections. +/** A collection of ports (all input or all output) with connections. * * An IO can contain ports of varying types, making routes/inserts/etc with * varied combinations of types (eg MIDI and audio) possible. */ -class IO : public PBD::StatefulDestructible +class IO : public SessionObject, public Latent { - public: - static const string state_node_name; + static const std::string state_node_name; - IO (Session&, string name, - int input_min = -1, int input_max = -1, - int output_min = -1, int output_max = -1, - DataType default_type = DataType::AUDIO); + enum Direction { + Input, + Output + }; + IO (Session&, const std::string& name, Direction, DataType default_type = DataType::AUDIO); IO (Session&, const XMLNode&, DataType default_type = DataType::AUDIO); virtual ~IO(); - int input_minimum() const { return _input_minimum; } - int input_maximum() const { return _input_maximum; } - int output_minimum() const { return _output_minimum; } - int output_maximum() const { return _output_maximum; } - - void set_input_minimum (int n); - void set_input_maximum (int n); - void set_output_minimum (int n); - void set_output_maximum (int n); - - DataType default_type() const { return _default_type; } - - const string& name() const { return _name; } - virtual int set_name (string str, void *src); - - virtual void silence (nframes_t, nframes_t offset); - - // These should be moved in to a separate object that manipulates an IO - - void pan (vector& bufs, uint32_t nbufs, nframes_t nframes, nframes_t offset, gain_t gain_coeff); - void pan_automated (vector& bufs, uint32_t nbufs, nframes_t start_frame, nframes_t end_frame, - nframes_t nframes, nframes_t offset); - void collect_input (vector&, uint32_t nbufs, nframes_t nframes, nframes_t offset); - void deliver_output (vector&, uint32_t nbufs, nframes_t nframes, nframes_t offset); - void deliver_output_no_pan (vector&, uint32_t nbufs, nframes_t nframes, nframes_t offset); - void just_meter_input (nframes_t start_frame, nframes_t end_frame, - nframes_t nframes, nframes_t offset); + Direction direction() const { return _direction; } - virtual uint32_t n_process_buffers () { return 0; } + DataType default_type() const { return _default_type; } + void set_default_type(DataType t) { _default_type = t; } - virtual void set_gain (gain_t g, void *src); - void inc_gain (gain_t delta, void *src); - gain_t gain () const { return _desired_gain; } - virtual gain_t effective_gain () const; + bool active() const { return _active; } + void set_active(bool yn) { _active = yn; } - Panner& panner() { return *_panner; } + bool set_name (const std::string& str); - int ensure_io (uint32_t, uint32_t, bool clear, void *src); + virtual void silence (nframes_t); - int use_input_connection (Connection&, void *src); - int use_output_connection (Connection&, void *src); + int ensure_io (ChanCount cnt, bool clear, void *src); - Connection *input_connection() const { return _input_connection; } - Connection *output_connection() const { return _output_connection; } + int connect_ports_to_bundle (boost::shared_ptr, void *); + int disconnect_ports_from_bundle (boost::shared_ptr, void *); - int add_input_port (string source, void *src, DataType type = DataType::NIL); - int add_output_port (string destination, void *src, DataType type = DataType::NIL); + BundleList bundles_connected (); - int remove_input_port (Port *, void *src); - int remove_output_port (Port *, void *src); + boost::shared_ptr bundle () { return _bundle; } - int set_input (Port *, void *src); + int add_port (std::string connection, void *src, DataType type = DataType::NIL); + int remove_port (Port *, void *src); + int connect (Port *our_port, std::string other_port, void *src); + int disconnect (Port *our_port, std::string other_port, void *src); + int disconnect (void *src); + bool connected_to (boost::shared_ptr) const; - int connect_input (Port *our_port, string other_port, void *src); - int connect_output (Port *our_port, string other_port, void *src); + nframes_t signal_latency() const { return _own_latency; } + nframes_t latency() const; + void set_port_latency (nframes_t); - int disconnect_input (Port *our_port, string other_port, void *src); - int disconnect_output (Port *our_port, string other_port, void *src); + void update_port_total_latencies (); - int disconnect_inputs (void *src); - int disconnect_outputs (void *src); + PortSet& ports() { return _ports; } + const PortSet& ports() const { return _ports; } - nframes_t output_latency() const; - nframes_t input_latency() const; - void set_port_latency (nframes_t); - - Port *output (uint32_t n) const { - if (n < _noutputs) { - return _outputs[n]; + Port *nth (uint32_t n) const { + if (n < _ports.num_ports()) { + return _ports.port(n); } else { return 0; } } - Port *input (uint32_t n) const { - if (n < _ninputs) { - return _inputs[n]; - } else { - return 0; - } - } + Port* port_by_name (const std::string& str) const; - uint32_t n_inputs () const { return _ninputs; } - uint32_t n_outputs () const { return _noutputs; } + AudioPort* audio(uint32_t n) const; + MidiPort* midi(uint32_t n) const; - sigc::signal input_changed; - sigc::signal output_changed; + const ChanCount& n_ports () const { return _ports.count(); } - sigc::signal gain_changed; - sigc::signal name_changed; + PBD::Signal2 changed; virtual XMLNode& state (bool full); XMLNode& get_state (void); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version); + int set_state_2X (const XMLNode&, int, bool); static int disable_connecting (void); static int enable_connecting (void); static int disable_ports (void); static int enable_ports (void); - static int disable_panners (void); - static int reset_panners (void); - - static sigc::signal PortsLegal; - static sigc::signal PannersLegal; - static sigc::signal ConnectingLegal; - static sigc::signal MoreOutputs; - static sigc::signal PortsCreated; - - PBD::Controllable& gain_control() { - return _gain_control; - } - - /* Peak metering */ - float peak_input_power (uint32_t n) { - if (_ninputs == 0) { - return minus_infinity(); - } else if (n < std::max (_ninputs, _noutputs)) { - return _visible_peak_power[n]; - } else { - return minus_infinity(); - } - } + static PBD::Signal1 PortCountChanged; // emitted when the number of ports changes - static void update_meters(); - - private: - - static sigc::signal Meter; - static Glib::StaticMutex m_meter_signal_lock; - sigc::connection m_meter_connection; - - public: - - /* automation */ - - static void set_automation_interval (jack_nframes_t frames) { - _automation_interval = frames; - } - - static jack_nframes_t automation_interval() { - return _automation_interval; - } - - void clear_automation (); - - bool gain_automation_recording() const { - return (_gain_automation_curve.automation_state() & (Write|Touch)); - } + static std::string name_from_state (const XMLNode&); + static void set_name_in_state (XMLNode&, const std::string&); - bool gain_automation_playback() const { - return (_gain_automation_curve.automation_state() & Play) || - ((_gain_automation_curve.automation_state() & Touch) && - !_gain_automation_curve.touching()); - } - - virtual void set_gain_automation_state (AutoState); - AutoState gain_automation_state() const { return _gain_automation_curve.automation_state(); } - sigc::signal gain_automation_state_changed; - - virtual void set_gain_automation_style (AutoStyle); - AutoStyle gain_automation_style () const { return _gain_automation_curve.automation_style(); } - sigc::signal gain_automation_style_changed; - - virtual void transport_stopped (nframes_t now); - void automation_snapshot (nframes_t now); + /* we have to defer/order port connection. this is how we do it. + */ - ARDOUR::Curve& gain_automation_curve () { return _gain_automation_curve; } + static PBD::Signal0 ConnectingLegal; + static bool connecting_legal; - void start_gain_touch (); - void end_gain_touch (); + XMLNode *pending_state_node; + int pending_state_node_version; + bool pending_state_node_in; - void start_pan_touch (uint32_t which); - void end_pan_touch (uint32_t which); + /* three utility functions - this just seems to be simplest place to put them */ - void defer_pan_reset (); - void allow_pan_reset (); + void collect_input (BufferSet& bufs, nframes_t nframes, ChanCount offset); + void process_input (boost::shared_ptr, sframes_t start_frame, sframes_t end_frame, nframes_t nframes); + void copy_to_outputs (BufferSet& bufs, DataType type, nframes_t nframes, nframes_t offset); - /* the session calls this for master outs before - anyone else. controls outs too, at some point. - */ + /* AudioTrack::deprecated_use_diskstream_connections() needs these */ - XMLNode *pending_state_node; - int ports_became_legal (); + int set_ports (const std::string& str); private: mutable Glib::Mutex io_lock; protected: - Session& _session; - Panner* _panner; - gain_t _gain; - gain_t _effective_gain; - gain_t _desired_gain; - Glib::Mutex declick_lock; - vector _outputs; - vector _inputs; - vector _peak_power; - vector _visible_peak_power; - string _name; - Connection* _input_connection; - Connection* _output_connection; - bool no_panner_reset; - XMLNode* deferred_state; - DataType _default_type; - bool _ignore_gain_on_deliver; - - - virtual void set_deferred_state() {} - - void reset_peak_meters(); - void reset_panner (); - - virtual uint32_t pans_required() const { return _ninputs; } - - static void apply_declick (vector&, uint32_t nbufs, nframes_t nframes, - gain_t initial, gain_t target, bool invert_polarity); - - struct GainControllable : public PBD::Controllable { - GainControllable (std::string name, IO& i) : Controllable (name), io (i) {} - - void set_value (float val); - float get_value (void) const; - - IO& io; - }; - - GainControllable _gain_control; - - nframes_t last_automation_snapshot; - static nframes_t _automation_interval; - - AutoState _gain_automation_state; - AutoStyle _gain_automation_style; - - bool apply_gain_automation; - Curve _gain_automation_curve; - - Glib::Mutex automation_lock; - - virtual int set_automation_state (const XMLNode&); - virtual XMLNode& get_automation_state (); - virtual int load_automation (std::string path); - - /* AudioTrack::deprecated_use_diskstream_connections() needs these */ - - int set_inputs (const string& str); - int set_outputs (const string& str); - - static bool connecting_legal; - static bool ports_legal; + PortSet _ports; + Direction _direction; + DataType _default_type; + bool _active; private: - - uint32_t _ninputs; - uint32_t _noutputs; - - /* are these the best variable names ever, or what? */ - - sigc::connection input_connection_configuration_connection; - sigc::connection output_connection_configuration_connection; - sigc::connection input_connection_connection_connection; - sigc::connection output_connection_connection_connection; - - static bool panners_legal; - int connecting_became_legal (); - int panners_became_legal (); - sigc::connection connection_legal_c; - sigc::connection port_legal_c; - sigc::connection panner_legal_c; + PBD::ScopedConnection connection_legal_c; - int _input_minimum; - int _input_maximum; - int _output_minimum; - int _output_maximum; + boost::shared_ptr _bundle; ///< a bundle representing our ports + struct UserBundleInfo { + UserBundleInfo (IO*, boost::shared_ptr b); + boost::shared_ptr bundle; + PBD::ScopedConnection changed; + }; + + std::vector _bundles_connected; ///< user bundles connected to our ports - static int parse_io_string (const string&, vector& chns); + static int parse_io_string (const std::string&, std::vector& chns); + static int parse_gain_string (const std::string&, std::vector& chns); - static int parse_gain_string (const string&, vector& chns); - - int set_sources (vector&, void *src, bool add); - int set_destinations (vector&, void *src, bool add); + int ensure_ports (ChanCount, bool clear, bool lockit, void *src); - int ensure_inputs (uint32_t, bool clear, bool lockit, void *src); - int ensure_outputs (uint32_t, bool clear, bool lockit, void *src); + void check_bundles_connected (); + void check_bundles (std::vector&, const PortSet&); - void drop_input_connection (); - void drop_output_connection (); + void bundle_changed (Bundle::Change); - void input_connection_configuration_changed (); - void input_connection_connection_changed (int); - void output_connection_configuration_changed (); - void output_connection_connection_changed (int); + int get_port_counts (const XMLNode& node, int version, ChanCount& n, boost::shared_ptr& c); + int get_port_counts_2X (const XMLNode& node, int version, ChanCount& n, boost::shared_ptr& c); + int create_ports (const XMLNode&, int version); + int make_connections (const XMLNode&, int, bool); + int make_connections_2X (const XMLNode &, int, bool); - int create_ports (const XMLNode&); - int make_connections (const XMLNode&); + boost::shared_ptr find_possible_bundle (const std::string &desired_name); - void setup_peak_meters (); - void meter (); + bool ensure_ports_locked (ChanCount, bool clear, void *src); - bool ensure_inputs_locked (uint32_t, bool clear, void *src); - bool ensure_outputs_locked (uint32_t, bool clear, void *src); + std::string build_legal_port_name (DataType type); + int32_t find_port_hole (const char* base); - int32_t find_input_port_hole (); - int32_t find_output_port_hole (); + void setup_bundle (); + std::string bundle_channel_name (uint32_t, uint32_t) const; }; } // namespace ARDOUR