martin@0
|
1 /*
|
martin@0
|
2 * Decoder.cpp
|
martin@0
|
3 * SoundField
|
martin@0
|
4 *
|
martin@0
|
5 * Created by Martin Morrell on 14/06/2012.
|
martin@0
|
6 * Copyright 2012 Queen Mary University of London. All rights reserved.
|
martin@0
|
7 *
|
martin@0
|
8 */
|
martin@0
|
9
|
martin@0
|
10
|
martin@0
|
11 #include "Decoder.h"
|
martin@0
|
12 #define _USE_MATH_DEFINES
|
martin@0
|
13 #include <cmath>
|
martin@0
|
14 #include <stdlib.h>
|
martin@0
|
15 #define RearVerbWidth 55
|
martin@0
|
16 #define RearVerbPattern 0.5
|
martin@0
|
17 #define HiVerbWidth 30
|
martin@0
|
18 #define HiVerbPattern 0.5
|
martin@0
|
19
|
martin@0
|
20
|
martin@0
|
21 double Decoder::degRad(double angle)
|
martin@0
|
22 {
|
martin@0
|
23 return (angle/180*M_PI);
|
martin@0
|
24 };
|
martin@0
|
25
|
martin@0
|
26
|
martin@0
|
27 double Decoder::radDeg(double angle)
|
martin@0
|
28 {
|
martin@0
|
29 return (angle/M_PI*180);
|
martin@0
|
30 };
|
martin@0
|
31
|
martin@0
|
32
|
martin@0
|
33 //Overall Functions
|
martin@0
|
34 void Decoder::monoDecoder(double &w, double &x, double &y, double &z)
|
martin@0
|
35 {
|
martin@0
|
36 //Sound field rotations. Only called if the value is not 0
|
martin@0
|
37 if (Rotate!=0.0f)
|
martin@0
|
38 rotateField(x, y);
|
martin@0
|
39
|
martin@0
|
40 if (Tilt!=0.0f)
|
martin@0
|
41 tiltField(y, z);
|
martin@0
|
42
|
martin@0
|
43 if (Tumble!=0.0f)
|
martin@0
|
44 tumbleField(x, z);
|
martin@0
|
45
|
martin@0
|
46
|
martin@0
|
47 //Zoom function. Only called if the value is not 0
|
martin@0
|
48 if (Zoom!=0.0f) {
|
martin@0
|
49 switch (ZoomMethod) {
|
martin@0
|
50 case 0:
|
martin@0
|
51 dominanceZoom(w, x, y, z);
|
martin@0
|
52 break;
|
martin@0
|
53 case 1:
|
martin@0
|
54 pressZoom(w, x, y, z);
|
martin@0
|
55 break;
|
martin@0
|
56 case 2:
|
martin@0
|
57 pushZoom(w, x, y, z);
|
martin@0
|
58 break;
|
martin@0
|
59 case 3:
|
martin@0
|
60 focusZoom(w, x, y, z);
|
martin@0
|
61 break;
|
martin@0
|
62
|
martin@0
|
63 default:
|
martin@0
|
64 break;
|
martin@0
|
65 }
|
martin@0
|
66 }
|
martin@0
|
67
|
martin@0
|
68
|
martin@0
|
69 //Centre virtual mic
|
martin@0
|
70 centreMic(w, x);
|
martin@0
|
71
|
martin@0
|
72 };
|
martin@0
|
73
|
martin@0
|
74
|
martin@0
|
75 void Decoder::stereoDecoder(double &w, double &x, double &y, double &z)
|
martin@0
|
76 {
|
martin@0
|
77 //Sound field rotations. Only called if the value is not 0
|
martin@0
|
78 if (Rotate!=0.0f)
|
martin@0
|
79 rotateField(x, y);
|
martin@0
|
80
|
martin@0
|
81 if (Tilt!=0.0f)
|
martin@0
|
82 tiltField(y, z);
|
martin@0
|
83
|
martin@0
|
84 if (Tumble!=0.0f)
|
martin@0
|
85 tumbleField(x, z);
|
martin@0
|
86
|
martin@0
|
87
|
martin@0
|
88 //Zoom function. Only called if the value is not 0
|
martin@0
|
89 if (Zoom!=0.0f) {
|
martin@0
|
90 switch (ZoomMethod) {
|
martin@0
|
91 case 0:
|
martin@0
|
92 dominanceZoom(w, x, y, z);
|
martin@0
|
93 break;
|
martin@0
|
94 case 1:
|
martin@0
|
95 pressZoom(w, x, y, z);
|
martin@0
|
96 break;
|
martin@0
|
97 case 2:
|
martin@0
|
98 pushZoom(w, x, y, z);
|
martin@0
|
99 break;
|
martin@0
|
100 case 3:
|
martin@0
|
101 focusZoom(w, x, y, z);
|
martin@0
|
102 break;
|
martin@0
|
103
|
martin@0
|
104 default:
|
martin@0
|
105 break;
|
martin@0
|
106 }
|
martin@0
|
107 }
|
martin@0
|
108
|
martin@0
|
109
|
martin@0
|
110 switch (Mode) {
|
martin@0
|
111 case 0:
|
martin@0
|
112 xyDecode(w, x, y, z);
|
martin@0
|
113 break;
|
martin@0
|
114 case 1:
|
martin@0
|
115 msDecode(w, x, y, z);
|
martin@0
|
116 break;
|
martin@0
|
117 default:
|
martin@0
|
118 break;
|
martin@0
|
119 }
|
martin@0
|
120
|
martin@0
|
121
|
martin@0
|
122 if (RearVerb > -40) {
|
martin@0
|
123 rearVerb(w, x, y, z);
|
martin@0
|
124 }
|
martin@0
|
125
|
martin@0
|
126 if (HiVerb >-40) {
|
martin@0
|
127 hiVerb(w, x, y, z);
|
martin@0
|
128 }
|
martin@0
|
129 };
|
martin@0
|
130
|
martin@0
|
131
|
martin@0
|
132 void Decoder::twoOneDecoder(double &w, double &x, double &y, double &z)
|
martin@0
|
133 {
|
martin@0
|
134 //Sound field rotations. Only called if the value is not 0
|
martin@0
|
135 if (Rotate!=0.0f)
|
martin@0
|
136 rotateField(x, y);
|
martin@0
|
137
|
martin@0
|
138 if (Tilt!=0.0f)
|
martin@0
|
139 tiltField(y, z);
|
martin@0
|
140
|
martin@0
|
141 if (Tumble!=0.0f)
|
martin@0
|
142 tumbleField(x, z);
|
martin@0
|
143
|
martin@0
|
144
|
martin@0
|
145 //Zoom function. Only called if the value is not 0
|
martin@0
|
146 if (Zoom!=0.0f) {
|
martin@0
|
147 switch (ZoomMethod) {
|
martin@0
|
148 case 0:
|
martin@0
|
149 dominanceZoom(w, x, y, z);
|
martin@0
|
150 break;
|
martin@0
|
151 case 1:
|
martin@0
|
152 pressZoom(w, x, y, z);
|
martin@0
|
153 break;
|
martin@0
|
154 case 2:
|
martin@0
|
155 pushZoom(w, x, y, z);
|
martin@0
|
156 break;
|
martin@0
|
157 case 3:
|
martin@0
|
158 focusZoom(w, x, y, z);
|
martin@0
|
159 break;
|
martin@0
|
160
|
martin@0
|
161 default:
|
martin@0
|
162 break;
|
martin@0
|
163 }
|
martin@0
|
164 }
|
martin@0
|
165
|
martin@0
|
166 //Subwoofer signal and filtering
|
martin@0
|
167 subSignal(w);
|
martin@0
|
168 filterLF();
|
martin@0
|
169 if (Fc>0) {
|
martin@0
|
170 filterHF(w, x, y, z);
|
martin@0
|
171 }
|
martin@0
|
172
|
martin@0
|
173
|
martin@0
|
174
|
martin@0
|
175 //Front virtual mics
|
martin@0
|
176 switch (Mode) {
|
martin@0
|
177 case 0:
|
martin@0
|
178 xyDecode(w, x, y, z);
|
martin@0
|
179 break;
|
martin@0
|
180 case 1:
|
martin@0
|
181 msDecode(w, x, y, z);
|
martin@0
|
182 break;
|
martin@0
|
183 default:
|
martin@0
|
184 break;
|
martin@0
|
185 }
|
martin@0
|
186
|
martin@0
|
187
|
martin@0
|
188 //Reverbs
|
martin@0
|
189 if (RearVerb > -40) {
|
martin@0
|
190 rearVerb(w, x, y, z);
|
martin@0
|
191 }
|
martin@0
|
192
|
martin@0
|
193 if (HiVerb >-40) {
|
martin@0
|
194 hiVerb(w, x, y, z);
|
martin@0
|
195 }
|
martin@0
|
196
|
martin@0
|
197 };
|
martin@0
|
198
|
martin@0
|
199
|
martin@0
|
200
|
martin@0
|
201 void Decoder::lrcsDecoder(double &w, double &x, double &y, double &z)
|
martin@0
|
202 {
|
martin@0
|
203 //Sound field rotations. Only called if the value is not 0
|
martin@0
|
204 if (Rotate!=0.0f)
|
martin@0
|
205 rotateField(x, y);
|
martin@0
|
206
|
martin@0
|
207 if (Tilt!=0.0f)
|
martin@0
|
208 tiltField(y, z);
|
martin@0
|
209
|
martin@0
|
210 if (Tumble!=0.0f)
|
martin@0
|
211 tumbleField(x, z);
|
martin@0
|
212
|
martin@0
|
213
|
martin@0
|
214 //Zoom function. Only called if the value is not 0
|
martin@0
|
215 if (Zoom!=0.0f) {
|
martin@0
|
216 switch (ZoomMethod) {
|
martin@0
|
217 case 0:
|
martin@0
|
218 dominanceZoom(w, x, y, z);
|
martin@0
|
219 break;
|
martin@0
|
220 case 1:
|
martin@0
|
221 pressZoom(w, x, y, z);
|
martin@0
|
222 break;
|
martin@0
|
223 case 2:
|
martin@0
|
224 pushZoom(w, x, y, z);
|
martin@0
|
225 break;
|
martin@0
|
226 case 3:
|
martin@0
|
227 focusZoom(w, x, y, z);
|
martin@0
|
228 break;
|
martin@0
|
229
|
martin@0
|
230 default:
|
martin@0
|
231 break;
|
martin@0
|
232 }
|
martin@0
|
233 }
|
martin@0
|
234
|
martin@0
|
235
|
martin@0
|
236 //Front virtual mics
|
martin@0
|
237 switch (Mode) {
|
martin@0
|
238 case 0:
|
martin@0
|
239 xyDecode(w, x, y, z);
|
martin@0
|
240 break;
|
martin@0
|
241 case 1:
|
martin@0
|
242 msDecode(w, x, y, z);
|
martin@0
|
243 break;
|
martin@0
|
244 default:
|
martin@0
|
245 break;
|
martin@0
|
246 }
|
martin@0
|
247
|
martin@0
|
248 //Rear virtual mics
|
martin@0
|
249 switch (surMode) {
|
martin@0
|
250 case 0:
|
martin@0
|
251 xySurDecode(w, x, y, z);
|
martin@0
|
252 break;
|
martin@0
|
253 case 1:
|
martin@0
|
254 msSurDecode(w, x, y, z);
|
martin@0
|
255 break;
|
martin@0
|
256 default:
|
martin@0
|
257 break;
|
martin@0
|
258 }
|
martin@0
|
259
|
martin@0
|
260
|
martin@0
|
261 };
|
martin@0
|
262
|
martin@0
|
263
|
martin@0
|
264
|
martin@0
|
265 void Decoder::fiveDecoder(double &w, double &x, double &y, double &z)
|
martin@0
|
266 {
|
martin@0
|
267 //Sound field rotations. Only called if the value is not 0
|
martin@0
|
268 if (Rotate!=0.0f)
|
martin@0
|
269 rotateField(x, y);
|
martin@0
|
270
|
martin@0
|
271 if (Tilt!=0.0f)
|
martin@0
|
272 tiltField(y, z);
|
martin@0
|
273
|
martin@0
|
274 if (Tumble!=0.0f)
|
martin@0
|
275 tumbleField(x, z);
|
martin@0
|
276
|
martin@0
|
277
|
martin@0
|
278 //Zoom function. Only called if the value is not 0
|
martin@0
|
279 if (Zoom!=0.0f) {
|
martin@0
|
280 switch (ZoomMethod) {
|
martin@0
|
281 case 0:
|
martin@0
|
282 dominanceZoom(w, x, y, z);
|
martin@0
|
283 break;
|
martin@0
|
284 case 1:
|
martin@0
|
285 pressZoom(w, x, y, z);
|
martin@0
|
286 break;
|
martin@0
|
287 case 2:
|
martin@0
|
288 pushZoom(w, x, y, z);
|
martin@0
|
289 break;
|
martin@0
|
290 case 3:
|
martin@0
|
291 focusZoom(w, x, y, z);
|
martin@0
|
292 break;
|
martin@0
|
293
|
martin@0
|
294 default:
|
martin@0
|
295 break;
|
martin@0
|
296 }
|
martin@0
|
297 }
|
martin@0
|
298
|
martin@0
|
299
|
martin@0
|
300 //Centre virtual mic
|
martin@0
|
301 centreMic(w, x);
|
martin@0
|
302
|
martin@0
|
303 //Front virtual mics
|
martin@0
|
304 switch (Mode) {
|
martin@0
|
305 case 0:
|
martin@0
|
306 xyDecode(w, x, y, z);
|
martin@0
|
307 break;
|
martin@0
|
308 case 1:
|
martin@0
|
309 msDecode(w, x, y, z);
|
martin@0
|
310 break;
|
martin@0
|
311 default:
|
martin@0
|
312 break;
|
martin@0
|
313 }
|
martin@0
|
314
|
martin@0
|
315 //Rear virtual mics
|
martin@0
|
316 switch (surMode) {
|
martin@0
|
317 case 0:
|
martin@0
|
318 xySurDecode(w, x, y, z);
|
martin@0
|
319 break;
|
martin@0
|
320 case 1:
|
martin@0
|
321 msSurDecode(w, x, y, z);
|
martin@0
|
322 break;
|
martin@0
|
323 default:
|
martin@0
|
324 break;
|
martin@0
|
325 }
|
martin@0
|
326
|
martin@0
|
327
|
martin@0
|
328 };
|
martin@0
|
329
|
martin@0
|
330
|
martin@0
|
331
|
martin@0
|
332 void Decoder::fiveOneDecoder(double &w, double &x, double &y, double &z)
|
martin@0
|
333 {
|
martin@0
|
334 //Sound field rotations. Only called if the value is not 0
|
martin@0
|
335 if (Rotate!=0.0f)
|
martin@0
|
336 rotateField(x, y);
|
martin@0
|
337
|
martin@0
|
338 if (Tilt!=0.0f)
|
martin@0
|
339 tiltField(y, z);
|
martin@0
|
340
|
martin@0
|
341 if (Tumble!=0.0f)
|
martin@0
|
342 tumbleField(x, z);
|
martin@0
|
343
|
martin@0
|
344
|
martin@0
|
345 //Zoom function. Only called if the value is not 0
|
martin@0
|
346 if (Zoom!=0.0f) {
|
martin@0
|
347 switch (ZoomMethod) {
|
martin@0
|
348 case 0:
|
martin@0
|
349 dominanceZoom(w, x, y, z);
|
martin@0
|
350 break;
|
martin@0
|
351 case 1:
|
martin@0
|
352 pressZoom(w, x, y, z);
|
martin@0
|
353 break;
|
martin@0
|
354 case 2:
|
martin@0
|
355 pushZoom(w, x, y, z);
|
martin@0
|
356 break;
|
martin@0
|
357 case 3:
|
martin@0
|
358 focusZoom(w, x, y, z);
|
martin@0
|
359 break;
|
martin@0
|
360
|
martin@0
|
361 default:
|
martin@0
|
362 break;
|
martin@0
|
363 }
|
martin@0
|
364 }
|
martin@0
|
365
|
martin@0
|
366 //Subwoofer signal and filtering
|
martin@0
|
367 subSignal(w);
|
martin@0
|
368 filterLF();
|
martin@0
|
369 if (Fc>0) {
|
martin@0
|
370 filterHF(w, x, y, z);
|
martin@0
|
371 }
|
martin@0
|
372
|
martin@0
|
373 //Centre virtual mic
|
martin@0
|
374 centreMic(w, x);
|
martin@0
|
375
|
martin@0
|
376 //Front virtual mics
|
martin@0
|
377 switch (Mode) {
|
martin@0
|
378 case 0:
|
martin@0
|
379 xyDecode(w, x, y, z);
|
martin@0
|
380 break;
|
martin@0
|
381 case 1:
|
martin@0
|
382 msDecode(w, x, y, z);
|
martin@0
|
383 break;
|
martin@0
|
384 default:
|
martin@0
|
385 break;
|
martin@0
|
386 }
|
martin@0
|
387
|
martin@0
|
388 //Rear virtual mics
|
martin@0
|
389 switch (surMode) {
|
martin@0
|
390 case 0:
|
martin@0
|
391 xySurDecode(w, x, y, z);
|
martin@0
|
392 break;
|
martin@0
|
393 case 1:
|
martin@0
|
394 msSurDecode(w, x, y, z);
|
martin@0
|
395 break;
|
martin@0
|
396 default:
|
martin@0
|
397 break;
|
martin@0
|
398 }
|
martin@0
|
399
|
martin@0
|
400
|
martin@0
|
401 };
|
martin@0
|
402
|
martin@0
|
403
|
martin@0
|
404
|
martin@0
|
405
|
martin@0
|
406
|
martin@0
|
407
|
martin@0
|
408 //SoundField Rotations
|
martin@0
|
409 void Decoder::rotateField(double &x, double &y)
|
martin@0
|
410 {
|
martin@1
|
411 double temp = x;
|
martin@0
|
412 x = cos(degRad(Rotate))*temp - sin(degRad(Rotate))*y;
|
martin@0
|
413 y = cos(degRad(Rotate))*y + sin(degRad(Rotate))*temp;
|
martin@0
|
414
|
martin@0
|
415 };
|
martin@0
|
416
|
martin@0
|
417
|
martin@0
|
418 void Decoder::tiltField(double &y, double &z)
|
martin@0
|
419 {
|
martin@1
|
420 double temp = y;
|
martin@0
|
421 y = cos(degRad(Tilt))*temp - sin(degRad(Tilt))*z;
|
martin@0
|
422 z = cos(degRad(Tilt))*z + sin(degRad(Tilt))*temp;
|
martin@0
|
423 };
|
martin@0
|
424
|
martin@0
|
425
|
martin@0
|
426 void Decoder::tumbleField(double &x, double &z)
|
martin@0
|
427 {
|
martin@1
|
428 double temp = x;
|
martin@0
|
429 x = cos(degRad(Tumble))*temp - sin(degRad(Tumble))*z;
|
martin@0
|
430 z = cos(degRad(Tumble))*z + sin(degRad(Tumble))*temp;
|
martin@0
|
431 };
|
martin@0
|
432
|
martin@0
|
433
|
martin@0
|
434
|
martin@0
|
435
|
martin@0
|
436 //Zoom Methods
|
martin@0
|
437 void Decoder::dominanceZoom(double &w, double &x, double &y, double &z)
|
martin@0
|
438 {
|
martin@0
|
439 double lambda = pow(10,(Zoom*0.24/20));
|
martin@1
|
440 double temp[4];
|
martin@1
|
441 temp[0]=w;
|
martin@1
|
442 temp[1]=x;
|
martin@1
|
443 temp[2]=y;
|
martin@1
|
444 temp[3]=z;
|
martin@0
|
445
|
martin@1
|
446 w = 0.5*(lambda+pow(lambda,-1))*temp[0] + pow(8,-0.5)*(lambda-pow(lambda,-1))*temp[1];
|
martin@1
|
447 x = 0.5*(lambda+pow(lambda,-1))*temp[1] + pow(2,-0.5)*(lambda-pow(lambda,-1))*temp[0];
|
martin@0
|
448 };
|
martin@0
|
449
|
martin@0
|
450
|
martin@0
|
451 void Decoder::pressZoom(double &w, double &x, double &y, double &z)
|
martin@0
|
452 {
|
martin@1
|
453 double temp[4];
|
martin@1
|
454 temp[0]=w;
|
martin@1
|
455 temp[1]=x;
|
martin@1
|
456 temp[2]=y;
|
martin@1
|
457 temp[3]=z;
|
martin@0
|
458
|
martin@1
|
459 x = (sqrt(2.0)*std::abs(sin(degRad(Zoom*0.9)))*sin(degRad(Zoom*0.9))*temp[0]) + (pow(cos(degRad(Zoom*0.9)),2)*temp[1]);
|
martin@1
|
460 y = cos(degRad(Zoom*0.9))*temp[2];
|
martin@1
|
461 z = cos(degRad(Zoom*0.9))*temp[3];
|
martin@0
|
462 };
|
martin@0
|
463
|
martin@0
|
464
|
martin@0
|
465 void Decoder::pushZoom(double &w, double &x, double &y, double &z)
|
martin@0
|
466 {
|
martin@1
|
467 double temp[4];
|
martin@1
|
468 temp[0]=w;
|
martin@1
|
469 temp[1]=x;
|
martin@1
|
470 temp[2]=y;
|
martin@1
|
471 temp[3]=z;
|
martin@0
|
472
|
martin@1
|
473 x = (sqrt(2.0)*std::abs(sin(degRad(Zoom*0.9)))*sin(degRad(Zoom*0.9))*temp[0]) + (pow(cos(degRad(Zoom*0.9)),2)*temp[1]);
|
martin@1
|
474 y = pow(cos(degRad(Zoom*0.9)),2)*temp[2];
|
martin@1
|
475 z = pow(cos(degRad(Zoom*0.9)),2)*temp[3];
|
martin@0
|
476 };
|
martin@0
|
477
|
martin@0
|
478
|
martin@0
|
479 void Decoder::focusZoom(double &w, double &x, double &y, double &z)
|
martin@0
|
480 {
|
martin@1
|
481 double temp[4];
|
martin@1
|
482 temp[0]=w;
|
martin@1
|
483 temp[1]=x;
|
martin@1
|
484 temp[2]=y;
|
martin@1
|
485 temp[3]=z;
|
martin@0
|
486
|
martin@1
|
487 w = ((1/(1+std::abs(sin(degRad(Zoom*0.9)))))*temp[0]) + ((1/sqrt(2.0))*(sin(degRad(Zoom*0.9))/(1+std::abs(sin(degRad(Zoom*0.9))))))* temp[1];
|
martin@1
|
488 x = sqrt(2.0)*(sin(degRad(Zoom*0.9))/(1+std::abs(sin(degRad(Zoom*0.9)))))*temp[0] + (1/(1+std::abs(sin(degRad(Zoom*0.9)))))*temp[1];
|
martin@1
|
489 y = sqrt((1-std::abs(sin(degRad(Zoom*0.9))))/(1+std::abs(sin(degRad(Zoom*0.9)))))*temp[2];
|
martin@1
|
490 z = sqrt((1-std::abs(sin(degRad(Zoom*0.9))))/(1+std::abs(sin(degRad(Zoom*0.9)))))*temp[3];
|
martin@0
|
491 };
|
martin@0
|
492
|
martin@0
|
493
|
martin@0
|
494
|
martin@0
|
495 //Stereo Decoders
|
martin@0
|
496 void Decoder::xyDecode(double &w, double &x, double &y, double &z)
|
martin@0
|
497 {
|
martin@0
|
498 outputL = Pattern*sqrt(2.0)*w + (1-Pattern)*(cos(degRad(Width))*x + sin(degRad(Width))*y);
|
martin@0
|
499 outputR = Pattern*sqrt(2.0)*w + (1-Pattern)*(cos(degRad(Width))*x - sin(degRad(Width))*y);
|
martin@0
|
500 };
|
martin@0
|
501
|
martin@0
|
502
|
martin@0
|
503 void Decoder::msDecode(double &w, double &x, double &y, double &z)
|
martin@0
|
504 {
|
martin@0
|
505 outputL = (cos(degRad(Width))*(Pattern*w*sqrt(2.0) + (1-Pattern)*x)) + (sin(degRad(Width))*y);
|
martin@0
|
506 outputR = (cos(degRad(Width))*(Pattern*w*sqrt(2.0) + (1-Pattern)*x)) - (sin(degRad(Width))*y);
|
martin@0
|
507 };
|
martin@0
|
508
|
martin@0
|
509
|
martin@0
|
510 //Stereo Reverbs
|
martin@0
|
511 void Decoder::rearVerb(double &w, double &x, double &y, double &z)
|
martin@0
|
512 {
|
martin@0
|
513 switch (Mode) {
|
martin@0
|
514 case 0:
|
martin@0
|
515 outputL += (RearVerbPattern*sqrt(2.0)*w + (1-RearVerbPattern)*(cos(degRad(RearVerbWidth))*-x + sin(degRad(RearVerbWidth))*y))*pow(10, RearVerb/20);
|
martin@0
|
516 outputR += (RearVerbPattern*sqrt(2.0)*w + (1-RearVerbPattern)*(cos(degRad(RearVerbWidth))*-x - sin(degRad(RearVerbWidth))*y))*pow(10, RearVerb/20);
|
martin@0
|
517 break;
|
martin@0
|
518 case 1:
|
martin@0
|
519 outputL += ((cos(degRad(RearVerbWidth))*(RearVerbPattern*w*sqrt(2.0) + (1-RearVerbPattern)*-x)) + (sin(degRad(RearVerbWidth))*y))*pow(10, RearVerb/20);
|
martin@0
|
520 outputR += ((cos(degRad(RearVerbWidth))*(RearVerbPattern*w*sqrt(2.0) + (1-RearVerbPattern)*-x)) - (sin(degRad(RearVerbWidth))*y))*pow(10, RearVerb/20);
|
martin@0
|
521 break;
|
martin@0
|
522 }
|
martin@0
|
523 };
|
martin@0
|
524
|
martin@0
|
525 void Decoder::hiVerb(double &w, double &x, double &y, double &z)
|
martin@0
|
526 {
|
martin@0
|
527 switch (Mode) {
|
martin@0
|
528 case 0:
|
martin@0
|
529 outputL += (HiVerbPattern*sqrt(2.0)*w + (1-HiVerbPattern)*(cos(degRad(HiVerbWidth))*z + sin(degRad(HiVerbWidth))*y))*pow(10, HiVerb/20);
|
martin@0
|
530 outputR += (HiVerbPattern*sqrt(2.0)*w + (1-HiVerbPattern)*(cos(degRad(HiVerbWidth))*z - sin(degRad(HiVerbWidth))*y))*pow(10, HiVerb/20);
|
martin@0
|
531 break;
|
martin@0
|
532 case 1:
|
martin@0
|
533 outputL += ((cos(degRad(HiVerbWidth))*(HiVerbPattern*w*sqrt(2.0) + (1-HiVerbPattern)*z)) + (sin(degRad(HiVerbWidth))*y))*pow(10, HiVerb/20);
|
martin@0
|
534 outputR += ((cos(degRad(HiVerbWidth))*(HiVerbPattern*w*sqrt(2.0) + (1-HiVerbPattern)*z)) - (sin(degRad(HiVerbWidth))*y))*pow(10, HiVerb/20);
|
martin@0
|
535 break;
|
martin@0
|
536 }
|
martin@0
|
537 };
|
martin@0
|
538
|
martin@0
|
539
|
martin@0
|
540 //Surround Decoders
|
martin@0
|
541 void Decoder::xySurDecode(double &w, double &x, double &y, double &z)
|
martin@0
|
542 {
|
martin@0
|
543 outputSL = (surPattern*sqrt(2.0)*w + (1-surPattern)*(cos(degRad(surWidth))*-x + sin(degRad(surWidth))*y))*surGain;
|
martin@0
|
544 outputSR = (surPattern*sqrt(2.0)*w + (1-surPattern)*(cos(degRad(surWidth))*-x - sin(degRad(surWidth))*y))*surGain;
|
martin@0
|
545 };
|
martin@0
|
546
|
martin@0
|
547
|
martin@0
|
548 void Decoder::msSurDecode(double &w, double &x, double &y, double &z)
|
martin@0
|
549 {
|
martin@0
|
550 outputSL = ((cos(degRad(surWidth))*(surPattern*w*sqrt(2.0) + (1-surPattern)*-x)) + (sin(degRad(surWidth))*y))*surGain;
|
martin@0
|
551 outputSR = ((cos(degRad(surWidth))*(surPattern*w*sqrt(2.0) + (1-surPattern)*-x)) - (sin(degRad(surWidth))*y))*surGain;
|
martin@0
|
552 };
|
martin@0
|
553
|
martin@0
|
554
|
martin@0
|
555 void Decoder::centreMic(double &w, double &x)
|
martin@0
|
556 {
|
martin@1
|
557 outputC = (centrePattern*sqrt(2.0)*w + (1-centrePattern)*x) * centreGain;
|
martin@0
|
558 };
|
martin@0
|
559
|
martin@0
|
560
|
martin@0
|
561 void Decoder::subSignal(double &w)
|
martin@0
|
562 {
|
martin@0
|
563 outputS = sqrt(2.0)*w*subGain;
|
martin@0
|
564 };
|
martin@0
|
565
|
martin@0
|
566
|
martin@0
|
567 void Decoder::filterCoefs(){
|
martin@0
|
568 int k = tan((M_PI*abs(Fc))/Fs);
|
martin@0
|
569 double denominator = pow(k, 2) + 2*k + 1;
|
martin@0
|
570
|
martin@0
|
571 //a values
|
martin@0
|
572 a[0] = 1;
|
martin@0
|
573 a[1] = (2*(pow(k,2)-1))/denominator;
|
martin@0
|
574 a[2] = (pow(k, 2) - 2*k + 1)/denominator;
|
martin@0
|
575
|
martin@0
|
576 //b LF value
|
martin@0
|
577 bLF[0] = pow(k, 2) / denominator;
|
martin@0
|
578 bLF[1] = 2 * bLF[0];
|
martin@0
|
579 bLF[2] = bLF[0];
|
martin@0
|
580
|
martin@0
|
581 //b HF values
|
martin@0
|
582 bHF[0] = 1/denominator;
|
martin@0
|
583 bHF[1] = -2 * bHF[0];
|
martin@0
|
584 bHF[2] = bHF[0];
|
martin@0
|
585 };
|
martin@0
|
586
|
martin@0
|
587
|
martin@0
|
588 void Decoder::filterLF(){
|
martin@0
|
589 double outLF;
|
martin@0
|
590
|
martin@1
|
591 //LF Filtering
|
martin@1
|
592 outLF = (double)outputS*bLF[0] + prevInS[0]*bLF[1] + prevInS[1]*bLF[2] + prevOutS[0]*a[1] + prevOutS[1]*a[2];
|
martin@0
|
593
|
martin@1
|
594 //Previous Input and Output Samples
|
martin@1
|
595 prevOutS[1] = prevOutS[0];
|
martin@1
|
596 prevOutS[0] = outLF;
|
martin@1
|
597 prevInS[1] = prevInS[0];
|
martin@1
|
598 prevInS[0] = (double)outputS;
|
martin@0
|
599
|
martin@1
|
600 //Final subwoofer Output
|
martin@0
|
601 outputS = outLF;
|
martin@0
|
602 };
|
martin@0
|
603
|
martin@0
|
604
|
martin@0
|
605 void Decoder::filterHF(double &w, double &x, double &y, double &z){
|
martin@0
|
606 double outHFw, outHFx, outHFy, outHFz;
|
martin@0
|
607
|
martin@0
|
608 //w Filtering
|
martin@0
|
609 outHFw = -((double)w*bHF[0] + prevInw[0]*bHF[1] + prevInw[1]*bHF[2] + prevOutw[0]*a[1] + prevOutw[1]*a[2]);
|
martin@0
|
610 prevOutw[1] = prevOutw[0];
|
martin@0
|
611 prevOutw[0] = outHFw;
|
martin@0
|
612 prevInw[1] = prevInw[0];
|
martin@0
|
613 prevInw[0] = (double)w;
|
martin@0
|
614 w = outHFw;
|
martin@0
|
615
|
martin@0
|
616 //x Filtering
|
martin@0
|
617 outHFx = -((double)x*bHF[0] + prevInx[0]*bHF[1] + prevInx[1]*bHF[2] + prevOutx[0]*a[1] + prevOutx[1]*a[2]);
|
martin@0
|
618 prevOutx[1] = prevOutx[0];
|
martin@0
|
619 prevOutx[0] = outHFx;
|
martin@0
|
620 prevInx[1] = prevInx[0];
|
martin@0
|
621 prevInx[0] = (double)x;
|
martin@0
|
622 x = outHFx;
|
martin@0
|
623
|
martin@0
|
624 //y Filtering
|
martin@0
|
625 outHFy = -((double)y*bHF[0] + prevIny[0]*bHF[1] + prevIny[1]*bHF[2] + prevOuty[0]*a[1] + prevOuty[1]*a[2]);
|
martin@0
|
626 prevOuty[1] = prevOuty[0];
|
martin@0
|
627 prevOuty[0] = outHFy;
|
martin@0
|
628 prevIny[1] = prevIny[0];
|
martin@0
|
629 prevIny[0] = (double)y;
|
martin@0
|
630 y = outHFy;
|
martin@0
|
631
|
martin@0
|
632 //z Filtering
|
martin@0
|
633 outHFz = -((double)z*bHF[0] + prevInz[0]*bHF[1] + prevInz[1]*bHF[2] + prevOutz[0]*a[1] + prevOutz[1]*a[2]);
|
martin@0
|
634 prevOutz[1] = prevOutz[0];
|
martin@0
|
635 prevOutz[0] = outHFz;
|
martin@0
|
636 prevInz[1] = prevInz[0];
|
martin@0
|
637 prevInz[0] = (double)z;
|
martin@0
|
638 z = outHFz;
|
martin@0
|
639 };
|
martin@0
|
640
|
martin@0
|
641
|
martin@0
|
642 void Decoder::clearFilter(){
|
martin@0
|
643 for (int i=0; i<2; i++) {
|
martin@1
|
644 prevInS[i] = 0;
|
martin@1
|
645 prevOutS[i] = 0;
|
martin@0
|
646 prevInw[i] = 0;
|
martin@0
|
647 prevOutw[i] = 0;
|
martin@0
|
648 prevInx[i] = 0;
|
martin@0
|
649 prevOutx[i] = 0;
|
martin@0
|
650 prevIny[i] = 0;
|
martin@0
|
651 prevOuty[i] = 0;
|
martin@0
|
652 prevInz[i] = 0;
|
martin@0
|
653 prevOutz[i] = 0;
|
martin@0
|
654 }
|
martin@0
|
655 }; |