From 0c49e5ba56bb9b944ea3a55ce34a7ecc69832f38 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 14 Aug 2010 22:59:55 -0700 Subject: Use click removal when starting a source --- Alc/mixer.c | 42 ++++++++++++++++++++++++++++++++++++++++++ OpenAL32/Include/alFilter.h | 37 +++++++++++++++++++++++++++++++++++++ OpenAL32/alSource.c | 6 +----- 3 files changed, 80 insertions(+), 5 deletions(-) diff --git a/Alc/mixer.c b/Alc/mixer.c index 08b501c4..2abaa8ce 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -96,6 +96,7 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext, ALfloat DrySend[OUTPUTCHANNELS]; ALfloat dryGainStep[OUTPUTCHANNELS]; ALfloat wetGainStep[MAX_SENDS]; + ALfloat *ClickRemoval; ALuint i, j, out; ALfloat value, outsamp; ALbufferlistitem *BufferListItem; @@ -140,6 +141,7 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext, WetSend[i] = ALSource->WetGains[i]; } + ClickRemoval = ALContext->Device->ClickRemoval; /* Compute the gain steps for each output channel */ DeviceFreq = ALContext->Device->Frequency; @@ -245,6 +247,20 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext, if(Channels == 1) /* Mono */ { #define DO_MIX(resampler) do { \ + if(j == 0 && ALSource->FirstStart) \ + { \ + value = (resampler)(Data[DataPosInt], Data[DataPosInt+1], \ + DataPosFrac); \ + outsamp = lpFilter4PC(DryFilter, 0, value) * -1.0f; \ + ClickRemoval[FRONT_LEFT] += outsamp*DrySend[FRONT_LEFT]; \ + ClickRemoval[FRONT_RIGHT] += outsamp*DrySend[FRONT_RIGHT]; \ + ClickRemoval[SIDE_LEFT] += outsamp*DrySend[SIDE_LEFT]; \ + ClickRemoval[SIDE_RIGHT] += outsamp*DrySend[SIDE_RIGHT]; \ + ClickRemoval[BACK_LEFT] += outsamp*DrySend[BACK_LEFT]; \ + ClickRemoval[BACK_RIGHT] += outsamp*DrySend[BACK_RIGHT]; \ + ClickRemoval[FRONT_CENTER] += outsamp*DrySend[FRONT_CENTER]; \ + ClickRemoval[BACK_CENTER] += outsamp*DrySend[BACK_CENTER]; \ + } \ while(BufferSize--) \ { \ for(i = 0;i < OUTPUTCHANNELS;i++) \ @@ -305,6 +321,20 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext, }; #define DO_MIX(resampler) do { \ + if(j == 0 && ALSource->FirstStart) \ + { \ + for(i = 0;i < Channels;i++) \ + { \ + value = (resampler)(Data[DataPosInt*Channels + i], \ + Data[(DataPosInt+1)*Channels + i], \ + DataPosFrac); \ + \ + outsamp = lpFilter2PC(DryFilter, chans[i]*2, value) * -1.0f; \ + ClickRemoval[chans[i]] += outsamp*DrySend[chans[i]]; \ + ClickRemoval[chans2[i*2+0]] += outsamp*DrySend[chans2[i*2+0]]; \ + ClickRemoval[chans2[i*2+1]] += outsamp*DrySend[chans2[i*2+1]]; \ + } \ + } \ const ALfloat scaler = 1.0f/Channels; \ while(BufferSize--) \ { \ @@ -360,6 +390,18 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext, }; #define DO_MIX(resampler) do { \ + if(j == 0 && ALSource->FirstStart) \ + { \ + for(i = 0;i < Channels;i++) \ + { \ + value = (resampler)(Data[DataPosInt*Channels + i], \ + Data[(DataPosInt+1)*Channels + i], \ + DataPosFrac); \ + \ + outsamp = lpFilter2PC(DryFilter, chans[i]*2, value) * -1.0f; \ + ClickRemoval[chans[i]] += outsamp*DrySend[chans[i]]; \ + } \ + } \ const ALfloat scaler = 1.0f/Channels; \ while(BufferSize--) \ { \ diff --git a/OpenAL32/Include/alFilter.h b/OpenAL32/Include/alFilter.h index 9f420d35..ef852d13 100644 --- a/OpenAL32/Include/alFilter.h +++ b/OpenAL32/Include/alFilter.h @@ -61,6 +61,43 @@ static __inline ALfloat lpFilter1P(FILTER *iir, ALuint offset, ALfloat input) return output; } +static __inline ALfloat lpFilter4PC(const FILTER *iir, ALuint offset, ALfloat input) +{ + const ALfloat *history = &iir->history[offset]; + ALfloat a = iir->coeff; + ALfloat output = input; + + output = output + (history[0]-output)*a; + output = output + (history[1]-output)*a; + output = output + (history[2]-output)*a; + output = output + (history[3]-output)*a; + + return output; +} + +static __inline ALfloat lpFilter2PC(const FILTER *iir, ALuint offset, ALfloat input) +{ + const ALfloat *history = &iir->history[offset]; + ALfloat a = iir->coeff; + ALfloat output = input; + + output = output + (history[0]-output)*a; + output = output + (history[1]-output)*a; + + return output; +} + +static __inline ALfloat lpFilter1PC(FILTER *iir, ALuint offset, ALfloat input) +{ + const ALfloat *history = &iir->history[offset]; + ALfloat a = iir->coeff; + ALfloat output = input; + + output = output + (history[0]-output)*a; + + return output; +} + /* Calculates the low-pass filter coefficient given the pre-scaled gain and * cos(w) value. Note that g should be pre-scaled (sqr(gain) for one-pole, * sqrt(gain) for four-pole, etc) */ diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 1e320e19..5435e5d0 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -1366,11 +1366,7 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) if(Source->lOffset) ApplyOffset(Source); - if(Source->BuffersPlayed == 0 && Source->position == 0 && - Source->position_fraction == 0) - Source->FirstStart = AL_TRUE; - else - Source->FirstStart = AL_FALSE; + Source->FirstStart = AL_TRUE; // If device is disconnected, go right to stopped if(!Context->Device->Connected) -- cgit v1.2.3