Exemple #1
0
void choose_ls_triplets(ls lss[MAX_LS_AMOUNT],   
			struct ls_triplet_chain **ls_triplets, int ls_amount) 
     /* Selects the loudspeaker triplets, and
      calculates the inversion matrices for each selected triplet.
     A line (connection) is drawn between each loudspeaker. The lines
     denote the sides of the triangles. The triangles should not be 
     intersecting. All crossing connections are searched and the 
     longer connection is erased. This yields non-intesecting triangles,
     which can be used in panning.*/
{
  int i,j,k,l,m,li, table_size;
  int *i_ptr;
  cart_vec vb1,vb2,tmp_vec;
  int connections[MAX_LS_AMOUNT][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;
  struct ls_triplet_chain *trip_ptr, *prev, *tmp_ptr;

  if (ls_amount == 0) {
    fprintf(stderr,"Number of loudspeakers is zero\nExiting\n");
    exit(-1);
  }
  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, lss) > MIN_VOL_P_SIDE_LGTH){
	  connections[i][j]=1;
	  connections[j][i]=1;
	  connections[i][k]=1;
	  connections[k][i]=1;
	  connections[j][k]=1;
	  connections[k][j]=1;
	  add_ldsp_triplet(i,j,k,ls_triplets, lss);
	}
      }
  /*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) {
	distance = fabs(vec_angle(lss[i].coords,lss[j].coords));
	k=0;
	while(distance_table[k] < distance)
	  k++;
	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];
	}
	distance_table[k] = distance;
	distance_table_i[k] = i;
	distance_table_j[k] = j;
      } 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++){
    int fst_ls = distance_table_i[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,lss) == 1){
	      connections[j][k] = 0;
	      connections[k][j] = 0;
	    }
	  }
  }

  /* remove triangles which had crossing sides
     with smaller triangles or include loudspeakers*/
  trip_ptr = *ls_triplets;
  prev = 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,lss,ls_amount) == 1 ){
      if(prev != NULL) {
	prev->next = trip_ptr->next;
	tmp_ptr = trip_ptr;
	trip_ptr = trip_ptr->next;
	free(tmp_ptr);
      } else {
	*ls_triplets = trip_ptr->next;
	tmp_ptr = trip_ptr;
	trip_ptr = trip_ptr->next;
	free(tmp_ptr);
      }
    } else {
      prev = trip_ptr;
      trip_ptr = trip_ptr->next;

    }
  }
}
static void choose_ls_triplets(t_def_ls *x) 
     /* Selects the loudspeaker triplets, and
      calculates the inversion matrices for each selected triplet.
     A line (connection) is drawn between each loudspeaker. The lines
     denote the sides of the triangles. The triangles should not be 
     intersecting. All crossing connections are searched and the 
     longer connection is erased. This yields non-intesecting triangles,
     which can be used in panning. 
     See theory in paper Pulkki, V. Lokki, T. "Creating Auditory Displays
     with Multiple Loudspeakers Using VBAP: A Case Study with
     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 connections[MAX_LS_AMOUNT][MAX_LS_AMOUNT];
  //float angles[MAX_LS_AMOUNT];
  //int sorted_angles[MAX_LS_AMOUNT];
  t_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)];
  t_float distance;
  t_ls_set *trip_ptr, *prev, *tmp_ptr;
  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"); 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)
				{
          connections[i][j]=1;
          connections[j][i]=1;
          connections[i][k]=1;
          connections[k][i]=1;
          connections[j][k]=1;
          connections[k][j]=1;
          add_ldsp_triplet(i,j,k,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) 
		  {
        distance = fabs(vec_angle(lss[i],lss[j]));
        k=0;
        while(distance_table[k] < distance)
          k++;
        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];
        }
        distance_table[k] = distance;
        distance_table_i[k] = i;
        distance_table_j[k] = j;
      } 
			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++)
	{
    int fst_ls = distance_table_i[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)
						{
              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)
	{
    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) 
			{
        prev->next = trip_ptr->next;
        tmp_ptr = trip_ptr;
        trip_ptr = trip_ptr->next;
        freebytes(tmp_ptr, sizeof (struct t_ls_set));
      } 
			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 
		{
      prev = trip_ptr;
      trip_ptr = trip_ptr->next;
    }
  }
  x->x_triplets_specified=1;
}