aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--alc/alu.cpp50
-rw-r--r--alc/front_stablizer.h14
2 files changed, 33 insertions, 31 deletions
diff --git a/alc/alu.cpp b/alc/alu.cpp
index 5ee1b4c3..17d78e71 100644
--- a/alc/alu.cpp
+++ b/alc/alu.cpp
@@ -1800,6 +1800,12 @@ void ProcessContexts(ALCdevice *device, const ALuint SamplesToDo)
}
+/* FIXME: This shouldn't really be applied to the final output mix like this,
+ * since a source mixed with direct channels shouldn't be subjected to this
+ * filtering. The only way to do that is as part of the ambisonic decode (in
+ * BFormatDec::process) where it can separate the pre-mixed direct-channel feed
+ * from the decoded soundfield.
+ */
void ApplyStablizer(FrontStablizer *Stablizer, const al::span<FloatBufferLine> Buffer,
const ALuint lidx, const ALuint ridx, const ALuint cidx, const ALuint SamplesToDo)
{
@@ -1820,42 +1826,33 @@ void ApplyStablizer(FrontStablizer *Stablizer, const al::span<FloatBufferLine> B
{
auto delay_end = std::rotate(Buffer[i].begin(),
buffer_end - FrontStablizer::DelayLength, buffer_end);
- std::swap_ranges(Buffer[i].begin(), delay_end, std::begin(DelayBuf));
+ std::swap_ranges(Buffer[i].begin(), delay_end, DelayBuf.begin());
}
else
{
auto delay_start = std::swap_ranges(Buffer[i].begin(), buffer_end,
- std::begin(DelayBuf));
- std::rotate(std::begin(DelayBuf), delay_start, std::end(DelayBuf));
+ DelayBuf.begin());
+ std::rotate(DelayBuf.begin(), delay_start, DelayBuf.end());
}
}
- al::span<float> tmpbuf{Stablizer->TempBuf, SamplesToDo+FrontStablizer::DelayLength};
-
- /* Use the right delay buf for the side signal delay. Combine the delayed
- * signal with the incoming signal.
+ /* Add a delay to the incoming side signal to keep it aligned with the mid
+ * filter delay.
*/
- auto tmpiter = std::copy_n(std::begin(Stablizer->DelayBuf[ridx]), FrontStablizer::DelayLength,
- tmpbuf.begin());
- for(size_t i{0};i < SamplesToDo;++i,++tmpiter)
- *tmpiter = Buffer[lidx][i] - Buffer[ridx][i];
- /* Hold on to the beginning for later, and save the end for next time. */
- std::copy_n(tmpbuf.begin(), SamplesToDo, std::begin(Stablizer->Side));
- std::copy_n(tmpbuf.begin()+SamplesToDo, FrontStablizer::DelayLength,
- std::begin(Stablizer->DelayBuf[ridx]));
-
- /* Use the left delay buf for the mid signal delay. Combine the delayed
- * signal with the incoming signal. Note that the samples are stored and
- * combined in reverse, so the newest samples are at the front and the
- * oldest at the back.
+ for(size_t i{0};i < SamplesToDo;++i)
+ Stablizer->Side[FrontStablizer::DelayLength+i] = Buffer[lidx][i] - Buffer[ridx][i];
+
+ /* Combine the delayed mid signal with the incoming signal. Note that the
+ * samples are stored and combined in reverse, so the newest samples are at
+ * the front and the oldest at the back.
*/
- tmpiter = tmpbuf.begin() + SamplesToDo;
- std::copy_n(std::cbegin(Stablizer->DelayBuf[lidx]), FrontStablizer::DelayLength, tmpiter);
+ al::span<float> tmpbuf{Stablizer->TempBuf};
+ auto tmpiter = tmpbuf.begin() + SamplesToDo;
+ std::copy(Stablizer->MidDelay.cbegin(), Stablizer->MidDelay.cend(), tmpiter);
for(size_t i{0};i < SamplesToDo;++i)
*--tmpiter = Buffer[lidx][i] + Buffer[ridx][i];
/* Save the newest samples for next time. */
- std::copy_n(tmpbuf.cbegin(), FrontStablizer::DelayLength,
- std::begin(Stablizer->DelayBuf[lidx]));
+ std::copy_n(tmpbuf.cbegin(), Stablizer->MidDelay.size(), Stablizer->MidDelay.begin());
/* Apply an all-pass on the reversed signal, then reverse the samples to
* get the forward signal with a reversed phase shift. The future samples
@@ -1869,7 +1866,7 @@ void ApplyStablizer(FrontStablizer *Stablizer, const al::span<FloatBufferLine> B
/* Now apply the band-splitter, combining its phase shift with the reversed
* phase shift, restoring the original phase on the split signal.
*/
- Stablizer->MidFilter.process(tmpbuf, Stablizer->MidHF, Stablizer->MidLF);
+ Stablizer->MidFilter.process(tmpbuf, Stablizer->MidHF.data(), Stablizer->MidLF.data());
/* This pans the separate low- and high-frequency signals between being on
* the center channel and the left+right channels. The low-frequency signal
@@ -1893,6 +1890,9 @@ void ApplyStablizer(FrontStablizer *Stablizer, const al::span<FloatBufferLine> B
Buffer[ridx][i] = (m - s) * 0.5f;
Buffer[cidx][i] += c * 0.5f;
}
+ /* Move the delayed side samples to the front for next time. */
+ auto side_end = Stablizer->Side.cbegin() + SamplesToDo;
+ std::copy(side_end, side_end+FrontStablizer::DelayLength, Stablizer->Side.begin());
}
void ApplyDistanceComp(const al::span<FloatBufferLine> Samples, const ALuint SamplesToDo,
diff --git a/alc/front_stablizer.h b/alc/front_stablizer.h
index bcffbb69..da39618e 100644
--- a/alc/front_stablizer.h
+++ b/alc/front_stablizer.h
@@ -4,8 +4,8 @@
#include <array>
#include <memory>
-#include "alcmain.h"
#include "almalloc.h"
+#include "bufferline.h"
#include "filters/splitter.h"
@@ -14,12 +14,14 @@ struct FrontStablizer {
FrontStablizer(size_t numchans) : DelayBuf{numchans} { }
- BandSplitter MidFilter;
- alignas(16) float MidLF[BUFFERSIZE]{};
- alignas(16) float MidHF[BUFFERSIZE]{};
- alignas(16) float Side[BUFFERSIZE]{};
+ alignas(16) std::array<float,BUFFERSIZE + DelayLength> Side{};
+ alignas(16) std::array<float,DelayLength> MidDelay{};
+
+ alignas(16) std::array<float,BUFFERSIZE + DelayLength> TempBuf{};
- alignas(16) float TempBuf[BUFFERSIZE + DelayLength]{};
+ BandSplitter MidFilter;
+ alignas(16) FloatBufferLine MidLF{};
+ alignas(16) FloatBufferLine MidHF{};
using DelayLine = std::array<float,DelayLength>;
al::FlexArray<DelayLine,16> DelayBuf;