diff options
author | Chris Robinson <[email protected]> | 2014-03-23 06:57:00 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2014-03-23 06:57:00 -0700 |
commit | 81e049bd47cc2423dc6983c47d9f99e70c3135ac (patch) | |
tree | 74424462f69b97dffaebdc04dc263bf5eeb6183c /Alc/ALu.c | |
parent | 0ce0a88fd67ddcf7cb5248ac08d36cfa1c0013eb (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.c | 127 |
1 files changed, 112 insertions, 15 deletions
@@ -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(); } |