From 25f7c2704382221c9d563a7c1e57c02252eb3dad Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 18 Sep 2011 09:52:40 -0700 Subject: [PATCH] Store the HRTF tables used in the device --- Alc/ALc.c | 4 +++- Alc/ALu.c | 10 +++++---- Alc/hrtf.c | 52 +++++++++++++++++++++++------------------------ OpenAL32/Include/alMain.h | 12 ++++++++--- 4 files changed, 44 insertions(+), 34 deletions(-) diff --git a/Alc/ALc.c b/Alc/ALc.c index dde5ce4c..d53829ea 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -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"); diff --git a/Alc/ALu.c b/Alc/ALu.c index 2b5a6e75..07dc3580 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -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; diff --git a/Alc/hrtf.c b/Alc/hrtf.c index 7fa051da..3d780c93 100644 --- a/Alc/hrtf.c +++ b/Alc/hrtf.c @@ -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); } diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 40b90383..a5a96e81 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -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<