aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2016-03-09 22:57:38 -0800
committerChris Robinson <[email protected]>2016-03-09 22:57:38 -0800
commit3e2672ec9f5c2a84a0f871bd0379ee387f9a95ce (patch)
tree13df9f8f0823f55d4ee2759fd3314dc9b174634f /Alc
parent3b9fe27cbe466ecb2a1aad8013f2dc256d708aaa (diff)
Track the virtual and real output buffers ecplicitly
Diffstat (limited to 'Alc')
-rw-r--r--Alc/ALc.c35
-rw-r--r--Alc/ALu.c54
-rw-r--r--Alc/effects/reverb.c36
3 files changed, 79 insertions, 46 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index fd44ed28..fb9f2caa 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -1855,6 +1855,10 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
al_free(device->DryBuffer);
device->DryBuffer = NULL;
+ device->VirtOut.Buffer = NULL;
+ device->VirtOut.NumChannels = 0;
+ device->RealOut.Buffer = NULL;
+ device->RealOut.NumChannels = 0;
UpdateClockBase(device);
@@ -2124,6 +2128,21 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
return ALC_INVALID_DEVICE;
}
+ if(device->Hrtf || device->Uhj_Encoder)
+ {
+ device->VirtOut.Buffer = device->DryBuffer;
+ device->VirtOut.NumChannels = device->NumChannels;
+ device->RealOut.Buffer = device->DryBuffer + device->NumChannels;
+ device->RealOut.NumChannels = 2;
+ }
+ else
+ {
+ device->VirtOut.Buffer = NULL;
+ device->VirtOut.NumChannels = 0;
+ device->RealOut.Buffer = device->DryBuffer;
+ device->RealOut.NumChannels = device->NumChannels;
+ }
+
SetMixerFPUMode(&oldMode);
V0(device->Backend,lock)();
context = ATOMIC_LOAD(&device->ContextList);
@@ -2261,6 +2280,10 @@ static ALCvoid FreeDevice(ALCdevice *device)
al_free(device->DryBuffer);
device->DryBuffer = NULL;
+ device->VirtOut.Buffer = NULL;
+ device->VirtOut.NumChannels = 0;
+ device->RealOut.Buffer = NULL;
+ device->RealOut.NumChannels = 0;
al_free(device);
}
@@ -3361,6 +3384,10 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
device->Render_Mode = NormalRender;
AL_STRING_INIT(device->DeviceName);
device->DryBuffer = NULL;
+ device->VirtOut.Buffer = NULL;
+ device->VirtOut.NumChannels = 0;
+ device->RealOut.Buffer = NULL;
+ device->RealOut.NumChannels = 0;
ATOMIC_INIT(&device->ContextList, NULL);
@@ -3616,6 +3643,10 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName,
AL_STRING_INIT(device->DeviceName);
device->DryBuffer = NULL;
+ device->VirtOut.Buffer = NULL;
+ device->VirtOut.NumChannels = 0;
+ device->RealOut.Buffer = NULL;
+ device->RealOut.NumChannels = 0;
InitUIntMap(&device->BufferMap, ~0);
InitUIntMap(&device->EffectMap, ~0);
@@ -3806,6 +3837,10 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN
device->Render_Mode = NormalRender;
AL_STRING_INIT(device->DeviceName);
device->DryBuffer = NULL;
+ device->VirtOut.Buffer = NULL;
+ device->VirtOut.NumChannels = 0;
+ device->RealOut.Buffer = NULL;
+ device->RealOut.NumChannels = 0;
ATOMIC_INIT(&device->ContextList, NULL);
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 38a4ef71..599ba3c2 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -581,8 +581,8 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A
* channels and write FrontLeft and FrontRight inputs to the
* first and second outputs.
*/
- voice->Direct.OutBuffer += voice->Direct.OutChannels;
- voice->Direct.OutChannels = 2;
+ voice->Direct.OutBuffer = Device->RealOut.Buffer;
+ voice->Direct.OutChannels = Device->RealOut.NumChannels;
for(c = 0;c < num_channels;c++)
{
for(j = 0;j < MAX_OUTPUT_CHANNELS;j++)
@@ -632,8 +632,8 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A
/* Full HRTF rendering. Skip the virtual channels and render each
* input channel to the real outputs.
*/
- voice->Direct.OutBuffer += voice->Direct.OutChannels;
- voice->Direct.OutChannels = 2;
+ voice->Direct.OutBuffer = Device->RealOut.Buffer;
+ voice->Direct.OutChannels = Device->RealOut.NumChannels;
for(c = 0;c < num_channels;c++)
{
if(chans[c].channel == LFE)
@@ -1131,8 +1131,8 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte
ALfloat dirfact = 1.0f;
ALfloat coeffs[MAX_AMBI_COEFFS];
- voice->Direct.OutBuffer += voice->Direct.OutChannels;
- voice->Direct.OutChannels = 2;
+ voice->Direct.OutBuffer = Device->RealOut.Buffer;
+ voice->Direct.OutChannels = Device->RealOut.NumChannels;
if(Distance > FLT_EPSILON)
{
@@ -1393,26 +1393,13 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
while(size > 0)
{
- ALfloat (*OutBuffer)[BUFFERSIZE];
- ALuint OutChannels;
-
IncrementRef(&device->MixCount);
- OutBuffer = device->DryBuffer;
- OutChannels = device->NumChannels;
-
SamplesToDo = minu(size, BUFFERSIZE);
- for(c = 0;c < OutChannels;c++)
- memset(OutBuffer[c], 0, SamplesToDo*sizeof(ALfloat));
- if(device->Hrtf || device->Uhj_Encoder)
- {
- /* Set OutBuffer/OutChannels to correspond to the actual output
- * with HRTF. Make sure to clear them too. */
- OutBuffer += OutChannels;
- OutChannels = 2;
- for(c = 0;c < OutChannels;c++)
- memset(OutBuffer[c], 0, SamplesToDo*sizeof(ALfloat));
- }
+ for(c = 0;c < device->VirtOut.NumChannels;c++)
+ memset(device->VirtOut.Buffer[c], 0, SamplesToDo*sizeof(ALfloat));
+ for(c = 0;c < device->RealOut.NumChannels;c++)
+ memset(device->RealOut.Buffer[c], 0, SamplesToDo*sizeof(ALfloat));
V0(device->Backend,lock)();
@@ -1495,12 +1482,13 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
ALuint irsize = GetHrtfIrSize(device->Hrtf);
MixHrtfParams hrtfparams;
memset(&hrtfparams, 0, sizeof(hrtfparams));
- for(c = 0;c < device->NumChannels;c++)
+ for(c = 0;c < device->VirtOut.NumChannels;c++)
{
hrtfparams.Current = &device->Hrtf_Params[c];
hrtfparams.Target = &device->Hrtf_Params[c];
- HrtfMix(OutBuffer, device->DryBuffer[c], 0, device->Hrtf_Offset,
- 0, irsize, &hrtfparams, &device->Hrtf_State[c], SamplesToDo
+ HrtfMix(device->RealOut.Buffer, device->VirtOut.Buffer[c], 0,
+ device->Hrtf_Offset, 0, irsize, &hrtfparams,
+ &device->Hrtf_State[c], SamplesToDo
);
}
device->Hrtf_Offset += SamplesToDo;
@@ -1510,7 +1498,8 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
if(device->Uhj_Encoder)
{
/* Encode to stereo-compatible 2-channel UHJ output. */
- EncodeUhj2(device->Uhj_Encoder, OutBuffer, device->DryBuffer, SamplesToDo);
+ EncodeUhj2(device->Uhj_Encoder, device->RealOut.Buffer,
+ device->VirtOut.Buffer, SamplesToDo);
}
if(device->Bs2b)
{
@@ -1518,17 +1507,20 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
for(i = 0;i < SamplesToDo;i++)
{
float samples[2];
- samples[0] = OutBuffer[0][i];
- samples[1] = OutBuffer[1][i];
+ samples[0] = device->RealOut.Buffer[0][i];
+ samples[1] = device->RealOut.Buffer[1][i];
bs2b_cross_feed(device->Bs2b, samples);
- OutBuffer[0][i] = samples[0];
- OutBuffer[1][i] = samples[1];
+ device->RealOut.Buffer[0][i] = samples[0];
+ device->RealOut.Buffer[1][i] = samples[1];
}
}
}
if(buffer)
{
+ ALfloat (*OutBuffer)[BUFFERSIZE] = device->RealOut.Buffer;
+ ALuint OutChannels = device->RealOut.NumChannels;;
+
#define WRITE(T, a, b, c, d) do { \
Write_##T((a), (b), (c), (d)); \
buffer = (T*)buffer + (c)*(d); \
diff --git a/Alc/effects/reverb.c b/Alc/effects/reverb.c
index 995ad6a5..a92fbd5b 100644
--- a/Alc/effects/reverb.c
+++ b/Alc/effects/reverb.c
@@ -364,6 +364,9 @@ static ALboolean ALreverbState_deviceUpdate(ALreverbState *State, ALCdevice *Dev
if(!AllocLines(frequency, State))
return AL_FALSE;
+ /* WARNING: This assumes the real output follows the virtual output in the
+ * device's DryBuffer.
+ */
State->ExtraChannels = (Device->Hrtf || Device->Uhj_Encoder) ? 2 : 0;
// Calculate the modulation filter coefficient. Notice that the exponent
@@ -666,16 +669,19 @@ static ALvoid UpdateMixedPanning(const ALCdevice *Device, const ALfloat *Reflect
ALfloat length;
ALuint i;
- /* With HRTF, the normal output provides a panned reverb channel when a
- * non-0-length vector is specified, while the real stereo output provides
- * two other "direct" non-panned reverb channels.
+ /* With HRTF or UHJ, the normal output provides a panned reverb channel
+ * when a non-0-length vector is specified, while the real stereo output
+ * provides two other "direct" non-panned reverb channels.
+ *
+ * WARNING: This assumes the real output follows the virtual output in the
+ * device's DryBuffer.
*/
memset(State->Early.PanGain, 0, sizeof(State->Early.PanGain));
length = sqrtf(ReflectionsPan[0]*ReflectionsPan[0] + ReflectionsPan[1]*ReflectionsPan[1] + ReflectionsPan[2]*ReflectionsPan[2]);
if(!(length > FLT_EPSILON))
{
- for(i = 0;i < 2;i++)
- State->Early.PanGain[i&3][Device->NumChannels+i] = Gain * EarlyGain;
+ for(i = 0;i < Device->RealOut.NumChannels;i++)
+ State->Early.PanGain[i&3][Device->VirtOut.NumChannels+i] = Gain * EarlyGain;
}
else
{
@@ -691,19 +697,19 @@ static ALvoid UpdateMixedPanning(const ALCdevice *Device, const ALfloat *Reflect
length = minf(length, 1.0f);
CalcDirectionCoeffs(pan, coeffs);
- ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, Gain, DirGains);
- for(i = 0;i < Device->NumChannels;i++)
+ ComputePanningGains(Device->AmbiCoeffs, Device->VirtOut.NumChannels, coeffs, Gain, DirGains);
+ for(i = 0;i < Device->VirtOut.NumChannels;i++)
State->Early.PanGain[3][i] = DirGains[i] * EarlyGain * length;
- for(i = 0;i < 2;i++)
- State->Early.PanGain[i&3][Device->NumChannels+i] = Gain * EarlyGain * (1.0f-length);
+ for(i = 0;i < Device->RealOut.NumChannels;i++)
+ State->Early.PanGain[i&3][Device->VirtOut.NumChannels+i] = Gain * EarlyGain * (1.0f-length);
}
memset(State->Late.PanGain, 0, sizeof(State->Late.PanGain));
length = sqrtf(LateReverbPan[0]*LateReverbPan[0] + LateReverbPan[1]*LateReverbPan[1] + LateReverbPan[2]*LateReverbPan[2]);
if(!(length > FLT_EPSILON))
{
- for(i = 0;i < 2;i++)
- State->Late.PanGain[i&3][Device->NumChannels+i] = Gain * LateGain;
+ for(i = 0;i < Device->RealOut.NumChannels;i++)
+ State->Late.PanGain[i&3][Device->VirtOut.NumChannels+i] = Gain * LateGain;
}
else
{
@@ -715,11 +721,11 @@ static ALvoid UpdateMixedPanning(const ALCdevice *Device, const ALfloat *Reflect
length = minf(length, 1.0f);
CalcDirectionCoeffs(pan, coeffs);
- ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, Gain, DirGains);
- for(i = 0;i < Device->NumChannels;i++)
+ ComputePanningGains(Device->AmbiCoeffs, Device->VirtOut.NumChannels, coeffs, Gain, DirGains);
+ for(i = 0;i < Device->VirtOut.NumChannels;i++)
State->Late.PanGain[3][i] = DirGains[i] * LateGain * length;
- for(i = 0;i < 2;i++)
- State->Late.PanGain[i&3][Device->NumChannels+i] = Gain * LateGain * (1.0f-length);
+ for(i = 0;i < Device->RealOut.NumChannels;i++)
+ State->Late.PanGain[i&3][Device->VirtOut.NumChannels+i] = Gain * LateGain * (1.0f-length);
}
}