From 98ff6f990af1ad3159c5d9a2209b7b6de36d2130 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 11 Sep 2012 05:24:19 -0700 Subject: [PATCH] Do the filtering separately from the mixing --- Alc/mixer.c | 29 ++++++++++++++++++++++++----- Alc/mixer_defs.h | 6 +++--- Alc/mixer_inc.c | 45 +++++++++++---------------------------------- Alc/mixer_sse.c | 22 +++++----------------- OpenAL32/Include/alu.h | 2 +- 5 files changed, 44 insertions(+), 60 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 = ¶ms->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 = ¶ms->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 = ¶ms->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 = ¶ms->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 diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 94e3dc17..cc18f1a7 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -88,7 +88,7 @@ typedef ALvoid (*DryMixerFunc)(struct ALsource *self, ALCdevice *Device, ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize); typedef ALvoid (*WetMixerFunc)(struct SendParams *params, - const ALfloat *RESTRICT data, ALuint srcchan, + const ALfloat *RESTRICT data, ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize); -- 2.11.4.GIT