1 #ifndef CORE_UHJFILTER_H
2 #define CORE_UHJFILTER_H
8 #include "bufferline.h"
9 #include "resampler_limits.h"
13 virtual ~DecoderBase() = default;
15 virtual void decode(const al::span
<float*> samples
, const size_t samplesToDo
,
16 const size_t forwardSamples
) = 0;
19 * The width factor for Super Stereo processing. Can be changed in between
20 * calls to decode, with valid values being between 0...0.7.
22 float mWidthControl
{0.593f
};
24 float mCurrentWidth
{-1.0f
};
28 struct UhjFilterBase
{
29 /* The filter delay is half it's effective size, so a delay of 128 has a
32 static constexpr size_t sFilterDelay
{128};
35 struct UhjEncoder
: public UhjFilterBase
{
36 /* Delays and processing storage for the unfiltered signal. */
37 alignas(16) std::array
<float,BufferLineSize
+sFilterDelay
> mS
{};
38 alignas(16) std::array
<float,BufferLineSize
+sFilterDelay
> mD
{};
40 /* History for the FIR filter. */
41 alignas(16) std::array
<float,sFilterDelay
*2 - 1> mWXHistory
{};
43 alignas(16) std::array
<float,BufferLineSize
+ sFilterDelay
*2> mTemp
{};
46 * Encodes a 2-channel UHJ (stereo-compatible) signal from a B-Format input
47 * signal. The input must use FuMa channel ordering and UHJ scaling (FuMa
48 * with an additional +3dB boost).
50 void encode(float *LeftOut
, float *RightOut
, const al::span
<const float*const,3> InSamples
,
51 const size_t SamplesToDo
);
53 DEF_NEWDEL(UhjEncoder
)
57 struct UhjDecoder
: public DecoderBase
, public UhjFilterBase
{
58 /* For 2-channel UHJ, shelf filters should use these LF responses. */
59 static constexpr float sWLFScale
{0.661f
};
60 static constexpr float sXYLFScale
{1.293f
};
62 alignas(16) std::array
<float,BufferLineSize
+MaxResamplerEdge
+sFilterDelay
> mS
{};
63 alignas(16) std::array
<float,BufferLineSize
+MaxResamplerEdge
+sFilterDelay
> mD
{};
64 alignas(16) std::array
<float,BufferLineSize
+MaxResamplerEdge
+sFilterDelay
> mT
{};
66 alignas(16) std::array
<float,sFilterDelay
-1> mDTHistory
{};
67 alignas(16) std::array
<float,sFilterDelay
-1> mSHistory
{};
69 alignas(16) std::array
<float,BufferLineSize
+MaxResamplerEdge
+ sFilterDelay
*2> mTemp
{};
72 * Decodes a 3- or 4-channel UHJ signal into a B-Format signal with FuMa
73 * channel ordering and UHJ scaling. For 3-channel, the 3rd channel may be
74 * attenuated by 'n', where 0 <= n <= 1. So to decode 2-channel UHJ, supply
75 * 3 channels with the 3rd channel silent (n=0). The B-Format signal
76 * reconstructed from 2-channel UHJ should not be run through a normal
77 * B-Format decoder, as it needs different shelf filters.
79 void decode(const al::span
<float*> samples
, const size_t samplesToDo
,
80 const size_t forwardSamples
) override
;
82 DEF_NEWDEL(UhjDecoder
)
85 struct UhjStereoDecoder
: public UhjDecoder
{
87 * Applies Super Stereo processing on a stereo signal to create a B-Format
88 * signal with FuMa channel ordering and UHJ scaling. The samples span
89 * should contain 3 channels, the first two being the left and right stereo
90 * channels, and the third left empty.
92 void decode(const al::span
<float*> samples
, const size_t samplesToDo
,
93 const size_t forwardSamples
) override
;
95 DEF_NEWDEL(UhjStereoDecoder
)
98 #endif /* CORE_UHJFILTER_H */