diff options
author | Chris Robinson <[email protected]> | 2019-05-28 17:18:22 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2019-05-28 17:18:22 -0700 |
commit | 838e2bae801fec73258c4b8332b4d95a34d0aff2 (patch) | |
tree | 9ceceb72d00fc8d7ec3648e8fc471ee90bafe950 /Alc | |
parent | c80ee5b7014d12675e2c615574c9f3f3354ffd1b (diff) |
Improve a couple algorithms
Diffstat (limited to 'Alc')
-rw-r--r-- | Alc/mastering.cpp | 40 | ||||
-rw-r--r-- | Alc/mastering.h | 3 | ||||
-rw-r--r-- | Alc/uhjfilter.cpp | 25 |
3 files changed, 39 insertions, 29 deletions
diff --git a/Alc/mastering.cpp b/Alc/mastering.cpp index 2cf6acf5..00b79e67 100644 --- a/Alc/mastering.cpp +++ b/Alc/mastering.cpp @@ -295,28 +295,30 @@ void GainCompressor(Compressor *Comp, const ALsizei SamplesToDo) */ void SignalDelay(Compressor *Comp, const ALsizei SamplesToDo, FloatBufferLine *OutBuffer) { - static constexpr ALsizei mask{BUFFERSIZE - 1}; const ALsizei numChans{Comp->mNumChans}; - const ALsizei indexIn{Comp->mDelayIndex}; - const ALsizei indexOut{Comp->mDelayIndex - Comp->mLookAhead}; + const ALsizei lookAhead{Comp->mLookAhead}; ASSUME(SamplesToDo > 0); ASSUME(numChans > 0); + ASSUME(lookAhead > 0); for(ALsizei c{0};c < numChans;c++) { - ALfloat *RESTRICT inout{al::assume_aligned<16>(OutBuffer[c].data())}; - ALfloat *RESTRICT delay{al::assume_aligned<16>(Comp->mDelay[c])}; - for(ALsizei i{0};i < SamplesToDo;i++) - { - const ALfloat sig{inout[i]}; + ALfloat *inout{al::assume_aligned<16>(OutBuffer[c].data())}; + ALfloat *delaybuf{al::assume_aligned<16>(Comp->mDelay[c].data())}; - inout[i] = delay[(indexOut + i) & mask]; - delay[(indexIn + i) & mask] = sig; + auto inout_end = inout + SamplesToDo; + if(LIKELY(SamplesToDo >= lookAhead)) + { + auto delay_end = std::rotate(inout, inout_end - lookAhead, inout_end); + std::swap_ranges(inout, delay_end, delaybuf); + } + else + { + auto delay_start = std::swap_ranges(inout, inout_end, delaybuf); + std::rotate(delaybuf, delay_start, delaybuf + lookAhead); } } - - Comp->mDelayIndex = (indexIn + SamplesToDo) & mask; } } // namespace @@ -354,9 +356,10 @@ std::unique_ptr<Compressor> CompressorInit(const ALsizei NumChans, const ALuint const ALfloat Ratio, const ALfloat KneeDb, const ALfloat AttackTime, const ALfloat ReleaseTime) { - auto lookAhead = static_cast<ALsizei>( + const auto lookAhead = static_cast<ALsizei>( clampf(std::round(LookAheadTime*SampleRate), 0.0f, BUFFERSIZE-1)); - auto hold = static_cast<ALsizei>(clampf(std::round(HoldTime*SampleRate), 0.0f, BUFFERSIZE-1)); + const auto hold = static_cast<ALsizei>( + clampf(std::round(HoldTime*SampleRate), 0.0f, BUFFERSIZE-1)); size_t size{sizeof(Compressor)}; if(lookAhead > 0) @@ -398,15 +401,15 @@ std::unique_ptr<Compressor> CompressorInit(const ALsizei NumChans, const ALuint { if(hold > 1) { - Comp->mHold = new (reinterpret_cast<void*>(Comp.get() + 1)) SlidingHold{}; + Comp->mHold = new (static_cast<void*>(Comp.get() + 1)) SlidingHold{}; Comp->mHold->mValues[0] = -std::numeric_limits<float>::infinity(); Comp->mHold->mExpiries[0] = hold; Comp->mHold->mLength = hold; - Comp->mDelay = reinterpret_cast<ALfloat(*)[BUFFERSIZE]>(Comp->mHold + 1); + Comp->mDelay = new (static_cast<void*>(Comp->mHold + 1)) FloatBufferLine{}; } else { - Comp->mDelay = reinterpret_cast<ALfloat(*)[BUFFERSIZE]>(Comp.get() + 1); + Comp->mDelay = new (static_cast<void*>(Comp.get() + 1)) FloatBufferLine{}; } } @@ -422,6 +425,9 @@ Compressor::~Compressor() if(mHold) mHold->~SlidingHold(); mHold = nullptr; + if(mDelay) + mDelay->~FloatBufferLine(); + mDelay = nullptr; } diff --git a/Alc/mastering.h b/Alc/mastering.h index 6cc40ba3..31d0ef97 100644 --- a/Alc/mastering.h +++ b/Alc/mastering.h @@ -50,8 +50,7 @@ struct Compressor { alignas(16) ALfloat mCrestFactor[BUFFERSIZE]{}; SlidingHold *mHold{nullptr}; - ALfloat (*mDelay)[BUFFERSIZE]{nullptr}; - ALsizei mDelayIndex{0}; + FloatBufferLine *mDelay{nullptr}; ALfloat mCrestCoeff{0.0f}; ALfloat mGainEstimate{0.0f}; diff --git a/Alc/uhjfilter.cpp b/Alc/uhjfilter.cpp index acdf6f0b..c2657f9f 100644 --- a/Alc/uhjfilter.cpp +++ b/Alc/uhjfilter.cpp @@ -66,15 +66,17 @@ void Uhj2Encoder::encode(FloatBufferLine &LeftOut, FloatBufferLine &RightOut, Fl ASSUME(SamplesToDo > 0); + auto winput = InSamples[0].cbegin(); + auto xinput = InSamples[1].cbegin(); + auto yinput = InSamples[2].cbegin(); for(ALsizei base{0};base < SamplesToDo;) { - ALsizei todo = mini(SamplesToDo - base, MAX_UPDATE_SAMPLES); + const ALsizei todo{mini(SamplesToDo - base, MAX_UPDATE_SAMPLES)}; ASSUME(todo > 0); /* D = 0.6554516*Y */ - const ALfloat *RESTRICT input{al::assume_aligned<16>(InSamples[2].data()+base)}; - for(ALsizei i{0};i < todo;i++) - temp[i] = 0.6554516f*input[i]; + std::transform(yinput+base, yinput+todo, std::begin(temp), + [](const float y) noexcept -> float { return 0.6554516f*y; }); allpass_process(&mFilter1_Y[0], temp, temp, Filter1CoeffSqr[0], todo); allpass_process(&mFilter1_Y[1], temp, temp, Filter1CoeffSqr[1], todo); allpass_process(&mFilter1_Y[2], temp, temp, Filter1CoeffSqr[2], todo); @@ -89,10 +91,9 @@ void Uhj2Encoder::encode(FloatBufferLine &LeftOut, FloatBufferLine &RightOut, Fl mLastY = temp[todo-1]; /* D += j(-0.3420201*W + 0.5098604*X) */ - const ALfloat *RESTRICT input0{al::assume_aligned<16>(InSamples[0].data()+base)}; - const ALfloat *RESTRICT input1{al::assume_aligned<16>(InSamples[1].data()+base)}; - for(ALsizei i{0};i < todo;i++) - temp[i] = -0.3420201f*input0[i] + 0.5098604f*input1[i]; + std::transform(winput, winput+todo, xinput, std::begin(temp), + [](const float w, const float x) noexcept -> float + { return -0.3420201f*w + 0.5098604f*x; }); allpass_process(&mFilter2_WX[0], temp, temp, Filter2CoeffSqr[0], todo); allpass_process(&mFilter2_WX[1], temp, temp, Filter2CoeffSqr[1], todo); allpass_process(&mFilter2_WX[2], temp, temp, Filter2CoeffSqr[2], todo); @@ -101,8 +102,9 @@ void Uhj2Encoder::encode(FloatBufferLine &LeftOut, FloatBufferLine &RightOut, Fl D[i] += temp[i]; /* S = 0.9396926*W + 0.1855740*X */ - for(ALsizei i{0};i < todo;i++) - temp[i] = 0.9396926f*input0[i] + 0.1855740f*input1[i]; + std::transform(winput, winput+todo, xinput, std::begin(temp), + [](const float w, const float x) noexcept -> float + { return 0.9396926f*w + 0.1855740f*x; }); allpass_process(&mFilter1_WX[0], temp, temp, Filter1CoeffSqr[0], todo); allpass_process(&mFilter1_WX[1], temp, temp, Filter1CoeffSqr[1], todo); allpass_process(&mFilter1_WX[2], temp, temp, Filter1CoeffSqr[2], todo); @@ -121,6 +123,9 @@ void Uhj2Encoder::encode(FloatBufferLine &LeftOut, FloatBufferLine &RightOut, Fl for(ALsizei i{0};i < todo;i++) right[i] += (S[i] - D[i]) * 0.5f; + winput += todo; + xinput += todo; + yinput += todo; base += todo; } } |