00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <math.h>
00026 #include <float.h>
00027 #include "ArrayDipole.hh"
00028
00029
00030 clArrayDipole::clArrayDipole ()
00031 {
00032 bInitialized = false;
00033 }
00034
00035
00036 clArrayDipole::~clArrayDipole ()
00037 {
00038 if (bInitialized) Uninitialize();
00039 }
00040
00041
00042 bool clArrayDipole::Initialize (GDT fSensorSpacing, GDT fSndSpeed,
00043 int iSRate, long lWinSize, GDT fLowFreqLimit, bool bEnableDebug)
00044 {
00045 long lSensCntr;
00046 GDT *fpNullPtr = NULL;
00047 GDT fLowFreq;
00048 GDT fHighFreq;
00049 GDT fAudioLow;
00050
00051 if (bEnableDebug) EnableDebug();
00052 if (bDebug) printf("Initializing dipole array\n");
00053 lWindowSize = lWinSize;
00054 iSampleRate = iSRate;
00055 if (bDebug) printf("Window size %li\n", lWindowSize);
00056 SetSoundSpeed(fSndSpeed);
00057 SetSampleRate(iSampleRate);
00058 fSpacing = fSensorSpacing;
00059 fDelay = fSpacing * fSecsPerMeter;
00060 if (bDebug) printf("Requested array frequency band %g - %g Hz\n",
00061 fLowFreqLimit, GetArrayFreq());
00062 if (GetMaxDelay() > lWindowSize)
00063 lBufferSize = GetMaxDelay() / lWindowSize * lWindowSize + lWindowSize;
00064 else
00065 lBufferSize = lWindowSize * 2;
00066 if (bDebug) printf("Buffer size %li (%li total)\n", lBufferSize,
00067 lBufferSize * 2);
00068 lBaseIdx = lBufferSize - lWindowSize;
00069 for (lSensCntr = 0; lSensCntr < 2; lSensCntr++)
00070 {
00071 if (!FilterBank[lSensCntr].Initialize(lWindowSize, fpNullPtr))
00072 return false;
00073 fLowFreq = fLowFreqLimit;
00074 fHighFreq = GetArrayFreq();
00075 FilterBank[lSensCntr].DesignBP(&fLowFreq, &fHighFreq, iSampleRate);
00076 RawBuf[lSensCntr].Size(lBufferSize * sizeof(GDT));
00077 FiltBuf[lSensCntr].Size(lBufferSize * sizeof(GDT));
00078 HFBuf[lSensCntr].Size(lWindowSize * sizeof(GDT));
00079 DSP.Zero((GDT *) RawBuf[lSensCntr], lBufferSize);
00080 DSP.Zero((GDT *) FiltBuf[lSensCntr], lBufferSize);
00081 if (!FilterBank[2 + lSensCntr].Initialize(lWindowSize, fpNullPtr,
00082 true)) return false;
00083 fAudioLow = fHighFreq;
00084 FilterBank[2 + lSensCntr].DesignHP(&fAudioLow, iSampleRate);
00085 }
00086 if (bDebug) printf("Filter size %li\n", lWindowSize * 2);
00087 if (bDebug) printf("Using frequency band %g - %g Hz for array\n",
00088 fLowFreq, fHighFreq);
00089 if (bDebug) printf("High frequency audio lower corner at %g Hz\n",
00090 fAudioLow);
00091 bInitialized = true;
00092 return true;
00093 }
00094
00095
00096 void clArrayDipole::Uninitialize ()
00097 {
00098 long lSensCntr;
00099
00100 bInitialized = false;
00101 for (lSensCntr = 0; lSensCntr < 2; lSensCntr++)
00102 {
00103 FilterBank[lSensCntr].Uninitialize();
00104 FilterBank[2 + lSensCntr].Uninitialize();
00105 }
00106 }
00107
00108
00109 GDT *clArrayDipole::GetRawPtr (long lSensor)
00110 {
00111 GDT *fpSensPtr = RawBuf[lSensor];
00112 return (&fpSensPtr[lBaseIdx]);
00113 }
00114
00115
00116 GDT *clArrayDipole::GetFiltPtr (long lSensor)
00117 {
00118 GDT *fpSensPtr = FiltBuf[lSensor];
00119 return (&fpSensPtr[lBaseIdx]);
00120 }
00121
00122
00123 GDT *clArrayDipole::GetHFPtr (long lSensor)
00124 {
00125 GDT *fpSensPtr = HFBuf[lSensor];
00126 return (&fpSensPtr[lBaseIdx]);
00127 }
00128
00129
00130 long clArrayDipole::GetMaxDelay ()
00131 {
00132 return ((long) (fDelay / fSampleSpacing + (GDT) 0.5));
00133 }
00134
00135
00136 GDT clArrayDipole::GetArrayFreq ()
00137 {
00138 return ((GDT) 1.0 / fDelay / (GDT) 2.0);
00139 }
00140
00141
00142 GDT clArrayDipole::GetDelay (GDT fDirection)
00143 {
00144 return (sin(fDirection) * fDelay);
00145 }
00146
00147
00148 GDT clArrayDipole::GetDelayTime (long lSensor, GDT fDirection)
00149 {
00150 if (fDirection == (GDT) 0.0) return ((GDT) 0.0);
00151 else if (fDirection > (GDT) 0.0 && lSensor == 1)
00152 {
00153 return GetDelay(fDirection);
00154 }
00155 else if (fDirection < (GDT) 0.0 && lSensor == 0)
00156 {
00157 return fabs(GetDelay(fDirection));
00158 }
00159 return ((GDT) 0.0);
00160 }
00161
00162
00163 long clArrayDipole::GetDelaySamples (long lSensor, GDT fDirection)
00164 {
00165 if (fDirection == (GDT) 0.0) return (0L);
00166 else if (fDirection > (GDT) 0.0 && lSensor == 1)
00167 {
00168 return ((long)
00169 (GetDelay(fDirection) / fSampleSpacing + (GDT) 0.5));
00170 }
00171 else if (fDirection < (GDT) 0.0 && lSensor == 0)
00172 {
00173 return ((long)
00174 (fabs(GetDelay(fDirection)) / fSampleSpacing + (GDT) 0.5));
00175 }
00176 return (0L);
00177 }
00178
00179
00180 void clArrayDipole::SetLowFreqLimit (GDT fLowFreqLimit)
00181 {
00182 long lSensCntr;
00183 GDT fLowFreq;
00184 GDT fHighFreq;
00185
00186 for (lSensCntr = 0; lSensCntr < 2; lSensCntr++)
00187 {
00188 fLowFreq = fLowFreqLimit;
00189 fHighFreq = GetArrayFreq();
00190 FilterBank[lSensCntr].DesignBP(&fLowFreq, &fHighFreq,
00191 iSampleRate);
00192 }
00193 if (bDebug) printf("Using frequency band %g - %g Hz for array\n",
00194 fLowFreq, fHighFreq);
00195 }
00196
00197
00198 void clArrayDipole::AddData (const GDT *fpSource, long lStartIndex,
00199 long lChannels)
00200 {
00201 long lBase;
00202 long lMoveIdx;
00203 long lDataCntr;
00204 GDT *fpRaw1 = RawBuf[0];
00205 GDT *fpRaw2 = RawBuf[1];
00206 GDT *fpDest1 = FiltBuf[0];
00207 GDT *fpDest2 = FiltBuf[1];
00208 GDT *fpHF1 = HFBuf[0];
00209 GDT *fpHF2 = HFBuf[1];
00210
00211 lBase = lBufferSize - lWindowSize;
00212 lMoveIdx = lWindowSize;
00213 DSP.Copy(fpRaw1, &fpRaw1[lMoveIdx], lBase);
00214 DSP.Copy(fpRaw2, &fpRaw2[lMoveIdx], lBase);
00215 DSP.Copy(fpDest1, &fpDest1[lMoveIdx], lBase);
00216 DSP.Copy(fpDest2, &fpDest2[lMoveIdx], lBase);
00217 for (lDataCntr = 0; lDataCntr < lWindowSize; lDataCntr++)
00218 {
00219 fpRaw1[lBase + lDataCntr] = fpDest1[lBase + lDataCntr] =
00220 fpHF1[lDataCntr] =
00221 fpSource[lDataCntr * lChannels + lStartIndex];
00222 fpRaw2[lBase + lDataCntr] = fpDest2[lBase + lDataCntr] =
00223 fpHF2[lDataCntr] =
00224 fpSource[lDataCntr * lChannels + lStartIndex + 1];
00225 }
00226 FilterBank[0].Put(&fpDest1[lBase], lWindowSize);
00227 FilterBank[1].Put(&fpDest2[lBase], lWindowSize);
00228 FilterBank[2].Put(fpHF1, lWindowSize);
00229 FilterBank[3].Put(fpHF2, lWindowSize);
00230 if (!FilterBank[0].Get(&fpDest1[lBase], lWindowSize))
00231 DSP.Zero(&fpDest1[lBase], lWindowSize);
00232 if (!FilterBank[1].Get(&fpDest2[lBase], lWindowSize))
00233 DSP.Zero(&fpDest2[lBase], lWindowSize);
00234 if (!FilterBank[2].Get(fpHF1, lWindowSize))
00235 DSP.Zero(fpHF1, lWindowSize);
00236 if (!FilterBank[3].Get(fpHF2, lWindowSize))
00237 DSP.Zero(fpHF2, lWindowSize);
00238 }
00239
00240
00241 void clArrayDipole::GetRawData (GDT **fpaDest, GDT fDirection)
00242 {
00243 long lDelay1;
00244 long lDelay2;
00245 GDT *fpDest1 = fpaDest[0];
00246 GDT *fpDest2 = fpaDest[1];
00247 GDT *fpSrc1 = RawBuf[0];
00248 GDT *fpSrc2 = RawBuf[1];
00249
00250 lDelay1 = GetDelaySamples(0, fDirection);
00251 lDelay2 = GetDelaySamples(1, fDirection);
00252 DSP.Copy(fpDest1, &fpSrc1[lBaseIdx - lDelay1], lWindowSize);
00253 DSP.Copy(fpDest2, &fpSrc2[lBaseIdx - lDelay2], lWindowSize);
00254 }
00255
00256
00257 GDT *clArrayDipole::GetRawDataPtr (long lSensor, GDT fDirection)
00258 {
00259 long lDelayCount;
00260 GDT *fpSource;
00261
00262 fpSource = RawBuf[lSensor];
00263 lDelayCount = GetDelaySamples(lSensor, fDirection);
00264 return (&fpSource[lBaseIdx - lDelayCount]);
00265 }
00266
00267
00268 void clArrayDipole::GetFilteredData (GDT **fpaDest, GDT fDirection)
00269 {
00270 long lDelay1;
00271 long lDelay2;
00272 GDT *fpDest1 = fpaDest[0];
00273 GDT *fpDest2 = fpaDest[1];
00274 GDT *fpSrc1 = FiltBuf[0];
00275 GDT *fpSrc2 = FiltBuf[1];
00276
00277 lDelay1 = GetDelaySamples(0, fDirection);
00278 lDelay2 = GetDelaySamples(1, fDirection);
00279 DSP.Copy(fpDest1, &fpSrc1[lBaseIdx - lDelay1], lWindowSize);
00280 DSP.Copy(fpDest2, &fpSrc2[lBaseIdx - lDelay2], lWindowSize);
00281 }
00282
00283
00284 GDT *clArrayDipole::GetFilteredDataPtr (long lSensor, GDT fDirection)
00285 {
00286 long lDelayCount;
00287 GDT *fpSource;
00288
00289 fpSource = FiltBuf[lSensor];
00290 lDelayCount = GetDelaySamples(lSensor, fDirection);
00291 return (&fpSource[lBaseIdx - lDelayCount]);
00292 }
00293
00294
00295 void clArrayDipole::GetAudioData (GDT *fpDest, GDT fDirection, bool bFullBand)
00296 {
00297 long lDelay1;
00298 long lDelay2;
00299 long lDataCntr;
00300 GDT fScaler;
00301 GDT *fpSrc1 = FiltBuf[0];
00302 GDT *fpSrc2 = FiltBuf[1];
00303 GDT *fpSrc3;
00304
00305 lDelay1 = GetDelaySamples(0, fDirection);
00306 lDelay2 = GetDelaySamples(1, fDirection);
00307 if (bFullBand)
00308 {
00309 fScaler = (GDT) 1.0 / (GDT) 3.0;
00310 if (fDirection >= 0.0)
00311 fpSrc3 = HFBuf[0];
00312 else
00313 fpSrc3 = HFBuf[1];
00314 for (lDataCntr = 0; lDataCntr < lWindowSize; lDataCntr++)
00315 {
00316 fpDest[lDataCntr] =
00317 (fpSrc1[lBaseIdx - lDelay1 + lDataCntr] +
00318 fpSrc2[lBaseIdx - lDelay2 + lDataCntr] +
00319 fpSrc3[lDataCntr]) * fScaler;
00320 }
00321 }
00322 else
00323 {
00324 DSP.Mix(fpDest, &fpSrc1[lBaseIdx - lDelay1],
00325 &fpSrc2[lBaseIdx - lDelay2], lWindowSize);
00326 }
00327 }
00328