Add config options to enable the hq ambisonic decoder
[openal-soft.git] / OpenAL32 / Include / alu.h
blob08f2520437909a99c2dd9a464b672d7acf3c3888
1 #ifndef _ALU_H_
2 #define _ALU_H_
4 #include <limits.h>
5 #include <math.h>
6 #ifdef HAVE_FLOAT_H
7 #include <float.h>
8 #endif
9 #ifdef HAVE_IEEEFP_H
10 #include <ieeefp.h>
11 #endif
13 #include "alMain.h"
14 #include "alBuffer.h"
15 #include "alFilter.h"
16 #include "alAuxEffectSlot.h"
18 #include "hrtf.h"
19 #include "align.h"
20 #include "math_defs.h"
23 #define MAX_PITCH (255)
25 /* Maximum number of buffer samples before the current pos needed for resampling. */
26 #define MAX_PRE_SAMPLES 12
28 /* Maximum number of buffer samples after the current pos needed for resampling. */
29 #define MAX_POST_SAMPLES 12
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
36 struct ALsource;
37 struct ALvoice;
38 struct ALeffectslot;
41 /* The number of distinct scale and phase intervals within the filter table. */
42 #define BSINC_SCALE_BITS 4
43 #define BSINC_SCALE_COUNT (1<<BSINC_SCALE_BITS)
44 #define BSINC_PHASE_BITS 4
45 #define BSINC_PHASE_COUNT (1<<BSINC_PHASE_BITS)
47 /* Interpolator state. Kind of a misnomer since the interpolator itself is
48 * stateless. This just keeps it from having to recompute scale-related
49 * mappings for every sample.
51 typedef struct BsincState {
52 ALfloat sf; /* Scale interpolation factor. */
53 ALuint m; /* Coefficient count. */
54 ALint l; /* Left coefficient offset. */
55 struct {
56 const ALfloat *filter; /* Filter coefficients. */
57 const ALfloat *scDelta; /* Scale deltas. */
58 const ALfloat *phDelta; /* Phase deltas. */
59 const ALfloat *spDelta; /* Scale-phase deltas. */
60 } coeffs[BSINC_PHASE_COUNT];
61 } BsincState;
64 typedef union aluVector {
65 alignas(16) ALfloat v[4];
66 } aluVector;
68 inline void aluVectorSet(aluVector *vector, ALfloat x, ALfloat y, ALfloat z, ALfloat w)
70 vector->v[0] = x;
71 vector->v[1] = y;
72 vector->v[2] = z;
73 vector->v[3] = w;
77 typedef union aluMatrixf {
78 alignas(16) ALfloat m[4][4];
79 } aluMatrixf;
81 inline void aluMatrixfSetRow(aluMatrixf *matrix, ALuint row,
82 ALfloat m0, ALfloat m1, ALfloat m2, ALfloat m3)
84 matrix->m[row][0] = m0;
85 matrix->m[row][1] = m1;
86 matrix->m[row][2] = m2;
87 matrix->m[row][3] = m3;
90 inline void aluMatrixfSet(aluMatrixf *matrix, ALfloat m00, ALfloat m01, ALfloat m02, ALfloat m03,
91 ALfloat m10, ALfloat m11, ALfloat m12, ALfloat m13,
92 ALfloat m20, ALfloat m21, ALfloat m22, ALfloat m23,
93 ALfloat m30, ALfloat m31, ALfloat m32, ALfloat m33)
95 aluMatrixfSetRow(matrix, 0, m00, m01, m02, m03);
96 aluMatrixfSetRow(matrix, 1, m10, m11, m12, m13);
97 aluMatrixfSetRow(matrix, 2, m20, m21, m22, m23);
98 aluMatrixfSetRow(matrix, 3, m30, m31, m32, m33);
102 typedef union aluMatrixd {
103 alignas(16) ALdouble m[4][4];
104 } aluMatrixd;
106 inline void aluMatrixdSetRow(aluMatrixd *matrix, ALuint row,
107 ALdouble m0, ALdouble m1, ALdouble m2, ALdouble m3)
109 matrix->m[row][0] = m0;
110 matrix->m[row][1] = m1;
111 matrix->m[row][2] = m2;
112 matrix->m[row][3] = m3;
115 inline void aluMatrixdSet(aluMatrixd *matrix, ALdouble m00, ALdouble m01, ALdouble m02, ALdouble m03,
116 ALdouble m10, ALdouble m11, ALdouble m12, ALdouble m13,
117 ALdouble m20, ALdouble m21, ALdouble m22, ALdouble m23,
118 ALdouble m30, ALdouble m31, ALdouble m32, ALdouble m33)
120 aluMatrixdSetRow(matrix, 0, m00, m01, m02, m03);
121 aluMatrixdSetRow(matrix, 1, m10, m11, m12, m13);
122 aluMatrixdSetRow(matrix, 2, m20, m21, m22, m23);
123 aluMatrixdSetRow(matrix, 3, m30, m31, m32, m33);
127 enum ActiveFilters {
128 AF_None = 0,
129 AF_LowPass = 1,
130 AF_HighPass = 2,
131 AF_BandPass = AF_LowPass | AF_HighPass
135 typedef struct MixGains {
136 ALfloat Current;
137 ALfloat Step;
138 ALfloat Target;
139 } MixGains;
141 typedef struct MixHrtfParams {
142 const HrtfParams *Target;
143 HrtfParams *Current;
144 struct {
145 alignas(16) ALfloat Coeffs[HRIR_LENGTH][2];
146 ALint Delay[2];
147 } Steps;
148 } MixHrtfParams;
150 typedef struct DirectParams {
151 ALfloat (*OutBuffer)[BUFFERSIZE];
152 ALuint OutChannels;
154 struct {
155 enum ActiveFilters ActiveType;
156 ALfilterState LowPass;
157 ALfilterState HighPass;
158 } Filters[MAX_INPUT_CHANNELS];
160 struct {
161 HrtfParams Current;
162 HrtfParams Target;
163 HrtfState State;
164 } Hrtf[MAX_INPUT_CHANNELS];
166 struct {
167 ALfloat Current[MAX_OUTPUT_CHANNELS];
168 ALfloat Target[MAX_OUTPUT_CHANNELS];
169 } Gains[MAX_INPUT_CHANNELS];
170 } DirectParams;
172 typedef struct SendParams {
173 ALfloat (*OutBuffer)[BUFFERSIZE];
174 ALuint OutChannels;
176 struct {
177 enum ActiveFilters ActiveType;
178 ALfilterState LowPass;
179 ALfilterState HighPass;
180 } Filters[MAX_INPUT_CHANNELS];
182 struct {
183 ALfloat Current[MAX_OUTPUT_CHANNELS];
184 ALfloat Target[MAX_OUTPUT_CHANNELS];
185 } Gains[MAX_INPUT_CHANNELS];
186 } SendParams;
189 typedef const ALfloat* (*ResamplerFunc)(const BsincState *state,
190 const ALfloat *src, ALuint frac, ALuint increment, ALfloat *restrict dst, ALuint dstlen
193 typedef void (*MixerFunc)(const ALfloat *data, ALuint OutChans,
194 ALfloat (*restrict OutBuffer)[BUFFERSIZE], struct MixGains *Gains,
195 ALuint Counter, ALuint OutPos, ALuint BufferSize);
196 typedef void (*HrtfMixerFunc)(ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALuint lidx, ALuint ridx,
197 const ALfloat *data, ALuint Counter, ALuint Offset, ALuint OutPos,
198 const ALuint IrSize, const MixHrtfParams *hrtfparams,
199 HrtfState *hrtfstate, ALuint BufferSize);
202 #define GAIN_SILENCE_THRESHOLD (0.00001f) /* -100dB */
204 #define SPEEDOFSOUNDMETRESPERSEC (343.3f)
205 #define AIRABSORBGAINHF (0.99426f) /* -0.05dB */
207 #define FRACTIONBITS (12)
208 #define FRACTIONONE (1<<FRACTIONBITS)
209 #define FRACTIONMASK (FRACTIONONE-1)
212 inline ALfloat minf(ALfloat a, ALfloat b)
213 { return ((a > b) ? b : a); }
214 inline ALfloat maxf(ALfloat a, ALfloat b)
215 { return ((a > b) ? a : b); }
216 inline ALfloat clampf(ALfloat val, ALfloat min, ALfloat max)
217 { return minf(max, maxf(min, val)); }
219 inline ALdouble mind(ALdouble a, ALdouble b)
220 { return ((a > b) ? b : a); }
221 inline ALdouble maxd(ALdouble a, ALdouble b)
222 { return ((a > b) ? a : b); }
223 inline ALdouble clampd(ALdouble val, ALdouble min, ALdouble max)
224 { return mind(max, maxd(min, val)); }
226 inline ALuint minu(ALuint a, ALuint b)
227 { return ((a > b) ? b : a); }
228 inline ALuint maxu(ALuint a, ALuint b)
229 { return ((a > b) ? a : b); }
230 inline ALuint clampu(ALuint val, ALuint min, ALuint max)
231 { return minu(max, maxu(min, val)); }
233 inline ALint mini(ALint a, ALint b)
234 { return ((a > b) ? b : a); }
235 inline ALint maxi(ALint a, ALint b)
236 { return ((a > b) ? a : b); }
237 inline ALint clampi(ALint val, ALint min, ALint max)
238 { return mini(max, maxi(min, val)); }
240 inline ALint64 mini64(ALint64 a, ALint64 b)
241 { return ((a > b) ? b : a); }
242 inline ALint64 maxi64(ALint64 a, ALint64 b)
243 { return ((a > b) ? a : b); }
244 inline ALint64 clampi64(ALint64 val, ALint64 min, ALint64 max)
245 { return mini64(max, maxi64(min, val)); }
247 inline ALuint64 minu64(ALuint64 a, ALuint64 b)
248 { return ((a > b) ? b : a); }
249 inline ALuint64 maxu64(ALuint64 a, ALuint64 b)
250 { return ((a > b) ? a : b); }
251 inline ALuint64 clampu64(ALuint64 val, ALuint64 min, ALuint64 max)
252 { return minu64(max, maxu64(min, val)); }
255 union ResamplerCoeffs {
256 ALfloat FIR4[FRACTIONONE][4];
257 ALfloat FIR8[FRACTIONONE][8];
259 extern alignas(16) union ResamplerCoeffs ResampleCoeffs;
261 extern alignas(16) const ALfloat bsincTab[18840];
264 inline ALfloat lerp(ALfloat val1, ALfloat val2, ALfloat mu)
266 return val1 + (val2-val1)*mu;
268 inline ALfloat resample_fir4(ALfloat val0, ALfloat val1, ALfloat val2, ALfloat val3, ALuint frac)
270 const ALfloat *k = ResampleCoeffs.FIR4[frac];
271 return k[0]*val0 + k[1]*val1 + k[2]*val2 + k[3]*val3;
273 inline ALfloat resample_fir8(ALfloat val0, ALfloat val1, ALfloat val2, ALfloat val3, ALfloat val4, ALfloat val5, ALfloat val6, ALfloat val7, ALuint frac)
275 const ALfloat *k = ResampleCoeffs.FIR8[frac];
276 return k[0]*val0 + k[1]*val1 + k[2]*val2 + k[3]*val3 +
277 k[4]*val4 + k[5]*val5 + k[6]*val6 + k[7]*val7;
281 void aluInitMixer(void);
283 ALvoid aluInitPanning(ALCdevice *Device);
285 void aluInitEffectPanning(struct ALeffectslot *slot);
288 * CalcDirectionCoeffs
290 * Calculates ambisonic coefficients based on a direction vector. The vector
291 * must not be longer than 1 unit.
293 void CalcDirectionCoeffs(const ALfloat dir[3], ALfloat coeffs[MAX_AMBI_COEFFS]);
296 * CalcXYZCoeffs
298 * Same as CalcDirectionCoeffs except the direction is specified as separate x,
299 * y, and z parameters instead of an array.
301 inline void CalcXYZCoeffs(ALfloat x, ALfloat y, ALfloat z, ALfloat coeffs[MAX_AMBI_COEFFS])
303 ALfloat dir[3] = { x, y, z };
304 CalcDirectionCoeffs(dir, coeffs);
308 * CalcAngleCoeffs
310 * Calculates ambisonic coefficients based on angle and elevation. The angle
311 * and elevation parameters are in radians, going right and up respectively.
313 void CalcAngleCoeffs(ALfloat angle, ALfloat elevation, ALfloat coeffs[MAX_AMBI_COEFFS]);
316 * ComputeAmbientGains
318 * Computes channel gains for ambient, omni-directional sounds.
320 void ComputeAmbientGains(const ChannelConfig *chancoeffs, ALuint numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
323 * ComputePanningGains
325 * Computes panning gains using the given channel decoder coefficients and the
326 * pre-calculated direction or angle coefficients.
328 void ComputePanningGains(const ChannelConfig *chancoeffs, ALuint numchans, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
331 * ComputeFirstOrderGains
333 * Sets channel gains for a first-order ambisonics input channel. The matrix is
334 * a 1x4 'slice' of a transform matrix for the input channel, used to scale and
335 * orient the sound samples.
337 void ComputeFirstOrderGains(const ChannelConfig *chancoeffs, ALuint numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
340 ALvoid UpdateContextSources(ALCcontext *context);
342 ALvoid CalcSourceParams(struct ALvoice *voice, const struct ALsource *source, const ALCcontext *ALContext);
343 ALvoid CalcNonAttnSourceParams(struct ALvoice *voice, const struct ALsource *source, const ALCcontext *ALContext);
345 ALvoid MixSource(struct ALvoice *voice, struct ALsource *source, ALCdevice *Device, ALuint SamplesToDo);
347 ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size);
348 /* Caller must lock the device. */
349 ALvoid aluHandleDisconnect(ALCdevice *device);
351 extern ALfloat ConeScale;
352 extern ALfloat ZScale;
354 #ifdef __cplusplus
356 #endif
358 #endif