Add noexcept to a bunch of inline functions
[openal-soft.git] / OpenAL32 / Include / alu.h
blobeb71290a8e95e51175152cca0a58018f80c4a098
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"
16 #include "hrtf.h"
17 #include "math_defs.h"
18 #include "filters/defs.h"
19 #include "filters/nfc.h"
22 enum class DistanceModel;
24 #define MAX_PITCH (255)
26 /* Maximum number of samples to pad on either end of a buffer for resampling.
27 * Note that both the beginning and end need padding!
29 #define MAX_RESAMPLE_PADDING 24
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
36 struct BSincTable;
37 struct ALsource;
38 struct ALbufferlistitem;
39 struct ALvoice;
40 struct ALeffectslot;
43 #define DITHER_RNG_SEED 22222
46 enum SpatializeMode {
47 SpatializeOff = AL_FALSE,
48 SpatializeOn = AL_TRUE,
49 SpatializeAuto = AL_AUTO_SOFT
52 enum Resampler {
53 PointResampler,
54 LinearResampler,
55 FIR4Resampler,
56 BSinc12Resampler,
57 BSinc24Resampler,
59 ResamplerMax = BSinc24Resampler
61 extern enum Resampler ResamplerDefault;
63 /* The number of distinct scale and phase intervals within the bsinc filter
64 * table.
66 #define BSINC_SCALE_BITS 4
67 #define BSINC_SCALE_COUNT (1<<BSINC_SCALE_BITS)
68 #define BSINC_PHASE_BITS 4
69 #define BSINC_PHASE_COUNT (1<<BSINC_PHASE_BITS)
71 /* Interpolator state. Kind of a misnomer since the interpolator itself is
72 * stateless. This just keeps it from having to recompute scale-related
73 * mappings for every sample.
75 typedef struct BsincState {
76 ALfloat sf; /* Scale interpolation factor. */
77 ALsizei m; /* Coefficient count. */
78 ALsizei l; /* Left coefficient offset. */
79 /* Filter coefficients, followed by the scale, phase, and scale-phase
80 * delta coefficients. Starting at phase index 0, each subsequent phase
81 * index follows contiguously.
83 const ALfloat *filter;
84 } BsincState;
86 typedef union InterpState {
87 BsincState bsinc;
88 } InterpState;
90 typedef const ALfloat* (*ResamplerFunc)(const InterpState *state,
91 const ALfloat *RESTRICT src, ALsizei frac, ALint increment,
92 ALfloat *RESTRICT dst, ALsizei dstlen
95 void BsincPrepare(const ALuint increment, BsincState *state, const struct BSincTable *table);
97 extern const struct BSincTable bsinc12;
98 extern const struct BSincTable bsinc24;
101 enum {
102 AF_None = 0,
103 AF_LowPass = 1,
104 AF_HighPass = 2,
105 AF_BandPass = AF_LowPass | AF_HighPass
109 typedef struct MixHrtfParams {
110 const ALfloat (*Coeffs)[2];
111 ALsizei Delay[2];
112 ALfloat Gain;
113 ALfloat GainStep;
114 } MixHrtfParams;
117 typedef struct DirectParams {
118 BiquadFilter LowPass;
119 BiquadFilter HighPass;
121 NfcFilter NFCtrlFilter;
123 struct {
124 HrtfParams Old;
125 HrtfParams Target;
126 HrtfState State;
127 } Hrtf;
129 struct {
130 ALfloat Current[MAX_OUTPUT_CHANNELS];
131 ALfloat Target[MAX_OUTPUT_CHANNELS];
132 } Gains;
133 } DirectParams;
135 typedef struct SendParams {
136 BiquadFilter LowPass;
137 BiquadFilter HighPass;
139 struct {
140 ALfloat Current[MAX_OUTPUT_CHANNELS];
141 ALfloat Target[MAX_OUTPUT_CHANNELS];
142 } Gains;
143 } SendParams;
146 struct ALvoiceProps {
147 ATOMIC(struct ALvoiceProps*) next;
149 ALfloat Pitch;
150 ALfloat Gain;
151 ALfloat OuterGain;
152 ALfloat MinGain;
153 ALfloat MaxGain;
154 ALfloat InnerAngle;
155 ALfloat OuterAngle;
156 ALfloat RefDistance;
157 ALfloat MaxDistance;
158 ALfloat RolloffFactor;
159 ALfloat Position[3];
160 ALfloat Velocity[3];
161 ALfloat Direction[3];
162 ALfloat Orientation[2][3];
163 ALboolean HeadRelative;
164 DistanceModel mDistanceModel;
165 enum Resampler Resampler;
166 ALboolean DirectChannels;
167 enum SpatializeMode SpatializeMode;
169 ALboolean DryGainHFAuto;
170 ALboolean WetGainAuto;
171 ALboolean WetGainHFAuto;
172 ALfloat OuterGainHF;
174 ALfloat AirAbsorptionFactor;
175 ALfloat RoomRolloffFactor;
176 ALfloat DopplerFactor;
178 ALfloat StereoPan[2];
180 ALfloat Radius;
182 /** Direct filter and auxiliary send info. */
183 struct {
184 ALfloat Gain;
185 ALfloat GainHF;
186 ALfloat HFReference;
187 ALfloat GainLF;
188 ALfloat LFReference;
189 } Direct;
190 struct {
191 struct ALeffectslot *Slot;
192 ALfloat Gain;
193 ALfloat GainHF;
194 ALfloat HFReference;
195 ALfloat GainLF;
196 ALfloat LFReference;
197 } Send[];
200 #define VOICE_IS_STATIC (1<<0)
201 #define VOICE_IS_FADING (1<<1) /* Fading sources use gain stepping for smooth transitions. */
202 #define VOICE_HAS_HRTF (1<<2)
203 #define VOICE_HAS_NFC (1<<3)
205 typedef struct ALvoice {
206 struct ALvoiceProps *Props;
208 ATOMIC(struct ALvoiceProps*) Update;
210 ATOMIC(struct ALsource*) Source;
211 ATOMIC(bool) Playing;
214 * Source offset in samples, relative to the currently playing buffer, NOT
215 * the whole queue, and the fractional (fixed-point) offset to the next
216 * sample.
218 ATOMIC(ALuint) position;
219 ATOMIC(ALsizei) position_fraction;
221 /* Current buffer queue item being played. */
222 ATOMIC(struct ALbufferlistitem*) current_buffer;
224 /* Buffer queue item to loop to at end of queue (will be NULL for non-
225 * looping voices).
227 ATOMIC(struct ALbufferlistitem*) loop_buffer;
230 * Number of channels and bytes-per-sample for the attached source's
231 * buffer(s).
233 ALsizei NumChannels;
234 ALsizei SampleSize;
236 /** Current target parameters used for mixing. */
237 ALint Step;
239 ResamplerFunc Resampler;
241 ALuint Flags;
243 ALuint Offset; /* Number of output samples mixed since starting. */
245 alignas(16) ALfloat PrevSamples[MAX_INPUT_CHANNELS][MAX_RESAMPLE_PADDING];
247 InterpState ResampleState;
249 struct {
250 int FilterType;
251 DirectParams Params[MAX_INPUT_CHANNELS];
253 ALfloat (*Buffer)[BUFFERSIZE];
254 ALsizei Channels;
255 ALsizei ChannelsPerOrder[MAX_AMBI_ORDER+1];
256 } Direct;
258 struct {
259 int FilterType;
260 SendParams Params[MAX_INPUT_CHANNELS];
262 ALfloat (*Buffer)[BUFFERSIZE];
263 ALsizei Channels;
264 } Send[];
265 } ALvoice;
267 void DeinitVoice(ALvoice *voice);
270 typedef void (*MixerFunc)(const ALfloat *data, ALsizei OutChans,
271 ALfloat (*RESTRICT OutBuffer)[BUFFERSIZE], ALfloat *CurrentGains,
272 const ALfloat *TargetGains, ALsizei Counter, ALsizei OutPos,
273 ALsizei BufferSize);
274 typedef void (*RowMixerFunc)(ALfloat *OutBuffer, const ALfloat *gains,
275 const ALfloat (*RESTRICT data)[BUFFERSIZE], ALsizei InChans,
276 ALsizei InPos, ALsizei BufferSize);
277 typedef void (*HrtfMixerFunc)(ALfloat *RESTRICT LeftOut, ALfloat *RESTRICT RightOut,
278 const ALfloat *data, ALsizei Offset, ALsizei OutPos,
279 const ALsizei IrSize, MixHrtfParams *hrtfparams,
280 HrtfState *hrtfstate, ALsizei BufferSize);
281 typedef void (*HrtfMixerBlendFunc)(ALfloat *RESTRICT LeftOut, ALfloat *RESTRICT RightOut,
282 const ALfloat *data, ALsizei Offset, ALsizei OutPos,
283 const ALsizei IrSize, const HrtfParams *oldparams,
284 MixHrtfParams *newparams, HrtfState *hrtfstate,
285 ALsizei BufferSize);
286 typedef void (*HrtfDirectMixerFunc)(ALfloat *RESTRICT LeftOut, ALfloat *RESTRICT RightOut,
287 const ALfloat *data, ALsizei Offset, const ALsizei IrSize,
288 const ALfloat (*RESTRICT Coeffs)[2],
289 ALfloat (*RESTRICT Values)[2], ALsizei BufferSize);
292 #define GAIN_MIX_MAX (16.0f) /* +24dB */
294 #define GAIN_SILENCE_THRESHOLD (0.00001f) /* -100dB */
296 #define SPEEDOFSOUNDMETRESPERSEC (343.3f)
297 #define AIRABSORBGAINHF (0.99426f) /* -0.05dB */
299 /* Target gain for the reverb decay feedback reaching the decay time. */
300 #define REVERB_DECAY_GAIN (0.001f) /* -60 dB */
302 #define FRACTIONBITS (12)
303 #define FRACTIONONE (1<<FRACTIONBITS)
304 #define FRACTIONMASK (FRACTIONONE-1)
307 inline ALfloat minf(ALfloat a, ALfloat b) noexcept
308 { return ((a > b) ? b : a); }
309 inline ALfloat maxf(ALfloat a, ALfloat b) noexcept
310 { return ((a > b) ? a : b); }
311 inline ALfloat clampf(ALfloat val, ALfloat min, ALfloat max) noexcept
312 { return minf(max, maxf(min, val)); }
314 inline ALdouble mind(ALdouble a, ALdouble b) noexcept
315 { return ((a > b) ? b : a); }
316 inline ALdouble maxd(ALdouble a, ALdouble b) noexcept
317 { return ((a > b) ? a : b); }
318 inline ALdouble clampd(ALdouble val, ALdouble min, ALdouble max) noexcept
319 { return mind(max, maxd(min, val)); }
321 inline ALuint minu(ALuint a, ALuint b) noexcept
322 { return ((a > b) ? b : a); }
323 inline ALuint maxu(ALuint a, ALuint b) noexcept
324 { return ((a > b) ? a : b); }
325 inline ALuint clampu(ALuint val, ALuint min, ALuint max) noexcept
326 { return minu(max, maxu(min, val)); }
328 inline ALint mini(ALint a, ALint b) noexcept
329 { return ((a > b) ? b : a); }
330 inline ALint maxi(ALint a, ALint b) noexcept
331 { return ((a > b) ? a : b); }
332 inline ALint clampi(ALint val, ALint min, ALint max) noexcept
333 { return mini(max, maxi(min, val)); }
335 inline ALint64 mini64(ALint64 a, ALint64 b) noexcept
336 { return ((a > b) ? b : a); }
337 inline ALint64 maxi64(ALint64 a, ALint64 b) noexcept
338 { return ((a > b) ? a : b); }
339 inline ALint64 clampi64(ALint64 val, ALint64 min, ALint64 max) noexcept
340 { return mini64(max, maxi64(min, val)); }
342 inline ALuint64 minu64(ALuint64 a, ALuint64 b) noexcept
343 { return ((a > b) ? b : a); }
344 inline ALuint64 maxu64(ALuint64 a, ALuint64 b) noexcept
345 { return ((a > b) ? a : b); }
346 inline ALuint64 clampu64(ALuint64 val, ALuint64 min, ALuint64 max) noexcept
347 { return minu64(max, maxu64(min, val)); }
349 inline size_t minz(size_t a, size_t b) noexcept
350 { return ((a > b) ? b : a); }
351 inline size_t maxz(size_t a, size_t b) noexcept
352 { return ((a > b) ? a : b); }
353 inline size_t clampz(size_t val, size_t min, size_t max) noexcept
354 { return minz(max, maxz(min, val)); }
357 inline ALfloat lerp(ALfloat val1, ALfloat val2, ALfloat mu) noexcept
359 return val1 + (val2-val1)*mu;
361 inline ALfloat cubic(ALfloat val1, ALfloat val2, ALfloat val3, ALfloat val4, ALfloat mu) noexcept
363 ALfloat mu2 = mu*mu, mu3 = mu2*mu;
364 ALfloat a0 = -0.5f*mu3 + mu2 + -0.5f*mu;
365 ALfloat a1 = 1.5f*mu3 + -2.5f*mu2 + 1.0f;
366 ALfloat a2 = -1.5f*mu3 + 2.0f*mu2 + 0.5f*mu;
367 ALfloat a3 = 0.5f*mu3 + -0.5f*mu2;
368 return val1*a0 + val2*a1 + val3*a2 + val4*a3;
372 enum HrtfRequestMode {
373 Hrtf_Default = 0,
374 Hrtf_Enable = 1,
375 Hrtf_Disable = 2,
378 void aluInit(void);
380 void aluInitMixer(void);
382 ResamplerFunc SelectResampler(enum Resampler resampler);
384 /* aluInitRenderer
386 * Set up the appropriate panning method and mixing method given the device
387 * properties.
389 void aluInitRenderer(ALCdevice *device, ALint hrtf_id, enum HrtfRequestMode hrtf_appreq, enum HrtfRequestMode hrtf_userreq);
391 void aluInitEffectPanning(struct ALeffectslot *slot);
393 void aluSelectPostProcess(ALCdevice *device);
396 * Calculates ambisonic encoder coefficients using the X, Y, and Z direction
397 * components, which must represent a normalized (unit length) vector, and the
398 * spread is the angular width of the sound (0...tau).
400 * NOTE: The components use ambisonic coordinates. As a result:
402 * Ambisonic Y = OpenAL -X
403 * Ambisonic Z = OpenAL Y
404 * Ambisonic X = OpenAL -Z
406 * The components are ordered such that OpenAL's X, Y, and Z are the first,
407 * second, and third parameters respectively -- simply negate X and Z.
409 void CalcAmbiCoeffs(const ALfloat y, const ALfloat z, const ALfloat x, const ALfloat spread,
410 ALfloat coeffs[MAX_AMBI_COEFFS]);
413 * CalcDirectionCoeffs
415 * Calculates ambisonic coefficients based on an OpenAL direction vector. The
416 * vector must be normalized (unit length), and the spread is the angular width
417 * of the sound (0...tau).
419 inline void CalcDirectionCoeffs(const ALfloat dir[3], ALfloat spread, ALfloat coeffs[MAX_AMBI_COEFFS])
421 /* Convert from OpenAL coords to Ambisonics. */
422 CalcAmbiCoeffs(-dir[0], dir[1], -dir[2], spread, coeffs);
426 * CalcAngleCoeffs
428 * Calculates ambisonic coefficients based on azimuth and elevation. The
429 * azimuth and elevation parameters are in radians, going right and up
430 * respectively.
432 inline void CalcAngleCoeffs(ALfloat azimuth, ALfloat elevation, ALfloat spread, ALfloat coeffs[MAX_AMBI_COEFFS])
434 ALfloat x = -sinf(azimuth) * cosf(elevation);
435 ALfloat y = sinf(elevation);
436 ALfloat z = cosf(azimuth) * cosf(elevation);
438 CalcAmbiCoeffs(x, y, z, spread, coeffs);
442 * ScaleAzimuthFront
444 * Scales the given azimuth toward the side (+/- pi/2 radians) for positions in
445 * front.
447 inline float ScaleAzimuthFront(float azimuth, float scale)
449 ALfloat sign = copysignf(1.0f, azimuth);
450 if(!(fabsf(azimuth) > F_PI_2))
451 return minf(fabsf(azimuth) * scale, F_PI_2) * sign;
452 return azimuth;
456 void ComputePanningGainsMC(const ChannelConfig *chancoeffs, ALsizei numchans, ALsizei numcoeffs, const ALfloat*RESTRICT coeffs, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
457 void ComputePanningGainsBF(const BFChannelConfig *chanmap, ALsizei numchans, const ALfloat*RESTRICT coeffs, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
460 * ComputePanGains
462 * Computes panning gains using the given channel decoder coefficients and the
463 * pre-calculated direction or angle coefficients. For B-Format sources, the
464 * coeffs are a 'slice' of a transform matrix for the input channel, used to
465 * scale and orient the sound samples.
467 inline void ComputePanGains(const MixParams *dry, const ALfloat*RESTRICT coeffs, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS])
469 if(dry->CoeffCount > 0)
470 ComputePanningGainsMC(dry->Ambi.Coeffs, dry->NumChannels, dry->CoeffCount,
471 coeffs, ingain, gains);
472 else
473 ComputePanningGainsBF(dry->Ambi.Map, dry->NumChannels, coeffs, ingain, gains);
477 ALboolean MixSource(struct ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsizei SamplesToDo);
479 void aluMixData(ALCdevice *device, ALvoid *OutBuffer, ALsizei NumSamples);
480 /* Caller must lock the device, and the mixer must not be running. */
481 void aluHandleDisconnect(ALCdevice *device, const char *msg, ...) DECL_FORMAT(printf, 2, 3);
483 extern MixerFunc MixSamples;
484 extern RowMixerFunc MixRowSamples;
486 extern ALfloat ConeScale;
487 extern ALfloat ZScale;
488 extern ALboolean OverrideReverbSpeedOfSound;
490 #ifdef __cplusplus
492 #endif
494 #endif