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.
This commit is contained in:
Ken Cooke 2016-07-14 18:34:07 -07:00
parent d84c7524bf
commit 2674df6095
2 changed files with 8 additions and 26 deletions

View file

@ -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;
}

View file

@ -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;