diff options
-rw-r--r-- | Alc/ALu.c | 53 | ||||
-rw-r--r-- | Alc/mixer.c | 25 | ||||
-rw-r--r-- | OpenAL32/Include/alSource.h | 4 | ||||
-rw-r--r-- | OpenAL32/Include/alu.h | 4 | ||||
-rw-r--r-- | OpenAL32/alSource.c | 12 |
5 files changed, 88 insertions, 10 deletions
@@ -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 + ); } } diff --git a/Alc/mixer.c b/Alc/mixer.c index ac433e35..32d4d308 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -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); } } diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 43e5bdf6..c3513525 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -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. */ diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index dd13a293..a3749ea1 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -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; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 16e3a930..7f8944a8 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -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; |