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