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