Jamoma API  0.6.0.a19
j.dbap.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationMaxExternals
4  *
5  * @brief j.dbap - Distance Based Amplitude Panning
6  *
7  * @details
8  *
9  * @authors Trond Lossius, Tim Place, Théo de la Hogue
10  *
11  * @copyright Copyright © 2009, Trond Lossius @n
12  * This code is licensed under the terms of the "New BSD License" @n
13  * http://creativecommons.org/licenses/BSD/
14  */
15 
16 
17 #include "JamomaForMax.h"
18 #include "j.dbap.h"
19 
20 // Globals
21 t_class *this_class = 0; // Required. Global pointing to this class
22 t_object *dummy = NULL;
23 
24 /************************************************************************************/
25 // Main() Function
26 
27 int JAMOMA_EXPORT_MAXOBJ main(void)
28 {
29  t_class *c;
30 
31  common_symbols_init();
32 
33  ps_rolloff = gensym("rolloff");
34  ps_src_position = gensym("src_position");
35  ps_src_gain = gensym("src_gain");
36  ps_src_mute = gensym("src_mute");
37  ps_src_blur = gensym("blur");
38  ps_dst_position = gensym("dst_position");
39  ps_dimensions = gensym("dimensions");
40  ps_num_sources = gensym("num_sources");
41  ps_num_destinations = gensym("num_destinations");
42  ps_jit_matrix = gensym("jit_matrix");
43  ps_getdata = gensym("getdata");
44  ps_setinfo = gensym("setinfo");
45 
46 
47  // Define our class
48  c = class_new("j.dbap",
49  (method)dbap_new,
50  (method)dbap_free,
51  sizeof(t_dbap),
52  (method)NULL,
53  A_GIMME,
54  0);
55 
56  // Make methods accessible for our class:
57  class_addmethod(c, (method)dbap_blur, "blur", A_GIMME, 0);
58  class_addmethod(c, (method)dbap_blurall, "blurall", A_FLOAT, 0);
59  class_addmethod(c, (method)dbap_source, "src_position", A_GIMME, 0);
60  class_addmethod(c, (method)dbap_destination, "dst_position", A_GIMME, 0);
61  class_addmethod(c, (method)dbap_sourcegain, "src_gain", A_GIMME, 0);
62  class_addmethod(c, (method)dbap_sourceweight, "src_weight", A_GIMME, 0);
63  class_addmethod(c, (method)dbap_mastergain, "master_gain", A_FLOAT, 0);
64  class_addmethod(c, (method)dbap_sourcemute, "src_mute", A_GIMME, 0);
65 
66  class_addmethod(c, (method)dbap_hull, "hull", A_LONG, 0);
67 
68  class_addmethod(c, (method)dbap_view, "view", A_GIMME, 0);
69  class_addmethod(c, (method)dbap_view_update, "view_update", A_LONG, 0);
70  class_addmethod(c, (method)dbap_view_size, "view_size", A_LONG, A_LONG, 0);
71  class_addmethod(c, (method)dbap_view_start, "view_start", A_GIMME, 0);
72  class_addmethod(c, (method)dbap_view_end, "view_end", A_GIMME, 0);
73 
74  class_addmethod(c, (method)dbap_assist, "assist", A_CANT, 0);
75  class_addmethod(c, (method)dbap_info, "info", 0);
76  class_addmethod(c, (method)object_obex_dumpout, "dumpout", 0);
77 
78  // Add attributes to our class:
79  CLASS_ATTR_LONG(c, "dimensions", 0, t_dbap, attr_dimensions);
80  CLASS_ATTR_ACCESSORS(c, "dimensions", NULL, dbap_attr_setdimensions);
81  CLASS_ATTR_ENUM(c, "dimensions", 0, "1 2 3");
82 
83  CLASS_ATTR_LONG(c, "num_sources", 0, t_dbap, attr_num_sources);
84  CLASS_ATTR_ACCESSORS(c, "num_sources", NULL, dbap_attr_setnum_sources);
85 
86  CLASS_ATTR_LONG(c, "num_destinations", 0, t_dbap, attr_num_destinations);
87  CLASS_ATTR_ACCESSORS(c, "num_destinations", NULL, dbap_attr_setnum_destinations);
88 
89  CLASS_ATTR_DOUBLE(c, "rolloff", 0, t_dbap, attr_rolloff);
90  CLASS_ATTR_ACCESSORS(c, "rolloff", (method)NULL, (method)dbap_attr_setrolloff);
91 
92  // Finalize our class
93  class_register(CLASS_BOX, c);
94  this_class = c;
95 
96  // Initialize Jitter by creating a dummy matrix
97  jamoma_loadextern(gensym("jit.matrix"), 0, NULL, &dummy);
98 
99  return 0;
100 }
101 
102 
103 /************************************************************************************/
104 // Object Life
105 #pragma mark -
106 #pragma mark object life
107 
108 void *dbap_new(t_symbol *msg, long argc, t_atom *argv)
109 {
110  t_dbap *x;
111  long i,j;
112 
113  x = (t_dbap *)object_alloc(this_class); // create the new instance and return a pointer to it
114 
115  if (x) {
116  object_obex_store(x, _sym_dumpout, (object *)outlet_new(x,NULL)); // dumpout
117  x->outlet[2] = outlet_new(x, 0); // Third outlet: Visualization data
118  x->outlet[1] = outlet_new(x, 0); // Middle outlet: Distance from convex hull
119  x->outlet[0] = outlet_new(x, 0); // Left outlet: Feed to matrix~
120 
121  // Initializing and setting defaults for attributes.
122  x->master_gain = 1.; // default value
123  x->attr_num_sources = 1; // default value
124  x->attr_num_destinations = 1; // default value
125  x->attr_dimensions = 2; // two-dimensional by default
126  x->attr_rolloff = 6.; // 6 dB rolloff by default
127 
128  x->attr_view_update = false;
129  atom_setsym(&x->last_view[0],gensym("all"));
130  atom_setlong(&x->last_view[1],1);
131 
132  x->attr_view_start.x = 0.; // default value
133  x->attr_view_start.y = 0.; // default value
134  x->attr_view_start.z = 0.; // default value
135  x->attr_view_end.x = 22.; // according to the dbap maxhelp space
136  x->attr_view_end.y = 15.; // according to the dbap maxhelp space
137  x->attr_view_end.z = 0.; // according to the dbap maxhelp space
138 
139  // prepare a jit_matrix_info, an unique name and an empty jit_matrix
140  jit_matrix_info_default(&x->view_info);
141  x->view_info.type = gensym("char");
142  x->view_info.planecount = 1;
143  x->view_info.dimcount = 2;
144  x->view_info.dim[0] = 80; // x size of the view matrix
145  x->view_info.dim[1] = 60; // y size of the view matrix
146  x->view_matrix = jit_object_new(ps_jit_matrix, &x->view_info);
147  x->view_name = jit_symbol_unique();
148  x->view_matrix = jit_object_register(x->view_matrix, x->view_name);
149 
150  for (i=0; i<MAX_NUM_SOURCES; i++) {
151  x->src_position[i].x = 0.;
152  x->src_position[i].y = 0.;
153  x->src_position[i].z = 0.;
154  x->blur[i] = 0.000001;
155  x->src_gain[i] = 1.0;
156  x->src_not_muted[i] = 1.0;
157  }
158 
159  for (i=0; i<MAX_NUM_DESTINATIONS; i++) {
160  x->dst_position[i].x = 0.;
161  x->dst_position[i].y = 0.;
162  x->dst_position[i].z = 0.;
163  }
164 
165  for (i=0;i<MAX_NUM_WEIGHTED_SOURCES;i++) {
166  for (j=0;j<MAX_NUM_WEIGHTED_DESTINATIONS;j++) {
167  x->src_weight[i][j] = 1.;
168  }
169  }
170 
171  x->hull_io = false;
172 
173  x->hull1.min = 0.0;
174  x->hull1.max = 0.0;
175 
176  x->hull2.num_dst = 0;
177 
178  attr_args_process(x, argc, argv); // handle attribute args
179  dbap_calculate_a(x); // calculate exponent coefficient used for rolloff
180  dbap_calculate_variance(x); // this implicitly also calculates all matrix values
181  }
182  return (x); // return the pointer
183 }
184 
185 void dbap_free(t_dbap *x)
186 {
187  // forget the matrix
188  jit_object_unregister(x->view_matrix);
189 
190  // free the matrix
191  jit_object_free(x->view_matrix);
192 }
193 
194 /********************************************************************************************/
195 // Methods bound to input/inlets
196 
197 #pragma mark -
198 #pragma mark methods
199 
200 
201 // set spatial blur for nth source
202 void dbap_blur(t_dbap *x, t_symbol *msg, long argc, t_atom *argv)
203 {
204  long n;
205  double f;
206 
207  if ((argc>=2) && argv) {
208  n = atom_getlong(argv)-1; // we start counting from 1 for sources
209  if ( (n<0) || (n>=MAX_NUM_SOURCES) ) {
210  error("Invalid argument(s) for blur");
211  return;
212  }
213  argv++;
214  f = atom_getfloat(argv);
215  if (f<0.000001)
216  f = 0.000001;
217  x->blur[n] = f;
218  dbap_calculate(x, n);
219  dbap_update_view(x);
220  }
221  else
222  error("Invalid argument(s) for blur");
223 }
224 
225 // set spatial blur for all sources
226 void dbap_blurall(t_dbap *x, double f)
227 {
228  long i;
229 
230  if (f<0.000001)
231  f = 0.000001;
232  for (i=0; i<x->attr_num_sources; i++) {
233  x->blur[i] = f;
234  dbap_calculate(x, i);
235  }
236  dbap_update_view(x);
237 }
238 
239 // set source position and calculate output
240 void dbap_source(t_dbap *x, void *msg, long argc, t_atom *argv)
241 {
242  long n;
243 
244  if (argc >= (x->attr_dimensions + 1)) {
245  n = atom_getlong(argv)-1; // we start counting from 1 for sources
246  if ( (n<0) || (n>=MAX_NUM_SOURCES) ) {
247  error("Invalid arguments for source.");
248  return;
249  }
250  switch (x->attr_dimensions)
251  {
252  case 1:
253  x->src_position[n].x = atom_getfloat(argv+1);
254  break;
255  case 2:
256  x->src_position[n].x = atom_getfloat(argv+1);
257  x->src_position[n].y = atom_getfloat(argv+2);
258  break;
259  case 3:
260  x->src_position[n].x = atom_getfloat(argv+1);
261  x->src_position[n].y = atom_getfloat(argv+2);
262  x->src_position[n].z = atom_getfloat(argv+3);
263  break;
264  }
265  dbap_calculate(x, n);
266  }
267  else
268  error("Invalid arguments for source.");
269 }
270 
271 
272 // set position of a destination
273 void dbap_destination(t_dbap *x, void *msg, long argc, t_atom *argv)
274 {
275  long n;
276 
277  if (argc >= (x->attr_dimensions + 1)) {
278  n = atom_getlong(argv)-1; // we start counting from 1 for destinations
279  if ( (n<0) || (n>=MAX_NUM_DESTINATIONS) ) {
280  error("Invalid arguments for destination.");
281  return;
282  }
283  switch (x->attr_dimensions)
284  {
285  case 1:
286  x->dst_position[n].x = atom_getfloat(argv+1);
287  break;
288  case 2:
289  x->dst_position[n].x = atom_getfloat(argv+1);
290  x->dst_position[n].y = atom_getfloat(argv+2);
291  break;
292  case 3:
293  x->dst_position[n].x = atom_getfloat(argv+1);
294  x->dst_position[n].y = atom_getfloat(argv+2);
295  x->dst_position[n].z = atom_getfloat(argv+3);
296  break;
297  }
298  // The set of destination points has been changed - recalculate variance.
299  dbap_calculate_variance(x); // implicitely updates all matrix values
300  if (x->hull_io) dbap_calculate_hull(x,n); // implicitely updates the hull
301  dbap_update_view(x); // implicitely updates the view
302  }
303  else
304  error("Invalid arguments for speaker.");
305 }
306 
307 
308 void dbap_sourcegain(t_dbap *x, void *msg, long argc, t_atom *argv)
309 {
310  long n;
311  double f;
312 
313  if ((argc>=2) && argv) {
314  n = atom_getlong(argv)-1; // we start counting from 1 for sources
315  if ( (n<0) || (n>=MAX_NUM_SOURCES) ) {
316  error("Invalid argument(s) for source_gain");
317  return;
318  }
319  argv++;
320  f = atom_getfloat(argv);
321  if (f<0.0)
322  f = 0.0;
323  x->src_gain[n] = f;
324  dbap_calculate(x, n);
325  }
326  else
327  error("Invalid argument(s) for source_gain");
328 }
329 
330 
331 
332 void dbap_mastergain(t_dbap *x, double f)
333 {
334  long i;
335 
336  x->master_gain = f;
337  if (x->master_gain<0.)
338  x->master_gain = 0;
339 
340  // Update all matrix values
341  for (i=0; i<x->attr_num_sources; i++)
342  dbap_calculate(x, i);
343 }
344 
345 void dbap_sourceweight(t_dbap *x, t_symbol *msg, long argc, t_atom *argv)
346 {
347  long source, i;
348  double weight;
349 
350  if (argc && argv) {
351 
352  if (atom_gettype(argv) == A_LONG) { // the first argument is the source number
353  source = atom_getlong(argv)-1; // we start counting from 1 for sources
354 
355  if ((source < 0)||(source >= x->attr_num_sources)) {
356  object_error((t_object*)x, "src_weight : the source n°%d doesn't exist", source+1);
357  return;
358  }
359  }
360  else {
361  object_error((t_object*)x, "src_weight : no source id");
362  return;
363  }
364 
365  for (i=0; i<x->attr_num_destinations; i++) { // the rest is the list of weights for each destination
366 
367  if (i+1 < argc) {
368  if (atom_gettype(&argv[i+1]) == A_LONG)
369  weight = (float)atom_getlong(&argv[i+1]);
370 
371  if (atom_gettype(&argv[i+1]) == A_FLOAT)
372  weight = atom_getfloat(&argv[i+1]);
373  }
374  else
375  weight = 0.0; // if the list is smaller than the src_weight array, fill src_weight with 0.0
376 
377  if (weight < 0.0)
378  weight = 0.0;
379 
380  x->src_weight[source][i] = weight;
381  }
382 
383  dbap_calculate(x, source);
384  dbap_update_view(x);
385  }
386  else
387  object_error((t_object*)x, "src_weight : needs arguments");
388 }
389 
390 void dbap_sourcemute(t_dbap *x, void *msg, long argc, t_atom *argv)
391 {
392  long n;
393 
394  if ((argc>=2) && argv) {
395  n = atom_getlong(argv)-1; // we start counting from 1 for sources
396  if ( (n<0) || (n>=MAX_NUM_SOURCES) ) {
397  error("Invalid argument(s) for source_mute");
398  return;
399  }
400  argv++;
401  x->src_not_muted[n] = (atom_getfloat(argv)==0.0);
402  dbap_calculate(x, n);
403  }
404  else
405  error("Invalid argument(s) for source_mute");
406 }
407 
408 /** Turn on/off the calculation of distance to hull */
409 void dbap_hull(t_dbap *x, long f)
410 {
411  bool refresh = false;
412 
413  x->hull_io = f > 0;
414 
415  // Has the hull been built?
416  if (x->hull_io) {
417  if (x->attr_dimensions == 1) {
418  if ((x->hull1.min == 0.)&&(x->hull1.max == 0.)) refresh = true;
419  }
420  else if (x->attr_dimensions == 2) {
421  if (x->hull2.num_dst == 0) refresh = true;
422  }
423  }
424  if (refresh) dbap_calculate_hull(x,1); //It's the same hull for all sources
425  //TODO : a hull for each source
426 }
427 
428 /** Display a hitmap view of the dbap for a destination and a source weight config or all (on the info outlet ?) */
429 void dbap_view(t_dbap *x, void *msg, long argc, t_atom *argv)
430 {
431  long dst, src,i;
432  t_symbol *all;
433 
434  // clear the view matrix
435  jit_object_method(x->view_matrix, _sym_clear);
436 
437  if ((argc==2) && argv) {
438  if ((atom_gettype(argv) == A_LONG) && (atom_gettype(argv+1) == A_LONG)) {
439  dst = atom_getlong(argv)-1; // we start counting from 1 for destinations
440  src = atom_getlong(argv+1)-1; // we start counting from 1 for sources
441  if ((src<0) || (src>=MAX_NUM_SOURCES) || (dst<0) || (dst>=MAX_NUM_DESTINATIONS)) {
442  error("Invalid argument(s) for view");
443  return;
444  }
445  dbap_calculate_view(x,dst,src);
446  }
447  else {
448  if ((atom_gettype(argv) == A_SYM) && (atom_gettype(argv+1) == A_LONG)) {
449  all = atom_getsym(argv);
450  src = atom_getlong(argv+1)-1; // we start counting from 1 for sources
451  if ((src<0) || (src>=MAX_NUM_SOURCES) || (all != gensym("all"))) {
452  error("Invalid argument(s) for view");
453  return;
454  }
455 
456  // Calculation for each non-zero weighted dst
457  for (i=0; i<x->attr_num_destinations; i++) {
458  if (x->src_weight[src][i] > 0)
459  dbap_calculate_view(x,i,src);
460  }
461  }
462  }
463 
464  dbap_output_view(x);
465 
466  // and we store the view for a later update process
467  x->last_view[0] = argv[0];
468  x->last_view[1] = argv[1];
469  }
470  else
471  error("Invalid argument(s) for view");
472 }
473 
474 /** Turn on/off the auto view updating */
475 void dbap_view_update(t_dbap *x, long io)
476 {
477  x->attr_view_update = io > 0;
478 
479  dbap_update_view(x);
480 }
481 
482 /** Set the size of hitmap view window */
483 void dbap_view_size(t_dbap *x, long sizeX, long sizeY) {
484 
485  if ((sizeX > 0)&&(sizeY > 0)) {
486 
487  // warn the user that large dimension while take a long to render
488  if ((sizeX > MAX_SIZE_VIEW_X)||(sizeY > MAX_SIZE_VIEW_Y))
489  object_warn((t_object*)x, "size over %d x %d takes time to render", MAX_SIZE_VIEW_X, MAX_SIZE_VIEW_Y);
490 
491  x->view_info.dim[0] = sizeX;
492  x->view_info.dim[1] = sizeY;
493 
494  // prepare the jit_matrix with the new jit_matrix_info
495  jit_object_method(x->view_matrix, ps_setinfo, &x->view_info);
496 
497  dbap_update_view(x);
498  }
499  else
500  error("Invalid argument(s) for view_size");
501 }
502 
503 /** Set the start point of the hitmap view window */
504 void dbap_view_start(t_dbap *x, void *msg, long argc, t_atom *argv) {
505 
506  if ((argc == x->attr_dimensions) && argv) {
507  if (atom_gettype(argv) == A_FLOAT)
508  x->attr_view_start.x = atom_getfloat(argv);
509  else {
510  dbap_update_view(x);
511  return;
512  }
513 
514  if (atom_gettype(argv+1) == A_FLOAT)
515  x->attr_view_start.y = atom_getfloat(argv+1);
516  else {
517  dbap_update_view(x);
518  return;
519  }
520 
521  if (atom_gettype(argv+2) == A_FLOAT)
522  x->attr_view_start.z = atom_getfloat(argv+2);
523  else {
524  dbap_update_view(x);
525  return;
526  }
527  }
528  else
529  error("Invalid argument(s) for view_start");
530 }
531 
532 /** Set the end point of the hitmap view window */
533 void dbap_view_end(t_dbap *x, void *msg, long argc, t_atom *argv) {
534 
535  if ((argc == x->attr_dimensions) && argv) {
536  if (atom_gettype(argv) == A_FLOAT)
537  x->attr_view_end.x = atom_getfloat(argv);
538  else {
539  dbap_update_view(x);
540  return;
541  }
542 
543  if (atom_gettype(argv+1) == A_FLOAT)
544  x->attr_view_end.y = atom_getfloat(argv+1);
545  else {
546  dbap_update_view(x);
547  return;
548  }
549 
550  if (atom_gettype(argv+2) == A_FLOAT)
551  x->attr_view_end.z = atom_getfloat(argv+2);
552  else {
553  dbap_update_view(x);
554  return;
555  }
556  }
557  else
558  error("Invalid argument(s) for view_end");
559 }
560 
561 void dbap_info(t_dbap *x)
562 {
563  t_atom a[4];
564  long i;
565 
566  atom_setfloat(&a[0], x->attr_rolloff);
567  object_obex_dumpout(x, ps_rolloff, 1, a);
568 
569  atom_setlong(&a[0], x->attr_dimensions);
570  object_obex_dumpout(x, ps_dimensions, 1, a);
571 
572  atom_setlong(&a[0], x->attr_num_sources);
573  object_obex_dumpout(x, ps_num_sources, 1, a);
574 
575  for (i=0; i<x->attr_num_sources; i++) {
576  atom_setlong(&a[0], i+1);
577  atom_setfloat(&a[1], x->src_position[i].x);
578  atom_setfloat(&a[2], x->src_position[i].y);
579  atom_setfloat(&a[3], x->src_position[i].z);
580  object_obex_dumpout(x, ps_src_position, x->attr_dimensions+1, a);
581  atom_setfloat(&a[1], x->src_gain[i]);
582  object_obex_dumpout(x, ps_src_gain, 2, a);
583  atom_setlong(&a[1], (x->src_not_muted[i]==0));
584  object_obex_dumpout(x, ps_src_mute, 2, a);
585  atom_setfloat(&a[1], x->blur[i]);
586  object_obex_dumpout(x, ps_src_blur, 2, a);
587  }
588 
589  atom_setlong(&a[0], x->attr_num_destinations);
590  object_obex_dumpout(x, ps_num_destinations, 1, a);
591 
592  for (i=0; i<x->attr_num_destinations; i++) {
593  atom_setlong(&a[0], i+1);
594  atom_setfloat(&a[1], x->dst_position[i].x);
595  atom_setfloat(&a[2], x->dst_position[i].y);
596  atom_setfloat(&a[3], x->dst_position[i].z);
597  object_obex_dumpout(x, ps_dst_position, x->attr_dimensions+1, a);
598  }
599 }
600 
601 
602 // Method for Assistance Messages
603 void dbap_assist(t_dbap *x, void *b, long msg, long arg, char *dst) // Display assistance messages
604 {
605  if (msg==1)
606  {
607  switch(arg)
608  {
609  case 0:
610  strcpy(dst, "set source and speaker positions");
611  break;
612  }
613  }
614  else if (msg==2)
615  {
616  switch(arg)
617  {
618  case 0:
619  strcpy(dst, "(list) messages for matrix~");
620  break;
621  case 1:
622  strcpy(dst, "(list) distance from convex hull");
623  break;
624  case 2:
625  strcpy(dst, "(jit_matrix) visualization");
626  break;
627  case 3:
628  strcpy(dst, "dumpout");
629  break;
630  }
631  }
632 }
633 
634 
635 /************************************************************************************/
636 // Methods bound to attributes
637 #pragma mark -
638 #pragma mark attribute accessors
639 
640 // ATTRIBUTE: dimensions (1-3)
641 t_max_err dbap_attr_setdimensions(t_dbap *x, void *attr, long argc, t_atom *argv)
642 {
643  long n;
644 
645  if (argc && argv) {
646  n = atom_getlong(argv);
647  if (n<1) n = 1;
648  if (n>3) n = 3;
649  x->attr_dimensions = n;
650  }
651 
652  return MAX_ERR_NONE;
653 }
654 
655 
656 // ATTRIBUTE: number of sources
657 t_max_err dbap_attr_setnum_sources(t_dbap *x, void *attr, long argc, t_atom *argv)
658 {
659  long n;
660 
661  if (argc && argv) {
662  n = atom_getlong(argv);
663  if (n<0)
664  n = 0;
665  if (n>MAX_NUM_SOURCES)
666  n = MAX_NUM_SOURCES;
667  x->attr_num_sources = n;
668  }
669  return MAX_ERR_NONE;
670 }
671 
672 // ATTRIBUTE: number of destinations
673 t_max_err dbap_attr_setnum_destinations(t_dbap *x, void *attr, long argc, t_atom *argv)
674 {
675  long n;
676 
677  if (argc && argv) {
678  n = atom_getlong(argv);
679  if (n<0)
680  n = 0;
681  if (n>MAX_NUM_DESTINATIONS)
682  n = MAX_NUM_DESTINATIONS;
683  x->attr_num_destinations = n;
684  // The set of destination points has been changed - recalculate blur radius.
686  }
687  return MAX_ERR_NONE;
688 }
689 
690 
691 // ATTRIBUTE: rolloff
692 t_max_err dbap_attr_setrolloff(t_dbap *x, void *attr, long argc, t_atom *argv)
693 {
694  double f;
695  long i;
696 
697  if (argc && argv) {
698  f = atom_getfloat(argv);
699  if (f<=0.0) {
700  error("Invalid argument for rolloff. Must be > 0");
701  return MAX_ERR_NONE;
702  }
703  x->attr_rolloff = f;
704  dbap_calculate_a(x);
705  dbap_update_view(x);
706  // Update all matrix values
707  for (i=0; i<x->attr_num_sources; i++)
708  dbap_calculate(x, i);
709  }
710  return MAX_ERR_NONE;
711 }
712 
713 
714 
715 /************************************************************************************/
716 // Methods bound to calculations
717 #pragma mark -
718 #pragma mark calculations
719 
720 
721 void dbap_calculate(t_dbap *x, long n)
722 {
723  // Update all matrix values
724  if (x->attr_dimensions == 1)
725  dbap_calculate1D(x, n);
726 
727  else if (x->attr_dimensions == 2)
728  dbap_calculate2D(x, n);
729 
730  else
731  dbap_calculate3D(x, n);
732 }
733 
734 
735 void dbap_calculate1D(t_dbap *x, long n)
736 {
737  double xPos; // x-position of the source
738  double dist; // Distance from source to convex hull
739  double k; // Scaling coefficient
740  double k2inv; // Inverse square of the scaling constant k
741  double dx; // Distance vector
742  double r2; // Bluriness ratio
743  double dia[MAX_NUM_DESTINATIONS]; // Distance to ith speaker to the power of x->a.
744  t_atom a[3]; // Output array of atoms
745  long i;
746 
747  xPos = x->src_position[n].x;
748 
749  // Calculate distance from convex hull and project position onto convex hull)
750  if (x->hull_io) {
751  if (xPos < x->hull1.min) {
752  dist = x->hull1.min - xPos;
753  xPos = x->hull1.min;
754  }
755  else if (xPos > x->hull1.max) {
756  dist = xPos - x->hull1.max;
757  xPos = x->hull1.max;
758  }
759  else
760  dist = 0.0;
761 
762  atom_setlong(&a[0], n);
763  atom_setfloat(&a[1], dist);
764  outlet_anything(x->outlet[1], _sym_list, 2, a);
765  }
766 
767  r2 = x->blur[n] * x->variance;
768  r2 = r2*r2;
769  k2inv = 0;
770  for (i=0; i<x->attr_num_destinations; i++) {
771  dx = xPos - x->dst_position[i].x;
772  dia[i] = pow(dx*dx + r2, 0.5*x->a);
773  k2inv = k2inv + (x->src_weight[n][i]*x->src_weight[n][i])/(dia[i]*dia[i]);
774  }
775  k = sqrt(1./k2inv);
776  k = k*x->master_gain*x->src_gain[n]*x->src_not_muted[n];
777 
778  atom_setlong(&a[0], n);
779  for (i=0; i<x->attr_num_destinations; i++) {
780  atom_setlong(&a[1], i);
781  atom_setfloat(&a[2], x->src_weight[n][i]*k/dia[i]);
782  outlet_anything(x->outlet[0], _sym_list, 3, a);
783  }
784 }
785 
786 
787 void dbap_calculate2D(t_dbap *x, long n)
788 {
789  double k; // Scaling coefficient
790  double k2inv; // Inverse square of the scaling constant k
791  double dx, dy; // Distance vector
792  double r2; // Bluriness ratio
793  double dia[MAX_NUM_DESTINATIONS]; // Distance to ith speaker to the power of x->a.
794  double sdia[MAX_NUM_DESTINATIONS]; // Squared Distance to ith speaker (without bluriness ratio)
795  long iC,iN; // index of the the dest C and N dest in dst_position[]
796  double sSC,sSN,sCN; // squared Distance of the Source to C and N and [CN]
797  t_xyz P; // Projection point of Source on [CN], pointer to coord of S, C and N
798  double kCN, dist, min_dist;
799  double v, out; // is the source out of the hull ? (-1 inside, 1 outside)
800  long id_min; // id of the closest dest
801  long i,j;
802  t_atom a[3]; // Output array of atoms
803 
804  r2 = x->blur[n] * x->variance;
805  r2 = r2*r2;
806  k2inv = 0;
807  for (i=0; i<x->attr_num_destinations; i++) {
808  dx = x->src_position[n].x - x->dst_position[i].x;
809  dy = x->src_position[n].y - x->dst_position[i].y;
810  dia[i] = pow((dx*dx + dy*dy + r2), (0.5*x->a));
811  if (x->hull_io) sdia[i] = dx*dx + dy*dy;
812 
813  k2inv = k2inv + (x->src_weight[n][i]*x->src_weight[n][i])/(dia[i]*dia[i]);
814  }
815 
816  if (x->hull_io) {
817  // Find the closest border in the hull
818  min_dist = 10000.;
819  out = -1.;
820  for (j=0; j<x->hull2.num_dst; j++) {
821  // index in the dst_position[]
822  iC = x->hull2.id_dst[j];
823  iN = x->hull2.id_dst[(j+1)%x->hull2.num_dst];
824  // squared distance of the source S to the dest C and N
825  sSC = sdia[iC];
826  sSN = sdia[iN];
827  // squared distance of the border
828  sCN = x->hull2.dst2next[j];
829  kCN = (sSC + sCN - sSN)/sCN;
830 
831  if (kCN<0) {
832  dist = sqrt(sSC);
833  }
834  else {
835  if (kCN>2) {
836  dist = sqrt(sSN);
837  }
838  else {
839  // the projection of the source on [CN] : <CP> = kCN * <CN>
840  P.x = (kCN/2) * (x->dst_position[iN].x - x->dst_position[iC].x) + x->dst_position[iC].x;
841  P.y = (kCN/2) * (x->dst_position[iN].y - x->dst_position[iC].y) + x->dst_position[iC].y;
842  // distance of SP
843  dx = x->src_position[n].x - P.x;
844  dy = x->src_position[n].y - P.y;
845  dist = sqrt(dx*dx + dy*dy);
846  }
847  }
848 
849  // is the source out of the hull ?
850  v = (x->dst_position[iN].x - x->dst_position[iC].x)*(x->src_position[n].y - x->dst_position[iC].y);
851  v -= (x->dst_position[iN].y - x->dst_position[iC].y)*(x->src_position[n].x - x->dst_position[iC].x);
852  if (v>0) out = 1.;
853 
854  if (dist < min_dist) {
855  min_dist = dist;
856  if (sSC < sSN) id_min = iC;
857  else id_min = iN;
858  }
859  }
860 
861  atom_setlong(&a[0],n+1); // src (index starts at one for users
862  atom_setfloat(&a[1],out*min_dist); // dist to hull
863  atom_setlong(&a[2],id_min+1); // id of the closest dst in the hull
864  outlet_anything(x->outlet[1], _sym_list, 3, a);
865  }
866 
867  k = sqrt(1./k2inv);
868  k = k*x->master_gain*x->src_gain[n]*x->src_not_muted[n];
869 
870  atom_setlong(&a[0], n);
871  for (i=0; i<x->attr_num_destinations; i++) {
872  atom_setlong(&a[1], i);
873  atom_setfloat(&a[2], x->src_weight[n][i]*k/dia[i]);
874  outlet_anything(x->outlet[0], _sym_list, 3, a);
875  }
876 }
877 
878 void dbap_calculate3D(t_dbap *x, long n)
879 {
880  double k; // Scaling coefficient
881  double k2inv; // Inverse square of the scaling constant k
882  double dx, dy, dz; // Distance vector
883  double r2; // Bluriness ratio
884  double dia[MAX_NUM_DESTINATIONS]; // Distance to ith speaker to the power of x->a.
885  t_atom a[3]; // Output array of atoms
886 
887 
888  long i;
889 
890  r2 = x->blur[n] * x->variance;
891  r2 = r2*r2;
892  k2inv = 0;
893  for (i=0; i<x->attr_num_destinations; i++) {
894  dx = x->src_position[n].x - x->dst_position[i].x;
895  dy = x->src_position[n].y - x->dst_position[i].y;
896  dz = x->src_position[n].z - x->dst_position[i].z;
897  dia[i] = pow(double(dx*dx + dy*dy + dz*dz + r2), double(0.5*x->a));
898  k2inv = k2inv + (x->src_weight[n][i]*x->src_weight[n][i])/(dia[i]*dia[i]);
899  }
900  k = sqrt(1./k2inv);
901  k = k*x->master_gain*x->src_gain[n]*x->src_not_muted[n];
902 
903  atom_setlong(&a[0], n);
904 
905  for (i=0; i<x->attr_num_destinations; i++) {
906  atom_setlong(&a[1], i);
907  atom_setfloat(&a[2], x->src_weight[n][i]*k/dia[i]);
908  outlet_anything(x->outlet[0], _sym_list, 3, a);
909  }
910 }
911 
912 
913 void dbap_calculate_a(t_dbap *x)
914 {
915  x->a = log(pow(10., (x->attr_rolloff / 20.)))/log(2.);
916 }
917 
918 
920 {
921  long i;
922  double a,b,c;
923 
924  a = 0.;
925  b = 0.;
926  c = 0.;
927  for (i=0; i<x->attr_num_destinations; i++) {
928  a += x->dst_position[i].x;
929  b += x->dst_position[i].y;
930  c += x->dst_position[i].z;
931  }
932  x->mean_dst_position.x = a/x->attr_num_destinations;
933  x->mean_dst_position.y = b/x->attr_num_destinations;
934  x->mean_dst_position.z = c/x->attr_num_destinations;
935 }
936 
937 
938 void dbap_calculate_variance(t_dbap *x)
939 {
940  long i;
941  double dx, dy, dz;
942  double d2=0;
943 
944 
946 
947  if (x->attr_dimensions == 1) {
948  for (i=0; i<x->attr_num_destinations; i++) {
949  dx = x->dst_position[i].x - x->mean_dst_position.x;
950  d2 += dx*dx;
951  }
952  }
953  else if (x->attr_dimensions == 2) {
954  for (i=0; i<x->attr_num_destinations; i++) {
955  dx = x->dst_position[i].x - x->mean_dst_position.x;
956  dy = x->dst_position[i].y - x->mean_dst_position.y;
957  d2 += dx*dx + dy*dy;
958  }
959  }
960  else {
961  for (i=0; i<x->attr_num_destinations; i++) {
962  dx = x->dst_position[i].x - x->mean_dst_position.x;
963  dy = x->dst_position[i].y - x->mean_dst_position.y;
964  dz = x->dst_position[i].z - x->mean_dst_position.z;
965  d2 += dx*dx + dy*dy + dz*dz;
966  }
967  }
968  x->variance = sqrt(d2/(x->attr_num_destinations-1));
969 
970  // Update all matrix values
971  for (i=0; i<x->attr_num_sources; i++)
972  dbap_calculate(x, i);
973 }
974 
975 
976 void dbap_calculate_hull(t_dbap *x, long n)
977 {
978  // Update all matrix values
979  if (x->attr_dimensions == 1)
980  dbap_calculate_hull1D(x, n);
981 
982  else if (x->attr_dimensions == 2)
983  dbap_calculate_hull2D(x, n);
984 
985  else
986  dbap_calculate_hull3D(x, n);
987 }
988 
989 
990 
991 void dbap_calculate_hull1D(t_dbap *x, long n)
992 {
993  long i;
994  double min, max;
995 
996  min = x->dst_position[0].x;
997  max = x->dst_position[0].x;
998 
999  for (i=1; i<x->attr_num_destinations; i++) {
1000  if (x->dst_position[i].x < min)
1001  min = x->dst_position[i].x;
1002  if (x->dst_position[i].x > max)
1003  max = x->dst_position[i].x;
1004  }
1005  x->hull1.min = min;
1006  x->hull1.max = max;
1007 }
1008 
1009 // TODO : a way to select dst
1010 // TODO : put the algorithm in hull2.cpp (keep it here while isn't tested to use post())
1011 void dbap_calculate_hull2D(t_dbap *x, long n)
1012 {
1013  t_H2D h2; // the data structure used to perform calculation
1014  long i,j;
1015  double dx,dy; // to calculate the lenght of each border of the hull
1016  long m; // Index of lowest so far
1017 
1018  //post("h2D : Start ********************************************");
1019  if (x->attr_num_destinations < 2) return;
1020  else h2.nb_point = x->attr_num_destinations;
1021 
1022  // Store dst coordinate to prepare algorithm
1023  for (i = 0; i<x->attr_num_destinations; i++) {
1024  h2.point[i].v[X] = (double) x->dst_position[i].x;
1025  h2.point[i].v[Y] = (double) x->dst_position[i].y;
1026  h2.point[i].vnum = i+1;
1027  h2.point[i].del = false;
1028  }
1029 
1030  // Find the lowest and rightmost Point
1031  m = 0;
1032  for (i = 1; i<x->attr_num_destinations; i++) {
1033  if ((h2.point[i].v[Y] < h2.point[m].v[Y]) || ((h2.point[i].v[Y] == h2.point[m].v[Y]) && (h2.point[i].v[X] > h2.point[m].v[X]))) {
1034  m = i;
1035  }
1036  }
1037 
1038 
1039  // Debug
1040  //post("h2D : The lowest and rigthmost point is %d", m+1);
1041 
1042  // Swap point[0] and point[m]
1043  Swap(h2.point,0,m);
1044 
1045  // add p0 to each point[i] (to get it during Compare without use a qsort_s)
1046  for (i = 0; i<x->attr_num_destinations; i++) {
1047  h2.point[i].p0[0] = h2.point[0].v[0];
1048  h2.point[i].p0[1] = h2.point[0].v[1];
1049  }
1050 
1051  // debug
1052  //dbap_hull2_postpoint(x, h2);
1053 
1054  qsort(
1055  &h2.point[1], // pointer to 1st elem
1056  x->attr_num_destinations-1, // number of elems
1057  sizeof(t_structPoint), // size of each elem
1058  Compare // -1,0,+1 compare function
1059  );
1060 
1061  // count nb_delete ('cause we can't do that in Compare)
1062  h2.nb_delete = 0;
1063  for (i = 1; i<x->attr_num_destinations; i++) {
1064  if (h2.point[i].del) h2.nb_delete++;
1065  }
1066 
1067  // debug
1068  //post("nb_del = %d",h2.nb_delete);
1069 
1070  // Remove all elements from point marked deleted
1071  if (h2.nb_delete > 0) {
1072  i = 0;
1073  j = 0;
1074  while (i < x->attr_num_destinations) {
1075  if (!h2.point[i].del) { // if not marked for deletion
1076  if (i != j) {
1077  Copy(h2.point,i,j); // Copy point[i] to point[j]
1078  Delete(h2.point,i); // Delete point[i]
1079  }
1080  j++;
1081  }
1082  else Delete(h2.point,i); // else Delete point[i]
1083  i++;
1084  }
1085  h2.nb_point = j;
1086  }
1087 
1088  // Debug
1089  //post("h2D : %d points sorted by angle",h2.nb_point);
1090 
1091  h2.stack = Graham(h2); // return NULL if it fails
1092 
1093  // Debug
1094  //post("h2D : Hull");
1095 
1096  // store result in x->hull2
1097  i = 0;
1098  if (h2.stack) {
1099  while (h2.stack) {
1100  // Debug
1101  //post("vnum = %d, x = %f, y = %f", h2.stack->p->vnum,h2.stack->p->v[X],h2.stack->p->v[Y]);
1102 
1103  x->hull2.id_dst[i] = (h2.stack->p->vnum)-1;
1104 
1105  // calculate the lenght of each border of the hull
1106  if (i>0) {
1107  dx = x->dst_position[x->hull2.id_dst[i-1]].x - x->dst_position[x->hull2.id_dst[i]].x;
1108  dy = x->dst_position[x->hull2.id_dst[i-1]].y - x->dst_position[x->hull2.id_dst[i]].y;
1109  x->hull2.dst2next[i-1] = dx*dx + dy*dy;
1110  //post("dist[%d %d] = %f", x->hull2.id_dst[i-1]+1,x->hull2.id_dst[i]+1,sqrt(x->hull2.dst2next[i-1]));
1111  }
1112 
1113  h2.stack = h2.stack->next;
1114  i++;
1115  }
1116  x->hull2.num_dst = i;
1117  // for the last border
1118  dx = x->dst_position[x->hull2.id_dst[i-1]].x - x->dst_position[x->hull2.id_dst[0]].x;
1119  dy = x->dst_position[x->hull2.id_dst[i-1]].y - x->dst_position[x->hull2.id_dst[0]].y;
1120  x->hull2.dst2next[i-1] = dx*dx + dy*dy;
1121  //post("dist[%d %d] = %f", x->hull2.id_dst[i-1]+1,x->hull2.id_dst[0]+1,sqrt(x->hull2.dst2next[i-1]));
1122 
1123  } // else do nothing
1124 
1125  // debug
1126  //for (i=0; i<x->hull2.num_dst; i++) {
1127  // post("id = %d",x->hull2.id_dst[i]+1);
1128  //}
1129 }
1130 
1131 // Print point[] (debugging)
1132 void dbap_hull2_postpoint(t_dbap *x, t_H2D h2)
1133 {
1134  long i;
1135  post("H2D : %d points", h2.nb_point);
1136  for (i = 0; i<x->attr_num_destinations; i++)
1137  if (!h2.point[i].del)
1138  post("vnum = %d, x = %f, y = %f",
1139  h2.point[i].vnum, h2.point[i].v[X], h2.point[i].v[Y]);
1140 }
1141 
1142 void dbap_calculate_hull3D(t_dbap *x, long n)
1143 {
1144  // TODO: develop algorithm calculating convex hull in 3 dimensions
1145 }
1146 
1147 void dbap_calculate_view(t_dbap *x, long dst, long src)
1148 {
1149 
1150  // Update all matrix values
1151  if (x->attr_dimensions == 1)
1152  dbap_calculate_view1D(x, dst, src);
1153 
1154  else if (x->attr_dimensions == 2)
1155  dbap_calculate_view2D(x, dst, src);
1156 
1157  else
1158  dbap_calculate_view3D(x, dst, src);
1159 }
1160 
1161 /** If the attr_view_update is true : calculate the last view */
1162 void dbap_update_view(t_dbap *x) {
1163 
1164  if (x->attr_view_update)
1165  defer_low(x,(method) dbap_view, gensym("view"), 2, x->last_view);
1166 }
1167 
1168 void dbap_calculate_view1D(t_dbap *x, long dst, long src)
1169 {
1170  post("TODO: 1D render view");
1171 }
1172 
1173 void dbap_calculate_view2D(t_dbap *x, long dst, long src)
1174 {
1175  double k; // Scaling coefficient
1176  double k2inv; // Inverse square of the scaling constant k
1177  double dx, dy; // Distance vector
1178  double r2; // Bluriness ratio
1179  double dia[MAX_NUM_DESTINATIONS]; // Distance to ith speaker to the power of x->a.
1180  double div_x, div_y;
1181  double pix;
1182  long i,j,d;
1183  unsigned char val;
1184  t_xyz temp_src;
1185  char *bp, *p;
1186 
1187  // get the data of the view matrix
1188  jit_object_method(x->view_matrix,ps_getdata, &bp);
1189  if (!bp)
1190  return;
1191 
1192  div_x = (x->attr_view_end.x - x->attr_view_start.x)/x->view_info.dim[0];
1193  div_y = (x->attr_view_end.y - x->attr_view_start.y)/x->view_info.dim[1];
1194 
1195  // For each pixel of the view window
1196  for (i=0; i<x->view_info.dim[0]; i++) {
1197 
1198  for (j=0 ; j<x->view_info.dim[1]; j++) {
1199 
1200  temp_src.x = x->attr_view_start.x + i * div_x;
1201  temp_src.y = x->attr_view_start.y + j * div_y;
1202 
1203  //> dbap calculation for the temp source
1204  //> calculation of the mean of amplitudes
1205 
1206  r2 = x->blur[src] * x->variance;
1207  r2 = r2*r2;
1208  k2inv = 0;
1209 
1210  for (d=0; d<x->attr_num_destinations; d++) {
1211  dx = temp_src.x - x->dst_position[d].x;
1212  dy = temp_src.y - x->dst_position[d].y;
1213  dia[d] = pow(double(dx*dx + dy*dy + r2), double(0.5*x->a));
1214  k2inv = k2inv + (x->src_weight[src][d]*x->src_weight[src][d])/(dia[d]*dia[d]);
1215  }
1216  k = sqrt(1./k2inv);
1217 
1218  // squared response [0::1]
1219  pix = k*x->src_weight[src][dst]/ dia[dst];
1220  pix *= pix;
1221  val = (unsigned char)(pix*255.);
1222 
1223  // get cell at (i,j)
1224  p = bp + i + (x->view_info.dim[1] - j-1)*x->view_info.dim[0];
1225 
1226  // keep the max
1227  if (*((unsigned char *)p) < val)
1228  *((unsigned char *)p) = val;
1229  }
1230  }
1231 }
1232 
1233 void dbap_calculate_view3D(t_dbap *x, long dst, long src)
1234 {
1235  post("TODO: 3D render view");
1236 }
1237 
1238 void dbap_output_view(t_dbap *x)
1239 {
1240  t_atom m[1]; // Output matrix name
1241  atom_setsym(&m[0], x->view_name);
1242  outlet_anything(x->outlet[2], _sym_jit_matrix, 1, m);
1243 }
void dbap_calculate_view2D(t_dbap *x, long dst, long src)
Calculate the view (2D-matrix) : 2D.
Definition: j.dbap.cpp:1173
t_max_err dbap_attr_setdimensions(t_dbap *x, void *attr, long argc, t_atom *argv)
Set number of dimensions of the system.
Definition: j.dbap.cpp:641
void dbap_mastergain(t_dbap *x, double f)
Set master gain for all values passed from the object to matrix~.
Definition: j.dbap.cpp:332
void dbap_calculate_hull3D(t_dbap *x, long n)
Calculate convex hull of space spanned by destination points: 3D.
Definition: j.dbap.cpp:1142
void dbap_calculate_a(t_dbap *x)
Calculation of exponent coefficient based on rolloff.
Definition: j.dbap.cpp:913
void dbap_assist(t_dbap *x, void *b, long msg, long arg, char *dst)
Display assist strings while patching.
Definition: j.dbap.cpp:603
void dbap_sourceweight(t_dbap *x, t_symbol *msg, long argc, t_atom *argv)
Set weight for nth source by passing a list to balance each destination.
Definition: j.dbap.cpp:345
t_max_err dbap_attr_setnum_destinations(t_dbap *x, void *attr, long argc, t_atom *argv)
Set the number of destinations of the system.
Definition: j.dbap.cpp:673
void dbap_calculate_mean_dst_position(t_dbap *x)
Calculate mean position of the destination points.
Definition: j.dbap.cpp:919
void dbap_calculate_hull(t_dbap *x, long n)
Calculate convex hull of space spanned by destination points.
Definition: j.dbap.cpp:976
bool JAMOMA_EXPORT jamoma_loadextern(t_symbol *objectname, long argc, t_atom *argv, t_object **object)
Load obex externals for use within other externals.
void dbap_calculate1D(t_dbap *x, long n)
Calculate matrix coefficients for nth source: 1D space.
Definition: j.dbap.cpp:735
void dbap_calculate_hull2D(t_dbap *x, long n)
Calculate convex hull of space spanned by destination points: 2D.
Definition: j.dbap.cpp:1011
void dbap_output_view(t_dbap *x)
Output the calculated view.
Definition: j.dbap.cpp:1238
void dbap_calculate_hull1D(t_dbap *x, long n)
Calculate convex hull of space spanned by destination points: 1D.
Definition: j.dbap.cpp:991
int JAMOMA_EXPORT_MAXOBJ main(void)
Set up this class as a Max external the first time an object of this kind is instantiated.
Definition: j.dbap.cpp:27
t_max_err dbap_attr_setrolloff(t_dbap *x, void *attr, long argc, t_atom *argv)
Set rolloff in dB.
Definition: j.dbap.cpp:692
void dbap_view(t_dbap *x, void *msg, long argc, t_atom *argv)
Display a hitmap view of the dbap for a destination and a source weight config or all (on the info ou...
Definition: j.dbap.cpp:429
void dbap_calculate_view3D(t_dbap *x, long dst, long src)
Calculate the view (2D-matrix) : 3D.
Definition: j.dbap.cpp:1233
void dbap_view_update(t_dbap *x, long io)
Turn on/off the auto view updating.
Definition: j.dbap.cpp:475
double x
x position
Definition: j.dbap.h:44
void dbap_calculate2D(t_dbap *x, long n)
Calculate matrix coefficients for nth source: 2D space.
Definition: j.dbap.cpp:787
void dbap_source(t_dbap *x, void *msg, long argc, t_atom *argv)
Set the position of the nth virtual source.
Definition: j.dbap.cpp:240
void dbap_calculate(t_dbap *x, long n)
General method for calculation of matrix coefficient for nth source.
Definition: j.dbap.cpp:721
void dbap_calculate_view(t_dbap *x, long dst, long src)
Calculate the view (2D-matrix)
Definition: j.dbap.cpp:1147
Various utilities for interfacing with Max that are not specific to JamomaModular as such...
void dbap_hull(t_dbap *x, long f)
Turn on/off the calculation of distance to hull.
Definition: j.dbap.cpp:409
void dbap_view_start(t_dbap *x, void *msg, long argc, t_atom *argv)
Set the start point of the hitmap view window.
Definition: j.dbap.cpp:504
void dbap_calculate_view1D(t_dbap *x, long dst, long src)
Calculate the view (2D-matrix) : 1D.
Definition: j.dbap.cpp:1168
void dbap_view_end(t_dbap *x, void *msg, long argc, t_atom *argv)
Set the end point of the hitmap view window.
Definition: j.dbap.cpp:533
t_max_err dbap_attr_setnum_sources(t_dbap *x, void *attr, long argc, t_atom *argv)
Set the number of sources of the system.
Definition: j.dbap.cpp:657
void dbap_blur(t_dbap *x, t_symbol *msg, long argc, t_atom *argv)
Set spatial blur for nth source.
Definition: j.dbap.cpp:202
void dbap_destination(t_dbap *x, void *msg, long argc, t_atom *argv)
Set the position of the nth speaker.
Definition: j.dbap.cpp:273
void dbap_blurall(t_dbap *x, double f)
Set spatial blur for all sources.
Definition: j.dbap.cpp:226
j.dbap - Distance Based Amplitude Panning
void dbap_info(t_dbap *x)
Get info on destination setup ++.
Definition: j.dbap.cpp:561
void dbap_sourcegain(t_dbap *x, void *msg, long argc, t_atom *argv)
Set input gain for nth source.
Definition: j.dbap.cpp:308
void dbap_calculate_variance(t_dbap *x)
Calculate bias-corrected variance of distance from destination points to mean destination point...
Definition: j.dbap.cpp:938
double y
y position
Definition: j.dbap.h:45
void dbap_sourcemute(t_dbap *x, void *msg, long argc, t_atom *argv)
Mute and unmute sources.
Definition: j.dbap.cpp:390
void dbap_update_view(t_dbap *x)
If the attr_view_update is true : calculate the last view.
Definition: j.dbap.cpp:1162
Data structure for storing a 1,2 or 3 dimensional space data.
Definition: j.dbap.h:43
t_class * this_class
Required. Global pointing to this class.
Definition: j.envexp.cpp:108
void dbap_view_size(t_dbap *x, long sizeX, long sizeY)
Set the size of hitmap view window.
Definition: j.dbap.cpp:483
void dbap_calculate3D(t_dbap *x, long n)
Calculate matrix coefficients for nth source: 3D space.
Definition: j.dbap.cpp:878