Do the filtering separately from the mixing
This commit is contained in:
parent
aaa81e00b7
commit
98ff6f990a
29
Alc/mixer.c
29
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++)
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user