X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fardour%2Fpanner.h;h=da68ed8578a8836b371a3e4eabfc85f20c44354e;hb=2a6dcddcc513fa3ebc1aad4b2e5fede62277aba5;hp=fb8048e7ef9f8b0731338d566dc5f593bdd65388;hpb=e14187aadd574d46c82d8eb0d151b526b84ddcc7;p=ardour.git diff --git a/libs/ardour/ardour/panner.h b/libs/ardour/ardour/panner.h index fb8048e7ef..da68ed8578 100644 --- a/libs/ardour/ardour/panner.h +++ b/libs/ardour/ardour/panner.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2004 Paul Davis + Copyright (C) 2004 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 @@ -25,16 +25,13 @@ #include #include #include -#include -#include -#include +#include "pbd/stateful.h" +#include "pbd/controllable.h" -#include -#include - -using std::istream; -using std::ostream; +#include "ardour/types.h" +#include "ardour/automation_control.h" +#include "ardour/processor.h" namespace ARDOUR { @@ -43,10 +40,10 @@ class Panner; class BufferSet; class AudioBuffer; -class StreamPanner : public sigc::trackable, public PBD::Stateful +class StreamPanner : public PBD::Stateful { public: - StreamPanner (Panner& p, Parameter param); + StreamPanner (Panner& p, Evoral::Parameter param); ~StreamPanner (); void set_muted (bool yn); @@ -56,42 +53,54 @@ class StreamPanner : public sigc::trackable, public PBD::Stateful void set_position (float x, float y, bool link_call = false); void set_position (float x, float y, float z, bool link_call = false); - void get_position (float& xpos) const { xpos = x; } - void get_position (float& xpos, float& ypos) const { xpos = x; ypos = y; } - void get_position (float& xpos, float& ypos, float& zpos) const { xpos = x; ypos = y; zpos = z; } + void get_position (float& xpos) const { xpos = _x; } + void get_position (float& xpos, float& ypos) const { xpos = _x; ypos = _y; } + void get_position (float& xpos, float& ypos, float& zpos) const { xpos = _x; ypos = _y; zpos = _z; } void get_effective_position (float& xpos) const { xpos = effective_x; } void get_effective_position (float& xpos, float& ypos) const { xpos = effective_x; ypos = effective_y; } void get_effective_position (float& xpos, float& ypos, float& zpos) const { xpos = effective_x; ypos = effective_y; zpos = effective_z; } + void distribute (AudioBuffer &, BufferSet &, gain_t, nframes_t); + void distribute_automated (AudioBuffer &, BufferSet &, nframes_t, nframes_t, nframes_t, pan_t **); + /* the basic StreamPanner API */ - virtual void distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, nframes_t nframes) = 0; - virtual void distribute_automated (AudioBuffer& src, BufferSet& obufs, - nframes_t start, nframes_t end, nframes_t nframes, pan_t** buffers) = 0; + /** + * Pan some input samples to a number of output buffers. + * + * @param src Input buffer. + * @param obufs Output buffers (one per panner output). + * @param gain_coeff Gain coefficient to apply to output samples. + * @param nframes Number of frames in the input. + */ + virtual void do_distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, nframes_t nframes) = 0; + virtual void do_distribute_automated (AudioBuffer& src, BufferSet& obufs, + nframes_t start, nframes_t end, nframes_t nframes, pan_t** buffers) = 0; boost::shared_ptr pan_control() { return _control; } - - sigc::signal Changed; /* for position */ - sigc::signal StateChanged; /* for mute */ - int set_state (const XMLNode&); + PBD::Signal0 Changed; /* for position */ + PBD::Signal0 StateChanged; /* for mute, mono */ + + int set_state (const XMLNode&, int version); virtual XMLNode& state (bool full_state) = 0; - + Panner & get_parent() { return parent; } /* old school automation loading */ - - virtual int load (istream&, string path, uint32_t&) = 0; + virtual int load (std::istream&, std::string path, uint32_t&) = 0; protected: friend class Panner; Panner& parent; - float x; - float y; - float z; + void set_mono (bool); + float _x; + float _y; + float _z; + /* these are for automation. they store the last value used by the most recent process() cycle. */ @@ -101,45 +110,33 @@ class StreamPanner : public sigc::trackable, public PBD::Stateful float effective_z; bool _muted; + bool _mono; - struct PanControllable : public AutomationControl { - PanControllable (Session& s, std::string name, StreamPanner& p, Parameter param) - : AutomationControl (s, param, - boost::shared_ptr(new AutomationList(param)), name) - , panner (p) - { assert(param.type() != NullAutomation); } - - AutomationList* alist() { return (AutomationList*)_list.get(); } - StreamPanner& panner; - - void set_value (float); - float get_value (void) const; - bool can_send_feedback() const; - }; - - boost::shared_ptr _control; + boost::shared_ptr _control; void add_state (XMLNode&); + + /* Update internal parameters based on _x, _y and _z */ virtual void update () = 0; }; class BaseStereoPanner : public StreamPanner { public: - BaseStereoPanner (Panner&, Parameter param); + BaseStereoPanner (Panner&, Evoral::Parameter param); ~BaseStereoPanner (); /* this class just leaves the pan law itself to be defined - by the update(), distribute_automated() + by the update(), do_distribute_automated() methods. derived classes also need a factory method and a type name. See EqualPowerStereoPanner as an example. */ - void distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, nframes_t nframes); + void do_distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, nframes_t nframes); /* old school automation loading */ - int load (istream&, string path, uint32_t&); + int load (std::istream&, std::string path, uint32_t&); protected: float left; @@ -153,21 +150,21 @@ class BaseStereoPanner : public StreamPanner class EqualPowerStereoPanner : public BaseStereoPanner { public: - EqualPowerStereoPanner (Panner&, Parameter param); + EqualPowerStereoPanner (Panner&, Evoral::Parameter param); ~EqualPowerStereoPanner (); - void distribute_automated (AudioBuffer& src, BufferSet& obufs, - nframes_t start, nframes_t end, nframes_t nframes, pan_t** buffers); + void do_distribute_automated (AudioBuffer& src, BufferSet& obufs, + nframes_t start, nframes_t end, nframes_t nframes, pan_t** buffers); void get_current_coefficients (pan_t*) const; void get_desired_coefficients (pan_t*) const; - static StreamPanner* factory (Panner&, Parameter param); - static string name; + static StreamPanner* factory (Panner&, Evoral::Parameter param); + static std::string name; XMLNode& state (bool full_state); XMLNode& get_state (void); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version); private: void update (); @@ -176,73 +173,79 @@ class EqualPowerStereoPanner : public BaseStereoPanner class Multi2dPanner : public StreamPanner { public: - Multi2dPanner (Panner& parent, Parameter); + Multi2dPanner (Panner& parent, Evoral::Parameter); ~Multi2dPanner (); - void distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, nframes_t nframes); - void distribute_automated (AudioBuffer& src, BufferSet& obufs, - nframes_t start, nframes_t end, nframes_t nframes, pan_t** buffers); + void do_distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, nframes_t nframes); + void do_distribute_automated (AudioBuffer& src, BufferSet& obufs, + nframes_t start, nframes_t end, nframes_t nframes, pan_t** buffers); - static StreamPanner* factory (Panner&, Parameter); - static string name; + static StreamPanner* factory (Panner&, Evoral::Parameter); + static std::string name; - XMLNode& state (bool full_state); + XMLNode& state (bool full_state); XMLNode& get_state (void); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version); /* old school automation loading */ - int load (istream&, string path, uint32_t&); + int load (std::istream&, std::string path, uint32_t&); private: void update (); }; -class Panner : public std::vector, public PBD::Stateful, public sigc::trackable + +/** Class to pan from some number of inputs to some number of outputs. + * This class has a number of StreamPanners, one for each input. + */ +class Panner : public SessionObject, public Automatable { - public: +public: struct Output { - float x; - float y; - pan_t current_pan; - pan_t desired_pan; - - Output (float xp, float yp) - : x (xp), y (yp), current_pan (0.0f), desired_pan (0.f) {} - + float x; + float y; + float z; + pan_t current_pan; + pan_t desired_pan; + + Output (float xp, float yp, float zp = 0.0) + : x (xp), y (yp), z (zp), current_pan (0), desired_pan (0) {} + }; - Panner (string name, Session&); + Panner (std::string name, Session&); virtual ~Panner (); + void clear_panners (); + bool empty() const { return _streampanners.empty(); } + + void set_automation_state (AutoState); + AutoState automation_state() const; + void set_automation_style (AutoStyle); + AutoStyle automation_style() const; + bool touching() const; + + bool can_support_io_configuration (const ChanCount& /*in*/, ChanCount& /*out*/) const { return true; }; + /// The fundamental Panner function - void distribute(BufferSet& src, BufferSet& dest, nframes_t start_frame, nframes_t end_frames, nframes_t nframes, nframes_t offset); + void run (BufferSet& src, BufferSet& dest, framepos_t start_frame, framepos_t end_frames, nframes_t nframes); bool bypassed() const { return _bypassed; } void set_bypassed (bool yn); + bool mono () const { return _mono; } + void set_mono (bool); StreamPanner* add (); void remove (uint32_t which); - void clear (); void reset (uint32_t noutputs, uint32_t npans); - - void snapshot (nframes_t now); - void transport_stopped (nframes_t frame); - - void clear_automation (); - - void set_automation_state (AutoState); - AutoState automation_state() const; - void set_automation_style (AutoStyle); - AutoStyle automation_style() const; - bool touching() const; + void reset_streampanner (uint32_t which_panner); + void reset_to_default (); XMLNode& get_state (void); XMLNode& state (bool full); - int set_state (const XMLNode&); + int set_state (const XMLNode&, int version); - sigc::signal Changed; - static bool equivalent (pan_t a, pan_t b) { return fabsf (a - b) < 0.002; // about 1 degree of arc for a stereo panner } @@ -251,9 +254,6 @@ class Panner : public std::vector, public PBD::Stateful, public s uint32_t nouts() const { return outputs.size(); } Output& output (uint32_t n) { return outputs[n]; } - std::vector outputs; - Session& session() const { return _session; } - enum LinkDirection { SameDirection, OppositeDirection @@ -261,15 +261,19 @@ class Panner : public std::vector, public PBD::Stateful, public s LinkDirection link_direction() const { return _link_direction; } void set_link_direction (LinkDirection); - + bool linked() const { return _linked; } void set_linked (bool yn); - sigc::signal LinkStateChanged; - sigc::signal StateChanged; /* for bypass */ + StreamPanner &streampanner( uint32_t n ) const { assert( n < _streampanners.size() ); return *_streampanners[n]; } + uint32_t npanners() const { return _streampanners.size(); } + + PBD::Signal0 Changed; /* panner and/or outputs count changed */ + PBD::Signal0 LinkStateChanged; + PBD::Signal0 StateChanged; /* for bypass */ /* only StreamPanner should call these */ - + void set_position (float x, StreamPanner& orig); void set_position (float x, float y, StreamPanner& orig); void set_position (float x, float y, float z, StreamPanner& orig); @@ -278,21 +282,50 @@ class Panner : public std::vector, public PBD::Stateful, public s int load (); + struct PanControllable : public AutomationControl { + PanControllable (Session& s, std::string name, Panner& p, Evoral::Parameter param) + : AutomationControl (s, param, + boost::shared_ptr(new AutomationList(param)), name) + , panner (p) + { assert(param.type() != NullAutomation); } + + AutomationList* alist() { return (AutomationList*)_list.get(); } + Panner& panner; + + void set_value (double); + double get_value (void) const; + }; + + boost::shared_ptr pan_control (int id, int chan=0) { + return automation_control (Evoral::Parameter (PanAutomation, chan, id)); + } + + boost::shared_ptr pan_control (int id, int chan=0) const { + return automation_control (Evoral::Parameter (PanAutomation, chan, id)); + } + + static std::string value_as_string (double); + private: - void distribute_no_automation(BufferSet& src, BufferSet& dest, nframes_t nframes, nframes_t offset, gain_t gain_coeff); + /* disallow copy construction */ + Panner (Panner const &); - Session& _session; + void distribute_no_automation(BufferSet& src, BufferSet& dest, nframes_t nframes, gain_t gain_coeff); + std::vector _streampanners; ///< one StreamPanner per input + std::vector outputs; uint32_t current_outs; bool _linked; bool _bypassed; + bool _mono; LinkDirection _link_direction; static float current_automation_version_number; + void setup_speakers (uint32_t nouts); + /* old school automation handling */ std::string automation_path; - void set_name (std::string); }; } // namespace ARDOUR