From 1709e7ed8ab8d925f1c67640cfd5ac3dbb80eb92 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 3 Jun 2012 01:50:53 +0200 Subject: [PATCH] Added: Specific code for amplitude based rolloff to avoid unneccesary log10 and pow calls and improve performance --- code/nel/src/sound/driver/source.cpp | 53 ++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/code/nel/src/sound/driver/source.cpp b/code/nel/src/sound/driver/source.cpp index df99b59ee..3ef9aa279 100644 --- a/code/nel/src/sound/driver/source.cpp +++ b/code/nel/src/sound/driver/source.cpp @@ -65,12 +65,59 @@ sint32 ISource::computeManualRollOff(sint32 volumeMB, sint32 mbMin, sint32 mbMax // common method used only with OptionManualRolloff. return the rolloff in amplitude ratio (gain) float ISource::computeManualRolloff(double alpha, float sqrdist, float distMin, float distMax) { - static const sint32 mbMin = -10000; - static const sint32 mbMax = 0; + /*static const sint mbMin = -10000; + static const sint mbMax = 0; sint32 rolloffMb = ISource::computeManualRollOff(mbMax, mbMin, mbMax, alpha, sqrdist, distMin, distMax); float rolloffGain = (float)pow(10.0, (double)rolloffMb / 2000.0); clamp(rolloffGain, 0.0f, 1.0f); - return rolloffGain; + return rolloffGain;*/ + + static const double mbMin = -10000; + static const double mbMax = 0; + + if (sqrdist < distMin * distMin) + { + // no attenuation + return 1.0f; + } + else + { + double dist = (double)sqrt(sqrdist); + if (alpha < 0.0f) + { + // inverse distance rolloff + float rolloff = distMin / dist; + if (alpha <= -1.0f) return rolloff; + + double mb = mbMin * (dist - distMin) / (distMax - distMin); + float mbrolloff = (float)pow(10.0, (double)mb / 2000.0); + return ((1.0 + alpha) * mbrolloff - alpha * rolloff); + } + else + { + if (sqrdist > distMax * distMax) + { + // full attenuation + return 0.0f; + } + if (alpha == 0.0f) + { + // linearly descending volume on a dB scale + double mb = mbMin * (dist - distMin) / (distMax - distMin); + return (float)pow(10.0, (double)mb / 2000.0); + } + else // if (alpha > 0.0f) + { + // linear distance rolloff + float rolloff = (distMax - dist) / (distMax - distMin); + if (alpha >= 1.0f) return rolloff; + + double mb = mbMin * (dist - distMin) / (distMax - distMin); + float mbrolloff = (float)pow(10.0, (double)mb / 2000.0); + return ((1.0 - alpha) * mbrolloff + alpha * rolloff); + } + } + } } } // NLSOUND