Use a more specialized mixer function for B-Format to HRTF

This commit is contained in:
Chris Robinson
2016-08-12 05:26:36 -07:00
parent c6c6e3324d
commit 770e2ff7ed
9 changed files with 66 additions and 27 deletions
+8 -11
View File
@@ -94,18 +94,18 @@ extern inline void aluMatrixfSet(aluMatrixf *matrix,
ALfloat m30, ALfloat m31, ALfloat m32, ALfloat m33);
static inline HrtfMixerFunc SelectHrtfMixer(void)
static inline HrtfDirectMixerFunc SelectHrtfMixer(void)
{
#ifdef HAVE_SSE
if((CPUCapFlags&CPU_CAP_SSE))
return MixHrtf_SSE;
return MixDirectHrtf_SSE;
#endif
#ifdef HAVE_NEON
if((CPUCapFlags&CPU_CAP_NEON))
return MixHrtf_Neon;
return MixDirectHrtf_Neon;
#endif
return MixHrtf_C;
return MixDirectHrtf_C;
}
@@ -1504,17 +1504,14 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
int ridx = GetChannelIdxByName(device->RealOut, FrontRight);
if(lidx != -1 && ridx != -1)
{
HrtfMixerFunc HrtfMix = SelectHrtfMixer();
HrtfDirectMixerFunc HrtfMix = SelectHrtfMixer();
ALuint irsize = device->Hrtf_IrSize;
MixHrtfParams hrtfparams;
memset(&hrtfparams, 0, sizeof(hrtfparams));
for(c = 0;c < device->Dry.NumChannels;c++)
{
hrtfparams.Current = &device->Hrtf_Params[c];
hrtfparams.Target = &device->Hrtf_Params[c];
HrtfMix(device->RealOut.Buffer, lidx, ridx,
device->Dry.Buffer[c], 0, device->Hrtf_Offset, 0,
irsize, &hrtfparams, &device->Hrtf_State[c], SamplesToDo
device->Dry.Buffer[c], device->Hrtf_Offset, irsize,
device->Hrtf_Coeffs[c], device->Hrtf_Values[c],
SamplesToDo
);
}
device->Hrtf_Offset += SamplesToDo;
+1
View File
@@ -166,6 +166,7 @@ static inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2],
}
#define MixHrtf MixHrtf_C
#define MixDirectHrtf MixDirectHrtf_C
#include "mixer_inc.c"
#undef MixHrtf
+12
View File
@@ -25,6 +25,10 @@ void MixHrtf_C(ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALuint lidx, ALuint ri
const ALfloat *data, ALuint Counter, ALuint Offset, ALuint OutPos,
const ALuint IrSize, const struct MixHrtfParams *hrtfparams,
struct HrtfState *hrtfstate, ALuint BufferSize);
void MixDirectHrtf_C(ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALuint lidx, ALuint ridx,
const ALfloat *data, ALuint Offset, const ALuint IrSize,
ALfloat (*restrict Coeffs)[2], ALfloat (*restrict Values)[2],
ALuint BufferSize);
void Mix_C(const ALfloat *data, ALuint OutChans, ALfloat (*restrict OutBuffer)[BUFFERSIZE],
struct MixGains *Gains, ALuint Counter, ALuint OutPos, ALuint BufferSize);
void MixRow_C(ALfloat *OutBuffer, const ALfloat *Mtx, ALfloat (*restrict data)[BUFFERSIZE],
@@ -35,6 +39,10 @@ void MixHrtf_SSE(ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALuint lidx, ALuint
const ALfloat *data, ALuint Counter, ALuint Offset, ALuint OutPos,
const ALuint IrSize, const struct MixHrtfParams *hrtfparams,
struct HrtfState *hrtfstate, ALuint BufferSize);
void MixDirectHrtf_SSE(ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALuint lidx, ALuint ridx,
const ALfloat *data, ALuint Offset, const ALuint IrSize,
ALfloat (*restrict Coeffs)[2], ALfloat (*restrict Values)[2],
ALuint BufferSize);
void Mix_SSE(const ALfloat *data, ALuint OutChans, ALfloat (*restrict OutBuffer)[BUFFERSIZE],
struct MixGains *Gains, ALuint Counter, ALuint OutPos, ALuint BufferSize);
void MixRow_SSE(ALfloat *OutBuffer, const ALfloat *Mtx, ALfloat (*restrict data)[BUFFERSIZE],
@@ -78,6 +86,10 @@ void MixHrtf_Neon(ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALuint lidx, ALuint
const ALfloat *data, ALuint Counter, ALuint Offset, ALuint OutPos,
const ALuint IrSize, const struct MixHrtfParams *hrtfparams,
struct HrtfState *hrtfstate, ALuint BufferSize);
void MixDirectHrtf_Neon(ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALuint lidx, ALuint ridx,
const ALfloat *data, ALuint Offset, const ALuint IrSize,
ALfloat (*restrict Coeffs)[2], ALfloat (*restrict Values)[2],
ALuint BufferSize);
void Mix_Neon(const ALfloat *data, ALuint OutChans, ALfloat (*restrict OutBuffer)[BUFFERSIZE],
struct MixGains *Gains, ALuint Counter, ALuint OutPos, ALuint BufferSize);
void MixRow_Neon(ALfloat *OutBuffer, const ALfloat *Mtx, ALfloat (*restrict data)[BUFFERSIZE],
+33
View File
@@ -114,3 +114,36 @@ skip_stepping:
OutPos += todo;
}
}
void MixDirectHrtf(ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALuint lidx, ALuint ridx,
const ALfloat *data, ALuint Offset, const ALuint IrSize,
ALfloat (*restrict Coeffs)[2], ALfloat (*restrict Values)[2],
ALuint BufferSize)
{
ALfloat out[MAX_UPDATE_SAMPLES][2];
ALfloat insample;
ALuint pos, i;
for(pos = 0;pos < BufferSize;)
{
ALuint todo = minu(BufferSize-pos, MAX_UPDATE_SAMPLES);
for(i = 0;i < todo;i++)
{
Values[(Offset+IrSize)&HRIR_MASK][0] = 0.0f;
Values[(Offset+IrSize)&HRIR_MASK][1] = 0.0f;
Offset++;
insample = *(data++);
ApplyCoeffs(Offset, Values, IrSize, Coeffs, insample, insample);
out[i][0] = Values[Offset&HRIR_MASK][0];
out[i][1] = Values[Offset&HRIR_MASK][1];
}
for(i = 0;i < todo;i++)
OutBuffer[lidx][pos+i] += out[i][0];
for(i = 0;i < todo;i++)
OutBuffer[ridx][pos+i] += out[i][1];
pos += todo;
}
}
+1
View File
@@ -70,6 +70,7 @@ static inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2],
}
#define MixHrtf MixHrtf_Neon
#define MixDirectHrtf MixDirectHrtf_Neon
#include "mixer_inc.c"
#undef MixHrtf
+1
View File
@@ -186,6 +186,7 @@ static inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2],
}
#define MixHrtf MixHrtf_SSE
#define MixDirectHrtf MixDirectHrtf_SSE
#include "mixer_inc.c"
#undef MixHrtf
+4 -14
View File
@@ -758,9 +758,8 @@ static void InitHQPanning(ALCdevice *device, const AmbDecConf *conf, const ALuin
static void InitHrtfPanning(ALCdevice *device)
{
ALfloat hrtf_coeffs[4][HRIR_LENGTH][2];
size_t count = 4;
ALuint i, j;
ALuint i;
for(i = 0;i < count;i++)
{
@@ -773,21 +772,12 @@ static void InitHrtfPanning(ALCdevice *device)
device->FOAOut.Ambi = device->Dry.Ambi;
device->FOAOut.CoeffCount = device->Dry.CoeffCount;
memset(hrtf_coeffs, 0, sizeof(hrtf_coeffs));
device->Hrtf_IrSize = BuildBFormatHrtf(device->Hrtf, hrtf_coeffs, device->Dry.NumChannels);
memset(device->Hrtf_Coeffs, 0, sizeof(device->Hrtf_Coeffs));
device->Hrtf_IrSize = BuildBFormatHrtf(device->Hrtf, device->Hrtf_Coeffs,
device->Dry.NumChannels);
/* Round up to the nearest multiple of 8 */
device->Hrtf_IrSize = (device->Hrtf_IrSize+7)&~7;
for(i = 0;i < device->Dry.NumChannels;i++)
{
for(j = 0;j < HRIR_LENGTH;j++)
{
device->Hrtf_Params[i].Coeffs[j][0] = hrtf_coeffs[i][j][0];
device->Hrtf_Params[i].Coeffs[j][1] = hrtf_coeffs[i][j][1];
}
device->Hrtf_Params[i].Delay[0] = 0;
device->Hrtf_Params[i].Delay[1] = 0;
}
}
static void InitUhjPanning(ALCdevice *device)
+2 -2
View File
@@ -599,8 +599,8 @@ struct ALCdevice_struct
ALCenum Hrtf_Status;
/* HRTF filter state for dry buffer content */
HrtfState Hrtf_State[4];
HrtfParams Hrtf_Params[4];
alignas(16) ALfloat Hrtf_Values[4][HRIR_LENGTH][2];
alignas(16) ALfloat Hrtf_Coeffs[4][HRIR_LENGTH][2];
ALuint Hrtf_Offset;
ALuint Hrtf_IrSize;
+4
View File
@@ -167,6 +167,10 @@ typedef void (*HrtfMixerFunc)(ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALuint
const ALfloat *data, ALuint Counter, ALuint Offset, ALuint OutPos,
const ALuint IrSize, const MixHrtfParams *hrtfparams,
HrtfState *hrtfstate, ALuint BufferSize);
typedef void (*HrtfDirectMixerFunc)(ALfloat (*restrict OutBuffer)[BUFFERSIZE],
ALuint lidx, ALuint ridx, const ALfloat *data, ALuint Offset,
const ALuint IrSize, ALfloat (*restrict Coeffs)[2],
ALfloat (*restrict Values)[2], ALuint BufferSize);
#define GAIN_SILENCE_THRESHOLD (0.00001f) /* -100dB */