aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
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 /Alc
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.
Diffstat (limited to 'Alc')
-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
6 files changed, 90 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