diff options
-rw-r--r-- | Alc/ALu.c | 93 | ||||
-rw-r--r-- | Alc/hrtf.c | 134 | ||||
-rw-r--r-- | Alc/hrtf.h | 1 | ||||
-rw-r--r-- | Alc/mixer.c | 40 | ||||
-rw-r--r-- | Alc/mixer_c.c | 12 | ||||
-rw-r--r-- | Alc/mixer_defs.h | 8 | ||||
-rw-r--r-- | Alc/mixer_inc.c | 58 | ||||
-rw-r--r-- | Alc/mixer_neon.c | 19 | ||||
-rw-r--r-- | Alc/mixer_sse.c | 17 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 2 | ||||
-rw-r--r-- | OpenAL32/Include/alu.h | 18 | ||||
-rw-r--r-- | OpenAL32/alSource.c | 1 |
12 files changed, 99 insertions, 304 deletions
@@ -287,42 +287,6 @@ static ALboolean BsincPrepare(const ALuint increment, BsincState *state) } -/* Calculates the fade time from the changes in gain and listener to source - * angle between updates. The result is a the time, in seconds, for the - * transition to complete. - */ -static ALfloat CalcFadeTime(ALfloat oldGain, ALfloat newGain, const aluVector *olddir, const aluVector *newdir) -{ - ALfloat gainChange, angleChange, change; - - /* Calculate the normalized dB gain change. */ - newGain = maxf(newGain, 0.0001f); - oldGain = maxf(oldGain, 0.0001f); - gainChange = fabsf(log10f(newGain / oldGain) / log10f(0.0001f)); - - /* Calculate the angle change only when there is enough gain to notice it. */ - angleChange = 0.0f; - if(gainChange > 0.0001f || newGain > 0.0001f) - { - /* No angle change when the directions are equal or degenerate (when - * both have zero length). - */ - if(newdir->v[0] != olddir->v[0] || newdir->v[1] != olddir->v[1] || newdir->v[2] != olddir->v[2]) - { - ALfloat dotp = aluDotproduct(olddir, newdir); - angleChange = acosf(clampf(dotp, -1.0f, 1.0f)) / F_PI; - } - } - - /* Use the largest of the two changes, and apply a significance shaping - * function to it. The result is then scaled to cover a 15ms transition - * range. - */ - change = maxf(angleChange * 25.0f, gainChange) * 2.0f; - return minf(change, 1.0f) * 0.015f; -} - - static ALvoid CalcListenerParams(ALlistener *Listener) { ALdouble N[3], V[3], U[3], P[3]; @@ -684,12 +648,12 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A if(chans[c].channel == LFE) { /* Skip LFE */ - voice->Direct.Hrtf[c].Params.Delay[0] = 0; - voice->Direct.Hrtf[c].Params.Delay[1] = 0; + voice->Direct.Hrtf[c].Target.Delay[0] = 0; + voice->Direct.Hrtf[c].Target.Delay[1] = 0; for(i = 0;i < HRIR_LENGTH;i++) { - voice->Direct.Hrtf[c].Params.Coeffs[i][0] = 0.0f; - voice->Direct.Hrtf[c].Params.Coeffs[i][1] = 0.0f; + voice->Direct.Hrtf[c].Target.Coeffs[i][0] = 0.0f; + voice->Direct.Hrtf[c].Target.Coeffs[i][1] = 0.0f; } for(i = 0;i < NumSends;i++) @@ -704,8 +668,8 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A /* Get the static HRIR coefficients and delays for this channel. */ GetLerpedHrtfCoeffs(Device->Hrtf, chans[c].elevation, chans[c].angle, 1.0f, DryGain, - voice->Direct.Hrtf[c].Params.Coeffs, - voice->Direct.Hrtf[c].Params.Delay + voice->Direct.Hrtf[c].Target.Coeffs, + voice->Direct.Hrtf[c].Target.Delay ); /* Normal panning for auxiliary sends. */ @@ -726,7 +690,6 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A } } } - voice->Direct.HrtfCounter = 0; voice->IsHrtf = AL_TRUE; } @@ -1186,37 +1149,10 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte dirfact *= 1.0f - (asinf(radius / Distance) / F_PI); } - /* Check to see if the HRIR is already moving. */ - if(voice->Moving) - { - ALfloat delta; - delta = CalcFadeTime(voice->Direct.LastGain, DryGain, - &voice->Direct.LastDir, &dir); - /* If the delta is large enough, get the moving HRIR target - * coefficients, target delays, steppping values, and counter. - */ - if(delta > 0.000015f) - { - ALuint counter = GetMovingHrtfCoeffs(Device->Hrtf, - ev, az, dirfact, DryGain, delta, voice->Direct.HrtfCounter, - voice->Direct.Hrtf[0].Params.Coeffs, voice->Direct.Hrtf[0].Params.Delay, - voice->Direct.Hrtf[0].Params.CoeffStep, voice->Direct.Hrtf[0].Params.DelayStep - ); - voice->Direct.HrtfCounter = counter; - voice->Direct.LastGain = DryGain; - voice->Direct.LastDir = dir; - } - } - else - { - /* Get the initial (static) HRIR coefficients and delays. */ - GetLerpedHrtfCoeffs(Device->Hrtf, ev, az, dirfact, DryGain, - voice->Direct.Hrtf[0].Params.Coeffs, - voice->Direct.Hrtf[0].Params.Delay); - voice->Direct.HrtfCounter = 0; - voice->Direct.LastGain = DryGain; - voice->Direct.LastDir = dir; - } + /* Get the HRIR coefficients and delays. */ + GetLerpedHrtfCoeffs(Device->Hrtf, ev, az, dirfact, DryGain, + voice->Direct.Hrtf[0].Target.Coeffs, + voice->Direct.Hrtf[0].Target.Delay); dir.v[0] *= dirfact; dir.v[1] *= dirfact; @@ -1537,11 +1473,16 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) { HrtfMixerFunc HrtfMix = SelectHrtfMixer(); ALuint irsize = GetHrtfIrSize(device->Hrtf); + MixHrtfParams hrtfparams; + memset(&hrtfparams, 0, sizeof(hrtfparams)); for(c = 0;c < device->NumChannels;c++) + { + hrtfparams.Current = &device->Hrtf_Params[c]; + hrtfparams.Target = &device->Hrtf_Params[c]; HrtfMix(OutBuffer, device->DryBuffer[c], 0, device->Hrtf_Offset, - 0, irsize, &device->Hrtf_Params[c], &device->Hrtf_State[c], - SamplesToDo + 0, irsize, &hrtfparams, &device->Hrtf_State[c], SamplesToDo ); + } device->Hrtf_Offset += SamplesToDo; } else if(device->Bs2b) @@ -181,140 +181,6 @@ void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azi } } -/* Calculates the moving HRIR target coefficients, target delays, and - * stepping values for the given polar elevation and azimuth in radians. - * Linear interpolation is used to increase the apparent resolution of the - * HRIR data set. 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(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat dirfact, ALfloat gain, ALfloat delta, ALint counter, ALfloat (*coeffs)[2], ALuint *delays, ALfloat (*coeffStep)[2], ALint *delayStep) -{ - ALuint evidx[2], lidx[4], ridx[4]; - ALfloat mu[3], blend[4]; - ALfloat left, right; - ALfloat steps; - ALuint i; - - /* Claculate elevation indices and interpolation factor. */ - CalcEvIndices(Hrtf->evCount, elevation, evidx, &mu[2]); - - for(i = 0;i < 2;i++) - { - ALuint azcount = Hrtf->azCount[evidx[i]]; - ALuint evoffset = Hrtf->evOffset[evidx[i]]; - ALuint azidx[2]; - - /* Calculate azimuth indices and interpolation factor for this elevation. */ - CalcAzIndices(azcount, azimuth, azidx, &mu[i]); - - /* Calculate a set of linear HRIR indices for left and right channels. */ - lidx[i*2 + 0] = evoffset + azidx[0]; - lidx[i*2 + 1] = evoffset + azidx[1]; - ridx[i*2 + 0] = evoffset + ((azcount-azidx[0]) % azcount); - ridx[i*2 + 1] = evoffset + ((azcount-azidx[1]) % azcount); - } - - // Calculate the stepping parameters. - steps = maxf(floorf(delta*Hrtf->sampleRate + 0.5f), 1.0f); - delta = 1.0f / steps; - - /* Calculate 4 blending weights for 2D bilinear interpolation. */ - blend[0] = (1.0f-mu[0]) * (1.0f-mu[2]); - blend[1] = ( mu[0]) * (1.0f-mu[2]); - blend[2] = (1.0f-mu[1]) * ( mu[2]); - blend[3] = ( mu[1]) * ( mu[2]); - - /* Calculate the HRIR delays using linear interpolation. Then calculate - * the delay stepping values using the target and previous running - * delays. - */ - left = (ALfloat)(delays[0] - (delayStep[0] * counter)); - right = (ALfloat)(delays[1] - (delayStep[1] * counter)); - - delays[0] = fastf2u((Hrtf->delays[lidx[0]]*blend[0] + Hrtf->delays[lidx[1]]*blend[1] + - Hrtf->delays[lidx[2]]*blend[2] + Hrtf->delays[lidx[3]]*blend[3]) * - dirfact + 0.5f) << HRTFDELAY_BITS; - delays[1] = fastf2u((Hrtf->delays[ridx[0]]*blend[0] + Hrtf->delays[ridx[1]]*blend[1] + - Hrtf->delays[ridx[2]]*blend[2] + Hrtf->delays[ridx[3]]*blend[3]) * - dirfact + 0.5f) << HRTFDELAY_BITS; - - delayStep[0] = fastf2i(delta * (delays[0] - left)); - delayStep[1] = fastf2i(delta * (delays[1] - right)); - - /* Calculate the sample offsets for the HRIR indices. */ - lidx[0] *= Hrtf->irSize; - lidx[1] *= Hrtf->irSize; - lidx[2] *= Hrtf->irSize; - lidx[3] *= Hrtf->irSize; - ridx[0] *= Hrtf->irSize; - ridx[1] *= Hrtf->irSize; - ridx[2] *= Hrtf->irSize; - ridx[3] *= Hrtf->irSize; - - /* Calculate the normalized and attenuated target HRIR coefficients using - * linear interpolation when there is enough gain to warrant it. Zero - * the target coefficients if gain is too low. Then calculate the - * coefficient stepping values using the target and previous running - * coefficients. - */ - if(gain > 0.0001f) - { - ALfloat c; - - i = 0; - left = coeffs[i][0] - (coeffStep[i][0] * counter); - right = coeffs[i][1] - (coeffStep[i][1] * counter); - - c = (Hrtf->coeffs[lidx[0]+i]*blend[0] + Hrtf->coeffs[lidx[1]+i]*blend[1] + - Hrtf->coeffs[lidx[2]+i]*blend[2] + Hrtf->coeffs[lidx[3]+i]*blend[3]); - coeffs[i][0] = lerp(PassthruCoeff, c, dirfact) * gain * (1.0f/32767.0f); - c = (Hrtf->coeffs[ridx[0]+i]*blend[0] + Hrtf->coeffs[ridx[1]+i]*blend[1] + - Hrtf->coeffs[ridx[2]+i]*blend[2] + Hrtf->coeffs[ridx[3]+i]*blend[3]); - coeffs[i][1] = lerp(PassthruCoeff, c, dirfact) * gain * (1.0f/32767.0f); - - coeffStep[i][0] = delta * (coeffs[i][0] - left); - coeffStep[i][1] = delta * (coeffs[i][1] - right); - - for(i = 1;i < Hrtf->irSize;i++) - { - left = coeffs[i][0] - (coeffStep[i][0] * counter); - right = coeffs[i][1] - (coeffStep[i][1] * counter); - - c = (Hrtf->coeffs[lidx[0]+i]*blend[0] + Hrtf->coeffs[lidx[1]+i]*blend[1] + - Hrtf->coeffs[lidx[2]+i]*blend[2] + Hrtf->coeffs[lidx[3]+i]*blend[3]); - coeffs[i][0] = lerp(0.0f, c, dirfact) * gain * (1.0f/32767.0f); - c = (Hrtf->coeffs[ridx[0]+i]*blend[0] + Hrtf->coeffs[ridx[1]+i]*blend[1] + - Hrtf->coeffs[ridx[2]+i]*blend[2] + Hrtf->coeffs[ridx[3]+i]*blend[3]); - coeffs[i][1] = lerp(0.0f, c, dirfact) * gain * (1.0f/32767.0f); - - coeffStep[i][0] = delta * (coeffs[i][0] - left); - coeffStep[i][1] = delta * (coeffs[i][1] - right); - } - } - else - { - for(i = 0;i < Hrtf->irSize;i++) - { - left = coeffs[i][0] - (coeffStep[i][0] * counter); - right = coeffs[i][1] - (coeffStep[i][1] * counter); - - coeffs[i][0] = 0.0f; - coeffs[i][1] = 0.0f; - - coeffStep[i][0] = delta * -left; - coeffStep[i][1] = delta * -right; - } - } - - /* The stepping count is the number of samples necessary for the HRIR to - * complete its transition. The mixer will only apply stepping for this - * many samples. - */ - return fastf2u(steps); -} - - /* Calculates HRTF coefficients for B-Format channels (only up to first-order). * Note that these will decode a B-Format output mix, which uses FuMa ordering * and scaling, not N3D! @@ -34,7 +34,6 @@ ALuint GetHrtfSampleRate(const struct Hrtf *Hrtf); ALuint GetHrtfIrSize(const struct Hrtf *Hrtf); void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat dirfact, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays); -ALuint GetMovingHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat dirfact, ALfloat gain, ALfloat delta, ALint counter, ALfloat (*coeffs)[2], ALuint *delays, ALfloat (*coeffStep)[2], ALint *delayStep); void GetBFormatHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat (*coeffs_list[4])[2], ALuint *delay_list[4]); #endif /* ALC_HRTF_H */ diff --git a/Alc/mixer.c b/Alc/mixer.c index 4688c89e..6b5272ea 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -601,9 +601,42 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam currents[j] = gains[j].Current; } else - MixHrtfSamples(parms->OutBuffer, samples, parms->HrtfCounter, voice->Offset, - OutPos, IrSize, &parms->Hrtf[chan].Params, - &parms->Hrtf[chan].State, DstBufferSize); + { + MixHrtfParams hrtfparams; + if(!Counter) + { + parms->Hrtf[chan].Current = parms->Hrtf[chan].Target; + for(j = 0;j < HRIR_LENGTH;j++) + { + hrtfparams.Steps.Coeffs[j][0] = 0.0f; + hrtfparams.Steps.Coeffs[j][1] = 0.0f; + } + hrtfparams.Steps.Delay[0] = 0; + hrtfparams.Steps.Delay[1] = 0; + } + else + { + ALfloat coeffdiff; + ALint delaydiff; + for(j = 0;j < HRIR_LENGTH;j++) + { + coeffdiff = parms->Hrtf[chan].Target.Coeffs[j][0] - parms->Hrtf[chan].Current.Coeffs[j][0]; + hrtfparams.Steps.Coeffs[j][0] = coeffdiff * Delta; + coeffdiff = parms->Hrtf[chan].Target.Coeffs[j][1] - parms->Hrtf[chan].Current.Coeffs[j][1]; + hrtfparams.Steps.Coeffs[j][1] = coeffdiff * Delta; + } + delaydiff = (ALint)(parms->Hrtf[chan].Target.Delay[0] - parms->Hrtf[chan].Current.Delay[0]); + hrtfparams.Steps.Delay[0] = fastf2i((ALfloat)delaydiff * Delta); + delaydiff = (ALint)(parms->Hrtf[chan].Target.Delay[1] - parms->Hrtf[chan].Current.Delay[1]); + hrtfparams.Steps.Delay[1] = fastf2i((ALfloat)delaydiff * Delta); + } + hrtfparams.Target = &parms->Hrtf[chan].Target; + hrtfparams.Current = &parms->Hrtf[chan].Current; + + MixHrtfSamples(parms->OutBuffer, samples, Counter, voice->Offset, + OutPos, IrSize, &hrtfparams, &parms->Hrtf[chan].State, + DstBufferSize); + } } for(j = 0;j < Device->NumAuxSends;j++) @@ -664,7 +697,6 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam OutPos += DstBufferSize; voice->Offset += DstBufferSize; - voice->Direct.HrtfCounter = maxu(voice->Direct.HrtfCounter, DstBufferSize) - DstBufferSize; /* Handle looping sources */ while(1) diff --git a/Alc/mixer_c.c b/Alc/mixer_c.c index ef37b730..e9d26140 100644 --- a/Alc/mixer_c.c +++ b/Alc/mixer_c.c @@ -101,18 +101,6 @@ void ALfilterState_processC(ALfilterState *filter, ALfloat *restrict dst, const } -static inline void SetupCoeffs(ALfloat (*restrict OutCoeffs)[2], - const HrtfParams *hrtfparams, - ALuint IrSize, ALuint Counter) -{ - ALuint c; - for(c = 0;c < IrSize;c++) - { - OutCoeffs[c][0] = hrtfparams->Coeffs[c][0] - (hrtfparams->CoeffStep[c][0]*Counter); - OutCoeffs[c][1] = hrtfparams->Coeffs[c][1] - (hrtfparams->CoeffStep[c][1]*Counter); - } -} - static inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*restrict Values)[2], const ALuint IrSize, ALfloat (*restrict Coeffs)[2], diff --git a/Alc/mixer_defs.h b/Alc/mixer_defs.h index 3c32278b..3fecab87 100644 --- a/Alc/mixer_defs.h +++ b/Alc/mixer_defs.h @@ -8,7 +8,7 @@ struct MixGains; -struct HrtfParams; +struct MixHrtfParams; struct HrtfState; /* C resamplers */ @@ -23,7 +23,7 @@ const ALfloat *Resample_bsinc32_C(const BsincState *state, const ALfloat *src, A /* C mixers */ void MixHrtf_C(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, ALuint Counter, ALuint Offset, ALuint OutPos, const ALuint IrSize, - const struct HrtfParams *hrtfparams, struct HrtfState *hrtfstate, + const struct MixHrtfParams *hrtfparams, struct HrtfState *hrtfstate, ALuint BufferSize); void Mix_C(const ALfloat *data, ALuint OutChans, ALfloat (*restrict OutBuffer)[BUFFERSIZE], struct MixGains *Gains, ALuint Counter, ALuint OutPos, ALuint BufferSize); @@ -31,7 +31,7 @@ void Mix_C(const ALfloat *data, ALuint OutChans, ALfloat (*restrict OutBuffer)[B /* SSE mixers */ void MixHrtf_SSE(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, ALuint Counter, ALuint Offset, ALuint OutPos, const ALuint IrSize, - const struct HrtfParams *hrtfparams, struct HrtfState *hrtfstate, + const struct MixHrtfParams *hrtfparams, struct HrtfState *hrtfstate, ALuint BufferSize); void Mix_SSE(const ALfloat *data, ALuint OutChans, ALfloat (*restrict OutBuffer)[BUFFERSIZE], struct MixGains *Gains, ALuint Counter, ALuint OutPos, ALuint BufferSize); @@ -72,7 +72,7 @@ const ALfloat *Resample_fir8_32_SSE41(const BsincState *state, const ALfloat *sr /* Neon mixers */ void MixHrtf_Neon(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, ALuint Counter, ALuint Offset, ALuint OutPos, const ALuint IrSize, - const struct HrtfParams *hrtfparams, struct HrtfState *hrtfstate, + const struct MixHrtfParams *hrtfparams, struct HrtfState *hrtfstate, ALuint BufferSize); void Mix_Neon(const ALfloat *data, ALuint OutChans, ALfloat (*restrict OutBuffer)[BUFFERSIZE], struct MixGains *Gains, ALuint Counter, ALuint OutPos, ALuint BufferSize); diff --git a/Alc/mixer_inc.c b/Alc/mixer_inc.c index a82930cc..d69becc9 100644 --- a/Alc/mixer_inc.c +++ b/Alc/mixer_inc.c @@ -6,11 +6,9 @@ #include "hrtf.h" #include "mixer_defs.h" #include "align.h" +#include "alu.h" -static inline void SetupCoeffs(ALfloat (*restrict OutCoeffs)[2], - const HrtfParams *hrtfparams, - ALuint IrSize, ALuint Counter); static inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*restrict Values)[2], const ALuint irSize, ALfloat (*restrict Coeffs)[2], @@ -24,39 +22,45 @@ static inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2], void MixHrtf(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, ALuint Counter, ALuint Offset, ALuint OutPos, const ALuint IrSize, - const HrtfParams *hrtfparams, HrtfState *hrtfstate, ALuint BufferSize) + const MixHrtfParams *hrtfparams, HrtfState *hrtfstate, ALuint BufferSize) { - alignas(16) ALfloat Coeffs[HRIR_LENGTH][2]; - ALuint Delay[2]; + ALfloat (*Coeffs)[2] = hrtfparams->Current->Coeffs; + ALuint Delay[2] = { hrtfparams->Current->Delay[0], hrtfparams->Current->Delay[1] }; ALfloat left, right; ALuint pos; - SetupCoeffs(Coeffs, hrtfparams, IrSize, Counter); - Delay[0] = hrtfparams->Delay[0] - (hrtfparams->DelayStep[0]*Counter); - Delay[1] = hrtfparams->Delay[1] - (hrtfparams->DelayStep[1]*Counter); - pos = 0; - for(;pos < BufferSize && pos < Counter;pos++) + if(pos < Counter) { - hrtfstate->History[Offset&HRTF_HISTORY_MASK] = data[pos]; - left = lerp(hrtfstate->History[(Offset-(Delay[0]>>HRTFDELAY_BITS))&HRTF_HISTORY_MASK], - hrtfstate->History[(Offset-(Delay[0]>>HRTFDELAY_BITS)-1)&HRTF_HISTORY_MASK], - (Delay[0]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE)); - right = lerp(hrtfstate->History[(Offset-(Delay[1]>>HRTFDELAY_BITS))&HRTF_HISTORY_MASK], - hrtfstate->History[(Offset-(Delay[1]>>HRTFDELAY_BITS)-1)&HRTF_HISTORY_MASK], - (Delay[1]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE)); + for(;pos < BufferSize && pos < Counter;pos++) + { + hrtfstate->History[Offset&HRTF_HISTORY_MASK] = data[pos]; + left = lerp(hrtfstate->History[(Offset-(Delay[0]>>HRTFDELAY_BITS))&HRTF_HISTORY_MASK], + hrtfstate->History[(Offset-(Delay[0]>>HRTFDELAY_BITS)-1)&HRTF_HISTORY_MASK], + (Delay[0]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE)); + right = lerp(hrtfstate->History[(Offset-(Delay[1]>>HRTFDELAY_BITS))&HRTF_HISTORY_MASK], + hrtfstate->History[(Offset-(Delay[1]>>HRTFDELAY_BITS)-1)&HRTF_HISTORY_MASK], + (Delay[1]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE)); - Delay[0] += hrtfparams->DelayStep[0]; - Delay[1] += hrtfparams->DelayStep[1]; + Delay[0] += hrtfparams->Steps.Delay[0]; + Delay[1] += hrtfparams->Steps.Delay[1]; - hrtfstate->Values[(Offset+IrSize)&HRIR_MASK][0] = 0.0f; - hrtfstate->Values[(Offset+IrSize)&HRIR_MASK][1] = 0.0f; - Offset++; + hrtfstate->Values[(Offset+IrSize)&HRIR_MASK][0] = 0.0f; + hrtfstate->Values[(Offset+IrSize)&HRIR_MASK][1] = 0.0f; + Offset++; - ApplyCoeffsStep(Offset, hrtfstate->Values, IrSize, Coeffs, hrtfparams->CoeffStep, left, right); - OutBuffer[0][OutPos] += hrtfstate->Values[Offset&HRIR_MASK][0]; - OutBuffer[1][OutPos] += hrtfstate->Values[Offset&HRIR_MASK][1]; - OutPos++; + ApplyCoeffsStep(Offset, hrtfstate->Values, IrSize, Coeffs, hrtfparams->Steps.Coeffs, left, right); + OutBuffer[0][OutPos] += hrtfstate->Values[Offset&HRIR_MASK][0]; + OutBuffer[1][OutPos] += hrtfstate->Values[Offset&HRIR_MASK][1]; + OutPos++; + } + + if(pos == Counter) + { + *hrtfparams->Current = *hrtfparams->Target; + Delay[0] = hrtfparams->Target->Delay[0]; + Delay[1] = hrtfparams->Target->Delay[1]; + } } Delay[0] >>= HRTFDELAY_BITS; diff --git a/Alc/mixer_neon.c b/Alc/mixer_neon.c index a89caeae..96936ef5 100644 --- a/Alc/mixer_neon.c +++ b/Alc/mixer_neon.c @@ -9,25 +9,6 @@ #include "hrtf.h" -static inline void SetupCoeffs(ALfloat (*restrict OutCoeffs)[2], - const HrtfParams *hrtfparams, - ALuint IrSize, ALuint Counter) -{ - ALuint c; - float32x4_t counter4; - { - float32x2_t counter2 = vdup_n_f32(-(float)Counter); - counter4 = vcombine_f32(counter2, counter2); - } - for(c = 0;c < IrSize;c += 2) - { - float32x4_t step4 = vld1q_f32((float32_t*)hrtfparams->CoeffStep[c]); - float32x4_t coeffs = vld1q_f32((float32_t*)hrtfparams->Coeffs[c]); - coeffs = vmlaq_f32(coeffs, step4, counter4); - vst1q_f32((float32_t*)OutCoeffs[c], coeffs); - } -} - static inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*restrict Values)[2], const ALuint IrSize, ALfloat (*restrict Coeffs)[2], diff --git a/Alc/mixer_sse.c b/Alc/mixer_sse.c index 090b7a5a..942e0453 100644 --- a/Alc/mixer_sse.c +++ b/Alc/mixer_sse.c @@ -71,23 +71,6 @@ const ALfloat *Resample_bsinc32_SSE(const BsincState *state, const ALfloat *src, } -static inline void SetupCoeffs(ALfloat (*restrict OutCoeffs)[2], - const HrtfParams *hrtfparams, - ALuint IrSize, ALuint Counter) -{ - const __m128 counter4 = _mm_set1_ps((float)Counter); - __m128 coeffs, step4; - ALuint i; - - for(i = 0;i < IrSize;i += 2) - { - step4 = _mm_load_ps(&hrtfparams->CoeffStep[i][0]); - coeffs = _mm_load_ps(&hrtfparams->Coeffs[i][0]); - coeffs = _mm_sub_ps(coeffs, _mm_mul_ps(step4, counter4)); - _mm_store_ps(&OutCoeffs[i][0], coeffs); - } -} - static inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*restrict Values)[2], const ALuint IrSize, ALfloat (*restrict Coeffs)[2], diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 8f1fd956..89936f85 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -404,9 +404,7 @@ typedef struct HrtfState { typedef struct HrtfParams { alignas(16) ALfloat Coeffs[HRIR_LENGTH][2]; - alignas(16) ALfloat CoeffStep[HRIR_LENGTH][2]; ALuint Delay[2]; - ALint DelayStep[2]; } HrtfParams; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 50ef1f5e..af2ea857 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -138,16 +138,19 @@ typedef struct MixGains { ALfloat Target; } MixGains; +typedef struct MixHrtfParams { + const HrtfParams *Target; + HrtfParams *Current; + struct { + alignas(16) ALfloat Coeffs[HRIR_LENGTH][2]; + ALint Delay[2]; + } Steps; +} MixHrtfParams; typedef struct DirectParams { ALfloat (*OutBuffer)[BUFFERSIZE]; ALuint OutChannels; - /* Last direction (relative to listener) and gain of a moving source. */ - aluVector LastDir; - ALfloat LastGain; - ALuint HrtfCounter; - struct { enum ActiveFilters ActiveType; ALfilterState LowPass; @@ -155,7 +158,8 @@ typedef struct DirectParams { } Filters[MAX_INPUT_CHANNELS]; struct { - HrtfParams Params; + HrtfParams Current; + HrtfParams Target; HrtfState State; } Hrtf[MAX_INPUT_CHANNELS]; @@ -191,7 +195,7 @@ typedef void (*MixerFunc)(const ALfloat *data, ALuint OutChans, ALuint Counter, ALuint OutPos, ALuint BufferSize); typedef void (*HrtfMixerFunc)(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, ALuint Counter, ALuint Offset, ALuint OutPos, - const ALuint IrSize, const HrtfParams *hrtfparams, + const ALuint IrSize, const MixHrtfParams *hrtfparams, HrtfState *hrtfstate, ALuint BufferSize); diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index f742e1fe..250c9d1e 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -2641,7 +2641,6 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) memset(voice->PrevSamples, 0, sizeof(voice->PrevSamples)); voice->Moving = AL_FALSE; - voice->Direct.HrtfCounter = 0; for(i = 0;i < MAX_INPUT_CHANNELS;i++) { ALsizei j; |