1 /*
2 Copyright (C) 2004-2009 Fons Adriaensen <fons@kokkinizita.net>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19
20 #include <string.h>
21 #include <math.h>
22 #include "ambisonic1.h"
23
24
25 #define DEG2RAD 0.01745329f
26 #define MIN3DB 0.707107f
27
28
setport(unsigned long port,LADSPA_Data * data)29 void Ladspa_Monopan11::setport (unsigned long port, LADSPA_Data *data)
30 {
31 _port [port] = data;
32 }
33
34
active(bool act)35 void Ladspa_Monopan11::active (bool act)
36 {
37 if (act) calcpar (0.0f, 0.0f);
38 }
39
40
calcpar(float az,float el)41 void Ladspa_Monopan11::calcpar (float az, float el)
42 {
43 float ce;
44
45 az *= DEG2RAD;
46 el *= DEG2RAD;
47 _zz = sinf (el);
48 ce = cosf (el);
49 _xx = ce * cosf (-az);
50 _yy = ce * sinf (-az);
51 }
52
53
runproc(unsigned long len,bool add)54 void Ladspa_Monopan11::runproc (unsigned long len, bool add)
55 {
56 float t, xx, yy, zz, dxx, dyy, dzz;
57 float *in, *out_w, *out_x, *out_y, *out_z;
58
59 xx = _xx;
60 yy = _yy;
61 zz = _zz;
62 calcpar (_port [CTL_AZIM][0], _port [CTL_ELEV][0]);
63 dxx = (_xx - xx) / len;
64 dyy = (_yy - yy) / len;
65 dzz = (_zz - zz) / len;
66
67 in = _port [INP];
68 out_w = _port [OUT_W];
69 out_x = _port [OUT_X];
70 out_y = _port [OUT_Y];
71 out_z = _port [OUT_Z];
72
73 while (len--)
74 {
75 xx += dxx;
76 yy += dyy;
77 zz += dzz;
78 t = *in++;
79 *out_w++ = MIN3DB * t;
80 *out_x++ = xx * t;
81 *out_y++ = yy * t;
82 *out_z++ = zz * t;
83 }
84 }
85
86
87
setport(unsigned long port,LADSPA_Data * data)88 void Ladspa_Stereopan11::setport (unsigned long port, LADSPA_Data *data)
89 {
90 _port [port] = data;
91 }
92
93
active(bool act)94 void Ladspa_Stereopan11::active (bool act)
95 {
96 if (act) calcpar (0.0f, 0.0f, 90.0f);
97 }
98
99
calcpar(float az,float el,float wd)100 void Ladspa_Stereopan11::calcpar (float az, float el, float wd)
101 {
102 float a, ce;
103
104 az *= DEG2RAD;
105 el *= DEG2RAD;
106 wd *= 0.5f * DEG2RAD;
107 _zz = sinf (el);
108 ce = cosf (el);
109 a = (az - wd);
110 _xl = ce * cosf (-a);
111 _yl = ce * sinf (-a);
112 a = (az + wd);
113 _xr = ce * cosf (-a);
114 _yr = ce * sinf (-a);
115 }
116
117
runproc(unsigned long len,bool add)118 void Ladspa_Stereopan11::runproc (unsigned long len, bool add)
119 {
120 float xl, xr, yl, yr, zz, dxl, dxr, dyl, dyr, dzz, u, v;
121 float *in_l, *in_r, *out_w, *out_x, *out_y, *out_z;
122
123 xl = _xl;
124 xr = _xr;
125 yl = _yl;
126 yr = _yr;
127 zz = _zz;
128 calcpar (_port [CTL_AZIM][0], _port [CTL_ELEV][0], _port [CTL_WIDTH][0]);
129 dxl = (_xl - xl) / len;
130 dxr = (_xr - xr) / len;
131 dyl = (_yl - yl) / len;
132 dyr = (_yr - yr) / len;
133 dzz = (_zz - zz) / len;
134
135 in_l = _port [INP_L];
136 in_r = _port [INP_R];
137 out_w = _port [OUT_W];
138 out_x = _port [OUT_X];
139 out_y = _port [OUT_Y];
140 out_z = _port [OUT_Z];
141
142 while (len--)
143 {
144 xl += dxl;
145 xr += dxr;
146 yl += dyl;
147 yr += dyr;
148 zz += dzz;
149 u = *in_l++;
150 v = *in_r++;
151 *out_w++ = MIN3DB * (u + v);
152 *out_z++ = zz * (u + v);
153 *out_x++ = xl * u + xr * v;
154 *out_y++ = yl * u + yr * v;
155 }
156 }
157
158
159
setport(unsigned long port,LADSPA_Data * data)160 void Ladspa_Rotator11::setport (unsigned long port, LADSPA_Data *data)
161 {
162 _port [port] = data;
163 }
164
165
active(bool act)166 void Ladspa_Rotator11::active (bool act)
167 {
168 if (act) calcpar (0.0f);
169 }
170
171
calcpar(float az)172 void Ladspa_Rotator11::calcpar (float az)
173 {
174 az *= DEG2RAD;
175 _c = cosf (az);
176 _s = sinf (az);
177 }
178
179
runproc(unsigned long len,bool add)180 void Ladspa_Rotator11::runproc (unsigned long len, bool add)
181 {
182
183 float c, s, dc, ds, x, y;
184 float *in_x, *in_y, *out_x, *out_y;
185
186 memcpy (_port [OUT_W], _port [INP_W], len * sizeof (float));
187 memcpy (_port [OUT_Z], _port [INP_Z], len * sizeof (float));
188
189 c = _c;
190 s = _s;
191 calcpar (_port [CTL_AZIM][0]);
192 dc = (_c - c) / len;
193 ds = (_s - s) / len;
194
195 in_x = _port [INP_X];
196 in_y = _port [INP_Y];
197 out_x = _port [OUT_X];
198 out_y = _port [OUT_Y];
199
200 while (len--)
201 {
202 c += dc;
203 s += ds;
204 x = *in_x++;
205 y = *in_y++;
206 *out_x++ = c * x + s * y;
207 *out_y++ = c * y - s * x;
208 }
209 }
210
211
212
setport(unsigned long port,LADSPA_Data * data)213 void Ladspa_SquareDec11::setport (unsigned long port, LADSPA_Data *data)
214 {
215 _port [port] = data;
216 }
217
218
active(bool act)219 void Ladspa_SquareDec11::active (bool act)
220 {
221 _wsh.reset ();
222 _xsh.reset ();
223 _ysh.reset ();
224 _xlp.reset ();
225 _ylp.reset ();
226 }
227
228
runproc(unsigned long len,bool add)229 void Ladspa_SquareDec11::runproc (unsigned long len, bool add)
230 {
231 int m;
232 float t, w, x, y;
233 float *in_w, *in_x, *in_y;
234 float *out_1, *out_2, *out_3, *out_4;
235
236 m = 0;
237 if (_port [CTL_SHELF][0] > 0)
238 {
239 m |= SHELF;
240 if ( (_port [CTL_HFG1][0] != _hfg1)
241 || (_port [CTL_LFG1][0] != _lfg1)
242 || (_port [CTL_FREQ][0] != _freq))
243 {
244 _hfg1 = _port [CTL_HFG1][0];
245 _lfg1 = _port [CTL_LFG1][0];
246 _freq = _port [CTL_FREQ][0];
247 _wsh.init (_fsam, _freq, sqrtf (_hfg1 / _lfg1), -1.0f);
248 _xsh.init (_fsam, _freq, sqrtf (_hfg1 * _lfg1), -_hfg1);
249 _ysh.init (_fsam, _freq, sqrtf (_hfg1 * _lfg1), -_hfg1);
250 }
251 }
252 else _hfg1 = _port [CTL_HFG1][0];
253 _mode = m & SHELF;
254
255 if (_dist != _port [CTL_DIST][0])
256 {
257 _dist = _port [CTL_DIST][0];
258 t = 54.0f / _dist;
259 _xlp.init (_fsam, t);
260 _ylp.init (_fsam, t);
261 }
262
263 in_w = _port [INP_W];
264 in_x = _port [INP_X];
265 in_y = _port [INP_Y];
266 out_1 = _port [OUT_1];
267 out_2 = _port [OUT_2];
268 out_3 = _port [OUT_3];
269 out_4 = _port [OUT_4];
270
271 if (_port [CTL_FRONT][0])
272 {
273 if (_mode & SHELF)
274 {
275 while (len--)
276 {
277 x = 0.7071f * *in_x++;
278 x = _xsh.process (x - _xlp.process (x));
279 y = 0.7071f * *in_y++;
280 y = _ysh.process (y - _ylp.process (y));
281 w = _wsh.process (*in_w++);
282 *out_1++ = w + x;
283 *out_2++ = w - y;
284 *out_3++ = w - x;
285 *out_4++ = w + y;
286 }
287 }
288 else
289 {
290 while (len--)
291 {
292 x = 0.7071f * *in_x++;
293 x = _hfg1 * (x - _xlp.process (x));
294 y = 0.7071f * *in_y++;
295 y = _hfg1 * (y - _ylp.process (y));
296 w = *in_w++;
297 *out_1++ = w + x;
298 *out_2++ = w - y;
299 *out_3++ = w - x;
300 *out_4++ = w + y;
301 }
302 }
303 }
304 else
305 {
306 if (_mode & SHELF)
307 {
308 while (len--)
309 {
310 x = 0.5f * *in_x++;
311 x = _xsh.process (x - _xlp.process (x));
312 y = 0.5f * *in_y++;
313 y = _ysh.process (y - _ylp.process (y));
314 w = _wsh.process (*in_w++);
315 *out_1++ = w + x + y;
316 *out_2++ = w + x - y;
317 *out_3++ = w - x - y;
318 *out_4++ = w - x + y;
319 }
320 }
321 else
322 {
323 while (len--)
324 {
325 x = 0.5f * *in_x++;
326 x = _hfg1 * (x - _xlp.process (x));
327 y = 0.5f * *in_y++;
328 y = _hfg1 * (y - _ylp.process (y));
329 w = *in_w++;
330 *out_1++ = w + x + y;
331 *out_2++ = w + x - y;
332 *out_3++ = w - x - y;
333 *out_4++ = w - x + y;
334 }
335 }
336 }
337 }
338
339
setport(unsigned long port,LADSPA_Data * data)340 void Ladspa_HexaDec11::setport (unsigned long port, LADSPA_Data *data)
341 {
342 _port [port] = data;
343 }
344
345
active(bool act)346 void Ladspa_HexaDec11::active (bool act)
347 {
348 _wsh.reset ();
349 _xsh.reset ();
350 _ysh.reset ();
351 _xlp.reset ();
352 _ylp.reset ();
353 }
354
355
runproc(unsigned long len,bool add)356 void Ladspa_HexaDec11::runproc (unsigned long len, bool add)
357 {
358
359 int m;
360 float t, w, x, y;
361 float *in_w, *in_x, *in_y;
362 float *out_1, *out_2, *out_3, *out_4, *out_5, *out_6;
363
364 m = 0;
365 if (_port [CTL_SHELF][0] > 0)
366 {
367 m |= SHELF;
368 if ( (_port [CTL_HFG1][0] != _hfg1)
369 || (_port [CTL_LFG1][0] != _lfg1)
370 || (_port [CTL_FREQ][0] != _freq))
371 {
372 _hfg1 = _port [CTL_HFG1][0];
373 _lfg1 = _port [CTL_LFG1][0];
374 _freq = _port [CTL_FREQ][0];
375 _wsh.init (_fsam, _freq, sqrtf (_hfg1 / _lfg1), -1.0f);
376 _xsh.init (_fsam, _freq, sqrtf (_hfg1 * _lfg1), -_hfg1);
377 _ysh.init (_fsam, _freq, sqrtf (_hfg1 * _lfg1), -_hfg1);
378 }
379 }
380 else _hfg1 = _port [CTL_HFG1][0];
381 _mode = m & SHELF;
382
383 if (_dist != _port [CTL_DIST][0])
384 {
385 _dist = _port [CTL_DIST][0];
386 t = 54.0f / _dist;
387 _xlp.init (_fsam, t);
388 _ylp.init (_fsam, t);
389 }
390
391 in_w = _port [INP_W];
392 in_x = _port [INP_X];
393 in_y = _port [INP_Y];
394 out_1 = _port [OUT_1];
395 out_2 = _port [OUT_2];
396 out_3 = _port [OUT_3];
397 out_4 = _port [OUT_4];
398 out_5 = _port [OUT_5];
399 out_6 = _port [OUT_6];
400
401 if (_port [CTL_FRONT][0])
402 {
403 if (_mode & SHELF)
404 {
405 while (len--)
406 {
407 x = 0.7071f * *in_x++;
408 x = _xsh.process (x - _xlp.process (x));
409 y = 0.6124f * *in_y++;
410 y = _ysh.process (y - _ylp.process (y));
411 w = _wsh.process (*in_w++);
412 *out_1++ = w + x;
413 *out_2++ = w + 0.5f * x - y;
414 *out_3++ = w - 0.5f * x - y;
415 *out_4++ = w - x;
416 *out_5++ = w - 0.5f * x + y;
417 *out_6++ = w + 0.5f * x + y;
418 }
419 }
420 else
421 {
422 while (len--)
423 {
424 x = 0.7071f * *in_x++;
425 x = _hfg1 * (x - _xlp.process (x));
426 y = 0.6124f * *in_y++;
427 y = _hfg1 * (y - _ylp.process (y));
428 w = *in_w++;
429 *out_1++ = w + x;
430 *out_2++ = w + 0.5f * x - y;
431 *out_3++ = w - 0.5f * x - y;
432 *out_4++ = w - x;
433 *out_5++ = w - 0.5f * x + y;
434 *out_6++ = w + 0.5f * x + y;
435 }
436 }
437 }
438 else
439 {
440 if (_mode & SHELF)
441 {
442 while (len--)
443 {
444 x = 0.6124f * *in_x++;
445 x = _xsh.process (x - _xlp.process (x));
446 y = 0.7071f * *in_y++;
447 y = _ysh.process (y - _ylp.process (y));
448 w = _wsh.process (*in_w++);
449 *out_1++ = w + x + 0.5f * y;
450 *out_2++ = w + x - 0.5f * y;
451 *out_3++ = w - y;
452 *out_4++ = w - x - 0.5f * y;
453 *out_5++ = w - x + 0.5f * y;
454 *out_6++ = w + y;
455 }
456 }
457 else
458 {
459 while (len--)
460 {
461 x = 0.6124f * *in_x++;
462 x = _hfg1 * (x - _xlp.process (x));
463 y = 0.7071f * *in_y++;
464 y = _hfg1 * (y - _ylp.process (y));
465 w = *in_w++;
466 *out_1++ = w + x + 0.5f * y;
467 *out_2++ = w + x - 0.5f * y;
468 *out_3++ = w - y;
469 *out_4++ = w - x - 0.5f * y;
470 *out_5++ = w - x + 0.5f * y;
471 *out_6++ = w + y;
472 }
473 }
474 }
475 }
476
477
setport(unsigned long port,LADSPA_Data * data)478 void Ladspa_CubeDec11::setport (unsigned long port, LADSPA_Data *data)
479 {
480 _port [port] = data;
481 }
482
483
active(bool act)484 void Ladspa_CubeDec11::active (bool act)
485 {
486 _wsh.reset ();
487 _xsh.reset ();
488 _ysh.reset ();
489 _zsh.reset ();
490 _xlp.reset ();
491 _ylp.reset ();
492 _zlp.reset ();
493 }
494
495
runproc(unsigned long len,bool add)496 void Ladspa_CubeDec11::runproc (unsigned long len, bool add)
497 {
498 int m;
499 float t, w, x, y, z;
500 float *in_w, *in_x, *in_y, *in_z;
501 float *out_1, *out_2, *out_3, *out_4, *out_5, *out_6, *out_7, *out_8;
502
503 m = 0;
504 if (_port [CTL_SHELF][0] > 0)
505 {
506 m |= SHELF;
507 if ( (_port [CTL_HFG1][0] != _hfg1)
508 || (_port [CTL_LFG1][0] != _lfg1)
509 || (_port [CTL_FREQ][0] != _freq))
510 {
511 _hfg1 = _port [CTL_HFG1][0];
512 _lfg1 = _port [CTL_LFG1][0];
513 _freq = _port [CTL_FREQ][0];
514 _wsh.init (_fsam, _freq, sqrtf (_hfg1 / _lfg1), -1.0f);
515 _xsh.init (_fsam, _freq, sqrtf (_hfg1 * _lfg1), -_hfg1);
516 _ysh.init (_fsam, _freq, sqrtf (_hfg1 * _lfg1), -_hfg1);
517 _zsh.init (_fsam, _freq, sqrtf (_hfg1 * _lfg1), -_hfg1);
518 }
519 }
520 else _hfg1 = _port [CTL_HFG1][0];
521 _mode = m & SHELF;
522
523 if (_dist != _port [CTL_DIST][0])
524 {
525 _dist = _port [CTL_DIST][0];
526 t = 54.0f / _dist;
527 _xlp.init (_fsam, t);
528 _ylp.init (_fsam, t);
529 _zlp.init (_fsam, t);
530 }
531
532 in_w = _port [INP_W];
533 in_x = _port [INP_X];
534 in_y = _port [INP_Y];
535 in_z = _port [INP_Z];
536 out_1 = _port [OUT_1];
537 out_2 = _port [OUT_2];
538 out_3 = _port [OUT_3];
539 out_4 = _port [OUT_4];
540 out_5 = _port [OUT_5];
541 out_6 = _port [OUT_6];
542 out_7 = _port [OUT_7];
543 out_8 = _port [OUT_8];
544
545 if (_mode & SHELF)
546 {
547 while (len--)
548 {
549 x = 0.4082f * *in_x++;
550 x = _xsh.process (x - _xlp.process (x));
551 y = 0.4082f * *in_y++;
552 y = _ysh.process (y - _ylp.process (y));
553 z = 0.4082f * *in_z++;
554 z = _zsh.process (z - _zlp.process (z));
555 w = _wsh.process (*in_w++);
556 *out_1++ = w + x + y - z;
557 *out_2++ = w + x - y - z;
558 *out_3++ = w - x - y - z;
559 *out_4++ = w - x + y - z;
560 *out_5++ = w + x + y + z;
561 *out_6++ = w + x - y + z;
562 *out_7++ = w - x - y + z;
563 *out_8++ = w - x + y + z;
564 }
565 }
566 else
567 {
568 while (len--)
569 {
570 x = 0.4082f * *in_x++;
571 x = _hfg1 * (x - _xlp.process (x));
572 y = 0.4082f * *in_y++;
573 y = _hfg1 * (y - _ylp.process (y));
574 z = 0.4082f * *in_z++;
575 z = _hfg1 * (z - _zlp.process (z));
576 w = *in_w++;
577 *out_1++ = w + x + y - z;
578 *out_2++ = w + x - y - z;
579 *out_3++ = w - x - y - z;
580 *out_4++ = w - x + y - z;
581 *out_5++ = w + x + y + z;
582 *out_6++ = w + x - y + z;
583 *out_7++ = w - x - y + z;
584 *out_8++ = w - x + y + z;
585 }
586 }
587 }
588
589