mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-09 16:52:12 +02:00
Merge pull request #10831 from kencooke/audio-hrtf-optimize
More HRTF optimizations
This commit is contained in:
commit
e9edf01a34
3 changed files with 68 additions and 17 deletions
|
@ -497,13 +497,14 @@ float computeGain(const AvatarAudioStream& listeningNodeStream, const Positional
|
|||
// avatar: apply fixed off-axis attenuation to make them quieter as they turn away
|
||||
} else if (!isEcho && (streamToAdd.getType() == PositionalAudioStream::Microphone)) {
|
||||
glm::vec3 rotatedListenerPosition = glm::inverse(streamToAdd.getOrientation()) * relativePosition;
|
||||
float angleOfDelivery = glm::angle(glm::vec3(0.0f, 0.0f, -1.0f),
|
||||
glm::normalize(rotatedListenerPosition));
|
||||
|
||||
// source directivity is based on angle of emission, in local coordinates
|
||||
glm::vec3 direction = glm::normalize(rotatedListenerPosition);
|
||||
float angleOfDelivery = fastAcosf(glm::clamp(-direction.z, -1.0f, 1.0f)); // UNIT_NEG_Z is "forward"
|
||||
|
||||
const float MAX_OFF_AXIS_ATTENUATION = 0.2f;
|
||||
const float OFF_AXIS_ATTENUATION_STEP = (1 - MAX_OFF_AXIS_ATTENUATION) / 2.0f;
|
||||
float offAxisCoefficient = MAX_OFF_AXIS_ATTENUATION +
|
||||
(angleOfDelivery * (OFF_AXIS_ATTENUATION_STEP / PI_OVER_TWO));
|
||||
float offAxisCoefficient = MAX_OFF_AXIS_ATTENUATION + (angleOfDelivery * (OFF_AXIS_ATTENUATION_STEP / PI_OVER_TWO));
|
||||
|
||||
gain *= offAxisCoefficient;
|
||||
}
|
||||
|
@ -545,7 +546,6 @@ float computeAzimuth(const AvatarAudioStream& listeningNodeStream, const Positio
|
|||
const glm::vec3& relativePosition) {
|
||||
glm::quat inverseOrientation = glm::inverse(listeningNodeStream.getOrientation());
|
||||
|
||||
// Compute sample delay for the two ears to create phase panning
|
||||
glm::vec3 rotatedSourcePosition = inverseOrientation * relativePosition;
|
||||
|
||||
// project the rotated source position vector onto the XZ plane
|
||||
|
@ -553,11 +553,16 @@ float computeAzimuth(const AvatarAudioStream& listeningNodeStream, const Positio
|
|||
|
||||
const float SOURCE_DISTANCE_THRESHOLD = 1e-30f;
|
||||
|
||||
if (glm::length2(rotatedSourcePosition) > SOURCE_DISTANCE_THRESHOLD) {
|
||||
float rotatedSourcePositionLength2 = glm::length2(rotatedSourcePosition);
|
||||
if (rotatedSourcePositionLength2 > SOURCE_DISTANCE_THRESHOLD) {
|
||||
|
||||
// produce an oriented angle about the y-axis
|
||||
return glm::orientedAngle(glm::vec3(0.0f, 0.0f, -1.0f), glm::normalize(rotatedSourcePosition), glm::vec3(0.0f, -1.0f, 0.0f));
|
||||
} else {
|
||||
// there is no distance between listener and source - return no azimuth
|
||||
return 0;
|
||||
glm::vec3 direction = rotatedSourcePosition * (1.0f / fastSqrtf(rotatedSourcePositionLength2));
|
||||
float angle = fastAcosf(glm::clamp(-direction.z, -1.0f, 1.0f)); // UNIT_NEG_Z is "forward"
|
||||
return (direction.x < 0.0f) ? -angle : angle;
|
||||
|
||||
} else {
|
||||
// no azimuth if they are in same spot
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
|
||||
#include "AudioClientLogging.h"
|
||||
#include "AudioLogging.h"
|
||||
#include "AudioHelpers.h"
|
||||
|
||||
#include "AudioClient.h"
|
||||
|
||||
|
@ -1688,23 +1689,24 @@ int AudioClient::calculateNumberOfFrameSamples(int numBytes) const {
|
|||
}
|
||||
|
||||
float AudioClient::azimuthForSource(const glm::vec3& relativePosition) {
|
||||
// copied from AudioMixer, more or less
|
||||
glm::quat inverseOrientation = glm::inverse(_orientationGetter());
|
||||
|
||||
// compute sample delay for the 2 ears to create phase panning
|
||||
glm::vec3 rotatedSourcePosition = inverseOrientation * relativePosition;
|
||||
|
||||
// project the rotated source position vector onto x-y plane
|
||||
// project the rotated source position vector onto the XZ plane
|
||||
rotatedSourcePosition.y = 0.0f;
|
||||
|
||||
static const float SOURCE_DISTANCE_THRESHOLD = 1e-30f;
|
||||
|
||||
if (glm::length2(rotatedSourcePosition) > SOURCE_DISTANCE_THRESHOLD) {
|
||||
float rotatedSourcePositionLength2 = glm::length2(rotatedSourcePosition);
|
||||
if (rotatedSourcePositionLength2 > SOURCE_DISTANCE_THRESHOLD) {
|
||||
|
||||
// produce an oriented angle about the y-axis
|
||||
return glm::orientedAngle(glm::vec3(0.0f, 0.0f, -1.0f), glm::normalize(rotatedSourcePosition), glm::vec3(0.0f, -1.0f, 0.0f));
|
||||
} else {
|
||||
|
||||
glm::vec3 direction = rotatedSourcePosition * (1.0f / fastSqrtf(rotatedSourcePositionLength2));
|
||||
float angle = fastAcosf(glm::clamp(-direction.z, -1.0f, 1.0f)); // UNIT_NEG_Z is "forward"
|
||||
return (direction.x < 0.0f) ? -angle : angle;
|
||||
|
||||
} else {
|
||||
// no azimuth if they are in same spot
|
||||
return 0.0f;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <NumericalConstants.h>
|
||||
|
||||
const int IEEE754_MANT_BITS = 23;
|
||||
const int IEEE754_EXPN_BIAS = 127;
|
||||
|
||||
|
@ -66,6 +68,48 @@ static inline float fastExp2f(float x) {
|
|||
return x * xi.f;
|
||||
}
|
||||
|
||||
//
|
||||
// on x86 architecture, assume that SSE2 is present
|
||||
//
|
||||
#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__x86_64__)
|
||||
|
||||
#include <xmmintrin.h>
|
||||
// inline sqrtss, without requiring /fp:fast
|
||||
static inline float fastSqrtf(float x) {
|
||||
return _mm_cvtss_f32(_mm_sqrt_ss(_mm_set_ss(x)));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline float fastSqrtf(float x) {
|
||||
return sqrtf(x);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// for -1 <= x <= 1, returns acos(x)
|
||||
// otherwise, returns NaN
|
||||
//
|
||||
// abs |error| < 7e-5, smooth
|
||||
//
|
||||
static inline float fastAcosf(float x) {
|
||||
|
||||
union { float f; int32_t i; } xi = { x };
|
||||
|
||||
int32_t sign = xi.i & 0x80000000;
|
||||
xi.i ^= sign; // fabs(x)
|
||||
|
||||
// compute sqrt(1-x) in parallel
|
||||
float r = fastSqrtf(1.0f - xi.f);
|
||||
|
||||
// polynomial for acos(x)/sqrt(1-x) over x=[0,1]
|
||||
xi.f = ((-0.0198439236f * xi.f + 0.0762021306f) * xi.f + -0.212940971f) * xi.f + 1.57079633f;
|
||||
|
||||
xi.f *= r;
|
||||
return (sign ? PI - xi.f : xi.f);
|
||||
}
|
||||
|
||||
//
|
||||
// Quantize a non-negative gain value to the nearest 0.5dB, and pack to a byte.
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue