00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #define COMPILE
00024 #include "Audio3D.hh"
00025
00026
00027 void clAudio3D::CopyToLocal(GDT *fpDest, const float *fpSrc)
00028 {
00029 long lCopyCntr;
00030
00031 for (lCopyCntr = 0l; lCopyCntr < HRTF_LENGTH; lCopyCntr++)
00032 {
00033 fpDest[lCopyCntr] = fpSrc[lCopyCntr];
00034 }
00035 for (lCopyCntr = HRTF_LENGTH; lCopyCntr < lFFTSize; lCopyCntr++)
00036 {
00037 fpDest[lCopyCntr] = (GDT) 0;
00038 }
00039 }
00040
00041
00042 void clAudio3D::HeadingElev0 (int iHeading)
00043 {
00044 int iAH = abs(iHeading);
00045
00046 if (iAH >= 0 && iAH <= 2)
00047 {
00048 CopyToLocal(fpLeftFilt, fpH0e000aL);
00049 CopyToLocal(fpRightFilt, fpH0e000aR);
00050 }
00051 else if (iAH >= 3 && iAH <= 7)
00052 {
00053 CopyToLocal(fpLeftFilt, fpH0e005aL);
00054 CopyToLocal(fpRightFilt, fpH0e005aR);
00055 }
00056 else if (iAH >= 8 && iAH <= 12)
00057 {
00058 CopyToLocal(fpLeftFilt, fpH0e010aL);
00059 CopyToLocal(fpRightFilt, fpH0e010aR);
00060 }
00061 else if (iAH >= 13 && iAH <= 17)
00062 {
00063 CopyToLocal(fpLeftFilt, fpH0e015aL);
00064 CopyToLocal(fpRightFilt, fpH0e015aR);
00065 }
00066 else if (iAH >= 18 && iAH <= 22)
00067 {
00068 CopyToLocal(fpLeftFilt, fpH0e020aL);
00069 CopyToLocal(fpRightFilt, fpH0e020aR);
00070 }
00071 else if (iAH >= 23 && iAH <= 27)
00072 {
00073 CopyToLocal(fpLeftFilt, fpH0e025aL);
00074 CopyToLocal(fpRightFilt, fpH0e025aR);
00075 }
00076 else if (iAH >= 28 && iAH <= 32)
00077 {
00078 CopyToLocal(fpLeftFilt, fpH0e030aL);
00079 CopyToLocal(fpRightFilt, fpH0e030aR);
00080 }
00081 else if (iAH >= 33 && iAH <= 37)
00082 {
00083 CopyToLocal(fpLeftFilt, fpH0e035aL);
00084 CopyToLocal(fpRightFilt, fpH0e035aR);
00085 }
00086 else if (iAH >= 38 && iAH <= 42)
00087 {
00088 CopyToLocal(fpLeftFilt, fpH0e040aL);
00089 CopyToLocal(fpRightFilt, fpH0e040aR);
00090 }
00091 else if (iAH >= 43 && iAH <= 47)
00092 {
00093 CopyToLocal(fpLeftFilt, fpH0e045aL);
00094 CopyToLocal(fpRightFilt, fpH0e045aR);
00095 }
00096 else if (iAH >= 48 && iAH <= 52)
00097 {
00098 CopyToLocal(fpLeftFilt, fpH0e050aL);
00099 CopyToLocal(fpRightFilt, fpH0e050aR);
00100 }
00101 else if (iAH >= 53 && iAH <= 57)
00102 {
00103 CopyToLocal(fpLeftFilt, fpH0e055aL);
00104 CopyToLocal(fpRightFilt, fpH0e055aR);
00105 }
00106 else if (iAH >= 58 && iAH <= 62)
00107 {
00108 CopyToLocal(fpLeftFilt, fpH0e060aL);
00109 CopyToLocal(fpRightFilt, fpH0e060aR);
00110 }
00111 else if (iAH >= 63 && iAH <= 67)
00112 {
00113 CopyToLocal(fpLeftFilt, fpH0e065aL);
00114 CopyToLocal(fpRightFilt, fpH0e065aR);
00115 }
00116 else if (iAH >= 68 && iAH <= 72)
00117 {
00118 CopyToLocal(fpLeftFilt, fpH0e070aL);
00119 CopyToLocal(fpRightFilt, fpH0e070aR);
00120 }
00121 else if (iAH >= 73 && iAH <= 77)
00122 {
00123 CopyToLocal(fpLeftFilt, fpH0e075aL);
00124 CopyToLocal(fpRightFilt, fpH0e075aR);
00125 }
00126 else if (iAH >= 78 && iAH <= 82)
00127 {
00128 CopyToLocal(fpLeftFilt, fpH0e080aL);
00129 CopyToLocal(fpRightFilt, fpH0e080aR);
00130 }
00131 else if (iAH >= 83 && iAH <= 87)
00132 {
00133 CopyToLocal(fpLeftFilt, fpH0e085aL);
00134 CopyToLocal(fpRightFilt, fpH0e085aR);
00135 }
00136 else if (iAH >= 88 && iAH <= 92)
00137 {
00138 CopyToLocal(fpLeftFilt, fpH0e090aL);
00139 CopyToLocal(fpRightFilt, fpH0e090aR);
00140 }
00141 else if (iAH >= 93 && iAH <= 97)
00142 {
00143 CopyToLocal(fpLeftFilt, fpH0e095aL);
00144 CopyToLocal(fpRightFilt, fpH0e095aR);
00145 }
00146 else if (iAH >= 98 && iAH <= 102)
00147 {
00148 CopyToLocal(fpLeftFilt, fpH0e100aL);
00149 CopyToLocal(fpRightFilt, fpH0e100aR);
00150 }
00151 else if (iAH >= 103 && iAH <= 107)
00152 {
00153 CopyToLocal(fpLeftFilt, fpH0e105aL);
00154 CopyToLocal(fpRightFilt, fpH0e105aR);
00155 }
00156 else if (iAH >= 108 && iAH <= 112)
00157 {
00158 CopyToLocal(fpLeftFilt, fpH0e110aL);
00159 CopyToLocal(fpRightFilt, fpH0e110aR);
00160 }
00161 else if (iAH >= 113 && iAH <= 117)
00162 {
00163 CopyToLocal(fpLeftFilt, fpH0e115aL);
00164 CopyToLocal(fpRightFilt, fpH0e115aR);
00165 }
00166 else if (iAH >= 118 && iAH <= 122)
00167 {
00168 CopyToLocal(fpLeftFilt, fpH0e120aL);
00169 CopyToLocal(fpRightFilt, fpH0e120aR);
00170 }
00171 else if (iAH >= 123 && iAH <= 127)
00172 {
00173 CopyToLocal(fpLeftFilt, fpH0e125aL);
00174 CopyToLocal(fpRightFilt, fpH0e125aR);
00175 }
00176 else if (iAH >= 128 && iAH <= 132)
00177 {
00178 CopyToLocal(fpLeftFilt, fpH0e130aL);
00179 CopyToLocal(fpRightFilt, fpH0e130aR);
00180 }
00181 else if (iAH >= 133 && iAH <= 137)
00182 {
00183 CopyToLocal(fpLeftFilt, fpH0e135aL);
00184 CopyToLocal(fpRightFilt, fpH0e135aR);
00185 }
00186 else if (iAH >= 138 && iAH <= 142)
00187 {
00188 CopyToLocal(fpLeftFilt, fpH0e140aL);
00189 CopyToLocal(fpRightFilt, fpH0e140aR);
00190 }
00191 else if (iAH >= 143 && iAH <= 147)
00192 {
00193 CopyToLocal(fpLeftFilt, fpH0e145aL);
00194 CopyToLocal(fpRightFilt, fpH0e145aR);
00195 }
00196 else if (iAH >= 148 && iAH <= 152)
00197 {
00198 CopyToLocal(fpLeftFilt, fpH0e150aL);
00199 CopyToLocal(fpRightFilt, fpH0e150aR);
00200 }
00201 else if (iAH >= 153 && iAH <= 157)
00202 {
00203 CopyToLocal(fpLeftFilt, fpH0e155aL);
00204 CopyToLocal(fpRightFilt, fpH0e155aR);
00205 }
00206 else if (iAH >= 158 && iAH <= 162)
00207 {
00208 CopyToLocal(fpLeftFilt, fpH0e160aL);
00209 CopyToLocal(fpRightFilt, fpH0e160aR);
00210 }
00211 else if (iAH >= 163 && iAH <= 167)
00212 {
00213 CopyToLocal(fpLeftFilt, fpH0e165aL);
00214 CopyToLocal(fpRightFilt, fpH0e165aR);
00215 }
00216 else if (iAH >= 168 && iAH <= 172)
00217 {
00218 CopyToLocal(fpLeftFilt, fpH0e170aL);
00219 CopyToLocal(fpRightFilt, fpH0e170aR);
00220 }
00221 else if (iAH >= 173 && iAH <= 177)
00222 {
00223 CopyToLocal(fpLeftFilt, fpH0e175aL);
00224 CopyToLocal(fpRightFilt, fpH0e175aR);
00225 }
00226 else
00227 {
00228 CopyToLocal(fpLeftFilt, fpH0e180aL);
00229 CopyToLocal(fpRightFilt, fpH0e180aR);
00230 }
00231 if (iHeading >= 0)
00232 Prepare(false);
00233 else
00234 Prepare(true);
00235 }
00236
00237
00238 void clAudio3D::HeadingElev90 ()
00239 {
00240 CopyToLocal(fpLeftFilt, fpH90e000aL);
00241 CopyToLocal(fpRightFilt, fpH90e000aR);
00242 Prepare(false);
00243 }
00244
00245
00246 void clAudio3D::Prepare (bool bSwapped)
00247 {
00248 GDT fLeftMin;
00249 GDT fLeftMax;
00250 GDT fRightMin;
00251 GDT fRightMax;
00252 #ifdef __GNUG__
00253 GDT fpLeftMagn[lSpectSize];
00254 GDT fpRightMagn[lSpectSize];
00255 #else
00256 clDSPAlloc LeftMagn;
00257 clDSPAlloc RightMagn;
00258 GDT *fpLeftMagn = (GDT *) LeftMagn.Size(lSpectSize * sizeof(GDT));
00259 GDT *fpRightMagn = (GDT *) RightMagn.Size(lSpectSize * sizeof(GDT));
00260 #endif
00261
00262 if (!bSwapped)
00263 {
00264 DSP.FFTi(spLeftFilt, fpLeftFilt);
00265 DSP.FFTi(spRightFilt, fpRightFilt);
00266 }
00267 else
00268 {
00269 DSP.FFTi(spRightFilt, fpLeftFilt);
00270 DSP.FFTi(spLeftFilt, fpRightFilt);
00271 }
00272 DSP.Magnitude(fpLeftMagn, spLeftFilt, lSpectSize);
00273 DSP.Magnitude(fpRightMagn, spRightFilt, lSpectSize);
00274 DSP.MinMax(&fLeftMin, &fLeftMax, fpLeftMagn, lSpectSize);
00275 DSP.MinMax(&fRightMin, &fRightMax, fpRightMagn, lSpectSize);
00276 if (fLeftMax >= fRightMax)
00277 fAmp = (GDT) 1 / fLeftMax;
00278 else
00279 fAmp = (GDT) 1 / fRightMax;
00280 }
00281
00282
00283 void clAudio3D::ProcessDistance (GDT *fpLeft, GDT *fpRight, long lDataCount)
00284 {
00285 long lDataCntr;
00286 GDT fWeight2 = (GDT) 1 - fDistance;
00287
00288 for (lDataCntr = 0l; lDataCntr < lDataCount; lDataCntr++)
00289 {
00290 fpLeft[lDataCntr] =
00291 fpLeft[lDataCntr] * fWeight2 + fpRight[lDataCntr] * fDistance;
00292 fpRight[lDataCntr] =
00293 fpRight[lDataCntr] * fWeight2 + fpLeft[lDataCntr] * fDistance;
00294 }
00295 }
00296
00297
00298 clAudio3D::clAudio3D ()
00299 {
00300 bInitialized = false;
00301 }
00302
00303
00304 clAudio3D::~clAudio3D ()
00305 {
00306 if (bInitialized) Uninitialize();
00307 }
00308
00309
00310 void clAudio3D::Initialize (long lSize)
00311 {
00312 GDT *fpNullPtr = NULL;
00313
00314 if (bInitialized) Uninitialize();
00315 lWindowSize = lSize;
00316 lFFTSize = lWindowSize;
00317 lSpectSize = lFFTSize / 2 + 1;
00318 DSP.FFTInitialize(lFFTSize, true);
00319 fpLeftFilt = (GDT *) LeftFilt.Size(lFFTSize * sizeof(GDT));
00320 fpRightFilt = (GDT *) RightFilt.Size(lFFTSize * sizeof(GDT));
00321 spLeftFilt = (GCDT *) CLeftFilt.Size(lSpectSize * sizeof(GCDT));
00322 spRightFilt = (GCDT *) CRightFilt.Size(lSpectSize * sizeof(GCDT));
00323 LeftData.Size(lWindowSize * sizeof(GDT));
00324 RightData.Size(lWindowSize * sizeof(GDT));
00325 CopyToLocal(fpLeftFilt, fpH0e000aL);
00326 CopyToLocal(fpRightFilt, fpH0e000aR);
00327 Prepare(false);
00328 FilterLeft.Initialize(lWindowSize, fpNullPtr);
00329 FilterRight.Initialize(lWindowSize, fpNullPtr);
00330 bInitialized = true;
00331 }
00332
00333
00334 void clAudio3D::Uninitialize ()
00335 {
00336 FilterLeft.Uninitialize();
00337 FilterRight.Uninitialize();
00338 DSP.FFTUninitialize();
00339 bInitialized = false;
00340 }
00341
00342
00343 void clAudio3D::SetAngles (int iHeading, int iPitch, GDT fDist)
00344 {
00345 if (iPitch <= -35) HeadingElevN40(iHeading);
00346 else if (iPitch > -35 && iPitch <= -25) HeadingElevN30(iHeading);
00347 else if (iPitch > -25 && iPitch <= -15) HeadingElevN20(iHeading);
00348 else if (iPitch > -15 && iPitch <= -5) HeadingElevN10(iHeading);
00349 else if (iPitch > -5 && iPitch < 5) HeadingElev0(iHeading);
00350 else if (iPitch >= 5 && iPitch < 15) HeadingElev10(iHeading);
00351 else if (iPitch >= 15 && iPitch < 25) HeadingElev20(iHeading);
00352 else if (iPitch >= 25 && iPitch < 35) HeadingElev30(iHeading);
00353 else if (iPitch >= 35 && iPitch < 45) HeadingElev40(iHeading);
00354 else if (iPitch >= 45 && iPitch < 55) HeadingElev50(iHeading);
00355 else if (iPitch >= 55 && iPitch < 65) HeadingElev60(iHeading);
00356 else if (iPitch >= 65 && iPitch < 75) HeadingElev70(iHeading);
00357 else if (iPitch >= 75 && iPitch < 85) HeadingElev80(iHeading);
00358 else HeadingElev90();
00359 fDistance = fDist;
00360 }
00361
00362
00363 void clAudio3D::Process (GDT *fpData)
00364 {
00365 long lDestCntr;
00366 long lSrcCntr;
00367 GDT *fpLeftData = LeftData;
00368 GDT *fpRightData = RightData;
00369
00370 lSrcCntr = 0l;
00371 for (lDestCntr = 0l; lDestCntr < lWindowSize; lDestCntr++)
00372 {
00373 fpLeftData[lDestCntr] = fpData[lSrcCntr++];
00374 fpRightData[lDestCntr] = fpData[lSrcCntr++];
00375 }
00376 FilterLeft.SetCoeffs(spLeftFilt);
00377 FilterRight.SetCoeffs(spRightFilt);
00378 FilterLeft.Put(fpLeftData, lWindowSize);
00379 FilterRight.Put(fpRightData, lWindowSize);
00380 if (!FilterLeft.Get(fpLeftData, lWindowSize))
00381 DSP.Zero(fpLeftData, lWindowSize);
00382 if (!FilterRight.Get(fpRightData, lWindowSize))
00383 DSP.Zero(fpRightData, lWindowSize);
00384 ProcessDistance(fpLeftData, fpRightData, lWindowSize);
00385 DSP.Mul(fpLeftData, fAmp, lWindowSize);
00386 DSP.Mul(fpRightData, fAmp, lWindowSize);
00387 lDestCntr = 0l;
00388 for (lSrcCntr = 0l; lSrcCntr < lWindowSize; lSrcCntr++)
00389 {
00390 fpData[lDestCntr++] = fpLeftData[lSrcCntr];
00391 fpData[lDestCntr++] = fpRightData[lSrcCntr];
00392 }
00393 }
00394
00395
00396 void clAudio3D::Process (GDT *fpLeftData, GDT *fpRightData)
00397 {
00398 FilterLeft.SetCoeffs(spLeftFilt);
00399 FilterRight.SetCoeffs(spRightFilt);
00400 FilterLeft.Put(fpLeftData, lWindowSize);
00401 FilterRight.Put(fpRightData, lWindowSize);
00402 if (!FilterLeft.Get(fpLeftData, lWindowSize))
00403 DSP.Zero(fpLeftData, lWindowSize);
00404 if (!FilterRight.Get(fpRightData, lWindowSize))
00405 DSP.Zero(fpRightData, lWindowSize);
00406 ProcessDistance(fpLeftData, fpRightData, lWindowSize);
00407 DSP.Mul(fpLeftData, fAmp, lWindowSize);
00408 DSP.Mul(fpRightData, fAmp, lWindowSize);
00409 }
00410