From 3ffaced0f3588dd24568dfc930ce7be25656cf73 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Thu, 17 Jan 2019 13:59:33 -0800 Subject: [PATCH] Experimental attenuation curve: linear falloff, with prescribed propagation limit. A positive coefficient sets logarithmic falloff, as before. A negative coefficient sets linear falloff, where abs(coefficient) is the distance limit in meters. --- assignment-client/src/audio/AudioMixer.cpp | 2 +- .../src/audio/AudioMixerSlave.cpp | 30 ++++++++++++++----- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 77f416f31e..f80ce2f4c3 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -736,7 +736,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)) { diff --git a/assignment-client/src/audio/AudioMixerSlave.cpp b/assignment-client/src/audio/AudioMixerSlave.cpp index 3caa5584da..a7abea3704 100644 --- a/assignment-client/src/audio/AudioMixerSlave.cpp +++ b/assignment-client/src/audio/AudioMixerSlave.cpp @@ -770,15 +770,29 @@ float computeGain(float masterListenerGain, const AvatarAudioStream& listeningNo break; } } - // translate the 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 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); + 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; }