1 /*
2  * Copyright (C) 2011-2017 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2011 Carl Hetherington <carl@carlh.net>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #ifndef __libardour_vbap_h__
21 #define __libardour_vbap_h__
22 
23 #include <map>
24 #include <string>
25 
26 #include "pbd/cartesian.h"
27 
28 #include "ardour/panner.h"
29 #include "ardour/panner_shell.h"
30 
31 #include "vbap_speakers.h"
32 
33 namespace ARDOUR
34 {
35 class Speakers;
36 class Pannable;
37 
38 class VBAPanner : public Panner
39 {
40 public:
41 	VBAPanner (boost::shared_ptr<Pannable>, boost::shared_ptr<Speakers>);
42 	~VBAPanner ();
43 
44 	void      configure_io (ChanCount in, ChanCount /* ignored - we use Speakers */);
45 	ChanCount in () const;
46 	ChanCount out () const;
47 
48 	void set_position (double);
49 	void set_width (double);
50 	void set_elevation (double);
51 
52 	static Panner* factory (boost::shared_ptr<Pannable>, boost::shared_ptr<Speakers>);
53 
54 	void distribute (BufferSet& ibufs, BufferSet& obufs, gain_t gain_coeff, pframes_t nframes);
55 
56 	void set_azimuth_elevation (double azimuth, double elevation);
57 
58 	std::string value_as_string (boost::shared_ptr<const AutomationControl>) const;
59 
60 	XMLNode& get_state ();
61 
62 	PBD::AngularVector          signal_position (uint32_t n) const;
63 	boost::shared_ptr<Speakers> get_speakers () const;
64 
65 	void reset ();
66 
67 private:
68 	struct Signal {
69 		PBD::AngularVector  direction;
70 		std::vector<double> gains; /* most recently used gain for all speakers */
71 
72 		int    outputs[3];         /* most recent set of outputs used (2 or 3, depending on dimension) */
73 		int    desired_outputs[3]; /* outputs to use the next time we distribute */
74 		double desired_gains[3];   /* target gains for desired_outputs */
75 
76 		Signal (VBAPanner&, uint32_t which, uint32_t n_speakers);
77 		void resize_gains (uint32_t n_speakers);
78 	};
79 
80 	std::vector<Signal*>            _signals;
81 	boost::shared_ptr<VBAPSpeakers> _speakers;
82 
83 	void compute_gains (double g[3], int ls[3], int azi, int ele);
84 	void update ();
85 	void clear_signals ();
86 
87 	void distribute_one (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, pframes_t nframes, uint32_t which);
88 	void distribute_one_automated (AudioBuffer& src, BufferSet& obufs,
89 	                               samplepos_t start, samplepos_t end, pframes_t nframes,
90 	                               pan_t** buffers, uint32_t which);
91 };
92 
93 } // namespace ARDOUR
94 
95 #endif /* __libardour_vbap_h__ */
96