annotate Source/Decoder.cpp @ 13:989865d55c73 tip

Commit.
author martinm_home <martin.morrell@eecs.qmul.ac.uk>
date Thu, 27 Sep 2012 23:30:29 +0100
parents 87dc3d84c120
children
rev   line source
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 };