1 /*
2  * Copyright (C) 2011-2015 Paul Davis <paul@linuxaudiosystems.com>
3  *
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.
8  *
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.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #ifndef __libardour_vbap_speakers_h__
20 #define __libardour_vbap_speakers_h__
21 
22 #include <string>
23 #include <vector>
24 
25 #include <boost/utility.hpp>
26 
27 #include <pbd/signals.h>
28 
29 #include "ardour/panner.h"
30 #include "ardour/speakers.h"
31 
32 namespace ARDOUR
33 {
34 class Speakers;
35 
36 class VBAPSpeakers : public boost::noncopyable
37 {
38 public:
39 	VBAPSpeakers (boost::shared_ptr<Speakers>);
40 
41 	typedef std::vector<double> dvector;
42 
matrix(int tuple)43 	const dvector matrix (int tuple) const
44 	{
45 		return _matrices[tuple];
46 	}
47 
speaker_for_tuple(int tuple,int which)48 	int speaker_for_tuple (int tuple, int which) const
49 	{
50 		return _speaker_tuples[tuple][which];
51 	}
52 
n_tuples()53 	int n_tuples () const
54 	{
55 		return _matrices.size ();
56 	}
57 
dimension()58 	int dimension () const
59 	{
60 		return _dimension;
61 	}
62 
n_speakers()63 	uint32_t n_speakers () const
64 	{
65 		return _speakers.size ();
66 	}
67 
parent()68 	boost::shared_ptr<Speakers> parent () const
69 	{
70 		return _parent;
71 	}
72 
73 	~VBAPSpeakers ();
74 
75 private:
76 	static const double         MIN_VOL_P_SIDE_LGTH;
77 	int                         _dimension;
78 	boost::shared_ptr<Speakers> _parent;
79 	std::vector<Speaker>        _speakers;
80 	PBD::ScopedConnection       speaker_connection;
81 
82 	struct azimuth_sorter {
operatorazimuth_sorter83 		bool operator() (const Speaker& s1, const Speaker& s2)
84 		{
85 			return s1.angles ().azi < s2.angles ().azi;
86 		}
87 	};
88 
89 	struct twoDmatrix : public dvector {
twoDmatrixtwoDmatrix90 		twoDmatrix () : dvector (4, 0.0) { }
91 	};
92 
93 	struct threeDmatrix : public dvector {
threeDmatrixthreeDmatrix94 		threeDmatrix () : dvector (9, 0.0) { }
95 	};
96 
97 	struct tmatrix : public dvector {
tmatrixtmatrix98 		tmatrix () : dvector (3, 0.0) { }
99 	};
100 
101 	std::vector<dvector> _matrices;       /* holds matrices for a given speaker combinations */
102 	std::vector<tmatrix> _speaker_tuples; /* holds speakers IDs for a given combination */
103 
104 	/* A struct for all loudspeakers */
105 	struct ls_triplet_chain {
106 		int                      ls_nos[3];
107 		float                    inv_mx[9];
108 		struct ls_triplet_chain* next;
109 	};
110 
111 	static double vec_angle (PBD::CartesianVector v1, PBD::CartesianVector v2);
112 	static double vec_length (PBD::CartesianVector v1);
113 	static double vec_prod (PBD::CartesianVector v1, PBD::CartesianVector v2);
114 	static double vol_p_side_lgth (int i, int j, int k, const std::vector<Speaker>&);
115 	static void   cross_prod (PBD::CartesianVector v1, PBD::CartesianVector v2, PBD::CartesianVector* res);
116 
117 	void update ();
118 	int  any_ls_inside_triplet (int a, int b, int c);
119 	void add_ldsp_triplet (int i, int j, int k, struct ls_triplet_chain** ls_triplets);
120 	int  lines_intersect (int i, int j, int k, int l);
121 	void calculate_3x3_matrixes (struct ls_triplet_chain* ls_triplets);
122 	void choose_speaker_triplets (struct ls_triplet_chain** ls_triplets);
123 	void choose_speaker_pairs ();
124 	void sort_2D_lss (int* sorted_lss);
125 	int  calc_2D_inv_tmatrix (double azi1, double azi2, double* inv_mat);
126 };
127 
128 } // namespace ARDOUR
129 
130 #endif /* __libardour_vbap_speakers_h__ */
131