Apply high-pass source filters as needed
This commit is contained in:
@@ -281,9 +281,10 @@ ALvoid CalcNonAttnSourceParams(ALactivesource *src, const ALCcontext *ALContext)
|
||||
ALfloat SourceVolume,ListenerGain,MinVolume,MaxVolume;
|
||||
ALbufferlistitem *BufferListItem;
|
||||
enum FmtChannels Channels;
|
||||
ALfloat DryGain, DryGainHF;
|
||||
ALfloat DryGain, DryGainHF, DryGainLF;
|
||||
ALfloat WetGain[MAX_SENDS];
|
||||
ALfloat WetGainHF[MAX_SENDS];
|
||||
ALfloat WetGainLF[MAX_SENDS];
|
||||
ALint NumSends, Frequency;
|
||||
const struct ChanMap *chans = NULL;
|
||||
enum Resampler Resampler;
|
||||
@@ -349,11 +350,13 @@ ALvoid CalcNonAttnSourceParams(ALactivesource *src, const ALCcontext *ALContext)
|
||||
DryGain = clampf(SourceVolume, MinVolume, MaxVolume);
|
||||
DryGain *= ALSource->Direct.Gain * ListenerGain;
|
||||
DryGainHF = ALSource->Direct.GainHF;
|
||||
DryGainLF = ALSource->Direct.GainLF;
|
||||
for(i = 0;i < NumSends;i++)
|
||||
{
|
||||
WetGain[i] = clampf(SourceVolume, MinVolume, MaxVolume);
|
||||
WetGain[i] *= ALSource->Send[i].Gain * ListenerGain;
|
||||
WetGainHF[i] = ALSource->Send[i].GainHF;
|
||||
WetGainLF[i] = ALSource->Send[i].GainLF;
|
||||
}
|
||||
|
||||
switch(Channels)
|
||||
@@ -582,27 +585,43 @@ ALvoid CalcNonAttnSourceParams(ALactivesource *src, const ALCcontext *ALContext)
|
||||
|
||||
{
|
||||
ALfloat gainhf = maxf(0.01f, DryGainHF);
|
||||
ALfloat gainlf = maxf(0.01f, DryGainLF);
|
||||
ALfloat hfscale = ALSource->Direct.HFReference / Frequency;
|
||||
ALfloat lfscale = ALSource->Direct.LFReference / Frequency;
|
||||
for(c = 0;c < num_channels;c++)
|
||||
{
|
||||
src->Direct.Filters[c] = (gainhf != 1.0f) ? AF_LowPass : AF_None;
|
||||
src->Direct.Filters[c] = (gainhf != 1.0f && gainlf != 1.0f) ? AF_BandPass :
|
||||
(gainhf != 1.0f) ? AF_LowPass :
|
||||
(gainlf != 1.0f) ? AF_HighPass : AF_None;
|
||||
ALfilterState_setParams(
|
||||
&src->Direct.LpFilter[c], ALfilterType_HighShelf, gainhf,
|
||||
hfscale, 0.0f
|
||||
);
|
||||
ALfilterState_setParams(
|
||||
&src->Direct.HpFilter[c], ALfilterType_LowShelf, gainlf,
|
||||
lfscale, 0.0f
|
||||
);
|
||||
}
|
||||
}
|
||||
for(i = 0;i < NumSends;i++)
|
||||
{
|
||||
ALfloat gainhf = maxf(0.01f, WetGainHF[i]);
|
||||
ALfloat gainlf = maxf(0.01f, WetGainLF[i]);
|
||||
ALfloat hfscale = ALSource->Send[i].HFReference / Frequency;
|
||||
ALfloat lfscale = ALSource->Send[i].LFReference / Frequency;
|
||||
for(c = 0;c < num_channels;c++)
|
||||
{
|
||||
src->Send[i].Filters[c] = (gainhf != 1.0f) ? AF_LowPass : AF_None;
|
||||
src->Send[i].Filters[c] = (gainhf != 1.0f && gainlf != 1.0f) ? AF_BandPass :
|
||||
(gainhf != 1.0f) ? AF_LowPass :
|
||||
(gainlf != 1.0f) ? AF_HighPass : AF_None;
|
||||
ALfilterState_setParams(
|
||||
&src->Send[i].LpFilter[c], ALfilterType_HighShelf, gainhf,
|
||||
hfscale, 0.0f
|
||||
);
|
||||
ALfilterState_setParams(
|
||||
&src->Send[i].HpFilter[c], ALfilterType_LowShelf, gainlf,
|
||||
lfscale, 0.0f
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -627,9 +646,11 @@ ALvoid CalcSourceParams(ALactivesource *src, const ALCcontext *ALContext)
|
||||
ALfloat DecayDistance[MAX_SENDS];
|
||||
ALfloat DryGain;
|
||||
ALfloat DryGainHF;
|
||||
ALfloat DryGainLF;
|
||||
ALboolean DryGainHFAuto;
|
||||
ALfloat WetGain[MAX_SENDS];
|
||||
ALfloat WetGainHF[MAX_SENDS];
|
||||
ALfloat WetGainLF[MAX_SENDS];
|
||||
ALboolean WetGainAuto;
|
||||
ALboolean WetGainHFAuto;
|
||||
enum Resampler Resampler;
|
||||
@@ -639,8 +660,12 @@ ALvoid CalcSourceParams(ALactivesource *src, const ALCcontext *ALContext)
|
||||
ALint i, j;
|
||||
|
||||
DryGainHF = 1.0f;
|
||||
DryGainLF = 1.0f;
|
||||
for(i = 0;i < MAX_SENDS;i++)
|
||||
{
|
||||
WetGainHF[i] = 1.0f;
|
||||
WetGainLF[i] = 1.0f;
|
||||
}
|
||||
|
||||
/* Get context/device properties */
|
||||
DopplerFactor = ALContext->DopplerFactor * ALSource->DopplerFactor;
|
||||
@@ -885,10 +910,12 @@ ALvoid CalcSourceParams(ALactivesource *src, const ALCcontext *ALContext)
|
||||
/* Apply gain and frequency filters */
|
||||
DryGain *= ALSource->Direct.Gain * ListenerGain;
|
||||
DryGainHF *= ALSource->Direct.GainHF;
|
||||
DryGainLF *= ALSource->Direct.GainLF;
|
||||
for(i = 0;i < NumSends;i++)
|
||||
{
|
||||
WetGain[i] *= ALSource->Send[i].Gain * ListenerGain;
|
||||
WetGainHF[i] *= ALSource->Send[i].GainHF;
|
||||
WetGainLF[i] *= ALSource->Send[i].GainLF;
|
||||
}
|
||||
|
||||
/* Calculate velocity-based doppler effect */
|
||||
@@ -1089,22 +1116,38 @@ ALvoid CalcSourceParams(ALactivesource *src, const ALCcontext *ALContext)
|
||||
|
||||
{
|
||||
ALfloat gainhf = maxf(0.01f, DryGainHF);
|
||||
ALfloat gainlf = maxf(0.01f, DryGainLF);
|
||||
ALfloat hfscale = ALSource->Direct.HFReference / Frequency;
|
||||
src->Direct.Filters[0] = (gainhf != 1.0f) ? AF_LowPass : AF_None;
|
||||
ALfloat lfscale = ALSource->Direct.LFReference / Frequency;
|
||||
src->Direct.Filters[0] = (gainhf != 1.0f && gainlf != 1.0f) ? AF_BandPass :
|
||||
(gainhf != 1.0f) ? AF_LowPass :
|
||||
(gainlf != 1.0f) ? AF_HighPass : AF_None;
|
||||
ALfilterState_setParams(
|
||||
&src->Direct.LpFilter[0], ALfilterType_HighShelf, gainhf,
|
||||
hfscale, 0.0f
|
||||
);
|
||||
ALfilterState_setParams(
|
||||
&src->Direct.HpFilter[0], ALfilterType_LowShelf, gainlf,
|
||||
lfscale, 0.0f
|
||||
);
|
||||
}
|
||||
for(i = 0;i < NumSends;i++)
|
||||
{
|
||||
ALfloat gainhf = maxf(0.01f, WetGainHF[i]);
|
||||
ALfloat gainlf = maxf(0.01f, WetGainLF[i]);
|
||||
ALfloat hfscale = ALSource->Send[i].HFReference / Frequency;
|
||||
src->Direct.Filters[0] = (gainhf != 1.0f) ? AF_LowPass : AF_None;
|
||||
ALfloat lfscale = ALSource->Send[i].LFReference / Frequency;
|
||||
src->Direct.Filters[0] = (gainhf != 1.0f && gainlf != 1.0f) ? AF_BandPass :
|
||||
(gainhf != 1.0f) ? AF_LowPass :
|
||||
(gainlf != 1.0f) ? AF_HighPass : AF_None;
|
||||
ALfilterState_setParams(
|
||||
&src->Send[i].LpFilter[0], ALfilterType_HighShelf, gainhf,
|
||||
hfscale, 0.0f
|
||||
);
|
||||
ALfilterState_setParams(
|
||||
&src->Send[i].HpFilter[0], ALfilterType_LowShelf, gainlf,
|
||||
lfscale, 0.0f
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+20
-5
@@ -84,7 +84,8 @@ static void SilenceData(ALfloat *dst, ALuint samples)
|
||||
}
|
||||
|
||||
|
||||
static void DoFilters(ALfilterState *lpfilter, ALfloat *restrict dst, const ALfloat *restrict src,
|
||||
static void DoFilters(ALfilterState *lpfilter, ALfilterState *hpfilter,
|
||||
ALfloat *restrict dst, const ALfloat *restrict src,
|
||||
ALuint numsamples, enum ActiveFilters type)
|
||||
{
|
||||
ALuint i;
|
||||
@@ -98,6 +99,18 @@ static void DoFilters(ALfilterState *lpfilter, ALfloat *restrict dst, const ALfl
|
||||
for(i = 0;i < numsamples;i++)
|
||||
dst[i] = ALfilterState_processSingle(lpfilter, src[i]);
|
||||
break;
|
||||
|
||||
case AF_HighPass:
|
||||
for(i = 0;i < numsamples;i++)
|
||||
dst[i] = ALfilterState_processSingle(hpfilter, src[i]);
|
||||
break;
|
||||
|
||||
case AF_BandPass:
|
||||
for(i = 0;i < numsamples;i++)
|
||||
dst[i] = ALfilterState_processSingle(hpfilter,
|
||||
ALfilterState_processSingle(lpfilter, src[i])
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,8 +345,9 @@ ALvoid MixSource(ALactivesource *src, ALCdevice *Device, ALuint SamplesToDo)
|
||||
{
|
||||
DirectParams *directparms = &src->Direct;
|
||||
|
||||
DoFilters(&directparms->LpFilter[chan], SrcData, ResampledData,
|
||||
DstBufferSize, directparms->Filters[chan]);
|
||||
DoFilters(&directparms->LpFilter[chan], &directparms->HpFilter[chan],
|
||||
SrcData, ResampledData, DstBufferSize,
|
||||
directparms->Filters[chan]);
|
||||
src->DryMix(directparms, SrcData, chan, OutPos, DstBufferSize);
|
||||
}
|
||||
|
||||
@@ -343,8 +357,9 @@ ALvoid MixSource(ALactivesource *src, ALCdevice *Device, ALuint SamplesToDo)
|
||||
if(!sendparms->OutBuffer)
|
||||
continue;
|
||||
|
||||
DoFilters(&sendparms->LpFilter[chan], SrcData, ResampledData,
|
||||
DstBufferSize, sendparms->Filters[chan]);
|
||||
DoFilters(&sendparms->LpFilter[chan], &sendparms->HpFilter[chan],
|
||||
SrcData, ResampledData, DstBufferSize,
|
||||
sendparms->Filters[chan]);
|
||||
src->WetMix(sendparms, SrcData, OutPos, DstBufferSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,12 +109,16 @@ typedef struct ALsource {
|
||||
ALfloat Gain;
|
||||
ALfloat GainHF;
|
||||
ALfloat HFReference;
|
||||
ALfloat GainLF;
|
||||
ALfloat LFReference;
|
||||
} Direct;
|
||||
struct {
|
||||
struct ALeffectslot *Slot;
|
||||
ALfloat Gain;
|
||||
ALfloat GainHF;
|
||||
ALfloat HFReference;
|
||||
ALfloat GainLF;
|
||||
ALfloat LFReference;
|
||||
} Send[MAX_SENDS];
|
||||
|
||||
/** Source needs to update its mixing parameters. */
|
||||
|
||||
@@ -42,6 +42,8 @@ extern "C" {
|
||||
enum ActiveFilters {
|
||||
AF_None = 0,
|
||||
AF_LowPass = 1,
|
||||
AF_HighPass = 2,
|
||||
AF_BandPass = AF_LowPass | AF_HighPass
|
||||
};
|
||||
|
||||
typedef struct HrtfState {
|
||||
@@ -61,6 +63,7 @@ typedef struct DirectParams {
|
||||
|
||||
enum ActiveFilters Filters[MAX_INPUT_CHANNELS];
|
||||
ALfilterState LpFilter[MAX_INPUT_CHANNELS];
|
||||
ALfilterState HpFilter[MAX_INPUT_CHANNELS];
|
||||
|
||||
/* If not 'moving', gain/coefficients are set directly without fading. */
|
||||
ALboolean Moving;
|
||||
@@ -94,6 +97,7 @@ typedef struct SendParams {
|
||||
|
||||
enum ActiveFilters Filters[MAX_INPUT_CHANNELS];
|
||||
ALfilterState LpFilter[MAX_INPUT_CHANNELS];
|
||||
ALfilterState HpFilter[MAX_INPUT_CHANNELS];
|
||||
|
||||
ALboolean Moving;
|
||||
ALuint Counter;
|
||||
|
||||
@@ -666,12 +666,16 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp p
|
||||
Source->Direct.Gain = 1.0f;
|
||||
Source->Direct.GainHF = 1.0f;
|
||||
Source->Direct.HFReference = LOWPASSFREQREF;
|
||||
Source->Direct.GainLF = 1.0f;
|
||||
Source->Direct.LFReference = HIGHPASSFREQREF;
|
||||
}
|
||||
else
|
||||
{
|
||||
Source->Direct.Gain = filter->Gain;
|
||||
Source->Direct.GainHF = filter->GainHF;
|
||||
Source->Direct.HFReference = filter->HFReference;
|
||||
Source->Direct.GainLF = filter->GainLF;
|
||||
Source->Direct.LFReference = filter->LFReference;
|
||||
}
|
||||
UnlockContext(Context);
|
||||
Source->NeedsUpdate = AL_TRUE;
|
||||
@@ -741,12 +745,16 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp p
|
||||
Source->Send[values[1]].Gain = 1.0f;
|
||||
Source->Send[values[1]].GainHF = 1.0f;
|
||||
Source->Send[values[1]].HFReference = LOWPASSFREQREF;
|
||||
Source->Send[values[1]].GainLF = 1.0f;
|
||||
Source->Send[values[1]].LFReference = HIGHPASSFREQREF;
|
||||
}
|
||||
else
|
||||
{
|
||||
Source->Send[values[1]].Gain = filter->Gain;
|
||||
Source->Send[values[1]].GainHF = filter->GainHF;
|
||||
Source->Send[values[1]].HFReference = filter->HFReference;
|
||||
Source->Send[values[1]].GainLF = filter->GainLF;
|
||||
Source->Send[values[1]].LFReference = filter->LFReference;
|
||||
}
|
||||
Source->NeedsUpdate = AL_TRUE;
|
||||
UnlockContext(Context);
|
||||
@@ -2319,11 +2327,15 @@ static ALvoid InitSourceParams(ALsource *Source)
|
||||
Source->Direct.Gain = 1.0f;
|
||||
Source->Direct.GainHF = 1.0f;
|
||||
Source->Direct.HFReference = LOWPASSFREQREF;
|
||||
Source->Direct.GainLF = 1.0f;
|
||||
Source->Direct.LFReference = HIGHPASSFREQREF;
|
||||
for(i = 0;i < MAX_SENDS;i++)
|
||||
{
|
||||
Source->Send[i].Gain = 1.0f;
|
||||
Source->Send[i].GainHF = 1.0f;
|
||||
Source->Send[i].HFReference = LOWPASSFREQREF;
|
||||
Source->Send[i].GainLF = 1.0f;
|
||||
Source->Send[i].LFReference = HIGHPASSFREQREF;
|
||||
}
|
||||
|
||||
Source->NeedsUpdate = AL_TRUE;
|
||||
|
||||
Reference in New Issue
Block a user