16 #include "alAuxEffectSlot.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
42 /* The number of distinct scale and phase intervals within the filter table. */
43 #define BSINC_SCALE_BITS 4
44 #define BSINC_SCALE_COUNT (1<<BSINC_SCALE_BITS)
45 #define BSINC_PHASE_BITS 4
46 #define BSINC_PHASE_COUNT (1<<BSINC_PHASE_BITS)
48 /* Interpolator state. Kind of a misnomer since the interpolator itself is
49 * stateless. This just keeps it from having to recompute scale-related
50 * mappings for every sample.
52 typedef struct BsincState
{
53 ALfloat sf
; /* Scale interpolation factor. */
54 ALuint m
; /* Coefficient count. */
55 ALint l
; /* Left coefficient offset. */
57 const ALfloat
*filter
; /* Filter coefficients. */
58 const ALfloat
*scDelta
; /* Scale deltas. */
59 const ALfloat
*phDelta
; /* Phase deltas. */
60 const ALfloat
*spDelta
; /* Scale-phase deltas. */
61 } coeffs
[BSINC_PHASE_COUNT
];
65 typedef union aluVector
{
66 alignas(16) ALfloat v
[4];
69 inline void aluVectorSet(aluVector
*vector
, ALfloat x
, ALfloat y
, ALfloat z
, ALfloat w
)
78 typedef union aluMatrixf
{
79 alignas(16) ALfloat m
[4][4];
82 inline void aluMatrixfSetRow(aluMatrixf
*matrix
, ALuint row
,
83 ALfloat m0
, ALfloat m1
, ALfloat m2
, ALfloat m3
)
85 matrix
->m
[row
][0] = m0
;
86 matrix
->m
[row
][1] = m1
;
87 matrix
->m
[row
][2] = m2
;
88 matrix
->m
[row
][3] = m3
;
91 inline void aluMatrixfSet(aluMatrixf
*matrix
, ALfloat m00
, ALfloat m01
, ALfloat m02
, ALfloat m03
,
92 ALfloat m10
, ALfloat m11
, ALfloat m12
, ALfloat m13
,
93 ALfloat m20
, ALfloat m21
, ALfloat m22
, ALfloat m23
,
94 ALfloat m30
, ALfloat m31
, ALfloat m32
, ALfloat m33
)
96 aluMatrixfSetRow(matrix
, 0, m00
, m01
, m02
, m03
);
97 aluMatrixfSetRow(matrix
, 1, m10
, m11
, m12
, m13
);
98 aluMatrixfSetRow(matrix
, 2, m20
, m21
, m22
, m23
);
99 aluMatrixfSetRow(matrix
, 3, m30
, m31
, m32
, m33
);
103 typedef union aluMatrixd
{
104 alignas(16) ALdouble m
[4][4];
107 inline void aluMatrixdSetRow(aluMatrixd
*matrix
, ALuint row
,
108 ALdouble m0
, ALdouble m1
, ALdouble m2
, ALdouble m3
)
110 matrix
->m
[row
][0] = m0
;
111 matrix
->m
[row
][1] = m1
;
112 matrix
->m
[row
][2] = m2
;
113 matrix
->m
[row
][3] = m3
;
116 inline void aluMatrixdSet(aluMatrixd
*matrix
, ALdouble m00
, ALdouble m01
, ALdouble m02
, ALdouble m03
,
117 ALdouble m10
, ALdouble m11
, ALdouble m12
, ALdouble m13
,
118 ALdouble m20
, ALdouble m21
, ALdouble m22
, ALdouble m23
,
119 ALdouble m30
, ALdouble m31
, ALdouble m32
, ALdouble m33
)
121 aluMatrixdSetRow(matrix
, 0, m00
, m01
, m02
, m03
);
122 aluMatrixdSetRow(matrix
, 1, m10
, m11
, m12
, m13
);
123 aluMatrixdSetRow(matrix
, 2, m20
, m21
, m22
, m23
);
124 aluMatrixdSetRow(matrix
, 3, m30
, m31
, m32
, m33
);
132 AF_BandPass
= AF_LowPass
| AF_HighPass
136 typedef struct MixGains
{
142 typedef struct MixHrtfParams
{
143 const HrtfParams
*Target
;
146 alignas(16) ALfloat Coeffs
[HRIR_LENGTH
][2];
151 typedef struct DirectParams
{
152 ALfloat (*OutBuffer
)[BUFFERSIZE
];
156 enum ActiveFilters ActiveType
;
157 ALfilterState LowPass
;
158 ALfilterState HighPass
;
159 } Filters
[MAX_INPUT_CHANNELS
];
165 } Hrtf
[MAX_INPUT_CHANNELS
];
168 ALfloat Current
[MAX_OUTPUT_CHANNELS
];
169 ALfloat Target
[MAX_OUTPUT_CHANNELS
];
170 } Gains
[MAX_INPUT_CHANNELS
];
173 typedef struct SendParams
{
174 ALfloat (*OutBuffer
)[BUFFERSIZE
];
178 enum ActiveFilters ActiveType
;
179 ALfilterState LowPass
;
180 ALfilterState HighPass
;
181 } Filters
[MAX_INPUT_CHANNELS
];
184 ALfloat Current
[MAX_OUTPUT_CHANNELS
];
185 ALfloat Target
[MAX_OUTPUT_CHANNELS
];
186 } Gains
[MAX_INPUT_CHANNELS
];
190 typedef const ALfloat
* (*ResamplerFunc
)(const BsincState
*state
,
191 const ALfloat
*src
, ALuint frac
, ALuint increment
, ALfloat
*restrict dst
, ALuint dstlen
194 typedef void (*MixerFunc
)(const ALfloat
*data
, ALuint OutChans
,
195 ALfloat (*restrict OutBuffer
)[BUFFERSIZE
], struct MixGains
*Gains
,
196 ALuint Counter
, ALuint OutPos
, ALuint BufferSize
);
197 typedef void (*HrtfMixerFunc
)(ALfloat (*restrict OutBuffer
)[BUFFERSIZE
], ALuint lidx
, ALuint ridx
,
198 const ALfloat
*data
, ALuint Counter
, ALuint Offset
, ALuint OutPos
,
199 const ALuint IrSize
, const MixHrtfParams
*hrtfparams
,
200 HrtfState
*hrtfstate
, ALuint BufferSize
);
203 #define GAIN_SILENCE_THRESHOLD (0.00001f) /* -100dB */
205 #define SPEEDOFSOUNDMETRESPERSEC (343.3f)
206 #define AIRABSORBGAINHF (0.99426f) /* -0.05dB */
208 #define FRACTIONBITS (12)
209 #define FRACTIONONE (1<<FRACTIONBITS)
210 #define FRACTIONMASK (FRACTIONONE-1)
213 inline ALfloat
minf(ALfloat a
, ALfloat b
)
214 { return ((a
> b
) ? b
: a
); }
215 inline ALfloat
maxf(ALfloat a
, ALfloat b
)
216 { return ((a
> b
) ? a
: b
); }
217 inline ALfloat
clampf(ALfloat val
, ALfloat min
, ALfloat max
)
218 { return minf(max
, maxf(min
, val
)); }
220 inline ALdouble
mind(ALdouble a
, ALdouble b
)
221 { return ((a
> b
) ? b
: a
); }
222 inline ALdouble
maxd(ALdouble a
, ALdouble b
)
223 { return ((a
> b
) ? a
: b
); }
224 inline ALdouble
clampd(ALdouble val
, ALdouble min
, ALdouble max
)
225 { return mind(max
, maxd(min
, val
)); }
227 inline ALuint
minu(ALuint a
, ALuint b
)
228 { return ((a
> b
) ? b
: a
); }
229 inline ALuint
maxu(ALuint a
, ALuint b
)
230 { return ((a
> b
) ? a
: b
); }
231 inline ALuint
clampu(ALuint val
, ALuint min
, ALuint max
)
232 { return minu(max
, maxu(min
, val
)); }
234 inline ALint
mini(ALint a
, ALint b
)
235 { return ((a
> b
) ? b
: a
); }
236 inline ALint
maxi(ALint a
, ALint b
)
237 { return ((a
> b
) ? a
: b
); }
238 inline ALint
clampi(ALint val
, ALint min
, ALint max
)
239 { return mini(max
, maxi(min
, val
)); }
241 inline ALint64
mini64(ALint64 a
, ALint64 b
)
242 { return ((a
> b
) ? b
: a
); }
243 inline ALint64
maxi64(ALint64 a
, ALint64 b
)
244 { return ((a
> b
) ? a
: b
); }
245 inline ALint64
clampi64(ALint64 val
, ALint64 min
, ALint64 max
)
246 { return mini64(max
, maxi64(min
, val
)); }
248 inline ALuint64
minu64(ALuint64 a
, ALuint64 b
)
249 { return ((a
> b
) ? b
: a
); }
250 inline ALuint64
maxu64(ALuint64 a
, ALuint64 b
)
251 { return ((a
> b
) ? a
: b
); }
252 inline ALuint64
clampu64(ALuint64 val
, ALuint64 min
, ALuint64 max
)
253 { return minu64(max
, maxu64(min
, val
)); }
256 union ResamplerCoeffs
{
257 ALfloat FIR4
[FRACTIONONE
][4];
258 ALfloat FIR8
[FRACTIONONE
][8];
260 extern alignas(16) union ResamplerCoeffs ResampleCoeffs
;
262 extern alignas(16) const ALfloat bsincTab
[18840];
265 inline ALfloat
lerp(ALfloat val1
, ALfloat val2
, ALfloat mu
)
267 return val1
+ (val2
-val1
)*mu
;
269 inline ALfloat
resample_fir4(ALfloat val0
, ALfloat val1
, ALfloat val2
, ALfloat val3
, ALuint frac
)
271 const ALfloat
*k
= ResampleCoeffs
.FIR4
[frac
];
272 return k
[0]*val0
+ k
[1]*val1
+ k
[2]*val2
+ k
[3]*val3
;
274 inline ALfloat
resample_fir8(ALfloat val0
, ALfloat val1
, ALfloat val2
, ALfloat val3
, ALfloat val4
, ALfloat val5
, ALfloat val6
, ALfloat val7
, ALuint frac
)
276 const ALfloat
*k
= ResampleCoeffs
.FIR8
[frac
];
277 return k
[0]*val0
+ k
[1]*val1
+ k
[2]*val2
+ k
[3]*val3
+
278 k
[4]*val4
+ k
[5]*val5
+ k
[6]*val6
+ k
[7]*val7
;
282 void aluInitMixer(void);
284 ALvoid
aluInitPanning(ALCdevice
*Device
, const struct AmbDecConf
*conf
);
286 void aluInitEffectPanning(struct ALeffectslot
*slot
);
289 * CalcDirectionCoeffs
291 * Calculates ambisonic coefficients based on a direction vector. The vector
292 * must not be longer than 1 unit.
294 void CalcDirectionCoeffs(const ALfloat dir
[3], ALfloat coeffs
[MAX_AMBI_COEFFS
]);
299 * Same as CalcDirectionCoeffs except the direction is specified as separate x,
300 * y, and z parameters instead of an array.
302 inline void CalcXYZCoeffs(ALfloat x
, ALfloat y
, ALfloat z
, ALfloat coeffs
[MAX_AMBI_COEFFS
])
304 ALfloat dir
[3] = { x
, y
, z
};
305 CalcDirectionCoeffs(dir
, coeffs
);
311 * Calculates ambisonic coefficients based on angle and elevation. The angle
312 * and elevation parameters are in radians, going right and up respectively.
314 void CalcAngleCoeffs(ALfloat angle
, ALfloat elevation
, ALfloat coeffs
[MAX_AMBI_COEFFS
]);
317 * ComputeAmbientGains
319 * Computes channel gains for ambient, omni-directional sounds.
321 void ComputeAmbientGains(const ChannelConfig
*chancoeffs
, ALuint numchans
, ALfloat ingain
, ALfloat gains
[MAX_OUTPUT_CHANNELS
]);
324 * ComputePanningGains
326 * Computes panning gains using the given channel decoder coefficients and the
327 * pre-calculated direction or angle coefficients.
329 void ComputePanningGains(const ChannelConfig
*chancoeffs
, ALuint numchans
, const ALfloat coeffs
[MAX_AMBI_COEFFS
], ALfloat ingain
, ALfloat gains
[MAX_OUTPUT_CHANNELS
]);
332 * ComputeFirstOrderGains
334 * Sets channel gains for a first-order ambisonics input channel. The matrix is
335 * a 1x4 'slice' of a transform matrix for the input channel, used to scale and
336 * orient the sound samples.
338 void ComputeFirstOrderGains(const ChannelConfig
*chancoeffs
, ALuint numchans
, const ALfloat mtx
[4], ALfloat ingain
, ALfloat gains
[MAX_OUTPUT_CHANNELS
]);
341 ALvoid
UpdateContextSources(ALCcontext
*context
);
343 ALvoid
CalcSourceParams(struct ALvoice
*voice
, const struct ALsource
*source
, const ALCcontext
*ALContext
);
344 ALvoid
CalcNonAttnSourceParams(struct ALvoice
*voice
, const struct ALsource
*source
, const ALCcontext
*ALContext
);
346 ALvoid
MixSource(struct ALvoice
*voice
, struct ALsource
*source
, ALCdevice
*Device
, ALuint SamplesToDo
);
348 ALvoid
aluMixData(ALCdevice
*device
, ALvoid
*buffer
, ALsizei size
);
349 /* Caller must lock the device. */
350 ALvoid
aluHandleDisconnect(ALCdevice
*device
);
352 extern ALfloat ConeScale
;
353 extern ALfloat ZScale
;