diff options
author | Chris Robinson <[email protected]> | 2023-01-04 22:02:29 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2023-01-04 23:03:15 -0800 |
commit | 078b50e0ed6a0b89aa2e1f84bbbebbf24b885a4e (patch) | |
tree | db7bee5d11af40ae01d6210cfd41f6fa60a247f9 /alc/effects/compressor.cpp | |
parent | e38413a4fbb0b4f85950c929141856a767993f4f (diff) |
Simplify handling effect output for spatial effects
Effects are given a 3D ambisonic buffer of the same order as the device, for
processing surround sound. Effects that pass input channels to matching output
channels as it processes them don't need to mix each input channel to all
output channels.
At most, an input channel may mix to a different output channel, if the target
buffer uses a different channel layout, and need a gain adjustment, if it uses
a different scaling. With a 2D output buffer, a number of channels can be
skipped altogether.
Diffstat (limited to 'alc/effects/compressor.cpp')
-rw-r--r-- | alc/effects/compressor.cpp | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/alc/effects/compressor.cpp b/alc/effects/compressor.cpp index 6202e58e..a4333539 100644 --- a/alc/effects/compressor.cpp +++ b/alc/effects/compressor.cpp @@ -64,7 +64,10 @@ namespace { struct CompressorState final : public EffectState { /* Effect gains for each channel */ - float mGain[MaxAmbiChannels][MaxAmbiChannels]{}; + struct { + uint mTarget{INVALID_CHANNEL_INDEX}; + float mGain{1.0f}; + } mChans[MaxAmbiChannels]; /* Effect parameters */ bool mEnabled{true}; @@ -103,9 +106,12 @@ void CompressorState::update(const ContextBase*, const EffectSlot *slot, mEnabled = props->Compressor.OnOff; mOutTarget = target.Main->Buffer; - auto set_gains = [slot,target](auto &gains, al::span<const float,MaxAmbiChannels> coeffs) - { ComputePanGains(target.Main, coeffs.data(), slot->Gain, gains); }; - SetAmbiPanIdentity(std::begin(mGain), slot->Wet.Buffer.size(), set_gains); + auto set_channel = [this](size_t idx, uint target, float gain) + { + mChans[idx].mTarget = target; + mChans[idx].mGain = gain; + }; + target.Main->setAmbiMixParams(slot->Wet, slot->Gain, set_channel); } void CompressorState::process(const size_t samplesToDo, @@ -158,19 +164,22 @@ void CompressorState::process(const size_t samplesToDo, mEnvFollower = env; /* Now compress the signal amplitude to output. */ - auto changains = std::addressof(mGain[0]); + auto chan = std::cbegin(mChans); for(const auto &input : samplesIn) { - const float *outgains{*(changains++)}; - for(FloatBufferLine &output : samplesOut) + const size_t outidx{chan->mTarget}; + if(outidx != INVALID_CHANNEL_INDEX) { - const float gain{*(outgains++)}; + const float *RESTRICT src{input.data() + base}; + float *RESTRICT dst{samplesOut[outidx].data() + base}; + const float gain{chan->mGain}; if(!(std::fabs(gain) > GainSilenceThreshold)) - continue; - - for(size_t i{0u};i < td;i++) - output[base+i] += input[base+i] * gains[i] * gain; + { + for(size_t i{0u};i < td;i++) + dst[i] += src[i] * gains[i] * gain; + } } + ++chan; } base += td; |