aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/mixer_c.c
diff options
context:
space:
mode:
Diffstat (limited to 'Alc/mixer_c.c')
-rw-r--r--Alc/mixer_c.c118
1 files changed, 74 insertions, 44 deletions
diff --git a/Alc/mixer_c.c b/Alc/mixer_c.c
index 36d8bf5a..6dd01e7d 100644
--- a/Alc/mixer_c.c
+++ b/Alc/mixer_c.c
@@ -15,28 +15,33 @@ static inline ALfloat lerp32(const ALfloat *vals, ALuint frac)
static inline ALfloat cubic32(const ALfloat *vals, ALuint frac)
{ return cubic(vals[-1], vals[0], vals[1], vals[2], frac * (1.0f/FRACTIONONE)); }
-void Resample_copy32_C(const ALfloat *data, ALuint UNUSED(frac),
- ALuint increment, ALfloat *restrict OutBuffer, ALuint BufferSize)
+const ALfloat *Resample_copy32_C(const ALfloat *src, ALuint UNUSED(frac),
+ ALuint increment, ALfloat *restrict dst, ALuint numsamples)
{
assert(increment==FRACTIONONE);
- memcpy(OutBuffer, data, (BufferSize+1)*sizeof(ALfloat));
+#if defined(HAVE_SSE) || defined(HAVE_NEON)
+ /* Avoid copying the source data if it's aligned like the destination. */
+ if((((intptr_t)src)&15) == (((intptr_t)dst)&15))
+ return src;
+#endif
+ memcpy(dst, src, numsamples*sizeof(ALfloat));
+ return dst;
}
#define DECL_TEMPLATE(Sampler) \
-void Resample_##Sampler##_C(const ALfloat *data, ALuint frac, \
- ALuint increment, ALfloat *restrict OutBuffer, ALuint BufferSize) \
+const ALfloat *Resample_##Sampler##_C(const ALfloat *src, ALuint frac, \
+ ALuint increment, ALfloat *restrict dst, ALuint numsamples) \
{ \
- ALuint pos = 0; \
ALuint i; \
- \
- for(i = 0;i < BufferSize+1;i++) \
+ for(i = 0;i < numsamples;i++) \
{ \
- OutBuffer[i] = Sampler(data + pos, frac); \
+ dst[i] = Sampler(src, frac); \
\
frac += increment; \
- pos += frac>>FRACTIONBITS; \
+ src += frac>>FRACTIONBITS; \
frac &= FRACTIONMASK; \
} \
+ return dst; \
}
DECL_TEMPLATE(point32)
@@ -46,13 +51,26 @@ DECL_TEMPLATE(cubic32)
#undef DECL_TEMPLATE
-static inline void ApplyCoeffsStep(const ALuint IrSize,
+void ALfilterState_processC(ALfilterState *filter, ALfloat *restrict dst, const ALfloat *src, ALuint numsamples)
+{
+ ALuint i;
+ for(i = 0;i < numsamples;i++)
+ *(dst++) = ALfilterState_processSingle(filter, *(src++));
+}
+
+
+static inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*restrict Values)[2],
+ const ALuint IrSize,
ALfloat (*restrict Coeffs)[2],
- const ALfloat (*restrict CoeffStep)[2])
+ const ALfloat (*restrict CoeffStep)[2],
+ ALfloat left, ALfloat right)
{
ALuint c;
for(c = 0;c < IrSize;c++)
{
+ const ALuint off = (Offset+c)&HRIR_MASK;
+ Values[off][0] += Coeffs[c][0] * left;
+ Values[off][1] += Coeffs[c][1] * right;
Coeffs[c][0] += CoeffStep[c][0];
Coeffs[c][1] += CoeffStep[c][1];
}
@@ -77,49 +95,61 @@ static inline void ApplyCoeffs(ALuint Offset, ALfloat (*restrict Values)[2],
#undef SUFFIX
-void MixDirect_C(const DirectParams *params, const ALfloat *restrict data, ALuint srcchan,
- ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
+void MixDirect_C(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data,
+ MixGains *Gains, ALuint Counter, ALuint OutPos, ALuint BufferSize)
{
- ALfloat (*restrict OutBuffer)[BUFFERSIZE] = params->OutBuffer;
- ALfloat *restrict ClickRemoval = params->ClickRemoval;
- ALfloat *restrict PendingClicks = params->PendingClicks;
- ALfloat DrySend;
- ALuint pos;
+ ALfloat DrySend, Step;
ALuint c;
for(c = 0;c < MaxChannels;c++)
{
- DrySend = params->Gains[srcchan][c];
+ ALuint pos = 0;
+ DrySend = Gains->Current[c];
+ Step = Gains->Step[c];
+ if(Step != 1.0f && Counter > 0)
+ {
+ for(;pos < BufferSize && pos < Counter;pos++)
+ {
+ OutBuffer[c][OutPos+pos] += data[pos]*DrySend;
+ DrySend *= Step;
+ }
+ if(pos == Counter)
+ DrySend = Gains->Target[c];
+ Gains->Current[c] = DrySend;
+ }
+
if(!(DrySend > GAIN_SILENCE_THRESHOLD))
continue;
-
- if(OutPos == 0)
- ClickRemoval[c] -= data[0]*DrySend;
- for(pos = 0;pos < BufferSize;pos++)
+ for(;pos < BufferSize;pos++)
OutBuffer[c][OutPos+pos] += data[pos]*DrySend;
- if(OutPos+pos == SamplesToDo)
- PendingClicks[c] += data[pos]*DrySend;
}
}
-void MixSend_C(const SendParams *params, const ALfloat *restrict data,
- ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
+void MixSend_C(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data,
+ MixGainMono *Gain, ALuint Counter, ALuint OutPos, ALuint BufferSize)
{
- ALfloat (*restrict OutBuffer)[BUFFERSIZE] = params->OutBuffer;
- ALfloat *restrict ClickRemoval = params->ClickRemoval;
- ALfloat *restrict PendingClicks = params->PendingClicks;
- ALfloat WetSend;
- ALuint pos;
-
- WetSend = params->Gain;
- if(!(WetSend > GAIN_SILENCE_THRESHOLD))
- return;
-
- if(OutPos == 0)
- ClickRemoval[0] -= data[0] * WetSend;
- for(pos = 0;pos < BufferSize;pos++)
- OutBuffer[0][OutPos+pos] += data[pos] * WetSend;
- if(OutPos+pos == SamplesToDo)
- PendingClicks[0] += data[pos] * WetSend;
+ ALfloat WetSend, Step;
+
+ {
+ ALuint pos = 0;
+ WetSend = Gain->Current;
+ Step = Gain->Step;
+ if(Step != 1.0f && Counter > 0)
+ {
+ for(;pos < BufferSize && pos < Counter;pos++)
+ {
+ OutBuffer[0][OutPos+pos] += data[pos]*WetSend;
+ WetSend *= Step;
+ }
+ if(pos == Counter)
+ WetSend = Gain->Target;
+ Gain->Current = WetSend;
+ }
+
+ if(!(WetSend > GAIN_SILENCE_THRESHOLD))
+ return;
+ for(;pos < BufferSize;pos++)
+ OutBuffer[0][OutPos+pos] += data[pos] * WetSend;
+ }
}