Avoid a stateful unique_ptr deleter
[openal-soft.git] / core / uhjfilter.h
blob1105870071143e704869a49b6cc1893133613fa7
1 #ifndef CORE_UHJFILTER_H
2 #define CORE_UHJFILTER_H
4 #include <array>
6 #include "almalloc.h"
7 #include "bufferline.h"
8 #include "resampler_limits.h"
11 struct UhjFilterBase {
12 /* The filter delay is half it's effective size, so a delay of 128 has a
13 * FIR length of 256.
15 static constexpr size_t sFilterDelay{128};
18 struct UhjEncoder : public UhjFilterBase {
19 /* Delays and processing storage for the unfiltered signal. */
20 alignas(16) std::array<float,BufferLineSize+sFilterDelay> mS{};
21 alignas(16) std::array<float,BufferLineSize+sFilterDelay> mD{};
23 /* History for the FIR filter. */
24 alignas(16) std::array<float,sFilterDelay*2 - 1> mWXHistory{};
26 alignas(16) std::array<float,BufferLineSize + sFilterDelay*2> mTemp{};
28 /**
29 * Encodes a 2-channel UHJ (stereo-compatible) signal from a B-Format input
30 * signal. The input must use FuMa channel ordering and UHJ scaling (FuMa
31 * with an additional +3dB boost).
33 void encode(float *LeftOut, float *RightOut, const FloatBufferLine *InSamples,
34 const size_t SamplesToDo);
36 DEF_NEWDEL(UhjEncoder)
40 struct UhjDecoder : public UhjFilterBase {
41 static constexpr size_t sLineSize{BufferLineSize+MaxResamplerPadding+sFilterDelay};
42 using BufferLine = std::array<float,sLineSize>;
44 alignas(16) std::array<float,BufferLineSize+MaxResamplerEdge+sFilterDelay> mS{};
45 alignas(16) std::array<float,BufferLineSize+MaxResamplerEdge+sFilterDelay> mD{};
46 alignas(16) std::array<float,BufferLineSize+MaxResamplerEdge+sFilterDelay> mT{};
48 alignas(16) std::array<float,sFilterDelay-1> mDTHistory{};
49 alignas(16) std::array<float,sFilterDelay-1> mSHistory{};
51 alignas(16) std::array<float,BufferLineSize+MaxResamplerEdge + sFilterDelay*2> mTemp{};
53 float mCurrentWidth{-1.0f};
55 /**
56 * The width factor for Super Stereo processing. Can be changed in between
57 * calls to decodeStereo, with valid values being between 0...0.7.
59 float mWidthControl{0.593f};
61 /**
62 * Decodes a 3- or 4-channel UHJ signal into a B-Format signal with FuMa
63 * channel ordering and UHJ scaling. For 3-channel, the 3rd channel may be
64 * attenuated by 'n', where 0 <= n <= 1. So to decode 2-channel UHJ, supply
65 * 3 channels with the 3rd channel silent (n=0). The B-Format signal
66 * reconstructed from 2-channel UHJ should not be run through a normal
67 * B-Format decoder, as it needs different shelf filters.
69 void decode(const al::span<float*> samples, const size_t samplesToDo,
70 const size_t forwardSamples);
72 /**
73 * Applies Super Stereo processing on a stereo signal to create a B-Format
74 * signal with FuMa channel ordering and UHJ scaling. The samples span
75 * should contain 3 channels, the first two being the left and right stereo
76 * channels, and the third left empty.
78 void decodeStereo(const al::span<float*> samples, const size_t samplesToDo,
79 const size_t forwardSamples);
81 using DecoderFunc = void (UhjDecoder::*)(const al::span<float*> samples,
82 const size_t samplesToDo, const size_t forwardSamples);
84 DEF_NEWDEL(UhjDecoder)
87 #endif /* CORE_UHJFILTER_H */