aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/mixvoice.cpp161
-rw-r--r--OpenAL32/Include/alu.h2
2 files changed, 89 insertions, 74 deletions
diff --git a/Alc/mixvoice.cpp b/Alc/mixvoice.cpp
index f68c0f0a..5b18d547 100644
--- a/Alc/mixvoice.cpp
+++ b/Alc/mixvoice.cpp
@@ -288,7 +288,7 @@ const ALfloat *DoFilters(BiquadFilter *lpfilter, BiquadFilter *hpfilter,
#define RESAMPLED_BUF 1
#define FILTERED_BUF 2
#define NFC_DATA_BUF 3
-ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsizei SamplesToDo)
+ALboolean MixSource(ALvoice *voice, const ALuint SourceID, ALCcontext *Context, const ALsizei SamplesToDo)
{
ASSUME(SamplesToDo > 0);
@@ -310,15 +310,60 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize
ASSUME(increment > 0);
ALCdevice *Device{Context->Device};
- ALsizei IrSize{Device->mHrtf ? Device->mHrtf->irSize : 0};
+ const ALsizei IrSize{Device->mHrtf ? Device->mHrtf->irSize : 0};
+ const ALsizei NumAuxSends{Device->NumAuxSends};
+ const int OutLIdx{GetChannelIdxByName(Device->RealOut, FrontLeft)};
+ const int OutRIdx{GetChannelIdxByName(Device->RealOut, FrontRight)};
+
+ ASSUME(IrSize >= 0);
+ ASSUME(NumAuxSends >= 0);
ResamplerFunc Resample{(increment == FRACTIONONE && DataPosFrac == 0) ?
Resample_copy_C : voice->Resampler};
ALsizei Counter{(voice->Flags&VOICE_IS_FADING) ? SamplesToDo : 0};
+ if(!Counter)
+ {
+ /* No fading, just overwrite the old/current params. */
+ for(ALsizei chan{0};chan < NumChannels;chan++)
+ {
+ DirectParams &parms = voice->Direct.Params[chan];
+ if(!(voice->Flags&VOICE_HAS_HRTF))
+ std::copy(std::begin(parms.Gains.Target), std::end(parms.Gains.Target),
+ std::begin(parms.Gains.Current));
+ else
+ parms.Hrtf.Old = parms.Hrtf.Target;
+ auto set_current = [chan](ALvoice::SendData &send) -> void
+ {
+ if(!send.Buffer)
+ return;
+
+ SendParams &parms = send.Params[chan];
+ std::copy(std::begin(parms.Gains.Target), std::end(parms.Gains.Target),
+ std::begin(parms.Gains.Current));
+ };
+ std::for_each(voice->Send, voice->Send+NumAuxSends, set_current);
+ }
+ }
+ else if((voice->Flags&VOICE_HAS_HRTF))
+ {
+ for(ALsizei chan{0};chan < NumChannels;chan++)
+ {
+ DirectParams &parms = voice->Direct.Params[chan];
+ if(!(parms.Hrtf.Old.Gain > GAIN_SILENCE_THRESHOLD))
+ {
+ /* The old HRTF params are silent, so overwrite the old
+ * coefficients with the new, and reset the old gain to 0. The
+ * future mix will then fade from silence.
+ */
+ parms.Hrtf.Old = parms.Hrtf.Target;
+ parms.Hrtf.Old.Gain = 0.0f;
+ }
+ }
+ }
+
ALsizei buffers_done{0};
ALsizei OutPos{0};
-
do {
/* Figure out how many buffer samples will be needed */
ALsizei DstBufferSize{SamplesToDo - OutPos};
@@ -504,43 +549,36 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize
Device->TempBuffer[RESAMPLED_BUF], DstBufferSize
)};
{
- DirectParams *parms{&voice->Direct.Params[chan]};
- const ALfloat *samples{DoFilters(&parms->LowPass, &parms->HighPass,
+ DirectParams &parms = voice->Direct.Params[chan];
+ const ALfloat *samples{DoFilters(&parms.LowPass, &parms.HighPass,
Device->TempBuffer[FILTERED_BUF], ResampledData, DstBufferSize,
voice->Direct.FilterType
)};
if(!(voice->Flags&VOICE_HAS_HRTF))
{
- if(!Counter)
- std::copy(std::begin(parms->Gains.Target), std::end(parms->Gains.Target),
- std::begin(parms->Gains.Current));
-
if(!(voice->Flags&VOICE_HAS_NFC))
MixSamples(samples, voice->Direct.Channels, voice->Direct.Buffer,
- parms->Gains.Current, parms->Gains.Target, Counter, OutPos,
- DstBufferSize
- );
+ parms.Gains.Current, parms.Gains.Target, Counter, OutPos,
+ DstBufferSize);
else
{
MixSamples(samples,
voice->Direct.ChannelsPerOrder[0], voice->Direct.Buffer,
- parms->Gains.Current, parms->Gains.Target, Counter, OutPos,
- DstBufferSize
- );
+ parms.Gains.Current, parms.Gains.Target, Counter, OutPos,
+ DstBufferSize);
ALfloat *nfcsamples{Device->TempBuffer[NFC_DATA_BUF]};
ALsizei chanoffset{voice->Direct.ChannelsPerOrder[0]};
using FilterProc = void (NfcFilter::*)(float*,const float*,int);
- auto apply_nfc = [voice,parms,samples,DstBufferSize,Counter,OutPos,&chanoffset,nfcsamples](FilterProc process, ALsizei order) -> void
+ auto apply_nfc = [voice,&parms,samples,DstBufferSize,Counter,OutPos,&chanoffset,nfcsamples](FilterProc process, ALsizei order) -> void
{
if(voice->Direct.ChannelsPerOrder[order] < 1)
return;
- (parms->NFCtrlFilter.*process)(nfcsamples, samples, DstBufferSize);
+ (parms.NFCtrlFilter.*process)(nfcsamples, samples, DstBufferSize);
MixSamples(nfcsamples, voice->Direct.ChannelsPerOrder[order],
- voice->Direct.Buffer+chanoffset, parms->Gains.Current+chanoffset,
- parms->Gains.Target+chanoffset, Counter, OutPos, DstBufferSize
- );
+ voice->Direct.Buffer+chanoffset, parms.Gains.Current+chanoffset,
+ parms.Gains.Target+chanoffset, Counter, OutPos, DstBufferSize);
chanoffset += voice->Direct.ChannelsPerOrder[order];
};
apply_nfc(&NfcFilter::process1, 1);
@@ -550,28 +588,12 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize
}
else
{
- const int lidx{GetChannelIdxByName(Device->RealOut, FrontLeft)};
- const int ridx{GetChannelIdxByName(Device->RealOut, FrontRight)};
- assert(lidx != -1 && ridx != -1);
-
ALsizei fademix{0};
- if(!Counter)
+ /* If fading, the old gain is not silence, and this is the
+ * first mixing pass, fade between the IRs.
+ */
+ if(Counter && (parms.Hrtf.Old.Gain > GAIN_SILENCE_THRESHOLD) && OutPos == 0)
{
- /* No fading, just overwrite the old HRTF params. */
- parms->Hrtf.Old = parms->Hrtf.Target;
- }
- else if(!(parms->Hrtf.Old.Gain > GAIN_SILENCE_THRESHOLD))
- {
- /* The old HRTF params are silent, so overwrite the old
- * coefficients with the new, and reset the old gain to
- * 0. The future mix will then fade from silence.
- */
- parms->Hrtf.Old = parms->Hrtf.Target;
- parms->Hrtf.Old.Gain = 0.0f;
- }
- else if(OutPos == 0)
- {
- /* First mixing pass, fade between the coefficients. */
fademix = mini(DstBufferSize, 128);
/* The new coefficients need to fade in completely
@@ -580,56 +602,54 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize
* and new target gains given how much of the fade time
* this mix handles.
*/
- ALfloat gain{lerp(parms->Hrtf.Old.Gain, parms->Hrtf.Target.Gain,
+ ALfloat gain{lerp(parms.Hrtf.Old.Gain, parms.Hrtf.Target.Gain,
minf(1.0f, (ALfloat)fademix/Counter))};
MixHrtfParams hrtfparams;
- hrtfparams.Coeffs = parms->Hrtf.Target.Coeffs;
- hrtfparams.Delay[0] = parms->Hrtf.Target.Delay[0];
- hrtfparams.Delay[1] = parms->Hrtf.Target.Delay[1];
+ hrtfparams.Coeffs = parms.Hrtf.Target.Coeffs;
+ hrtfparams.Delay[0] = parms.Hrtf.Target.Delay[0];
+ hrtfparams.Delay[1] = parms.Hrtf.Target.Delay[1];
hrtfparams.Gain = 0.0f;
hrtfparams.GainStep = gain / (ALfloat)fademix;
MixHrtfBlendSamples(
- voice->Direct.Buffer[lidx], voice->Direct.Buffer[ridx],
- samples, voice->Offset, OutPos, IrSize, &parms->Hrtf.Old,
- &hrtfparams, &parms->Hrtf.State, fademix
- );
+ voice->Direct.Buffer[OutLIdx], voice->Direct.Buffer[OutRIdx],
+ samples, voice->Offset, OutPos, IrSize, &parms.Hrtf.Old,
+ &hrtfparams, &parms.Hrtf.State, fademix);
/* Update the old parameters with the result. */
- parms->Hrtf.Old = parms->Hrtf.Target;
+ parms.Hrtf.Old = parms.Hrtf.Target;
if(fademix < Counter)
- parms->Hrtf.Old.Gain = hrtfparams.Gain;
+ parms.Hrtf.Old.Gain = hrtfparams.Gain;
}
if(fademix < DstBufferSize)
{
const ALsizei todo{DstBufferSize - fademix};
- ALfloat gain{parms->Hrtf.Target.Gain};
+ ALfloat gain{parms.Hrtf.Target.Gain};
/* Interpolate the target gain if the gain fading lasts
* longer than this mix.
*/
if(Counter > DstBufferSize)
- gain = lerp(parms->Hrtf.Old.Gain, gain,
+ gain = lerp(parms.Hrtf.Old.Gain, gain,
(ALfloat)todo/(Counter-fademix));
MixHrtfParams hrtfparams;
- hrtfparams.Coeffs = parms->Hrtf.Target.Coeffs;
- hrtfparams.Delay[0] = parms->Hrtf.Target.Delay[0];
- hrtfparams.Delay[1] = parms->Hrtf.Target.Delay[1];
- hrtfparams.Gain = parms->Hrtf.Old.Gain;
- hrtfparams.GainStep = (gain - parms->Hrtf.Old.Gain) / (ALfloat)todo;
+ hrtfparams.Coeffs = parms.Hrtf.Target.Coeffs;
+ hrtfparams.Delay[0] = parms.Hrtf.Target.Delay[0];
+ hrtfparams.Delay[1] = parms.Hrtf.Target.Delay[1];
+ hrtfparams.Gain = parms.Hrtf.Old.Gain;
+ hrtfparams.GainStep = (gain - parms.Hrtf.Old.Gain) / (ALfloat)todo;
MixHrtfSamples(
- voice->Direct.Buffer[lidx], voice->Direct.Buffer[ridx],
+ voice->Direct.Buffer[OutLIdx], voice->Direct.Buffer[OutRIdx],
samples+fademix, voice->Offset+fademix, OutPos+fademix, IrSize,
- &hrtfparams, &parms->Hrtf.State, todo
- );
+ &hrtfparams, &parms.Hrtf.State, todo);
/* Store the interpolated gain or the final target gain
* depending if the fade is done.
*/
if(DstBufferSize < Counter)
- parms->Hrtf.Old.Gain = gain;
+ parms.Hrtf.Old.Gain = gain;
else
- parms->Hrtf.Old.Gain = parms->Hrtf.Target.Gain;
+ parms.Hrtf.Old.Gain = parms.Hrtf.Target.Gain;
}
}
}
@@ -640,19 +660,14 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize
if(!send.Buffer)
return;
- SendParams *parms = &send.Params[chan];
- const ALfloat *samples{DoFilters(&parms->LowPass, &parms->HighPass,
- FilterBuf, ResampledData, DstBufferSize, send.FilterType
- )};
+ SendParams &parms = send.Params[chan];
+ const ALfloat *samples{DoFilters(&parms.LowPass, &parms.HighPass,
+ FilterBuf, ResampledData, DstBufferSize, send.FilterType)};
- if(!Counter)
- std::copy(std::begin(parms->Gains.Target), std::end(parms->Gains.Target),
- std::begin(parms->Gains.Current));
- MixSamples(samples, send.Channels, send.Buffer,
- parms->Gains.Current, parms->Gains.Target, Counter, OutPos, DstBufferSize
- );
+ MixSamples(samples, send.Channels, send.Buffer, parms.Gains.Current,
+ parms.Gains.Target, Counter, OutPos, DstBufferSize);
};
- std::for_each(voice->Send, voice->Send+Device->NumAuxSends, mix_send);
+ std::for_each(voice->Send, voice->Send+NumAuxSends, mix_send);
}
/* Update positions */
DataPosFrac += increment*DstBufferSize;
diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h
index 934d6866..42c754cc 100644
--- a/OpenAL32/Include/alu.h
+++ b/OpenAL32/Include/alu.h
@@ -475,7 +475,7 @@ inline void ComputePanGains(const MixParams *dry, const ALfloat*RESTRICT coeffs,
void ComputePanGains(const ALeffectslot *slot, const ALfloat*RESTRICT coeffs, ALfloat ingain, ALfloat (&gains)[MAX_OUTPUT_CHANNELS]);
-ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsizei SamplesToDo);
+ALboolean MixSource(ALvoice *voice, const ALuint SourceID, ALCcontext *Context, const ALsizei SamplesToDo);
void aluMixData(ALCdevice *device, ALvoid *OutBuffer, ALsizei NumSamples);
/* Caller must lock the device, and the mixer must not be running. */