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