Refactor distance attenuation for near-field HRTF.

Adds near-field attenuation from 0.125m to 1m, calibrated to 0dB at 1m. Overload will trigger dynamic range compression at the peak-limiter.
This commit is contained in:
Ken Cooke 2018-02-22 16:05:01 -08:00
parent e367167709
commit f25b8e8df0
2 changed files with 9 additions and 27 deletions

View file

@ -489,9 +489,6 @@ float approximateGain(const AvatarAudioStream& listeningNodeStream, const Positi
// avatar: skip attenuation - it is too costly to approximate
// distance attenuation: approximate, ignore zone-specific attenuations
// this is a good approximation for streams further than ATTENUATION_START_DISTANCE
// those streams closer will be amplified; amplifying close streams is acceptable
// when throttling, as close streams are expected to be heard by a user
float distance = glm::length(relativePosition);
return gain / distance;
@ -536,23 +533,15 @@ float computeGain(const AudioMixerClientData& listenerNodeData, const AvatarAudi
break;
}
}
// translate the zone setting to gain per log2(distance)
float g = glm::clamp(1.0f - attenuationPerDoublingInDistance, EPSILON, 1.0f);
// distance attenuation
const float ATTENUATION_START_DISTANCE = 1.0f;
float distance = glm::length(relativePosition);
assert(ATTENUATION_START_DISTANCE > EPSILON);
if (distance >= ATTENUATION_START_DISTANCE) {
// translate the zone setting to gain per log2(distance)
float g = 1.0f - attenuationPerDoublingInDistance;
g = glm::clamp(g, EPSILON, 1.0f);
// calculate the distance coefficient using the distance to this node
float distanceCoefficient = fastExp2f(fastLog2f(g) * fastLog2f(distance/ATTENUATION_START_DISTANCE));
// multiply the current attenuation coefficient by the distance coefficient
gain *= distanceCoefficient;
}
// calculate the attenuation using the distance to this node
// reference attenuation of 0dB at distance = 1.0m
gain *= exp2f(log2f(g) * log2f(std::max(distance, HRTF_DISTANCE_MIN)));
gain = std::min(gain, 1.0f / HRTF_DISTANCE_MIN);
return gain;
}

View file

@ -1824,16 +1824,9 @@ float AudioClient::azimuthForSource(const glm::vec3& relativePosition) {
float AudioClient::gainForSource(float distance, float volume) {
const float ATTENUATION_BEGINS_AT_DISTANCE = 1.0f;
// I'm assuming that the AudioMixer's getting of the stream's attenuation
// factor is basically same as getting volume
float gain = volume;
// attenuate based on distance
if (distance >= ATTENUATION_BEGINS_AT_DISTANCE) {
gain /= (distance/ATTENUATION_BEGINS_AT_DISTANCE); // attenuation = -6dB * log2(distance)
}
// attenuation = -6dB * log2(distance)
// reference attenuation of 0dB at distance = 1.0m
float gain = volume / std::max(distance, HRTF_DISTANCE_MIN);
return gain;
}