Use separate methods for the dry and wet mixing loops
parent
67f1cdfcbe
commit
2450ee1723
10
Alc/ALu.c
10
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)
|
||||
{
|
||||
|
|
217
Alc/mixer.c
217
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]; \
|
||||
|
@ -239,59 +236,6 @@ static void Mix_Hrtf_##sampler(ALsource *Source, ALCdevice *Device, \
|
|||
Coeffs[0][1] * right; \
|
||||
} \
|
||||
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; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
|
@ -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; \
|
||||
\
|
||||
for(out = 0;out < Device->NumAuxSends;out++) \
|
||||
increment = Source->Params.Step; \
|
||||
\
|
||||
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; \
|
||||
pos = 0; \
|
||||
frac = srcfrac; \
|
||||
\
|
||||
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++) \
|
||||
if(OutPos == 0) \
|
||||
{ \
|
||||
pos = 0; \
|
||||
frac = srcfrac; \
|
||||
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 = 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);\
|
||||
\
|
||||
value = lpFilter1PC(WetFilter, i, value); \
|
||||
WetPendingClicks[0] += value * WetSend; \
|
||||
} \
|
||||
OutPos -= BufferSize; \
|
||||
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(OutPos == SamplesToDo) \
|
||||
{ \
|
||||
value = sampler(data + pos*NumChannels + i, NumChannels,frac); \
|
||||
\
|
||||
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;
|
||||
|
|
|
@ -123,7 +123,8 @@ typedef struct ALsource
|
|||
|
||||
/** Current target parameters used for mixing. */
|
||||
struct {
|
||||
MixerFunc DoMix;
|
||||
DryMixerFunc DryMix;
|
||||
WetMixerFunc WetMix;
|
||||
|
||||
ALint Step;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue