diff options
author | Chris Robinson <[email protected]> | 2016-04-15 22:05:47 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2016-04-15 22:05:47 -0700 |
commit | a6c70992b01b168d561c448fa235a86c9697b6ef (patch) | |
tree | c7fcc5d4d66e0f50a34e982abb954421c596c5d8 | |
parent | e16032e1f0c92ff23c70393eccbac7def14d4bab (diff) |
More directly map coefficients for ambisonic mixing buffers
Instead of looping over all the coefficients for each channel with multiplies,
when we know only one will have a non-0 factor for ambisonic mixing buffers,
just index the one with a non-0 factor.
-rw-r--r-- | Alc/ALu.c | 13 | ||||
-rw-r--r-- | Alc/effects/autowah.c | 2 | ||||
-rw-r--r-- | Alc/effects/chorus.c | 8 | ||||
-rw-r--r-- | Alc/effects/compressor.c | 4 | ||||
-rw-r--r-- | Alc/effects/dedicated.c | 11 | ||||
-rw-r--r-- | Alc/effects/distortion.c | 2 | ||||
-rw-r--r-- | Alc/effects/echo.c | 6 | ||||
-rw-r--r-- | Alc/effects/equalizer.c | 4 | ||||
-rw-r--r-- | Alc/effects/flanger.c | 8 | ||||
-rw-r--r-- | Alc/effects/modulator.c | 4 | ||||
-rw-r--r-- | Alc/effects/reverb.c | 21 | ||||
-rw-r--r-- | Alc/panning.c | 166 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 16 | ||||
-rw-r--r-- | OpenAL32/Include/alu.h | 25 |
14 files changed, 160 insertions, 130 deletions
@@ -519,8 +519,8 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A voice->Direct.OutBuffer = Device->FOAOut.Buffer; voice->Direct.OutChannels = Device->FOAOut.NumChannels; for(c = 0;c < num_channels;c++) - ComputeFirstOrderGains(Device->FOAOut.AmbiCoeffs, Device->FOAOut.NumChannels, matrix.m[c], - DryGain, voice->Direct.Gains[c].Target); + ComputeFirstOrderGains(Device->FOAOut, matrix.m[c], DryGain, + voice->Direct.Gains[c].Target); for(i = 0;i < NumSends;i++) { @@ -682,9 +682,8 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A else { CalcAngleCoeffs(chans[c].angle, chans[c].elevation, coeffs); - ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels, - Device->Dry.CoeffCount, coeffs, DryGain, voice->Direct.Gains[c].Target - ); + ComputePanningGains(Device->Dry, coeffs, DryGain, + voice->Direct.Gains[c].Target); } for(i = 0;i < NumSends;i++) @@ -1184,9 +1183,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte else { CalcDirectionCoeffs(dir, coeffs); - ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels, - Device->Dry.CoeffCount, coeffs, DryGain, voice->Direct.Gains[0].Target - ); + ComputePanningGains(Device->Dry, coeffs, DryGain, voice->Direct.Gains[0].Target); } for(i = 0;i < NumSends;i++) diff --git a/Alc/effects/autowah.c b/Alc/effects/autowah.c index 20ae26e4..7c5abfb1 100644 --- a/Alc/effects/autowah.c +++ b/Alc/effects/autowah.c @@ -75,7 +75,7 @@ static ALvoid ALautowahState_update(ALautowahState *state, const ALCdevice *devi state->PeakGain = slot->EffectProps.Autowah.PeakGain; state->Resonance = slot->EffectProps.Autowah.Resonance; - ComputeAmbientGains(device->Dry.AmbiCoeffs, device->Dry.NumChannels, slot->Gain, state->Gain); + ComputeAmbientGains(device->Dry, slot->Gain, state->Gain); } static ALvoid ALautowahState_process(ALautowahState *state, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels) diff --git a/Alc/effects/chorus.c b/Alc/effects/chorus.c index a55983ab..94c9fc47 100644 --- a/Alc/effects/chorus.c +++ b/Alc/effects/chorus.c @@ -113,13 +113,9 @@ static ALvoid ALchorusState_update(ALchorusState *state, const ALCdevice *Device /* Gains for left and right sides */ CalcXYZCoeffs(-1.0f, 0.0f, 0.0f, coeffs); - ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels, - Device->Dry.CoeffCount, coeffs, Slot->Gain, state->Gain[0] - ); + ComputePanningGains(Device->Dry, coeffs, Slot->Gain, state->Gain[0]); CalcXYZCoeffs( 1.0f, 0.0f, 0.0f, coeffs); - ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels, - Device->Dry.CoeffCount, coeffs, Slot->Gain, state->Gain[1] - ); + ComputePanningGains(Device->Dry, coeffs, Slot->Gain, state->Gain[1]); phase = Slot->EffectProps.Chorus.Phase; rate = Slot->EffectProps.Chorus.Rate; diff --git a/Alc/effects/compressor.c b/Alc/effects/compressor.c index 4e1d55f1..bc4955b9 100644 --- a/Alc/effects/compressor.c +++ b/Alc/effects/compressor.c @@ -72,8 +72,8 @@ static ALvoid ALcompressorState_update(ALcompressorState *state, const ALCdevice STATIC_CAST(ALeffectState,state)->OutBuffer = device->FOAOut.Buffer; STATIC_CAST(ALeffectState,state)->OutChannels = device->FOAOut.NumChannels; for(i = 0;i < 4;i++) - ComputeFirstOrderGains(device->FOAOut.AmbiCoeffs, device->FOAOut.NumChannels, - matrix.m[i], slot->Gain, state->Gain[i]); + ComputeFirstOrderGains(device->FOAOut, matrix.m[i], slot->Gain, + state->Gain[i]); } static ALvoid ALcompressorState_process(ALcompressorState *state, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels) diff --git a/Alc/effects/dedicated.c b/Alc/effects/dedicated.c index 9fd10177..20acfdcf 100644 --- a/Alc/effects/dedicated.c +++ b/Alc/effects/dedicated.c @@ -59,9 +59,9 @@ static ALvoid ALdedicatedState_update(ALdedicatedState *state, const ALCdevice * int idx; if((idx=GetChannelIdxByName(device->RealOut, LFE)) != -1) { - state->gains[idx] = Gain; STATIC_CAST(ALeffectState,state)->OutBuffer = device->RealOut.Buffer; STATIC_CAST(ALeffectState,state)->OutChannels = device->RealOut.NumChannels; + state->gains[idx] = Gain; } } else if(Slot->EffectType == AL_EFFECT_DEDICATED_DIALOGUE) @@ -71,23 +71,22 @@ static ALvoid ALdedicatedState_update(ALdedicatedState *state, const ALCdevice * * plays from the front-center location. */ if((idx=GetChannelIdxByName(device->RealOut, FrontCenter)) != -1) { - state->gains[idx] = Gain; STATIC_CAST(ALeffectState,state)->OutBuffer = device->RealOut.Buffer; STATIC_CAST(ALeffectState,state)->OutChannels = device->RealOut.NumChannels; + state->gains[idx] = Gain; } else { + STATIC_CAST(ALeffectState,state)->OutBuffer = device->Dry.Buffer; + STATIC_CAST(ALeffectState,state)->OutChannels = device->Dry.NumChannels; if((idx=GetChannelIdxByName(device->Dry, FrontCenter)) != -1) state->gains[idx] = Gain; else { ALfloat coeffs[MAX_AMBI_COEFFS]; CalcXYZCoeffs(0.0f, 0.0f, -1.0f, coeffs); - ComputePanningGains(device->Dry.AmbiCoeffs, device->Dry.NumChannels, - device->Dry.CoeffCount, coeffs, Gain, state->gains); + ComputePanningGains(device->Dry, coeffs, Gain, state->gains); } - STATIC_CAST(ALeffectState,state)->OutBuffer = device->Dry.Buffer; - STATIC_CAST(ALeffectState,state)->OutChannels = device->Dry.NumChannels; } } } diff --git a/Alc/effects/distortion.c b/Alc/effects/distortion.c index 92eb1a6d..7a4c2f62 100644 --- a/Alc/effects/distortion.c +++ b/Alc/effects/distortion.c @@ -83,7 +83,7 @@ static ALvoid ALdistortionState_update(ALdistortionState *state, const ALCdevice cutoff / (frequency*4.0f), calc_rcpQ_from_bandwidth(cutoff / (frequency*4.0f), bandwidth) ); - ComputeAmbientGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels, Slot->Gain, state->Gain); + ComputeAmbientGains(Device->Dry, Slot->Gain, state->Gain); } static ALvoid ALdistortionState_process(ALdistortionState *state, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels) diff --git a/Alc/effects/echo.c b/Alc/effects/echo.c index 00bf5d9f..9fd31864 100644 --- a/Alc/effects/echo.c +++ b/Alc/effects/echo.c @@ -104,13 +104,11 @@ static ALvoid ALechoState_update(ALechoState *state, const ALCdevice *Device, co /* First tap panning */ CalcXYZCoeffs(-lrpan, 0.0f, 0.0f, coeffs); - ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels, - Device->Dry.CoeffCount, coeffs, gain, state->Gain[0]); + ComputePanningGains(Device->Dry, coeffs, gain, state->Gain[0]); /* Second tap panning */ CalcXYZCoeffs( lrpan, 0.0f, 0.0f, coeffs); - ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels, - Device->Dry.CoeffCount, coeffs, gain, state->Gain[1]); + ComputePanningGains(Device->Dry, coeffs, gain, state->Gain[1]); } static ALvoid ALechoState_process(ALechoState *state, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels) diff --git a/Alc/effects/equalizer.c b/Alc/effects/equalizer.c index f3383bd2..e0fa010e 100644 --- a/Alc/effects/equalizer.c +++ b/Alc/effects/equalizer.c @@ -113,8 +113,8 @@ static ALvoid ALequalizerState_update(ALequalizerState *state, const ALCdevice * STATIC_CAST(ALeffectState,state)->OutBuffer = device->FOAOut.Buffer; STATIC_CAST(ALeffectState,state)->OutChannels = device->FOAOut.NumChannels; for(i = 0;i < MAX_EFFECT_CHANNELS;i++) - ComputeFirstOrderGains(device->FOAOut.AmbiCoeffs, device->FOAOut.NumChannels, - matrix.m[i], slot->Gain, state->Gain[i]); + ComputeFirstOrderGains(device->FOAOut, matrix.m[i], slot->Gain, + state->Gain[i]); /* Calculate coefficients for the each type of filter. Note that the shelf * filters' gain is for the reference frequency, which is the centerpoint diff --git a/Alc/effects/flanger.c b/Alc/effects/flanger.c index c323c17a..e394f9f2 100644 --- a/Alc/effects/flanger.c +++ b/Alc/effects/flanger.c @@ -113,13 +113,9 @@ static ALvoid ALflangerState_update(ALflangerState *state, const ALCdevice *Devi /* Gains for left and right sides */ CalcXYZCoeffs(-1.0f, 0.0f, 0.0f, coeffs); - ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels, - Device->Dry.CoeffCount, coeffs, Slot->Gain, state->Gain[0] - ); + ComputePanningGains(Device->Dry, coeffs, Slot->Gain, state->Gain[0]); CalcXYZCoeffs( 1.0f, 0.0f, 0.0f, coeffs); - ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels, - Device->Dry.CoeffCount, coeffs, Slot->Gain, state->Gain[1] - ); + ComputePanningGains(Device->Dry, coeffs, Slot->Gain, state->Gain[1]); phase = Slot->EffectProps.Flanger.Phase; rate = Slot->EffectProps.Flanger.Rate; diff --git a/Alc/effects/modulator.c b/Alc/effects/modulator.c index 03e0d458..fb75043a 100644 --- a/Alc/effects/modulator.c +++ b/Alc/effects/modulator.c @@ -132,8 +132,8 @@ static ALvoid ALmodulatorState_update(ALmodulatorState *state, const ALCdevice * STATIC_CAST(ALeffectState,state)->OutBuffer = Device->FOAOut.Buffer; STATIC_CAST(ALeffectState,state)->OutChannels = Device->FOAOut.NumChannels; for(i = 0;i < MAX_EFFECT_CHANNELS;i++) - ComputeFirstOrderGains(Device->FOAOut.AmbiCoeffs, Device->FOAOut.NumChannels, - matrix.m[i], Slot->Gain, state->Gain[i]); + ComputeFirstOrderGains(Device->FOAOut, matrix.m[i], Slot->Gain, + state->Gain[i]); } static ALvoid ALmodulatorState_process(ALmodulatorState *state, ALuint SamplesToDo, const ALfloat (*restrict SamplesIn)[BUFFERSIZE], ALfloat (*restrict SamplesOut)[BUFFERSIZE], ALuint NumChannels) diff --git a/Alc/effects/reverb.c b/Alc/effects/reverb.c index e5c19d82..bb980ac2 100644 --- a/Alc/effects/reverb.c +++ b/Alc/effects/reverb.c @@ -720,8 +720,7 @@ static ALvoid UpdateMixedPanning(const ALCdevice *Device, const ALfloat *Reflect length = minf(length, 1.0f); CalcDirectionCoeffs(pan, coeffs); - ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels, - Device->Dry.CoeffCount, coeffs, Gain, DirGains); + ComputePanningGains(Device->Dry, coeffs, Gain, DirGains); for(i = 0;i < Device->Dry.NumChannels;i++) State->Early.PanGain[3][i] = DirGains[i] * EarlyGain * length; for(i = 0;i < Device->RealOut.NumChannels;i++) @@ -745,8 +744,7 @@ static ALvoid UpdateMixedPanning(const ALCdevice *Device, const ALfloat *Reflect length = minf(length, 1.0f); CalcDirectionCoeffs(pan, coeffs); - ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels, - Device->Dry.CoeffCount, coeffs, Gain, DirGains); + ComputePanningGains(Device->Dry, coeffs, Gain, DirGains); for(i = 0;i < Device->Dry.NumChannels;i++) State->Late.PanGain[3][i] = DirGains[i] * LateGain * length; for(i = 0;i < Device->RealOut.NumChannels;i++) @@ -763,8 +761,7 @@ static ALvoid UpdateDirectPanning(const ALCdevice *Device, const ALfloat *Reflec ALuint i; /* Apply a boost of about 3dB to better match the expected stereo output volume. */ - ComputeAmbientGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels, - Gain*1.414213562f, AmbientGains); + ComputeAmbientGains(Device->Dry, Gain*1.414213562f, AmbientGains); memset(State->Early.PanGain, 0, sizeof(State->Early.PanGain)); length = sqrtf(ReflectionsPan[0]*ReflectionsPan[0] + ReflectionsPan[1]*ReflectionsPan[1] + ReflectionsPan[2]*ReflectionsPan[2]); @@ -787,8 +784,7 @@ static ALvoid UpdateDirectPanning(const ALCdevice *Device, const ALfloat *Reflec length = minf(length, 1.0f); CalcDirectionCoeffs(pan, coeffs); - ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels, - Device->Dry.CoeffCount, coeffs, Gain, DirGains); + ComputePanningGains(Device->Dry, coeffs, Gain, DirGains); for(i = 0;i < Device->Dry.NumChannels;i++) State->Early.PanGain[i&3][i] = lerp(AmbientGains[i], DirGains[i], length) * EarlyGain; } @@ -810,8 +806,7 @@ static ALvoid UpdateDirectPanning(const ALCdevice *Device, const ALfloat *Reflec length = minf(length, 1.0f); CalcDirectionCoeffs(pan, coeffs); - ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels, - Device->Dry.CoeffCount, coeffs, Gain, DirGains); + ComputePanningGains(Device->Dry, coeffs, Gain, DirGains); for(i = 0;i < Device->Dry.NumChannels;i++) State->Late.PanGain[i&3][i] = lerp(AmbientGains[i], DirGains[i], length) * LateGain; } @@ -861,8 +856,7 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection for(i = 0;i < 4;i++) { CalcDirectionCoeffs(PanDirs[i], coeffs); - ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels, - Device->Dry.CoeffCount, coeffs, Gain*EarlyGain*gain[i], + ComputePanningGains(Device->Dry, coeffs, Gain*EarlyGain*gain[i], State->Early.PanGain[i]); } @@ -893,8 +887,7 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection for(i = 0;i < 4;i++) { CalcDirectionCoeffs(PanDirs[i], coeffs); - ComputePanningGains(Device->Dry.AmbiCoeffs, Device->Dry.NumChannels, - Device->Dry.CoeffCount, coeffs, Gain*LateGain*gain[i], + ComputePanningGains(Device->Dry, coeffs, Gain*LateGain*gain[i], State->Late.PanGain[i]); } } diff --git a/Alc/panning.c b/Alc/panning.c index 9ad9d2a7..0e04f074 100644 --- a/Alc/panning.c +++ b/Alc/panning.c @@ -149,7 +149,7 @@ void CalcAngleCoeffs(ALfloat azimuth, ALfloat elevation, ALfloat coeffs[MAX_AMBI } -void ComputeAmbientGains(const ChannelConfig *chancoeffs, ALuint numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]) +void ComputeAmbientGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]) { ALuint i; @@ -164,7 +164,22 @@ void ComputeAmbientGains(const ChannelConfig *chancoeffs, ALuint numchans, ALflo gains[i] = 0.0f; } -void ComputePanningGains(const ChannelConfig *chancoeffs, ALuint numchans, ALuint numcoeffs, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]) +void ComputeAmbientGainsBF(const BFChannelConfig *chanmap, ALuint numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]) +{ + ALfloat gain = 0.0f; + ALuint i; + + for(i = 0;i < numchans;i++) + { + if(chanmap[i].Index == 0) + gain += chanmap[i].Scale; + } + gains[0] = gain * 1.414213562f * ingain; + for(i = 1;i < MAX_OUTPUT_CHANNELS;i++) + gains[i] = 0.0f; +} + +void ComputePanningGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, ALuint numcoeffs, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]) { ALuint i, j; @@ -189,7 +204,7 @@ void ComputePanningGainsBF(const BFChannelConfig *chanmap, ALuint numchans, cons gains[i] = 0.0f; } -void ComputeFirstOrderGains(const ChannelConfig *chancoeffs, ALuint numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]) +void ComputeFirstOrderGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]) { ALuint i, j; @@ -524,16 +539,34 @@ static void InitPanning(ALCdevice *device) for(i = 0;i < MAX_OUTPUT_CHANNELS;i++) device->Dry.ChannelName[i] = device->RealOut.ChannelName[i]; - SetChannelMap(device->Dry.ChannelName, device->Dry.AmbiCoeffs, chanmap, count, - &device->Dry.NumChannels, AL_TRUE); - device->Dry.CoeffCount = coeffcount; + if(device->FmtChans == DevFmtBFormat3D) + { + for(i = 0;i < count;i++) + { + ALuint acn = FuMa2ACN[i]; + device->Dry.Ambi.Map[i].Scale = 1.0f/FuMa2N3DScale[acn]; + device->Dry.Ambi.Map[i].Index = acn; + } + device->Dry.CoeffCount = 0; + device->Dry.NumChannels = count; - memset(device->FOAOut.AmbiCoeffs, 0, sizeof(device->FOAOut.AmbiCoeffs)); - for(i = 0;i < device->Dry.NumChannels;i++) + memcpy(&device->FOAOut.Ambi, &device->Dry.Ambi, sizeof(device->FOAOut.Ambi)); + device->FOAOut.CoeffCount = device->Dry.CoeffCount; + } + else { - device->FOAOut.AmbiCoeffs[i][0] = device->Dry.AmbiCoeffs[i][0]; - for(j = 1;j < 4;j++) - device->FOAOut.AmbiCoeffs[i][j] = device->Dry.AmbiCoeffs[i][j] * ambiscale; + SetChannelMap(device->Dry.ChannelName, device->Dry.Ambi.Coeffs, chanmap, count, + &device->Dry.NumChannels, AL_TRUE); + device->Dry.CoeffCount = coeffcount; + + memset(&device->FOAOut.Ambi, 0, sizeof(device->FOAOut.Ambi)); + for(i = 0;i < device->Dry.NumChannels;i++) + { + device->FOAOut.Ambi.Coeffs[i][0] = device->Dry.Ambi.Coeffs[i][0]; + for(j = 1;j < 4;j++) + device->FOAOut.Ambi.Coeffs[i][j] = device->Dry.Ambi.Coeffs[i][j] * ambiscale; + } + device->FOAOut.CoeffCount = 4; } } @@ -585,78 +618,60 @@ static void InitCustomPanning(ALCdevice *device, const AmbDecConf *conf, const A for(i = 0;i < MAX_OUTPUT_CHANNELS;i++) device->Dry.ChannelName[i] = device->RealOut.ChannelName[i]; - SetChannelMap(device->Dry.ChannelName, device->Dry.AmbiCoeffs, chanmap, + SetChannelMap(device->Dry.ChannelName, device->Dry.Ambi.Coeffs, chanmap, conf->NumSpeakers, &device->Dry.NumChannels, AL_FALSE); device->Dry.CoeffCount = (conf->ChanMask > 0x1ff) ? 16 : (conf->ChanMask > 0xf) ? 9 : 4; - memset(device->FOAOut.AmbiCoeffs, 0, sizeof(device->FOAOut.AmbiCoeffs)); + memset(&device->FOAOut.Ambi, 0, sizeof(device->FOAOut.Ambi)); for(i = 0;i < device->Dry.NumChannels;i++) { - device->FOAOut.AmbiCoeffs[i][0] = device->Dry.AmbiCoeffs[i][0]; + device->FOAOut.Ambi.Coeffs[i][0] = device->Dry.Ambi.Coeffs[i][0]; for(j = 1;j < 4;j++) - device->FOAOut.AmbiCoeffs[i][j] = device->Dry.AmbiCoeffs[i][j] * ambiscale; + device->FOAOut.Ambi.Coeffs[i][j] = device->Dry.Ambi.Coeffs[i][j] * ambiscale; } + device->FOAOut.CoeffCount = 4; } static void InitHQPanning(ALCdevice *device, const AmbDecConf *conf, const ALuint speakermap[MAX_OUTPUT_CHANNELS]) { - /* NOTE: This is ACN/N3D ordering and scaling, rather than FuMa. */ - static const ChannelMap Ambi3D[9] = { - /* Zeroth order */ - { Aux0, { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } }, - /* First order */ - { Aux1, { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } }, - { Aux2, { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } }, - { Aux3, { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } }, - /* Second order */ - { Aux4, { 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f } }, - { Aux5, { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f } }, - { Aux6, { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f } }, - { Aux7, { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f } }, - { Aux8, { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } }, - }, Ambi2D[7] = { - /* Zeroth order */ - { Aux0, { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } }, - /* First order */ - { Aux1, { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } }, - { Aux2, { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } }, - /* Second order */ - { Aux3, { 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } }, - { Aux4, { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } }, - /* Third order */ - { Aux5, { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } }, - { Aux6, { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f } }, - }; - const ChannelMap *chanmap = NULL; const char *devname; int decflags = 0; size_t count; ALuint i; if((conf->ChanMask & ~0x831b)) - { - count = (conf->ChanMask > 0xf) ? 9 : 4; - chanmap = Ambi3D; - } + count = (conf->ChanMask > 0xf) ? (conf->ChanMask > 0x1ff) ? 16: 9 : 4; else - { count = (conf->ChanMask > 0xf) ? (conf->ChanMask > 0x1ff) ? 7 : 5 : 3; - chanmap = Ambi2D; - } devname = al_string_get_cstr(device->DeviceName); if(GetConfigValueBool(devname, "decoder", "distance-comp", 1)) decflags |= BFDF_DistanceComp; for(i = 0;i < count;i++) - device->Dry.ChannelName[i] = chanmap[i].ChanName; + device->Dry.ChannelName[i] = Aux0 + i; for(;i < MAX_OUTPUT_CHANNELS;i++) device->Dry.ChannelName[i] = InvalidChannel; - SetChannelMap(device->Dry.ChannelName, device->Dry.AmbiCoeffs, chanmap, count, - &device->Dry.NumChannels, AL_FALSE); - device->Dry.CoeffCount = (conf->ChanMask > 0x1ff) ? 16 : - (conf->ChanMask > 0xf) ? 9 : 4; + if((conf->ChanMask & ~0x831b)) + { + for(i = 0;i < count;i++) + { + device->Dry.Ambi.Map[i].Scale = 1.0f; + device->Dry.Ambi.Map[i].Index = i; + } + } + else + { + static int map[MAX_AMBI_COEFFS] = { 0, 1, 3, 4, 8, 9, 15 }; + for(i = 0;i < count;i++) + { + device->Dry.Ambi.Map[i].Scale = 1.0f; + device->Dry.Ambi.Map[i].Index = map[i]; + } + } + device->Dry.CoeffCount = 0; + device->Dry.NumChannels = count; TRACE("Enabling %s-band %s-order%s ambisonic decoder\n", (conf->FreqBands == 1) ? "single" : "dual", @@ -667,15 +682,19 @@ static void InitHQPanning(ALCdevice *device, const AmbDecConf *conf, const ALuin speakermap, decflags); if(bformatdec_getOrder(device->AmbiDecoder) < 2) - memcpy(device->FOAOut.AmbiCoeffs, device->Dry.AmbiCoeffs, - sizeof(device->FOAOut.AmbiCoeffs)); + { + memcpy(&device->FOAOut.Ambi, &device->Dry.Ambi, sizeof(device->FOAOut.Ambi)); + device->FOAOut.CoeffCount = device->Dry.CoeffCount; + } else { - memset(device->FOAOut.AmbiCoeffs, 0, sizeof(device->FOAOut.AmbiCoeffs)); - device->FOAOut.AmbiCoeffs[0][0] = 1.0f; - device->FOAOut.AmbiCoeffs[1][1] = 1.0f; - device->FOAOut.AmbiCoeffs[2][2] = 1.0f; - device->FOAOut.AmbiCoeffs[3][3] = 1.0f; + memset(&device->FOAOut.Ambi, 0, sizeof(device->FOAOut.Ambi)); + for(i = 0;i < 4;i++) + { + device->FOAOut.Ambi.Map[i].Scale = 1.0f; + device->FOAOut.Ambi.Map[i].Index = i; + } + device->FOAOut.CoeffCount = 0; } } @@ -713,12 +732,12 @@ static void InitHrtfPanning(ALCdevice *device) device->Dry.ChannelName[i] = chanmap[i].ChanName; for(;i < MAX_OUTPUT_CHANNELS;i++) device->Dry.ChannelName[i] = InvalidChannel; - SetChannelMap(device->Dry.ChannelName, device->Dry.AmbiCoeffs, chanmap, count, + SetChannelMap(device->Dry.ChannelName, device->Dry.Ambi.Coeffs, chanmap, count, &device->Dry.NumChannels, AL_TRUE); device->Dry.CoeffCount = 4; - memcpy(device->FOAOut.AmbiCoeffs, device->Dry.AmbiCoeffs, - sizeof(device->FOAOut.AmbiCoeffs)); + memcpy(&device->FOAOut.Ambi, &device->Dry.Ambi, sizeof(device->FOAOut.Ambi)); + device->FOAOut.CoeffCount = device->Dry.CoeffCount; for(i = 0;i < device->Dry.NumChannels;i++) { @@ -738,12 +757,17 @@ static void InitUhjPanning(ALCdevice *device) device->Dry.ChannelName[i] = chanmap[i].ChanName; for(;i < MAX_OUTPUT_CHANNELS;i++) device->Dry.ChannelName[i] = InvalidChannel; - SetChannelMap(device->Dry.ChannelName, device->Dry.AmbiCoeffs, chanmap, count, - &device->Dry.NumChannels, AL_TRUE); - device->Dry.CoeffCount = 4; + for(i = 0;i < count;i++) + { + ALuint acn = FuMa2ACN[i]; + device->Dry.Ambi.Map[i].Scale = 1.0f/FuMa2N3DScale[acn]; + device->Dry.Ambi.Map[i].Index = acn; + } + device->Dry.CoeffCount = 0; + device->Dry.NumChannels = count; - memcpy(device->FOAOut.AmbiCoeffs, device->Dry.AmbiCoeffs, - sizeof(device->FOAOut.AmbiCoeffs)); + memcpy(&device->FOAOut.Ambi, &device->Dry.Ambi, sizeof(device->FOAOut.Ambi)); + device->FOAOut.CoeffCount = device->Dry.CoeffCount; } void aluInitRenderer(ALCdevice *device, ALint hrtf_id, enum HrtfRequestMode hrtf_appreq, enum HrtfRequestMode hrtf_userreq) @@ -759,7 +783,7 @@ void aluInitRenderer(ALCdevice *device, ALint hrtf_id, enum HrtfRequestMode hrtf al_string_clear(&device->Hrtf_Name); device->Render_Mode = NormalRender; - memset(device->Dry.AmbiCoeffs, 0, sizeof(device->Dry.AmbiCoeffs)); + memset(&device->Dry.Ambi, 0, sizeof(device->Dry.Ambi)); device->Dry.CoeffCount = 0; device->Dry.NumChannels = 0; diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 52296a15..12c4c610 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -509,8 +509,12 @@ struct ALCdevice_struct struct { /* Channel names for the dry buffer mix. */ enum Channel ChannelName[MAX_OUTPUT_CHANNELS]; - /* Ambisonic coefficients for mixing to the dry buffer. */ - ChannelConfig AmbiCoeffs[MAX_OUTPUT_CHANNELS]; + union { + /* Ambisonic coefficients for mixing to the dry buffer. */ + ChannelConfig Coeffs[MAX_OUTPUT_CHANNELS]; + /* Coefficient channel mapping for mixing to the dry buffer. */ + BFChannelConfig Map[MAX_OUTPUT_CHANNELS]; + } Ambi; /* Number of coefficients in each ChannelConfig to mix together (4 for * first-order, 9 for second-order, etc). */ @@ -523,8 +527,12 @@ struct ALCdevice_struct /* First-order ambisonics output, to be upsampled to the dry buffer if different. */ struct { - /* Ambisonic coefficients for mixing. */ - ChannelConfig AmbiCoeffs[MAX_OUTPUT_CHANNELS]; + union { + ChannelConfig Coeffs[MAX_OUTPUT_CHANNELS]; + BFChannelConfig Map[MAX_OUTPUT_CHANNELS]; + } Ambi; + /* Will only be 4 or 0. */ + ALuint CoeffCount; ALfloat (*Buffer)[BUFFERSIZE]; ALuint NumChannels; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 8b11bdd4..c6b5aba0 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -330,7 +330,14 @@ void CalcAngleCoeffs(ALfloat azimuth, ALfloat elevation, ALfloat coeffs[MAX_AMBI * * Computes channel gains for ambient, omni-directional sounds. */ -void ComputeAmbientGains(const ChannelConfig *chancoeffs, ALuint numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); +#define ComputeAmbientGains(b, g, o) do { \ + if((b).CoeffCount > 0) \ + ComputeAmbientGainsMC((b).Ambi.Coeffs, (b).NumChannels, g, o); \ + else \ + ComputeAmbientGainsBF((b).Ambi.Map, (b).NumChannels, g, o); \ +} while (0) +void ComputeAmbientGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); +void ComputeAmbientGainsBF(const BFChannelConfig *chanmap, ALuint numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); /** * ComputePanningGains @@ -338,7 +345,13 @@ void ComputeAmbientGains(const ChannelConfig *chancoeffs, ALuint numchans, ALflo * Computes panning gains using the given channel decoder coefficients and the * pre-calculated direction or angle coefficients. */ -void ComputePanningGains(const ChannelConfig *chancoeffs, ALuint numchans, ALuint numcoeffs, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); +#define ComputePanningGains(b, c, g, o) do { \ + if((b).CoeffCount > 0) \ + ComputePanningGainsMC((b).Ambi.Coeffs, (b).NumChannels, (b).CoeffCount, c, g, o);\ + else \ + ComputePanningGainsBF((b).Ambi.Map, (b).NumChannels, c, g, o); \ +} while (0) +void ComputePanningGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, ALuint numcoeffs, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); void ComputePanningGainsBF(const BFChannelConfig *chanmap, ALuint numchans, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); /** @@ -348,7 +361,13 @@ void ComputePanningGainsBF(const BFChannelConfig *chanmap, ALuint numchans, cons * a 1x4 'slice' of a transform matrix for the input channel, used to scale and * orient the sound samples. */ -void ComputeFirstOrderGains(const ChannelConfig *chancoeffs, ALuint numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); +#define ComputeFirstOrderGains(b, m, g, o) do { \ + if((b).CoeffCount > 0) \ + ComputeFirstOrderGainsMC((b).Ambi.Coeffs, (b).NumChannels, m, g, o); \ + else \ + ComputeFirstOrderGainsBF((b).Ambi.Map, (b).NumChannels, m, g, o); \ +} while (0) +void ComputeFirstOrderGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); void ComputeFirstOrderGainsBF(const BFChannelConfig *chanmap, ALuint numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); |