Simplify handling the stablizer side channel delay

This commit is contained in:
Chris Robinson
2020-05-21 13:48:50 -07:00
parent e98017b475
commit da3dfa2fb0
2 changed files with 32 additions and 30 deletions
+24 -24
View File
@@ -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]));
for(size_t i{0};i < SamplesToDo;++i)
Stablizer->Side[FrontStablizer::DelayLength+i] = Buffer[lidx][i] - Buffer[ridx][i];
/* 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.
/* 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,
+8 -6
View File
@@ -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) float TempBuf[BUFFERSIZE + DelayLength]{};
alignas(16) std::array<float,BUFFERSIZE + DelayLength> TempBuf{};
BandSplitter MidFilter;
alignas(16) FloatBufferLine MidLF{};
alignas(16) FloatBufferLine MidHF{};
using DelayLine = std::array<float,DelayLength>;
al::FlexArray<DelayLine,16> DelayBuf;