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