From 2450ee1723daddd8f0977f2589b45e126b1ae62a Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 27 Apr 2012 23:46:51 -0700 Subject: [PATCH] Use separate methods for the dry and wet mixing loops --- Alc/ALu.c | 10 ++- Alc/mixer.c | 213 ++++++++++++++++++++------------------------ OpenAL32/Include/alSource.h | 3 +- OpenAL32/Include/alu.h | 17 ++-- 4 files changed, 115 insertions(+), 128 deletions(-) diff --git a/Alc/ALu.c b/Alc/ALu.c index f6a4b8c1..fabef277 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -172,9 +172,10 @@ ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext) BufferListItem = BufferListItem->next; } if(!DirectChannels && Device->Hrtf) - ALSource->Params.DoMix = SelectHrtfMixer(Resampler); + ALSource->Params.DryMix = SelectHrtfMixer(Resampler); else - ALSource->Params.DoMix = SelectMixer(Resampler); + ALSource->Params.DryMix = SelectDirectMixer(Resampler); + ALSource->Params.WetMix = SelectSendMixer(Resampler); /* Calculate gains */ DryGain = clampf(SourceVolume, MinVolume, MaxVolume); @@ -684,9 +685,10 @@ ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext) BufferListItem = BufferListItem->next; } if(Device->Hrtf) - ALSource->Params.DoMix = SelectHrtfMixer(Resampler); + ALSource->Params.DryMix = SelectHrtfMixer(Resampler); else - ALSource->Params.DoMix = SelectMixer(Resampler); + ALSource->Params.DryMix = SelectDirectMixer(Resampler); + ALSource->Params.WetMix = SelectSendMixer(Resampler); if(Device->Hrtf) { diff --git a/Alc/mixer.c b/Alc/mixer.c index 7d51ee51..c169f5c8 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -101,7 +101,7 @@ static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2], #endif #define DECL_TEMPLATE(sampler) \ -static void Mix_Hrtf_##sampler(ALsource *Source, ALCdevice *Device, \ +static void MixDirect_Hrtf_##sampler(ALsource *Source, ALCdevice *Device, \ const ALfloat *RESTRICT data, ALuint srcfrac, ALuint OutPos, \ ALuint SamplesToDo, ALuint BufferSize) \ { \ @@ -114,8 +114,8 @@ static void Mix_Hrtf_##sampler(ALsource *Source, ALCdevice *Device, \ FILTER *DryFilter; \ ALuint BufferIdx; \ ALuint increment; \ - ALuint i, out, c; \ ALfloat value; \ + ALuint i, c; \ \ increment = Source->Params.Step; \ \ @@ -124,9 +124,6 @@ static void Mix_Hrtf_##sampler(ALsource *Source, ALCdevice *Device, \ PendingClicks = Device->PendingClicks; \ DryFilter = &Source->Params.Direct.iirFilter; \ \ - pos = 0; \ - frac = srcfrac; \ - \ for(i = 0;i < NumChannels;i++) \ { \ ALfloat (*RESTRICT TargetCoeffs)[2] = Source->Params.Hrtf.Coeffs[i]; \ @@ -240,59 +237,6 @@ static void Mix_Hrtf_##sampler(ALsource *Source, ALCdevice *Device, \ } \ OutPos -= BufferSize; \ } \ - \ - for(out = 0;out < Device->NumAuxSends;out++) \ - { \ - ALeffectslot *Slot = Source->Params.Send[out].Slot; \ - ALfloat WetSend; \ - ALfloat *RESTRICT WetBuffer; \ - ALfloat *RESTRICT WetClickRemoval; \ - ALfloat *RESTRICT WetPendingClicks; \ - FILTER *WetFilter; \ - \ - if(Slot == NULL) \ - continue; \ - \ - WetBuffer = Slot->WetBuffer; \ - WetClickRemoval = Slot->ClickRemoval; \ - WetPendingClicks = Slot->PendingClicks; \ - WetFilter = &Source->Params.Send[out].iirFilter; \ - WetSend = Source->Params.Send[out].Gain; \ - \ - for(i = 0;i < NumChannels;i++) \ - { \ - pos = 0; \ - frac = srcfrac; \ - \ - if(LIKELY(OutPos == 0)) \ - { \ - value = sampler(data + pos*NumChannels + i, NumChannels,frac);\ - value = lpFilter1PC(WetFilter, i, value); \ - \ - WetClickRemoval[0] -= value * WetSend; \ - } \ - for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \ - { \ - value = sampler(data + pos*NumChannels + i, NumChannels,frac);\ - value = lpFilter1P(WetFilter, i, value); \ - \ - WetBuffer[OutPos] += value * WetSend; \ - \ - frac += increment; \ - pos += frac>>FRACTIONBITS; \ - frac &= FRACTIONMASK; \ - OutPos++; \ - } \ - if(LIKELY(OutPos == SamplesToDo)) \ - { \ - value = sampler(data + pos*NumChannels + i, NumChannels,frac);\ - value = lpFilter1PC(WetFilter, i, value); \ - \ - WetPendingClicks[0] += value * WetSend; \ - } \ - OutPos -= BufferSize; \ - } \ - } \ } DECL_TEMPLATE(point32) @@ -303,7 +247,7 @@ DECL_TEMPLATE(cubic32) #define DECL_TEMPLATE(sampler) \ -static void Mix_##sampler(ALsource *Source, ALCdevice *Device, \ +static void MixDirect_##sampler(ALsource *Source, ALCdevice *Device, \ const ALfloat *RESTRICT data, ALuint srcfrac, ALuint OutPos, \ ALuint SamplesToDo, ALuint BufferSize) \ { \ @@ -315,8 +259,8 @@ static void Mix_##sampler(ALsource *Source, ALCdevice *Device, \ ALuint pos, frac; \ ALuint BufferIdx; \ ALuint increment; \ - ALuint i, out, c; \ ALfloat value; \ + ALuint i, c; \ \ increment = Source->Params.Step; \ \ @@ -325,9 +269,6 @@ static void Mix_##sampler(ALsource *Source, ALCdevice *Device, \ PendingClicks = Device->PendingClicks; \ DryFilter = &Source->Params.Direct.iirFilter; \ \ - pos = 0; \ - frac = srcfrac; \ - \ for(i = 0;i < NumChannels;i++) \ { \ for(c = 0;c < MAXCHANNELS;c++) \ @@ -367,58 +308,73 @@ static void Mix_##sampler(ALsource *Source, ALCdevice *Device, \ } \ OutPos -= BufferSize; \ } \ +} + +DECL_TEMPLATE(point32) +DECL_TEMPLATE(lerp32) +DECL_TEMPLATE(cubic32) + +#undef DECL_TEMPLATE + +#define DECL_TEMPLATE(sampler) \ +static void MixSend_##sampler(ALsource *Source, ALuint sendidx, \ + const ALfloat *RESTRICT data, ALuint srcfrac, ALuint OutPos, \ + ALuint SamplesToDo, ALuint BufferSize) \ +{ \ + const ALuint NumChannels = Source->NumChannels; \ + ALeffectslot *Slot; \ + ALfloat WetSend; \ + ALfloat *WetBuffer; \ + ALfloat *WetClickRemoval; \ + ALfloat *WetPendingClicks; \ + FILTER *WetFilter; \ + ALuint pos, frac; \ + ALuint BufferIdx; \ + ALuint increment; \ + ALfloat value; \ + ALuint i; \ + \ + increment = Source->Params.Step; \ \ - for(out = 0;out < Device->NumAuxSends;out++) \ + Slot = Source->Params.Send[sendidx].Slot; \ + WetBuffer = Slot->WetBuffer; \ + WetClickRemoval = Slot->ClickRemoval; \ + WetPendingClicks = Slot->PendingClicks; \ + WetFilter = &Source->Params.Send[sendidx].iirFilter; \ + WetSend = Source->Params.Send[sendidx].Gain; \ + \ + for(i = 0;i < NumChannels;i++) \ { \ - ALeffectslot *Slot = Source->Params.Send[out].Slot; \ - ALfloat WetSend; \ - ALfloat *WetBuffer; \ - ALfloat *WetClickRemoval; \ - ALfloat *WetPendingClicks; \ - FILTER *WetFilter; \ - \ - if(Slot == NULL) \ - continue; \ - \ - WetBuffer = Slot->WetBuffer; \ - WetClickRemoval = Slot->ClickRemoval; \ - WetPendingClicks = Slot->PendingClicks; \ - WetFilter = &Source->Params.Send[out].iirFilter; \ - WetSend = Source->Params.Send[out].Gain; \ - \ - for(i = 0;i < NumChannels;i++) \ - { \ - pos = 0; \ - frac = srcfrac; \ + pos = 0; \ + frac = srcfrac; \ \ - if(OutPos == 0) \ - { \ - value = sampler(data + pos*NumChannels + i, NumChannels,frac);\ + if(OutPos == 0) \ + { \ + value = sampler(data + pos*NumChannels + i, NumChannels,frac); \ \ - value = lpFilter1PC(WetFilter, i, value); \ - WetClickRemoval[0] -= value * WetSend; \ - } \ - for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \ - { \ - value = sampler(data + pos*NumChannels + i, NumChannels,frac);\ + value = lpFilter1PC(WetFilter, i, value); \ + WetClickRemoval[0] -= value * WetSend; \ + } \ + for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \ + { \ + value = sampler(data + pos*NumChannels + i, NumChannels,frac); \ \ - value = lpFilter1P(WetFilter, i, value); \ - WetBuffer[OutPos] += value * WetSend; \ + value = lpFilter1P(WetFilter, i, value); \ + WetBuffer[OutPos] += value * WetSend; \ \ - frac += increment; \ - pos += frac>>FRACTIONBITS; \ - frac &= FRACTIONMASK; \ - OutPos++; \ - } \ - if(OutPos == SamplesToDo) \ - { \ - value = sampler(data + pos*NumChannels + i, NumChannels,frac);\ + frac += increment; \ + pos += frac>>FRACTIONBITS; \ + frac &= FRACTIONMASK; \ + OutPos++; \ + } \ + if(OutPos == SamplesToDo) \ + { \ + value = sampler(data + pos*NumChannels + i, NumChannels,frac); \ \ - value = lpFilter1PC(WetFilter, i, value); \ - WetPendingClicks[0] += value * WetSend; \ - } \ - OutPos -= BufferSize; \ + value = lpFilter1PC(WetFilter, i, value); \ + WetPendingClicks[0] += value * WetSend; \ } \ + OutPos -= BufferSize; \ } \ } @@ -429,32 +385,48 @@ DECL_TEMPLATE(cubic32) #undef DECL_TEMPLATE -MixerFunc SelectMixer(enum Resampler Resampler) +DryMixerFunc SelectDirectMixer(enum Resampler Resampler) { switch(Resampler) { case PointResampler: - return Mix_point32; + return MixDirect_point32; case LinearResampler: - return Mix_lerp32; + return MixDirect_lerp32; case CubicResampler: - return Mix_cubic32; + return MixDirect_cubic32; case ResamplerMax: break; } return NULL; } -MixerFunc SelectHrtfMixer(enum Resampler Resampler) +DryMixerFunc SelectHrtfMixer(enum Resampler Resampler) { switch(Resampler) { case PointResampler: - return Mix_Hrtf_point32; + return MixDirect_Hrtf_point32; case LinearResampler: - return Mix_Hrtf_lerp32; + return MixDirect_Hrtf_lerp32; case CubicResampler: - return Mix_Hrtf_cubic32; + return MixDirect_Hrtf_cubic32; + case ResamplerMax: + break; + } + return NULL; +} + +WetMixerFunc SelectSendMixer(enum Resampler Resampler) +{ + switch(Resampler) + { + case PointResampler: + return MixSend_point32; + case LinearResampler: + return MixSend_lerp32; + case CubicResampler: + return MixSend_cubic32; case ResamplerMax: break; } @@ -743,8 +715,15 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo) BufferSize = minu(BufferSize, (SamplesToDo-OutPos)); SrcData += BufferPrePadding*NumChannels; - Source->Params.DoMix(Source, Device, SrcData, DataPosFrac, - OutPos, SamplesToDo, BufferSize); + Source->Params.DryMix(Source, Device, SrcData, DataPosFrac, + OutPos, SamplesToDo, BufferSize); + for(i = 0;i < Device->NumAuxSends;i++) + { + if(!Source->Params.Send[i].Slot) + continue; + Source->Params.WetMix(Source, i, SrcData, DataPosFrac, + OutPos, SamplesToDo, BufferSize); + } for(i = 0;i < BufferSize;i++) { DataPosFrac += increment; diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 98803115..badf4e18 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -123,7 +123,8 @@ typedef struct ALsource /** Current target parameters used for mixing. */ struct { - MixerFunc DoMix; + DryMixerFunc DryMix; + WetMixerFunc WetMix; ALint Step; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 68353a00..cf083d4b 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -120,10 +120,14 @@ extern "C" { struct ALsource; struct ALbuffer; -typedef ALvoid (*MixerFunc)(struct ALsource *self, ALCdevice *Device, - const ALfloat *RESTRICT data, ALuint srcfrac, - ALuint OutPos, ALuint SamplesToDo, - ALuint BufferSize); +typedef ALvoid (*DryMixerFunc)(struct ALsource *self, ALCdevice *Device, + const ALfloat *RESTRICT data, ALuint srcfrac, + ALuint OutPos, ALuint SamplesToDo, + ALuint BufferSize); +typedef ALvoid (*WetMixerFunc)(struct ALsource *self, ALuint sendidx, + const ALfloat *RESTRICT data, ALuint srcfrac, + ALuint OutPos, ALuint SamplesToDo, + ALuint BufferSize); enum Resampler { PointResampler, @@ -293,8 +297,9 @@ ALint aluCart2LUTpos(ALfloat re, ALfloat im); ALvoid CalcSourceParams(struct ALsource *ALSource, const ALCcontext *ALContext); ALvoid CalcNonAttnSourceParams(struct ALsource *ALSource, const ALCcontext *ALContext); -MixerFunc SelectMixer(enum Resampler Resampler); -MixerFunc SelectHrtfMixer(enum Resampler Resampler); +DryMixerFunc SelectDirectMixer(enum Resampler Resampler); +DryMixerFunc SelectHrtfMixer(enum Resampler Resampler); +WetMixerFunc SelectSendMixer(enum Resampler Resampler); ALvoid MixSource(struct ALsource *Source, ALCdevice *Device, ALuint SamplesToDo); -- 2.11.4.GIT