aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2019-05-28 17:18:22 -0700
committerChris Robinson <[email protected]>2019-05-28 17:18:22 -0700
commit838e2bae801fec73258c4b8332b4d95a34d0aff2 (patch)
tree9ceceb72d00fc8d7ec3648e8fc471ee90bafe950 /Alc
parentc80ee5b7014d12675e2c615574c9f3f3354ffd1b (diff)
Improve a couple algorithms
Diffstat (limited to 'Alc')
-rw-r--r--Alc/mastering.cpp40
-rw-r--r--Alc/mastering.h3
-rw-r--r--Alc/uhjfilter.cpp25
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;
}
}