aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2022-05-14 21:23:03 -0700
committerChris Robinson <[email protected]>2022-05-14 21:23:03 -0700
commit83238973ed08225adf03e76b6933e0c209f93fd9 (patch)
tree7e5a1d68cba91ae46cddaa7a2506a54eb4f3c19b
parent0a57ebdd495149156736aea3e1aba4d2b3e55dd4 (diff)
Use virtual functions for the decoder
-rw-r--r--alc/alu.cpp2
-rw-r--r--core/uhjfilter.cpp2
-rw-r--r--core/uhjfilter.h46
-rw-r--r--core/voice.cpp15
-rw-r--r--core/voice.h3
5 files changed, 39 insertions, 29 deletions
diff --git a/alc/alu.cpp b/alc/alu.cpp
index c7fb5f57..487ce4c8 100644
--- a/alc/alu.cpp
+++ b/alc/alu.cpp
@@ -765,7 +765,7 @@ void CalcPanningAndFilters(Voice *voice, const float xpos, const float ypos, con
voice->mFlags.reset(VoiceHasHrtf).reset(VoiceHasNfc);
if(auto *decoder{voice->mDecoder.get()})
- decoder->mWidthControl = minf(props->EnhWidth, 0.7f);
+ decoder->setWidth(minf(props->EnhWidth, 0.7f));
if(IsAmbisonic(voice->mFmtChannels))
{
diff --git a/core/uhjfilter.cpp b/core/uhjfilter.cpp
index 7fb23131..6cdc2944 100644
--- a/core/uhjfilter.cpp
+++ b/core/uhjfilter.cpp
@@ -174,7 +174,7 @@ void UhjDecoder::decode(const al::span<float*> samples, const size_t samplesToDo
* where j is a +90 degree phase shift. w is a variable control for the
* resulting stereo width, with the range 0 <= w <= 0.7.
*/
-void UhjDecoder::decodeStereo(const al::span<float*> samples, const size_t samplesToDo,
+void UhjStereoDecoder::decode(const al::span<float*> samples, const size_t samplesToDo,
const size_t forwardSamples)
{
ASSUME(samplesToDo > 0);
diff --git a/core/uhjfilter.h b/core/uhjfilter.h
index 8f2736bf..73be7d17 100644
--- a/core/uhjfilter.h
+++ b/core/uhjfilter.h
@@ -9,6 +9,16 @@
#include "resampler_limits.h"
+struct DecoderBase {
+ virtual ~DecoderBase() = default;
+
+ virtual void setWidth(float width) noexcept = 0;
+
+ virtual void decode(const al::span<float*> samples, const size_t samplesToDo,
+ const size_t forwardSamples) = 0;
+};
+
+
struct UhjFilterBase {
/* The filter delay is half it's effective size, so a delay of 128 has a
* FIR length of 256.
@@ -38,7 +48,7 @@ struct UhjEncoder : public UhjFilterBase {
};
-struct UhjDecoder : public UhjFilterBase {
+struct UhjDecoder : public DecoderBase, public UhjFilterBase {
alignas(16) std::array<float,BufferLineSize+MaxResamplerEdge+sFilterDelay> mS{};
alignas(16) std::array<float,BufferLineSize+MaxResamplerEdge+sFilterDelay> mD{};
alignas(16) std::array<float,BufferLineSize+MaxResamplerEdge+sFilterDelay> mT{};
@@ -48,13 +58,7 @@ struct UhjDecoder : public UhjFilterBase {
alignas(16) std::array<float,BufferLineSize+MaxResamplerEdge + sFilterDelay*2> mTemp{};
- float mCurrentWidth{-1.0f};
-
- /**
- * The width factor for Super Stereo processing. Can be changed in between
- * calls to decodeStereo, with valid values being between 0...0.7.
- */
- float mWidthControl{0.593f};
+ void setWidth(float) noexcept override { }
/**
* Decodes a 3- or 4-channel UHJ signal into a B-Format signal with FuMa
@@ -65,7 +69,22 @@ struct UhjDecoder : public UhjFilterBase {
* B-Format decoder, as it needs different shelf filters.
*/
void decode(const al::span<float*> samples, const size_t samplesToDo,
- const size_t forwardSamples);
+ const size_t forwardSamples) override;
+
+ DEF_NEWDEL(UhjDecoder)
+};
+
+struct UhjStereoDecoder : public UhjDecoder {
+ float mCurrentWidth{-1.0f};
+
+ /**
+ * The width factor for Super Stereo processing. Can be changed in between
+ * calls to decodeStereo, with valid values being between 0...0.7.
+ */
+ float mWidthControl{0.593f};
+
+ void setWidth(float width) noexcept override
+ { mWidthControl = width; }
/**
* Applies Super Stereo processing on a stereo signal to create a B-Format
@@ -73,13 +92,10 @@ struct UhjDecoder : public UhjFilterBase {
* should contain 3 channels, the first two being the left and right stereo
* channels, and the third left empty.
*/
- void decodeStereo(const al::span<float*> samples, const size_t samplesToDo,
- const size_t forwardSamples);
-
- using DecoderFunc = void (UhjDecoder::*)(const al::span<float*> samples,
- const size_t samplesToDo, const size_t forwardSamples);
+ void decode(const al::span<float*> samples, const size_t samplesToDo,
+ const size_t forwardSamples) override;
- DEF_NEWDEL(UhjDecoder)
+ DEF_NEWDEL(UhjStereoDecoder)
};
#endif /* CORE_UHJFILTER_H */
diff --git a/core/voice.cpp b/core/voice.cpp
index e269c4a9..48a2de51 100644
--- a/core/voice.cpp
+++ b/core/voice.cpp
@@ -637,8 +637,8 @@ void Voice::mix(const State vstate, ContextBase *Context, const uint SamplesToDo
if(mDecoder)
{
SrcBufferSize = SrcBufferSize - PostPadding + MaxResamplerEdge;
- ((*mDecoder).*mDecoderFunc)(MixingSamples, SrcBufferSize,
- srcOffset * likely(vstate == Playing));
+ mDecoder->decode(MixingSamples, SrcBufferSize,
+ likely(vstate == Playing) ? srcOffset : 0.0f);
}
/* Store the last source samples used for next time. */
if(likely(vstate == Playing))
@@ -853,17 +853,12 @@ void Voice::prepare(DeviceBase *device)
mPrevSamples.reserve(maxu(2, num_channels));
mPrevSamples.resize(num_channels);
- if(IsUHJ(mFmtChannels))
- {
+ if(mFmtChannels == FmtSuperStereo)
+ mDecoder = std::make_unique<UhjStereoDecoder>();
+ else if(IsUHJ(mFmtChannels))
mDecoder = std::make_unique<UhjDecoder>();
- mDecoderFunc = (mFmtChannels == FmtSuperStereo) ? &UhjDecoder::decodeStereo
- : &UhjDecoder::decode;
- }
else
- {
mDecoder = nullptr;
- mDecoderFunc = nullptr;
- }
/* Clear the stepping value explicitly so the mixer knows not to mix this
* until the update gets applied.
diff --git a/core/voice.h b/core/voice.h
index 70b80841..3cf10d22 100644
--- a/core/voice.h
+++ b/core/voice.h
@@ -219,8 +219,7 @@ struct Voice {
AmbiScaling mAmbiScaling;
uint mAmbiOrder;
- std::unique_ptr<UhjDecoder> mDecoder;
- UhjDecoder::DecoderFunc mDecoderFunc{};
+ std::unique_ptr<DecoderBase> mDecoder;
/** Current target parameters used for mixing. */
uint mStep{0};