Mercurial > hg > ambi-plugin
view Source/Decoder.cpp @ 12:87dc3d84c120
Addressed the load program defaults over user settings 'feature'.
Removed isChild on objects that are added before the frame creation since a)they're always there and b) doesn't write to all displays present.
author | martinm_home <martin.morrell@eecs.qmul.ac.uk> |
---|---|
date | Thu, 27 Sep 2012 23:29:16 +0100 |
parents | 76e2e62635b4 |
children |
line wrap: on
line source
/* * Decoder.cpp * ClassicAmbiDec * * Created by Martin Morrell on 14/06/2012. * Copyright 2012 Queen Mary University of London. All rights reserved. * */ #include "Decoder.h" #define _USE_MATH_DEFINES #include <cmath> #include <stdlib.h> #define RearVerbWidth 55 //Rear Verb Microphone Width #define RearVerbPattern 0.5 //Rear Verb Microphone Pattern #define HiVerbWidth 30 //Hi Verb Microphone Width #define HiVerbPattern 0.5 //Hi Verb Microphone Pattern Decoder::Decoder() { // myDecoder parameters Rotate=0.0; Tilt=0.0; Tumble=0.0; Zoom=0.0; ZoomMethod=0.0; Width=45.0; Pattern=0.5; Mode=0; RearVerb=-100; HiVerb=-100; surMode=0; surPattern=0.5; surWidth=60.0; surGain = 0.0; Fc = 120; centrePattern=0.5; centreGain=0.0; subGain=0.0; Fs = 44100; filterCoefs(); decoderMode=2; //Default mode is Stereo channelOrder=1; mode5x=0; // Zero up decoder outputs as a safety outputL=0.0; outputR=0.0; outputC=0.0; outputS=0.0; outputSL=0.0; outputSR=0.0; }; //Conversion Functions double Decoder::degRad(double angle) { return (angle/180*M_PI); }; double Decoder::radDeg(double angle) { return (angle/M_PI*180); }; //Overall Function int Decoder::processDecoder(double &w, double &x, double &y, double &z) { //Sound field rotations. Only called if the value is not 0 if (Rotate!=0.0f) rotateField(x, y); if (Tilt!=0.0f) tiltField(y, z); if (Tumble!=0.0f) tumbleField(x, z); //Zoom function. Only called if the value is not 0 if (Zoom!=0.0f) { switch (ZoomMethod) { case 0: dominanceZoom(w, x, y, z); break; case 1: pressZoom(w, x, y, z); break; case 2: pushZoom(w, x, y, z); break; case 3: focusZoom(w, x, y, z); break; default: break; } } switch (decoderMode) { case 1: monoDecoder(w, x, y, z); if (channelOrder==0) { output[0]=outputC; return 1; } else if (channelOrder==1) { output[0]=0; output[1]=0; output[2]=outputC; output[3]=0; output[4]=0; output[5]=0; return 6; } else { return 0; } break; case 2: stereoDecoder(w, x, y, z); if (channelOrder==0) { output[0]=outputL; output[1]=outputR; return 2; } else if (channelOrder==1) { output[0]=outputL; output[1]=outputR; output[2]=0; output[3]=0; output[4]=0; output[5]=0; return 6; } else { return 0; } break; case 3: { twoOneDecoder(w, x, y, z); if (channelOrder==0) { output[0]=outputL; output[1]=outputR; output[2]=outputS; return 3; } else if (channelOrder==1) { output[0]=outputL; output[1]=outputR; output[2]=0; output[3]=outputS; output[4]=0; output[5]=0; return 6; } else { return 0; } break; } case 4: quadDecoder(w, x, y, z); if (channelOrder==0) { output[0]=outputL; output[1]=outputR; output[2]=outputSR; output[3]=outputSR; return 4; } else if (channelOrder==1) { output[0]=outputL; output[1]=outputR; output[2]=0; output[3]=0; output[4]=outputSL; output[5]=outputSR; return 6; break; } else { return 0; } case 5: fiveDecoder(w, x, y, z); if (channelOrder==0) { output[0]=outputL; output[1]=outputR; output[2]=outputC; output[3]=outputSL; output[4]=outputSR; return 5; } else if (channelOrder==1) { output[0]=outputL; output[1]=outputR; output[2]=outputC; output[3]=0; output[4]=outputSL; output[5]=outputSR; return 6; break; } else { return 0; } case 6: fiveOneDecoder(w, x, y, z); if (channelOrder==0) { output[0]=outputL; output[1]=outputR; output[2]=outputC; output[3]=outputS; output[4]=outputSL; output[5]=outputSR; return 6; } else if (channelOrder==1) { output[0]=outputL; output[1]=outputR; output[2]=outputC; output[3]=outputS; output[4]=outputSL; output[5]=outputSR; return 6; break; } else { return 0; } default: return 0; break; } }; //Decoder Mode Functions void Decoder::monoDecoder(double &w, double &x, double &y, double &z)//NOT USED { //Centre virtual mic centreMic(w, x); }; void Decoder::stereoDecoder(double &w, double &x, double &y, double &z) { switch (Mode) { case 0: xyDecode(w, x, y, z); break; case 1: msDecode(w, x, y, z); break; default: break; } if (RearVerb > -40) { rearVerb(w, x, y, z); } if (HiVerb >-40) { hiVerb(w, x, y, z); } }; void Decoder::twoOneDecoder(double &w, double &x, double &y, double &z) { //Subwoofer signal and filtering filterLF(w); filterHF(w, x, y, z); //Front virtual mics switch (Mode) { case 0: xyDecode(w, x, y, z); break; case 1: msDecode(w, x, y, z); break; default: break; } //Reverbs if (RearVerb > -40) { rearVerb(w, x, y, z); } if (HiVerb >-40) { hiVerb(w, x, y, z); } }; void Decoder::quadDecoder(double &w, double &x, double &y, double &z) { //Front virtual mics switch (Mode) { case 0: xyDecode(w, x, y, z); break; case 1: msDecode(w, x, y, z); break; default: break; } //Rear virtual mics switch (surMode) { case 0: xySurDecode(w, x, y, z); break; case 1: msSurDecode(w, x, y, z); break; default: break; } }; void Decoder::fiveDecoder(double &w, double &x, double &y, double &z) { switch (mode5x) { case 0://Mic Pattern Decode { //Centre virtual mic centreMic(w, x); //Front virtual mics switch (Mode) { case 0: { xyDecode(w, x, y, z); break; } case 1: { msDecode(w, x, y, z); break; } default: break; } //Rear virtual mics switch (surMode) { case 0: { xySurDecode(w, x, y, z); break; } case 1: { msSurDecode(w, x, y, z); break; } default: break; } break; } case 1://Heller 1 Decode - little centre { heller1(w, x, y, z); break; } case 2://Heller 2 Decode - More centre { heller2(w, x, y, z); break; } default: break; } }; void Decoder::fiveOneDecoder(double &w, double &x, double &y, double &z) { //Subwoofer signal and filtering filterLF(w); filterHF(w, x, y, z); switch (mode5x) { case 0://Mic Pattern Decode { //Centre virtual mic centreMic(w, x); //Front virtual mics switch (Mode) { case 0: { xyDecode(w, x, y, z); break; } case 1: { msDecode(w, x, y, z); break; } default: break; } //Rear virtual mics switch (surMode) { case 0: { xySurDecode(w, x, y, z); break; } case 1: { msSurDecode(w, x, y, z); break; } default: break; } break; } case 1://Heller 1 Decode - little centre { heller1(w, x, y, z); break; } case 2://Heller 2 Decode - More centre { heller2(w, x, y, z); break; } default: break; } }; //Sound Field Rotations void Decoder::rotateField(double &x, double &y) { double temp = x; x = cos(degRad(Rotate))*temp - sin(degRad(Rotate))*y; y = cos(degRad(Rotate))*y + sin(degRad(Rotate))*temp; }; void Decoder::tiltField(double &y, double &z) { double temp = y; y = cos(degRad(Tilt))*temp - sin(degRad(Tilt))*z; z = cos(degRad(Tilt))*z + sin(degRad(Tilt))*temp; }; void Decoder::tumbleField(double &x, double &z) { double temp = x; x = cos(degRad(Tumble))*temp - sin(degRad(Tumble))*z; z = cos(degRad(Tumble))*z + sin(degRad(Tumble))*temp; }; //Zoom Methods void Decoder::dominanceZoom(double &w, double &x, double &y, double &z) { double lambda = pow(10,(Zoom*0.24/20)); double temp[4]; temp[0]=w; temp[1]=x; temp[2]=y; temp[3]=z; w = 0.5*(lambda+pow(lambda,-1))*temp[0] + pow(8,-0.5)*(lambda-pow(lambda,-1))*temp[1]; x = 0.5*(lambda+pow(lambda,-1))*temp[1] + pow(2,-0.5)*(lambda-pow(lambda,-1))*temp[0]; }; void Decoder::pressZoom(double &w, double &x, double &y, double &z) { double temp[4]; temp[0]=w; temp[1]=x; temp[2]=y; temp[3]=z; 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]); y = cos(degRad(Zoom*0.9))*temp[2]; z = cos(degRad(Zoom*0.9))*temp[3]; }; void Decoder::pushZoom(double &w, double &x, double &y, double &z) { double temp[4]; temp[0]=w; temp[1]=x; temp[2]=y; temp[3]=z; 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]); y = pow(cos(degRad(Zoom*0.9)),2)*temp[2]; z = pow(cos(degRad(Zoom*0.9)),2)*temp[3]; }; void Decoder::focusZoom(double &w, double &x, double &y, double &z) { double temp[4]; temp[0]=w; temp[1]=x; temp[2]=y; temp[3]=z; 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]; 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]; y = sqrt((1-std::abs(sin(degRad(Zoom*0.9))))/(1+std::abs(sin(degRad(Zoom*0.9)))))*temp[2]; z = sqrt((1-std::abs(sin(degRad(Zoom*0.9))))/(1+std::abs(sin(degRad(Zoom*0.9)))))*temp[3]; }; //Stereo Microphone Pairs void Decoder::xyDecode(double &w, double &x, double &y, double &z) { outputL = Pattern*sqrt(2.0)*w + (1-Pattern)*(cos(degRad(Width))*x + sin(degRad(Width))*y); outputR = Pattern*sqrt(2.0)*w + (1-Pattern)*(cos(degRad(Width))*x - sin(degRad(Width))*y); }; void Decoder::msDecode(double &w, double &x, double &y, double &z) { outputL = (cos(degRad(Width))*(Pattern*w*sqrt(2.0) + (1-Pattern)*x)) + (sin(degRad(Width))*y); outputR = (cos(degRad(Width))*(Pattern*w*sqrt(2.0) + (1-Pattern)*x)) - (sin(degRad(Width))*y); }; //Stereo Reverbs void Decoder::rearVerb(double &w, double &x, double &y, double &z) { switch (Mode) { case 0: outputL += (RearVerbPattern*sqrt(2.0)*w + (1-RearVerbPattern)*(cos(degRad(RearVerbWidth))*-x + sin(degRad(RearVerbWidth))*y))*pow(10, RearVerb/20); outputR += (RearVerbPattern*sqrt(2.0)*w + (1-RearVerbPattern)*(cos(degRad(RearVerbWidth))*-x - sin(degRad(RearVerbWidth))*y))*pow(10, RearVerb/20); break; case 1: outputL += ((cos(degRad(RearVerbWidth))*(RearVerbPattern*w*sqrt(2.0) + (1-RearVerbPattern)*-x)) + (sin(degRad(RearVerbWidth))*y))*pow(10, RearVerb/20); outputR += ((cos(degRad(RearVerbWidth))*(RearVerbPattern*w*sqrt(2.0) + (1-RearVerbPattern)*-x)) - (sin(degRad(RearVerbWidth))*y))*pow(10, RearVerb/20); break; } }; void Decoder::hiVerb(double &w, double &x, double &y, double &z) { switch (Mode) { case 0: outputL += (HiVerbPattern*sqrt(2.0)*w + (1-HiVerbPattern)*(cos(degRad(HiVerbWidth))*z + sin(degRad(HiVerbWidth))*y))*pow(10, HiVerb/20); outputR += (HiVerbPattern*sqrt(2.0)*w + (1-HiVerbPattern)*(cos(degRad(HiVerbWidth))*z - sin(degRad(HiVerbWidth))*y))*pow(10, HiVerb/20); break; case 1: outputL += ((cos(degRad(HiVerbWidth))*(HiVerbPattern*w*sqrt(2.0) + (1-HiVerbPattern)*z)) + (sin(degRad(HiVerbWidth))*y))*pow(10, HiVerb/20); outputR += ((cos(degRad(HiVerbWidth))*(HiVerbPattern*w*sqrt(2.0) + (1-HiVerbPattern)*z)) - (sin(degRad(HiVerbWidth))*y))*pow(10, HiVerb/20); break; } }; //Surround Microphone Pairs void Decoder::xySurDecode(double &w, double &x, double &y, double &z) { outputSL = (surPattern*sqrt(2.0)*w + (1-surPattern)*(cos(degRad(surWidth))*-x + sin(degRad(surWidth))*y))*pow(10, surGain/20); outputSR = (surPattern*sqrt(2.0)*w + (1-surPattern)*(cos(degRad(surWidth))*-x - sin(degRad(surWidth))*y))*pow(10, surGain/20); }; void Decoder::msSurDecode(double &w, double &x, double &y, double &z) { outputSL = ((cos(degRad(surWidth))*(surPattern*w*sqrt(2.0) + (1-surPattern)*-x)) + (sin(degRad(surWidth))*y))*pow(10, surGain/20); outputSR = ((cos(degRad(surWidth))*(surPattern*w*sqrt(2.0) + (1-surPattern)*-x)) - (sin(degRad(surWidth))*y))*pow(10, surGain/20); }; //Centre Microphone Pairs void Decoder::centreMic(double &w, double &x) { outputC = (centrePattern*sqrt(2.0)*w + (1-centrePattern)*x) * pow(10, centreGain/20); }; //Heller 5.x Decoding void Decoder::heller1(double &w, double &x, double &y, double &z) { outputL = (0.28205165*w +0.24760232*x +0.18790454*y)*1.40171951577097; outputR = (0.28204229*w +0.24758662*x -0.18792311*y)*1.40171951577097; outputC = (-0.04881270*w -0.02756928*x +0.00001724*y)*1.40171951577097; outputSL = (0.44947336*w -0.23381746*x +0.31911519*y)*1.40171951577097; outputSR = (0.44945895*w -0.23380219*x -0.31911386*y)*1.40171951577097; }; void Decoder::heller2(double &w, double &x, double &y, double &z) { outputL = (0.21426224*w +0.19218459*x +0.20409261*y)*1.38921598327229; outputR = (0.21426400*w +0.19218379*x -0.20409362*y)*1.38921598327229; outputC = (0.09993309*w +0.15577050*x +0.00000000*y)*1.38921598327229; outputSL = (0.44287748*w -0.27006948*x +0.30405695*y)*1.38921598327229; outputSR = (0.44287676*w -0.27006941*x -0.30405595*y)*1.38921598327229; }; //Second Order IIR Filter void Decoder::filterCoefs(){ double k = tan((M_PI*Fc)/Fs); double denominator = pow(k, 2.0) + 2.0*k + 1; clearFilter(); //a values a[0] = 1; a[1] = (2.0*(pow(k, 2.0)-1))/denominator; a[2] = (pow(k, 2.0) - 2.0*k + 1)/denominator; //b LF value bLF[0] = pow(k, 2.0) / denominator; bLF[1] = 2.0 * bLF[0]; bLF[2] = bLF[0]; //b HF values bHF[0] = 1/denominator; bHF[1] = -2 * bHF[0]; bHF[2] = bHF[0]; }; void Decoder::filterLF(double &w){ double outLF; //LF Filtering outLF = w*sqrt(2.0)*bLF[0] + prevInS[0]*bLF[1] + prevInS[1]*bLF[2] - prevOutS[0]*a[1] - prevOutS[1]*a[2]; //Previous Input and Output Samples prevOutS[1] = prevOutS[0]; prevOutS[0] = outLF; prevInS[1] = prevInS[0]; prevInS[0] = w*sqrt(2.0); //Final subwoofer Output outputS = outLF*pow(10, subGain/20); }; void Decoder::filterHF(double &w, double &x, double &y, double &z){ double outHFw, outHFx, outHFy, outHFz; //w Filtering outHFw = w*bHF[0] + prevInw[0]*bHF[1] + prevInw[1]*bHF[2] - prevOutw[0]*a[1] - prevOutw[1]*a[2]; prevOutw[1] = prevOutw[0]; prevOutw[0] = outHFw; prevInw[1] = prevInw[0]; prevInw[0] = w; w = -outHFw; //x Filtering outHFx = x*bHF[0] + prevInx[0]*bHF[1] + prevInx[1]*bHF[2] - prevOutx[0]*a[1] - prevOutx[1]*a[2]; prevOutx[1] = prevOutx[0]; prevOutx[0] = outHFx; prevInx[1] = prevInx[0]; prevInx[0] = x; x = -outHFx; //y Filtering outHFy = y*bHF[0] + prevIny[0]*bHF[1] + prevIny[1]*bHF[2] - prevOuty[0]*a[1] - prevOuty[1]*a[2]; prevOuty[1] = prevOuty[0]; prevOuty[0] = outHFy; prevIny[1] = prevIny[0]; prevIny[0] = y; y = -outHFy; //z Filtering outHFz = z*bHF[0] + prevInz[0]*bHF[1] + prevInz[1]*bHF[2] - prevOutz[0]*a[1] - prevOutz[1]*a[2]; prevOutz[1] = prevOutz[0]; prevOutz[0] = outHFz; prevInz[1] = prevInz[0]; prevInz[0] = z; z = -outHFz; }; void Decoder::clearFilter(){ for (int i=0; i<2; i++) { prevInS[i] = 0; prevOutS[i] = 0; prevInw[i] = 0; prevOutw[i] = 0; prevInx[i] = 0; prevOutx[i] = 0; prevIny[i] = 0; prevOuty[i] = 0; prevInz[i] = 0; prevOutz[i] = 0; } };