diff options
author | Chris Robinson <[email protected]> | 2016-03-09 22:57:38 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2016-03-09 22:57:38 -0800 |
commit | 3e2672ec9f5c2a84a0f871bd0379ee387f9a95ce (patch) | |
tree | 13df9f8f0823f55d4ee2759fd3314dc9b174634f /Alc | |
parent | 3b9fe27cbe466ecb2a1aad8013f2dc256d708aaa (diff) |
Track the virtual and real output buffers ecplicitly
Diffstat (limited to 'Alc')
-rw-r--r-- | Alc/ALc.c | 35 | ||||
-rw-r--r-- | Alc/ALu.c | 54 | ||||
-rw-r--r-- | Alc/effects/reverb.c | 36 |
3 files changed, 79 insertions, 46 deletions
@@ -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); @@ -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); } } |