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 setWidth(float width
) noexcept
= 0;
17 virtual void decode(const al::span
<float*> samples
, const size_t samplesToDo
,
18 const size_t forwardSamples
) = 0;
22 struct UhjFilterBase
{
23 /* The filter delay is half it's effective size, so a delay of 128 has a
26 static constexpr size_t sFilterDelay
{128};
29 struct UhjEncoder
: public UhjFilterBase
{
30 /* Delays and processing storage for the unfiltered signal. */
31 alignas(16) std::array
<float,BufferLineSize
+sFilterDelay
> mS
{};
32 alignas(16) std::array
<float,BufferLineSize
+sFilterDelay
> mD
{};
34 /* History for the FIR filter. */
35 alignas(16) std::array
<float,sFilterDelay
*2 - 1> mWXHistory
{};
37 alignas(16) std::array
<float,BufferLineSize
+ sFilterDelay
*2> mTemp
{};
40 * Encodes a 2-channel UHJ (stereo-compatible) signal from a B-Format input
41 * signal. The input must use FuMa channel ordering and UHJ scaling (FuMa
42 * with an additional +3dB boost).
44 void encode(float *LeftOut
, float *RightOut
, const al::span
<const float*const,3> InSamples
,
45 const size_t SamplesToDo
);
47 DEF_NEWDEL(UhjEncoder
)
51 struct UhjDecoder
: public DecoderBase
, public UhjFilterBase
{
52 alignas(16) std::array
<float,BufferLineSize
+MaxResamplerEdge
+sFilterDelay
> mS
{};
53 alignas(16) std::array
<float,BufferLineSize
+MaxResamplerEdge
+sFilterDelay
> mD
{};
54 alignas(16) std::array
<float,BufferLineSize
+MaxResamplerEdge
+sFilterDelay
> mT
{};
56 alignas(16) std::array
<float,sFilterDelay
-1> mDTHistory
{};
57 alignas(16) std::array
<float,sFilterDelay
-1> mSHistory
{};
59 alignas(16) std::array
<float,BufferLineSize
+MaxResamplerEdge
+ sFilterDelay
*2> mTemp
{};
61 void setWidth(float) noexcept override
{ }
64 * Decodes a 3- or 4-channel UHJ signal into a B-Format signal with FuMa
65 * channel ordering and UHJ scaling. For 3-channel, the 3rd channel may be
66 * attenuated by 'n', where 0 <= n <= 1. So to decode 2-channel UHJ, supply
67 * 3 channels with the 3rd channel silent (n=0). The B-Format signal
68 * reconstructed from 2-channel UHJ should not be run through a normal
69 * B-Format decoder, as it needs different shelf filters.
71 void decode(const al::span
<float*> samples
, const size_t samplesToDo
,
72 const size_t forwardSamples
) override
;
74 DEF_NEWDEL(UhjDecoder
)
77 struct UhjStereoDecoder
: public UhjDecoder
{
78 float mCurrentWidth
{-1.0f
};
81 * The width factor for Super Stereo processing. Can be changed in between
82 * calls to decodeStereo, with valid values being between 0...0.7.
84 float mWidthControl
{0.593f
};
86 void setWidth(float width
) noexcept override
87 { mWidthControl
= width
; }
90 * Applies Super Stereo processing on a stereo signal to create a B-Format
91 * signal with FuMa channel ordering and UHJ scaling. The samples span
92 * should contain 3 channels, the first two being the left and right stereo
93 * channels, and the third left empty.
95 void decode(const al::span
<float*> samples
, const size_t samplesToDo
,
96 const size_t forwardSamples
) override
;
98 DEF_NEWDEL(UhjStereoDecoder
)
101 #endif /* CORE_UHJFILTER_H */