summaryrefslogtreecommitdiff
path: root/libs/ardour/vbap_speakers.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ardour/vbap_speakers.cc')
-rw-r--r--libs/ardour/vbap_speakers.cc202
1 files changed, 69 insertions, 133 deletions
diff --git a/libs/ardour/vbap_speakers.cc b/libs/ardour/vbap_speakers.cc
index 3881c971d8..308f1beafb 100644
--- a/libs/ardour/vbap_speakers.cc
+++ b/libs/ardour/vbap_speakers.cc
@@ -39,100 +39,40 @@
#include "ardour/vbap_speakers.h"
using namespace ARDOUR;
+using namespace PBD;
using namespace std;
-VBAPSpeakers::Speaker::Speaker (int i, double azimuth, double elevation)
- : id (i)
-{
- move (azimuth, elevation);
- cerr << setprecision (5) << "%%%%%%%%%% New speaker @ " << angles.azi << ", " << angles.ele << endl;
-}
-
-void
-VBAPSpeakers::Speaker::move (double azimuth, double elevation)
-{
- angles.azi = azimuth;
- angles.ele = elevation;
- angles.length = 1.0;
- angle_to_cart (&angles, &coords);
-}
+VBAPSpeakers* VBAPSpeakers::_instance = 0;
-VBAPSpeakers::VBAPSpeakers ()
- : _dimension (2)
-{
-}
-
-VBAPSpeakers::~VBAPSpeakers ()
+VBAPSpeakers&
+VBAPSpeakers::instance (Speakers& s)
{
-}
-
-void
-VBAPSpeakers::dump_speakers (ostream& o)
-{
- for (vector<Speaker>::iterator i = _speakers.begin(); i != _speakers.end(); ++i) {
- o << "Speaker " << (*i).id << " @ "
- << (*i).coords.x << ", " << (*i).coords.y << ", " << (*i).coords.z
- << " azimuth " << (*i).angles.azi
- << " elevation " << (*i).angles.ele
- << " distance " << (*i).angles.length
- << endl;
+ if (_instance == 0) {
+ _instance = new VBAPSpeakers (s);
}
-}
-void
-VBAPSpeakers::clear_speakers ()
-{
- _speakers.clear ();
- update ();
+ return *_instance;
}
-int
-VBAPSpeakers::add_speaker (double azimuth, double elevation)
-{
- int id = _speakers.size();
-
- cerr << "Added speaker " << id << " at " << azimuth << " /= " << elevation << endl;
-
- _speakers.push_back (Speaker (id, azimuth, elevation));
- update ();
-
- dump_speakers (cerr);
-
- return id;
-}
-
-void
-VBAPSpeakers::remove_speaker (int id)
+VBAPSpeakers::VBAPSpeakers (Speakers& s)
+ : _dimension (2)
+ , _speakers (s.speakers())
{
- for (vector<Speaker>::iterator i = _speakers.begin(); i != _speakers.end(); ) {
- if ((*i).id == id) {
- i = _speakers.erase (i);
- update ();
- break;
- }
- }
+ s.Changed.connect_same_thread (speaker_connection, boost::bind (&VBAPSpeakers::update, this));
}
-void
-VBAPSpeakers::move_speaker (int id, double direction, double elevation)
+VBAPSpeakers::~VBAPSpeakers ()
{
- for (vector<Speaker>::iterator i = _speakers.begin(); i != _speakers.end(); ++i) {
- if ((*i).id == id) {
- (*i).move (direction, elevation);
- update ();
- break;
- }
- }
}
void
VBAPSpeakers::update ()
{
int dim = 2;
-
- for (vector<Speaker>::iterator i = _speakers.begin(); i != _speakers.end(); ++i) {
- if ((*i).angles.ele != 0.0) {
- cerr << "\n\n\nSPEAKER " << (*i).id << " has ele = " << (*i).angles.ele << "\n\n\n\n";
+
+ for (vector<Speaker>::const_iterator i = _speakers.begin(); i != _speakers.end(); ++i) {
+ if ((*i).angles().ele != 0.0) {
+ cerr << "\n\n\nSPEAKER " << (*i).id << " has ele = " << (*i).angles().ele << "\n\n\n\n";
dim = 3;
break;
}
@@ -157,17 +97,9 @@ VBAPSpeakers::update ()
} else {
choose_speaker_pairs ();
}
-
- Changed (); /* EMIT SIGNAL */
}
void
-VBAPSpeakers::angle_to_cart(ang_vec *from, cart_vec *to)
-{
- PBD::azi_ele_to_cart (from->azi, from->ele, to->x, to->y, to->z);
-}
-
-void
VBAPSpeakers::choose_speaker_triplets(struct ls_triplet_chain **ls_triplets)
{
/* Selects the loudspeaker triplets, and
@@ -217,7 +149,7 @@ VBAPSpeakers::choose_speaker_triplets(struct ls_triplet_chain **ls_triplets)
for (i = 0;i < n_speakers; i++) {
for (j = i+1; j < n_speakers; j++) {
if (connections[i][j] == 1) {
- distance = fabs(vec_angle(_speakers[i].coords,_speakers[j].coords));
+ distance = fabs(vec_angle(_speakers[i].coords(),_speakers[j].coords()));
k=0;
while(distance_table[k] < distance) {
k++;
@@ -291,7 +223,9 @@ VBAPSpeakers::any_ls_inside_triplet(int a, int b, int c)
{
/* returns 1 if there is loudspeaker(s) inside given ls triplet */
float invdet;
- cart_vec *lp1, *lp2, *lp3;
+ const CartesianVector* lp1;
+ const CartesianVector* lp2;
+ const CartesianVector* lp3;
float invmx[9];
int i,j;
float tmp;
@@ -299,9 +233,9 @@ VBAPSpeakers::any_ls_inside_triplet(int a, int b, int c)
bool this_inside;
int n_speakers = _speakers.size();
- lp1 = &(_speakers[a].coords);
- lp2 = &(_speakers[b].coords);
- lp3 = &(_speakers[c].coords);
+ lp1 = &(_speakers[a].coords());
+ lp2 = &(_speakers[b].coords());
+ lp3 = &(_speakers[c].coords());
/* matrix inversion */
invdet = 1.0 / ( lp1->x * ((lp2->y * lp3->z) - (lp2->z * lp3->y))
@@ -323,9 +257,9 @@ VBAPSpeakers::any_ls_inside_triplet(int a, int b, int c)
if (i != a && i!=b && i != c) {
this_inside = true;
for (j = 0; j < 3; j++) {
- tmp = _speakers[i].coords.x * invmx[0 + j*3];
- tmp += _speakers[i].coords.y * invmx[1 + j*3];
- tmp += _speakers[i].coords.z * invmx[2 + j*3];
+ tmp = _speakers[i].coords().x * invmx[0 + j*3];
+ tmp += _speakers[i].coords().y * invmx[1 + j*3];
+ tmp += _speakers[i].coords().z * invmx[2 + j*3];
if (tmp < -0.001) {
this_inside = false;
}
@@ -369,7 +303,7 @@ VBAPSpeakers::add_ldsp_triplet(int i, int j, int k, struct ls_triplet_chain **ls
}
float
-VBAPSpeakers::vec_angle(cart_vec v1, cart_vec v2)
+VBAPSpeakers::vec_angle(CartesianVector v1, CartesianVector v2)
{
float inner= ((v1.x*v2.x + v1.y*v2.y + v1.z*v2.z)/
(vec_length(v1) * vec_length(v2)));
@@ -386,13 +320,13 @@ VBAPSpeakers::vec_angle(cart_vec v1, cart_vec v2)
}
float
-VBAPSpeakers::vec_length(cart_vec v1)
+VBAPSpeakers::vec_length(CartesianVector v1)
{
return (sqrt(v1.x*v1.x + v1.y*v1.y + v1.z*v1.z));
}
float
-VBAPSpeakers::vec_prod(cart_vec v1, cart_vec v2)
+VBAPSpeakers::vec_prod(CartesianVector v1, CartesianVector v2)
{
return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
}
@@ -405,13 +339,13 @@ VBAPSpeakers::vol_p_side_lgth(int i, int j,int k, const vector<Speaker>& speaker
This is used when removing too narrow triangles. */
float volper, lgth;
- cart_vec xprod;
+ CartesianVector xprod;
- cross_prod (speakers[i].coords, speakers[j].coords, &xprod);
- volper = fabsf (vec_prod(xprod, speakers[k].coords));
- lgth = (fabsf (vec_angle(speakers[i].coords, speakers[j].coords))
- + fabsf (vec_angle(speakers[i].coords, speakers[k].coords))
- + fabsf (vec_angle(speakers[j].coords, speakers[k].coords)));
+ cross_prod (speakers[i].coords(), speakers[j].coords(), &xprod);
+ volper = fabsf (vec_prod(xprod, speakers[k].coords()));
+ lgth = (fabsf (vec_angle(speakers[i].coords(), speakers[j].coords()))
+ + fabsf (vec_angle(speakers[i].coords(), speakers[k].coords()))
+ + fabsf (vec_angle(speakers[j].coords(), speakers[k].coords())));
if (lgth > 0.00001) {
return volper / lgth;
@@ -421,7 +355,7 @@ VBAPSpeakers::vol_p_side_lgth(int i, int j,int k, const vector<Speaker>& speaker
}
void
-VBAPSpeakers::cross_prod(cart_vec v1,cart_vec v2, cart_vec *res)
+VBAPSpeakers::cross_prod(CartesianVector v1,CartesianVector v2, CartesianVector *res)
{
float length;
@@ -429,7 +363,7 @@ VBAPSpeakers::cross_prod(cart_vec v1,cart_vec v2, cart_vec *res)
res->y = (v1.z * v2.x ) - (v1.x * v2.z);
res->z = (v1.x * v2.y ) - (v1.y * v2.x);
- length= vec_length(*res);
+ length = vec_length(*res);
res->x /= length;
res->y /= length;
res->z /= length;
@@ -446,30 +380,30 @@ VBAPSpeakers::lines_intersect (int i, int j, int k, int l)
if you want to have that paper.
*/
- cart_vec v1;
- cart_vec v2;
- cart_vec v3, neg_v3;
+ CartesianVector v1;
+ CartesianVector v2;
+ CartesianVector v3, neg_v3;
float dist_ij,dist_kl,dist_iv3,dist_jv3,dist_inv3,dist_jnv3;
float dist_kv3,dist_lv3,dist_knv3,dist_lnv3;
- cross_prod(_speakers[i].coords,_speakers[j].coords,&v1);
- cross_prod(_speakers[k].coords,_speakers[l].coords,&v2);
+ cross_prod(_speakers[i].coords(),_speakers[j].coords(),&v1);
+ cross_prod(_speakers[k].coords(),_speakers[l].coords(),&v2);
cross_prod(v1,v2,&v3);
neg_v3.x= 0.0 - v3.x;
neg_v3.y= 0.0 - v3.y;
neg_v3.z= 0.0 - v3.z;
- dist_ij = (vec_angle(_speakers[i].coords,_speakers[j].coords));
- dist_kl = (vec_angle(_speakers[k].coords,_speakers[l].coords));
- dist_iv3 = (vec_angle(_speakers[i].coords,v3));
- dist_jv3 = (vec_angle(v3,_speakers[j].coords));
- dist_inv3 = (vec_angle(_speakers[i].coords,neg_v3));
- dist_jnv3 = (vec_angle(neg_v3,_speakers[j].coords));
- dist_kv3 = (vec_angle(_speakers[k].coords,v3));
- dist_lv3 = (vec_angle(v3,_speakers[l].coords));
- dist_knv3 = (vec_angle(_speakers[k].coords,neg_v3));
- dist_lnv3 = (vec_angle(neg_v3,_speakers[l].coords));
+ dist_ij = (vec_angle(_speakers[i].coords(),_speakers[j].coords()));
+ dist_kl = (vec_angle(_speakers[k].coords(),_speakers[l].coords()));
+ dist_iv3 = (vec_angle(_speakers[i].coords(),v3));
+ dist_jv3 = (vec_angle(v3,_speakers[j].coords()));
+ dist_inv3 = (vec_angle(_speakers[i].coords(),neg_v3));
+ dist_jnv3 = (vec_angle(neg_v3,_speakers[j].coords()));
+ dist_kv3 = (vec_angle(_speakers[k].coords(),v3));
+ dist_lv3 = (vec_angle(v3,_speakers[l].coords()));
+ dist_knv3 = (vec_angle(_speakers[k].coords(),neg_v3));
+ dist_lnv3 = (vec_angle(neg_v3,_speakers[l].coords()));
/* if one of loudspeakers is close to crossing point, don't do anything*/
@@ -496,7 +430,9 @@ VBAPSpeakers::calculate_3x3_matrixes(struct ls_triplet_chain *ls_triplets)
{
/* Calculates the inverse matrices for 3D */
float invdet;
- cart_vec *lp1, *lp2, *lp3;
+ const CartesianVector* lp1;
+ const CartesianVector* lp2;
+ const CartesianVector* lp3;
float *invmx;
struct ls_triplet_chain *tr_ptr = ls_triplets;
int triplet_count = 0;
@@ -524,9 +460,9 @@ VBAPSpeakers::calculate_3x3_matrixes(struct ls_triplet_chain *ls_triplets)
}
while (tr_ptr != 0) {
- lp1 = &(_speakers[tr_ptr->ls_nos[0]].coords);
- lp2 = &(_speakers[tr_ptr->ls_nos[1]].coords);
- lp3 = &(_speakers[tr_ptr->ls_nos[2]].coords);
+ lp1 = &(_speakers[tr_ptr->ls_nos[0]].coords());
+ lp2 = &(_speakers[tr_ptr->ls_nos[1]].coords());
+ lp3 = &(_speakers[tr_ptr->ls_nos[2]].coords());
/* matrix inversion */
invmx = tr_ptr->inv_mx;
@@ -603,17 +539,17 @@ VBAPSpeakers::choose_speaker_pairs (){
for (speaker = 0; speaker < n_speakers-1; speaker++) {
cerr << "Looking at "
- << _speakers[sorted_speakers[speaker]].id << " @ " << _speakers[sorted_speakers[speaker]].angles.azi
+ << _speakers[sorted_speakers[speaker]].id << " @ " << _speakers[sorted_speakers[speaker]].angles().azi
<< " and "
- << _speakers[sorted_speakers[speaker+1]].id << " @ " << _speakers[sorted_speakers[speaker+1]].angles.azi
+ << _speakers[sorted_speakers[speaker+1]].id << " @ " << _speakers[sorted_speakers[speaker+1]].angles().azi
<< " delta = "
- << _speakers[sorted_speakers[speaker+1]].angles.azi - _speakers[sorted_speakers[speaker]].angles.azi
+ << _speakers[sorted_speakers[speaker+1]].angles().azi - _speakers[sorted_speakers[speaker]].angles().azi
<< endl;
- if ((_speakers[sorted_speakers[speaker+1]].angles.azi -
- _speakers[sorted_speakers[speaker]].angles.azi) <= AZIMUTH_DELTA_THRESHOLD_DEGREES) {
- if (calc_2D_inv_tmatrix( _speakers[sorted_speakers[speaker]].angles.azi,
- _speakers[sorted_speakers[speaker+1]].angles.azi,
+ if ((_speakers[sorted_speakers[speaker+1]].angles().azi -
+ _speakers[sorted_speakers[speaker]].angles().azi) <= AZIMUTH_DELTA_THRESHOLD_DEGREES) {
+ if (calc_2D_inv_tmatrix( _speakers[sorted_speakers[speaker]].angles().azi,
+ _speakers[sorted_speakers[speaker+1]].angles().azi,
inverse_matrix[speaker]) != 0){
exists[speaker] = true;
expected_pairs++;
@@ -621,10 +557,10 @@ VBAPSpeakers::choose_speaker_pairs (){
}
}
- if (((6.283 - _speakers[sorted_speakers[n_speakers-1]].angles.azi)
- +_speakers[sorted_speakers[0]].angles.azi) <= AZIMUTH_DELTA_THRESHOLD_DEGREES) {
- if (calc_2D_inv_tmatrix(_speakers[sorted_speakers[n_speakers-1]].angles.azi,
- _speakers[sorted_speakers[0]].angles.azi,
+ if (((6.283 - _speakers[sorted_speakers[n_speakers-1]].angles().azi)
+ +_speakers[sorted_speakers[0]].angles().azi) <= AZIMUTH_DELTA_THRESHOLD_DEGREES) {
+ if (calc_2D_inv_tmatrix(_speakers[sorted_speakers[n_speakers-1]].angles().azi,
+ _speakers[sorted_speakers[0]].angles().azi,
inverse_matrix[n_speakers-1]) != 0) {
exists[n_speakers-1] = true;
expected_pairs++;