Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

ArrayDipole.cc

Go to the documentation of this file.
00001 /*
00002 
00003     Class for dipole array operations
00004     Copyright (C) 1999-2003 Jussi Laako
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 

Generated on Sun Oct 26 19:11:18 2003 for HASAS by doxygen 1.3.3