diff options
-rw-r--r-- | alc/effects/distortion.cpp | 24 | ||||
-rw-r--r-- | alc/effects/equalizer.cpp | 34 | ||||
-rw-r--r-- | alc/effects/modulator.cpp | 2 | ||||
-rw-r--r-- | alc/effects/reverb.cpp | 16 | ||||
-rw-r--r-- | alc/filters/biquad.cpp | 8 | ||||
-rw-r--r-- | alc/filters/biquad.h | 5 | ||||
-rw-r--r-- | alc/voice.cpp | 46 |
7 files changed, 67 insertions, 68 deletions
diff --git a/alc/effects/distortion.cpp b/alc/effects/distortion.cpp index 0916b7c6..48fc83ee 100644 --- a/alc/effects/distortion.cpp +++ b/alc/effects/distortion.cpp @@ -20,11 +20,10 @@ #include "config.h" +#include <algorithm> #include <cmath> #include <cstdlib> -#include <cmath> - #include "al/auxeffectslot.h" #include "alcmain.h" #include "alcontext.h" @@ -114,26 +113,25 @@ void DistortionState::process(const size_t samplesToDo, const al::span<const Flo * (which is fortunately first step of distortion). So combine three * operations into the one. */ - mLowpass.process(mBuffer[1], mBuffer[0], todo); + mLowpass.process({mBuffer[0], todo}, mBuffer[1]); /* Second step, do distortion using waveshaper function to emulate * signal processing during tube overdriving. Three steps of * waveshaping are intended to modify waveform without boost/clipping/ * attenuation process. */ - for(size_t i{0u};i < todo;i++) + auto proc_sample = [fc](float smp) -> float { - ALfloat smp{mBuffer[1][i]}; - - smp = (1.0f + fc) * smp/(1.0f + fc*fabsf(smp)); - smp = (1.0f + fc) * smp/(1.0f + fc*fabsf(smp)) * -1.0f; - smp = (1.0f + fc) * smp/(1.0f + fc*fabsf(smp)); - - mBuffer[0][i] = smp; - } + smp = (1.0f + fc) * smp/(1.0f + fc*std::abs(smp)); + smp = (1.0f + fc) * smp/(1.0f + fc*std::abs(smp)) * -1.0f; + smp = (1.0f + fc) * smp/(1.0f + fc*std::abs(smp)); + return smp; + }; + std::transform(std::begin(mBuffer[1]), std::begin(mBuffer[1])+todo, std::begin(mBuffer[0]), + proc_sample); /* Third step, do bandpass filtering of distorted signal. */ - mBandpass.process(mBuffer[1], mBuffer[0], todo); + mBandpass.process({mBuffer[0], todo}, mBuffer[1]); todo >>= 2; const ALfloat *outgains{mGain}; diff --git a/alc/effects/equalizer.cpp b/alc/effects/equalizer.cpp index 11fb1498..a4204b3a 100644 --- a/alc/effects/equalizer.cpp +++ b/alc/effects/equalizer.cpp @@ -117,25 +117,26 @@ void EqualizerState::update(const ALCcontext *context, const ALeffectslot *slot, /* Calculate coefficients for the each type of filter. Note that the shelf * and peaking filters' gain is for the centerpoint of the transition band, - * meaning its dB needs to be doubled for the shelf or peak to reach the - * provided gain. + * while the effect property gains are for the shelf/peak itself. So the + * property gains need their dB halved (sqrt of linear gain) for the + * shelf/peak to reach the provided gain. */ - gain = maxf(std::sqrt(props->Equalizer.LowGain), 0.0625f); /* Limit -24dB */ - f0norm = props->Equalizer.LowCutoff/frequency; + gain = std::sqrt(props->Equalizer.LowGain); + f0norm = props->Equalizer.LowCutoff / frequency; mChans[0].filter[0].setParamsFromSlope(BiquadType::LowShelf, f0norm, gain, 0.75f); - gain = maxf(std::sqrt(props->Equalizer.Mid1Gain), 0.0625f); - f0norm = props->Equalizer.Mid1Center/frequency; + gain = std::sqrt(props->Equalizer.Mid1Gain); + f0norm = props->Equalizer.Mid1Center / frequency; mChans[0].filter[1].setParamsFromBandwidth(BiquadType::Peaking, f0norm, gain, props->Equalizer.Mid1Width); - gain = maxf(std::sqrt(props->Equalizer.Mid2Gain), 0.0625f); - f0norm = props->Equalizer.Mid2Center/frequency; + gain = std::sqrt(props->Equalizer.Mid2Gain); + f0norm = props->Equalizer.Mid2Center / frequency; mChans[0].filter[2].setParamsFromBandwidth(BiquadType::Peaking, f0norm, gain, props->Equalizer.Mid2Width); - gain = maxf(std::sqrt(props->Equalizer.HighGain), 0.0625f); - f0norm = props->Equalizer.HighCutoff/frequency; + gain = std::sqrt(props->Equalizer.HighGain); + f0norm = props->Equalizer.HighCutoff / frequency; mChans[0].filter[3].setParamsFromSlope(BiquadType::HighShelf, f0norm, gain, 0.75f); /* Copy the filter coefficients for the other input channels. */ @@ -157,16 +158,17 @@ void EqualizerState::update(const ALCcontext *context, const ALeffectslot *slot, void EqualizerState::process(const size_t samplesToDo, const al::span<const FloatBufferLine> samplesIn, const al::span<FloatBufferLine> samplesOut) { + const al::span<float> buffer{mSampleBuffer, samplesToDo}; auto chandata = std::addressof(mChans[0]); for(const auto &input : samplesIn) { - chandata->filter[0].process(mSampleBuffer, input.data(), samplesToDo); - chandata->filter[1].process(mSampleBuffer, mSampleBuffer, samplesToDo); - chandata->filter[2].process(mSampleBuffer, mSampleBuffer, samplesToDo); - chandata->filter[3].process(mSampleBuffer, mSampleBuffer, samplesToDo); + chandata->filter[0].process({input.data(), samplesToDo}, buffer.begin()); + chandata->filter[1].process(buffer, buffer.begin()); + chandata->filter[2].process(buffer, buffer.begin()); + chandata->filter[3].process(buffer, buffer.begin()); - MixSamples({mSampleBuffer, samplesToDo}, samplesOut, chandata->CurrentGains, - chandata->TargetGains, samplesToDo, 0); + MixSamples(buffer, samplesOut, chandata->CurrentGains, chandata->TargetGains, samplesToDo, + 0u); ++chandata; } } diff --git a/alc/effects/modulator.cpp b/alc/effects/modulator.cpp index aa339dea..00afa052 100644 --- a/alc/effects/modulator.cpp +++ b/alc/effects/modulator.cpp @@ -146,7 +146,7 @@ void ModulatorState::process(const size_t samplesToDo, const al::span<const Floa { alignas(16) ALfloat temps[MAX_UPDATE_SAMPLES]; - chandata->Filter.process(temps, &input[base], td); + chandata->Filter.process({&input[base], td}, temps); for(size_t i{0u};i < td;i++) temps[i] *= modsamples[i]; diff --git a/alc/effects/reverb.cpp b/alc/effects/reverb.cpp index 6a5503f5..c8ebba68 100644 --- a/alc/effects/reverb.cpp +++ b/alc/effects/reverb.cpp @@ -286,10 +286,10 @@ struct T60Filter { const ALfloat hfDecayTime, const ALfloat lf0norm, const ALfloat hf0norm); /* Applies the two T60 damping filter sections. */ - void process(ALfloat *samples, const size_t todo) + void process(const al::span<float> samples) { - HFFilter.process(samples, samples, todo); - LFFilter.process(samples, samples, todo); + HFFilter.process(samples, samples.begin()); + LFFilter.process(samples, samples.begin()); } }; @@ -1359,7 +1359,7 @@ void ReverbState::lateUnfaded(const size_t offset, const size_t todo) late_delay.Line[late_feedb_tap++][j]*midGain; } while(--td); } - mLate.T60[j].process(mTempSamples[j].data(), todo); + mLate.T60[j].process({mTempSamples[j].data(), todo}); } /* Apply a vector all-pass to improve micro-surface diffusion, and write @@ -1420,7 +1420,7 @@ void ReverbState::lateFaded(const size_t offset, const size_t todo, const ALfloa late_delay.Line[late_feedb_tap1++][j]*gfade1; } while(--td); } - mLate.T60[j].process(mTempSamples[j].data(), todo); + mLate.T60[j].process({mTempSamples[j].data(), todo}); } mLate.VecAp.processFaded(mTempSamples, offset, mixX, mixY, fade, fadeStep, todo); @@ -1445,9 +1445,9 @@ void ReverbState::process(const size_t samplesToDo, const al::span<const FloatBu MixRowSamples(tmpspan, {B2A[c], numInput}, samplesIn[0].data(), samplesIn[0].size()); /* Band-pass the incoming samples and feed the initial delay line. */ - mFilter[c].Lp.process(mTempLine.data(), mTempLine.data(), samplesToDo); - mFilter[c].Hp.process(mTempLine.data(), mTempLine.data(), samplesToDo); - mDelay.write(offset, c, mTempLine.data(), samplesToDo); + mFilter[c].Lp.process(tmpspan, tmpspan.begin()); + mFilter[c].Hp.process(tmpspan, tmpspan.begin()); + mDelay.write(offset, c, tmpspan.cbegin(), samplesToDo); } /* Process reverb for these samples. */ diff --git a/alc/filters/biquad.cpp b/alc/filters/biquad.cpp index 13cbca3f..271ca696 100644 --- a/alc/filters/biquad.cpp +++ b/alc/filters/biquad.cpp @@ -89,10 +89,8 @@ void BiquadFilterR<Real>::setParams(BiquadType type, Real f0norm, Real gain, Rea } template<typename Real> -void BiquadFilterR<Real>::process(Real *dst, const Real *src, const size_t numsamples) +void BiquadFilterR<Real>::process(const al::span<const Real> src, Real *dst) { - ASSUME(numsamples > 0); - const Real b0{mB0}; const Real b1{mB1}; const Real b2{mB2}; @@ -111,12 +109,12 @@ void BiquadFilterR<Real>::process(Real *dst, const Real *src, const size_t numsa */ auto proc_sample = [b0,b1,b2,a1,a2,&z1,&z2](Real input) noexcept -> Real { - Real output = input*b0 + z1; + const Real output{input*b0 + z1}; z1 = input*b1 - output*a1 + z2; z2 = input*b2 - output*a2; return output; }; - std::transform(src, src+numsamples, dst, proc_sample); + std::transform(src.cbegin(), src.cend(), dst, proc_sample); mZ1 = z1; mZ2 = z2; diff --git a/alc/filters/biquad.h b/alc/filters/biquad.h index a8bc86e7..30eed57d 100644 --- a/alc/filters/biquad.h +++ b/alc/filters/biquad.h @@ -6,6 +6,7 @@ #include <cstddef> #include <utility> +#include "alspan.h" #include "math_defs.h" @@ -114,14 +115,14 @@ public: } - void process(Real *dst, const Real *src, const size_t numsamples); + void process(const al::span<const Real> src, Real *dst); /* Rather hacky. It's just here to support "manual" processing. */ std::pair<Real,Real> getComponents() const noexcept { return {mZ1, mZ2}; } void setComponents(Real z1, Real z2) noexcept { mZ1 = z1; mZ2 = z2; } Real processOne(const Real in, Real &z1, Real &z2) const noexcept { - Real out{in*mB0 + z1}; + const Real out{in*mB0 + z1}; z1 = in*mB1 - out*mA1 + z2; z2 = in*mB2 - out*mA2; return out; diff --git a/alc/voice.cpp b/alc/voice.cpp index 14680a78..4697cc56 100644 --- a/alc/voice.cpp +++ b/alc/voice.cpp @@ -284,31 +284,31 @@ void SendSourceStoppedEvent(ALCcontext *context, ALuint id) } -const ALfloat *DoFilters(BiquadFilter *lpfilter, BiquadFilter *hpfilter, ALfloat *dst, - const ALfloat *src, const size_t numsamples, int type) +const float *DoFilters(BiquadFilter *lpfilter, BiquadFilter *hpfilter, float *dst, + const al::span<const float> src, int type) { switch(type) { - case AF_None: - lpfilter->clear(); - hpfilter->clear(); - break; - - case AF_LowPass: - lpfilter->process(dst, src, numsamples); - hpfilter->clear(); - return dst; - case AF_HighPass: - lpfilter->clear(); - hpfilter->process(dst, src, numsamples); - return dst; - - case AF_BandPass: - lpfilter->process(dst, src, numsamples); - hpfilter->process(dst, dst, numsamples); - return dst; + case AF_None: + lpfilter->clear(); + hpfilter->clear(); + break; + + case AF_LowPass: + lpfilter->process(src, dst); + hpfilter->clear(); + return dst; + case AF_HighPass: + lpfilter->clear(); + hpfilter->process(src, dst); + return dst; + + case AF_BandPass: + lpfilter->process(src, dst); + hpfilter->process({dst, src.size()}, dst); + return dst; } - return src; + return src.data(); } @@ -694,7 +694,7 @@ void ALvoice::mix(const State vstate, ALCcontext *Context, const ALuint SamplesT { DirectParams &parms = chandata.mDryParams; const ALfloat *samples{DoFilters(&parms.LowPass, &parms.HighPass, FilterBuf, - ResampledData, DstBufferSize, mDirect.FilterType)}; + {ResampledData, DstBufferSize}, mDirect.FilterType)}; if((mFlags&VOICE_HAS_HRTF)) { @@ -726,7 +726,7 @@ void ALvoice::mix(const State vstate, ALCcontext *Context, const ALuint SamplesT SendParams &parms = chandata.mWetParams[send]; const ALfloat *samples{DoFilters(&parms.LowPass, &parms.HighPass, FilterBuf, - ResampledData, DstBufferSize, mSend[send].FilterType)}; + {ResampledData, DstBufferSize}, mSend[send].FilterType)}; const float *TargetGains{UNLIKELY(vstate == ALvoice::Stopping) ? SilentTarget.data() : parms.Gains.Target.data()}; |