1 /*
2     Copyright (C) 2010 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 "ambisonic0.h"
23 
24 
setport(unsigned long port,LADSPA_Data * data)25 void Ladspa_Tricard2amb::setport (unsigned long port, LADSPA_Data *data)
26 {
27     _port [port] = data;
28 }
29 
30 
active(bool act)31 void Ladspa_Tricard2amb::active (bool act)
32 {
33 }
34 
35 
runproc(unsigned long len,bool add)36 void Ladspa_Tricard2amb::runproc (unsigned long len, bool add)
37 {
38     int   i;
39     float lt, rt, bk;
40     float *inp_L, *inp_R, *inp_B, *out_W, *out_X, *out_Y;
41 
42     inp_L = _port [INP_L];
43     inp_R = _port [INP_R];
44     inp_B = _port [INP_B];
45     out_W = _port [OUT_W];
46     out_X = _port [OUT_X];
47     out_Y = _port [OUT_Y];
48     memset (_port [OUT_Z], 0, len * sizeof (float));
49 
50     for (i = 0; i < (int)len; i++)
51     {
52 	lt = inp_L [i];
53 	rt = inp_R [i];
54 	bk = inp_B [i];
55 	out_W [i] = 0.47140f * (lt + rt + bk);
56 	out_X [i] = 0.66667f * (lt + rt) - 1.33333f * bk;
57 	out_Y [i] = 1.15470f * (lt - rt);
58     }
59 }
60 
61 
62 
setport(unsigned long port,LADSPA_Data * data)63 void Ladspa_Virtualmic::setport (unsigned long port, LADSPA_Data *data)
64 {
65     _port [port] = data;
66 }
67 
68 
active(bool act)69 void Ladspa_Virtualmic::active (bool act)
70 {
71 }
72 
73 
runproc(unsigned long len,bool add)74 void Ladspa_Virtualmic::runproc (unsigned long len, bool add)
75 {
76     _vmic.set_elev (_port [CTL_ELEV][0]);
77     _vmic.set_azim (_port [CTL_AZIM][0]);
78     _vmic.set_angle (_port [CTL_ANGLE][0]);
79     _vmic.set_direc (_port [CTL_POLAR][0]);
80     _vmic.process (len,
81                    _port [INP_W], _port [INP_X], _port [INP_Y], _port [INP_Z],
82                    _port [OUT_L], _port [OUT_R]);
83 }
84 
85 
86 
87 
Ladspa_UHJ_encoder(unsigned long fsam)88 Ladspa_UHJ_encoder::Ladspa_UHJ_encoder (unsigned long fsam) :
89     LadspaPlugin (fsam),
90     _err (false)
91 {
92     if (   Allpass22::initquad (&_Wfilt_r, &_Wfilt_i, fsam)
93         || Allpass22::initquad (&_Xfilt_r, &_Xfilt_i, fsam)
94         || Allpass22::initquad (&_Yfilt_r, 0, fsam)) _err = true;
95 }
96 
97 
setport(unsigned long port,LADSPA_Data * data)98 void Ladspa_UHJ_encoder::setport (unsigned long port, LADSPA_Data *data)
99 {
100     _port [port] = data;
101 }
102 
103 
active(bool act)104 void Ladspa_UHJ_encoder::active (bool act)
105 {
106     if (act)
107     {
108 	_Wfilt_r.reset ();
109 	_Wfilt_i.reset ();
110 	_Xfilt_r.reset ();
111 	_Xfilt_i.reset ();
112 	_Yfilt_r.reset ();
113     }
114 }
115 
116 
runproc(unsigned long len,bool add)117 void Ladspa_UHJ_encoder::runproc (unsigned long len, bool add)
118 {
119 //     |         W                   X                Y         Z
120 // ------------------------------------------------------------------
121 //  L  |   0.4698 - 0.1710j    0.0928 + 0.2550j    0.3277       0
122 //  R  |   0.4698 + 0.1710j    0.0928 - 0.2550j   -0.3277       0
123 
124     float *W, *X, *Y, *L, *R;
125     float s, d;
126     int   j, k;
127     float Wdata_r [80];
128     float Wdata_i [80];
129     float Xdata_r [80];
130     float Xdata_i [80];
131     float Ydata_r [80];
132 
133     W = _port [INP_W];
134     X = _port [INP_X];
135     Y = _port [INP_Y];
136     L = _port [OUT_L];
137     R = _port [OUT_R];
138 
139     if (_err)
140     {
141 	memset (L, 0, len *sizeof (float));
142 	memset (R, 0, len *sizeof (float));
143 	return;
144     }
145 
146     while (len)
147     {
148 	k = (len < 80) ? len : 64;
149 	_Wfilt_r.process (k, W, Wdata_r);
150 	_Wfilt_i.process (k, W, Wdata_i);
151 	_Xfilt_r.process (k, X, Xdata_r);
152 	_Xfilt_i.process (k, X, Xdata_i);
153 	_Yfilt_r.process (k, Y, Ydata_r);
154 	for (j = 0; j < k; j++)
155 	{
156 	    s =  0.4698f * Wdata_r [j] + 0.0928f * Xdata_r [j];
157 	    d = -0.1710f * Wdata_i [j] + 0.2550f * Xdata_i [j] + 0.3277f * Ydata_r [j];
158 	    L [j] = s + d;
159 	    R [j] = s - d;
160 	}
161 	W += k;
162 	X += k;
163 	Y += k;
164 	L += k;
165         R += k;
166 	len -= k;
167     }
168 }
169 
170 
171 
Ladspa_UHJ_decoder(unsigned long fsam)172 Ladspa_UHJ_decoder::Ladspa_UHJ_decoder (unsigned long fsam) :
173     LadspaPlugin (fsam),
174     _err (false)
175 {
176     if (   Allpass22::initquad (&_Lfilt_r, &_Lfilt_i, fsam)
177         || Allpass22::initquad (&_Rfilt_r, &_Rfilt_i, fsam)) _err = true;
178 }
179 
180 
setport(unsigned long port,LADSPA_Data * data)181 void Ladspa_UHJ_decoder::setport (unsigned long port, LADSPA_Data *data)
182 {
183     _port [port] = data;
184 }
185 
186 
active(bool act)187 void Ladspa_UHJ_decoder::active (bool act)
188 {
189     if (act)
190     {
191 	_Lfilt_r.reset ();
192 	_Lfilt_i.reset ();
193 	_Rfilt_r.reset ();
194 	_Rfilt_i.reset ();
195     }
196 }
197 
198 
runproc(unsigned long len,bool add)199 void Ladspa_UHJ_decoder::runproc (unsigned long len, bool add)
200 {
201 //      |         L                   R
202 // ---------------------------------------------
203 //  W   |   0.491 + 0.082j      0.491 - 0.082j
204 //  X   |   0.210 - 0.414j      0.210 + 0.414j
205 //  Y   |   0.382 + 0.193j     -0.382 + 0.193j
206 
207     float *L, *R, *W, *X, *Y, *Z;
208     float sr, dr, si, di;
209     int   j, k;
210     float Ldata_r [80];
211     float Ldata_i [80];
212     float Rdata_r [80];
213     float Rdata_i [80];
214 
215     L = _port [INP_L];
216     R = _port [INP_R];
217     W = _port [OUT_W];
218     X = _port [OUT_X];
219     Y = _port [OUT_Y];
220     Z = _port [OUT_Z];
221 
222     memset (Z, 0, len *sizeof (float));
223     if (_err)
224     {
225 	memset (W, 0, len *sizeof (float));
226 	memset (X, 0, len *sizeof (float));
227 	memset (Y, 0, len *sizeof (float));
228 	return;
229     }
230 
231     while (len)
232     {
233 	k = (len < 80) ? len : 64;
234 	_Lfilt_r.process (k, L, Ldata_r);
235 	_Lfilt_i.process (k, L, Ldata_i);
236 	_Rfilt_r.process (k, R, Rdata_r);
237 	_Rfilt_i.process (k, R, Rdata_i);
238 	for (j = 0; j < k; j++)
239 	{
240 	    sr = Ldata_r [j] + Rdata_r [j];
241 	    dr = Ldata_r [j] - Rdata_r [j];
242 	    si = Ldata_i [j] + Rdata_i [j];
243 	    di = Ldata_i [j] - Rdata_i [j];
244 	    W [j] = 0.491f * sr + 0.082f * di;
245 	    X [j] = 0.210f * sr - 0.414f * di;
246 	    Y [j] = 0.382f * dr + 0.193f * si;
247 	}
248 	L += k;
249         R += k;
250 	W += k;
251 	X += k;
252 	Y += k;
253 	len -= k;
254     }
255 }
256 
257 
258