Avoid class templates for the POPCNT64/CTZ64 macros
[openal-soft.git] / alc / uhjfilter.h
blob17a01d20e8ce37768d8428a798d2ff7d652c0bb1
1 #ifndef UHJFILTER_H
2 #define UHJFILTER_H
4 #include <array>
6 #include "alcmain.h"
7 #include "almalloc.h"
10 /* Encoding 2-channel UHJ from B-Format is done as:
12 * S = 0.9396926*W + 0.1855740*X
13 * D = j(-0.3420201*W + 0.5098604*X) + 0.6554516*Y
15 * Left = (S + D)/2.0
16 * Right = (S - D)/2.0
18 * where j is a wide-band +90 degree phase shift.
20 * The phase shift is done using a FIR filter derived from an FFT'd impulse
21 * with the desired shift.
24 struct Uhj2Encoder {
25 /* A particular property of the filter allows it to cover nearly twice its
26 * length, so the filter size is also the effective delay (despite being
27 * center-aligned).
29 constexpr static size_t sFilterSize{128};
31 /* Delays for the unfiltered signal. */
32 alignas(16) std::array<float,sFilterSize> mMidDelay{};
33 alignas(16) std::array<float,sFilterSize> mSideDelay{};
35 alignas(16) std::array<float,BUFFERSIZE+sFilterSize> mMid{};
36 alignas(16) std::array<float,BUFFERSIZE+sFilterSize> mSide{};
38 /* History for the FIR filter. */
39 alignas(16) std::array<float,sFilterSize*2 - 1> mSideHistory{};
41 alignas(16) std::array<float,BUFFERSIZE + sFilterSize*2> mTemp{};
43 /**
44 * Encodes a 2-channel UHJ (stereo-compatible) signal from a B-Format input
45 * signal. The input must use FuMa channel ordering and scaling.
47 void encode(FloatBufferLine &LeftOut, FloatBufferLine &RightOut,
48 const FloatBufferLine *InSamples, const size_t SamplesToDo);
50 DEF_NEWDEL(Uhj2Encoder)
53 #endif /* UHJFILTER_H */