Use a non-interleaved DryBuffer

This commit is contained in:
Chris Robinson
2012-09-11 06:32:42 -07:00
parent 98ff6f990a
commit 4c5cb2189b
10 changed files with 73 additions and 84 deletions
+27 -23
View File
@@ -797,7 +797,7 @@ static __inline ALubyte aluF2UB(ALfloat val)
static void Write_##T##_##N(ALCdevice *device, T *RESTRICT buffer, \
ALuint SamplesToDo) \
{ \
ALfloat (*RESTRICT DryBuffer)[MaxChannels] = device->DryBuffer; \
ALfloat (*RESTRICT DryBuffer)[BUFFERSIZE] = device->DryBuffer; \
const enum Channel *ChanMap = device->DevChannels; \
ALuint i, j; \
\
@@ -807,7 +807,7 @@ static void Write_##T##_##N(ALCdevice *device, T *RESTRICT buffer, \
enum Channel chan = ChanMap[j]; \
\
for(i = 0;i < SamplesToDo;i++) \
out[i*N] = func(DryBuffer[i][chan]); \
out[i*N] = func(DryBuffer[chan][i]); \
} \
}
@@ -913,7 +913,8 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
while(size > 0)
{
SamplesToDo = minu(size, BUFFERSIZE);
memset(device->DryBuffer, 0, SamplesToDo*MaxChannels*sizeof(ALfloat));
for(c = 0;c < MaxChannels;c++)
memset(device->DryBuffer[c], 0, SamplesToDo*sizeof(ALfloat));
ALCdevice_Lock(device);
ctx = device->ContextList;
@@ -1002,7 +1003,7 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
{
for(i = 0;i < SamplesToDo;i++)
{
device->DryBuffer[i][FrontCenter] += device->ClickRemoval[FrontCenter];
device->DryBuffer[FrontCenter][i] += device->ClickRemoval[FrontCenter];
device->ClickRemoval[FrontCenter] -= device->ClickRemoval[FrontCenter] * (1.0f/256.0f);
}
device->ClickRemoval[FrontCenter] += device->PendingClicks[FrontCenter];
@@ -1011,38 +1012,41 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
else if(device->FmtChans == DevFmtStereo)
{
/* Assumes the first two channels are FrontLeft and FrontRight */
for(i = 0;i < SamplesToDo;i++)
{
for(c = 0;c < 2;c++)
{
device->DryBuffer[i][c] += device->ClickRemoval[c];
device->ClickRemoval[c] -= device->ClickRemoval[c] * (1.0f/256.0f);
}
}
for(c = 0;c < 2;c++)
{
device->ClickRemoval[c] += device->PendingClicks[c];
ALfloat offset = device->ClickRemoval[c];
for(i = 0;i < SamplesToDo;i++)
{
device->DryBuffer[c][i] += offset;
offset -= offset * (1.0f/256.0f);
}
device->ClickRemoval[c] = offset + device->PendingClicks[c];
device->PendingClicks[c] = 0.0f;
}
if(device->Bs2b)
{
float samples[2];
for(i = 0;i < SamplesToDo;i++)
bs2b_cross_feed(device->Bs2b, &device->DryBuffer[i][0]);
{
samples[0] = device->DryBuffer[FrontLeft][i];
samples[1] = device->DryBuffer[FrontRight][i];
bs2b_cross_feed(device->Bs2b, samples);
device->DryBuffer[FrontLeft][i] = samples[0];
device->DryBuffer[FrontRight][i] = samples[1];
}
}
}
else
{
for(i = 0;i < SamplesToDo;i++)
{
for(c = 0;c < MaxChannels;c++)
{
device->DryBuffer[i][c] += device->ClickRemoval[c];
device->ClickRemoval[c] -= device->ClickRemoval[c] * (1.0f/256.0f);
}
}
for(c = 0;c < MaxChannels;c++)
{
device->ClickRemoval[c] += device->PendingClicks[c];
ALfloat offset = device->ClickRemoval[c];
for(i = 0;i < SamplesToDo;i++)
{
device->DryBuffer[c][i] += offset;
offset -= offset * (1.0f/256.0f);
}
device->ClickRemoval[c] = offset + device->PendingClicks[c];
device->PendingClicks[c] = 0.0f;
}
}
+5 -8
View File
@@ -66,19 +66,16 @@ static ALvoid DedicatedUpdate(ALeffectState *effect, ALCdevice *device, const AL
state->gains[LFE] = Gain;
}
static ALvoid DedicatedProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MaxChannels])
static ALvoid DedicatedProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[BUFFERSIZE])
{
ALdedicatedState *state = (ALdedicatedState*)effect;
const ALfloat *gains = state->gains;
ALuint i, s;
ALuint i, c;
for(i = 0;i < SamplesToDo;i++)
for(c = 0;c < MaxChannels;c++)
{
ALfloat sample;
sample = SamplesIn[i];
for(s = 0;s < MaxChannels;s++)
SamplesOut[i][s] = sample * gains[s];
for(i = 0;i < SamplesToDo;i++)
SamplesOut[c][i] = SamplesIn[i] * gains[c];
}
}
+3 -3
View File
@@ -126,7 +126,7 @@ static ALvoid EchoUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffec
ComputeAngleGains(Device, atan2f(+lrpan, 0.0f), (1.0f-dirGain)*F_PI, gain, state->Gain[1]);
}
static ALvoid EchoProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MaxChannels])
static ALvoid EchoProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[BUFFERSIZE])
{
ALechoState *state = (ALechoState*)effect;
const ALuint mask = state->BufferLength-1;
@@ -141,12 +141,12 @@ static ALvoid EchoProcess(ALeffectState *effect, ALuint SamplesToDo, const ALflo
/* First tap */
smp = state->SampleBuffer[(offset-tap1) & mask];
for(k = 0;k < MaxChannels;k++)
SamplesOut[i][k] += smp * state->Gain[0][k];
SamplesOut[k][i] += smp * state->Gain[0][k];
/* Second tap */
smp = state->SampleBuffer[(offset-tap2) & mask];
for(k = 0;k < MaxChannels;k++)
SamplesOut[i][k] += smp * state->Gain[1][k];
SamplesOut[k][i] += smp * state->Gain[1][k];
// Apply damping and feedback gain to the second tap, and mix in the
// new sample
+3 -3
View File
@@ -84,7 +84,7 @@ static __inline ALfloat hpFilter1P(FILTER *iir, ALuint offset, ALfloat input)
#define DECL_TEMPLATE(func) \
static void Process##func(ALmodulatorState *state, ALuint SamplesToDo, \
const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MaxChannels]) \
const ALfloat *SamplesIn, ALfloat (*SamplesOut)[BUFFERSIZE]) \
{ \
const ALuint step = state->step; \
ALuint index = state->index; \
@@ -102,7 +102,7 @@ static void Process##func(ALmodulatorState *state, ALuint SamplesToDo, \
samp = hpFilter1P(&state->iirFilter, 0, samp); \
\
for(k = 0;k < MaxChannels;k++) \
SamplesOut[i][k] += state->Gain[k] * samp; \
SamplesOut[k][i] += state->Gain[k] * samp; \
} \
state->index = index; \
}
@@ -160,7 +160,7 @@ static ALvoid ModulatorUpdate(ALeffectState *effect, ALCdevice *Device, const AL
}
}
static ALvoid ModulatorProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MaxChannels])
static ALvoid ModulatorProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[BUFFERSIZE])
{
ALmodulatorState *state = (ALmodulatorState*)effect;
+4 -4
View File
@@ -546,7 +546,7 @@ static __inline ALvoid EAXVerbPass(ALverbState *State, ALfloat in, ALfloat *earl
// This processes the reverb state, given the input samples and an output
// buffer.
static ALvoid VerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MaxChannels])
static ALvoid VerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[BUFFERSIZE])
{
ALverbState *State = (ALverbState*)effect;
ALuint index, c;
@@ -566,13 +566,13 @@ static ALvoid VerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALflo
// Output the results.
for(c = 0;c < MaxChannels;c++)
SamplesOut[index][c] += panGain[c] * out[c&3];
SamplesOut[c][index] += panGain[c] * out[c&3];
}
}
// This processes the EAX reverb state, given the input samples and an output
// buffer.
static ALvoid EAXVerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MaxChannels])
static ALvoid EAXVerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[BUFFERSIZE])
{
ALverbState *State = (ALverbState*)effect;
ALuint index, c;
@@ -584,7 +584,7 @@ static ALvoid EAXVerbProcess(ALeffectState *effect, ALuint SamplesToDo, const AL
EAXVerbPass(State, SamplesIn[index], early, late);
for(c = 0;c < MaxChannels;c++)
SamplesOut[index][c] += State->Early.PanGain[c]*early[c&3] +
SamplesOut[c][index] += State->Early.PanGain[c]*early[c&3] +
State->Late.PanGain[c]*late[c&3];
}
}
+10 -11
View File
@@ -41,7 +41,7 @@ void MixDirect_Hrtf(ALsource *Source, ALCdevice *Device, DirectParams *params,
{
const ALint *RESTRICT DelayStep = params->Hrtf.DelayStep;
const ALuint IrSize = GetHrtfIrSize(Device->Hrtf);
ALfloat (*RESTRICT DryBuffer)[MaxChannels];
ALfloat (*RESTRICT DryBuffer)[BUFFERSIZE];
ALfloat *RESTRICT ClickRemoval, *RESTRICT PendingClicks;
ALfloat (*RESTRICT CoeffStep)[2] = params->Hrtf.CoeffStep;
ALfloat (*RESTRICT TargetCoeffs)[2] = params->Hrtf.Coeffs[srcchan];
@@ -103,8 +103,8 @@ void MixDirect_Hrtf(ALsource *Source, ALCdevice *Device, DirectParams *params,
Offset++;
ApplyCoeffsStep(Offset, Values, IrSize, Coeffs, CoeffStep, left, right);
DryBuffer[OutPos][FrontLeft] += Values[Offset&HRIR_MASK][0];
DryBuffer[OutPos][FrontRight] += Values[Offset&HRIR_MASK][1];
DryBuffer[FrontLeft][OutPos] += Values[Offset&HRIR_MASK][0];
DryBuffer[FrontRight][OutPos] += Values[Offset&HRIR_MASK][1];
OutPos++;
Counter--;
@@ -123,8 +123,8 @@ void MixDirect_Hrtf(ALsource *Source, ALCdevice *Device, DirectParams *params,
Offset++;
ApplyCoeffs(Offset, Values, IrSize, Coeffs, left, right);
DryBuffer[OutPos][FrontLeft] += Values[Offset&HRIR_MASK][0];
DryBuffer[OutPos][FrontRight] += Values[Offset&HRIR_MASK][1];
DryBuffer[FrontLeft][OutPos] += Values[Offset&HRIR_MASK][0];
DryBuffer[FrontRight][OutPos] += Values[Offset&HRIR_MASK][1];
OutPos++;
}
@@ -147,7 +147,7 @@ void MixDirect(ALsource *Source, ALCdevice *Device, DirectParams *params,
const ALfloat *RESTRICT data, ALuint srcchan,
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
{
ALfloat (*RESTRICT DryBuffer)[MaxChannels];
ALfloat (*RESTRICT DryBuffer)[BUFFERSIZE];
ALfloat *RESTRICT ClickRemoval, *RESTRICT PendingClicks;
ALIGN(16) ALfloat DrySend[MaxChannels];
ALuint pos;
@@ -167,13 +167,12 @@ void MixDirect(ALsource *Source, ALCdevice *Device, DirectParams *params,
for(c = 0;c < MaxChannels;c++)
ClickRemoval[c] -= data[pos]*DrySend[c];
}
for(pos = 0;pos < BufferSize;pos++)
for(c = 0;c < MaxChannels;c++)
{
for(c = 0;c < MaxChannels;c++)
DryBuffer[OutPos][c] += data[pos]*DrySend[c];
OutPos++;
for(pos = 0;pos < BufferSize;pos++)
DryBuffer[c][OutPos+pos] += data[pos]*DrySend[c];
}
if(OutPos == SamplesToDo)
if(OutPos+pos == SamplesToDo)
{
for(c = 0;c < MaxChannels;c++)
PendingClicks[c] += data[pos]*DrySend[c];
+18 -29
View File
@@ -132,10 +132,9 @@ void MixDirect_SSE(ALsource *Source, ALCdevice *Device, DirectParams *params,
const ALfloat *RESTRICT data, ALuint srcchan,
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
{
ALfloat (*RESTRICT DryBuffer)[MaxChannels];
ALfloat (*RESTRICT DryBuffer)[BUFFERSIZE];
ALfloat *RESTRICT ClickRemoval, *RESTRICT PendingClicks;
ALfloat DrySend[MaxChannels];
ALIGN(16) ALfloat value[4];
ALuint pos;
ALuint c;
(void)Source;
@@ -153,38 +152,28 @@ void MixDirect_SSE(ALsource *Source, ALCdevice *Device, DirectParams *params,
for(c = 0;c < MaxChannels;c++)
ClickRemoval[c] -= data[pos]*DrySend[c];
}
for(pos = 0;pos < BufferSize-3;pos += 4)
for(c = 0;c < MaxChannels;c++)
{
const __m128 val4 = _mm_load_ps(&data[pos]);
const __m128 gain = _mm_set1_ps(DrySend[c]);
for(pos = 0;pos < BufferSize-3;pos += 4)
{
const __m128 val4 = _mm_load_ps(&data[pos]);
__m128 dry4 = _mm_load_ps(&DryBuffer[c][OutPos+pos]);
dry4 = _mm_add_ps(dry4, _mm_mul_ps(val4, gain));
_mm_store_ps(&DryBuffer[c][OutPos+pos], dry4);
}
}
if(pos < BufferSize)
{
ALuint oldpos = pos;
for(c = 0;c < MaxChannels;c++)
{
const __m128 gain = _mm_set1_ps(DrySend[c]);
__m128 dry4;
value[0] = DryBuffer[OutPos ][c];
value[1] = DryBuffer[OutPos+1][c];
value[2] = DryBuffer[OutPos+2][c];
value[3] = DryBuffer[OutPos+3][c];
dry4 = _mm_load_ps(value);
dry4 = _mm_add_ps(dry4, _mm_mul_ps(val4, gain));
_mm_store_ps(value, dry4);
DryBuffer[OutPos ][c] = value[0];
DryBuffer[OutPos+1][c] = value[1];
DryBuffer[OutPos+2][c] = value[2];
DryBuffer[OutPos+3][c] = value[3];
pos = oldpos;
for(;pos < BufferSize;pos++)
DryBuffer[c][OutPos+pos] += data[pos]*DrySend[c];
}
OutPos += 4;
}
for(;pos < BufferSize;pos++)
{
for(c = 0;c < MaxChannels;c++)
DryBuffer[OutPos][c] += data[pos]*DrySend[c];
OutPos++;
}
if(OutPos == SamplesToDo)
if(OutPos+pos == SamplesToDo)
{
for(c = 0;c < MaxChannels;c++)
PendingClicks[c] += data[pos]*DrySend[c];
+1 -1
View File
@@ -40,7 +40,7 @@ struct ALeffectState {
ALvoid (*Destroy)(ALeffectState *State);
ALboolean (*DeviceUpdate)(ALeffectState *State, ALCdevice *Device);
ALvoid (*Update)(ALeffectState *State, ALCdevice *Device, const ALeffectslot *Slot);
ALvoid (*Process)(ALeffectState *State, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MaxChannels]);
ALvoid (*Process)(ALeffectState *State, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[BUFFERSIZE]);
};
ALeffectState *NoneCreate(void);
+1 -1
View File
@@ -618,7 +618,7 @@ struct ALCdevice_struct
ALuint NumChan;
// Dry path buffer mix
ALIGN(16) ALfloat DryBuffer[BUFFERSIZE][MaxChannels];
ALIGN(16) ALfloat DryBuffer[MaxChannels][BUFFERSIZE];
ALIGN(16) ALfloat ClickRemoval[MaxChannels];
ALIGN(16) ALfloat PendingClicks[MaxChannels];
+1 -1
View File
@@ -405,7 +405,7 @@ static ALvoid NoneUpdate(ALeffectState *State, ALCdevice *Device, const ALeffect
(void)Device;
(void)Slot;
}
static ALvoid NoneProcess(ALeffectState *State, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MaxChannels])
static ALvoid NoneProcess(ALeffectState *State, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[BUFFERSIZE])
{
(void)State;
(void)SamplesToDo;