mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-07 18:02:31 +02:00
Merge pull request #14732 from kencooke/audio-distattn-improvements
Bug fixes and improvements to audio distance attenuation
This commit is contained in:
commit
5d49a3f6df
5 changed files with 35 additions and 11 deletions
|
@ -743,7 +743,7 @@ void AudioMixer::parseSettingsObject(const QJsonObject& settingsObject) {
|
|||
float coefficient = coefficientObject.value(COEFFICIENT).toString().toFloat(&ok);
|
||||
|
||||
|
||||
if (ok && coefficient >= 0.0f && coefficient <= 1.0f &&
|
||||
if (ok && coefficient <= 1.0f &&
|
||||
itSource != end(_audioZones) &&
|
||||
itListener != end(_audioZones)) {
|
||||
|
||||
|
|
|
@ -770,13 +770,29 @@ float computeGain(float masterListenerGain, const AvatarAudioStream& listeningNo
|
|||
break;
|
||||
}
|
||||
}
|
||||
// translate the zone setting to gain per log2(distance)
|
||||
float g = glm::clamp(1.0f - attenuationPerDoublingInDistance, EPSILON, 1.0f);
|
||||
|
||||
// calculate the attenuation using the distance to this node
|
||||
// reference attenuation of 0dB at distance = 1.0m
|
||||
gain *= fastExp2f(fastLog2f(g) * fastLog2f(std::max(distance, HRTF_NEARFIELD_MIN)));
|
||||
gain = std::min(gain, 1.0f / HRTF_NEARFIELD_MIN);
|
||||
if (attenuationPerDoublingInDistance < 0.0f) {
|
||||
// translate a negative zone setting to distance limit
|
||||
const float MIN_DISTANCE_LIMIT = ATTN_DISTANCE_REF + 1.0f; // silent after 1m
|
||||
float distanceLimit = std::max(-attenuationPerDoublingInDistance, MIN_DISTANCE_LIMIT);
|
||||
|
||||
// calculate the LINEAR attenuation using the distance to this node
|
||||
// reference attenuation of 0dB at distance = ATTN_DISTANCE_REF
|
||||
float d = distance - ATTN_DISTANCE_REF;
|
||||
gain *= std::max(1.0f - d / (distanceLimit - ATTN_DISTANCE_REF), 0.0f);
|
||||
gain = std::min(gain, ATTN_GAIN_MAX);
|
||||
|
||||
} else {
|
||||
// translate a positive zone setting to gain per log2(distance)
|
||||
const float MIN_ATTENUATION_COEFFICIENT = 0.001f; // -60dB per log2(distance)
|
||||
float g = glm::clamp(1.0f - attenuationPerDoublingInDistance, MIN_ATTENUATION_COEFFICIENT, 1.0f);
|
||||
|
||||
// calculate the LOGARITHMIC attenuation using the distance to this node
|
||||
// reference attenuation of 0dB at distance = ATTN_DISTANCE_REF
|
||||
float d = (1.0f / ATTN_DISTANCE_REF) * std::max(distance, HRTF_NEARFIELD_MIN);
|
||||
gain *= fastExp2f(fastLog2f(g) * fastLog2f(d));
|
||||
gain = std::min(gain, ATTN_GAIN_MAX);
|
||||
}
|
||||
|
||||
return gain;
|
||||
}
|
||||
|
|
|
@ -1979,8 +1979,10 @@ float AudioClient::azimuthForSource(const glm::vec3& relativePosition) {
|
|||
float AudioClient::gainForSource(float distance, float volume) {
|
||||
|
||||
// attenuation = -6dB * log2(distance)
|
||||
// reference attenuation of 0dB at distance = 1.0m
|
||||
float gain = volume / std::max(distance, HRTF_NEARFIELD_MIN);
|
||||
// reference attenuation of 0dB at distance = ATTN_DISTANCE_REF
|
||||
float d = (1.0f / ATTN_DISTANCE_REF) * std::max(distance, HRTF_NEARFIELD_MIN);
|
||||
float gain = volume / d;
|
||||
gain = std::min(gain, ATTN_GAIN_MAX);
|
||||
|
||||
return gain;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,10 @@ static const float HRTF_NEARFIELD_MAX = 1.0f; // distance in meters
|
|||
static const float HRTF_NEARFIELD_MIN = 0.125f; // distance in meters
|
||||
static const float HRTF_HEAD_RADIUS = 0.0875f; // average human head in meters
|
||||
|
||||
// Distance attenuation
|
||||
static const float ATTN_DISTANCE_REF = 2.0f; // distance where attn is 0dB
|
||||
static const float ATTN_GAIN_MAX = 16.0f; // max gain allowed by distance attn (+24dB)
|
||||
|
||||
class AudioHRTF {
|
||||
|
||||
public:
|
||||
|
|
|
@ -43,8 +43,9 @@ static inline float fastLog2f(float x) {
|
|||
}
|
||||
|
||||
//
|
||||
// for -127 <= x < 128, returns exp2(x)
|
||||
// otherwise, returns undefined
|
||||
// for -126 <= x < 128, returns exp2(x)
|
||||
// for x < -126, returns 0
|
||||
// for x >= 128, returns undefined
|
||||
//
|
||||
// rel |error| < 9e-6, smooth (exact for x=N)
|
||||
//
|
||||
|
@ -60,6 +61,7 @@ static inline float fastExp2f(float x) {
|
|||
x -= xi.i;
|
||||
|
||||
// construct exp2(xi) as a float
|
||||
xi.i &= ~(xi.i >> 31); // MAX(xi.i, 0)
|
||||
xi.i <<= IEEE754_MANT_BITS;
|
||||
|
||||
// polynomial for exp2(x) over x=[0,1]
|
||||
|
|
Loading…
Reference in a new issue