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 "SpectDirLine2.hh"
00028
00029
00030 void clSpectDirLine2::Calculate (int iScaling, stpSpectDir2RN spRemoveNoise)
00031 {
00032 long lSensorCntr;
00033 long lSpectCntr;
00034 GDT fMagnitude;
00035 GDT fPhaseDiff;
00036 GDT fFrequency;
00037 GDT fScaleExp;
00038 GDT *fpLeftRN;
00039 GDT *fpRightRN;
00040 GCDT *spLeftSpect;
00041 GCDT *spRightSpect;
00042
00043 for (lSensorCntr = 0l; lSensorCntr < lSensorCount; lSensorCntr++)
00044 {
00045 DSP.Mul(vfpProcBuf[lSensorCntr], fpWinFunc, lFFTSize);
00046 DSP.FFTi(vspSpect[lSensorCntr], vfpProcBuf[lSensorCntr]);
00047 if (spRemoveNoise->iType != SDL2_BNER_NONE)
00048 {
00049 DSP.Magnitude(vfpRNBuf[lSensorCntr], vspSpect[lSensorCntr],
00050 lSpectSize);
00051 switch (spRemoveNoise->iType)
00052 {
00053 case SDL2_BNER_TPSW:
00054 BNER.TPSW(vfpRNBuf[lSensorCntr], spRemoveNoise->fAlpha,
00055 spRemoveNoise->lMeanLength, spRemoveNoise->lGapLength,
00056 lSpectSize);
00057 break;
00058 case SDL2_BNER_OTA:
00059 BNER.OTA(vfpRNBuf[lSensorCntr], spRemoveNoise->fAlpha,
00060 spRemoveNoise->lMeanLength, lSpectSize);
00061 break;
00062 case SDL2_BNER_DIFF:
00063 BNER.Diff(vfpRNBuf[lSensorCntr], spRemoveNoise->fAlpha,
00064 lSpectSize);
00065 break;
00066 case SDL2_BNER_IDIFF:
00067 BNER.InvDiff(vfpRNBuf[lSensorCntr], spRemoveNoise->fAlpha,
00068 lSpectSize);
00069 break;
00070 }
00071 }
00072 }
00073 for (lSensorCntr = 0l; lSensorCntr < (lSensorCount - 1); lSensorCntr++)
00074 {
00075 fpLeftRN = vfpRNBuf[lSensorCntr];
00076 fpRightRN = vfpRNBuf[lSensorCntr + 1];
00077 spLeftSpect = vspSpect[lSensorCntr];
00078 spRightSpect = vspSpect[lSensorCntr + 1];
00079 for (lSpectCntr = lMinBin; lSpectCntr < lMaxBin; lSpectCntr++)
00080 {
00081 std::complex<GDT> cplxLeft(spLeftSpect[lSpectCntr].R,
00082 spLeftSpect[lSpectCntr].I);
00083 std::complex<GDT> cplxRight(spRightSpect[lSpectCntr].R,
00084 spRightSpect[lSpectCntr].I);
00085 std::complex<GDT> cplxCorr = cplxLeft * conj(cplxRight);
00086 if (spRemoveNoise->iType == SDL2_BNER_NONE)
00087
00088 fMagnitude = norm(cplxCorr);
00089 else
00090 fMagnitude = fpLeftRN[lSpectCntr] + fpRightRN[lSpectCntr];
00091 switch (iScaling)
00092 {
00093 case SDL2_SCALE_LIN:
00094 break;
00095 case SDL2_SCALE_LOG:
00096 default:
00097 fMagnitude = 1.0 / (fabs(20.0 * log10(fMagnitude)) + 1.0);
00098 break;
00099 }
00100 fPhaseDiff = arg(cplxCorr);
00101 fFrequency = lSpectCntr * fFreqRes;
00102 fpLevRes[lSpectCntr] += fMagnitude;
00103 fpDirRes[lSpectCntr] *= GetDirection(fFrequency, fPhaseDiff);
00104 }
00105 }
00106 fScaleExp = (GDT) 1.0 / (GDT) (lSensorCount - 1);
00107 for (lSpectCntr = lMinBin; lSpectCntr < lMaxBin; lSpectCntr++)
00108 {
00109 fpDirRes[lSpectCntr] = pow(fpDirRes[lSpectCntr], fScaleExp);
00110 }
00111 }
00112
00113
00114 clSpectDirLine2::clSpectDirLine2 (long lSensors, GDT fSensorSpacing,
00115 GDT fSoundSpeed, double dSampleRate, long lFiltSize, int iFilterType,
00116 long lWindowSize, GDT fIntTimeReq, bool bEnableDebug)
00117 {
00118 long lSensorCntr;
00119 long lTwosPower;
00120 GDT fWindowTime;
00121 GDT *fpNullPtr = NULL;
00122
00123 lSensorCount = lSensors;
00124 SetSensorSpacing(fSensorSpacing);
00125 SetSoundSpeed(fSoundSpeed);
00126 bDebug = bEnableDebug;
00127 lFilterSize = lFiltSize;
00128 lFFTSize = lWindowSize;
00129 lTwosPower = (long)
00130 floor(log(dSampleRate / 2.0 / GetArrayFrequency()) / log(2.0));
00131 lDecimation = (long) pow(2.0, (double) lTwosPower);
00132 lSpectSize = lFFTSize / 2 + 1;
00133 fFreqRes =
00134 (GDT) dSampleRate / (GDT) lDecimation / (GDT) 2 / (GDT) lSpectSize;
00135 fWindowTime = (GDT) lFFTSize / ((GDT) dSampleRate / (GDT) lDecimation);
00136 if (fIntTimeReq <= 0)
00137 {
00138 fIntTime = fWindowTime;
00139 fOverlap = 0.0f;
00140 }
00141 else
00142 {
00143 fOverlap = 1.0f - fIntTimeReq / fWindowTime;
00144 lOldData = DSP.Round(lFFTSize * fOverlap);
00145 if (lOldData >= lFFTSize) lOldData = lFFTSize - 1l;
00146 lNewData = lFFTSize - lOldData;
00147 fIntTime = fWindowTime * ((GDT) lNewData / (GDT) lFFTSize);
00148 }
00149 lMaxBin = DSP.Round(GetArrayFrequency() / fFreqRes);
00150 fpWinFunc = (GDT *) WinFuncBuf.Size(lFFTSize * sizeof(GDT));
00151 DSP.WinExactBlackman(fpWinFunc, lFFTSize);
00152 fpLevRes = (GDT *) LevResBuf.Size(lSpectSize * sizeof(GDT));
00153 fpDirRes = (GDT *) DirResBuf.Size(lSpectSize * sizeof(GDT));
00154 vProcBuf.resize(lSensorCount);
00155 vPrevBuf.resize(lSensorCount);
00156 vRNBuf.resize(lSensorCount);
00157 vSpectBuf.resize(lSensorCount);
00158 for (lSensorCntr = 0l; lSensorCntr < lSensorCount; lSensorCntr++)
00159 {
00160 vProcBuf[lSensorCntr].Size(lFFTSize * sizeof(GDT));
00161 vfpProcBuf.push_back(vProcBuf[lSensorCntr]);
00162 vPrevBuf[lSensorCntr].Size(lFFTSize * sizeof(GDT));
00163 vfpPrevBuf.push_back(vPrevBuf[lSensorCntr]);
00164 vRNBuf[lSensorCntr].Size(lSpectSize * sizeof(GDT));
00165 vfpRNBuf.push_back(vRNBuf[lSensorCntr]);
00166 vSpectBuf[lSensorCntr].Size(sizeof(GCDT) * lSpectSize);
00167 vspSpect.push_back(vSpectBuf[lSensorCntr]);
00168 vDecimator.push_back(new clRecDecimator);
00169 vDecimator[lSensorCntr]->Initialize(lDecimation, lFilterSize,
00170 fpNullPtr, 0, iFilterType);
00171 }
00172 DSP.FFTInitialize(lFFTSize, true);
00173 if (bDebug)
00174 {
00175 printf("Filter size %li, DFT size %li\n", lFilterSize, lFFTSize);
00176 switch (iFilterType)
00177 {
00178 case clRecDecimator::FILTER_TYPE_FFT:
00179 puts("Using FFT decimation filter");
00180 break;
00181 case clRecDecimator::FILTER_TYPE_FIR:
00182 puts("Using FIR decimation filter");
00183 break;
00184 case clRecDecimator::FILTER_TYPE_IIR:
00185 puts("Using IIR decimation filter");
00186 break;
00187 }
00188 if (lOldData > 0l)
00189 {
00190 printf("Overlap %.1f%%, %li/%li\n", fOverlap * 100.0f,
00191 lNewData, lOldData);
00192 }
00193 printf("Array frequency %.2f\n", GetArrayFrequency());
00194 printf("Decimation %li, Nyquist %.2f, resolution %.3f\n",
00195 lDecimation, ((GDT) dSampleRate / (GDT) lDecimation / (GDT) 2),
00196 fFreqRes);
00197 }
00198 }
00199
00200
00201 clSpectDirLine2::~clSpectDirLine2 ()
00202 {
00203 while (vDecimator.size() > 0)
00204 {
00205 delete vDecimator[vDecimator.size() - 1];
00206 vDecimator.pop_back();
00207 }
00208 }
00209
00210
00211 void clSpectDirLine2::PutData (const GDT *fpInputData, long lSampleCount,
00212 long lStartCh, long lChCount)
00213 {
00214 long lSensorCntr;
00215 long lChSampleCount;
00216
00217 lChSampleCount = lSampleCount / lChCount;
00218 fpExtBuf = (GDT *) ExtBuf.Size(lChSampleCount * sizeof(GDT));
00219 for (lSensorCntr = 0l; lSensorCntr < lSensorCount; lSensorCntr++)
00220 {
00221 DSP.Extract(fpExtBuf, fpInputData, lStartCh + lSensorCntr, lChCount,
00222 lSampleCount);
00223 vDecimator[lSensorCntr]->Put(fpExtBuf, lChSampleCount);
00224 }
00225 }
00226
00227
00228 bool clSpectDirLine2::GetResults (GDT *fpLevelResults, GDT *fpDirResults,
00229 GDT fLowFreqLimit, int iScaling, stpSpectDir2RN spRemoveNoise)
00230 {
00231 long lSensorCntr;
00232
00233 for (lSensorCntr = 0l; lSensorCntr < lSensorCount; lSensorCntr++)
00234 {
00235 if (lOldData <= 0l)
00236 {
00237 if (!vDecimator[lSensorCntr]->Get(vfpProcBuf[lSensorCntr],
00238 lFFTSize)) return false;
00239 }
00240 else
00241 {
00242 GDT *fpProc = vfpProcBuf[lSensorCntr];
00243 GDT *fpOld = vfpPrevBuf[lSensorCntr];
00244
00245 if (vDecimator[lSensorCntr]->Get(&fpProc[lOldData], lNewData))
00246 {
00247 DSP.Copy(fpProc, &fpOld[lNewData], lOldData);
00248 DSP.Copy(fpOld, fpProc, lFFTSize);
00249 }
00250 else return false;
00251 }
00252 }
00253 lMinBin = DSP.Round(fLowFreqLimit / fFreqRes);
00254 if (lMinBin <= 0l) lMinBin = 1l;
00255 else if (lMinBin >= lMaxBin) lMinBin = lMaxBin - 1l;
00256 DSP.Zero(fpLevRes, lSpectSize);
00257 DSP.Zero(fpDirRes, lSpectSize);
00258 Calculate(iScaling, spRemoveNoise);
00259 if (fpLevelResults != NULL)
00260 DSP.Copy(fpLevelResults, fpLevRes, lSpectSize);
00261 if (fpDirResults != NULL)
00262 DSP.Copy(fpDirResults, fpDirRes, lSpectSize);
00263 return true;
00264 }