aboutsummaryrefslogtreecommitdiff
path: root/define_loudspeakers.c
diff options
context:
space:
mode:
Diffstat (limited to 'define_loudspeakers.c')
-rw-r--r--define_loudspeakers.c680
1 files changed, 330 insertions, 350 deletions
diff --git a/define_loudspeakers.c b/define_loudspeakers.c
index 34561d3..ce064f1 100644
--- a/define_loudspeakers.c
+++ b/define_loudspeakers.c
@@ -1,255 +1,172 @@
-/* define_loudspeakers.c
+/* define_loudspeakers.c 1.00b1----> x-max4.2
-written by Ville Pulkki 1999
+written by Ville Pulkki 1999-2003
Helsinki University of Technology
and
Unversity of California at Berkeley
See copyright in file with name COPYRIGHT */
-#include <math.h>
-#include "m_pd.h" /* you must include this - it contains the external object's link to pure data */
-
-#define RES_ID 9172 /* resource ID for assistance (we'll add that later) */
-#define MAX_LS_AMOUNT 55 /* maximum amount of loudspeakers, can be raised */
-#define MIN_VOL_P_SIDE_LGTH 0.01
-
-#ifndef NT
-#define NULL 0L
-#endif
-#ifndef IRIX
-#define fabsf fabs
-#endif
-
-/* A struct for a loudspeaker instance */
-typedef struct { /* distance value is 1.0 == unit vectors */
- float x; /* cartesian coordinates */
- float y;
- float z;
- float azi; /* polar coordinates */
- float ele;
- int channel_nbr; /* which speaker channel number */
-} t_ls;
-
-/* A struct for all loudspeaker sets */
-typedef struct t_ls_set {
- int ls_nos[3]; /* channel numbers */
- float inv_mx[9]; /* inverse 3x3 or 2x2 matrix */
- struct t_ls_set *next; /* next set (triplet or pair) */
-} t_ls_set;
-
-typedef struct /* This defines the object as an entity made up of other things */
-{
- t_object x_ob; /* gotta say this... it creates a reference to your object */
- long x_ls_read; /* 1 if loudspeaker directions have been read */
- long x_triplets_specified; /* 1 if loudspeaker triplets have been chosen */
- t_ls x_ls[MAX_LS_AMOUNT]; /* loudspeakers */
- t_ls_set *x_ls_set; /* loudspeaker sets */
- void *x_outlet0; /* outlet creation - inlets are automatic */
- long x_ls_amount; /* number of loudspeakers */
- long x_dimension; /* 2 (horizontal arrays) or 3 (3d setups) */
-} t_def_ls;
-
-static t_class *def_ls_class; /* so max can identify your object */
-void def_ls_bang(t_def_ls *x);
-void def_ls_int(t_def_ls *x, t_float n);
-void def_ls_read_directions(t_def_ls *x, t_symbol *s, int ac, t_atom *av);
-void def_ls_read_triplets(t_def_ls *x, t_symbol *s, int ac, t_atom *av);
-static void *def_ls_new(t_symbol *s, int ac, t_atom *av); /* using A_GIMME - typed message list */
-void def_ls(float g[3], long ls[3], t_def_ls *x);
-void ls_angles_to_cart(t_ls *ls);
-void choose_ls_triplets(t_def_ls *x);
-int any_ls_inside_triplet(int a, int b, int c,t_ls lss[MAX_LS_AMOUNT],int ls_amount);
-void add_ldsp_triplet(int i, int j, int k, t_def_ls *x);
-float vec_angle(t_ls v1, t_ls v2);
-float vec_length(t_ls v1);
-float vec_prod(t_ls v1, t_ls v2);
-float vec_prod(t_ls v1, t_ls v2);
-float vol_p_side_lgth(int i, int j,int k, t_ls lss[MAX_LS_AMOUNT] );
-void unq_cross_prod(t_ls v1,t_ls v2, t_ls *res);
-int lines_intersect(int i,int j,int k,int l,t_ls lss[MAX_LS_AMOUNT]);
-void calculate_3x3_matrixes(t_def_ls *x);
-void choose_ls_tuplets(t_def_ls *x);
-int calc_2D_inv_tmatrix(float azi1,float azi2, float inv_mat[4]);
-void sort_2D_lss(t_ls lss[MAX_LS_AMOUNT], int sorted_lss[MAX_LS_AMOUNT],
- int ls_amount);
-
-/* above are the prototypes for the methods/procedures/functions you will use */
+#include "define_loudspeakers.h"
+#ifndef VBAP_OBJECT
+# ifdef PD
+// If we are within VBAP (which includes define_loudspeakers), then don't create a main for define_loudspeakres
void define_loudspeakers_setup(void)
{
def_ls_class = class_new(gensym("define_loudspeakers"), (t_newmethod)def_ls_new, 0, (short)sizeof(t_def_ls), 0, A_GIMME, 0);
/* def_ls_new = creation function, A_DEFLONG = its (optional) arguement is a long (32-bit) int */
-/*
-/* addbang((method)def_ls_bang); /* the procedure it uses when it gets a bang in the left inlet */
-/* addint((method)def_ls_int); /* the rocedure for an int in the left inlet (inlet 0) */
-/* addmess((method)def_ls_read_directions, "ls-directions", A_GIMME, 0);
-/* addmess((method)def_ls_read_triplets, "ls-triplets", A_GIMME, 0);
-*/
- class_addbang(def_ls_class, def_ls_bang);
- class_addfloat(def_ls_class, def_ls_int);
- class_addmethod(def_ls_class, (t_method)def_ls_read_directions, gensym("ls-directions"), A_GIMME, 0);
+
+ class_addbang(def_ls_class, (t_method)def_ls_bang); /* the procedure it uses when it gets a bang in the left inlet */
+ class_addmethod(def_ls_class, (t_method)def_ls_read_directions, gensym("ls-directions"), A_GIMME, 0);
class_addmethod(def_ls_class, (t_method)def_ls_read_triplets, gensym("ls-triplets"), A_GIMME, 0);
+
+ post(DFLS_VERSION);
}
+# else /* Max */
+void main(void)
+{
+ setup((t_messlist **)&def_ls_class, (method)def_ls_new, 0L, (short)sizeof(t_def_ls), 0L, A_GIMME, 0);
+ /* def_ls_new = creation function, A_DEFLONG = its (optional) arguement is a long (32-bit) int */
+
+ addbang((method)def_ls_bang); /* the procedure it uses when it gets a bang in the left inlet */
+ addmess((method)def_ls_read_directions, "ls-directions", A_GIMME, 0);
+ addmess((method)def_ls_read_triplets, "ls-triplets", A_GIMME, 0);
+ addmess((method)traces, "enabletrace", A_LONG, 0);
+ post(DFLS_VERSION);
+}
+# endif /* PD */
+#endif /* ! VBAP_OBJECT */
void def_ls_bang(t_def_ls *x) /* x = reference to this instance of the object */
-{ /* calculate and print out chosen loudspeaker sets and corresponding matrices */
- t_atom at[MAX_LS_AMOUNT*2+1];
- float g[3];
- long ls[3];
- long i;
+{ // calculate and print out chosen loudspeaker sets and corresponding matrices
- if(x->x_ls_read == 1){
- if(x->x_ls_amount < x->x_dimension){
- post("define-loudspeakers: Too few loudspeakers!",0);
+ if(x->x_ls_read == 1)
+ {
+ if(x->x_def_ls_amount < x->x_def_ls_dimension)
+ {
+ error("define-loudspeakers: Too few loudspeakers!");
return;
- } else if(x->x_dimension == 3){
- if(x->x_triplets_specified==0)
- choose_ls_triplets(x);
- calculate_3x3_matrixes(x);
- } else if(x->x_dimension == 2)
+ }
+ else
+ {
+ if(x->x_def_ls_dimension == 3)
+ {
+ if(x->x_triplets_specified==0) choose_ls_triplets(x);
+ calculate_3x3_matrixes(x);
+ }
+ else if(x->x_def_ls_dimension == 2)
+ {
choose_ls_tuplets(x);
- else {
- post("define-loudspeakers: Error in loudspeaker direction data");
- post("dimension azimuth1 [elevation1] azimuth2 [elevation2]...");
- post("dimension == 2 for horizontal ls arrays");
- post("dimension == 3 for 3-D ls arrays (speakers also upward and/or downward ",0);
+ }
+ else
+ {
+ error("define-loudspeakers: Error in loudspeaker direction data");
+ error("dimension azimuth1 [elevation1] azimuth2 [elevation2]...");
+ error("dimension == 2 for horizontal ls arrays");
+ error("dimension == 3 for 3-D ls arrays (speakers also upward and/or downward ");
}
- } else{
- post("define-loudspeakers: Error in loudspeaker direction data",0);
- post("dimension azimuth1 [elevation1] azimuth2 [elevation2]...",0);
- post("dimension == 2 for horizontal ls arrays",0);
- post("dimension == 3 for 3-D ls arrays (speakers also upward and/or downward ",0);
+ }
+ }
+ else
+ {
+ error("define-loudspeakers: Error in loudspeaker direction data");
+ error("dimension azimuth1 [elevation1] azimuth2 [elevation2]...");
+ error("dimension == 2 for horizontal ls arrays");
+ error("dimension == 3 for 3-D ls arrays (speakers also upward and/or downward ");
}
}
/*--------------------------------------------------------------------------*/
-void def_ls_int(t_def_ls *x, t_float n) /* x = the instance of the object, n = the int received in the right inlet */
+/*
+void def_ls_int(t_def_ls *x, long n) // x = the instance of the object, n = the int received in the right inlet
{
- /* do something if an int comes in the left inlet??? */
+ // do something if an int comes in the left inlet???
}
+*/
-void def_ls_read_triplets(t_def_ls *x, t_symbol *s, int ac, t_atom *av)
-/* when loudspeaker triplets come in a message */
+void def_ls_read_triplets(t_def_ls *x, t_symbol *s, int ac, Atom *av)
+// when loudspeaker triplets come in a message
{
- long l1,l2,l3,i;
t_ls_set *trip_ptr, *tmp_ptr, *prev;
- if(x->x_ls_read == 0){
- post("define_loudspeakers: Define loudspeaker directions first!",0);
+ if(x->x_ls_read == 0)
+ {
+ error("define_loudspeakers: Define loudspeaker directions first!");
return;
}
- if(x->x_dimension == 2){
- post("define_loudspeakers: Can't specify loudspeaker triplets in 2-D setup!",0);
+ if(x->x_def_ls_dimension == 2)
+ {
+ error("define_loudspeakers: Can't specify loudspeaker triplets in 2-D setup!");
return;
}
trip_ptr = x->x_ls_set;
- prev = NULL;
- while (trip_ptr != NULL){
- tmp_ptr = trip_ptr;
- trip_ptr = trip_ptr->next;
- freebytes(tmp_ptr, sizeof (struct t_ls_set));
- }
- x->x_ls_set = NULL;
+ prev = NULL;
+ while (trip_ptr != NULL)
+ {
+ tmp_ptr = trip_ptr;
+ trip_ptr = trip_ptr->next;
+ freebytes(tmp_ptr, sizeof (struct t_ls_set));
+ }
+ x->x_ls_set = NULL;
- for(i=0;i<ac;i+=3){
-/* if(av[i].a_type == A_LONG)
+ int i;
+ for(i=0;i<ac;i+=3)
+ {
+ long l1 = 0,l2 = 0,l3 = 0;
+
+/*
+ if(av[i].a_type == A_LONG)
l1 = av[i].a_w.w_long;
- else */
- if(av[i].a_type == A_FLOAT)
+ else */ if(av[i].a_type == A_FLOAT)
l1 = (long) av[i].a_w.w_float;
-/* if(av[i+1].a_type == A_LONG)
+
+/*
+ if(av[i+1].a_type == A_LONG)
l2 = av[i+1].a_w.w_long;
- else */
- if(av[i+1].a_type == A_FLOAT)
+ else */ if(av[i+1].a_type == A_FLOAT)
l2 = (long) av[i+1].a_w.w_float;
-/* if(av[i+2].a_type == A_LONG)
+
+/*
+ if(av[i+2].a_type == A_LONG)
l3 = av[i+2].a_w.w_long;
- else */
- if(av[i+2].a_type == A_FLOAT)
+ else */ if(av[i+2].a_type == A_FLOAT)
l3 = (long) av[i+2].a_w.w_float;
- add_ldsp_triplet(l1-1,l2-1,l3-1,x);
- }
- x->x_triplets_specified=1;
+
+ add_ldsp_triplet(l1-1,l2-1,l3-1,x);
+ }
+ x->x_triplets_specified=1;
}
-void def_ls_read_directions(t_def_ls *x, t_symbol *s, int ac, t_atom *av)
-/* when loudspeaker directions come in a message */
+void def_ls_read_directions(t_def_ls *x, t_symbol *s, int ac, Atom *av)
+// when loudspeaker directions come in a message
{
- t_ls_set *trip_ptr, *prev, *tmp_ptr;
- long i,pointer,newlyread;
- newlyread = 0;
-/* if(av[0].a_type == A_LONG){
- x->x_dimension= av[0].a_w.w_long;
- newlyread = 1;
- } else */
- if(av[0].a_type == A_FLOAT) {
- x->x_dimension= (int) av[0].a_w.w_float;
- newlyread = 1;
- } else x->x_dimension= 0;
-
- if(x->x_dimension <2 || x->x_dimension >3){
- post("define-loudspeakers: Dimension has to be 2 or 3!",0);
- return;
- }
-
- pointer = 1;
- x->x_ls_amount= (ac-1) / (x->x_dimension - 1);
- for(i=0; i < x->x_ls_amount;i++){
-/* if(av[0].a_type == A_LONG)
- x->x_ls[i].azi = (float) av[pointer].a_w.w_long;
- else */
- if(av[0].a_type == A_FLOAT)
- x->x_ls[i].azi = av[pointer].a_w.w_float;
- else {
- post("define-loudspeakers: Error in loudspeaker data!",0);
- newlyread =0;
- return;
+ if (x->x_ls_read)
+ {
+ // Remove old matrices
+ t_ls_set* trip_ptr = x->x_ls_set;
+ while (trip_ptr != NULL)
+ { // remove old matrices
+ t_ls_set* tmp_ptr = trip_ptr;
+ trip_ptr = trip_ptr->next;
+ freebytes(tmp_ptr, sizeof (struct t_ls_set));
}
- pointer++;
- if(x->x_dimension == 3){
-/* if(av[0].a_type == A_LONG)
- x->x_ls[i].ele = (float) av[pointer].a_w.w_long;
- else */
- if(av[0].a_type == A_FLOAT)
- x->x_ls[i].ele = av[pointer].a_w.w_float;
- else {
- post("define-loudspeakers: Error in loudspeaker data!",0);
- newlyread =0;
- return;
- }
- pointer++;
- } else
- x->x_ls[i].ele = 0.0; /* 2-D case */
}
-
- if(newlyread == 1){
- x->x_ls_read = 1; /* preprocess data */
- for(i=0;i<x->x_ls_amount;i++)
- ls_angles_to_cart(&x->x_ls[i]);
- trip_ptr = x->x_ls_set;
- prev = NULL;
- while (trip_ptr != NULL){ /* remove old matrices */
- tmp_ptr = trip_ptr;
- trip_ptr = trip_ptr->next;
- freebytes(tmp_ptr, sizeof (struct t_ls_set));
- }
- x->x_ls_set = NULL;
- }
- x->x_triplets_specified=0;
+ x->x_ls_set = NULL;
+
+ initContent_ls_directions(x,ac,av);
}
/*--------------------------------------------------------------------------*/
void ls_angles_to_cart(t_ls *ls)
-/* convert angular direction to cartesian */
+// convert angular direction to cartesian
{
- float atorad = (2 * 3.1415927 / 360) ;
float azi = ls->azi;
float ele = ls->ele;
ls->x = cos((float) azi * atorad) * cos((float) ele * atorad);
@@ -257,73 +174,92 @@ void ls_angles_to_cart(t_ls *ls)
ls->z = sin((float) ele * atorad);
}
-static void *def_ls_new(t_symbol *s, int ac, t_atom *av) /* create new instance of object... MUST
- send it an int even if you do nothing with this int!! */
+/* create new instance of object... MUST send it an int even if you do nothing with this int!! */
+void *def_ls_new(t_symbol *s, int ac, Atom *av)
{
- long i,pointer;
- t_def_ls *x;
+ // s is object name (we ignore it)
+ t_def_ls *x = (t_def_ls *)newobject(def_ls_class);
- x = (t_def_ls *)pd_new(def_ls_class);
-
+#ifdef PD
+ x->x_outlet0 = outlet_new(&x->x_obj, gensym("list")); /* create a (list) outlet */
+#else /* Max */
+ x->x_outlet0 = outlet_new(x, 0L); /* create a (list) outlet */
+#endif /* PD */
+
+ initContent_ls_directions(x,ac,av); // Initialize object internal data from a ls-directions list
+
+ return x; /* return a reference to the object instance */
+}
+
+/* define-loudspeakers message integrated into vbap object */
+void vbap_def_ls(t_def_ls *x, t_symbol *s, int ac, Atom *av)
+{
+ initContent_ls_directions(x,ac,av); // Initialize object internal data from a ls-directions list
+ def_ls_bang(x); // calculate and send matrix to vbap
+}
+
+/** Initialize the object content from parameters : ls-directions list */
+void initContent_ls_directions(t_def_ls *x,int ac,Atom*av)
+{
x->x_ls_read = 0;
-/* if(av[0].a_type == A_LONG){
- x->x_dimension= av[0].a_w.w_long;
+
+ long d = 0;
+/* if (av[0].a_type == A_LONG) d = av[0].a_w.w_long;
+ else */ if(av[0].a_type == A_FLOAT) d = (long)av[0].a_w.w_float;
+ else { error("define-loudspeakers: dimension NaN"); return; }
+
+ if (d==2 || d==3)
+ {
+ x->x_def_ls_dimension= d;
x->x_ls_read = 1;
- } else */
- if(av[0].a_type == A_FLOAT) {
- x->x_dimension= (int) av[0].a_w.w_float;
- x->x_ls_read = 1;
- } else x->x_dimension= 0;
+ }
+ else
+ {
+ x->x_def_ls_dimension= 0;
+ error("define-loudspeakers: Dimension has to be 2 or 3!");
+ return;
+ }
+
+ int pointer = 1;
+ x->x_def_ls_amount= (ac-1) / (x->x_def_ls_dimension - 1);
+
+ // read loudspeaker direction angles
+ int i;
+ for(i=0; i < x->x_def_ls_amount;i++)
+ {
+ float azi = 0;
+/* if(av[pointer].a_type == A_LONG) azi = (float) av[pointer].a_w.w_long;
+ else */ if(av[pointer].a_type == A_FLOAT) azi = av[pointer].a_w.w_float;
+ else { error("define-loudspeakers: direction angle #%d NaN",i+1); x->x_ls_read = 0; return; }
+
+ x->x_ls[i].azi = azi;
- if(x->x_dimension <2 || x->x_dimension >3){
- post("define-loudspeakers: Dimension has to be 2 or 3!",0);
- return(0);
- }
-
-
- pointer = 1;
- x->x_ls_amount= (ac-1) / (x->x_dimension - 1);
-
- /* read loudspeaker direction angles */
- for(i=0; i < x->x_ls_amount;i++){
-/* if(av[0].a_type == A_LONG)
- x->x_ls[i].azi = (float) av[pointer].a_w.w_long;
- else */
- if(av[0].a_type == A_FLOAT)
- x->x_ls[i].azi = av[pointer].a_w.w_float;
- else {
- post("define-loudspeakers: Error in loudspeaker data!",0);
- x->x_ls_read =0;
- return(0);
- }
pointer++;
- if(x->x_dimension == 3){ /* 3-D */
-/* if(av[0].a_type == A_LONG)
- x->x_ls[i].ele = (float) av[pointer].a_w.w_long;
- else */
- if(av[0].a_type == A_FLOAT)
- x->x_ls[i].ele = av[pointer].a_w.w_float;
- else {
- post("define-loudspeakers: Error in loudspeaker data!",0);
- x->x_ls_read =0;
- return(0);
- }
+
+ float ele = 0; // in 2d elevation is zero
+ if(x->x_def_ls_dimension == 3)
+ { // 3-D
+/* if(av[pointer].a_type == A_LONG) ele = (float) av[pointer].a_w.w_long;
+ else */ if(av[pointer].a_type == A_FLOAT) ele = av[pointer].a_w.w_float;
+ else { error("define-loudspeakers: elevation #%d NaN",i+1); x->x_ls_read = 0; return; }
+
pointer++;
- } else
- x->x_ls[i].ele = 0.0; /* in 2d elevation is zero */
+ }
+ x->x_ls[i].ele = ele;
}
if(x->x_ls_read == 1)
- for(i=0;i<x->x_ls_amount;i++)
+ {
+ int i;
+ for(i=0;i<x->x_def_ls_amount;i++)
+ {
ls_angles_to_cart(&x->x_ls[i]);
+ }
+ }
x->x_triplets_specified=0;
- x->x_outlet0 = outlet_new(&x->x_ob, gensym("list")); /* create a (list) outlet */
x->x_ls_set = NULL;
- return(x); /* return a reference to the object instance */
}
-
-
void choose_ls_triplets(t_def_ls *x)
/* Selects the loudspeaker triplets, and
calculates the inversion matrices for each selected triplet.
@@ -337,28 +273,27 @@ void choose_ls_triplets(t_def_ls *x)
DIVA Project" in International Conference on
Auditory Displays -98.*/
{
- int i,j,k,l,m,li, table_size;
- int *i_ptr;
- t_ls vb1,vb2,tmp_vec;
+ int i,j,k,l,/*m,li,*/ table_size;
+ //int *i_ptr;
+ //t_ls vb1,vb2,tmp_vec;
int connections[MAX_LS_AMOUNT][MAX_LS_AMOUNT];
- float angles[MAX_LS_AMOUNT];
- int sorted_angles[MAX_LS_AMOUNT];
+ //float angles[MAX_LS_AMOUNT];
+ //int sorted_angles[MAX_LS_AMOUNT];
float distance_table[((MAX_LS_AMOUNT * (MAX_LS_AMOUNT - 1)) / 2)];
int distance_table_i[((MAX_LS_AMOUNT * (MAX_LS_AMOUNT - 1)) / 2)];
int distance_table_j[((MAX_LS_AMOUNT * (MAX_LS_AMOUNT - 1)) / 2)];
float distance;
t_ls_set *trip_ptr, *prev, *tmp_ptr;
- int ls_amount = x->x_ls_amount;
+ int ls_amount = x->x_def_ls_amount;
t_ls *lss = x->x_ls;
- if (ls_amount == 0) {
- post("define-loudspeakers: Number of loudspeakers is zero",0);
- return;
- }
-
+ if (ls_amount == 0) { post("define-loudspeakers: Number of loudspeakers is zero"); return; }
+
for(i=0;i<ls_amount;i++)
for(j=i+1;j<ls_amount;j++)
- for(k=j+1;k<ls_amount;k++){
- if(vol_p_side_lgth(i,j,k, x->x_ls) > MIN_VOL_P_SIDE_LGTH){
+ for(k=j+1;k<ls_amount;k++)
+ {
+ if(vol_p_side_lgth(i,j,k, x->x_ls) > MIN_VOL_P_SIDE_LGTH)
+ {
connections[i][j]=1;
connections[j][i]=1;
connections[i][k]=1;
@@ -369,18 +304,23 @@ void choose_ls_triplets(t_def_ls *x)
}
}
+
/*calculate distancies between all lss and sorting them*/
table_size =(((ls_amount - 1) * (ls_amount)) / 2);
for(i=0;i<table_size; i++)
distance_table[i] = 100000.0;
- for(i=0;i<ls_amount;i++){
- for(j=(i+1);j<ls_amount; j++){
- if(connections[i][j] == 1) {
+ for(i=0;i<ls_amount;i++)
+ {
+ for(j=(i+1);j<ls_amount; j++)
+ {
+ if(connections[i][j] == 1)
+ {
distance = fabs(vec_angle(lss[i],lss[j]));
k=0;
while(distance_table[k] < distance)
k++;
- for(l=(table_size - 1);l > k ;l--){
+ for(l=(table_size - 1);l > k ;l--)
+ {
distance_table[l] = distance_table[l-1];
distance_table_i[l] = distance_table_i[l-1];
distance_table_j[l] = distance_table_j[l-1];
@@ -388,55 +328,73 @@ void choose_ls_triplets(t_def_ls *x)
distance_table[k] = distance;
distance_table_i[k] = i;
distance_table_j[k] = j;
- } else
+ }
+ else
+ {
table_size--;
+ }
}
}
/* disconnecting connections which are crossing shorter ones,
starting from shortest one and removing all that cross it,
and proceeding to next shortest */
- for(i=0; i<(table_size); i++){
+ for(i=0; i<(table_size); i++)
+ {
int fst_ls = distance_table_i[i];
- int sec_ls = distance_table_j[i];
+ int sec_ls = distance_table_j[i];
if(connections[fst_ls][sec_ls] == 1)
+ {
for(j=0; j<ls_amount ; j++)
+ {
for(k=j+1; k<ls_amount; k++)
- if( (j!=fst_ls) && (k != sec_ls) && (k!=fst_ls) && (j != sec_ls)){
- if(lines_intersect(fst_ls, sec_ls, j,k,x->x_ls) == 1){
+ {
+ if( (j!=fst_ls) && (k != sec_ls) && (k!=fst_ls) && (j != sec_ls))
+ {
+ if(lines_intersect(fst_ls, sec_ls, j,k,x->x_ls) == 1)
+ {
connections[j][k] = 0;
connections[k][j] = 0;
}
}
+ }
+ }
+ }
}
/* remove triangles which had crossing sides
with smaller triangles or include loudspeakers*/
trip_ptr = x->x_ls_set;
prev = NULL;
- while (trip_ptr != NULL){
+ while (trip_ptr != NULL)
+ {
i = trip_ptr->ls_nos[0];
j = trip_ptr->ls_nos[1];
k = trip_ptr->ls_nos[2];
if(connections[i][j] == 0 ||
connections[i][k] == 0 ||
connections[j][k] == 0 ||
- any_ls_inside_triplet(i,j,k,x->x_ls,ls_amount) == 1 ){
- if(prev != NULL) {
+ any_ls_inside_triplet(i,j,k,x->x_ls,ls_amount) == 1 )
+ {
+ if(prev != NULL)
+ {
prev->next = trip_ptr->next;
tmp_ptr = trip_ptr;
trip_ptr = trip_ptr->next;
freebytes(tmp_ptr, sizeof (struct t_ls_set));
- } else {
+ }
+ else
+ {
x->x_ls_set = trip_ptr->next;
tmp_ptr = trip_ptr;
trip_ptr = trip_ptr->next;
freebytes(tmp_ptr, sizeof (struct t_ls_set));
}
- } else {
+ }
+ else
+ {
prev = trip_ptr;
trip_ptr = trip_ptr->next;
-
}
}
x->x_triplets_specified=1;
@@ -449,7 +407,7 @@ int any_ls_inside_triplet(int a, int b, int c,t_ls lss[MAX_LS_AMOUNT],int ls_amo
float invdet;
t_ls *lp1, *lp2, *lp3;
float invmx[9];
- int i,j,k;
+ int i,j;
float tmp;
int any_ls_inside, this_inside;
@@ -473,10 +431,13 @@ int any_ls_inside_triplet(int a, int b, int c,t_ls lss[MAX_LS_AMOUNT],int ls_amo
invmx[8] = ((lp1->x * lp2->y) - (lp1->y * lp2->x)) * invdet;
any_ls_inside = 0;
- for(i=0; i< ls_amount; i++) {
- if (i != a && i!=b && i != c){
+ for(i=0; i< ls_amount; i++)
+ {
+ if (i != a && i!=b && i != c)
+ {
this_inside = 1;
- for(j=0; j< 3; j++){
+ for(j=0; j< 3; j++)
+ {
tmp = lss[i].x * invmx[0 + j*3];
tmp += lss[i].y * invmx[1 + j*3];
tmp += lss[i].z * invmx[2 + j*3];
@@ -496,12 +457,12 @@ void add_ldsp_triplet(int i, int j, int k, t_def_ls *x)
struct t_ls_set *trip_ptr, *prev;
trip_ptr = x->x_ls_set;
prev = NULL;
- while (trip_ptr != NULL){
+ while (trip_ptr != NULL)
+ {
prev = trip_ptr;
trip_ptr = trip_ptr->next;
}
- trip_ptr = (struct t_ls_set*)
- getbytes (sizeof (struct t_ls_set));
+ trip_ptr = (struct t_ls_set*) getbytes (sizeof (struct t_ls_set));
if(prev == NULL)
x->x_ls_set = trip_ptr;
else
@@ -509,14 +470,14 @@ void add_ldsp_triplet(int i, int j, int k, t_def_ls *x)
trip_ptr->next = NULL;
trip_ptr->ls_nos[0] = i;
trip_ptr->ls_nos[1] = j;
- trip_ptr->ls_nos[2] = k;
+ trip_ptr->ls_nos[2] = k;
}
float vec_angle(t_ls v1, t_ls v2)
-/* angle between two loudspeakers */
+// angle between two loudspeakers
{
float inner= ((v1.x*v2.x + v1.y*v2.y + v1.z*v2.z)/
(vec_length(v1) * vec_length(v2)));
@@ -528,26 +489,27 @@ float vec_angle(t_ls v1, t_ls v2)
}
float vec_length(t_ls v1)
-/* length of a vector */
+// length of a vector
{
return (sqrt(v1.x*v1.x + v1.y*v1.y + v1.z*v1.z));
}
float vec_prod(t_ls v1, t_ls v2)
-/* vector dot product */
+// vector dot product
{
return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
}
-float vol_p_side_lgth(int i, int j,int k, t_ls lss[MAX_LS_AMOUNT] ){
+float vol_p_side_lgth(int i, int j,int k, t_ls lss[MAX_LS_AMOUNT] )
+{
/* calculate volume of the parallelepiped defined by the loudspeaker
direction vectors and divide it with total length of the triangle sides.
This is used when removing too narrow triangles. */
float volper, lgth;
t_ls xprod;
- unq_cross_prod(lss[i], lss[j], &xprod);
+ ls_cross_prod(lss[i], lss[j], &xprod);
volper = fabsf(vec_prod(xprod, lss[k]));
lgth = (fabsf(vec_angle(lss[i],lss[j]))
+ fabsf(vec_angle(lss[i],lss[k]))
@@ -558,14 +520,15 @@ float vol_p_side_lgth(int i, int j,int k, t_ls lss[MAX_LS_AMOUNT] ){
return 0.0;
}
-void unq_cross_prod(t_ls v1,t_ls v2,
+void ls_cross_prod(t_ls v1,t_ls v2,
t_ls *res)
-/* vector cross product */
+// vector cross product
{
float length;
res->x = (v1.y * v2.z ) - (v1.z * v2.y);
res->y = (v1.z * v2.x ) - (v1.x * v2.z);
res->z = (v1.x * v2.y ) - (v1.y * v2.x);
+
length= vec_length(*res);
res->x /= length;
res->y /= length;
@@ -580,13 +543,13 @@ int lines_intersect(int i,int j,int k,int l,t_ls lss[MAX_LS_AMOUNT])
t_ls v1;
t_ls v2;
t_ls v3, neg_v3;
- float angle;
+ //float angle;
float dist_ij,dist_kl,dist_iv3,dist_jv3,dist_inv3,dist_jnv3;
float dist_kv3,dist_lv3,dist_knv3,dist_lnv3;
- unq_cross_prod(lss[i],lss[j],&v1);
- unq_cross_prod(lss[k],lss[l],&v2);
- unq_cross_prod(v1,v2,&v3);
+ ls_cross_prod(lss[i],lss[j],&v1);
+ ls_cross_prod(lss[k],lss[l],&v2);
+ ls_cross_prod(v1,v2,&v3);
neg_v3.x= 0.0 - v3.x;
neg_v3.y= 0.0 - v3.y;
@@ -605,12 +568,12 @@ int lines_intersect(int i,int j,int k,int l,t_ls lss[MAX_LS_AMOUNT])
/* if one of loudspeakers is close to crossing point, don't do anything*/
if(fabsf(dist_iv3) <= 0.01 || fabsf(dist_jv3) <= 0.01 ||
- fabsf(dist_kv3) <= 0.01 || fabsf(dist_lv3) <= 0.01 ||
+ fabsf(dist_kv3) <= 0.01 || fabsf(dist_lv3) <= 0.01 ||
fabsf(dist_inv3) <= 0.01 || fabsf(dist_jnv3) <= 0.01 ||
fabsf(dist_knv3) <= 0.01 || fabsf(dist_lnv3) <= 0.01 )
return(0);
- /* if crossing point is on line between both loudspeakers return 1 */
+ // if crossing point is on line between both loudspeakers return 1
if (((fabsf(dist_ij - (dist_iv3 + dist_jv3)) <= 0.01 ) &&
(fabsf(dist_kl - (dist_kv3 + dist_lv3)) <= 0.01)) ||
((fabsf(dist_ij - (dist_inv3 + dist_jnv3)) <= 0.01) &&
@@ -627,28 +590,30 @@ void calculate_3x3_matrixes(t_def_ls *x)
float invdet;
t_ls *lp1, *lp2, *lp3;
float *invmx;
- float *ptr;
+ //float *ptr;
struct t_ls_set *tr_ptr = x->x_ls_set;
- int triplet_amount = 0, ftable_size,i,j,k, pointer,list_length=0;
- t_atom *at;
+ int triplet_amount = 0, /*ftable_size,*/i,pointer,list_length=0;
+ Atom *at;
t_ls *lss = x->x_ls;
- if (tr_ptr == NULL){
- post("define-loudspeakers: Not valid 3-D configuration\n",1);
+ if (tr_ptr == NULL)
+ {
+ error("define-loudspeakers: Not valid 3-D configuration\n");
return;
}
/* counting triplet amount */
- while(tr_ptr != NULL){
+ while(tr_ptr != NULL)
+ {
triplet_amount++;
tr_ptr = tr_ptr->next;
}
tr_ptr = x->x_ls_set;
- list_length= triplet_amount * 21 + 2; /* was: + 3, pure data doesn't like errors on list_length */
- at= (t_atom *) getbytes(list_length*sizeof(t_atom));
+ list_length= triplet_amount * 21 + 3;
+ at= (Atom *) getbytes(list_length*sizeof(Atom));
- SETFLOAT(&at[0], x->x_dimension);
- SETFLOAT(&at[1], x->x_ls_amount);
+ SETLONG(&at[0], x->x_def_ls_dimension);
+ SETLONG(&at[1], x->x_def_ls_amount);
pointer=2;
while(tr_ptr != NULL){
@@ -672,7 +637,7 @@ void calculate_3x3_matrixes(t_def_ls *x)
invmx[5] = ((lp1->x * lp3->y) - (lp1->y * lp3->x)) * -invdet;
invmx[8] = ((lp1->x * lp2->y) - (lp1->y * lp2->x)) * invdet;
for(i=0;i<3;i++){
- SETFLOAT(&at[pointer], tr_ptr->ls_nos[i]+1);
+ SETLONG(&at[pointer], tr_ptr->ls_nos[i]+1);
pointer++;
}
for(i=0;i<9;i++){
@@ -691,8 +656,9 @@ void calculate_3x3_matrixes(t_def_ls *x)
tr_ptr = tr_ptr->next;
}
- outlet_anything(x->x_outlet0, gensym("loudspeaker-matrices"), list_length, at);
- freebytes(at, list_length*sizeof(t_atom));
+ sendLoudspeakerMatrices(x,list_length, at);
+// outlet_anything(x->x_outlet0, gensym("loudspeaker-matrices"), list_length, at);
+ freebytes(at, list_length*sizeof(Atom));
}
@@ -701,20 +667,21 @@ void choose_ls_tuplets(t_def_ls *x)
/* selects the loudspeaker pairs, calculates the inversion
matrices and stores the data to a global array*/
{
- float atorad = (2 * 3.1415927 / 360) ;
- int i,j,k;
- float w1,w2;
- float p1,p2;
+ //float atorad = (2 * 3.1415927 / 360) ;
+ int i,j;
+ //float w1,w2;
+ //float p1,p2;
int sorted_lss[MAX_LS_AMOUNT];
int exist[MAX_LS_AMOUNT];
int amount=0;
- float inv_mat[MAX_LS_AMOUNT][4]; /* In 2-D ls amount == max amount of LS pairs */
- float *ptr;
- float *ls_table;
+ float inv_mat[MAX_LS_AMOUNT][4]; // In 2-D ls amount == max amount of LS pairs
+ float mat[MAX_LS_AMOUNT][4];
+ //float *ptr;
+ //float *ls_table;
t_ls *lss = x->x_ls;
- long ls_amount=x->x_ls_amount;
+ long ls_amount=x->x_def_ls_amount;
long list_length;
- t_atom *at;
+ Atom *at;
long pointer;
for(i=0;i<MAX_LS_AMOUNT;i++){
@@ -730,69 +697,79 @@ void choose_ls_tuplets(t_def_ls *x)
lss[sorted_lss[i]].azi) <= (180 - 10)){
if (calc_2D_inv_tmatrix( lss[sorted_lss[i]].azi,
lss[sorted_lss[i+1]].azi,
- inv_mat[i]) != 0){
+ inv_mat[i],mat[i]) != 0){
exist[i]=1;
amount++;
}
}
}
- if(((6.283 - lss[sorted_lss[ls_amount-1]].azi)
+ if(((360 - lss[sorted_lss[ls_amount-1]].azi)
+lss[sorted_lss[0]].azi) <= (180 - 10)) {
if(calc_2D_inv_tmatrix(lss[sorted_lss[ls_amount-1]].azi,
lss[sorted_lss[0]].azi,
- inv_mat[ls_amount-1]) != 0) {
+ inv_mat[ls_amount-1],mat[ls_amount-1]) != 0) {
exist[ls_amount-1]=1;
amount++;
}
}
- /* Output */
- list_length= amount * 6 + 2;
- at= (t_atom *) getbytes(list_length*sizeof(t_atom));
+ // Output
+ list_length= amount * 10 + 2;
+ at= (Atom *) getbytes(list_length*sizeof(Atom));
- SETFLOAT(&at[0], x->x_dimension);
- SETFLOAT(&at[1], x->x_ls_amount);
+ SETLONG(&at[0], x->x_def_ls_dimension);
+ SETLONG(&at[1], x->x_def_ls_amount);
pointer=2;
for (i=0;i<ls_amount - 1;i++){
if(exist[i] == 1) {
- SETFLOAT(&at[pointer], sorted_lss[i]+1);
+ SETLONG(&at[pointer], sorted_lss[i]+1);
pointer++;
- SETFLOAT(&at[pointer], sorted_lss[i+1]+1);
+ SETLONG(&at[pointer], sorted_lss[i+1]+1);
pointer++;
for(j=0;j<4;j++) {
SETFLOAT(&at[pointer], inv_mat[i][j]);
pointer++;
}
+ for(j=0;j<4;j++) {
+ SETFLOAT(&at[pointer], mat[i][j]);
+ pointer++;
+ }
}
}
if(exist[ls_amount-1] == 1) {
- SETFLOAT(&at[pointer], sorted_lss[ls_amount-1]+1);
+ SETLONG(&at[pointer], sorted_lss[ls_amount-1]+1);
pointer++;
- SETFLOAT(&at[pointer], sorted_lss[0]+1);
+ SETLONG(&at[pointer], sorted_lss[0]+1);
pointer++;
for(j=0;j<4;j++) {
SETFLOAT(&at[pointer], inv_mat[ls_amount-1][j]);
pointer++;
}
+ for(j=0;j<4;j++) {
+ SETFLOAT(&at[pointer], mat[ls_amount-1][j]);
+ pointer++;
+ }
}
- outlet_anything(x->x_outlet0, gensym("loudspeaker-matrices"), list_length, at);
- freebytes(at, list_length*sizeof(t_atom));
+ sendLoudspeakerMatrices(x,list_length, at);
+ //outlet_anything(x->x_outlet0, gensym("loudspeaker-matrices"), list_length, at);
+ freebytes(at, list_length*sizeof(Atom));
}
void sort_2D_lss(t_ls lss[MAX_LS_AMOUNT], int sorted_lss[MAX_LS_AMOUNT],
int ls_amount)
-/* sort loudspeakers according to azimuth angle */
+// sort loudspeakers according to azimuth angle
{
- int i,j,index;
float tmp, tmp_azi;
- float rad2ang = 360.0 / ( 2 * 3.141592 );
+// float rad2ang = 360.0f / ( 2.0f * M_PI );
- float x,y;
+ //float x,y;
/* Transforming angles between -180 and 180 */
- for (i=0;i<ls_amount;i++) {
+ int i;
+ for (i=0;i<ls_amount;i++)
+ {
ls_angles_to_cart(&lss[i]);
lss[i].azi = acos( lss[i].x) * rad2ang;
if (fabs(lss[i].y) <= 0.001)
@@ -801,10 +778,15 @@ void sort_2D_lss(t_ls lss[MAX_LS_AMOUNT], int sorted_lss[MAX_LS_AMOUNT],
tmp = lss[i].y / fabs(lss[i].y);
lss[i].azi *= tmp;
}
- for (i=0;i<ls_amount;i++){
+for (i=0;i<ls_amount;i++)
+ {
tmp = 2000;
- for (j=0 ; j<ls_amount;j++){
- if (lss[j].azi <= tmp){
+ int index = 0;
+ int j;
+ for (j=0 ; j<ls_amount;j++)
+ {
+ if (lss[j].azi <= tmp)
+ {
tmp=lss[j].azi;
index = j;
}
@@ -813,25 +795,25 @@ void sort_2D_lss(t_ls lss[MAX_LS_AMOUNT], int sorted_lss[MAX_LS_AMOUNT],
tmp_azi = (lss[index].azi);
lss[index].azi = (tmp_azi + (float) 4000.0);
}
- for (i=0;i<ls_amount;i++) {
+ for (i=0;i<ls_amount;i++)
+ {
tmp_azi = (lss[i].azi);
lss[i].azi = (tmp_azi - (float) 4000.0);
}
}
-int calc_2D_inv_tmatrix(float azi1,float azi2, float inv_mat[4])
-/* calculate inverse 2x2 matrix */
+int calc_2D_inv_tmatrix(float azi1,float azi2, float inv_mat[4],float mat[4])
+// calculate inverse 2x2 matrix
{
float x1,x2,x3,x4; /* x1 x3 */
- float y1,y2,y3,y4; /* x2 x4 */
+ //float y1,y2,y3,y4; /* x2 x4 */
float det;
- float rad2ang = 360.0 / ( 2 * 3.141592 );
- x1 = cos(azi1 / rad2ang);
- x2 = sin(azi1 / rad2ang);
- x3 = cos(azi2 / rad2ang);
- x4 = sin(azi2 / rad2ang);
+ mat[0]=x1 = cos(azi1 / rad2ang);
+ mat[1]=x2 = sin(azi1 / rad2ang);
+ mat[2]=x3 = cos(azi2 / rad2ang);
+ mat[3]=x4 = sin(azi2 / rad2ang);
det = (x1 * x4) - ( x3 * x2 );
if(fabsf(det) <= 0.001) {
@@ -848,5 +830,3 @@ int calc_2D_inv_tmatrix(float azi1,float azi2, float inv_mat[4])
return 1;
}
}
-
-