diff options
-rw-r--r-- | Alc/ALc.c | 2 | ||||
-rw-r--r-- | Alc/ALu.c | 165 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 7 | ||||
-rw-r--r-- | OpenAL32/Include/alu.h | 2 |
4 files changed, 106 insertions, 70 deletions
@@ -2216,6 +2216,8 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) } TRACE("Output limiter %s\n", device->Limiter ? "enabled" : "disabled"); + aluSelectPostProcess(device); + /* Need to delay returning failure until replacement Send arrays have been * allocated with the appropriate size. */ @@ -208,6 +208,98 @@ void aluInit(void) MixDirectHrtf = SelectHrtfMixer(); } + +static void ProcessHrtf(ALCdevice *device, ALsizei SamplesToDo) +{ + DirectHrtfState *state; + int lidx, ridx; + ALsizei c; + + if(device->AmbiUp) + ambiup_process(device->AmbiUp, + device->Dry.Buffer, device->Dry.NumChannels, device->FOAOut.Buffer, + SamplesToDo + ); + + lidx = GetChannelIdxByName(&device->RealOut, FrontLeft); + ridx = GetChannelIdxByName(&device->RealOut, FrontRight); + assert(lidx != -1 && ridx != -1); + + state = device->Hrtf; + for(c = 0;c < device->Dry.NumChannels;c++) + { + MixDirectHrtf(device->RealOut.Buffer[lidx], device->RealOut.Buffer[ridx], + device->Dry.Buffer[c], state->Offset, state->IrSize, + state->Chan[c].Coeffs, state->Chan[c].Values, SamplesToDo + ); + } + state->Offset += SamplesToDo; +} + +static void ProcessAmbiDec(ALCdevice *device, ALsizei SamplesToDo) +{ + if(device->Dry.Buffer != device->FOAOut.Buffer) + bformatdec_upSample(device->AmbiDecoder, + device->Dry.Buffer, device->FOAOut.Buffer, device->FOAOut.NumChannels, + SamplesToDo + ); + bformatdec_process(device->AmbiDecoder, + device->RealOut.Buffer, device->RealOut.NumChannels, device->Dry.Buffer, + SamplesToDo + ); +} + +static void ProcessAmbiUp(ALCdevice *device, ALsizei SamplesToDo) +{ + ambiup_process(device->AmbiUp, + device->RealOut.Buffer, device->RealOut.NumChannels, device->FOAOut.Buffer, + SamplesToDo + ); +} + +static void ProcessUhj(ALCdevice *device, ALsizei SamplesToDo) +{ + int lidx = GetChannelIdxByName(&device->RealOut, FrontLeft); + int ridx = GetChannelIdxByName(&device->RealOut, FrontRight); + if(LIKELY(lidx != -1 && ridx != -1)) + { + /* Encode to stereo-compatible 2-channel UHJ output. */ + EncodeUhj2(device->Uhj_Encoder, + device->RealOut.Buffer[lidx], device->RealOut.Buffer[ridx], + device->Dry.Buffer, SamplesToDo + ); + } +} + +static void ProcessBs2b(ALCdevice *device, ALsizei SamplesToDo) +{ + int lidx = GetChannelIdxByName(&device->RealOut, FrontLeft); + int ridx = GetChannelIdxByName(&device->RealOut, FrontRight); + if(LIKELY(lidx != -1 && ridx != -1)) + { + /* Apply binaural/crossfeed filter */ + bs2b_cross_feed(device->Bs2b, device->RealOut.Buffer[lidx], + device->RealOut.Buffer[ridx], SamplesToDo); + } +} + +void aluSelectPostProcess(ALCdevice *device) +{ + if(device->HrtfHandle) + device->PostProcess = ProcessHrtf; + else if(device->AmbiDecoder) + device->PostProcess = ProcessAmbiDec; + else if(device->AmbiUp) + device->PostProcess = ProcessAmbiUp; + else if(device->Uhj_Encoder) + device->PostProcess = ProcessUhj; + else if(device->Bs2b) + device->PostProcess = ProcessBs2b; + else + device->PostProcess = NULL; +} + + /* Prepares the interpolator for a given rate (determined by increment). A * result of AL_FALSE indicates that the filter output will completely cut * the input signal. @@ -1723,74 +1815,11 @@ void aluMixData(ALCdevice *device, ALvoid *OutBuffer, ALsizei NumSamples) device->SamplesDone %= device->Frequency; IncrementRef(&device->MixCount); - if(device->HrtfHandle) - { - DirectHrtfState *state; - int lidx, ridx; - - if(device->AmbiUp) - ambiup_process(device->AmbiUp, - device->Dry.Buffer, device->Dry.NumChannels, device->FOAOut.Buffer, - SamplesToDo - ); - - lidx = GetChannelIdxByName(&device->RealOut, FrontLeft); - ridx = GetChannelIdxByName(&device->RealOut, FrontRight); - assert(lidx != -1 && ridx != -1); - - state = device->Hrtf; - for(c = 0;c < device->Dry.NumChannels;c++) - { - MixDirectHrtf(device->RealOut.Buffer[lidx], device->RealOut.Buffer[ridx], - device->Dry.Buffer[c], state->Offset, state->IrSize, - state->Chan[c].Coeffs, state->Chan[c].Values, SamplesToDo - ); - } - state->Offset += SamplesToDo; - } - else if(device->AmbiDecoder) - { - if(device->Dry.Buffer != device->FOAOut.Buffer) - bformatdec_upSample(device->AmbiDecoder, - device->Dry.Buffer, device->FOAOut.Buffer, device->FOAOut.NumChannels, - SamplesToDo - ); - bformatdec_process(device->AmbiDecoder, - device->RealOut.Buffer, device->RealOut.NumChannels, device->Dry.Buffer, - SamplesToDo - ); - } - else if(device->AmbiUp) - { - ambiup_process(device->AmbiUp, - device->RealOut.Buffer, device->RealOut.NumChannels, device->FOAOut.Buffer, - SamplesToDo - ); - } - else if(device->Uhj_Encoder) - { - int lidx = GetChannelIdxByName(&device->RealOut, FrontLeft); - int ridx = GetChannelIdxByName(&device->RealOut, FrontRight); - if(lidx != -1 && ridx != -1) - { - /* Encode to stereo-compatible 2-channel UHJ output. */ - EncodeUhj2(device->Uhj_Encoder, - device->RealOut.Buffer[lidx], device->RealOut.Buffer[ridx], - device->Dry.Buffer, SamplesToDo - ); - } - } - else if(device->Bs2b) - { - int lidx = GetChannelIdxByName(&device->RealOut, FrontLeft); - int ridx = GetChannelIdxByName(&device->RealOut, FrontRight); - if(lidx != -1 && ridx != -1) - { - /* Apply binaural/crossfeed filter */ - bs2b_cross_feed(device->Bs2b, device->RealOut.Buffer[lidx], - device->RealOut.Buffer[ridx], SamplesToDo); - } - } + /* Apply post-process for finalizing the Dry mix to the RealOut + * (Ambisonic decode, UHJ encode, etc). + */ + if(LIKELY(device->PostProcess)) + device->PostProcess(device, SamplesToDo); if(OutBuffer) { diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index baf610b8..8c2615cf 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -462,8 +462,9 @@ typedef struct RealMixParams { ALsizei NumChannels; } RealMixParams; -struct ALCdevice_struct -{ +typedef void (*POSTPROCESS)(ALCdevice *device, ALsizei SamplesToDo); + +struct ALCdevice_struct { RefCount ref; ATOMIC(ALenum) Connected; @@ -507,6 +508,8 @@ struct ALCdevice_struct vector_FilterSubList FilterList; almtx_t FilterLock; + POSTPROCESS PostProcess; + /* HRTF state and info */ struct DirectHrtfState *Hrtf; al_string HrtfName; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 920b7b44..a151c761 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -429,6 +429,8 @@ void aluInitRenderer(ALCdevice *device, ALint hrtf_id, enum HrtfRequestMode hrtf void aluInitEffectPanning(struct ALeffectslot *slot); +void aluSelectPostProcess(ALCdevice *device); + /** * CalcDirectionCoeffs * |