aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2017-05-03 03:29:21 -0700
committerChris Robinson <[email protected]>2017-05-03 03:29:21 -0700
commit444e9563b357b4e2af0d428afac9f87596aba9a6 (patch)
tree1fc1f56f2a748332ad21b482895ea1fff3f7f9f7
parent4e5c4b8e01060bb34c58480895e70a0529d8a55e (diff)
Add a mixing function to blend HRIRs
This is a bit more efficient than calling the normal HRTF mixing function twice, and helps solve the problem of the values generated from convolution not being consistent with the new HRIR.
-rw-r--r--Alc/mixer.c40
-rw-r--r--Alc/mixer_c.c1
-rw-r--r--Alc/mixer_defs.h15
-rw-r--r--Alc/mixer_inc.c59
-rw-r--r--Alc/mixer_neon.c1
-rw-r--r--Alc/mixer_sse.c1
-rw-r--r--OpenAL32/Include/alu.h5
7 files changed, 95 insertions, 27 deletions
diff --git a/Alc/mixer.c b/Alc/mixer.c
index a7adf9b6..6eaf4caf 100644
--- a/Alc/mixer.c
+++ b/Alc/mixer.c
@@ -53,6 +53,7 @@ enum Resampler ResamplerDefault = LinearResampler;
static MixerFunc MixSamples = Mix_C;
static HrtfMixerFunc MixHrtfSamples = MixHrtf_C;
+HrtfMixerBlendFunc MixHrtfBlendSamples = MixHrtfBlend_C;
MixerFunc SelectMixer(void)
{
@@ -90,10 +91,22 @@ static inline HrtfMixerFunc SelectHrtfMixer(void)
if((CPUCapFlags&CPU_CAP_SSE))
return MixHrtf_SSE;
#endif
-
return MixHrtf_C;
}
+static inline HrtfMixerBlendFunc SelectHrtfBlendMixer(void)
+{
+#ifdef HAVE_NEON
+ if((CPUCapFlags&CPU_CAP_NEON))
+ return MixHrtfBlend_Neon;
+#endif
+#ifdef HAVE_SSE
+ if((CPUCapFlags&CPU_CAP_SSE))
+ return MixHrtfBlend_SSE;
+#endif
+ return MixHrtfBlend_C;
+}
+
ResamplerFunc SelectResampler(enum Resampler resampler)
{
switch(resampler)
@@ -174,6 +187,7 @@ void aluInitMixer(void)
}
}
+ MixHrtfBlendSamples = SelectHrtfBlendMixer();
MixHrtfSamples = SelectHrtfMixer();
MixSamples = SelectMixer();
}
@@ -511,25 +525,10 @@ ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei
}
else if(firstpass)
{
- HrtfState backupstate = parms->Hrtf.State;
ALfloat gain;
/* Fade between the coefficients over 64 samples. */
- fademix = mini(DstBufferSize, 64);
-
- /* The old coefficients need to fade to silence
- * completely since they'll be replaced after this mix.
- */
- hrtfparams.Coeffs = SAFE_CONST(ALfloat2*,parms->Hrtf.Old.Coeffs);
- hrtfparams.Delay[0] = parms->Hrtf.Old.Delay[0];
- hrtfparams.Delay[1] = parms->Hrtf.Old.Delay[1];
- hrtfparams.Gain = parms->Hrtf.Old.Gain;
- hrtfparams.GainStep = -hrtfparams.Gain / (ALfloat)fademix;
- MixHrtfSamples(
- voice->Direct.Buffer[lidx], voice->Direct.Buffer[ridx],
- samples, voice->Offset, OutPos, IrSize, &hrtfparams,
- &backupstate, fademix
- );
+ fademix = mini(DstBufferSize, 64);
/* The new coefficients need to fade in completely
* since they're replacing the old ones. To keep the
@@ -544,10 +543,11 @@ ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei
hrtfparams.Delay[1] = parms->Hrtf.Target.Delay[1];
hrtfparams.Gain = 0.0f;
hrtfparams.GainStep = gain / (ALfloat)fademix;
- MixHrtfSamples(
+
+ MixHrtfBlendSamples(
voice->Direct.Buffer[lidx], voice->Direct.Buffer[ridx],
- samples, voice->Offset, OutPos, IrSize, &hrtfparams,
- &parms->Hrtf.State, fademix
+ samples, voice->Offset, OutPos, IrSize, &parms->Hrtf.Old,
+ &hrtfparams, &parms->Hrtf.State, fademix
);
/* Update the old parameters with the result. */
parms->Hrtf.Old = parms->Hrtf.Target;
diff --git a/Alc/mixer_c.c b/Alc/mixer_c.c
index f0db2ebc..87f2fe90 100644
--- a/Alc/mixer_c.c
+++ b/Alc/mixer_c.c
@@ -146,6 +146,7 @@ static inline void ApplyCoeffs(ALsizei Offset, ALfloat (*restrict Values)[2],
}
#define MixHrtf MixHrtf_C
+#define MixHrtfBlend MixHrtfBlend_C
#define MixDirectHrtf MixDirectHrtf_C
#include "mixer_inc.c"
#undef MixHrtf
diff --git a/Alc/mixer_defs.h b/Alc/mixer_defs.h
index dce748c5..462d6179 100644
--- a/Alc/mixer_defs.h
+++ b/Alc/mixer_defs.h
@@ -24,6 +24,11 @@ void MixHrtf_C(ALfloat *restrict LeftOut, ALfloat *restrict RightOut,
const ALfloat *data, ALsizei Offset, ALsizei OutPos,
const ALsizei IrSize, struct MixHrtfParams *hrtfparams,
struct HrtfState *hrtfstate, ALsizei BufferSize);
+void MixHrtfBlend_C(ALfloat *restrict LeftOut, ALfloat *restrict RightOut,
+ const ALfloat *data, ALsizei Offset, ALsizei OutPos,
+ const ALsizei IrSize, const HrtfParams *oldparams,
+ MixHrtfParams *newparams, HrtfState *hrtfstate,
+ ALsizei BufferSize);
void MixDirectHrtf_C(ALfloat *restrict LeftOut, ALfloat *restrict RightOut,
const ALfloat *data, ALsizei Offset, const ALsizei IrSize,
const ALfloat (*restrict Coeffs)[2], ALfloat (*restrict Values)[2],
@@ -40,6 +45,11 @@ void MixHrtf_SSE(ALfloat *restrict LeftOut, ALfloat *restrict RightOut,
const ALfloat *data, ALsizei Offset, ALsizei OutPos,
const ALsizei IrSize, struct MixHrtfParams *hrtfparams,
struct HrtfState *hrtfstate, ALsizei BufferSize);
+void MixHrtfBlend_SSE(ALfloat *restrict LeftOut, ALfloat *restrict RightOut,
+ const ALfloat *data, ALsizei Offset, ALsizei OutPos,
+ const ALsizei IrSize, const HrtfParams *oldparams,
+ MixHrtfParams *newparams, HrtfState *hrtfstate,
+ ALsizei BufferSize);
void MixDirectHrtf_SSE(ALfloat *restrict LeftOut, ALfloat *restrict RightOut,
const ALfloat *data, ALsizei Offset, const ALsizei IrSize,
const ALfloat (*restrict Coeffs)[2], ALfloat (*restrict Values)[2],
@@ -89,6 +99,11 @@ void MixHrtf_Neon(ALfloat *restrict LeftOut, ALfloat *restrict RightOut,
const ALfloat *data, ALsizei Offset, ALsizei OutPos,
const ALsizei IrSize, struct MixHrtfParams *hrtfparams,
struct HrtfState *hrtfstate, ALsizei BufferSize);
+void MixHrtfBlend_Neon(ALfloat *restrict LeftOut, ALfloat *restrict RightOut,
+ const ALfloat *data, ALsizei Offset, ALsizei OutPos,
+ const ALsizei IrSize, const HrtfParams *oldparams,
+ MixHrtfParams *newparams, HrtfState *hrtfstate,
+ ALsizei BufferSize);
void MixDirectHrtf_Neon(ALfloat *restrict LeftOut, ALfloat *restrict RightOut,
const ALfloat *data, ALsizei Offset, const ALsizei IrSize,
const ALfloat (*restrict Coeffs)[2], ALfloat (*restrict Values)[2],
diff --git a/Alc/mixer_inc.c b/Alc/mixer_inc.c
index 16c3a61e..3c9d4dc5 100644
--- a/Alc/mixer_inc.c
+++ b/Alc/mixer_inc.c
@@ -32,21 +32,66 @@ void MixHrtf(ALfloat *restrict LeftOut, ALfloat *restrict RightOut,
for(i = 0;i < BufferSize;i++)
{
hrtfstate->History[Offset&HRTF_HISTORY_MASK] = *(data++);
- left = hrtfstate->History[(Offset-Delay[0])&HRTF_HISTORY_MASK];
- right = hrtfstate->History[(Offset-Delay[1])&HRTF_HISTORY_MASK];
+ left = hrtfstate->History[(Offset-Delay[0])&HRTF_HISTORY_MASK]*gain;
+ right = hrtfstate->History[(Offset-Delay[1])&HRTF_HISTORY_MASK]*gain;
- hrtfstate->Values[(Offset+IrSize)&HRIR_MASK][0] = 0.0f;
- hrtfstate->Values[(Offset+IrSize)&HRIR_MASK][1] = 0.0f;
- Offset++;
+ hrtfstate->Values[(Offset+IrSize-1)&HRIR_MASK][0] = 0.0f;
+ hrtfstate->Values[(Offset+IrSize-1)&HRIR_MASK][1] = 0.0f;
ApplyCoeffs(Offset, hrtfstate->Values, IrSize, Coeffs, left, right);
- *(LeftOut++) += hrtfstate->Values[Offset&HRIR_MASK][0]*gain;
- *(RightOut++) += hrtfstate->Values[Offset&HRIR_MASK][1]*gain;
+ *(LeftOut++) += hrtfstate->Values[Offset&HRIR_MASK][0];
+ *(RightOut++) += hrtfstate->Values[Offset&HRIR_MASK][1];
+
gain += gainstep;
+ Offset++;
}
hrtfparams->Gain = gain;
}
+void MixHrtfBlend(ALfloat *restrict LeftOut, ALfloat *restrict RightOut,
+ const ALfloat *data, ALsizei Offset, ALsizei OutPos,
+ const ALsizei IrSize, const HrtfParams *oldparams,
+ MixHrtfParams *newparams, HrtfState *hrtfstate,
+ ALsizei BufferSize)
+{
+ const ALfloat (*OldCoeffs)[2] = ASSUME_ALIGNED(oldparams->Coeffs, 16);
+ const ALsizei OldDelay[2] = { oldparams->Delay[0], oldparams->Delay[1] };
+ ALfloat oldGain = oldparams->Gain;
+ ALfloat oldGainStep = -oldGain / (ALfloat)BufferSize;
+ const ALfloat (*NewCoeffs)[2] = ASSUME_ALIGNED(newparams->Coeffs, 16);
+ const ALsizei NewDelay[2] = { newparams->Delay[0], newparams->Delay[1] };
+ ALfloat newGain = newparams->Gain;
+ ALfloat newGainStep = newparams->GainStep;
+ ALfloat left, right;
+ ALsizei i;
+
+ LeftOut += OutPos;
+ RightOut += OutPos;
+ for(i = 0;i < BufferSize;i++)
+ {
+ hrtfstate->Values[(Offset+IrSize-1)&HRIR_MASK][0] = 0.0f;
+ hrtfstate->Values[(Offset+IrSize-1)&HRIR_MASK][1] = 0.0f;
+
+ hrtfstate->History[Offset&HRTF_HISTORY_MASK] = *(data++);
+
+ left = hrtfstate->History[(Offset-OldDelay[0])&HRTF_HISTORY_MASK]*oldGain;
+ right = hrtfstate->History[(Offset-OldDelay[1])&HRTF_HISTORY_MASK]*oldGain;
+ ApplyCoeffs(Offset, hrtfstate->Values, IrSize, OldCoeffs, left, right);
+
+ left = hrtfstate->History[(Offset-NewDelay[0])&HRTF_HISTORY_MASK]*newGain;
+ right = hrtfstate->History[(Offset-NewDelay[1])&HRTF_HISTORY_MASK]*newGain;
+ ApplyCoeffs(Offset, hrtfstate->Values, IrSize, NewCoeffs, left, right);
+
+ *(LeftOut++) += hrtfstate->Values[Offset&HRIR_MASK][0];
+ *(RightOut++) += hrtfstate->Values[Offset&HRIR_MASK][1];
+
+ oldGain += oldGainStep;
+ newGain += newGainStep;
+ Offset++;
+ }
+ newparams->Gain = newGain;
+}
+
void MixDirectHrtf(ALfloat *restrict LeftOut, ALfloat *restrict RightOut,
const ALfloat *data, ALsizei Offset, const ALsizei IrSize,
const ALfloat (*restrict Coeffs)[2], ALfloat (*restrict Values)[2],
diff --git a/Alc/mixer_neon.c b/Alc/mixer_neon.c
index 65dd608c..51191783 100644
--- a/Alc/mixer_neon.c
+++ b/Alc/mixer_neon.c
@@ -221,6 +221,7 @@ static inline void ApplyCoeffs(ALsizei Offset, ALfloat (*restrict Values)[2],
}
#define MixHrtf MixHrtf_Neon
+#define MixHrtfBlend MixHrtfBlend_Neon
#define MixDirectHrtf MixDirectHrtf_Neon
#include "mixer_inc.c"
#undef MixHrtf
diff --git a/Alc/mixer_sse.c b/Alc/mixer_sse.c
index d30ec982..68786573 100644
--- a/Alc/mixer_sse.c
+++ b/Alc/mixer_sse.c
@@ -124,6 +124,7 @@ static inline void ApplyCoeffs(ALsizei Offset, ALfloat (*restrict Values)[2],
}
#define MixHrtf MixHrtf_SSE
+#define MixHrtfBlend MixHrtfBlend_SSE
#define MixDirectHrtf MixDirectHrtf_SSE
#include "mixer_inc.c"
#undef MixHrtf
diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h
index 3cb94270..168a754f 100644
--- a/OpenAL32/Include/alu.h
+++ b/OpenAL32/Include/alu.h
@@ -301,6 +301,11 @@ typedef void (*HrtfMixerFunc)(ALfloat *restrict LeftOut, ALfloat *restrict Right
const ALfloat *data, ALsizei Offset, ALsizei OutPos,
const ALsizei IrSize, MixHrtfParams *hrtfparams,
HrtfState *hrtfstate, ALsizei BufferSize);
+typedef void (*HrtfMixerBlendFunc)(ALfloat *restrict LeftOut, ALfloat *restrict RightOut,
+ const ALfloat *data, ALsizei Offset, ALsizei OutPos,
+ const ALsizei IrSize, const HrtfParams *oldparams,
+ MixHrtfParams *newparams, HrtfState *hrtfstate,
+ ALsizei BufferSize);
typedef void (*HrtfDirectMixerFunc)(ALfloat *restrict LeftOut, ALfloat *restrict RightOut,
const ALfloat *data, ALsizei Offset, const ALsizei IrSize,
const ALfloat (*restrict Coeffs)[2],