aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2012-09-11 05:24:19 -0700
committerChris Robinson <[email protected]>2012-09-11 05:56:19 -0700
commit98ff6f990af1ad3159c5d9a2209b7b6de36d2130 (patch)
tree05a1c609d19ed26961057b6228696ad34c2cec4e /Alc
parentaaa81e00b75d0df6b83be5d3f6e54227110145ae (diff)
Do the filtering separately from the mixing
Diffstat (limited to 'Alc')
-rw-r--r--Alc/mixer.c29
-rw-r--r--Alc/mixer_defs.h6
-rw-r--r--Alc/mixer_inc.c45
-rw-r--r--Alc/mixer_sse.c22
4 files changed, 43 insertions, 59 deletions
diff --git a/Alc/mixer.c b/Alc/mixer.c
index a7882c23..41eba4ae 100644
--- a/Alc/mixer.c
+++ b/Alc/mixer.c
@@ -191,6 +191,16 @@ static void Resample(enum Resampler Resampler, const ALfloat *data, ALuint frac,
}
+static void Filter2P(FILTER *filter, ALuint chan, ALfloat *RESTRICT dst,
+ const ALfloat *RESTRICT src, ALuint numsamples)
+{
+ ALuint i;
+ for(i = 0;i < numsamples;i++)
+ dst[i] = lpFilter2P(filter, chan, src[i]);
+ dst[i] = lpFilter2PC(filter, chan, src[i]);
+}
+
+
ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
{
ALbufferlistitem *BufferListItem;
@@ -432,20 +442,29 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
SrcData += BufferPrePadding*NumChannels;
for(i = 0;i < NumChannels;i++)
{
+ DirectParams *directparms = &Source->Params.Direct;
+ ALIGN(16) ALfloat FilteredData[BUFFERSIZE];
ALfloat ResampledData[BUFFERSIZE];
Resample(Resampler, SrcData+i, DataPosFrac, increment,
NumChannels, ResampledData, BufferSize);
- Source->Params.DryMix(Source, Device, &Source->Params.Direct,
- ResampledData, i, OutPos, SamplesToDo,
+ Filter2P(&directparms->iirFilter, i, FilteredData, ResampledData,
+ BufferSize);
+ Source->Params.DryMix(Source, Device, directparms,
+ FilteredData, i, OutPos, SamplesToDo,
BufferSize);
+
for(j = 0;j < Device->NumAuxSends;j++)
{
- if(!Source->Params.Send[j].Slot)
+ SendParams *sendparms = &Source->Params.Send[j];
+ if(!sendparms->Slot)
continue;
- Source->Params.WetMix(&Source->Params.Send[j], ResampledData, i,
- OutPos, SamplesToDo, BufferSize);
+
+ Filter2P(&sendparms->iirFilter, i, FilteredData, ResampledData,
+ BufferSize);
+ Source->Params.WetMix(sendparms, FilteredData, OutPos,
+ SamplesToDo, BufferSize);
}
}
for(i = 0;i < BufferSize;i++)
diff --git a/Alc/mixer_defs.h b/Alc/mixer_defs.h
index fb3d3d8f..7e930a39 100644
--- a/Alc/mixer_defs.h
+++ b/Alc/mixer_defs.h
@@ -13,16 +13,16 @@ struct SendParams;
/* C mixers */
void MixDirect_Hrtf_C(struct ALsource*,ALCdevice*,struct DirectParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint);
void MixDirect_C(struct ALsource*,ALCdevice*,struct DirectParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint);
-void MixSend_C(struct SendParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint);
+void MixSend_C(struct SendParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint);
/* SSE mixers */
void MixDirect_Hrtf_SSE(struct ALsource*,ALCdevice*,struct DirectParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint);
void MixDirect_SSE(struct ALsource*,ALCdevice*,struct DirectParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint);
-void MixSend_SSE(struct SendParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint);
+void MixSend_SSE(struct SendParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint);
/* Neon mixers */
void MixDirect_Hrtf_Neon(struct ALsource*,ALCdevice*,struct DirectParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint);
void MixDirect_Neon(struct ALsource*,ALCdevice*,struct DirectParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint);
-void MixSend_Neon(struct SendParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint);
+void MixSend_Neon(struct SendParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint);
#endif /* MIXER_DEFS_H */
diff --git a/Alc/mixer_inc.c b/Alc/mixer_inc.c
index c3df342e..f60ade65 100644
--- a/Alc/mixer_inc.c
+++ b/Alc/mixer_inc.c
@@ -53,15 +53,12 @@ void MixDirect_Hrtf(ALsource *Source, ALCdevice *Device, DirectParams *params,
ALIGN(16) ALfloat Coeffs[HRIR_LENGTH][2];
ALuint Delay[2];
ALfloat left, right;
- FILTER *DryFilter;
- ALfloat value;
ALuint pos;
ALuint c;
DryBuffer = Device->DryBuffer;
ClickRemoval = Device->ClickRemoval;
PendingClicks = Device->PendingClicks;
- DryFilter = &params->iirFilter;
pos = 0;
for(c = 0;c < IrSize;c++)
@@ -75,9 +72,7 @@ void MixDirect_Hrtf(ALsource *Source, ALCdevice *Device, DirectParams *params,
if(LIKELY(OutPos == 0))
{
- value = lpFilter2PC(DryFilter, srcchan, data[pos]);
-
- History[Offset&SRC_HISTORY_MASK] = value;
+ History[Offset&SRC_HISTORY_MASK] = data[pos];
left = lerp(History[(Offset-(Delay[0]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK],
History[(Offset-(Delay[0]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK],
(Delay[0]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE));
@@ -92,9 +87,7 @@ void MixDirect_Hrtf(ALsource *Source, ALCdevice *Device, DirectParams *params,
}
for(pos = 0;pos < BufferSize && Counter > 0;pos++)
{
- value = lpFilter2P(DryFilter, srcchan, data[pos]);
-
- History[Offset&SRC_HISTORY_MASK] = value;
+ History[Offset&SRC_HISTORY_MASK] = data[pos];
left = lerp(History[(Offset-(Delay[0]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK],
History[(Offset-(Delay[0]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK],
(Delay[0]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE));
@@ -121,9 +114,7 @@ void MixDirect_Hrtf(ALsource *Source, ALCdevice *Device, DirectParams *params,
Delay[1] >>= HRTFDELAY_BITS;
for(;pos < BufferSize;pos++)
{
- value = lpFilter2P(DryFilter, srcchan, data[pos]);
-
- History[Offset&SRC_HISTORY_MASK] = value;
+ History[Offset&SRC_HISTORY_MASK] = data[pos];
left = History[(Offset-Delay[0])&SRC_HISTORY_MASK];
right = History[(Offset-Delay[1])&SRC_HISTORY_MASK];
@@ -139,9 +130,7 @@ void MixDirect_Hrtf(ALsource *Source, ALCdevice *Device, DirectParams *params,
}
if(LIKELY(OutPos == SamplesToDo))
{
- value = lpFilter2PC(DryFilter, srcchan, data[pos]);
-
- History[Offset&SRC_HISTORY_MASK] = value;
+ History[Offset&SRC_HISTORY_MASK] = data[pos];
left = History[(Offset-Delay[0])&SRC_HISTORY_MASK];
right = History[(Offset-Delay[1])&SRC_HISTORY_MASK];
@@ -161,16 +150,13 @@ void MixDirect(ALsource *Source, ALCdevice *Device, DirectParams *params,
ALfloat (*RESTRICT DryBuffer)[MaxChannels];
ALfloat *RESTRICT ClickRemoval, *RESTRICT PendingClicks;
ALIGN(16) ALfloat DrySend[MaxChannels];
- FILTER *DryFilter;
ALuint pos;
- ALfloat value;
ALuint c;
(void)Source;
DryBuffer = Device->DryBuffer;
ClickRemoval = Device->ClickRemoval;
PendingClicks = Device->PendingClicks;
- DryFilter = &params->iirFilter;
for(c = 0;c < MaxChannels;c++)
DrySend[c] = params->Gains[srcchan][c];
@@ -178,28 +164,25 @@ void MixDirect(ALsource *Source, ALCdevice *Device, DirectParams *params,
pos = 0;
if(OutPos == 0)
{
- value = lpFilter2PC(DryFilter, srcchan, data[pos]);
for(c = 0;c < MaxChannels;c++)
- ClickRemoval[c] -= value*DrySend[c];
+ ClickRemoval[c] -= data[pos]*DrySend[c];
}
for(pos = 0;pos < BufferSize;pos++)
{
- value = lpFilter2P(DryFilter, srcchan, data[pos]);
for(c = 0;c < MaxChannels;c++)
- DryBuffer[OutPos][c] += value*DrySend[c];
+ DryBuffer[OutPos][c] += data[pos]*DrySend[c];
OutPos++;
}
if(OutPos == SamplesToDo)
{
- value = lpFilter2PC(DryFilter, srcchan, data[pos]);
for(c = 0;c < MaxChannels;c++)
- PendingClicks[c] += value*DrySend[c];
+ PendingClicks[c] += data[pos]*DrySend[c];
}
}
#endif
#ifndef NO_MIXSEND
-void MixSend(SendParams *params, const ALfloat *RESTRICT data, ALuint srcchan,
+void MixSend(SendParams *params, const ALfloat *RESTRICT data,
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
{
ALeffectslot *Slot;
@@ -207,33 +190,27 @@ void MixSend(SendParams *params, const ALfloat *RESTRICT data, ALuint srcchan,
ALfloat *WetBuffer;
ALfloat *WetClickRemoval;
ALfloat *WetPendingClicks;
- FILTER *WetFilter;
ALuint pos;
- ALfloat value;
Slot = params->Slot;
WetBuffer = Slot->WetBuffer;
WetClickRemoval = Slot->ClickRemoval;
WetPendingClicks = Slot->PendingClicks;
- WetFilter = &params->iirFilter;
WetSend = params->Gain;
pos = 0;
if(OutPos == 0)
{
- value = lpFilter2PC(WetFilter, srcchan, data[pos]);
- WetClickRemoval[0] -= value * WetSend;
+ WetClickRemoval[0] -= data[pos] * WetSend;
}
for(pos = 0;pos < BufferSize;pos++)
{
- value = lpFilter2P(WetFilter, srcchan, data[pos]);
- WetBuffer[OutPos] += value * WetSend;
+ WetBuffer[OutPos] += data[pos] * WetSend;
OutPos++;
}
if(OutPos == SamplesToDo)
{
- value = lpFilter2PC(WetFilter, srcchan, data[pos]);
- WetPendingClicks[0] += value * WetSend;
+ WetPendingClicks[0] += data[pos] * WetSend;
}
}
#endif
diff --git a/Alc/mixer_sse.c b/Alc/mixer_sse.c
index 27b550e0..434857c1 100644
--- a/Alc/mixer_sse.c
+++ b/Alc/mixer_sse.c
@@ -134,9 +134,8 @@ void MixDirect_SSE(ALsource *Source, ALCdevice *Device, DirectParams *params,
{
ALfloat (*RESTRICT DryBuffer)[MaxChannels];
ALfloat *RESTRICT ClickRemoval, *RESTRICT PendingClicks;
- ALIGN(16) ALfloat DrySend[MaxChannels];
+ ALfloat DrySend[MaxChannels];
ALIGN(16) ALfloat value[4];
- FILTER *DryFilter;
ALuint pos;
ALuint c;
(void)Source;
@@ -144,7 +143,6 @@ void MixDirect_SSE(ALsource *Source, ALCdevice *Device, DirectParams *params,
DryBuffer = Device->DryBuffer;
ClickRemoval = Device->ClickRemoval;
PendingClicks = Device->PendingClicks;
- DryFilter = &params->iirFilter;
for(c = 0;c < MaxChannels;c++)
DrySend[c] = params->Gains[srcchan][c];
@@ -152,20 +150,12 @@ void MixDirect_SSE(ALsource *Source, ALCdevice *Device, DirectParams *params,
pos = 0;
if(OutPos == 0)
{
- value[0] = lpFilter2PC(DryFilter, srcchan, data[pos]);
for(c = 0;c < MaxChannels;c++)
- ClickRemoval[c] -= value[0]*DrySend[c];
+ ClickRemoval[c] -= data[pos]*DrySend[c];
}
for(pos = 0;pos < BufferSize-3;pos += 4)
{
- __m128 val4;
-
- value[0] = lpFilter2P(DryFilter, srcchan, data[pos ]);
- value[1] = lpFilter2P(DryFilter, srcchan, data[pos+1]);
- value[2] = lpFilter2P(DryFilter, srcchan, data[pos+2]);
- value[3] = lpFilter2P(DryFilter, srcchan, data[pos+3]);
- val4 = _mm_load_ps(value);
-
+ const __m128 val4 = _mm_load_ps(&data[pos]);
for(c = 0;c < MaxChannels;c++)
{
const __m128 gain = _mm_set1_ps(DrySend[c]);
@@ -190,16 +180,14 @@ void MixDirect_SSE(ALsource *Source, ALCdevice *Device, DirectParams *params,
}
for(;pos < BufferSize;pos++)
{
- value[0] = lpFilter2P(DryFilter, srcchan, data[pos]);
for(c = 0;c < MaxChannels;c++)
- DryBuffer[OutPos][c] += value[0]*DrySend[c];
+ DryBuffer[OutPos][c] += data[pos]*DrySend[c];
OutPos++;
}
if(OutPos == SamplesToDo)
{
- value[0] = lpFilter2PC(DryFilter, srcchan, data[pos]);
for(c = 0;c < MaxChannels;c++)
- PendingClicks[c] += value[0]*DrySend[c];
+ PendingClicks[c] += data[pos]*DrySend[c];
}
}
#define NO_MIXDIRECT