aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/ALu.c
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2017-05-24 23:21:08 -0700
committerChris Robinson <[email protected]>2017-05-25 03:24:35 -0700
commit9d4f601a8a71afbcc7b889a78e55fb9c714d289a (patch)
tree67c66d7af158a8fd0252632650bce90cc95db667 /Alc/ALu.c
parentc68a537ae8fd358856170112938359a743f1899e (diff)
Apply distance compensation separately
Diffstat (limited to 'Alc/ALu.c')
-rw-r--r--Alc/ALu.c109
1 files changed, 66 insertions, 43 deletions
diff --git a/Alc/ALu.c b/Alc/ALu.c
index a297292f..fec31b34 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -1494,6 +1494,50 @@ static void UpdateContextSources(ALCcontext *ctx, const struct ALeffectslotArray
}
+static void ApplyDistanceComp(ALfloatBUFFERSIZE *restrict Samples, DistanceComp *distcomp,
+ ALfloat *restrict Values, ALsizei SamplesToDo, ALsizei numchans)
+{
+ ALsizei i, c;
+
+ Values = ASSUME_ALIGNED(Values, 16);
+ for(c = 0;c < numchans;c++)
+ {
+ ALfloat *restrict inout = ASSUME_ALIGNED(Samples[c], 16);
+ const ALfloat gain = distcomp[c].Gain;
+ const ALsizei base = distcomp[c].Length;
+ ALfloat *restrict distbuf = ASSUME_ALIGNED(distcomp[c].Buffer, 16);
+
+ if(base == 0)
+ {
+ if(gain < 1.0f)
+ {
+ for(i = 0;i < SamplesToDo;i++)
+ inout[i] *= gain;
+ }
+ continue;
+ }
+
+ if(SamplesToDo >= base)
+ {
+ for(i = 0;i < base;i++)
+ Values[i] = distbuf[i];
+ for(;i < SamplesToDo;i++)
+ Values[i] = inout[i-base];
+ memcpy(distbuf, &inout[SamplesToDo-base], base*sizeof(ALfloat));
+ }
+ else
+ {
+ for(i = 0;i < SamplesToDo;i++)
+ Values[i] = distbuf[i];
+ memmove(distbuf, distbuf+SamplesToDo, (base-SamplesToDo)*sizeof(ALfloat));
+ memcpy(distbuf+base-SamplesToDo, inout, SamplesToDo*sizeof(ALfloat));
+ }
+ for(i = 0;i < SamplesToDo;i++)
+ inout[i] = Values[i]*gain;
+ }
+}
+
+
static_assert(LIMITER_VALUE_MAX < (UINT_MAX/LIMITER_WINDOW_SIZE), "LIMITER_VALUE_MAX is too big");
static void ApplyLimiter(struct OutputLimiter *Limiter,
@@ -1613,39 +1657,16 @@ DECL_TEMPLATE(ALushort, aluF2USDithered, aluF2SDithered, 32768)
#define DECL_TEMPLATE(T, D, func) \
static void Write##T##D(const ALfloatBUFFERSIZE *InBuffer, ALvoid *OutBuffer, \
- DistanceComp *distcomp, \
- const ALfloat *restrict DitherValues, \
- ALsizei SamplesToDo, ALsizei numchans) \
+ const ALfloat *restrict DitherValues, \
+ ALsizei SamplesToDo, ALsizei numchans) \
{ \
ALsizei i, j; \
for(j = 0;j < numchans;j++) \
{ \
const ALfloat *restrict in = ASSUME_ALIGNED(InBuffer[j], 16); \
T *restrict out = (T*)OutBuffer + j; \
- const ALfloat gain = distcomp[j].Gain; \
- const ALsizei base = distcomp[j].Length; \
- ALfloat *restrict distbuf = ASSUME_ALIGNED(distcomp[j].Buffer, 16); \
- if(base > 0 || gain != 1.0f) \
- { \
- if(SamplesToDo >= base) \
- { \
- for(i = 0;i < base;i++) \
- out[i*numchans] = func(distbuf[i]*gain, DitherValues[i]); \
- for(;i < SamplesToDo;i++) \
- out[i*numchans] = func(in[i-base]*gain, DitherValues[i]); \
- memcpy(distbuf, &in[SamplesToDo-base], base*sizeof(ALfloat)); \
- } \
- else \
- { \
- for(i = 0;i < SamplesToDo;i++) \
- out[i*numchans] = func(distbuf[i]*gain, DitherValues[i]); \
- memmove(distbuf, distbuf+SamplesToDo, \
- (base-SamplesToDo)*sizeof(ALfloat)); \
- memcpy(distbuf+base-SamplesToDo, in, \
- SamplesToDo*sizeof(ALfloat)); \
- } \
- } \
- else for(i = 0;i < SamplesToDo;i++) \
+ \
+ for(i = 0;i < SamplesToDo;i++) \
out[i*numchans] = func(in[i], DitherValues[i]); \
} \
}
@@ -1837,9 +1858,12 @@ void aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
ALfloat (*OutBuffer)[BUFFERSIZE] = device->RealOut.Buffer;
ALsizei OutChannels = device->RealOut.NumChannels;
struct OutputLimiter *Limiter = device->Limiter;
- DistanceComp *DistComp;
ALfloat *DitherValues;
+ /* Use NFCtrlData for temp value storage. */
+ ApplyDistanceComp(OutBuffer, device->ChannelDelay, device->NFCtrlData,
+ SamplesToDo, OutChannels);
+
if(Limiter)
{
const ALfloat AttackRate = powf(0.0001f, 1.0f/(device->Frequency*Limiter->AttackRate));
@@ -1874,55 +1898,54 @@ void aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
}
DitherValues = device->NFCtrlData;
- DistComp = device->ChannelDelay;
-#define WRITE(T, D, a, b, c, d, e, f) do { \
- Write##T##D(SAFE_CONST(ALfloatBUFFERSIZE*,(a)), (b), (c), (d), (e), (f)); \
- buffer = (T*)buffer + (e)*(f); \
+#define WRITE(T, D, a, b, c, d, e) do { \
+ Write##T##D(SAFE_CONST(ALfloatBUFFERSIZE*,(a)), (b), (c), (d), (e)); \
+ buffer = (T*)buffer + (d)*(e); \
} while(0)
switch(device->FmtType)
{
case DevFmtByte:
if(device->DitherEnabled)
- WRITE(ALbyte, _Dithered, OutBuffer, buffer, DistComp, DitherValues,
+ WRITE(ALbyte, _Dithered, OutBuffer, buffer, DitherValues,
SamplesToDo, OutChannels);
else
- WRITE(ALbyte, /*no dither*/, OutBuffer, buffer, DistComp, DitherValues,
+ WRITE(ALbyte, /*no dither*/, OutBuffer, buffer, DitherValues,
SamplesToDo, OutChannels);
break;
case DevFmtUByte:
if(device->DitherEnabled)
- WRITE(ALubyte, _Dithered, OutBuffer, buffer, DistComp, DitherValues,
+ WRITE(ALubyte, _Dithered, OutBuffer, buffer, DitherValues,
SamplesToDo, OutChannels);
else
- WRITE(ALubyte, /*no dither*/, OutBuffer, buffer, DistComp, DitherValues,
+ WRITE(ALubyte, /*no dither*/, OutBuffer, buffer, DitherValues,
SamplesToDo, OutChannels);
break;
case DevFmtShort:
if(device->DitherEnabled)
- WRITE(ALshort, _Dithered, OutBuffer, buffer, DistComp, DitherValues,
+ WRITE(ALshort, _Dithered, OutBuffer, buffer, DitherValues,
SamplesToDo, OutChannels);
else
- WRITE(ALshort, /*no dither*/, OutBuffer, buffer, DistComp, DitherValues,
+ WRITE(ALshort, /*no dither*/, OutBuffer, buffer, DitherValues,
SamplesToDo, OutChannels);
break;
case DevFmtUShort:
if(device->DitherEnabled)
- WRITE(ALushort, _Dithered, OutBuffer, buffer, DistComp, DitherValues,
+ WRITE(ALushort, _Dithered, OutBuffer, buffer, DitherValues,
SamplesToDo, OutChannels);
else
- WRITE(ALushort, /*no dither*/, OutBuffer, buffer, DistComp, DitherValues,
+ WRITE(ALushort, /*no dither*/, OutBuffer, buffer, DitherValues,
SamplesToDo, OutChannels);
break;
case DevFmtInt:
- WRITE(ALint, /*no dither*/, OutBuffer, buffer, DistComp, DitherValues,
+ WRITE(ALint, /*no dither*/, OutBuffer, buffer, DitherValues,
SamplesToDo, OutChannels);
break;
case DevFmtUInt:
- WRITE(ALuint, /*no dither*/, OutBuffer, buffer, DistComp, DitherValues,
+ WRITE(ALuint, /*no dither*/, OutBuffer, buffer, DitherValues,
SamplesToDo, OutChannels);
break;
case DevFmtFloat:
- WRITE(ALfloat, /*no dither*/, OutBuffer, buffer, DistComp, DitherValues,
+ WRITE(ALfloat, /*no dither*/, OutBuffer, buffer, DitherValues,
SamplesToDo, OutChannels);
break;
}