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