Store the HRTF tables used in the device
This commit is contained in:
@@ -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");
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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__)
|
||||
|
||||
Reference in New Issue
Block a user