diff options
Diffstat (limited to 'libs/ardour/ardour')
-rw-r--r-- | libs/ardour/ardour/amp.h | 67 | ||||
-rw-r--r-- | libs/ardour/ardour/automatable.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/click.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/delivery.h | 85 | ||||
-rw-r--r-- | libs/ardour/ardour/io.h | 274 | ||||
-rw-r--r-- | libs/ardour/ardour/io_processor.h | 28 | ||||
-rw-r--r-- | libs/ardour/ardour/meter.h | 18 | ||||
-rw-r--r-- | libs/ardour/ardour/mute_master.h | 77 | ||||
-rw-r--r-- | libs/ardour/ardour/panner.h | 8 | ||||
-rw-r--r-- | libs/ardour/ardour/port_insert.h | 13 | ||||
-rw-r--r-- | libs/ardour/ardour/processor.h | 22 | ||||
-rw-r--r-- | libs/ardour/ardour/rc_configuration_vars.h | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/return.h | 20 | ||||
-rw-r--r-- | libs/ardour/ardour/route.h | 165 | ||||
-rw-r--r-- | libs/ardour/ardour/send.h | 26 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 13 |
16 files changed, 440 insertions, 381 deletions
diff --git a/libs/ardour/ardour/amp.h b/libs/ardour/ardour/amp.h index 152b89a431..03cc3d02f7 100644 --- a/libs/ardour/ardour/amp.h +++ b/libs/ardour/ardour/amp.h @@ -22,19 +22,20 @@ #include "ardour/types.h" #include "ardour/chan_count.h" #include "ardour/processor.h" +#include "ardour/automation_control.h" namespace ARDOUR { class BufferSet; class IO; - +class MuteMaster; /** Applies a declick operation to all audio inputs, passing the same number of * audio outputs, and passing through any other types unchanged. */ class Amp : public Processor { public: - Amp(Session& s, IO& io); + Amp(Session& s, boost::shared_ptr<MuteMaster> m); bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const; bool configure_io (ChanCount in, ChanCount out); @@ -44,38 +45,54 @@ public: bool apply_gain() const { return _apply_gain; } void apply_gain(bool yn) { _apply_gain = yn; } + void setup_gain_automation (sframes_t start_frame, sframes_t end_frame, nframes_t nframes); + bool apply_gain_automation() const { return _apply_gain_automation; } void apply_gain_automation(bool yn) { _apply_gain_automation = yn; } - void muute(bool yn) { _mute = yn; } + XMLNode& state (bool full); - void set_gain(float current, float desired) { - _current_gain = current; - _desired_gain = desired; - } - - void apply_mute(bool yn, float current=1.0, float desired=0.0) { - _mute = yn; - _current_mute_gain = current; - _desired_mute_gain = desired; - } + static void apply_gain (BufferSet& bufs, nframes_t nframes, gain_t initial, gain_t target); + static void apply_simple_gain(BufferSet& bufs, nframes_t nframes, gain_t target); - XMLNode& state (bool full); + gain_t gain () const { return _gain_control->user_float(); } - static void apply_gain (BufferSet& bufs, nframes_t nframes, - gain_t initial, gain_t target, bool invert_polarity); + virtual void set_gain (gain_t g, void *src); + void inc_gain (gain_t delta, void *src); - static void apply_simple_gain(BufferSet& bufs, nframes_t nframes, gain_t target); + static void update_meters(); + + /* automation */ + + struct GainControl : public AutomationControl { + GainControl (std::string name, Session& session, Amp* a, const Evoral::Parameter ¶m, + boost::shared_ptr<AutomationList> al = boost::shared_ptr<AutomationList>() ) + : AutomationControl (session, param, al, name ) + , _amp (a) + {} + + void set_value (float val); + float get_value (void) const; + + Amp* _amp; + }; + + boost::shared_ptr<GainControl> gain_control() { + return _gain_control; + } + + boost::shared_ptr<const GainControl> gain_control() const { + return _gain_control; + } private: - IO& _io; - bool _mute; - bool _apply_gain; - bool _apply_gain_automation; - float _current_gain; - float _desired_gain; - float _current_mute_gain; - float _desired_mute_gain; + bool _denormal_protection; + bool _apply_gain; + bool _apply_gain_automation; + float _current_gain; + + boost::shared_ptr<GainControl> _gain_control; + boost::shared_ptr<MuteMaster> _mute_master; }; diff --git a/libs/ardour/ardour/automatable.h b/libs/ardour/ardour/automatable.h index 5eacfa14b2..ed98e8d8ba 100644 --- a/libs/ardour/ardour/automatable.h +++ b/libs/ardour/ardour/automatable.h @@ -58,7 +58,7 @@ public: virtual void add_control(boost::shared_ptr<Evoral::Control>); virtual void automation_snapshot(nframes_t now, bool force); - virtual void transport_stopped(nframes_t now); + virtual void transport_stopped (sframes_t now); virtual std::string describe_parameter(Evoral::Parameter param); diff --git a/libs/ardour/ardour/click.h b/libs/ardour/ardour/click.h index 8488df47a6..2f174ab472 100644 --- a/libs/ardour/ardour/click.h +++ b/libs/ardour/ardour/click.h @@ -27,7 +27,7 @@ namespace ARDOUR { class ClickIO : public IO { public: - ClickIO (Session& s, const std::string& name) : IO (s, name) {} + ClickIO (Session& s, const std::string& name) : IO (s, name, IO::Output) {} ~ClickIO() {} protected: diff --git a/libs/ardour/ardour/delivery.h b/libs/ardour/ardour/delivery.h index 8d083695b1..645b601251 100644 --- a/libs/ardour/ardour/delivery.h +++ b/libs/ardour/ardour/delivery.h @@ -28,48 +28,91 @@ namespace ARDOUR { class BufferSet; class IO; +class MuteMaster; +class Panner; class Delivery : public IOProcessor { public: enum Role { - Send = 0x1, - Solo = 0x2, + Insert = 0x1, + Send = 0x2, Listen = 0x4, Main = 0x8 }; - Delivery (Session& s, IO* io, const std::string& name, Role); - Delivery (Session& s, const std::string& name, Role); - Delivery (Session&, const XMLNode&); + Delivery (Session& s, boost::shared_ptr<IO> io, boost::shared_ptr<MuteMaster> mm, const std::string& name, Role); + Delivery (Session& s, boost::shared_ptr<MuteMaster> mm, const std::string& name, Role); + Delivery (Session&, boost::shared_ptr<MuteMaster> mm, const XMLNode&); + bool set_name (const std::string& name); bool visible() const; - Role role() const { return _role; } - bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const; bool configure_io (ChanCount in, ChanCount out); void run_in_place (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nframes_t nframes); - void set_metering (bool yn); - - bool muted_by_self() const { return _muted_by_self; } - bool muted_by_others() const { return _muted_by_others; } + /* supplemental method use with MIDI */ + + void flush (nframes_t nframes); + + void no_outs_cuz_we_no_monitor(bool); + + void mod_solo_level (int32_t); + uint32_t solo_level() const { return _solo_level; } + bool soloed () const { return (bool) _solo_level; } + + bool solo_isolated() const { return _solo_isolated; } + void set_solo_isolated (bool); + + void cycle_start (nframes_t); + void increment_output_offset (nframes_t); + void transport_stopped (sframes_t frame); + + BufferSet& output_buffers() { return *_output_buffers; } + + sigc::signal<void> MuteChange; - void set_self_mute (bool); - void set_nonself_mute (bool); - - sigc::signal<void> SelfMuteChange; - sigc::signal<void> OtherMuteChange; + static sigc::signal<void,nframes_t> CycleStart; XMLNode& state (bool full); int set_state (const XMLNode&); -private: - Role _role; - bool _metering; - bool _muted_by_self; - bool _muted_by_others; + /* Panning */ + + static int disable_panners (void); + static int reset_panners (void); + + boost::shared_ptr<Panner> panner() const { return _panner; } + + void reset_panner (); + void defer_pan_reset (); + void allow_pan_reset (); + + uint32_t pans_required() const { return _configured_input.n_audio(); } + void start_pan_touch (uint32_t which); + void end_pan_touch (uint32_t which); + + protected: + Role _role; + BufferSet* _output_buffers; + gain_t _current_gain; + nframes_t _output_offset; + bool _no_outs_cuz_we_no_monitor; + uint32_t _solo_level; + bool _solo_isolated; + boost::shared_ptr<MuteMaster> _mute_master; + bool no_panner_reset; + boost::shared_ptr<Panner> _panner; + + static bool panners_legal; + static sigc::signal<int> PannersLegal; + + int panners_became_legal (); + sigc::connection panner_legal_c; + void output_changed (IOChange, void*); + + gain_t target_gain (); }; diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h index 23e4f576df..3f222c6aa1 100644 --- a/libs/ardour/ardour/io.h +++ b/libs/ardour/ardour/io.h @@ -55,134 +55,83 @@ class AudioPort; class BufferSet; class Bundle; class MidiPort; -class Panner; class PeakMeter; class Port; +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 SessionObject, public AutomatableControls, public Latent +class IO : public SessionObject, public Latent { public: static const std::string state_node_name; - IO (Session&, const std::string& name, 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(); - bool active() const { return _active; } - void set_active (bool yn); - + Direction direction() const { return _direction; } + DataType default_type() const { return _default_type; } void set_default_type(DataType t) { _default_type = t; } + + bool active() const { return _active; } + void set_active(bool yn) { _active = yn; } bool set_name (const std::string& str); virtual void silence (nframes_t); - void collect_input (BufferSet& bufs, nframes_t nframes, ChanCount offset=ChanCount::ZERO); - void deliver_output (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nframes_t nframes); - void just_meter_input (sframes_t start_frame, sframes_t end_frame, nframes_t nframes); - - BufferSet& output_buffers() { return *_output_buffers; } - - gain_t gain () const { return _gain_control->user_float(); } - virtual gain_t effective_gain () const; - - void set_denormal_protection (bool yn, void *src); - bool denormal_protection() const { return _denormal_protection; } - - void set_phase_invert (bool yn, void *src); - bool phase_invert() const { return _phase_invert; } - - void reset_panner (); - - boost::shared_ptr<Amp> amp() const { return _amp; } - - PeakMeter& peak_meter() { return *_meter.get(); } - const PeakMeter& peak_meter() const { return *_meter.get(); } - boost::shared_ptr<PeakMeter> shared_peak_meter() const { return _meter; } - - boost::shared_ptr<Panner> panner() const { return _panner; } - - int ensure_io (ChanCount in, ChanCount out, bool clear, void *src); + int ensure_io (ChanCount cnt, bool clear, void *src); - int connect_input_ports_to_bundle (boost::shared_ptr<Bundle>, void *); - int disconnect_input_ports_from_bundle (boost::shared_ptr<Bundle>, void *); - int connect_output_ports_to_bundle (boost::shared_ptr<Bundle>, void *); - int disconnect_output_ports_from_bundle (boost::shared_ptr<Bundle>, void *); + int connect_ports_to_bundle (boost::shared_ptr<Bundle>, void *); + int disconnect_ports_from_bundle (boost::shared_ptr<Bundle>, void *); - BundleList bundles_connected_to_inputs (); - BundleList bundles_connected_to_outputs (); + BundleList bundles_connected (); - boost::shared_ptr<Bundle> bundle_for_inputs () { return _bundle_for_inputs; } - boost::shared_ptr<Bundle> bundle_for_outputs () { return _bundle_for_outputs; } + boost::shared_ptr<Bundle> bundle () { return _bundle; } - int add_input_port (std::string source, void *src, DataType type = DataType::NIL); - int add_output_port (std::string destination, void *src, DataType type = DataType::NIL); - - int remove_input_port (Port *, void *src); - int remove_output_port (Port *, void *src); - - int set_input (Port *, void *src); - - int connect_input (Port *our_port, std::string other_port, void *src); - int connect_output (Port *our_port, std::string other_port, void *src); - - int disconnect_input (Port *our_port, std::string other_port, void *src); - int disconnect_output (Port *our_port, std::string other_port, void *src); - - int disconnect_inputs (void *src); - int disconnect_outputs (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 IO>) const; nframes_t signal_latency() const { return _own_latency; } - nframes_t output_latency() const; - nframes_t input_latency() const; + nframes_t latency() const; void set_port_latency (nframes_t); void update_port_total_latencies (); - const PortSet& inputs() const { return _inputs; } - const PortSet& outputs() const { return _outputs; } + PortSet& ports() { return _ports; } + const PortSet& ports() const { return _ports; } - Port *output (uint32_t n) const { - if (n < _outputs.num_ports()) { - return _outputs.port(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 < _inputs.num_ports()) { - return _inputs.port(n); - } else { - return 0; - } - } + AudioPort* audio(uint32_t n) const; + MidiPort* midi(uint32_t n) const; - AudioPort* audio_input(uint32_t n) const; - AudioPort* audio_output(uint32_t n) const; - MidiPort* midi_input(uint32_t n) const; - MidiPort* midi_output(uint32_t n) const; + const ChanCount& n_ports () const { return _ports.count(); } - const ChanCount& n_inputs () const { return _inputs.count(); } - const ChanCount& n_outputs () const { return _outputs.count(); } - - void attach_buffers(ChanCount ignored); - - sigc::signal<void> active_changed; - - sigc::signal<void,IOChange,void*> input_changed; - sigc::signal<void,IOChange,void*> output_changed; + sigc::signal<void,IOChange,void*> changed; virtual XMLNode& state (bool full); XMLNode& get_state (void); @@ -192,130 +141,45 @@ class IO : public SessionObject, public AutomatableControls, public Latent 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<int> PortsLegal; - static sigc::signal<int> PannersLegal; - static sigc::signal<int> ConnectingLegal; - /// raised when the number of input or output ports changes - static sigc::signal<void,ChanCount> PortCountChanged; - static sigc::signal<void,nframes_t> CycleStart; - - static void update_meters(); + static sigc::signal<void,ChanCount> PortCountChanged; // emitted when the number of ports changes + static std::string name_from_state (const XMLNode&); static void set_name_in_state (XMLNode&, const std::string&); - private: - - static sigc::signal<void> Meter; - static Glib::StaticMutex m_meter_signal_lock; - sigc::connection m_meter_connection; - - public: - - /* automation */ - - struct GainControl : public AutomationControl { - GainControl (std::string name, IO* i, const Evoral::Parameter ¶m, - boost::shared_ptr<AutomationList> al = boost::shared_ptr<AutomationList>() ) - : AutomationControl (i->_session, param, al, name ) - , _io (i) - {} - - void set_value (float val); - float get_value (void) const; - - IO* _io; - }; + /* we have to defer/order port connection. this is how we do it. + */ - boost::shared_ptr<GainControl> gain_control() { - return _gain_control; - } - boost::shared_ptr<const GainControl> gain_control() const { - return _gain_control; - } + static sigc::signal<int> ConnectingLegal; + static bool connecting_legal; - void clear_automation (); + XMLNode *pending_state_node; - void set_parameter_automation_state (Evoral::Parameter, AutoState); + /* three utility functions - this just seems to be simplest place to put them */ - virtual void transport_stopped (nframes_t now); - virtual void automation_snapshot (nframes_t now, bool force); + void collect_input (BufferSet& bufs, nframes_t nframes, ChanCount offset); + void process_input (boost::shared_ptr<Processor>, 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); - void start_pan_touch (uint32_t which); - void end_pan_touch (uint32_t which); - - void defer_pan_reset (); - void allow_pan_reset (); + /* AudioTrack::deprecated_use_diskstream_connections() needs these */ - /* the session calls this for master outs before - anyone else. controls outs too, at some point. - */ - - XMLNode *pending_state_node; - int ports_became_legal (); + int set_ports (const std::string& str); private: mutable Glib::Mutex io_lock; protected: - BufferSet* _output_buffers; //< Set directly to output port buffers - bool _active; - gain_t _gain; - Glib::Mutex declick_lock; - PortSet _outputs; - PortSet _inputs; - bool no_panner_reset; - bool _phase_invert; - bool _denormal_protection; - XMLNode* deferred_state; - DataType _default_type; - nframes_t _output_offset; - - boost::shared_ptr<Amp> _amp; - boost::shared_ptr<PeakMeter> _meter; - boost::shared_ptr<Panner> _panner; - - virtual void prepare_inputs (nframes_t nframes); - virtual void flush_outputs (nframes_t nframes); - - virtual void set_deferred_state() {} - - virtual uint32_t pans_required() const - { return _inputs.count().n_audio(); } - - boost::shared_ptr<GainControl> _gain_control; - - virtual void set_gain (gain_t g, void *src); - void inc_gain (gain_t delta, void *src); - - virtual int load_automation (std::string path); - - /* AudioTrack::deprecated_use_diskstream_connections() needs these */ - - int set_inputs (const std::string& str); - int set_outputs (const std::string& str); - - void increment_output_offset (nframes_t); - void cycle_start (nframes_t); - - static bool connecting_legal; - static bool ports_legal; - + PortSet _ports; + Direction _direction; + DataType _default_type; + bool _active; + private: - static bool panners_legal; - - void copy_to_outputs (BufferSet& bufs, DataType type, nframes_t nframes); int connecting_became_legal (); - int panners_became_legal (); sigc::connection connection_legal_c; - sigc::connection port_legal_c; - sigc::connection panner_legal_c; - boost::shared_ptr<Bundle> _bundle_for_inputs; ///< a bundle representing our inputs - boost::shared_ptr<Bundle> _bundle_for_outputs; ///< a bundle representing our outputs + boost::shared_ptr<Bundle> _bundle; ///< a bundle representing our ports struct UserBundleInfo { UserBundleInfo (IO*, boost::shared_ptr<UserBundle> b); @@ -324,45 +188,31 @@ class IO : public SessionObject, public AutomatableControls, public Latent sigc::connection changed; }; - std::vector<UserBundleInfo> _bundles_connected_to_outputs; ///< user bundles connected to our outputs - std::vector<UserBundleInfo> _bundles_connected_to_inputs; ///< user bundles connected to our inputs + std::vector<UserBundleInfo> _bundles_connected; ///< user bundles connected to our ports static int parse_io_string (const std::string&, std::vector<std::string>& chns); - static int parse_gain_string (const std::string&, std::vector<std::string>& chns); - int set_sources (std::vector<std::string>&, void *src, bool add); - int set_destinations (std::vector<std::string>&, void *src, bool add); - - int ensure_inputs (ChanCount, bool clear, bool lockit, void *src); - int ensure_outputs (ChanCount, bool clear, bool lockit, void *src); + int ensure_ports (ChanCount, bool clear, bool lockit, void *src); - void check_bundles_connected_to_inputs (); - void check_bundles_connected_to_outputs (); + void check_bundles_connected (); void check_bundles (std::vector<UserBundleInfo>&, const PortSet&); void bundle_changed (Bundle::Change); - int get_port_counts (const XMLNode& node, ChanCount& in, ChanCount& out, - boost::shared_ptr<Bundle>& ic, boost::shared_ptr<Bundle>& oc); + int get_port_counts (const XMLNode& node, ChanCount& n, boost::shared_ptr<Bundle>& c); int create_ports (const XMLNode&); int make_connections (const XMLNode&); - boost::shared_ptr<Bundle> find_possible_bundle (const std::string &desired_name, const std::string &default_name, const std::string &connection_type_name); - virtual void setup_peak_meters (); - void meter (); + boost::shared_ptr<Bundle> find_possible_bundle (const std::string &desired_name); - bool ensure_inputs_locked (ChanCount, bool clear, void *src); - bool ensure_outputs_locked (ChanCount, bool clear, void *src); + bool ensure_ports_locked (ChanCount, bool clear, void *src); - std::string build_legal_port_name (DataType type, bool for_input); - int32_t find_input_port_hole (const char* base); - int32_t find_output_port_hole (const char* base); + std::string build_legal_port_name (DataType type); + int32_t find_port_hole (const char* base); - void setup_bundles_for_inputs_and_outputs (); - void setup_bundle_for_inputs (); - void setup_bundle_for_outputs (); + void setup_bundles (); std::string bundle_channel_name (uint32_t, uint32_t) const; }; diff --git a/libs/ardour/ardour/io_processor.h b/libs/ardour/ardour/io_processor.h index 896de52a3b..72be2c0743 100644 --- a/libs/ardour/ardour/io_processor.h +++ b/libs/ardour/ardour/io_processor.h @@ -38,15 +38,16 @@ namespace ARDOUR { class Session; class IO; -/** A mixer strip element (Processor) with Jack ports (IO). +/** A mixer strip element (Processor) with 1 or 2 IO elements. */ class IOProcessor : public Processor { public: - IOProcessor (Session&, const std::string& proc_name, const std::string io_name="", - ARDOUR::DataType default_type = DataType::AUDIO); - IOProcessor (Session&, IO* io, const std::string& proc_name, + IOProcessor (Session&, bool with_input, bool with_output, + const std::string& proc_name, const std::string io_name="", ARDOUR::DataType default_type = DataType::AUDIO); + IOProcessor (Session&, boost::shared_ptr<IO> input, boost::shared_ptr<IO> output, + const std::string& proc_name, ARDOUR::DataType default_type = DataType::AUDIO); virtual ~IOProcessor (); bool set_name (const std::string& str); @@ -56,13 +57,14 @@ class IOProcessor : public Processor virtual ChanCount natural_output_streams() const; virtual ChanCount natural_input_streams () const; - boost::shared_ptr<IO> io() { return _io; } - boost::shared_ptr<const IO> io() const { return _io; } - void set_io (boost::shared_ptr<IO>); + boost::shared_ptr<IO> input() { return _input; } + boost::shared_ptr<const IO> input() const { return _input; } + boost::shared_ptr<IO> output() { return _output; } + boost::shared_ptr<const IO> output() const { return _output; } + void set_input (boost::shared_ptr<IO>); + void set_output (boost::shared_ptr<IO>); - virtual void automation_snapshot (nframes_t now, bool force); - - virtual void run_in_place (BufferSet& in, sframes_t start, sframes_t end, nframes_t nframes) = 0; + void run_in_place (BufferSet& in, sframes_t start, sframes_t end, nframes_t nframes) = 0; void silence (nframes_t nframes); sigc::signal<void,IOProcessor*,bool> AutomationPlaybackChanged; @@ -72,12 +74,14 @@ class IOProcessor : public Processor int set_state (const XMLNode&); protected: - boost::shared_ptr<IO> _io; + boost::shared_ptr<IO> _input; + boost::shared_ptr<IO> _output; private: /* disallow copy construction */ IOProcessor (const IOProcessor&); - bool _own_io; + bool _own_input; + bool _own_output; }; diff --git a/libs/ardour/ardour/meter.h b/libs/ardour/ardour/meter.h index 250fb3111e..43df5e936c 100644 --- a/libs/ardour/ardour/meter.h +++ b/libs/ardour/ardour/meter.h @@ -20,6 +20,7 @@ #define __ardour_meter_h__ #include <vector> +#include <sigc++/slot.h> #include "ardour/types.h" #include "ardour/processor.h" #include "pbd/fastlog.h" @@ -30,6 +31,20 @@ class BufferSet; class ChanCount; class Session; +class Metering { + public: + static void update_meters (); + static sigc::signal<void> Meter; + + static sigc::connection connect (sigc::slot<void> the_slot); + static void disconnect (sigc::connection& c); + + private: + /* this object is not meant to be instantiated */ + virtual void foo() = 0; + + static Glib::StaticMutex m_meter_signal_lock; +}; /** Meters peaks on the input and stores them for access. */ @@ -37,6 +52,8 @@ class PeakMeter : public Processor { public: PeakMeter(Session& s) : Processor(s, "Meter") {} + void meter(); + void reset (); void reset_max (); @@ -66,7 +83,6 @@ public: private: friend class IO; - void meter(); std::vector<float> _peak_power; std::vector<float> _visible_peak_power; diff --git a/libs/ardour/ardour/mute_master.h b/libs/ardour/ardour/mute_master.h new file mode 100644 index 0000000000..d55de0c856 --- /dev/null +++ b/libs/ardour/ardour/mute_master.h @@ -0,0 +1,77 @@ +/* + Copyright (C) 2009 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef __ardour_mute_master_h__ +#define __ardour_mute_master_h__ + +#include "evoral/Parameter.hpp" +#include "ardour/automation_control.h" +#include "ardour/automation_list.h" + +namespace ARDOUR { + +class Session; + +class MuteMaster : public AutomationControl +{ + public: + enum MutePoint { + PreFader = 0x1, + PostFader = 0x2, + Listen = 0x4, + Main = 0x8 + }; + + MuteMaster (Session& s, const std::string& name); + ~MuteMaster() {} + + bool muted_pre_fader() const { return _mute_point & PreFader; } + bool muted_post_fader() const { return _mute_point & PostFader; } + bool muted_listen() const { return _mute_point & Listen; } + bool muted_main () const { return _mute_point & Main; } + + bool muted_at (MutePoint mp) const { return _mute_point & mp; } + bool muted() const { return _mute_point != MutePoint (0) && get_value() != 0.0; } + + gain_t mute_gain_at (MutePoint) const; + + void clear_mute (); + void mute_at (MutePoint); + void unmute_at (MutePoint); + + void mute (bool yn); + + /* Controllable interface */ + + void set_value (float); /* note: float is used as a bitfield of MutePoints */ + float get_value () const; + + sigc::signal<void> MutePointChanged; + + XMLNode& get_state(); + int set_state(const XMLNode& node); + + private: + AutomationList* _automation; + MutePoint _mute_point; +}; + +} // namespace ARDOUR + +#endif /*__ardour_mute_master_h__ */ diff --git a/libs/ardour/ardour/panner.h b/libs/ardour/ardour/panner.h index 9bc1817af0..3c66046ad1 100644 --- a/libs/ardour/ardour/panner.h +++ b/libs/ardour/ardour/panner.h @@ -183,7 +183,7 @@ class Multi2dPanner : public StreamPanner }; -class Panner : public Processor +class Panner : public SessionObject, public AutomatableControls { public: struct Output { @@ -204,18 +204,16 @@ class Panner : public Processor void clear_panners (); bool empty() const { return _streampanners.empty(); } - /// The fundamental Panner function void set_automation_state (AutoState); AutoState automation_state() const; void set_automation_style (AutoStyle); AutoStyle automation_style() const; bool touching() const; - bool is_in_place () const { return false; } - bool is_out_of_place () const { return true; } bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const { return true; }; - void run_out_of_place(BufferSet& src, BufferSet& dest, sframes_t start_frame, sframes_t end_frames, nframes_t nframes); + /// The fundamental Panner function + void run (BufferSet& src, BufferSet& dest, sframes_t start_frame, sframes_t end_frames, nframes_t nframes); //void* get_inline_gui() const = 0; //void* get_full_gui() const = 0; diff --git a/libs/ardour/ardour/port_insert.h b/libs/ardour/ardour/port_insert.h index 56aa43c6c5..fa9c31efe6 100644 --- a/libs/ardour/ardour/port_insert.h +++ b/libs/ardour/ardour/port_insert.h @@ -34,25 +34,28 @@ class XMLNode; namespace ARDOUR { class Session; +class IO; +class Delivery; +class MuteMaster; /** Port inserts: send output to a Jack port, pick up input at a Jack port */ class PortInsert : public IOProcessor { public: - PortInsert (Session&); - PortInsert (Session&, const XMLNode&); + PortInsert (Session&, boost::shared_ptr<MuteMaster> mm); + PortInsert (Session&, boost::shared_ptr<MuteMaster> mm, const XMLNode&); ~PortInsert (); XMLNode& state(bool full); XMLNode& get_state(void); int set_state(const XMLNode&); - void init (); - void run_in_place (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nframes_t nframes); nframes_t signal_latency() const; + + bool set_name (const std::string& name); bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const; bool configure_io (ChanCount in, ChanCount out); @@ -62,6 +65,8 @@ class PortInsert : public IOProcessor private: /* disallow copy construction */ PortInsert (const PortInsert&); + + boost::shared_ptr<Delivery> _out; uint32_t bitslot; }; diff --git a/libs/ardour/ardour/processor.h b/libs/ardour/ardour/processor.h index 73a93b31d9..61a266e9c5 100644 --- a/libs/ardour/ardour/processor.h +++ b/libs/ardour/ardour/processor.h @@ -53,24 +53,26 @@ class Processor : public SessionObject, public AutomatableControls, public Laten virtual ~Processor() { } - /** Configuration of a processor on a bus - * (i.e. how to apply to a BufferSet) - */ - struct Mapping { - ChanCount in; - ChanCount out; - }; - virtual bool visible() const { return true; } bool active () const { return _active; } + + /* we keep loose tabs on the "placement" of a Processor. Ultimately, + they are all executed as a single list, but there are some + semantics that require knowing whether a Processor is before + or after the fader, or panner etc. See Route::reorder_processors() + to see where this gets set. + */ + + Placement placement() const { return _placement; } + void set_placement (Placement p) { _placement = p; } bool get_next_ab_is_active () const { return _next_ab_is_active; } void set_next_ab_is_active (bool yn) { _next_ab_is_active = yn; } virtual nframes_t signal_latency() const { return 0; } - virtual void transport_stopped (nframes_t frame) {} + virtual void transport_stopped (sframes_t frame) {} virtual void set_block_size (nframes_t nframes) {} @@ -127,7 +129,7 @@ protected: ChanCount _configured_input; ChanCount _configured_output; void* _gui; /* generic, we don't know or care what this is */ - Mapping _mapping; + Placement _placement; }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/rc_configuration_vars.h b/libs/ardour/ardour/rc_configuration_vars.h index 99ac902629..1a4c49fe64 100644 --- a/libs/ardour/ardour/rc_configuration_vars.h +++ b/libs/ardour/ardour/rc_configuration_vars.h @@ -84,6 +84,7 @@ CONFIG_VARIABLE (bool, all_safe, "all-safe", false) CONFIG_VARIABLE (bool, show_solo_mutes, "show-solo-mutes", false) CONFIG_VARIABLE (bool, solo_mute_override, "solo-mute-override", false) CONFIG_VARIABLE (bool, tape_machine_mode, "tape-machine-mode", false) +CONFIG_VARIABLE (gain_t, solo_mute_gain, "solo_mute-gain", 0.0) /* click */ diff --git a/libs/ardour/ardour/return.h b/libs/ardour/ardour/return.h index 2b6cd0b69e..5c2a82e3aa 100644 --- a/libs/ardour/ardour/return.h +++ b/libs/ardour/ardour/return.h @@ -32,6 +32,9 @@ namespace ARDOUR { +class Amp; +class PeakMeter; + class Return : public IOProcessor { public: @@ -43,9 +46,12 @@ public: void run_in_place (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nframes_t nframes); - void activate() {} - void deactivate () {} + boost::shared_ptr<Amp> amp() const { return _amp; } + boost::shared_ptr<PeakMeter> meter() const { return _meter; } + bool metering() const { return _metering; } + void set_metering (bool yn) { _metering = yn; } + XMLNode& state(bool full); XMLNode& get_state(void); int set_state(const XMLNode& node); @@ -55,14 +61,22 @@ public: bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const; bool configure_io (ChanCount in, ChanCount out); - static uint32_t how_many_sends(); + static uint32_t how_many_returns(); static void make_unique (XMLNode &, Session &); + protected: + bool _metering; + boost::shared_ptr<Amp> _amp; + boost::shared_ptr<PeakMeter> _meter; + private: /* disallow copy construction */ Return (const Return&); uint32_t _bitslot; + + void collect_input (BufferSet& bufs, nframes_t nframes, ChanCount offset=ChanCount::ZERO); + void just_meter_input (sframes_t start_frame, sframes_t end_frame, nframes_t nframes); }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index 8de82bb219..a2ad716592 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -41,24 +41,19 @@ #include "ardour/ardour.h" #include "ardour/io.h" #include "ardour/types.h" +#include "ardour/mute_master.h" namespace ARDOUR { class Amp; class Delivery; class IOProcessor; +class Panner; class Processor; class RouteGroup; class Send; -enum mute_type { - PRE_FADER = 0x1, - POST_FADER = 0x2, - CONTROL_OUTS = 0x4, - MAIN_OUTS = 0x8 -}; - -class Route : public IO +class Route : public SessionObject, public AutomatableControls { public: @@ -75,6 +70,16 @@ class Route : public IO Route (Session&, const XMLNode&, DataType default_type = DataType::AUDIO); virtual ~Route(); + boost::shared_ptr<IO> input() const { return _input; } + boost::shared_ptr<IO> output() const { return _output; } + + ChanCount n_inputs() const { return _input->n_ports(); } + ChanCount n_outputs() const { return _output->n_ports(); } + + bool active() const { return _active; } + void set_active (bool yn); + + static std::string ensure_track_or_route_name(std::string, Session &); std::string comment() { return _comment; } @@ -102,6 +107,7 @@ class Route : public IO 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_processors); @@ -110,38 +116,44 @@ class Route : public IO /* 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); - + + void set_mute (bool yn, void* src); + bool muted () const; + void set_solo (bool yn, void *src); - bool soloed() const { return _soloed; } + bool soloed() const; - void set_solo_safe (bool yn, void *src); - bool solo_safe() const { return _solo_safe; } + void set_solo_isolated (bool yn, void *src); + bool solo_isolated() const; - void set_mute (bool yn, void *src); - bool muted() const { return _muted; } - bool solo_muted() const { return desired_solo_gain == 0.0; } + void set_phase_invert (bool yn, void* src); + bool phase_invert() const; - void set_mute_config (mute_type, bool, void *src); - bool get_mute_config (mute_type); + void set_denormal_protection (bool yn, void* src); + bool denormal_protection() const; void set_edit_group (RouteGroup *, void *); void drop_edit_group (void *); - RouteGroup *edit_group () { return _edit_group; } + RouteGroup *edit_group () const { return _edit_group; } void set_mix_group (RouteGroup *, void *); void drop_mix_group (void *); - RouteGroup *mix_group () { return _mix_group; } + RouteGroup *mix_group () const { return _mix_group; } virtual void set_meter_point (MeterPoint, void *src); MeterPoint meter_point() const { return _meter_point; } + void meter (); /* Processors */ + boost::shared_ptr<Amp> amp() const { return _amp; } + PeakMeter& peak_meter() { return *_meter.get(); } + const PeakMeter& peak_meter() const { return *_meter.get(); } + boost::shared_ptr<PeakMeter> shared_peak_meter() const { return _meter; } + void flush_processors (); void foreach_processor (sigc::slot<void, boost::weak_ptr<Processor> > method) { @@ -180,7 +192,7 @@ class Route : public IO boost::shared_ptr<Delivery> control_outs() const { return _control_outs; } boost::shared_ptr<Delivery> main_outs() const { return _main_outs; } - + boost::shared_ptr<Send> send_for (boost::shared_ptr<const IO> target) const; /** A record of the stream configuration at some point in the processor list. @@ -213,8 +225,10 @@ class Route : public IO void set_user_latency (nframes_t); nframes_t initial_delay() const { return _initial_delay; } + sigc::signal<void> active_changed; sigc::signal<void,void*> solo_changed; sigc::signal<void,void*> solo_safe_changed; + sigc::signal<void,void*> solo_isolated_changed; sigc::signal<void,void*> comment_changed; sigc::signal<void,void*> mute_changed; sigc::signal<void,void*> pre_fader_changed; @@ -240,8 +254,8 @@ class Route : public IO virtual XMLNode& get_template(); XMLNode& get_processor_state (); - int set_processor_state (const XMLNode&); - + virtual void set_processor_state (const XMLNode&); + int save_as_template (const std::string& path, const std::string& name); sigc::signal<void,void*> SelectedChanged; @@ -252,28 +266,38 @@ class Route : public IO bool feeds (boost::shared_ptr<IO>); std::set<boost::shared_ptr<Route> > fed_by; - struct ToggleControllable : public PBD::Controllable { - enum ToggleType { - MuteControl = 0, - SoloControl - }; - - ToggleControllable (std::string name, Route&, ToggleType); - void set_value (float); - float get_value (void) const; - - Route& route; - ToggleType type; + /* Controls (not all directly owned by the Route */ + + boost::shared_ptr<AutomationControl> get_control (const Evoral::Parameter& param); + + struct SoloControllable : public AutomationControl { + SoloControllable (std::string name, Route&); + void set_value (float); + float get_value (void) const; + + Route& route; }; - boost::shared_ptr<PBD::Controllable> solo_control() { + boost::shared_ptr<AutomationControl> solo_control() const { return _solo_control; } - boost::shared_ptr<PBD::Controllable> mute_control() { - return _mute_control; + boost::shared_ptr<AutomationControl> mute_control() const { + return _mute_master; } - + + boost::shared_ptr<MuteMaster> mute_master() const { + return _mute_master; + } + + /* Route doesn't own these items, but sub-objects that it does own have them + and to make UI code a bit simpler, we provide direct access to them + here. + */ + + boost::shared_ptr<Panner> panner() const; + boost::shared_ptr<AutomationControl> gain_control() const; + void automation_snapshot (nframes_t now, bool force=false); void protect_automation (); @@ -288,10 +312,11 @@ class Route : public IO friend class Session; void catch_up_on_solo_mute_override (); - void set_solo_mute (bool yn); + void mod_solo_level (int32_t); void set_block_size (nframes_t nframes); bool has_external_redirects() const; void curve_reallocate (); + void just_meter_input (sframes_t start_frame, sframes_t end_frame, nframes_t nframes); protected: nframes_t check_initial_delay (nframes_t, nframes_t&); @@ -303,44 +328,38 @@ class Route : public IO sframes_t start_frame, sframes_t end_frame, nframes_t nframes, bool with_processors, int declick); - Flag _flags; - int _pending_declick; - MeterPoint _meter_point; + boost::shared_ptr<IO> _input; + boost::shared_ptr<IO> _output; - gain_t solo_gain; - gain_t mute_gain; - gain_t desired_solo_gain; - gain_t desired_mute_gain; - + bool _active; nframes_t _initial_delay; nframes_t _roll_delay; + ProcessorList _processors; mutable Glib::RWLock _processor_lock; boost::shared_ptr<Delivery> _main_outs; boost::shared_ptr<Delivery> _control_outs; // XXX to be removed/generalized by listen points - RouteGroup *_edit_group; - RouteGroup *_mix_group; - std::string _comment; - bool _have_internal_generator; - - boost::shared_ptr<ToggleControllable> _solo_control; - boost::shared_ptr<ToggleControllable> _mute_control; - - /* tight cache-line access here is more important than sheer speed of access. - keep these after things that should be aligned - */ - bool _muted : 1; - bool _soloed : 1; - bool _solo_safe : 1; + Flag _flags; + int _pending_declick; + MeterPoint _meter_point; + uint32_t _phase_invert; + bool _denormal_protection; + 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; + boost::shared_ptr<SoloControllable> _solo_control; + boost::shared_ptr<MuteMaster> _mute_master; + + RouteGroup* _edit_group; + RouteGroup* _mix_group; + std::string _comment; + bool _have_internal_generator; + bool _solo_safe; + DataType _default_type; + protected: virtual XMLNode& state(bool); @@ -358,13 +377,14 @@ class Route : public IO uint32_t pans_required() const; ChanCount n_process_buffers (); - void setup_peak_meters (); - virtual int _set_state (const XMLNode&, bool call_base); - virtual void _set_processor_states (const XMLNodeList&); boost::shared_ptr<Delivery> add_listener (boost::shared_ptr<IO>, const std::string&); + boost::shared_ptr<Amp> _amp; + boost::shared_ptr<PeakMeter> _meter; + sigc::connection _meter_connection; + private: void init (); @@ -386,8 +406,7 @@ class Route : public IO int configure_processors (ProcessorStreams*); int configure_processors_unlocked (ProcessorStreams*); - - void set_deferred_state (); + bool add_processor_from_xml (const XMLNode&, Placement); bool add_processor_from_xml (const XMLNode&, ProcessorList::iterator iter); diff --git a/libs/ardour/ardour/send.h b/libs/ardour/ardour/send.h index b47263b547..302f512c9c 100644 --- a/libs/ardour/ardour/send.h +++ b/libs/ardour/ardour/send.h @@ -23,40 +23,52 @@ #include <sigc++/signal.h> #include <string> - #include "pbd/stateful.h" + #include "ardour/ardour.h" #include "ardour/audioengine.h" #include "ardour/delivery.h" namespace ARDOUR { +class PeakMeter; +class Amp; + class Send : public Delivery { public: - Send (Session&); - Send (Session&, const XMLNode&); + Send (Session&, boost::shared_ptr<MuteMaster>); + Send (Session&, boost::shared_ptr<MuteMaster>, const XMLNode&); virtual ~Send (); uint32_t bit_slot() const { return _bitslot; } - - void activate() {} - void deactivate () {} + boost::shared_ptr<Amp> amp() const { return _amp; } + boost::shared_ptr<PeakMeter> meter() const { return _meter; } + + bool metering() const { return _metering; } + void set_metering (bool yn) { _metering = yn; } + XMLNode& state(bool full); XMLNode& get_state(void); int set_state(const XMLNode& node); uint32_t pans_required() const { return _configured_input.n_audio(); } + void run_in_place (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nframes_t nframes); + bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const; - bool configure_io (ChanCount in, ChanCount out); bool set_name (const std::string& str); static uint32_t how_many_sends(); static void make_unique (XMLNode &, Session &); + protected: + bool _metering; + boost::shared_ptr<Amp> _amp; + boost::shared_ptr<PeakMeter> _meter; + private: /* disallow copy construction */ Send (const Send&); diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 3d85c8d200..d476a958d8 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -730,8 +730,8 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable /* session-wide solo/mute/rec-enable */ - bool soloing() const { return currently_soloing; } - + bool soloing() const { return _non_soloed_outs_muted; } + void set_all_solo (bool); void set_all_mute (bool); @@ -743,8 +743,8 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable /* control/master out */ - boost::shared_ptr<IO> control_out() const { return _control_out; } - boost::shared_ptr<IO> master_out() const { return _master_out; } + boost::shared_ptr<Route> control_out() const { return _control_out; } + boost::shared_ptr<Route> master_out() const { return _master_out; } /* insert/send management */ @@ -1040,6 +1040,7 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable bool _have_captured; float _meter_hold; float _meter_falloff; + bool _non_soloed_outs_muted; void set_worst_io_latencies (); void set_worst_io_latencies_x (IOChange asifwecare, void *ignored) { @@ -1688,8 +1689,8 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable /* main outs */ uint32_t main_outs; - boost::shared_ptr<IO> _master_out; - boost::shared_ptr<IO> _control_out; + boost::shared_ptr<Route> _master_out; + boost::shared_ptr<Route> _control_out; gain_t* _gain_automation_buffer; pan_t** _pan_automation_buffer; |