Avoid class templates for the POPCNT64/CTZ64 macros
[openal-soft.git] / alc / hrtf.h
bloba0d36890f626b60306b202bf558fe8337ee161dc
1 #ifndef ALC_HRTF_H
2 #define ALC_HRTF_H
4 #include <array>
5 #include <cstddef>
6 #include <memory>
7 #include <string>
9 #include "AL/al.h"
11 #include "almalloc.h"
12 #include "alspan.h"
13 #include "ambidefs.h"
14 #include "atomic.h"
15 #include "bufferline.h"
16 #include "filters/splitter.h"
17 #include "intrusive_ptr.h"
18 #include "vector.h"
21 #define HRTF_HISTORY_BITS 6
22 #define HRTF_HISTORY_LENGTH (1<<HRTF_HISTORY_BITS)
23 #define HRTF_HISTORY_MASK (HRTF_HISTORY_LENGTH-1)
25 #define HRIR_BITS 7
26 #define HRIR_LENGTH (1<<HRIR_BITS)
27 #define HRIR_MASK (HRIR_LENGTH-1)
29 #define MIN_IR_LENGTH 8
31 using float2 = std::array<float,2>;
32 using HrirArray = std::array<float2,HRIR_LENGTH>;
33 using ubyte2 = std::array<ALubyte,2>;
36 struct HrtfStore {
37 RefCount mRef;
39 ALuint sampleRate;
40 ALuint irSize;
42 struct Field {
43 float distance;
44 ALubyte evCount;
46 /* NOTE: Fields are stored *backwards*. field[0] is the farthest field, and
47 * field[fdCount-1] is the nearest.
49 ALuint fdCount;
50 const Field *field;
52 struct Elevation {
53 ALushort azCount;
54 ALushort irOffset;
56 Elevation *elev;
57 const HrirArray *coeffs;
58 const ubyte2 *delays;
60 void add_ref();
61 void release();
63 DEF_PLACE_NEWDEL()
65 using HrtfStorePtr = al::intrusive_ptr<HrtfStore>;
68 struct HrtfFilter {
69 alignas(16) HrirArray Coeffs;
70 std::array<ALuint,2> Delay;
71 float Gain;
75 struct EvRadians { float value; };
76 struct AzRadians { float value; };
77 struct AngularPoint {
78 EvRadians Elev;
79 AzRadians Azim;
82 #define HRTF_DIRECT_DELAY 192
83 struct DirectHrtfState {
84 struct ChannelData {
85 std::array<float,HRTF_DIRECT_DELAY> mDelay{};
86 BandSplitter mSplitter;
87 float mHfScale{};
88 alignas(16) HrirArray mCoeffs{};
91 std::array<float,HRTF_DIRECT_DELAY+BUFFERSIZE> mTemp;
93 /* HRTF filter state for dry buffer content */
94 ALuint mIrSize{0};
95 al::FlexArray<ChannelData> mChannels;
97 DirectHrtfState(size_t numchans) : mChannels{numchans} { }
98 /**
99 * Produces HRTF filter coefficients for decoding B-Format, given a set of
100 * virtual speaker positions, a matching decoding matrix, and per-order
101 * high-frequency gains for the decoder. The calculated impulse responses
102 * are ordered and scaled according to the matrix input.
104 void build(const HrtfStore *Hrtf, const al::span<const AngularPoint> AmbiPoints,
105 const float (*AmbiMatrix)[MAX_AMBI_CHANNELS],
106 const al::span<const float,MAX_AMBI_ORDER+1> AmbiOrderHFGain);
108 static std::unique_ptr<DirectHrtfState> Create(size_t num_chans);
110 DEF_FAM_NEWDEL(DirectHrtfState, mChannels)
114 al::vector<std::string> EnumerateHrtf(const char *devname);
115 HrtfStorePtr GetLoadedHrtf(const std::string &name, const char *devname, const ALuint devrate);
117 void GetHrtfCoeffs(const HrtfStore *Hrtf, float elevation, float azimuth, float distance,
118 float spread, HrirArray &coeffs, const al::span<ALuint,2> delays);
120 #endif /* ALC_HRTF_H */