From 2674df6095382bc6894265e3810c4ceb1aad9824 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Thu, 14 Jul 2016 18:34:07 -0700 Subject: [PATCH] Fix the distance-attenuation model (for injectors only) The original attenuation model seems wrong, under-attenuating at close distance but completely muting after 45m. This uses a physics-based model of -6dB per doubling of distance in free space, for the injectors. The AudioMixer model and domain settings still need to be reworked in a future PR. --- libraries/audio-client/src/AudioClient.cpp | 32 +++++----------------- libraries/audio-client/src/AudioClient.h | 2 +- 2 files changed, 8 insertions(+), 26 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 50039ba668..84d0146f3b 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -885,7 +885,7 @@ void AudioClient::mixLocalAudioInjectors(int16_t* inputBuffer) { // calculate distance, gain and azimuth for hrtf glm::vec3 relativePosition = injector->getPosition() - _positionGetter(); float distance = glm::max(glm::length(relativePosition), EPSILON); - float gain = gainForSource(relativePosition, injector->getVolume()); + float gain = gainForSource(distance, injector->getVolume()); float azimuth = azimuthForSource(relativePosition); injector->getLocalHRTF().render(_scratchBuffer, _hrtfBuffer, 1, azimuth, distance, gain, AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL); @@ -1299,37 +1299,19 @@ float AudioClient::azimuthForSource(const glm::vec3& relativePosition) { } } -float AudioClient::gainForSource(const glm::vec3& relativePosition, float volume) { - // TODO: put these in a place where we can share with AudioMixer! - const float DEFAULT_ATTENUATION_PER_DOUBLING_IN_DISTANCE = 0.18f; +float AudioClient::gainForSource(float distance, float volume) { + const float ATTENUATION_BEGINS_AT_DISTANCE = 1.0f; - - //qDebug() << "initial gain is " << volume; - // I'm assuming that the AudioMixer's getting of the stream's attenuation // factor is basically same as getting volume float gain = volume; - float distanceBetween = glm::length(relativePosition); - if (distanceBetween < EPSILON ) { - distanceBetween = EPSILON; + + // attenuate based on distance + if (distance >= ATTENUATION_BEGINS_AT_DISTANCE) { + gain /= distance; // attenuation = -6dB * log2(distance) } - // audio mixer has notion of zones. Unsure how to map that across here... - - // attenuate based on distance now - if (distanceBetween >= ATTENUATION_BEGINS_AT_DISTANCE) { - float distanceCoefficient = 1.0f - (logf(distanceBetween/ATTENUATION_BEGINS_AT_DISTANCE) / logf(2.0f) - * DEFAULT_ATTENUATION_PER_DOUBLING_IN_DISTANCE); - if (distanceCoefficient < 0.0f) { - distanceCoefficient = 0.0f; - } - - gain *= distanceCoefficient; - } - - //qDebug() << "calculated gain as " << gain; - return gain; } diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index df7b10ab04..3e4aa931a6 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -217,7 +217,7 @@ private: void outputFormatChanged(); void mixLocalAudioInjectors(int16_t* inputBuffer); float azimuthForSource(const glm::vec3& relativePosition); - float gainForSource(const glm::vec3& relativePosition, float volume); + float gainForSource(float distance, float volume); QByteArray firstInputFrame; QAudioInput* _audioInput;