]> git.tdb.fi Git - ext/openal.git/blob - utils/makemhr/makemhr.h
Import OpenAL Soft 1.23.1 sources
[ext/openal.git] / utils / makemhr / makemhr.h
1 #ifndef MAKEMHR_H
2 #define MAKEMHR_H
3
4 #include <vector>
5 #include <complex>
6
7 #include "alcomplex.h"
8 #include "polyphase_resampler.h"
9
10
11 // The maximum path length used when processing filenames.
12 #define MAX_PATH_LEN                 (256)
13
14 // The limit to the number of 'distances' listed in the data set definition.
15 // Must be less than 256
16 #define MAX_FD_COUNT                 (16)
17
18 // The limits to the number of 'elevations' listed in the data set definition.
19 // Must be less than 256.
20 #define MIN_EV_COUNT                 (5)
21 #define MAX_EV_COUNT                 (181)
22
23 // The limits for each of the 'azimuths' listed in the data set definition.
24 // Must be less than 256.
25 #define MIN_AZ_COUNT                 (1)
26 #define MAX_AZ_COUNT                 (255)
27
28 // The limits for the 'distance' from source to listener for each field in
29 // the definition file.
30 #define MIN_DISTANCE                 (0.05)
31 #define MAX_DISTANCE                 (2.50)
32
33 // The limits for the sample 'rate' metric in the data set definition and for
34 // resampling.
35 #define MIN_RATE                     (32000)
36 #define MAX_RATE                     (96000)
37
38 // The limits for the HRIR 'points' metric in the data set definition.
39 #define MIN_POINTS                   (16)
40 #define MAX_POINTS                   (8192)
41
42
43 using uint = unsigned int;
44
45 /* Complex double type. */
46 using complex_d = std::complex<double>;
47
48
49 enum ChannelModeT : bool {
50     CM_AllowStereo = false,
51     CM_ForceMono = true
52 };
53
54 // Sample and channel type enum values.
55 enum SampleTypeT {
56     ST_S16 = 0,
57     ST_S24 = 1
58 };
59
60 // Certain iterations rely on these integer enum values.
61 enum ChannelTypeT {
62     CT_NONE   = -1,
63     CT_MONO   = 0,
64     CT_STEREO = 1
65 };
66
67 // Structured HRIR storage for stereo azimuth pairs, elevations, and fields.
68 struct HrirAzT {
69     double mAzimuth{0.0};
70     uint mIndex{0u};
71     double mDelays[2]{0.0, 0.0};
72     double *mIrs[2]{nullptr, nullptr};
73 };
74
75 struct HrirEvT {
76     double mElevation{0.0};
77     al::span<HrirAzT> mAzs;
78 };
79
80 struct HrirFdT {
81     double mDistance{0.0};
82     uint mEvStart{0u};
83     al::span<HrirEvT> mEvs;
84 };
85
86 // The HRIR metrics and data set used when loading, processing, and storing
87 // the resulting HRTF.
88 struct HrirDataT {
89     uint mIrRate{0u};
90     SampleTypeT mSampleType{ST_S24};
91     ChannelTypeT mChannelType{CT_NONE};
92     uint mIrPoints{0u};
93     uint mFftSize{0u};
94     uint mIrSize{0u};
95     double mRadius{0.0};
96     uint mIrCount{0u};
97
98     std::vector<double> mHrirsBase;
99     std::vector<HrirEvT> mEvsBase;
100     std::vector<HrirAzT> mAzsBase;
101
102     std::vector<HrirFdT> mFds;
103
104     /* GCC warns when it tries to inline this. */
105     ~HrirDataT();
106 };
107
108
109 bool PrepareHrirData(const al::span<const double> distances,
110     const al::span<const uint,MAX_FD_COUNT> evCounts,
111     const al::span<const std::array<uint,MAX_EV_COUNT>,MAX_FD_COUNT> azCounts, HrirDataT *hData);
112 void MagnitudeResponse(const uint n, const complex_d *in, double *out);
113
114 // Performs a forward FFT.
115 inline void FftForward(const uint n, complex_d *inout)
116 { forward_fft(al::as_span(inout, n)); }
117
118 // Performs an inverse FFT.
119 inline void FftInverse(const uint n, complex_d *inout)
120 {
121     inverse_fft(al::as_span(inout, n));
122     double f{1.0 / n};
123     for(uint i{0};i < n;i++)
124         inout[i] *= f;
125 }
126
127 // Performs linear interpolation.
128 inline double Lerp(const double a, const double b, const double f)
129 { return a + f * (b - a); }
130
131 #endif /* MAKEMHR_H */