Store the HRTF tables used in the device

This commit is contained in:
Chris Robinson
2011-09-18 09:52:40 -07:00
parent ec3b78e52d
commit 25f7c27043
4 changed files with 44 additions and 34 deletions
+3 -1
View File
@@ -1190,9 +1190,11 @@ static ALCboolean UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
device->PendingClicks[i] = 0.0f;
}
device->Hrtf = NULL;
device->Flags &= ~DEVICE_USE_HRTF;
if(!device->IsLoopbackDevice && GetConfigValueBool(NULL, "hrtf", AL_FALSE))
device->Flags |= DEVICE_USE_HRTF;
if((device->Flags&DEVICE_USE_HRTF) && !IsHrtfCompatible(device))
if((device->Flags&DEVICE_USE_HRTF) && !(device->Hrtf=GetHrtf(device)))
device->Flags &= ~DEVICE_USE_HRTF;
TRACE("HRTF %s\n", (device->Flags&DEVICE_USE_HRTF)?"enabled":"disabled");
+6 -4
View File
@@ -283,7 +283,8 @@ ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext)
{
/* Get the static HRIR coefficients and delays for this
* channel. */
GetLerpedHrtfCoeffs(0.0, angles[c] * (M_PI/180.0),
GetLerpedHrtfCoeffs(ALContext->Device->Hrtf,
0.0, angles[c] * (M_PI/180.0),
DryGain*ListenerGain,
ALSource->Params.HrtfCoeffs[c],
ALSource->Params.HrtfDelay[c]);
@@ -722,8 +723,9 @@ ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext)
// coefficients, target delays, steppping values, and counter.
if(delta > 0.001f)
{
ALSource->HrtfCounter = GetMovingHrtfCoeffs(ev, az, DryGain,
delta, ALSource->HrtfCounter,
ALSource->HrtfCounter = GetMovingHrtfCoeffs(Device->Hrtf,
ev, az, DryGain, delta,
ALSource->HrtfCounter,
ALSource->Params.HrtfCoeffs[0],
ALSource->Params.HrtfDelay[0],
ALSource->Params.HrtfCoeffStep,
@@ -737,7 +739,7 @@ ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext)
else
{
// Get the initial (static) HRIR coefficients and delays.
GetLerpedHrtfCoeffs(ev, az, DryGain,
GetLerpedHrtfCoeffs(Device->Hrtf, ev, az, DryGain,
ALSource->Params.HrtfCoeffs[0],
ALSource->Params.HrtfDelay[0]);
ALSource->HrtfCounter = 0;
+26 -26
View File
@@ -53,7 +53,7 @@ static struct Hrtf {
ALuint sampleRate;
ALshort coeffs[HRIR_COUNT][HRIR_LENGTH];
ALubyte delays[HRIR_COUNT];
} Hrtf = {
} LoadedHrtf = {
44100,
#include "hrtf_tables.inc"
};
@@ -116,7 +116,7 @@ ALfloat CalcHrtfDelta(ALfloat oldGain, ALfloat newGain, const ALfloat olddir[3],
// elevation and azimuth in radians. Linear interpolation is used to
// increase the apparent resolution of the HRIR dataset. The coefficients
// are also normalized and attenuated by the specified gain.
void GetLerpedHrtfCoeffs(ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays)
void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays)
{
ALuint evidx[2], azidx[2];
ALfloat mu[3];
@@ -156,11 +156,11 @@ void GetLerpedHrtfCoeffs(ALfloat elevation, ALfloat azimuth, ALfloat gain, ALflo
ALdouble scale = gain * (1.0/32767.0);
for(i = 0;i < HRIR_LENGTH;i++)
{
coeffs[i][0] = lerp(lerp(Hrtf.coeffs[lidx[0]][i], Hrtf.coeffs[lidx[1]][i], mu[0]),
lerp(Hrtf.coeffs[lidx[2]][i], Hrtf.coeffs[lidx[3]][i], mu[1]),
coeffs[i][0] = lerp(lerp(Hrtf->coeffs[lidx[0]][i], Hrtf->coeffs[lidx[1]][i], mu[0]),
lerp(Hrtf->coeffs[lidx[2]][i], Hrtf->coeffs[lidx[3]][i], mu[1]),
mu[2]) * scale;
coeffs[i][1] = lerp(lerp(Hrtf.coeffs[ridx[0]][i], Hrtf.coeffs[ridx[1]][i], mu[0]),
lerp(Hrtf.coeffs[ridx[2]][i], Hrtf.coeffs[ridx[3]][i], mu[1]),
coeffs[i][1] = lerp(lerp(Hrtf->coeffs[ridx[0]][i], Hrtf->coeffs[ridx[1]][i], mu[0]),
lerp(Hrtf->coeffs[ridx[2]][i], Hrtf->coeffs[ridx[3]][i], mu[1]),
mu[2]) * scale;
}
}
@@ -174,11 +174,11 @@ void GetLerpedHrtfCoeffs(ALfloat elevation, ALfloat azimuth, ALfloat gain, ALflo
}
// Calculate the HRIR delays using linear interpolation.
delays[0] = (ALuint)(lerp(lerp(Hrtf.delays[lidx[0]], Hrtf.delays[lidx[1]], mu[0]),
lerp(Hrtf.delays[lidx[2]], Hrtf.delays[lidx[3]], mu[1]),
delays[0] = (ALuint)(lerp(lerp(Hrtf->delays[lidx[0]], Hrtf->delays[lidx[1]], mu[0]),
lerp(Hrtf->delays[lidx[2]], Hrtf->delays[lidx[3]], mu[1]),
mu[2]) * 65536.0f);
delays[1] = (ALuint)(lerp(lerp(Hrtf.delays[ridx[0]], Hrtf.delays[ridx[1]], mu[0]),
lerp(Hrtf.delays[ridx[2]], Hrtf.delays[ridx[3]], mu[1]),
delays[1] = (ALuint)(lerp(lerp(Hrtf->delays[ridx[0]], Hrtf->delays[ridx[1]], mu[0]),
lerp(Hrtf->delays[ridx[2]], Hrtf->delays[ridx[3]], mu[1]),
mu[2]) * 65536.0f);
}
@@ -188,7 +188,7 @@ void GetLerpedHrtfCoeffs(ALfloat elevation, ALfloat azimuth, ALfloat gain, ALflo
// HRIR dataset. The coefficients are also normalized and attenuated by the
// specified gain. Stepping resolution and count is determined using the
// given delta factor between 0.0 and 1.0.
ALuint GetMovingHrtfCoeffs(ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat delta, ALint counter, ALfloat (*coeffs)[2], ALuint *delays, ALfloat (*coeffStep)[2], ALint *delayStep)
ALuint GetMovingHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat delta, ALint counter, ALfloat (*coeffs)[2], ALuint *delays, ALfloat (*coeffStep)[2], ALint *delayStep)
{
ALuint evidx[2], azidx[2];
ALuint lidx[4], ridx[4];
@@ -223,7 +223,7 @@ ALuint GetMovingHrtfCoeffs(ALfloat elevation, ALfloat azimuth, ALfloat gain, ALf
ridx[3] = evOffset[evidx[1]] + ((azCount[evidx[1]]-azidx[1]) % azCount[evidx[1]]);
// Calculate the stepping parameters.
delta = maxf(floor(delta*(Hrtf.sampleRate*0.015f) + 0.5), 1.0f);
delta = maxf(floor(delta*(Hrtf->sampleRate*0.015f) + 0.5), 1.0f);
step = 1.0f / delta;
// Calculate the normalized and attenuated target HRIR coefficients using
@@ -239,11 +239,11 @@ ALuint GetMovingHrtfCoeffs(ALfloat elevation, ALfloat azimuth, ALfloat gain, ALf
left = coeffs[i][0] - (coeffStep[i][0] * counter);
right = coeffs[i][1] - (coeffStep[i][1] * counter);
coeffs[i][0] = lerp(lerp(Hrtf.coeffs[lidx[0]][i], Hrtf.coeffs[lidx[1]][i], mu[0]),
lerp(Hrtf.coeffs[lidx[2]][i], Hrtf.coeffs[lidx[3]][i], mu[1]),
coeffs[i][0] = lerp(lerp(Hrtf->coeffs[lidx[0]][i], Hrtf->coeffs[lidx[1]][i], mu[0]),
lerp(Hrtf->coeffs[lidx[2]][i], Hrtf->coeffs[lidx[3]][i], mu[1]),
mu[2]) * scale;
coeffs[i][1] = lerp(lerp(Hrtf.coeffs[ridx[0]][i], Hrtf.coeffs[ridx[1]][i], mu[0]),
lerp(Hrtf.coeffs[ridx[2]][i], Hrtf.coeffs[ridx[3]][i], mu[1]),
coeffs[i][1] = lerp(lerp(Hrtf->coeffs[ridx[0]][i], Hrtf->coeffs[ridx[1]][i], mu[0]),
lerp(Hrtf->coeffs[ridx[2]][i], Hrtf->coeffs[ridx[3]][i], mu[1]),
mu[2]) * scale;
coeffStep[i][0] = step * (coeffs[i][0] - left);
@@ -271,11 +271,11 @@ ALuint GetMovingHrtfCoeffs(ALfloat elevation, ALfloat azimuth, ALfloat gain, ALf
left = delays[0] - (delayStep[0] * counter);
right = delays[1] - (delayStep[1] * counter);
delays[0] = (ALuint)(lerp(lerp(Hrtf.delays[lidx[0]], Hrtf.delays[lidx[1]], mu[0]),
lerp(Hrtf.delays[lidx[2]], Hrtf.delays[lidx[3]], mu[1]),
delays[0] = (ALuint)(lerp(lerp(Hrtf->delays[lidx[0]], Hrtf->delays[lidx[1]], mu[0]),
lerp(Hrtf->delays[lidx[2]], Hrtf->delays[lidx[3]], mu[1]),
mu[2]) * 65536.0f);
delays[1] = (ALuint)(lerp(lerp(Hrtf.delays[ridx[0]], Hrtf.delays[ridx[1]], mu[0]),
lerp(Hrtf.delays[ridx[2]], Hrtf.delays[ridx[3]], mu[1]),
delays[1] = (ALuint)(lerp(lerp(Hrtf->delays[ridx[0]], Hrtf->delays[ridx[1]], mu[0]),
lerp(Hrtf->delays[ridx[2]], Hrtf->delays[ridx[3]], mu[1]),
mu[2]) * 65536.0f);
delayStep[0] = (ALint)(step * (delays[0] - left));
@@ -287,13 +287,13 @@ ALuint GetMovingHrtfCoeffs(ALfloat elevation, ALfloat azimuth, ALfloat gain, ALf
return (ALuint)delta;
}
ALCboolean IsHrtfCompatible(ALCdevice *device)
const struct Hrtf *GetHrtf(ALCdevice *device)
{
if(device->FmtChans == DevFmtStereo && device->Frequency == Hrtf.sampleRate)
return ALC_TRUE;
if(device->FmtChans == DevFmtStereo && device->Frequency == LoadedHrtf.sampleRate)
return &LoadedHrtf;
ERR("Incompatible format: %s %uhz\n",
DevFmtChannelsString(device->FmtChans), device->Frequency);
return ALC_FALSE;
return NULL;
}
void InitHrtf(void)
@@ -404,10 +404,10 @@ void InitHrtf(void)
f = NULL;
if(!failed)
Hrtf = newdata;
LoadedHrtf = newdata;
else
ERR("Failed to load %s\n", fname);
}
TRACE("HRTF support for format: %s %uhz\n",
DevFmtChannelsString(DevFmtStereo), Hrtf.sampleRate);
DevFmtChannelsString(DevFmtStereo), LoadedHrtf.sampleRate);
}
+9 -3
View File
@@ -384,6 +384,9 @@ extern "C" {
#define LOWPASSFREQCUTOFF (5000)
struct Hrtf;
// Find the next power-of-2 for non-power-of-2 numbers.
static __inline ALuint NextPowerOf2(ALuint value)
{
@@ -549,6 +552,9 @@ struct ALCdevice_struct
// Map of Filters for this device
UIntMap FilterMap;
/* HRTF filter tables */
const struct Hrtf *Hrtf;
// Stereo-to-binaural filter
struct bs2b *Bs2b;
ALCint Bs2bLevel;
@@ -679,10 +685,10 @@ const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans);
#define HRIR_LENGTH (1<<HRIR_BITS)
#define HRIR_MASK (HRIR_LENGTH-1)
void InitHrtf(void);
ALCboolean IsHrtfCompatible(ALCdevice *device);
const struct Hrtf *GetHrtf(ALCdevice *device);
ALfloat CalcHrtfDelta(ALfloat oldGain, ALfloat newGain, const ALfloat olddir[3], const ALfloat newdir[3]);
void GetLerpedHrtfCoeffs(ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays);
ALuint GetMovingHrtfCoeffs(ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat delta, ALint counter, ALfloat (*coeffs)[2], ALuint *delays, ALfloat (*coeffStep)[2], ALint *delayStep);
void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays);
ALuint GetMovingHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat delta, ALint counter, ALfloat (*coeffs)[2], ALuint *delays, ALfloat (*coeffStep)[2], ALint *delayStep);
void al_print(const char *func, const char *fmt, ...) PRINTF_STYLE(2,3);
#define AL_PRINT(...) al_print(__FUNCTION__, __VA_ARGS__)