2 Copyright (C) 2004 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #ifndef __ardour_panner_h__
21 #define __ardour_panner_h__
28 #include <sigc++/signal.h>
30 #include "pbd/stateful.h"
31 #include "pbd/controllable.h"
33 #include "ardour/types.h"
34 #include "ardour/automation_control.h"
35 #include "ardour/processor.h"
44 class StreamPanner : public sigc::trackable, public PBD::Stateful
47 StreamPanner (Panner& p, Evoral::Parameter param);
50 void set_muted (bool yn);
51 bool muted() const { return _muted; }
53 void set_position (float x, bool link_call = false);
54 void set_position (float x, float y, bool link_call = false);
55 void set_position (float x, float y, float z, bool link_call = false);
57 void get_position (float& xpos) const { xpos = x; }
58 void get_position (float& xpos, float& ypos) const { xpos = x; ypos = y; }
59 void get_position (float& xpos, float& ypos, float& zpos) const { xpos = x; ypos = y; zpos = z; }
61 void get_effective_position (float& xpos) const { xpos = effective_x; }
62 void get_effective_position (float& xpos, float& ypos) const { xpos = effective_x; ypos = effective_y; }
63 void get_effective_position (float& xpos, float& ypos, float& zpos) const { xpos = effective_x; ypos = effective_y; zpos = effective_z; }
65 /* the basic StreamPanner API */
67 virtual void distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, nframes_t nframes) = 0;
68 virtual void distribute_automated (AudioBuffer& src, BufferSet& obufs,
69 nframes_t start, nframes_t end, nframes_t nframes, pan_t** buffers) = 0;
71 boost::shared_ptr<AutomationControl> pan_control() { return _control; }
73 sigc::signal<void> Changed; /* for position */
74 sigc::signal<void> StateChanged; /* for mute */
76 int set_state (const XMLNode&, int version);
77 virtual XMLNode& state (bool full_state) = 0;
79 Panner & get_parent() { return parent; }
81 /* old school automation loading */
83 virtual int load (std::istream&, std::string path, uint32_t&) = 0;
93 /* these are for automation. they store the last value
94 used by the most recent process() cycle.
103 boost::shared_ptr<AutomationControl> _control;
105 void add_state (XMLNode&);
106 virtual void update () = 0;
109 class BaseStereoPanner : public StreamPanner
112 BaseStereoPanner (Panner&, Evoral::Parameter param);
113 ~BaseStereoPanner ();
115 /* this class just leaves the pan law itself to be defined
116 by the update(), distribute_automated()
117 methods. derived classes also need a factory method
118 and a type name. See EqualPowerStereoPanner as an example.
121 void distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, nframes_t nframes);
123 /* old school automation loading */
125 int load (std::istream&, std::string path, uint32_t&);
136 class EqualPowerStereoPanner : public BaseStereoPanner
139 EqualPowerStereoPanner (Panner&, Evoral::Parameter param);
140 ~EqualPowerStereoPanner ();
142 void distribute_automated (AudioBuffer& src, BufferSet& obufs,
143 nframes_t start, nframes_t end, nframes_t nframes, pan_t** buffers);
145 void get_current_coefficients (pan_t*) const;
146 void get_desired_coefficients (pan_t*) const;
148 static StreamPanner* factory (Panner&, Evoral::Parameter param);
149 static std::string name;
151 XMLNode& state (bool full_state);
152 XMLNode& get_state (void);
153 int set_state (const XMLNode&, int version);
159 class Multi2dPanner : public StreamPanner
162 Multi2dPanner (Panner& parent, Evoral::Parameter);
165 void distribute (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, nframes_t nframes);
166 void distribute_automated (AudioBuffer& src, BufferSet& obufs,
167 nframes_t start, nframes_t end, nframes_t nframes, pan_t** buffers);
169 static StreamPanner* factory (Panner&, Evoral::Parameter);
170 static std::string name;
172 XMLNode& state (bool full_state);
173 XMLNode& get_state (void);
174 int set_state (const XMLNode&, int version);
176 /* old school automation loading */
178 int load (std::istream&, std::string path, uint32_t&);
185 class Panner : public SessionObject, public AutomatableControls
194 Output (float xp, float yp)
195 : x (xp), y (yp), current_pan (0.0f), desired_pan (0.f) {}
199 //Panner (std::string name, Session&, int _num_bufs);
200 Panner (std::string name, Session&);
203 void clear_panners ();
204 bool empty() const { return _streampanners.empty(); }
206 void set_automation_state (AutoState);
207 AutoState automation_state() const;
208 void set_automation_style (AutoStyle);
209 AutoStyle automation_style() const;
210 bool touching() const;
212 bool can_support_io_configuration (const ChanCount& /*in*/, ChanCount& /*out*/) const { return true; };
214 /// The fundamental Panner function
215 void run (BufferSet& src, BufferSet& dest, sframes_t start_frame, sframes_t end_frames, nframes_t nframes);
217 //void* get_inline_gui() const = 0;
218 //void* get_full_gui() const = 0;
220 bool bypassed() const { return _bypassed; }
221 void set_bypassed (bool yn);
223 StreamPanner* add ();
224 void remove (uint32_t which);
225 void reset (uint32_t noutputs, uint32_t npans);
226 void reset_streampanner (uint32_t which_panner);
227 void reset_to_default ();
229 XMLNode& get_state (void);
230 XMLNode& state (bool full);
231 int set_state (const XMLNode&, int version);
233 static bool equivalent (pan_t a, pan_t b) {
234 return fabsf (a - b) < 0.002; // about 1 degree of arc for a stereo panner
237 void move_output (uint32_t, float x, float y);
238 uint32_t nouts() const { return outputs.size(); }
239 Output& output (uint32_t n) { return outputs[n]; }
241 std::vector<Output> outputs;
248 LinkDirection link_direction() const { return _link_direction; }
249 void set_link_direction (LinkDirection);
251 bool linked() const { return _linked; }
252 void set_linked (bool yn);
254 StreamPanner &streampanner( uint32_t n ) const { assert( n < _streampanners.size() ); return *_streampanners[n]; }
255 uint32_t npanners() const { return _streampanners.size(); }
257 sigc::signal<void> Changed;
258 sigc::signal<void> LinkStateChanged;
259 sigc::signal<void> StateChanged; /* for bypass */
261 /* only StreamPanner should call these */
263 void set_position (float x, StreamPanner& orig);
264 void set_position (float x, float y, StreamPanner& orig);
265 void set_position (float x, float y, float z, StreamPanner& orig);
267 /* old school automation */
271 struct PanControllable : public AutomationControl {
272 PanControllable (Session& s, std::string name, Panner& p, Evoral::Parameter param)
273 : AutomationControl (s, param,
274 boost::shared_ptr<AutomationList>(new AutomationList(param)), name)
276 { assert(param.type() != NullAutomation); }
278 AutomationList* alist() { return (AutomationList*)_list.get(); }
281 void set_value (float);
282 float get_value (void) const;
285 boost::shared_ptr<AutomationControl> pan_control (int id, int chan=0) {
286 return automation_control(Evoral::Parameter (PanAutomation, chan, id));
289 boost::shared_ptr<const AutomationControl> pan_control (int id, int chan=0) const {
290 return automation_control(Evoral::Parameter (PanAutomation, chan, id));
294 /* disallow copy construction */
295 Panner (Panner const &);
297 void distribute_no_automation(BufferSet& src, BufferSet& dest, nframes_t nframes, gain_t gain_coeff);
298 std::vector<StreamPanner*> _streampanners;
299 uint32_t current_outs;
302 LinkDirection _link_direction;
304 static float current_automation_version_number;
306 /* old school automation handling */
308 std::string automation_path;
311 } // namespace ARDOUR
313 #endif /*__ardour_panner_h__ */