X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fardour%2Froute.h;h=217ce36fe9759e8bd61776b9f4bd39493fbc89b1;hb=022818b4a796f52c0a91eea42e65aec0bc7bed43;hp=12f6dfd56a799da48e256e241f1bb19abdf9eb24;hpb=8e79cd5610789b377d0975640a555cc45d9300cb;p=ardour.git diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index 12f6dfd56a..217ce36fe9 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -15,22 +15,23 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #ifndef __ardour_route_h__ #define __ardour_route_h__ #include +#include #include -#include #include +#include #include #include +#include -#include #include +#include #include #include #include @@ -39,13 +40,12 @@ #include #include -#include -#include #include namespace ARDOUR { -class Insert; +class Processor; +class IOProcessor; class Send; class RouteGroup; @@ -60,7 +60,8 @@ class Route : public IO { protected: - typedef list > RedirectList; + typedef list > ProcessorList; + public: enum Flag { @@ -69,56 +70,57 @@ class Route : public IO ControlOut = 0x4 }; - Route (Session&, std::string name, int input_min, int input_max, int output_min, int output_max, Flag flags = Flag(0), DataType default_type = DataType::AUDIO); Route (Session&, const XMLNode&, DataType default_type = DataType::AUDIO); virtual ~Route(); + static std::string ensure_track_or_route_name(std::string, Session &); + std::string comment() { return _comment; } void set_comment (std::string str, void *src); long order_key (const char* name) const; void set_order_key (const char* name, long n); - bool hidden() const { return _flags & Hidden; } - bool master() const { return _flags & MasterOut; } - bool control() const { return _flags & ControlOut; } + bool is_hidden() const { return _flags & Hidden; } + bool is_master() const { return _flags & MasterOut; } + bool is_control() const { return _flags & ControlOut; } /* these are the core of the API of a Route. see the protected sections as well */ - virtual int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, - nframes_t offset, int declick, bool can_record, bool rec_monitors_input); + virtual int roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, + nframes_t offset, int declick, bool can_record, bool rec_monitors_input); + + virtual int no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, + nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input); - virtual int no_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, - nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input); + virtual int silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, + nframes_t offset, bool can_record, bool rec_monitors_input); - virtual int silent_roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, - nframes_t offset, bool can_record, bool rec_monitors_input); virtual void toggle_monitor_input (); virtual bool can_record() { return false; } virtual void set_record_enable (bool yn, void *src) {} virtual bool record_enabled() const { return false; } - virtual void handle_transport_stopped (bool abort, bool did_locate, bool flush_redirects); + virtual void handle_transport_stopped (bool abort, bool did_locate, bool flush_processors); virtual void set_pending_declick (int); /* end of vfunc-based API */ + void shift (nframes64_t, nframes64_t); + /* override IO::set_gain() to provide group control */ void set_gain (gain_t val, void *src); void inc_gain (gain_t delta, void *src); - - bool active() const { return _active; } - void set_active (bool yn); - + void set_solo (bool yn, void *src); bool soloed() const { return _soloed; } void set_solo_safe (bool yn, void *src); bool solo_safe() const { return _solo_safe; } - + void set_mute (bool yn, void *src); bool muted() const { return _muted; } bool solo_muted() const { return desired_solo_gain == 0.0; } @@ -126,9 +128,6 @@ class Route : public IO void set_mute_config (mute_type, bool, void *src); bool get_mute_config (mute_type); - void set_phase_invert (bool yn, void *src); - bool phase_invert() const { return _phase_invert; } - void set_edit_group (RouteGroup *, void *); void drop_edit_group (void *); RouteGroup *edit_group () { return _edit_group; } @@ -137,46 +136,61 @@ class Route : public IO void drop_mix_group (void *); RouteGroup *mix_group () { return _mix_group; } - virtual void set_meter_point (MeterPoint, void *src); - MeterPoint meter_point() const { return _meter_point; } + virtual void set_meter_point (MeterPoint, void *src); + MeterPoint meter_point() const { return _meter_point; } - /* Redirects */ + /* Processors */ - void flush_redirects (); + void flush_processors (); - template void foreach_redirect (T *obj, void (T::*func)(boost::shared_ptr)) { - Glib::RWLock::ReaderLock lm (redirect_lock); - for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) { - (obj->*func) (*i); + void foreach_processor (sigc::slot > method) { + Glib::RWLock::ReaderLock lm (_processor_lock); + for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) { + method (boost::weak_ptr (*i)); } } - boost::shared_ptr nth_redirect (uint32_t n) { - Glib::RWLock::ReaderLock lm (redirect_lock); - RedirectList::iterator i; - for (i = _redirects.begin(); i != _redirects.end() && n; ++i, --n); - if (i == _redirects.end()) { - return boost::shared_ptr (); + boost::shared_ptr nth_processor (uint32_t n) { + Glib::RWLock::ReaderLock lm (_processor_lock); + ProcessorList::iterator i; + for (i = _processors.begin(); i != _processors.end() && n; ++i, --n); + if (i == _processors.end()) { + return boost::shared_ptr (); } else { return *i; } } - uint32_t max_redirect_outs () const { return redirect_max_outs; } - - int add_redirect (boost::shared_ptr, void *src, uint32_t* err_streams = 0); - int add_redirects (const RedirectList&, void *src, uint32_t* err_streams = 0); - int remove_redirect (boost::shared_ptr, void *src, uint32_t* err_streams = 0); - int copy_redirects (const Route&, Placement, uint32_t* err_streams = 0); - int sort_redirects (uint32_t* err_streams = 0); - - void clear_redirects (void *src); - void all_redirects_flip(); - void all_redirects_active (bool state); + ChanCount max_processor_outs () const { return processor_max_outs; } + ChanCount pre_fader_streams() 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. + */ + struct ProcessorStreams { + ProcessorStreams(size_t i=0, ChanCount c=ChanCount()) : index(i), count(c) {} + + size_t index; ///< Index of processor where configuration failed + ChanCount count; ///< Input requested of processor + }; + + int add_processor (boost::shared_ptr, ProcessorStreams* err = 0); + int add_processors (const ProcessorList&, ProcessorStreams* err = 0); + int remove_processor (boost::shared_ptr, ProcessorStreams* err = 0); + int sort_processors (ProcessorStreams* err = 0); + void disable_processors (Placement); + void disable_processors (); + void disable_plugins (Placement); + void disable_plugins (); + void ab_plugins (bool forward); + void clear_processors (Placement); + void all_processors_flip(); + void all_processors_active (Placement, bool state); virtual nframes_t update_total_latency(); - nframes_t signal_latency() const { return _own_latency; } - virtual void set_latency_delay (nframes_t); + void set_latency_delay (nframes_t); + void set_user_latency (nframes_t); + nframes_t initial_delay() const { return _initial_delay; } sigc::signal solo_changed; sigc::signal solo_safe_changed; @@ -186,12 +200,13 @@ class Route : public IO sigc::signal post_fader_changed; sigc::signal control_outs_changed; sigc::signal main_outs_changed; - sigc::signal redirects_changed; + sigc::signal processors_changed; sigc::signal record_enable_changed; sigc::signal edit_group_changed; sigc::signal mix_group_changed; - sigc::signal active_changed; sigc::signal meter_change; + sigc::signal signal_latency_changed; + sigc::signal initial_delay_changed; /* gui's call this for their own purposes. */ @@ -203,13 +218,16 @@ class Route : public IO int set_state(const XMLNode& node); virtual XMLNode& get_template(); + XMLNode& get_processor_state (); + int set_processor_state (const XMLNode&); + sigc::signal SelectedChanged; int set_control_outs (const vector& ports); IO* control_outs() { return _control_outs; } bool feeds (boost::shared_ptr); - set > fed_by; + std::set > fed_by; struct ToggleControllable : public PBD::Controllable { enum ToggleType { @@ -225,107 +243,110 @@ class Route : public IO ToggleType type; }; - PBD::Controllable& solo_control() { + boost::shared_ptr solo_control() { return _solo_control; } - PBD::Controllable& mute_control() { + boost::shared_ptr mute_control() { return _mute_control; } - void automation_snapshot (nframes_t now); + void automation_snapshot (nframes_t now, bool force=false); void protect_automation (); void set_remote_control_id (uint32_t id); uint32_t remote_control_id () const; sigc::signal RemoteControlIDChanged; + void sync_order_keys (const char* base); + static sigc::signal SyncOrderKeys; + protected: friend class Session; + void catch_up_on_solo_mute_override (); void set_solo_mute (bool yn); void set_block_size (nframes_t nframes); bool has_external_redirects() const; void curve_reallocate (); protected: - Flag _flags; - - /* tight cache-line access here is more important than sheer speed of - access. - */ - - bool _muted : 1; - bool _soloed : 1; - bool _solo_safe : 1; - bool _phase_invert : 1; - bool _recordable : 1; - bool _active : 1; - bool _mute_affects_pre_fader : 1; - bool _mute_affects_post_fader : 1; - bool _mute_affects_control_outs : 1; - bool _mute_affects_main_outs : 1; - bool _silent : 1; - bool _declickable : 1; - int _pending_declick; + nframes_t check_initial_delay (nframes_t, nframes_t&, nframes_t&); + + void passthru (nframes_t start_frame, nframes_t end_frame, + nframes_t nframes, nframes_t offset, int declick, bool meter_inputs); + + virtual void process_output_buffers (BufferSet& bufs, + nframes_t start_frame, nframes_t end_frame, + nframes_t nframes, nframes_t offset, bool with_processors, int declick, + bool meter); + + Flag _flags; + int _pending_declick; + MeterPoint _meter_point; + + gain_t solo_gain; + gain_t mute_gain; + gain_t desired_solo_gain; + gain_t desired_mute_gain; - MeterPoint _meter_point; - - gain_t solo_gain; - gain_t mute_gain; - gain_t desired_solo_gain; - gain_t desired_mute_gain; - - nframes_t check_initial_delay (nframes_t, nframes_t&, nframes_t&); - - nframes_t _initial_delay; - nframes_t _roll_delay; - nframes_t _own_latency; - RedirectList _redirects; - Glib::RWLock redirect_lock; - IO *_control_outs; - Glib::Mutex control_outs_lock; - RouteGroup *_edit_group; - RouteGroup *_mix_group; - std::string _comment; - bool _have_internal_generator; - - ToggleControllable _solo_control; - ToggleControllable _mute_control; + nframes_t _initial_delay; + nframes_t _roll_delay; + ProcessorList _processors; + Glib::RWLock _processor_lock; + IO *_control_outs; + Glib::Mutex _control_outs_lock; + RouteGroup *_edit_group; + RouteGroup *_mix_group; + std::string _comment; + bool _have_internal_generator; - void passthru (nframes_t start_frame, nframes_t end_frame, - nframes_t nframes, nframes_t offset, int declick, bool meter_inputs); + boost::shared_ptr _solo_control; + boost::shared_ptr _mute_control; + + /* tight cache-line access here is more important than sheer speed of access. + keep these after things that should be aligned + */ - void process_output_buffers (vector& bufs, uint32_t nbufs, - nframes_t start_frame, nframes_t end_frame, - nframes_t nframes, nframes_t offset, bool with_redirects, int declick, - bool meter); + bool _muted : 1; + bool _soloed : 1; + bool _solo_safe : 1; + bool _recordable : 1; + bool _mute_affects_pre_fader : 1; + bool _mute_affects_post_fader : 1; + bool _mute_affects_control_outs : 1; + bool _mute_affects_main_outs : 1; + bool _silent : 1; + bool _declickable : 1; protected: - /* for derived classes */ virtual XMLNode& state(bool); + void passthru_silence (nframes_t start_frame, nframes_t end_frame, + nframes_t nframes, nframes_t offset, int declick, + bool meter); + void silence (nframes_t nframes, nframes_t offset); + sigc::connection input_signal_connection; - uint32_t redirect_max_outs; + ChanCount processor_max_outs; uint32_t _remote_control_id; uint32_t pans_required() const; - uint32_t n_process_buffers (); + ChanCount n_process_buffers (); - virtual int _set_state (const XMLNode&, bool call_base); + virtual int _set_state (const XMLNode&, bool call_base); + virtual void _set_processor_states (const XMLNodeList&); private: void init (); static uint32_t order_key_cnt; - struct ltstr - { - bool operator()(const char* s1, const char* s2) const - { + struct ltstr { + bool operator()(const char* s1, const char* s2) const { return strcmp(s1, s2) < 0; } }; @@ -336,27 +357,24 @@ class Route : public IO void input_change_handler (IOChange, void *src); void output_change_handler (IOChange, void *src); - bool legal_redirect (Redirect&); - int reset_plugin_counts (uint32_t*); /* locked */ - int _reset_plugin_counts (uint32_t*); /* unlocked */ - - /* plugin count handling */ + int reset_processor_counts (ProcessorStreams*); /* locked */ + int _reset_processor_counts (ProcessorStreams*); /* unlocked */ - struct InsertCount { - boost::shared_ptr insert; - int32_t cnt; - int32_t in; - int32_t out; + /** processor I/O channels and plugin count handling */ + struct ProcessorCount { + boost::shared_ptr processor; + ChanCount in; + ChanCount out; - InsertCount (boost::shared_ptr ins) : insert (ins), cnt (-1) {} + ProcessorCount (boost::shared_ptr ins) : processor(ins) {} }; - int32_t apply_some_plugin_counts (std::list& iclist); - int32_t check_some_plugin_counts (std::list& iclist, int32_t required_inputs, uint32_t* err_streams); + int32_t apply_some_processor_counts (std::list& iclist); + bool check_some_processor_counts (std::list& iclist, + ChanCount required_inputs, ProcessorStreams* err_streams); void set_deferred_state (); - void add_redirect_from_xml (const XMLNode&); - void redirect_active_proxy (Redirect*, void*); + void add_processor_from_xml (const XMLNode&); }; } // namespace ARDOUR