1 #ifndef BFORMATDEC_H
2 #define BFORMATDEC_H
3 
4 #include <array>
5 #include <cstddef>
6 #include <memory>
7 
8 #include "almalloc.h"
9 #include "alspan.h"
10 #include "core/ambidefs.h"
11 #include "core/bufferline.h"
12 #include "core/devformat.h"
13 #include "core/filters/splitter.h"
14 
15 struct AmbDecConf;
16 struct FrontStablizer;
17 
18 
19 using ChannelDec = std::array<float,MaxAmbiChannels>;
20 
21 class BFormatDec {
22     static constexpr size_t sHFBand{0};
23     static constexpr size_t sLFBand{1};
24     static constexpr size_t sNumBands{2};
25 
26     struct ChannelDecoder {
27         union MatrixU {
28             float Dual[sNumBands][MAX_OUTPUT_CHANNELS];
29             float Single[MAX_OUTPUT_CHANNELS];
30         } mGains{};
31 
32         /* NOTE: BandSplitter filter is unused with single-band decoding. */
33         BandSplitter mXOver;
34     };
35 
36     alignas(16) std::array<FloatBufferLine,2> mSamples;
37 
38     const std::unique_ptr<FrontStablizer> mStablizer;
39     const bool mDualBand{false};
40 
41     al::FlexArray<ChannelDecoder> mChannelDec;
42 
43 public:
44     BFormatDec(const AmbDecConf *conf, const bool allow_2band, const size_t inchans,
45         const uint srate, const uint (&chanmap)[MAX_OUTPUT_CHANNELS],
46         std::unique_ptr<FrontStablizer> stablizer);
47     BFormatDec(const size_t inchans, const al::span<const ChannelDec> coeffs,
48         const al::span<const ChannelDec> coeffslf, std::unique_ptr<FrontStablizer> stablizer);
49 
hasStablizer()50     bool hasStablizer() const noexcept { return mStablizer != nullptr; };
51 
52     /* Decodes the ambisonic input to the given output channels. */
53     void process(const al::span<FloatBufferLine> OutBuffer, const FloatBufferLine *InSamples,
54         const size_t SamplesToDo);
55 
56     /* Decodes the ambisonic input to the given output channels with stablization. */
57     void processStablize(const al::span<FloatBufferLine> OutBuffer,
58         const FloatBufferLine *InSamples, const size_t lidx, const size_t ridx, const size_t cidx,
59         const size_t SamplesToDo);
60 
61     /* Retrieves per-order HF scaling factors for "upsampling" ambisonic data. */
62     static std::array<float,MaxAmbiOrder+1> GetHFOrderScales(const uint in_order,
63         const uint out_order) noexcept;
64 
65     static std::unique_ptr<BFormatDec> Create(const AmbDecConf *conf, const bool allow_2band,
66         const size_t inchans, const uint srate, const uint (&chanmap)[MAX_OUTPUT_CHANNELS],
67         std::unique_ptr<FrontStablizer> stablizer);
68     static std::unique_ptr<BFormatDec> Create(const size_t inchans,
69         const al::span<const ChannelDec> coeffs, const al::span<const ChannelDec> coeffslf,
70         std::unique_ptr<FrontStablizer> stablizer);
71 
72     DEF_FAM_NEWDEL(BFormatDec, mChannelDec)
73 };
74 
75 #endif /* BFORMATDEC_H */
76