mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
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:
parent
d84c7524bf
commit
2674df6095
2 changed files with 8 additions and 26 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue