00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <cstdio>
00024 #include <cmath>
00025 #include <complex>
00026
00027 #include "SpectDirDipole2.hh"
00028
00029
00030 void clSpectDirDipole2::Calculate (int iScaling, stpSpectDir2RN spRemoveNoise)
00031 {
00032 long lSensorCntr;
00033 long lSpectCntr;
00034 GDT fMagnitude;
00035 GDT fPhaseDiff;
00036 GDT fFrequency;
00037 GDT *fpLeftRN;
00038 GDT *fpRightRN;
00039 GCDT *spLeftSpect;
00040 GCDT *spRightSpect;
00041
00042 for (lSensorCntr = 0l; lSensorCntr < 2l; lSensorCntr++)
00043 {
00044 DSP.Mul(fpProcBuf[lSensorCntr], fpWinFunc, lFFTSize);
00045 DSP.FFTi(spSpect[lSensorCntr], fpProcBuf[lSensorCntr]);
00046 if (spRemoveNoise->iType != SDD2_BNER_NONE)
00047 {
00048 DSP.Magnitude(fpRNBuf[lSensorCntr], spSpect[lSensorCntr],
00049 lSpectSize);
00050 switch (spRemoveNoise->iType)
00051 {
00052 case SDD2_BNER_TPSW:
00053 BNER.TPSW(fpRNBuf[lSensorCntr], spRemoveNoise->fAlpha,
00054 spRemoveNoise->lMeanLength, spRemoveNoise->lGapLength,
00055 lSpectSize);
00056 break;
00057 case SDD2_BNER_OTA:
00058 BNER.OTA(fpRNBuf[lSensorCntr], spRemoveNoise->fAlpha,
00059 spRemoveNoise->lMeanLength, lSpectSize);
00060 break;
00061 case SDD2_BNER_DIFF:
00062 BNER.Diff(fpRNBuf[lSensorCntr], spRemoveNoise->fAlpha,
00063 lSpectSize);
00064 break;
00065 case SDD2_BNER_IDIFF:
00066 BNER.InvDiff(fpRNBuf[lSensorCntr], spRemoveNoise->fAlpha,
00067 lSpectSize);
00068 break;
00069 }
00070 }
00071 }
00072 fpLeftRN = fpRNBuf[0];
00073 fpRightRN = fpRNBuf[1];
00074 spLeftSpect = spSpect[0];
00075 spRightSpect = spSpect[1];
00076 for (lSpectCntr = lMinBin; lSpectCntr < lMaxBin; lSpectCntr++)
00077 {
00078 std::complex<GDT> cplxLeft(spLeftSpect[lSpectCntr].R,
00079 spLeftSpect[lSpectCntr].I);
00080 std::complex<GDT> cplxRight(spRightSpect[lSpectCntr].R,
00081 spRightSpect[lSpectCntr].I);
00082 std::complex<GDT> cplxCorr = cplxLeft * conj(cplxRight);
00083 if (spRemoveNoise->iType == SDD2_BNER_NONE)
00084
00085 fMagnitude = norm(cplxCorr);
00086 else
00087 fMagnitude = fpLeftRN[lSpectCntr] + fpRightRN[lSpectCntr];
00088 switch (iScaling)
00089 {
00090 case SDD2_SCALE_LIN:
00091 break;
00092 case SDD2_SCALE_LOG:
00093 default:
00094 fMagnitude = 1.0 / (fabs(20.0 * log10(fMagnitude)) + 1.0);
00095 break;
00096 }
00097 fPhaseDiff = arg(cplxCorr);
00098 fFrequency = lSpectCntr * fFreqRes;
00099 fpLevRes[lSpectCntr] = fMagnitude;
00100 fpDirRes[lSpectCntr] = GetDirection(fFrequency, fPhaseDiff);
00101 }
00102 }
00103
00104
00105 clSpectDirDipole2::clSpectDirDipole2 (GDT fSensorSpacing, GDT fSoundSpeed,
00106 double dSampleRate, long lFiltSize, int iFilterType, long lWindowSize,
00107 GDT fIntTimeReq, bool bEnableDebug)
00108 {
00109 long lSensorCntr;
00110 long lTwosPower;
00111 GDT fWindowTime;
00112 GDT *fpNullPtr = NULL;
00113
00114 SetSensorSpacing(fSensorSpacing);
00115 SetSoundSpeed(fSoundSpeed);
00116 bDebug = bEnableDebug;
00117 lFilterSize = lFiltSize;
00118 lFFTSize = lWindowSize;
00119 lTwosPower = (long)
00120 floor(log(dSampleRate / 2.0 / GetArrayFrequency()) / log(2.0));
00121 lDecimation = (long) pow(2.0, (double) lTwosPower);
00122 lSpectSize = lFFTSize / 2 + 1;
00123 fFreqRes =
00124 (GDT) dSampleRate / (GDT) lDecimation / (GDT) 2 / (GDT) lSpectSize;
00125 fWindowTime = (GDT) lFFTSize / ((GDT) dSampleRate / (GDT) lDecimation);
00126 if (fIntTimeReq <= 0)
00127 {
00128 fIntTime = fWindowTime;
00129 fOverlap = 0.0f;
00130 }
00131 else
00132 {
00133 fOverlap = 1.0f - fIntTimeReq / fWindowTime;
00134 lOldData = DSP.Round(lFFTSize * fOverlap);
00135 if (lOldData >= lFFTSize) lOldData = lFFTSize - 1l;
00136 lNewData = lFFTSize - lOldData;
00137 fIntTime = fWindowTime * ((GDT) lNewData / (GDT) lFFTSize);
00138 }
00139 lMaxBin = DSP.Round(GetArrayFrequency() / fFreqRes);
00140 fpWinFunc = (GDT *) WinFuncBuf.Size(lFFTSize * sizeof(GDT));
00141 DSP.WinExactBlackman(fpWinFunc, lFFTSize);
00142 fpLevRes = (GDT *) LevResBuf.Size(lSpectSize * sizeof(GDT));
00143 fpDirRes = (GDT *) DirResBuf.Size(lSpectSize * sizeof(GDT));
00144 for (lSensorCntr = 0l; lSensorCntr < 2; lSensorCntr++)
00145 {
00146 ProcBuf[lSensorCntr].Size(lFFTSize * sizeof(GDT));
00147 fpProcBuf[lSensorCntr] = ProcBuf[lSensorCntr];
00148 PrevBuf[lSensorCntr].Size(lFFTSize * sizeof(GDT));
00149 fpPrevBuf[lSensorCntr] = PrevBuf[lSensorCntr];
00150 RNBuf[lSensorCntr].Size(lSpectSize * sizeof(GDT));
00151 fpRNBuf[lSensorCntr] = RNBuf[lSensorCntr];
00152 SpectBuf[lSensorCntr].Size(sizeof(GCDT) * lSpectSize);
00153 spSpect[lSensorCntr] = SpectBuf[lSensorCntr];
00154 Decimator[lSensorCntr].Initialize(lDecimation, lFilterSize, fpNullPtr,
00155 0, iFilterType);
00156 }
00157 DSP.FFTInitialize(lFFTSize, true);
00158 if (bDebug)
00159 {
00160 printf("Filter size %li, DFT size %li\n", lFilterSize, lFFTSize);
00161 switch (iFilterType)
00162 {
00163 case clRecDecimator::FILTER_TYPE_FFT:
00164 puts("Using FFT decimation filter");
00165 break;
00166 case clRecDecimator::FILTER_TYPE_FIR:
00167 puts("Using FIR decimation filter");
00168 break;
00169 case clRecDecimator::FILTER_TYPE_IIR:
00170 puts("Using IIR decimation filter");
00171 break;
00172 }
00173 if (lOldData > 0l)
00174 {
00175 printf("Overlap %.1f%%, %li/%li\n", fOverlap * 100.0f,
00176 lNewData, lOldData);
00177 }
00178 printf("Array frequency %.2f\n", GetArrayFrequency());
00179 printf("Decimation %li, Nyquist %.2f, resolution %.3f\n",
00180 lDecimation, ((GDT) dSampleRate / (GDT) lDecimation / (GDT) 2),
00181 fFreqRes);
00182 }
00183 }
00184
00185
00186 clSpectDirDipole2::~clSpectDirDipole2 ()
00187 {
00188 }
00189
00190
00191 void clSpectDirDipole2::PutData (const GDT *fpInputData, long lSampleCount,
00192 long lStartCh, long lChCount)
00193 {
00194 long lSensorCntr;
00195 long lChSampleCount;
00196
00197 lChSampleCount = lSampleCount / lChCount;
00198 fpExtBuf = (GDT *) ExtBuf.Size(lChSampleCount * sizeof(GDT));
00199 for (lSensorCntr = 0l; lSensorCntr < 2l; lSensorCntr++)
00200 {
00201 DSP.Extract(fpExtBuf, fpInputData, lStartCh + lSensorCntr, lChCount,
00202 lSampleCount);
00203 Decimator[lSensorCntr].Put(fpExtBuf, lChSampleCount);
00204 }
00205 }
00206
00207
00208 bool clSpectDirDipole2::GetResults (GDT *fpLevelResults, GDT *fpDirResults,
00209 GDT fLowFreqLimit, int iScaling, stpSpectDir2RN spRemoveNoise)
00210 {
00211 long lSensorCntr;
00212
00213 for (lSensorCntr = 0l; lSensorCntr < 2l; lSensorCntr++)
00214 {
00215 if (lOldData <= 0l)
00216 {
00217 if (!Decimator[lSensorCntr].Get(fpProcBuf[lSensorCntr], lFFTSize))
00218 return false;
00219 }
00220 else
00221 {
00222 GDT *fpProc = fpProcBuf[lSensorCntr];
00223 GDT *fpOld = fpPrevBuf[lSensorCntr];
00224
00225 if (Decimator[lSensorCntr].Get(&fpProc[lOldData], lNewData))
00226 {
00227 DSP.Copy(fpProc, &fpOld[lNewData], lOldData);
00228 DSP.Copy(fpOld, fpProc, lFFTSize);
00229 }
00230 else return false;
00231 }
00232 }
00233 lMinBin = DSP.Round(fLowFreqLimit / fFreqRes);
00234 if (lMinBin <= 0l) lMinBin = 1l;
00235 else if (lMinBin >= lMaxBin) lMinBin = lMaxBin - 1l;
00236 DSP.Zero(fpLevRes, lSpectSize);
00237 DSP.Zero(fpDirRes, lSpectSize);
00238 Calculate(iScaling, spRemoveNoise);
00239 if (fpLevelResults != NULL)
00240 DSP.Copy(fpLevelResults, fpLevRes, lSpectSize);
00241 if (fpDirResults != NULL)
00242 DSP.Copy(fpDirResults, fpDirRes, lSpectSize);
00243 return true;
00244 }