aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/mixer.c
diff options
context:
space:
mode:
Diffstat (limited to 'Alc/mixer.c')
-rw-r--r--Alc/mixer.c99
1 files changed, 91 insertions, 8 deletions
diff --git a/Alc/mixer.c b/Alc/mixer.c
index ddcf6f6b..4688c89e 100644
--- a/Alc/mixer.c
+++ b/Alc/mixer.c
@@ -401,6 +401,19 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam
OutPos = 0;
do {
ALuint SrcBufferSize, DstBufferSize;
+ ALuint Counter;
+ ALfloat Delta;
+
+ if(!voice->Moving)
+ {
+ Counter = 0;
+ Delta = 0.0f;
+ }
+ else
+ {
+ Counter = SamplesToDo - OutPos;
+ Delta = 1.0f / (ALfloat)Counter;
+ }
/* Figure out how many buffer samples will be needed */
DataSize64 = SamplesToDo-OutPos;
@@ -549,10 +562,46 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam
parms->Filters[chan].ActiveType
);
if(!voice->IsHrtf)
- MixSamples(samples, parms->OutChannels, parms->OutBuffer, parms->Gains[chan],
- parms->Counter, OutPos, DstBufferSize);
+ {
+ ALfloat *restrict currents = parms->Gains[chan].Current;
+ const ALfloat *targets = parms->Gains[chan].Target;
+ MixGains gains[MAX_OUTPUT_CHANNELS];
+
+ if(!Counter)
+ {
+ for(j = 0;j < parms->OutChannels;j++)
+ {
+ gains[j].Target = targets[j];
+ gains[j].Current = gains[j].Target;
+ gains[j].Step = 0.0f;
+ }
+ }
+ else
+ {
+ for(j = 0;j < parms->OutChannels;j++)
+ {
+ ALfloat diff;
+ gains[j].Target = targets[j];
+ gains[j].Current = currents[j];
+ diff = gains[j].Target - gains[j].Current;
+ if(fabsf(diff) >= GAIN_SILENCE_THRESHOLD)
+ gains[j].Step = diff * Delta;
+ else
+ {
+ gains[j].Current = gains[j].Target;
+ gains[j].Step = 0.0f;
+ }
+ }
+ }
+
+ MixSamples(samples, parms->OutChannels, parms->OutBuffer, gains,
+ Counter, OutPos, DstBufferSize);
+
+ for(j = 0;j < parms->OutChannels;j++)
+ currents[j] = gains[j].Current;
+ }
else
- MixHrtfSamples(parms->OutBuffer, samples, parms->Counter, voice->Offset,
+ MixHrtfSamples(parms->OutBuffer, samples, parms->HrtfCounter, voice->Offset,
OutPos, IrSize, &parms->Hrtf[chan].Params,
&parms->Hrtf[chan].State, DstBufferSize);
}
@@ -560,6 +609,9 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam
for(j = 0;j < Device->NumAuxSends;j++)
{
SendParams *parms = &voice->Send[j];
+ ALfloat *restrict currents = parms->Gains[chan].Current;
+ const ALfloat *targets = parms->Gains[chan].Target;
+ MixGains gains[MAX_OUTPUT_CHANNELS];
const ALfloat *samples;
if(!parms->OutBuffer)
@@ -570,8 +622,39 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam
Device->FilteredData, ResampledData, DstBufferSize,
parms->Filters[chan].ActiveType
);
- MixSamples(samples, parms->OutChannels, parms->OutBuffer, parms->Gains[chan],
- parms->Counter, OutPos, DstBufferSize);
+
+ if(!Counter)
+ {
+ for(j = 0;j < parms->OutChannels;j++)
+ {
+ gains[j].Target = targets[j];
+ gains[j].Current = gains[j].Target;
+ gains[j].Step = 0.0f;
+ }
+ }
+ else
+ {
+ for(j = 0;j < parms->OutChannels;j++)
+ {
+ ALfloat diff;
+ gains[j].Target = targets[j];
+ gains[j].Current = currents[j];
+ diff = gains[j].Target - gains[j].Current;
+ if(fabsf(diff) >= GAIN_SILENCE_THRESHOLD)
+ gains[j].Step = diff * Delta;
+ else
+ {
+ gains[j].Current = gains[j].Target;
+ gains[j].Step = 0.0f;
+ }
+ }
+ }
+
+ MixSamples(samples, parms->OutChannels, parms->OutBuffer, gains,
+ Counter, OutPos, DstBufferSize);
+
+ for(j = 0;j < parms->OutChannels;j++)
+ currents[j] = gains[j].Current;
}
}
/* Update positions */
@@ -581,9 +664,7 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam
OutPos += DstBufferSize;
voice->Offset += DstBufferSize;
- voice->Direct.Counter = maxu(voice->Direct.Counter, DstBufferSize) - DstBufferSize;
- for(j = 0;j < Device->NumAuxSends;j++)
- voice->Send[j].Counter = maxu(voice->Send[j].Counter, DstBufferSize) - DstBufferSize;
+ voice->Direct.HrtfCounter = maxu(voice->Direct.HrtfCounter, DstBufferSize) - DstBufferSize;
/* Handle looping sources */
while(1)
@@ -630,6 +711,8 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam
}
} while(State == AL_PLAYING && OutPos < SamplesToDo);
+ voice->Moving = AL_TRUE;
+
/* Update source info */
Source->state = State;
ATOMIC_STORE(&Source->current_buffer, BufferListItem);