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