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