Fix some formatting in the 3D7.1 preset
[openal-soft.git] / core / uhjfilter.h
blobeeabb6d2df897f8d250a497668c418673f2b1eb1
1 #ifndef CORE_UHJFILTER_H
2 #define CORE_UHJFILTER_H
4 #include <array>
6 #include "almalloc.h"
7 #include "alspan.h"
8 #include "bufferline.h"
9 #include "resampler_limits.h"
12 struct DecoderBase {
13 virtual ~DecoderBase() = default;
15 virtual void decode(const al::span<float*> samples, const size_t samplesToDo,
16 const size_t forwardSamples) = 0;
18 /**
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
30 * FIR length of 256.
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{};
45 /**
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{};
71 /**
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 {
86 /**
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 */