2016-02-26 12:57:03 -08:00
|
|
|
#ifndef UHJFILTER_H
|
|
|
|
#define UHJFILTER_H
|
|
|
|
|
2020-05-08 01:24:14 -07:00
|
|
|
#include <array>
|
|
|
|
|
2019-07-28 18:33:29 -07:00
|
|
|
#include "alcmain.h"
|
2018-11-21 15:31:32 -08:00
|
|
|
#include "almalloc.h"
|
2016-02-26 12:57:03 -08:00
|
|
|
|
2018-11-03 14:39:16 -07:00
|
|
|
|
2016-02-26 12:57:03 -08:00
|
|
|
/* Encoding 2-channel UHJ from B-Format is done as:
|
|
|
|
*
|
2016-03-01 13:37:12 -08:00
|
|
|
* S = 0.9396926*W + 0.1855740*X
|
|
|
|
* D = j(-0.3420201*W + 0.5098604*X) + 0.6554516*Y
|
2016-02-26 12:57:03 -08:00
|
|
|
*
|
|
|
|
* Left = (S + D)/2.0
|
|
|
|
* Right = (S - D)/2.0
|
|
|
|
*
|
|
|
|
* where j is a wide-band +90 degree phase shift.
|
|
|
|
*
|
2020-05-08 15:38:14 -07:00
|
|
|
* The phase shift is done using a FIR filter derived from an FFT'd impulse
|
|
|
|
* with the desired shift.
|
2016-02-26 12:57:03 -08:00
|
|
|
*/
|
|
|
|
|
2018-11-21 15:31:32 -08:00
|
|
|
struct Uhj2Encoder {
|
2020-05-08 15:38:14 -07:00
|
|
|
/* A particular property of the filter allows it to cover nearly twice its
|
|
|
|
* length, so the filter size is also the effective delay (despite being
|
|
|
|
* center-aligned).
|
|
|
|
*/
|
|
|
|
constexpr static size_t sFilterSize{128};
|
|
|
|
|
|
|
|
/* Delays for the unfiltered signal. */
|
2020-05-11 17:42:08 -07:00
|
|
|
alignas(16) std::array<float,sFilterSize> mMidDelay{};
|
|
|
|
alignas(16) std::array<float,sFilterSize> mSideDelay{};
|
2020-05-08 15:38:14 -07:00
|
|
|
|
|
|
|
/* History for the FIR filter. */
|
2020-05-11 17:42:08 -07:00
|
|
|
alignas(16) std::array<float,sFilterSize*2 - 1> mSideHistory{};
|
2020-05-08 15:38:14 -07:00
|
|
|
|
2020-05-11 17:42:08 -07:00
|
|
|
alignas(16) std::array<float,BUFFERSIZE + sFilterSize*2> mTemp{};
|
2020-05-07 19:59:18 -07:00
|
|
|
|
2020-05-11 17:42:08 -07:00
|
|
|
alignas(16) std::array<float,BUFFERSIZE> mMid{};
|
|
|
|
alignas(16) std::array<float,BUFFERSIZE> mSide{};
|
2018-12-26 13:20:59 -08:00
|
|
|
|
2020-05-08 15:38:14 -07:00
|
|
|
/**
|
|
|
|
* Encodes a 2-channel UHJ (stereo-compatible) signal from a B-Format input
|
2018-12-26 13:20:59 -08:00
|
|
|
* signal. The input must use FuMa channel ordering and scaling.
|
|
|
|
*/
|
2020-05-08 15:38:14 -07:00
|
|
|
void encode(FloatBufferLine &LeftOut, FloatBufferLine &RightOut,
|
|
|
|
const FloatBufferLine *InSamples, const size_t SamplesToDo);
|
2018-11-21 15:31:32 -08:00
|
|
|
|
|
|
|
DEF_NEWDEL(Uhj2Encoder)
|
|
|
|
};
|
2016-02-26 12:57:03 -08:00
|
|
|
|
|
|
|
#endif /* UHJFILTER_H */
|