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 <math.h>
00025 #include <float.h>
00026
00027 #include "ArraySensor.hh"
00028
00029
00030 inline void clArraySensor::SinCosC (float fX,
00031 float *fpSinX, float *fpCosX)
00032 {
00033 #ifdef _GNU_SOURCE
00034 sincosf(fX, fpSinX, fpCosX);
00035 #else
00036 *fpSinX = sin(fX);
00037 *fpCosX = cos(fX);
00038 #endif
00039 *fpSinX = -(*fpSinX);
00040 }
00041
00042
00043 inline void clArraySensor::SinCosC (double dX,
00044 double *dpSinX, double *dpCosX)
00045 {
00046 #ifdef _GNU_SOURCE
00047 sincos(dX, dpSinX, dpCosX);
00048 #else
00049 *dpSinX = sin(dX);
00050 *dpCosX = cos(dX);
00051 #endif
00052 *dpSinX = -(*dpSinX);
00053 }
00054
00055
00056 clArraySensor::clArraySensor ()
00057 {
00058 bDebug = false;
00059 fShadeCoeff = 1;
00060 fPI = acos(-1.0);
00061 }
00062
00063
00064 bool clArraySensor::Initialize (GDT fLDistance, GDT fRDistance, long lWinSize)
00065 {
00066 GDT *fpNullPtr = NULL;
00067
00068 fLeftDistance = fLDistance;
00069 fRightDistance = fRDistance;
00070 lWindowSize = lWinSize;
00071 lProcCount = lWindowSize / 2;
00072 if (bDebug)
00073 {
00074 printf("Left distance %g, right distance %g\n",
00075 fLeftDistance, fRightDistance);
00076 printf("Window size %li\n", lWinSize);
00077 }
00078 dspvProcData.SetSize(lProcCount);
00079 if (!Filter.Initialize(lWindowSize, fpNullPtr,
00080 (GDT) DSP_FILT_DEF_OVERLAP, (GDT) DSP_FILT_DEF_BETA,
00081 FILTER_SMOOTH_KAISER_BESSEL))
00082 return false;
00083 return true;
00084 }
00085
00086
00087 void clArraySensor::SetSampleRate (GDT fFs)
00088 {
00089 fSampleRate = fFs;
00090 fSampleSpacing = (GDT) 1.0 / fSampleRate;
00091 fFreqResolution = fSampleRate / (GDT) 2 /
00092 (GDT) (lWindowSize / 2 + 1);
00093 if (bDebug)
00094 {
00095 printf("Samplerate %g, spacing %g ms, resolution %g Hz\n",
00096 fSampleRate, fSampleSpacing * 1000.0, fFreqResolution);
00097 }
00098 }
00099
00100
00101 void clArraySensor::SetSoundSpeed (GDT fSndSpeed)
00102 {
00103 fSoundSpeed = fSndSpeed;
00104 fSecsPerMeter = (GDT) 1.0 / fSndSpeed;
00105 fLeftTime = fLeftDistance * fSecsPerMeter;
00106 fRightTime = fRightDistance * fSecsPerMeter;
00107 if (bDebug)
00108 {
00109 printf("Sound speed %g ms/m\n", fSecsPerMeter * 1000.0);
00110 printf("Left delay time %g ms, right delay time %g ms\n",
00111 fLeftTime * 1000.0, fRightTime * 1000.0);
00112 }
00113 }
00114
00115
00116 void clArraySensor::SetArrayFrequency (GDT fFa)
00117 {
00118 fArrayFrequency = fFa;
00119 if (bDebug) printf("Array frequency %g Hz\n", fArrayFrequency);
00120 }
00121
00122
00123 void clArraySensor::SetShading (GDT fCoeff)
00124 {
00125 fShadeCoeff = fCoeff;
00126 if (bDebug) printf("Shading coefficient %g\n", fShadeCoeff);
00127 }
00128
00129
00130 void clArraySensor::SetDirection (GDT fDir, bool bLowPass)
00131 {
00132 long lMaxBin;
00133 long lBinCntr;
00134 GDT fDirPhase;
00135 GDT fArrayTime;
00136 GDT fFreqTime;
00137 GDT fFreqPhase;
00138 GDT fHighCoeff;
00139 clDSPVector<GCDT> dspvFiltCoeffs;
00140
00141 if (bDebug)
00142 {
00143
00144
00145
00146
00147 }
00148 dspvFiltCoeffs.SetSize(lWindowSize / 2 + 1);
00149 fDirPhase = sin(fDir) * fPI;
00150 fArrayTime = (fDir < (GDT) 0) ? fRightTime : fLeftTime;
00151 lMaxBin = (long) (fArrayFrequency / fFreqResolution + (GDT) 0.5);
00152 if (lMaxBin > dspvFiltCoeffs.Size())
00153 lMaxBin = dspvFiltCoeffs.Size();
00154 for (lBinCntr = 0; lBinCntr < lMaxBin; lBinCntr++)
00155 {
00156 fFreqTime = (GDT) 1 /
00157 ((GDT) lBinCntr * fFreqResolution * (GDT) 2);
00158 fFreqPhase = fDirPhase * (fArrayTime / fFreqTime);
00159 SinCosC(fFreqPhase, &dspvFiltCoeffs[lBinCntr].I,
00160 &dspvFiltCoeffs[lBinCntr].R);
00161 }
00162 fHighCoeff = (bLowPass) ? 0 : 1;
00163 for (lBinCntr = lMaxBin; lBinCntr < dspvFiltCoeffs.Size(); lBinCntr++)
00164 {
00165 dspvFiltCoeffs[lBinCntr].R = fHighCoeff;
00166 dspvFiltCoeffs[lBinCntr].I = (GDT) 0;
00167 }
00168 Filter.SetCoeffs(dspvFiltCoeffs.Ptr(), true);
00169 }
00170
00171
00172 void clArraySensor::Put (const GDT *fpSrc, long lSrcCount)
00173 {
00174 dspvInData.Put(fpSrc, lSrcCount);
00175 while (dspvInData.Get(dspvProcData.Ptr(), dspvProcData.Size()))
00176 {
00177 dspvProcData *= fShadeCoeff;
00178 Filter.Put(dspvProcData.Ptr(), dspvProcData.Size());
00179 while (Filter.Get(dspvProcData.Ptr(), dspvProcData.Size()))
00180 {
00181 dspvOutData.Put(dspvProcData.Ptr(), dspvProcData.Size());
00182 }
00183 }
00184 }
00185
00186
00187 bool clArraySensor::Get (GDT *fpDest, long lDestCount)
00188 {
00189 return dspvOutData.Get(fpDest, lDestCount);
00190 }