aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/ALu.c
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2014-03-23 06:57:00 -0700
committerChris Robinson <[email protected]>2014-03-23 06:57:00 -0700
commit81e049bd47cc2423dc6983c47d9f99e70c3135ac (patch)
tree74424462f69b97dffaebdc04dc263bf5eeb6183c /Alc/ALu.c
parent0ce0a88fd67ddcf7cb5248ac08d36cfa1c0013eb (diff)
Step mixing gains per-sample for non-HRTF mixing
This fades the dry mixing gains using a logarithmic curve, which should produce a smoother transition than a linear one. It functions similarly to a linear fade except that step = (target - current) / numsteps; ... gain += step; becomes step = powf(target / current, 1.0f / numsteps); ... gain *= step; where 'target' and 'current' are clamped to a lower bound that is greater than 0 (which makes no sense on a logarithmic scale). Consequently, the non-HRTF direct mixers do not do not feed into the click removal and pending click buffers, as this per-sample fading would do an adequate job of stopping clicks and pops caused by extreme gain changes. These buffers should be removed shortly.
Diffstat (limited to 'Alc/ALu.c')
-rw-r--r--Alc/ALu.c127
1 files changed, 112 insertions, 15 deletions
diff --git a/Alc/ALu.c b/Alc/ALu.c
index ca0c0be4..9c563023 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -291,7 +291,7 @@ ALvoid CalcNonAttnSourceParams(ALactivesource *src, const ALCcontext *ALContext)
ALboolean DirectChannels;
ALfloat hwidth = 0.0f;
ALfloat Pitch;
- ALint i, c;
+ ALint i, j, c;
/* Get device properties */
NumSends = Device->NumAuxSends;
@@ -420,11 +420,11 @@ ALvoid CalcNonAttnSourceParams(ALactivesource *src, const ALCcontext *ALContext)
if(DirectChannels != AL_FALSE)
{
- ALfloat (*SrcMatrix)[MaxChannels] = src->Direct.Mix.Gains;
+ ALfloat (*Matrix)[MaxChannels] = src->Direct.Mix.Gains.Target;
for(i = 0;i < MAX_INPUT_CHANNELS;i++)
{
for(c = 0;c < MaxChannels;c++)
- SrcMatrix[i][c] = 0.0f;
+ Matrix[i][c] = 0.0f;
}
for(c = 0;c < num_channels;c++)
{
@@ -433,13 +433,47 @@ ALvoid CalcNonAttnSourceParams(ALactivesource *src, const ALCcontext *ALContext)
enum Channel chan = Device->Speaker2Chan[i];
if(chan == chans[c].channel)
{
- SrcMatrix[c][chan] = DryGain;
+ Matrix[c][chan] = DryGain;
break;
}
}
}
- src->Direct.Counter = 0;
- src->Direct.Moving = AL_TRUE;
+
+ if(src->Direct.Moving)
+ {
+ ALfloat (*restrict Current)[MaxChannels] = src->Direct.Mix.Gains.Current;
+ ALfloat (*restrict Step)[MaxChannels] = src->Direct.Mix.Gains.Step;
+ for(i = 0;i < MAX_INPUT_CHANNELS;i++)
+ {
+ for(j = 0;j < MaxChannels;j++)
+ {
+ ALfloat cur = maxf(Current[i][j], GAIN_SILENCE_THRESHOLD);
+ ALfloat trg = maxf(Matrix[i][j], GAIN_SILENCE_THRESHOLD);
+ if(fabs(trg - cur) >= GAIN_SILENCE_THRESHOLD)
+ Step[i][j] = powf(trg/cur, 1.0f/64.0f);
+ else
+ Step[i][j] = 1.0f;
+ Current[i][j] = cur;
+ }
+ }
+ src->Direct.Counter = 64;
+ }
+ else
+ {
+ ALfloat (*restrict Current)[MaxChannels] = src->Direct.Mix.Gains.Current;
+ ALfloat (*restrict Step)[MaxChannels] = src->Direct.Mix.Gains.Step;
+ for(i = 0;i < MAX_INPUT_CHANNELS;i++)
+ {
+ for(j = 0;j < MaxChannels;j++)
+ {
+ Current[i][j] = Matrix[i][j];
+ Step[i][j] = 1.0f;
+ }
+ }
+ src->Direct.Counter = 0;
+ src->Direct.Moving = AL_TRUE;
+ }
+
src->DryMix = SelectDirectMixer();
}
else if(Device->Hrtf)
@@ -475,11 +509,11 @@ ALvoid CalcNonAttnSourceParams(ALactivesource *src, const ALCcontext *ALContext)
}
else
{
- ALfloat (*SrcMatrix)[MaxChannels] = src->Direct.Mix.Gains;
+ ALfloat (*Matrix)[MaxChannels] = src->Direct.Mix.Gains.Target;
for(i = 0;i < MAX_INPUT_CHANNELS;i++)
{
for(c = 0;c < MaxChannels;c++)
- SrcMatrix[i][c] = 0.0f;
+ Matrix[i][c] = 0.0f;
}
DryGain *= lerp(1.0f, 1.0f/sqrtf((float)Device->NumChan), hwidth/F_PI);
@@ -488,14 +522,48 @@ ALvoid CalcNonAttnSourceParams(ALactivesource *src, const ALCcontext *ALContext)
/* Special-case LFE */
if(chans[c].channel == LFE)
{
- SrcMatrix[c][chans[c].channel] = DryGain;
+ Matrix[c][chans[c].channel] = DryGain;
continue;
}
ComputeAngleGains(Device, chans[c].angle, hwidth, DryGain,
- SrcMatrix[c]);
+ Matrix[c]);
}
- src->Direct.Counter = 0;
- src->Direct.Moving = AL_TRUE;
+
+ if(src->Direct.Moving)
+ {
+ ALfloat (*restrict Current)[MaxChannels] = src->Direct.Mix.Gains.Current;
+ ALfloat (*restrict Step)[MaxChannels] = src->Direct.Mix.Gains.Step;
+ for(i = 0;i < MAX_INPUT_CHANNELS;i++)
+ {
+ for(j = 0;j < MaxChannels;j++)
+ {
+ ALfloat trg = maxf(Matrix[i][j], GAIN_SILENCE_THRESHOLD);
+ ALfloat cur = maxf(Current[i][j], GAIN_SILENCE_THRESHOLD);
+ if(fabs(trg - cur) >= GAIN_SILENCE_THRESHOLD)
+ Step[i][j] = powf(trg/cur, 1.0f/64.0f);
+ else
+ Step[i][j] = 1.0f;
+ Current[i][j] = cur;
+ }
+ }
+ src->Direct.Counter = 64;
+ }
+ else
+ {
+ ALfloat (*restrict Current)[MaxChannels] = src->Direct.Mix.Gains.Current;
+ ALfloat (*restrict Step)[MaxChannels] = src->Direct.Mix.Gains.Step;
+ for(i = 0;i < MAX_INPUT_CHANNELS;i++)
+ {
+ for(j = 0;j < MaxChannels;j++)
+ {
+ Current[i][j] = Matrix[i][j];
+ Step[i][j] = 1.0f;
+ }
+ }
+ src->Direct.Counter = 0;
+ src->Direct.Moving = AL_TRUE;
+ }
+
src->DryMix = SelectDirectMixer();
}
for(i = 0;i < NumSends;i++)
@@ -919,7 +987,7 @@ ALvoid CalcSourceParams(ALactivesource *src, const ALCcontext *ALContext)
}
else
{
- ALfloat (*Matrix)[MaxChannels] = src->Direct.Mix.Gains;
+ ALfloat (*Matrix)[MaxChannels] = src->Direct.Mix.Gains.Target;
ALfloat DirGain = 0.0f;
ALfloat AmbientGain;
@@ -951,8 +1019,37 @@ ALvoid CalcSourceParams(ALactivesource *src, const ALCcontext *ALContext)
Matrix[0][chan] = maxf(Matrix[0][chan], AmbientGain);
}
- src->Direct.Counter = 0;
- src->Direct.Moving = AL_TRUE;
+ if(src->Direct.Moving)
+ {
+ ALfloat (*restrict Current)[MaxChannels] = src->Direct.Mix.Gains.Current;
+ ALfloat (*restrict Step)[MaxChannels] = src->Direct.Mix.Gains.Step;
+ for(j = 0;j < MaxChannels;j++)
+ {
+ ALfloat cur = maxf(Current[0][j], GAIN_SILENCE_THRESHOLD);
+ ALfloat trg = maxf(Matrix[0][j], GAIN_SILENCE_THRESHOLD);
+ if(fabs(trg - cur) >= GAIN_SILENCE_THRESHOLD)
+ Step[0][j] = powf(trg/cur, 1.0f/64.0f);
+ else
+ Step[0][j] = 1.0f;
+ Current[0][j] = cur;
+ }
+ src->Direct.Counter = 64;
+ }
+ else
+ {
+ ALfloat (*restrict Current)[MaxChannels] = src->Direct.Mix.Gains.Current;
+ ALfloat (*restrict Step)[MaxChannels] = src->Direct.Mix.Gains.Step;
+ for(i = 0;i < MAX_INPUT_CHANNELS;i++)
+ {
+ for(j = 0;j < MaxChannels;j++)
+ {
+ Current[i][j] = Matrix[i][j];
+ Step[i][j] = 1.0f;
+ }
+ }
+ src->Direct.Counter = 0;
+ src->Direct.Moving = AL_TRUE;
+ }
src->DryMix = SelectDirectMixer();
}