Add a higher quality bsinc resampler using 24 sample points
[openal-soft.git] / OpenAL32 / Include / alu.h
blobb322995b2cb731de80350136756208bdc2e95d11
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 "nfcfilter.h"
21 #include "math_defs.h"
24 #define MAX_PITCH (255)
26 /* Maximum number of buffer samples before the current pos needed for resampling. */
27 #define MAX_PRE_SAMPLES 24
29 /* Maximum number of buffer samples after the current pos needed for resampling. */
30 #define MAX_POST_SAMPLES 24
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
37 struct BSincTable;
38 struct ALsource;
39 struct ALbufferlistitem;
40 struct ALvoice;
41 struct ALeffectslot;
44 #define DITHER_RNG_SEED 22222
47 enum SpatializeMode {
48 SpatializeOff = AL_FALSE,
49 SpatializeOn = AL_TRUE,
50 SpatializeAuto = AL_AUTO_SOFT
53 enum Resampler {
54 PointResampler,
55 LinearResampler,
56 FIR4Resampler,
57 BSinc12Resampler,
58 BSinc24Resampler,
60 ResamplerMax = BSinc24Resampler
62 extern enum Resampler ResamplerDefault;
64 /* The number of distinct scale and phase intervals within the bsinc filter
65 * table.
67 #define BSINC_SCALE_BITS 4
68 #define BSINC_SCALE_COUNT (1<<BSINC_SCALE_BITS)
69 #define BSINC_PHASE_BITS 4
70 #define BSINC_PHASE_COUNT (1<<BSINC_PHASE_BITS)
72 /* Interpolator state. Kind of a misnomer since the interpolator itself is
73 * stateless. This just keeps it from having to recompute scale-related
74 * mappings for every sample.
76 typedef struct BsincState {
77 ALfloat sf; /* Scale interpolation factor. */
78 ALsizei m; /* Coefficient count. */
79 ALint l; /* Left coefficient offset. */
80 /* Filter coefficients, followed by the scale, phase, and scale-phase
81 * delta coefficients. Starting at phase index 0, each subsequent phase
82 * index follows contiguously.
84 const ALfloat *filter;
85 } BsincState;
87 typedef struct Sinc4State {
88 const ALfloat (*filter)[4];
89 } Sinc4State;
91 typedef union InterpState {
92 BsincState bsinc;
93 Sinc4State sinc4;
94 } InterpState;
96 typedef const ALfloat* (*ResamplerFunc)(const InterpState *state,
97 const ALfloat *restrict src, ALsizei frac, ALint increment,
98 ALfloat *restrict dst, ALsizei dstlen
101 ALboolean BsincPrepare(const ALuint increment, BsincState *state, const struct BSincTable *table);
103 extern const struct BSincTable bsinc12;
104 extern const struct BSincTable bsinc24;
107 typedef union aluVector {
108 alignas(16) ALfloat v[4];
109 } aluVector;
111 inline void aluVectorSet(aluVector *vector, ALfloat x, ALfloat y, ALfloat z, ALfloat w)
113 vector->v[0] = x;
114 vector->v[1] = y;
115 vector->v[2] = z;
116 vector->v[3] = w;
120 typedef union aluMatrixf {
121 alignas(16) ALfloat m[4][4];
122 } aluMatrixf;
123 extern const aluMatrixf IdentityMatrixf;
125 inline void aluMatrixfSetRow(aluMatrixf *matrix, ALuint row,
126 ALfloat m0, ALfloat m1, ALfloat m2, ALfloat m3)
128 matrix->m[row][0] = m0;
129 matrix->m[row][1] = m1;
130 matrix->m[row][2] = m2;
131 matrix->m[row][3] = m3;
134 inline void aluMatrixfSet(aluMatrixf *matrix, ALfloat m00, ALfloat m01, ALfloat m02, ALfloat m03,
135 ALfloat m10, ALfloat m11, ALfloat m12, ALfloat m13,
136 ALfloat m20, ALfloat m21, ALfloat m22, ALfloat m23,
137 ALfloat m30, ALfloat m31, ALfloat m32, ALfloat m33)
139 aluMatrixfSetRow(matrix, 0, m00, m01, m02, m03);
140 aluMatrixfSetRow(matrix, 1, m10, m11, m12, m13);
141 aluMatrixfSetRow(matrix, 2, m20, m21, m22, m23);
142 aluMatrixfSetRow(matrix, 3, m30, m31, m32, m33);
146 enum ActiveFilters {
147 AF_None = 0,
148 AF_LowPass = 1,
149 AF_HighPass = 2,
150 AF_BandPass = AF_LowPass | AF_HighPass
154 typedef struct MixHrtfParams {
155 const ALfloat (*Coeffs)[2];
156 ALsizei Delay[2];
157 ALfloat Gain;
158 ALfloat GainStep;
159 } MixHrtfParams;
162 typedef struct DirectParams {
163 ALfilterState LowPass;
164 ALfilterState HighPass;
166 NfcFilter NFCtrlFilter[MAX_AMBI_ORDER];
168 struct {
169 HrtfParams Old;
170 HrtfParams Target;
171 HrtfState State;
172 } Hrtf;
174 struct {
175 ALfloat Current[MAX_OUTPUT_CHANNELS];
176 ALfloat Target[MAX_OUTPUT_CHANNELS];
177 } Gains;
178 } DirectParams;
180 typedef struct SendParams {
181 ALfilterState LowPass;
182 ALfilterState HighPass;
184 struct {
185 ALfloat Current[MAX_OUTPUT_CHANNELS];
186 ALfloat Target[MAX_OUTPUT_CHANNELS];
187 } Gains;
188 } SendParams;
191 struct ALvoiceProps {
192 ATOMIC(struct ALvoiceProps*) next;
194 ALfloat Pitch;
195 ALfloat Gain;
196 ALfloat OuterGain;
197 ALfloat MinGain;
198 ALfloat MaxGain;
199 ALfloat InnerAngle;
200 ALfloat OuterAngle;
201 ALfloat RefDistance;
202 ALfloat MaxDistance;
203 ALfloat RolloffFactor;
204 ALfloat Position[3];
205 ALfloat Velocity[3];
206 ALfloat Direction[3];
207 ALfloat Orientation[2][3];
208 ALboolean HeadRelative;
209 enum DistanceModel DistanceModel;
210 enum Resampler Resampler;
211 ALboolean DirectChannels;
212 enum SpatializeMode SpatializeMode;
214 ALboolean DryGainHFAuto;
215 ALboolean WetGainAuto;
216 ALboolean WetGainHFAuto;
217 ALfloat OuterGainHF;
219 ALfloat AirAbsorptionFactor;
220 ALfloat RoomRolloffFactor;
221 ALfloat DopplerFactor;
223 ALfloat StereoPan[2];
225 ALfloat Radius;
227 /** Direct filter and auxiliary send info. */
228 struct {
229 ALfloat Gain;
230 ALfloat GainHF;
231 ALfloat HFReference;
232 ALfloat GainLF;
233 ALfloat LFReference;
234 } Direct;
235 struct {
236 struct ALeffectslot *Slot;
237 ALfloat Gain;
238 ALfloat GainHF;
239 ALfloat HFReference;
240 ALfloat GainLF;
241 ALfloat LFReference;
242 } Send[];
245 /* If not 'fading', gain targets are used directly without fading. */
246 #define VOICE_IS_FADING (1<<0)
247 #define VOICE_HAS_HRTF (1<<1)
248 #define VOICE_HAS_NFC (1<<2)
250 typedef struct ALvoice {
251 struct ALvoiceProps *Props;
253 ATOMIC(struct ALvoiceProps*) Update;
254 ATOMIC(struct ALvoiceProps*) FreeList;
256 ATOMIC(struct ALsource*) Source;
257 ATOMIC(bool) Playing;
260 * Source offset in samples, relative to the currently playing buffer, NOT
261 * the whole queue, and the fractional (fixed-point) offset to the next
262 * sample.
264 ATOMIC(ALuint) position;
265 ATOMIC(ALsizei) position_fraction;
267 /* Current buffer queue item being played. */
268 ATOMIC(struct ALbufferlistitem*) current_buffer;
270 /* Buffer queue item to loop to at end of queue (will be NULL for non-
271 * looping voices).
273 ATOMIC(struct ALbufferlistitem*) loop_buffer;
276 * Number of channels and bytes-per-sample for the attached source's
277 * buffer(s).
279 ALsizei NumChannels;
280 ALsizei SampleSize;
282 /** Current target parameters used for mixing. */
283 ALint Step;
285 ResamplerFunc Resampler;
287 ALuint Flags;
289 ALuint Offset; /* Number of output samples mixed since starting. */
291 alignas(16) ALfloat PrevSamples[MAX_INPUT_CHANNELS][MAX_PRE_SAMPLES];
293 InterpState ResampleState;
295 struct {
296 enum ActiveFilters FilterType;
297 DirectParams Params[MAX_INPUT_CHANNELS];
299 ALfloat (*Buffer)[BUFFERSIZE];
300 ALsizei Channels;
301 ALsizei ChannelsPerOrder[MAX_AMBI_ORDER+1];
302 } Direct;
304 struct {
305 enum ActiveFilters FilterType;
306 SendParams Params[MAX_INPUT_CHANNELS];
308 ALfloat (*Buffer)[BUFFERSIZE];
309 ALsizei Channels;
310 } Send[];
311 } ALvoice;
313 void DeinitVoice(ALvoice *voice);
316 typedef void (*MixerFunc)(const ALfloat *data, ALsizei OutChans,
317 ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALfloat *CurrentGains,
318 const ALfloat *TargetGains, ALsizei Counter, ALsizei OutPos,
319 ALsizei BufferSize);
320 typedef void (*RowMixerFunc)(ALfloat *OutBuffer, const ALfloat *gains,
321 const ALfloat (*restrict data)[BUFFERSIZE], ALsizei InChans,
322 ALsizei InPos, ALsizei BufferSize);
323 typedef void (*HrtfMixerFunc)(ALfloat *restrict LeftOut, ALfloat *restrict RightOut,
324 const ALfloat *data, ALsizei Offset, ALsizei OutPos,
325 const ALsizei IrSize, MixHrtfParams *hrtfparams,
326 HrtfState *hrtfstate, ALsizei BufferSize);
327 typedef void (*HrtfMixerBlendFunc)(ALfloat *restrict LeftOut, ALfloat *restrict RightOut,
328 const ALfloat *data, ALsizei Offset, ALsizei OutPos,
329 const ALsizei IrSize, const HrtfParams *oldparams,
330 MixHrtfParams *newparams, HrtfState *hrtfstate,
331 ALsizei BufferSize);
332 typedef void (*HrtfDirectMixerFunc)(ALfloat *restrict LeftOut, ALfloat *restrict RightOut,
333 const ALfloat *data, ALsizei Offset, const ALsizei IrSize,
334 const ALfloat (*restrict Coeffs)[2],
335 ALfloat (*restrict Values)[2], ALsizei BufferSize);
338 #define GAIN_MIX_MAX (16.0f) /* +24dB */
340 #define GAIN_SILENCE_THRESHOLD (0.00001f) /* -100dB */
342 #define SPEEDOFSOUNDMETRESPERSEC (343.3f)
343 #define AIRABSORBGAINHF (0.99426f) /* -0.05dB */
345 /* Target gain for the reverb decay feedback reaching the decay time. */
346 #define REVERB_DECAY_GAIN (0.001f) /* -60 dB */
348 #define FRACTIONBITS (12)
349 #define FRACTIONONE (1<<FRACTIONBITS)
350 #define FRACTIONMASK (FRACTIONONE-1)
353 inline ALfloat minf(ALfloat a, ALfloat b)
354 { return ((a > b) ? b : a); }
355 inline ALfloat maxf(ALfloat a, ALfloat b)
356 { return ((a > b) ? a : b); }
357 inline ALfloat clampf(ALfloat val, ALfloat min, ALfloat max)
358 { return minf(max, maxf(min, val)); }
360 inline ALdouble mind(ALdouble a, ALdouble b)
361 { return ((a > b) ? b : a); }
362 inline ALdouble maxd(ALdouble a, ALdouble b)
363 { return ((a > b) ? a : b); }
364 inline ALdouble clampd(ALdouble val, ALdouble min, ALdouble max)
365 { return mind(max, maxd(min, val)); }
367 inline ALuint minu(ALuint a, ALuint b)
368 { return ((a > b) ? b : a); }
369 inline ALuint maxu(ALuint a, ALuint b)
370 { return ((a > b) ? a : b); }
371 inline ALuint clampu(ALuint val, ALuint min, ALuint max)
372 { return minu(max, maxu(min, val)); }
374 inline ALint mini(ALint a, ALint b)
375 { return ((a > b) ? b : a); }
376 inline ALint maxi(ALint a, ALint b)
377 { return ((a > b) ? a : b); }
378 inline ALint clampi(ALint val, ALint min, ALint max)
379 { return mini(max, maxi(min, val)); }
381 inline ALint64 mini64(ALint64 a, ALint64 b)
382 { return ((a > b) ? b : a); }
383 inline ALint64 maxi64(ALint64 a, ALint64 b)
384 { return ((a > b) ? a : b); }
385 inline ALint64 clampi64(ALint64 val, ALint64 min, ALint64 max)
386 { return mini64(max, maxi64(min, val)); }
388 inline ALuint64 minu64(ALuint64 a, ALuint64 b)
389 { return ((a > b) ? b : a); }
390 inline ALuint64 maxu64(ALuint64 a, ALuint64 b)
391 { return ((a > b) ? a : b); }
392 inline ALuint64 clampu64(ALuint64 val, ALuint64 min, ALuint64 max)
393 { return minu64(max, maxu64(min, val)); }
396 inline ALfloat lerp(ALfloat val1, ALfloat val2, ALfloat mu)
398 return val1 + (val2-val1)*mu;
400 inline ALfloat resample_fir4(ALfloat val0, ALfloat val1, ALfloat val2, ALfloat val3, const ALfloat *restrict filter)
402 return filter[0]*val0 + filter[1]*val1 + filter[2]*val2 + filter[3]*val3;
406 enum HrtfRequestMode {
407 Hrtf_Default = 0,
408 Hrtf_Enable = 1,
409 Hrtf_Disable = 2,
412 void aluInit(void);
414 void aluInitMixer(void);
416 MixerFunc SelectMixer(void);
417 RowMixerFunc SelectRowMixer(void);
418 ResamplerFunc SelectResampler(enum Resampler resampler);
420 /* aluInitRenderer
422 * Set up the appropriate panning method and mixing method given the device
423 * properties.
425 void aluInitRenderer(ALCdevice *device, ALint hrtf_id, enum HrtfRequestMode hrtf_appreq, enum HrtfRequestMode hrtf_userreq);
427 void aluInitEffectPanning(struct ALeffectslot *slot);
430 * CalcDirectionCoeffs
432 * Calculates ambisonic coefficients based on a direction vector. The vector
433 * must be normalized (unit length), and the spread is the angular width of the
434 * sound (0...tau).
436 void CalcDirectionCoeffs(const ALfloat dir[3], ALfloat spread, ALfloat coeffs[MAX_AMBI_COEFFS]);
439 * CalcAngleCoeffs
441 * Calculates ambisonic coefficients based on azimuth and elevation. The
442 * azimuth and elevation parameters are in radians, going right and up
443 * respectively.
445 inline void CalcAngleCoeffs(ALfloat azimuth, ALfloat elevation, ALfloat spread, ALfloat coeffs[MAX_AMBI_COEFFS])
447 ALfloat dir[3] = {
448 sinf(azimuth) * cosf(elevation),
449 sinf(elevation),
450 -cosf(azimuth) * cosf(elevation)
452 CalcDirectionCoeffs(dir, spread, coeffs);
456 * CalcAnglePairwiseCoeffs
458 * Calculates ambisonic coefficients based on azimuth and elevation. The
459 * azimuth and elevation parameters are in radians, going right and up
460 * respectively. This pairwise variant warps the result such that +30 azimuth
461 * is full right, and -30 azimuth is full left.
463 void CalcAnglePairwiseCoeffs(ALfloat azimuth, ALfloat elevation, ALfloat spread, ALfloat coeffs[MAX_AMBI_COEFFS]);
466 * ComputeAmbientGains
468 * Computes channel gains for ambient, omni-directional sounds.
470 #define ComputeAmbientGains(b, g, o) do { \
471 if((b).CoeffCount > 0) \
472 ComputeAmbientGainsMC((b).Ambi.Coeffs, (b).NumChannels, g, o); \
473 else \
474 ComputeAmbientGainsBF((b).Ambi.Map, (b).NumChannels, g, o); \
475 } while (0)
476 void ComputeAmbientGainsMC(const ChannelConfig *chancoeffs, ALsizei numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
477 void ComputeAmbientGainsBF(const BFChannelConfig *chanmap, ALsizei numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
480 * ComputePanningGains
482 * Computes panning gains using the given channel decoder coefficients and the
483 * pre-calculated direction or angle coefficients.
485 #define ComputePanningGains(b, c, g, o) do { \
486 if((b).CoeffCount > 0) \
487 ComputePanningGainsMC((b).Ambi.Coeffs, (b).NumChannels, (b).CoeffCount, c, g, o);\
488 else \
489 ComputePanningGainsBF((b).Ambi.Map, (b).NumChannels, c, g, o); \
490 } while (0)
491 void ComputePanningGainsMC(const ChannelConfig *chancoeffs, ALsizei numchans, ALsizei numcoeffs, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
492 void ComputePanningGainsBF(const BFChannelConfig *chanmap, ALsizei numchans, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
495 * ComputeFirstOrderGains
497 * Sets channel gains for a first-order ambisonics input channel. The matrix is
498 * a 1x4 'slice' of a transform matrix for the input channel, used to scale and
499 * orient the sound samples.
501 #define ComputeFirstOrderGains(b, m, g, o) do { \
502 if((b).CoeffCount > 0) \
503 ComputeFirstOrderGainsMC((b).Ambi.Coeffs, (b).NumChannels, m, g, o); \
504 else \
505 ComputeFirstOrderGainsBF((b).Ambi.Map, (b).NumChannels, m, g, o); \
506 } while (0)
507 void ComputeFirstOrderGainsMC(const ChannelConfig *chancoeffs, ALsizei numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
508 void ComputeFirstOrderGainsBF(const BFChannelConfig *chanmap, ALsizei numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]);
511 ALboolean MixSource(struct ALvoice *voice, struct ALsource *Source, ALCdevice *Device, ALsizei SamplesToDo);
513 void aluMixData(ALCdevice *device, ALvoid *OutBuffer, ALsizei NumSamples);
514 /* Caller must lock the device. */
515 void aluHandleDisconnect(ALCdevice *device);
517 extern ALfloat ConeScale;
518 extern ALfloat ZScale;
520 #ifdef __cplusplus
522 #endif
524 #endif