aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2010-08-16 14:53:21 -0700
committerChris Robinson <[email protected]>2010-08-16 14:53:21 -0700
commite5cae875020ceced4a62557c230bb58a67fbe036 (patch)
treebde1be117497e1123db891278c36a3309a21df1d
parentba0ec1b4bac81fc636efb2881261dcf6516f85ba (diff)
Handle clicks by watching changes between updates
-rw-r--r--Alc/ALc.c3
-rw-r--r--Alc/mixer.c148
-rw-r--r--OpenAL32/Include/alAuxEffectSlot.h1
-rw-r--r--OpenAL32/Include/alMain.h1
-rw-r--r--OpenAL32/alAuxEffectSlot.c3
5 files changed, 110 insertions, 46 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 7e94895b..d05bbebc 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -902,7 +902,10 @@ static ALCboolean UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
device->SamplesPlayed /= oldRate;
for(i = 0;i < OUTPUTCHANNELS;i++)
+ {
device->ClickRemoval[i] = 0.0f;
+ device->PendingClicks[i] = 0.0f;
+ }
for(i = 0;i < device->NumContexts;i++)
{
diff --git a/Alc/mixer.c b/Alc/mixer.c
index e73d6aac..e454d553 100644
--- a/Alc/mixer.c
+++ b/Alc/mixer.c
@@ -90,11 +90,9 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext,
static ALfloat DummyClickRemoval[OUTPUTCHANNELS];
ALfloat *WetBuffer[MAX_SENDS];
ALfloat DrySend[OUTPUTCHANNELS];
- ALfloat dryGainDiff[OUTPUTCHANNELS];
- ALfloat wetGainDiff[MAX_SENDS];
- ALboolean UpdateClick;
+ ALfloat *ClickRemoval, *PendingClicks;
ALfloat *WetClickRemoval[MAX_SENDS];
- ALfloat *ClickRemoval;
+ ALfloat *WetPendingClicks[MAX_SENDS];
ALuint i, j, out;
ALfloat value, outsamp;
ALbufferlistitem *BufferListItem;
@@ -108,30 +106,13 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext,
ALboolean Looping;
ALenum State;
- UpdateClick = (ALSource->FirstStart || ALSource->NeedsUpdate);
ClickRemoval = ALContext->Device->ClickRemoval;
-
- if(ALSource->FirstStart)
- {
- /* When starting, assume a previous gain of 0 */
- for(i = 0;i < OUTPUTCHANNELS;i++)
- DrySend[i] = 0.0f;
- for(i = 0;i < MAX_SENDS;i++)
- WetSend[i] = 0.0f;
- }
- else
- {
- for(i = 0;i < OUTPUTCHANNELS;i++)
- DrySend[i] = ALSource->Params.DryGains[i];
- for(i = 0;i < MAX_SENDS;i++)
- WetSend[i] = ALSource->Params.WetGains[i];
- }
+ PendingClicks = ALContext->Device->PendingClicks;
if(ALSource->NeedsUpdate)
{
ALsource_Update(ALSource, ALContext);
ALSource->NeedsUpdate = AL_FALSE;
- UpdateClick = AL_TRUE;
}
/* Get source info */
@@ -143,15 +124,9 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext,
Looping = ALSource->bLooping;
for(i = 0;i < OUTPUTCHANNELS;i++)
- {
- dryGainDiff[i] = DrySend[i] - ALSource->Params.DryGains[i];
DrySend[i] = ALSource->Params.DryGains[i];
- }
for(i = 0;i < MAX_SENDS;i++)
- {
- wetGainDiff[i] = WetSend[i] - ALSource->Params.WetGains[i];
WetSend[i] = ALSource->Params.WetGains[i];
- }
/* Get fixed point step */
increment = ALSource->Params.Step;
@@ -166,6 +141,9 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext,
WetClickRemoval[i] = (ALSource->Send[i].Slot ?
ALSource->Send[i].Slot->ClickRemoval :
DummyClickRemoval);
+ WetPendingClicks[i] = (ALSource->Send[i].Slot ?
+ ALSource->Send[i].Slot->PendingClicks :
+ DummyClickRemoval);
}
/* Get current buffer queue item */
@@ -248,24 +226,25 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext,
if(Channels == 1) /* Mono */
{
#define DO_MIX(resampler) do { \
- if(j == 0 && UpdateClick) \
+ if(j == 0) \
{ \
value = (resampler)(Data[DataPosInt], Data[DataPosInt+1], \
DataPosFrac); \
+ \
outsamp = lpFilter4PC(DryFilter, 0, value); \
- ClickRemoval[FRONT_LEFT] += outsamp*dryGainDiff[FRONT_LEFT]; \
- ClickRemoval[FRONT_RIGHT] += outsamp*dryGainDiff[FRONT_RIGHT]; \
- ClickRemoval[SIDE_LEFT] += outsamp*dryGainDiff[SIDE_LEFT]; \
- ClickRemoval[SIDE_RIGHT] += outsamp*dryGainDiff[SIDE_RIGHT]; \
- ClickRemoval[BACK_LEFT] += outsamp*dryGainDiff[BACK_LEFT]; \
- ClickRemoval[BACK_RIGHT] += outsamp*dryGainDiff[BACK_RIGHT]; \
- ClickRemoval[FRONT_CENTER] += outsamp*dryGainDiff[FRONT_CENTER]; \
- ClickRemoval[BACK_CENTER] += outsamp*dryGainDiff[BACK_CENTER]; \
+ 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]; \
\
for(out = 0;out < MAX_SENDS;out++) \
{ \
outsamp = lpFilter2PC(WetFilter[out], 0, value); \
- WetClickRemoval[out][0] += outsamp*wetGainDiff[out]; \
+ WetClickRemoval[out][0] -= outsamp*WetSend[out]; \
} \
} \
while(BufferSize--) \
@@ -297,6 +276,29 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext,
DataPosFrac &= FRACTIONMASK; \
j++; \
} \
+ if(j == SamplesToDo) \
+ { \
+ ALuint pos = ((DataPosInt < DataSize) ? DataPosInt : (DataPosInt-1)); \
+ ALuint frac = ((DataPosInt < DataSize) ? DataPosFrac : \
+ ((DataPosFrac-increment)&FRACTIONMASK)); \
+ value = (resampler)(Data[pos], Data[pos+1], frac); \
+ \
+ outsamp = lpFilter4PC(DryFilter, 0, value); \
+ PendingClicks[FRONT_LEFT] += outsamp*DrySend[FRONT_LEFT]; \
+ PendingClicks[FRONT_RIGHT] += outsamp*DrySend[FRONT_RIGHT]; \
+ PendingClicks[SIDE_LEFT] += outsamp*DrySend[SIDE_LEFT]; \
+ PendingClicks[SIDE_RIGHT] += outsamp*DrySend[SIDE_RIGHT]; \
+ PendingClicks[BACK_LEFT] += outsamp*DrySend[BACK_LEFT]; \
+ PendingClicks[BACK_RIGHT] += outsamp*DrySend[BACK_RIGHT]; \
+ PendingClicks[FRONT_CENTER] += outsamp*DrySend[FRONT_CENTER]; \
+ PendingClicks[BACK_CENTER] += outsamp*DrySend[BACK_CENTER]; \
+ \
+ for(out = 0;out < MAX_SENDS;out++) \
+ { \
+ outsamp = lpFilter2PC(WetFilter[out], 0, value); \
+ WetPendingClicks[out][0] += outsamp*WetSend[out]; \
+ } \
+ } \
} while(0)
switch(Resampler)
@@ -324,7 +326,7 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext,
#define DO_MIX(resampler) do { \
const ALfloat scaler = 1.0f/Channels; \
- if(j == 0 && UpdateClick) \
+ if(j == 0) \
{ \
for(i = 0;i < Channels;i++) \
{ \
@@ -333,14 +335,14 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext,
DataPosFrac); \
\
outsamp = lpFilter2PC(DryFilter, chans[i]*2, value); \
- ClickRemoval[chans[i]] += outsamp*dryGainDiff[chans[i]]; \
- ClickRemoval[chans2[i*2+0]] += outsamp*dryGainDiff[chans2[i*2+0]];\
- ClickRemoval[chans2[i*2+1]] += outsamp*dryGainDiff[chans2[i*2+1]];\
+ 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]]; \
\
for(out = 0;out < MAX_SENDS;out++) \
{ \
outsamp = lpFilter1PC(WetFilter[out], chans[out], value) * scaler;\
- WetClickRemoval[out][0] += outsamp*wetGainDiff[out]; \
+ WetClickRemoval[out][0] -= outsamp*WetSend[out]; \
} \
} \
} \
@@ -369,6 +371,29 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext,
DataPosFrac &= FRACTIONMASK; \
j++; \
} \
+ if(j == SamplesToDo) \
+ { \
+ ALuint pos = ((DataPosInt < DataSize) ? DataPosInt : (DataPosInt-1)); \
+ ALuint frac = ((DataPosInt < DataSize) ? DataPosFrac : \
+ ((DataPosFrac-increment)&FRACTIONMASK)); \
+ for(i = 0;i < Channels;i++) \
+ { \
+ value = (resampler)(Data[pos*Channels + i], \
+ Data[(pos+1)*Channels + i], \
+ frac); \
+ \
+ outsamp = lpFilter2PC(DryFilter, chans[i]*2, value); \
+ PendingClicks[chans[i]] += outsamp*DrySend[chans[i]]; \
+ PendingClicks[chans2[i*2+0]] += outsamp*DrySend[chans2[i*2+0]]; \
+ PendingClicks[chans2[i*2+1]] += outsamp*DrySend[chans2[i*2+1]]; \
+ \
+ for(out = 0;out < MAX_SENDS;out++) \
+ { \
+ outsamp = lpFilter1PC(WetFilter[out], chans[out], value) * scaler;\
+ WetPendingClicks[out][0] += outsamp*WetSend[out]; \
+ } \
+ } \
+ } \
} while(0)
switch(Resampler)
@@ -394,7 +419,7 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext,
#define DO_MIX(resampler) do { \
const ALfloat scaler = 1.0f/Channels; \
- if(j == 0 && UpdateClick) \
+ if(j == 0) \
{ \
for(i = 0;i < Channels;i++) \
{ \
@@ -403,12 +428,12 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext,
DataPosFrac); \
\
outsamp = lpFilter2PC(DryFilter, chans[i]*2, value); \
- ClickRemoval[chans[i]] += outsamp*dryGainDiff[chans[i]]; \
+ ClickRemoval[chans[i]] -= outsamp*DrySend[chans[i]]; \
\
for(out = 0;out < MAX_SENDS;out++) \
{ \
outsamp = lpFilter1PC(WetFilter[out], chans[out], value) * scaler;\
- WetClickRemoval[out][0] += outsamp*wetGainDiff[out]; \
+ WetClickRemoval[out][0] -= outsamp*WetSend[out]; \
} \
} \
} \
@@ -435,6 +460,27 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext,
DataPosFrac &= FRACTIONMASK; \
j++; \
} \
+ if(j == SamplesToDo) \
+ { \
+ ALuint pos = ((DataPosInt < DataSize) ? DataPosInt : (DataPosInt-1)); \
+ ALuint frac = ((DataPosInt < DataSize) ? DataPosFrac : \
+ ((DataPosFrac-increment)&FRACTIONMASK)); \
+ for(i = 0;i < Channels;i++) \
+ { \
+ value = (resampler)(Data[pos*Channels + i], \
+ Data[(pos+1)*Channels + i], \
+ frac); \
+ \
+ outsamp = lpFilter2PC(DryFilter, chans[i]*2, value); \
+ PendingClicks[chans[i]] += outsamp*DrySend[chans[i]]; \
+ \
+ for(out = 0;out < MAX_SENDS;out++) \
+ { \
+ outsamp = lpFilter1PC(WetFilter[out], chans[out], value) * scaler;\
+ WetPendingClicks[out][0] += outsamp*WetSend[out]; \
+ } \
+ } \
+ } \
} while(0)
switch(Resampler)
@@ -631,6 +677,11 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
ClickRemoval[0] -= ClickRemoval[0] / 256.0f;
ALEffectSlot->WetBuffer[i] += ClickRemoval[0];
}
+ for(i = 0;i < 1;i++)
+ {
+ ALEffectSlot->ClickRemoval[i] += ALEffectSlot->PendingClicks[i];
+ ALEffectSlot->PendingClicks[i] = 0.0f;
+ }
ALEffect_Process(ALEffectSlot->EffectState, ALEffectSlot, SamplesToDo, ALEffectSlot->WetBuffer, DryBuffer);
@@ -652,6 +703,11 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
DryBuffer[i][c] += ClickRemoval[c];
}
}
+ for(i = 0;i < OUTPUTCHANNELS;i++)
+ {
+ device->ClickRemoval[i] += device->PendingClicks[i];
+ device->PendingClicks[i] = 0.0f;
+ }
ChanMap = device->DevChannels;
Matrix = device->ChannelMatrix;
diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h
index eb7351b2..92165d62 100644
--- a/OpenAL32/Include/alAuxEffectSlot.h
+++ b/OpenAL32/Include/alAuxEffectSlot.h
@@ -23,6 +23,7 @@ typedef struct ALeffectslot
ALfloat WetBuffer[BUFFERSIZE];
ALfloat ClickRemoval[1];
+ ALfloat PendingClicks[1];
ALuint refcount;
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 1aa3d03e..e5193f70 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -410,6 +410,7 @@ struct ALCdevice_struct
ALuint NumChan;
ALfloat ClickRemoval[OUTPUTCHANNELS];
+ ALfloat PendingClicks[OUTPUTCHANNELS];
// Contexts created on this device
ALCcontext **Contexts;
diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c
index a7ea0e32..d8ccaf71 100644
--- a/OpenAL32/alAuxEffectSlot.c
+++ b/OpenAL32/alAuxEffectSlot.c
@@ -89,7 +89,10 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo
for(j = 0;j < BUFFERSIZE;j++)
slot->WetBuffer[j] = 0.0f;
for(j = 0;j < 1;j++)
+ {
slot->ClickRemoval[j] = 0.0f;
+ slot->PendingClicks[j] = 0.0f;
+ }
slot->refcount = 0;
}
}