1 /* 2 * Copyright (C) 2006-2011 David Robillard <d@drobilla.net> 3 * Copyright (C) 2008-2017 Paul Davis <paul@linuxaudiosystems.com> 4 * Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net> 5 * Copyright (C) 2013 John Emmas <john@creativepost.co.uk> 6 * Copyright (C) 2014-2017 Robin Gareus <robin@gareus.org> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License along 19 * with this program; if not, write to the Free Software Foundation, Inc., 20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 */ 22 23 #ifndef __ardour_panner_h__ 24 #define __ardour_panner_h__ 25 26 #include <cmath> 27 #include <cassert> 28 #include <vector> 29 #include <string> 30 #include <iostream> 31 32 #include "pbd/cartesian.h" 33 #include "pbd/signals.h" 34 #include "pbd/stateful.h" 35 36 #include "ardour/libardour_visibility.h" 37 #include "ardour/types.h" 38 #include "ardour/automation_control.h" 39 #include "ardour/automatable.h" 40 41 42 /* This section is for actual panners to use. They will include this file, 43 * declare ARDOURPANNER_DLL_EXPORTS during compilation, and ... voila. 44 */ 45 46 #ifdef ARDOURPANNER_DLL_EXPORTS // defined if we are building a panner implementation 47 #define ARDOURPANNER_API LIBARDOUR_DLL_EXPORT 48 #else 49 #define ARDOURPANNER_API LIBARDOUR_DLL_IMPORT 50 #endif 51 #define ARDOURPANNER_LOCAL LIBARDOUR_DLL_LOCAL 52 53 namespace ARDOUR { 54 55 class Session; 56 class Pannable; 57 class BufferSet; 58 class AudioBuffer; 59 class Speakers; 60 61 class LIBARDOUR_API Panner : public PBD::Stateful, public PBD::ScopedConnectionList 62 { 63 public: 64 Panner (boost::shared_ptr<Pannable>); 65 ~Panner (); 66 get_speakers()67 virtual boost::shared_ptr<Speakers> get_speakers() const { return boost::shared_ptr<Speakers>(); } 68 69 virtual ChanCount in() const = 0; 70 virtual ChanCount out() const = 0; 71 configure_io(ARDOUR::ChanCount,ARDOUR::ChanCount)72 virtual void configure_io (ARDOUR::ChanCount /*in*/, ARDOUR::ChanCount /*out*/) {} 73 74 /* derived implementations of these methods must indicate 75 whether it is legal for a Controllable to use the 76 value of the argument (post-call) in a call to 77 Controllable::set_value(). 78 79 they have a choice of: 80 81 * return true, leave argument unchanged 82 * return true, modify argument 83 * return false 84 */ 85 clamp_position(double &)86 virtual bool clamp_position (double&) { return true; } clamp_width(double &)87 virtual bool clamp_width (double&) { return true; } clamp_elevation(double &)88 virtual bool clamp_elevation (double&) { return true; } 89 position_range()90 virtual std::pair<double, double> position_range () const { return std::make_pair (-DBL_MAX, DBL_MAX); } width_range()91 virtual std::pair<double, double> width_range () const { return std::make_pair (-DBL_MAX, DBL_MAX); } elevation_range()92 virtual std::pair<double, double> elevation_range () const { return std::make_pair (-DBL_MAX, DBL_MAX); } 93 set_position(double)94 virtual void set_position (double) { } set_width(double)95 virtual void set_width (double) { } set_elevation(double)96 virtual void set_elevation (double) { } 97 position()98 virtual double position () const { return 0.0; } width()99 virtual double width () const { return 0.0; } elevation()100 virtual double elevation () const { return 0.0; } 101 signal_position(uint32_t)102 virtual PBD::AngularVector signal_position (uint32_t) const { return PBD::AngularVector(); } 103 104 virtual void reset () = 0; 105 106 /* azimut, width or elevation updated -> recalc signal_position -> emit Changed */ 107 PBD::Signal0<void> SignalPositionChanged; 108 109 /** 110 * Pan some input buffers to a number of output buffers. 111 * 112 * @param ibufs Input buffers (one per panner input) 113 * @param obufs Output buffers (one per panner output). 114 * @param gain_coeff fixed, additional gain coefficient to apply to output samples. 115 * @param nframes Number of samples in the input. 116 * 117 * Derived panners can choose to implement these if they need to gain more 118 * control over the panning algorithm. The default is to call 119 * distribute_one() or distribute_one_automated() on each input buffer to 120 * deliver it to each output buffer. 121 * 122 * If a panner does not need to override this default behaviour, it can 123 * just implement distribute_one() and distribute_one_automated() (below). 124 */ 125 virtual void distribute (BufferSet& ibufs, BufferSet& obufs, gain_t gain_coeff, pframes_t nframes); 126 virtual void distribute_automated (BufferSet& ibufs, BufferSet& obufs, 127 samplepos_t start, samplepos_t end, pframes_t nframes, 128 pan_t** buffers); 129 130 int set_state (const XMLNode&, int version); 131 XMLNode& get_state (); 132 pannable()133 boost::shared_ptr<Pannable> pannable() const { return _pannable; } 134 135 virtual void freeze (); 136 virtual void thaw (); 137 what_can_be_automated()138 const std::set<Evoral::Parameter>& what_can_be_automated() const { 139 return _can_automate_list; 140 } 141 142 virtual std::string value_as_string (boost::shared_ptr<const AutomationControl>) const = 0; 143 144 protected: 145 virtual void distribute_one (AudioBuffer&, BufferSet& obufs, gain_t gain_coeff, pframes_t nframes, uint32_t which) = 0; 146 virtual void distribute_one_automated (AudioBuffer&, BufferSet& obufs, 147 samplepos_t start, samplepos_t end, pframes_t nframes, 148 pan_t** buffers, uint32_t which) = 0; 149 150 boost::shared_ptr<Pannable> _pannable; 151 std::set<Evoral::Parameter> _can_automate_list; 152 153 int32_t _frozen; 154 }; 155 156 } // namespace 157 158 extern "C" { 159 struct LIBARDOUR_API PanPluginDescriptor { 160 std::string name; 161 std::string panner_uri; 162 std::string gui_uri; 163 int32_t in; 164 int32_t out; 165 uint32_t priority; 166 ARDOUR::Panner* (*factory)(boost::shared_ptr<ARDOUR::Pannable>, boost::shared_ptr<ARDOUR::Speakers>); 167 }; 168 } 169 170 #endif /* __ardour_panner_h__ */ 171