mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-13 22:27:13 +02:00
Compensate the near-field azimuth correction for the parallax baked into the HRTF dataset
This commit is contained in:
parent
cc7b9a254b
commit
41ccf6afd8
2 changed files with 26 additions and 12 deletions
|
@ -775,20 +775,28 @@ static void distanceBiquad(float distance, float& b0, float& b1, float& b2, floa
|
|||
// Geometric correction of the azimuth, to the angle at each ear.
|
||||
// D. Brungart, "Auditory parallax effects in the HRTF for nearby sources," IEEE WASPAA (1999).
|
||||
//
|
||||
static void nearFieldAzimuth(float azimuth, float distance, float& azimuthL, float& azimuthR) {
|
||||
static void nearFieldAzimuthCorrection(float azimuth, float distance, float& azimuthL, float& azimuthR) {
|
||||
|
||||
// FIXME: optimize
|
||||
float dx = distance * cosf(azimuth);
|
||||
float dy = distance * sinf(azimuth);
|
||||
|
||||
azimuthL = atan2f(dy + HRTF_HEAD_RADIUS, dx);
|
||||
azimuthR = atan2f(dy - HRTF_HEAD_RADIUS, dx);
|
||||
// at reference distance, the azimuth parallax is correct
|
||||
float dx0 = HRTF_AZIMUTH_REF * cosf(azimuth);
|
||||
float dy0 = HRTF_AZIMUTH_REF * sinf(azimuth);
|
||||
|
||||
float deltaL = atan2f(dy + HRTF_HEAD_RADIUS, dx) - atan2f(dy0 + HRTF_HEAD_RADIUS, dx0);
|
||||
float deltaR = atan2f(dy - HRTF_HEAD_RADIUS, dx) - atan2f(dy0 - HRTF_HEAD_RADIUS, dx0);
|
||||
|
||||
// add the azimuth correction
|
||||
// NOTE: must converge to 0 when distance = HRTF_AZIMUTH_REF
|
||||
azimuthL += deltaL;
|
||||
azimuthR += deltaR;
|
||||
}
|
||||
|
||||
//
|
||||
// Approximate the near-field DC gain correction at each ear.
|
||||
//
|
||||
static void nearFieldGain(float azimuth, float distance, float& gainL, float& gainR) {
|
||||
static void nearFieldGainCorrection(float azimuth, float distance, float& gainL, float& gainR) {
|
||||
|
||||
// normalized distance factor = [0,1] as distance = [HRTF_NEARFIELD_MAX,HRTF_HEAD_RADIUS]
|
||||
assert(distance < HRTF_NEARFIELD_MAX);
|
||||
|
@ -816,9 +824,9 @@ static void nearFieldGain(float azimuth, float distance, float& gainL, float& ga
|
|||
float cR = ((-0.000452339132f * angleR - 0.00173192444f) * angleR + 0.162476536f) * angleR;
|
||||
|
||||
// approximate the gain correction
|
||||
// NOTE: this must converge to 1.0 when distance = HRTF_NEARFIELD_MAX at all azimuth
|
||||
gainL = 1.0f - d * cL;
|
||||
gainR = 1.0f - d * cR;
|
||||
// NOTE: must converge to 0 when distance = HRTF_NEARFIELD_MAX
|
||||
gainL -= d * cL;
|
||||
gainR -= d * cR;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -894,14 +902,17 @@ static void setFilters(float firCoef[4][HRTF_TAPS], float bqCoef[5][8], int dela
|
|||
distance = MAX(distance, HRTF_NEARFIELD_MIN);
|
||||
|
||||
// compute the azimuth correction at each ear
|
||||
float azimuthL, azimuthR;
|
||||
nearFieldAzimuth(azimuth, distance, azimuthL, azimuthR);
|
||||
float azimuthL = azimuth;
|
||||
float azimuthR = azimuth;
|
||||
if (distance < HRTF_AZIMUTH_REF) {
|
||||
nearFieldAzimuthCorrection(azimuth, distance, azimuthL, azimuthR);
|
||||
}
|
||||
|
||||
// compute the DC gain correction at each ear
|
||||
float gainL = 1.0f;
|
||||
float gainR = 1.0f;
|
||||
if (distance < HRTF_NEARFIELD_MAX) {
|
||||
nearFieldGain(azimuth, distance, gainL, gainR);
|
||||
nearFieldGainCorrection(azimuth, distance, gainL, gainR);
|
||||
}
|
||||
|
||||
// parameters for table interpolation
|
||||
|
@ -976,7 +987,8 @@ static void setFilters(float firCoef[4][HRTF_TAPS], float bqCoef[5][8], int dela
|
|||
//
|
||||
// Second biquad implements the near-field or distance filter.
|
||||
//
|
||||
if (distance < 1.0f) {
|
||||
if (distance < HRTF_NEARFIELD_MAX) {
|
||||
|
||||
nearFieldFilter(gainL, b0, b1, a1);
|
||||
|
||||
bqCoef[0][channel+4] = b0;
|
||||
|
@ -994,6 +1006,7 @@ static void setFilters(float firCoef[4][HRTF_TAPS], float bqCoef[5][8], int dela
|
|||
bqCoef[4][channel+5] = 0.0f;
|
||||
|
||||
} else {
|
||||
|
||||
distanceBiquad(distance, b0, b1, b2, a1, a2);
|
||||
|
||||
bqCoef[0][channel+4] = b0;
|
||||
|
|
|
@ -24,6 +24,7 @@ static const int HRTF_BLOCK = 240; // block processing size
|
|||
static const float HRTF_GAIN = 1.0f; // HRTF global gain adjustment
|
||||
|
||||
// Near-field HRTF
|
||||
static const float HRTF_AZIMUTH_REF = 2.0f; // IRCAM Listen HRTF was recorded at 2 meters
|
||||
static const float HRTF_NEARFIELD_MAX = 1.0f; // distance in meters
|
||||
static const float HRTF_NEARFIELD_MIN = 0.125f; // distance in meters
|
||||
static const float HRTF_HEAD_RADIUS = 0.0875f; // average human head in meters
|
||||
|
|
Loading…
Reference in a new issue