X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fardour%2Fpanner.h;h=087471032d12acb2722ad3fe6a82718253c6950f;hb=ba0458cf1f6c69366e89631d8fff916ad183d768;hp=34b99e63bfee9545719767d56e4d25f98049b591;hpb=aaa91db6d9592684258267981e619b44cc2b7c40;p=ardour.git diff --git a/libs/ardour/ardour/panner.h b/libs/ardour/ardour/panner.h index 34b99e63bf..087471032d 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,27 +25,22 @@ #include #include #include -#include -#include -#include +#include "pbd/stateful.h" +#include "pbd/controllable.h" -#include -#include -#include - -using std::istream; -using std::ostream; +#include "ardour/types.h" +#include "ardour/automation_control.h" +#include "ardour/processor.h" namespace ARDOUR { -class Route; class Session; class Panner; class BufferSet; class AudioBuffer; -class StreamPanner : public sigc::trackable, public PBD::Stateful +class StreamPanner : public PBD::Stateful { public: StreamPanner (Panner& p, Evoral::Parameter param); @@ -58,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. */ @@ -103,10 +110,13 @@ class StreamPanner : public sigc::trackable, public PBD::Stateful float effective_z; bool _muted; + bool _mono; boost::shared_ptr _control; void add_state (XMLNode&); + + /* Update internal parameters based on _x, _y and _z */ virtual void update () = 0; }; @@ -117,16 +127,16 @@ class BaseStereoPanner : public StreamPanner ~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; @@ -143,18 +153,18 @@ class EqualPowerStereoPanner : public BaseStereoPanner 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&, Evoral::Parameter param); - static string name; + 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 (); @@ -166,76 +176,74 @@ class Multi2dPanner : public StreamPanner 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&, Evoral::Parameter); - static string name; + 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 Processor +/** 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; + pan_t current_pan; + pan_t desired_pan; + + Output (float xp, float yp) + : x (xp), y (yp), current_pan (0), desired_pan (0) {} + }; - //Panner (std::string name, Session&, int _num_bufs); - Panner (string name, Session&); + Panner (std::string name, Session&); virtual ~Panner (); 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, nframes_t start_frame, nframes_t end_frames, nframes_t nframes, nframes_t offset); + bool can_support_io_configuration (const ChanCount& /*in*/, ChanCount& /*out*/) const { return true; }; - //void* get_inline_gui() const = 0; - //void* get_full_gui() const = 0; + /// The fundamental Panner function + 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 reset (uint32_t noutputs, uint32_t npans); - - - + 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); static bool equivalent (pan_t a, pan_t b) { return fabsf (a - b) < 0.002; // about 1 degree of arc for a stereo panner @@ -245,8 +253,6 @@ class Panner : public Processor uint32_t nouts() const { return outputs.size(); } Output& output (uint32_t n) { return outputs[n]; } - std::vector outputs; - enum LinkDirection { SameDirection, OppositeDirection @@ -254,19 +260,19 @@ class Panner : public Processor LinkDirection link_direction() const { return _link_direction; } void set_link_direction (LinkDirection); - + bool linked() const { return _linked; } void set_linked (bool yn); StreamPanner &streampanner( uint32_t n ) const { assert( n < _streampanners.size() ); return *_streampanners[n]; } uint32_t npanners() const { return _streampanners.size(); } - sigc::signal Changed; - sigc::signal LinkStateChanged; - sigc::signal StateChanged; /* for bypass */ + 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); @@ -276,33 +282,40 @@ class Panner : public Processor int load (); struct PanControllable : public AutomationControl { - PanControllable (Session& s, std::string name, Panner& p, Evoral::Parameter param) + 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 (float); - float get_value (void) const; + 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)); + 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)); + 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); - std::vector _streampanners; + /* disallow copy construction */ + Panner (Panner const &); + + 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;