Store the output limiter values as fixed-point integers
[openal-soft.git] / OpenAL32 / Include / alMain.h
blob7d9ab4d91c3896d7c59905c0c312fa20ec02323e
1 #ifndef AL_MAIN_H
2 #define AL_MAIN_H
4 #include <string.h>
5 #include <stdio.h>
6 #include <stddef.h>
7 #include <stdarg.h>
8 #include <assert.h>
9 #include <math.h>
10 #include <limits.h>
12 #ifdef HAVE_STRINGS_H
13 #include <strings.h>
14 #endif
16 #ifdef HAVE_FENV_H
17 #include <fenv.h>
18 #endif
20 #include "AL/al.h"
21 #include "AL/alc.h"
22 #include "AL/alext.h"
24 #include "static_assert.h"
25 #include "align.h"
26 #include "atomic.h"
27 #include "uintmap.h"
28 #include "vector.h"
29 #include "alstring.h"
30 #include "almalloc.h"
31 #include "threads.h"
33 #ifndef ALC_SOFT_loopback2
34 #define ALC_SOFT_loopback2 1
35 #define ALC_AMBISONIC_LAYOUT_SOFT 0x1997
36 #define ALC_AMBISONIC_SCALING_SOFT 0x1998
37 #define ALC_AMBISONIC_ORDER_SOFT 0x1999
39 #define ALC_BFORMAT3D_SOFT 0x1508
41 /* Ambisonic layouts */
42 #define ALC_ACN_SOFT 0x1600
43 #define ALC_FUMA_SOFT 0x1601
45 /* Ambisonic scalings (normalization) */
46 /*#define ALC_FUMA_SOFT*/
47 #define ALC_SN3D_SOFT 0x1602
48 #define ALC_N3D_SOFT 0x1603
50 typedef ALCboolean (ALC_APIENTRY*LPALCISAMBISONICFORMATSUPPORTEDSOFT)(ALCdevice *device, ALCenum layout, ALCenum scaling, ALsizei order);
51 #ifdef AL_ALEXT_PROTOTYPES
52 ALC_API ALCboolean ALC_APIENTRY alcIsAmbisonicFormatSupportedSOFT(ALCdevice *device, ALCenum layout, ALCenum scaling, ALsizei order);
53 #endif
54 #endif
56 #ifndef ALC_SOFT_device_clock
57 #define ALC_SOFT_device_clock 1
58 typedef int64_t ALCint64SOFT;
59 typedef uint64_t ALCuint64SOFT;
60 #define ALC_DEVICE_CLOCK_SOFT 0x1600
61 #define ALC_DEVICE_LATENCY_SOFT 0x1601
62 #define ALC_DEVICE_CLOCK_LATENCY_SOFT 0x1602
63 typedef void (ALC_APIENTRY*LPALCGETINTEGER64VSOFT)(ALCdevice *device, ALCenum pname, ALsizei size, ALCint64SOFT *values);
64 #ifdef AL_ALEXT_PROTOTYPES
65 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALsizei size, ALCint64SOFT *values);
66 #endif
67 #endif
69 #ifndef AL_SOFT_buffer_samples2
70 #define AL_SOFT_buffer_samples2 1
71 /* Channel configurations */
72 #define AL_MONO_SOFT 0x1500
73 #define AL_STEREO_SOFT 0x1501
74 #define AL_REAR_SOFT 0x1502
75 #define AL_QUAD_SOFT 0x1503
76 #define AL_5POINT1_SOFT 0x1504
77 #define AL_6POINT1_SOFT 0x1505
78 #define AL_7POINT1_SOFT 0x1506
79 #define AL_BFORMAT2D_SOFT 0x1507
80 #define AL_BFORMAT3D_SOFT 0x1508
82 /* Sample types */
83 #define AL_BYTE_SOFT 0x1400
84 #define AL_UNSIGNED_BYTE_SOFT 0x1401
85 #define AL_SHORT_SOFT 0x1402
86 #define AL_UNSIGNED_SHORT_SOFT 0x1403
87 #define AL_INT_SOFT 0x1404
88 #define AL_UNSIGNED_INT_SOFT 0x1405
89 #define AL_FLOAT_SOFT 0x1406
90 #define AL_DOUBLE_SOFT 0x1407
91 #define AL_BYTE3_SOFT 0x1408
92 #define AL_UNSIGNED_BYTE3_SOFT 0x1409
93 #define AL_MULAW_SOFT 0x140A
95 /* Storage formats */
96 #define AL_MONO8_SOFT 0x1100
97 #define AL_MONO16_SOFT 0x1101
98 #define AL_MONO32F_SOFT 0x10010
99 #define AL_STEREO8_SOFT 0x1102
100 #define AL_STEREO16_SOFT 0x1103
101 #define AL_STEREO32F_SOFT 0x10011
102 #define AL_QUAD8_SOFT 0x1204
103 #define AL_QUAD16_SOFT 0x1205
104 #define AL_QUAD32F_SOFT 0x1206
105 #define AL_REAR8_SOFT 0x1207
106 #define AL_REAR16_SOFT 0x1208
107 #define AL_REAR32F_SOFT 0x1209
108 #define AL_5POINT1_8_SOFT 0x120A
109 #define AL_5POINT1_16_SOFT 0x120B
110 #define AL_5POINT1_32F_SOFT 0x120C
111 #define AL_6POINT1_8_SOFT 0x120D
112 #define AL_6POINT1_16_SOFT 0x120E
113 #define AL_6POINT1_32F_SOFT 0x120F
114 #define AL_7POINT1_8_SOFT 0x1210
115 #define AL_7POINT1_16_SOFT 0x1211
116 #define AL_7POINT1_32F_SOFT 0x1212
117 #define AL_BFORMAT2D_8_SOFT 0x20021
118 #define AL_BFORMAT2D_16_SOFT 0x20022
119 #define AL_BFORMAT2D_32F_SOFT 0x20023
120 #define AL_BFORMAT3D_8_SOFT 0x20031
121 #define AL_BFORMAT3D_16_SOFT 0x20032
122 #define AL_BFORMAT3D_32F_SOFT 0x20033
124 /* Buffer attributes */
125 #define AL_INTERNAL_FORMAT_SOFT 0x2008
126 #define AL_BYTE_LENGTH_SOFT 0x2009
127 #define AL_SAMPLE_LENGTH_SOFT 0x200A
128 #define AL_SEC_LENGTH_SOFT 0x200B
130 #if 0
131 typedef void (AL_APIENTRY*LPALBUFFERSAMPLESSOFT)(ALuint,ALuint,ALenum,ALsizei,ALenum,ALenum,const ALvoid*);
132 typedef void (AL_APIENTRY*LPALGETBUFFERSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,ALvoid*);
133 typedef ALboolean (AL_APIENTRY*LPALISBUFFERFORMATSUPPORTEDSOFT)(ALenum);
134 #ifdef AL_ALEXT_PROTOTYPES
135 AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer, ALuint samplerate, ALenum internalformat, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data);
136 AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, ALvoid *data);
137 AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum format);
138 #endif
139 #endif
140 #endif
142 #ifndef ALC_SOFT_output_limiter
143 #define ALC_SOFT_output_limiter
144 #define ALC_OUTPUT_LIMITER_SOFT 0x199A
145 #endif
147 #ifndef AL_SOFT_source_spatialize
148 #define AL_SOFT_source_spatialize
149 #define AL_SOURCE_SPATIALIZE_SOFT 0x1214
150 #define AL_AUTO_SOFT 0x0002
151 #endif
154 #if defined(_WIN64)
155 #define SZFMT "%I64u"
156 #elif defined(_WIN32)
157 #define SZFMT "%u"
158 #else
159 #define SZFMT "%zu"
160 #endif
163 #ifdef __GNUC__
164 /* Because of a long-standing deficiency in C, you're not allowed to implicitly
165 * cast a pointer-to-type-array to a pointer-to-const-type-array. For example,
167 * int (*ptr)[10];
168 * const int (*cptr)[10] = ptr;
170 * is not allowed and most compilers will generate noisy warnings about
171 * incompatible types, even though it just makes the array elements const.
172 * Clang will allow it if you make the array type a typedef, like this:
174 * typedef int int10[10];
175 * int10 *ptr;
176 * const int10 *cptr = ptr;
178 * however GCC does not and still issues the incompatible type warning. The
179 * "proper" way to fix it is to add an explicit cast for the constified type,
180 * but that removes the vast majority of otherwise useful type-checking you'd
181 * get, and runs the risk of improper casts if types are later changed. Leaving
182 * it non-const can also be an issue if you use it as a function parameter, and
183 * happen to have a const type as input (and also reduce the capabilities of
184 * the compiler to better optimize the function).
186 * So to work around the problem, we use a macro. The macro first assigns the
187 * incoming variable to the specified non-const type to ensure it's the correct
188 * type, then casts the variable as the desired constified type. Very ugly, but
189 * I'd rather not have hundreds of lines of warnings because I want to tell the
190 * compiler that some array(s) can't be changed by the code, or have lots of
191 * error-prone casts.
193 #define SAFE_CONST(T, var) __extension__({ \
194 T _tmp = (var); \
195 (const T)_tmp; \
197 #else
198 /* Non-GNU-compatible compilers have to use a straight cast with no extra
199 * checks, due to the lack of multi-statement expressions.
201 #define SAFE_CONST(T, var) ((const T)(var))
202 #endif
205 #ifdef __GNUC__
206 /* This helps cast away the const-ness of a pointer without accidentally
207 * changing the pointer type. This is necessary due to Clang's inability to use
208 * atomic_load on a const _Atomic variable.
210 #define CONST_CAST(T, V) __extension__({ \
211 const T _tmp = (V); \
212 (T)_tmp; \
214 #else
215 #define CONST_CAST(T, V) ((T)(V))
216 #endif
219 typedef ALint64SOFT ALint64;
220 typedef ALuint64SOFT ALuint64;
222 #ifndef U64
223 #if defined(_MSC_VER)
224 #define U64(x) ((ALuint64)(x##ui64))
225 #elif SIZEOF_LONG == 8
226 #define U64(x) ((ALuint64)(x##ul))
227 #elif SIZEOF_LONG_LONG == 8
228 #define U64(x) ((ALuint64)(x##ull))
229 #endif
230 #endif
232 #ifndef UINT64_MAX
233 #define UINT64_MAX U64(18446744073709551615)
234 #endif
236 #ifndef UNUSED
237 #if defined(__cplusplus)
238 #define UNUSED(x)
239 #elif defined(__GNUC__)
240 #define UNUSED(x) UNUSED_##x __attribute__((unused))
241 #elif defined(__LCLINT__)
242 #define UNUSED(x) /*@unused@*/ x
243 #else
244 #define UNUSED(x) x
245 #endif
246 #endif
248 #ifdef __GNUC__
249 #define DECL_FORMAT(x, y, z) __attribute__((format(x, (y), (z))))
250 #else
251 #define DECL_FORMAT(x, y, z)
252 #endif
254 /* Calculates the size of a struct with N elements of a flexible array member.
255 * GCC and Clang allow offsetof(Type, fam[N]) for this, but MSVC seems to have
256 * trouble, so a bit more verbose workaround is needed.
258 #define FAM_SIZE(T, M, N) (offsetof(T, M) + sizeof(((T*)NULL)->M[0])*(N))
260 #if defined(__GNUC__) && defined(__i386__)
261 /* force_align_arg_pointer is required for proper function arguments aligning
262 * when SSE code is used. Some systems (Windows, QNX) do not guarantee our
263 * thread functions will be properly aligned on the stack, even though GCC may
264 * generate code with the assumption that it is. */
265 #define FORCE_ALIGN __attribute__((force_align_arg_pointer))
266 #else
267 #define FORCE_ALIGN
268 #endif
270 #ifdef HAVE_C99_VLA
271 #define DECL_VLA(T, _name, _size) T _name[(_size)]
272 #else
273 #define DECL_VLA(T, _name, _size) T *_name = alloca((_size) * sizeof(T))
274 #endif
276 #ifndef PATH_MAX
277 #ifdef MAX_PATH
278 #define PATH_MAX MAX_PATH
279 #else
280 #define PATH_MAX 4096
281 #endif
282 #endif
285 static const union {
286 ALuint u;
287 ALubyte b[sizeof(ALuint)];
288 } EndianTest = { 1 };
289 #define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1)
291 #define COUNTOF(x) (sizeof(x) / sizeof(0[x]))
294 #define DERIVE_FROM_TYPE(t) t t##_parent
295 #define STATIC_CAST(to, obj) (&(obj)->to##_parent)
296 #ifdef __GNUC__
297 #define STATIC_UPCAST(to, from, obj) __extension__({ \
298 static_assert(__builtin_types_compatible_p(from, __typeof(*(obj))), \
299 "Invalid upcast object from type"); \
300 (to*)((char*)(obj) - offsetof(to, from##_parent)); \
302 #else
303 #define STATIC_UPCAST(to, from, obj) ((to*)((char*)(obj) - offsetof(to, from##_parent)))
304 #endif
306 #define DECLARE_FORWARD(T1, T2, rettype, func) \
307 rettype T1##_##func(T1 *obj) \
308 { return T2##_##func(STATIC_CAST(T2, obj)); }
310 #define DECLARE_FORWARD1(T1, T2, rettype, func, argtype1) \
311 rettype T1##_##func(T1 *obj, argtype1 a) \
312 { return T2##_##func(STATIC_CAST(T2, obj), a); }
314 #define DECLARE_FORWARD2(T1, T2, rettype, func, argtype1, argtype2) \
315 rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b) \
316 { return T2##_##func(STATIC_CAST(T2, obj), a, b); }
318 #define DECLARE_FORWARD3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
319 rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b, argtype3 c) \
320 { return T2##_##func(STATIC_CAST(T2, obj), a, b, c); }
323 #define GET_VTABLE1(T1) (&(T1##_vtable))
324 #define GET_VTABLE2(T1, T2) (&(T1##_##T2##_vtable))
326 #define SET_VTABLE1(T1, obj) ((obj)->vtbl = GET_VTABLE1(T1))
327 #define SET_VTABLE2(T1, T2, obj) (STATIC_CAST(T2, obj)->vtbl = GET_VTABLE2(T1, T2))
329 #define DECLARE_THUNK(T1, T2, rettype, func) \
330 static rettype T1##_##T2##_##func(T2 *obj) \
331 { return T1##_##func(STATIC_UPCAST(T1, T2, obj)); }
333 #define DECLARE_THUNK1(T1, T2, rettype, func, argtype1) \
334 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a) \
335 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a); }
337 #define DECLARE_THUNK2(T1, T2, rettype, func, argtype1, argtype2) \
338 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b) \
339 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b); }
341 #define DECLARE_THUNK3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
342 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c) \
343 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c); }
345 #define DECLARE_THUNK4(T1, T2, rettype, func, argtype1, argtype2, argtype3, argtype4) \
346 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c, argtype4 d) \
347 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c, d); }
349 #define DECLARE_DEFAULT_ALLOCATORS(T) \
350 static void* T##_New(size_t size) { return al_malloc(16, size); } \
351 static void T##_Delete(void *ptr) { al_free(ptr); }
353 /* Helper to extract an argument list for VCALL. Not used directly. */
354 #define EXTRACT_VCALL_ARGS(...) __VA_ARGS__))
356 /* Call a "virtual" method on an object, with arguments. */
357 #define V(obj, func) ((obj)->vtbl->func((obj), EXTRACT_VCALL_ARGS
358 /* Call a "virtual" method on an object, with no arguments. */
359 #define V0(obj, func) ((obj)->vtbl->func((obj) EXTRACT_VCALL_ARGS
361 #define DELETE_OBJ(obj) do { \
362 if((obj) != NULL) \
364 V0((obj),Destruct)(); \
365 V0((obj),Delete)(); \
367 } while(0)
370 #define EXTRACT_NEW_ARGS(...) __VA_ARGS__); \
372 } while(0)
374 #define NEW_OBJ(_res, T) do { \
375 _res = T##_New(sizeof(T)); \
376 if(_res) \
378 memset(_res, 0, sizeof(T)); \
379 T##_Construct(_res, EXTRACT_NEW_ARGS
380 #define NEW_OBJ0(_res, T) do { \
381 _res = T##_New(sizeof(T)); \
382 if(_res) \
384 memset(_res, 0, sizeof(T)); \
385 T##_Construct(_res EXTRACT_NEW_ARGS
388 #ifdef __cplusplus
389 extern "C" {
390 #endif
392 struct Hrtf;
393 struct HrtfEntry;
394 struct OutputLimiter;
397 #define DEFAULT_OUTPUT_RATE (44100)
398 #define MIN_OUTPUT_RATE (8000)
401 /* Find the next power-of-2 for non-power-of-2 numbers. */
402 inline ALuint NextPowerOf2(ALuint value)
404 if(value > 0)
406 value--;
407 value |= value>>1;
408 value |= value>>2;
409 value |= value>>4;
410 value |= value>>8;
411 value |= value>>16;
413 return value+1;
416 /** Round up a value to the next multiple. */
417 inline size_t RoundUp(size_t value, size_t r)
419 value += r-1;
420 return value - (value%r);
423 /* Fast float-to-int conversion. Assumes the FPU is already in round-to-zero
424 * mode. */
425 inline ALint fastf2i(ALfloat f)
427 #ifdef HAVE_LRINTF
428 return lrintf(f);
429 #elif defined(_MSC_VER) && defined(_M_IX86)
430 ALint i;
431 __asm fld f
432 __asm fistp i
433 return i;
434 #else
435 return (ALint)f;
436 #endif
439 /* Fast float-to-uint conversion. Assumes the FPU is already in round-to-zero
440 * mode. */
441 inline ALuint fastf2u(ALfloat f)
442 { return fastf2i(f); }
445 enum DevProbe {
446 ALL_DEVICE_PROBE,
447 CAPTURE_DEVICE_PROBE
450 typedef struct {
451 ALCenum (*OpenPlayback)(ALCdevice*, const ALCchar*);
452 void (*ClosePlayback)(ALCdevice*);
453 ALCboolean (*ResetPlayback)(ALCdevice*);
454 ALCboolean (*StartPlayback)(ALCdevice*);
455 void (*StopPlayback)(ALCdevice*);
457 ALCenum (*OpenCapture)(ALCdevice*, const ALCchar*);
458 void (*CloseCapture)(ALCdevice*);
459 void (*StartCapture)(ALCdevice*);
460 void (*StopCapture)(ALCdevice*);
461 ALCenum (*CaptureSamples)(ALCdevice*, void*, ALCuint);
462 ALCuint (*AvailableSamples)(ALCdevice*);
463 } BackendFuncs;
465 ALCboolean alc_qsa_init(BackendFuncs *func_list);
466 void alc_qsa_deinit(void);
467 void alc_qsa_probe(enum DevProbe type);
469 struct ALCbackend;
472 enum DistanceModel {
473 InverseDistanceClamped = AL_INVERSE_DISTANCE_CLAMPED,
474 LinearDistanceClamped = AL_LINEAR_DISTANCE_CLAMPED,
475 ExponentDistanceClamped = AL_EXPONENT_DISTANCE_CLAMPED,
476 InverseDistance = AL_INVERSE_DISTANCE,
477 LinearDistance = AL_LINEAR_DISTANCE,
478 ExponentDistance = AL_EXPONENT_DISTANCE,
479 DisableDistance = AL_NONE,
481 DefaultDistanceModel = InverseDistanceClamped
484 enum Channel {
485 FrontLeft = 0,
486 FrontRight,
487 FrontCenter,
488 LFE,
489 BackLeft,
490 BackRight,
491 BackCenter,
492 SideLeft,
493 SideRight,
495 UpperFrontLeft,
496 UpperFrontRight,
497 UpperBackLeft,
498 UpperBackRight,
499 LowerFrontLeft,
500 LowerFrontRight,
501 LowerBackLeft,
502 LowerBackRight,
504 Aux0,
505 Aux1,
506 Aux2,
507 Aux3,
508 Aux4,
509 Aux5,
510 Aux6,
511 Aux7,
512 Aux8,
513 Aux9,
514 Aux10,
515 Aux11,
516 Aux12,
517 Aux13,
518 Aux14,
519 Aux15,
521 InvalidChannel
525 /* Device formats */
526 enum DevFmtType {
527 DevFmtByte = ALC_BYTE_SOFT,
528 DevFmtUByte = ALC_UNSIGNED_BYTE_SOFT,
529 DevFmtShort = ALC_SHORT_SOFT,
530 DevFmtUShort = ALC_UNSIGNED_SHORT_SOFT,
531 DevFmtInt = ALC_INT_SOFT,
532 DevFmtUInt = ALC_UNSIGNED_INT_SOFT,
533 DevFmtFloat = ALC_FLOAT_SOFT,
535 DevFmtTypeDefault = DevFmtFloat
537 enum DevFmtChannels {
538 DevFmtMono = ALC_MONO_SOFT,
539 DevFmtStereo = ALC_STEREO_SOFT,
540 DevFmtQuad = ALC_QUAD_SOFT,
541 DevFmtX51 = ALC_5POINT1_SOFT,
542 DevFmtX61 = ALC_6POINT1_SOFT,
543 DevFmtX71 = ALC_7POINT1_SOFT,
544 DevFmtAmbi3D = ALC_BFORMAT3D_SOFT,
546 /* Similar to 5.1, except using rear channels instead of sides */
547 DevFmtX51Rear = 0x80000000,
549 DevFmtChannelsDefault = DevFmtStereo
551 #define MAX_OUTPUT_CHANNELS (16)
553 ALsizei BytesFromDevFmt(enum DevFmtType type);
554 ALsizei ChannelsFromDevFmt(enum DevFmtChannels chans, ALsizei ambiorder);
555 inline ALsizei FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type, ALsizei ambiorder)
557 return ChannelsFromDevFmt(chans, ambiorder) * BytesFromDevFmt(type);
560 enum AmbiLayout {
561 AmbiLayout_FuMa = ALC_FUMA_SOFT, /* FuMa channel order */
562 AmbiLayout_ACN = ALC_ACN_SOFT, /* ACN channel order */
564 AmbiLayout_Default = AmbiLayout_ACN
567 enum AmbiNorm {
568 AmbiNorm_FuMa = ALC_FUMA_SOFT, /* FuMa normalization */
569 AmbiNorm_SN3D = ALC_SN3D_SOFT, /* SN3D normalization */
570 AmbiNorm_N3D = ALC_N3D_SOFT, /* N3D normalization */
572 AmbiNorm_Default = AmbiNorm_SN3D
576 extern const struct EffectList {
577 const char *name;
578 int type;
579 const char *ename;
580 ALenum val;
581 } EffectList[];
584 enum DeviceType {
585 Playback,
586 Capture,
587 Loopback
591 enum RenderMode {
592 NormalRender,
593 StereoPair,
594 HrtfRender
598 /* The maximum number of Ambisonics coefficients. For a given order (o), the
599 * size needed will be (o+1)**2, thus zero-order has 1, first-order has 4,
600 * second-order has 9, third-order has 16, and fourth-order has 25.
602 #define MAX_AMBI_ORDER 3
603 #define MAX_AMBI_COEFFS ((MAX_AMBI_ORDER+1) * (MAX_AMBI_ORDER+1))
605 /* A bitmask of ambisonic channels with height information. If none of these
606 * channels are used/needed, there's no height (e.g. with most surround sound
607 * speaker setups). This only specifies up to 4th order, which is the highest
608 * order a 32-bit mask value can specify (a 64-bit mask could handle up to 7th
609 * order). This is ACN ordering, with bit 0 being ACN 0, etc.
611 #define AMBI_PERIPHONIC_MASK (0xfe7ce4)
613 /* The maximum number of Ambisonic coefficients for 2D (non-periphonic)
614 * representation. This is 2 per each order above zero-order, plus 1 for zero-
615 * order. Or simply, o*2 + 1.
617 #define MAX_AMBI2D_COEFFS (MAX_AMBI_ORDER*2 + 1)
620 typedef ALfloat ChannelConfig[MAX_AMBI_COEFFS];
621 typedef struct BFChannelConfig {
622 ALfloat Scale;
623 ALsizei Index;
624 } BFChannelConfig;
626 typedef union AmbiConfig {
627 /* Ambisonic coefficients for mixing to the dry buffer. */
628 ChannelConfig Coeffs[MAX_OUTPUT_CHANNELS];
629 /* Coefficient channel mapping for mixing to the dry buffer. */
630 BFChannelConfig Map[MAX_OUTPUT_CHANNELS];
631 } AmbiConfig;
634 #define HRTF_HISTORY_BITS (6)
635 #define HRTF_HISTORY_LENGTH (1<<HRTF_HISTORY_BITS)
636 #define HRTF_HISTORY_MASK (HRTF_HISTORY_LENGTH-1)
638 #define HRIR_BITS (7)
639 #define HRIR_LENGTH (1<<HRIR_BITS)
640 #define HRIR_MASK (HRIR_LENGTH-1)
642 typedef struct HrtfState {
643 alignas(16) ALfloat History[HRTF_HISTORY_LENGTH];
644 alignas(16) ALfloat Values[HRIR_LENGTH][2];
645 } HrtfState;
647 typedef struct HrtfParams {
648 alignas(16) ALfloat Coeffs[HRIR_LENGTH][2];
649 ALsizei Delay[2];
650 ALfloat Gain;
651 } HrtfParams;
653 typedef struct DirectHrtfState {
654 /* HRTF filter state for dry buffer content */
655 ALsizei Offset;
656 ALsizei IrSize;
657 struct {
658 alignas(16) ALfloat Values[HRIR_LENGTH][2];
659 alignas(16) ALfloat Coeffs[HRIR_LENGTH][2];
660 } Chan[];
661 } DirectHrtfState;
663 typedef struct EnumeratedHrtf {
664 al_string name;
666 struct HrtfEntry *hrtf;
667 } EnumeratedHrtf;
668 TYPEDEF_VECTOR(EnumeratedHrtf, vector_EnumeratedHrtf)
671 /* Maximum delay in samples for speaker distance compensation. */
672 #define MAX_DELAY_LENGTH 1024
674 typedef struct DistanceComp {
675 ALfloat Gain;
676 ALsizei Length; /* Valid range is [0...MAX_DELAY_LENGTH). */
677 ALfloat *Buffer;
678 } DistanceComp;
680 /* Size for temporary storage of buffer data, in ALfloats. Larger values need
681 * more memory, while smaller values may need more iterations. The value needs
682 * to be a sensible size, however, as it constrains the max stepping value used
683 * for mixing, as well as the maximum number of samples per mixing iteration.
685 #define BUFFERSIZE 2048
687 struct ALCdevice_struct
689 RefCount ref;
691 ALCboolean Connected;
692 enum DeviceType Type;
694 ALuint Frequency;
695 ALuint UpdateSize;
696 ALuint NumUpdates;
697 enum DevFmtChannels FmtChans;
698 enum DevFmtType FmtType;
699 ALboolean IsHeadphones;
700 ALsizei AmbiOrder;
701 /* For DevFmtAmbi* output only, specifies the channel order and
702 * normalization.
704 enum AmbiLayout AmbiLayout;
705 enum AmbiNorm AmbiScale;
707 al_string DeviceName;
709 ATOMIC(ALCenum) LastError;
711 // Maximum number of sources that can be created
712 ALuint SourcesMax;
713 // Maximum number of slots that can be created
714 ALuint AuxiliaryEffectSlotMax;
716 ALCuint NumMonoSources;
717 ALCuint NumStereoSources;
718 ALsizei NumAuxSends;
720 // Map of Buffers for this device
721 UIntMap BufferMap;
723 // Map of Effects for this device
724 UIntMap EffectMap;
726 // Map of Filters for this device
727 UIntMap FilterMap;
729 /* HRTF state and info */
730 DirectHrtfState *Hrtf;
731 al_string HrtfName;
732 struct Hrtf *HrtfHandle;
733 vector_EnumeratedHrtf HrtfList;
734 ALCenum HrtfStatus;
736 /* UHJ encoder state */
737 struct Uhj2Encoder *Uhj_Encoder;
739 /* High quality Ambisonic decoder */
740 struct BFormatDec *AmbiDecoder;
742 /* Stereo-to-binaural filter */
743 struct bs2b *Bs2b;
745 /* First-order ambisonic upsampler for higher-order output */
746 struct AmbiUpsampler *AmbiUp;
748 /* Rendering mode. */
749 enum RenderMode Render_Mode;
751 // Device flags
752 ALuint Flags;
754 ALuint64 ClockBase;
755 ALuint SamplesDone;
757 /* Temp storage used for each source when mixing. */
758 alignas(16) ALfloat SourceData[BUFFERSIZE];
759 alignas(16) ALfloat ResampledData[BUFFERSIZE];
760 alignas(16) ALfloat FilteredData[BUFFERSIZE];
761 alignas(16) ALfloat NFCtrlData[BUFFERSIZE];
763 /* The "dry" path corresponds to the main output. */
764 struct {
765 AmbiConfig Ambi;
766 /* Number of coefficients in each Ambi.Coeffs to mix together (4 for
767 * first-order, 9 for second-order, etc). If the count is 0, Ambi.Map
768 * is used instead to map each output to a coefficient index.
770 ALsizei CoeffCount;
772 ALfloat (*Buffer)[BUFFERSIZE];
773 ALsizei NumChannels;
774 ALsizei NumChannelsPerOrder[MAX_AMBI_ORDER+1];
775 } Dry;
777 /* First-order ambisonics output, to be upsampled to the dry buffer if different. */
778 struct {
779 AmbiConfig Ambi;
780 /* Will only be 4 or 0. */
781 ALsizei CoeffCount;
783 ALfloat (*Buffer)[BUFFERSIZE];
784 ALsizei NumChannels;
785 } FOAOut;
787 /* "Real" output, which will be written to the device buffer. May alias the
788 * dry buffer.
790 struct {
791 enum Channel ChannelName[MAX_OUTPUT_CHANNELS];
793 ALfloat (*Buffer)[BUFFERSIZE];
794 ALsizei NumChannels;
795 } RealOut;
797 struct OutputLimiter *Limiter;
799 /* The average speaker distance as determined by the ambdec configuration
800 * (or alternatively, by the NFC-HOA reference delay). Only used for NFC.
802 ALfloat AvgSpeakerDist;
804 /* Delay buffers used to compensate for speaker distances. */
805 DistanceComp ChannelDelay[MAX_OUTPUT_CHANNELS];
807 /* Running count of the mixer invocations, in 31.1 fixed point. This
808 * actually increments *twice* when mixing, first at the start and then at
809 * the end, so the bottom bit indicates if the device is currently mixing
810 * and the upper bits indicates how many mixes have been done.
812 RefCount MixCount;
814 /* Default effect slot */
815 struct ALeffectslot *DefaultSlot;
817 // Contexts created on this device
818 ATOMIC(ALCcontext*) ContextList;
820 almtx_t BackendLock;
821 struct ALCbackend *Backend;
823 void *ExtraData; // For the backend's use
825 ALCdevice *volatile next;
827 /* Memory space used by the default slot (Playback devices only) */
828 alignas(16) ALCbyte _slot_mem[];
831 // Frequency was requested by the app or config file
832 #define DEVICE_FREQUENCY_REQUEST (1u<<1)
833 // Channel configuration was requested by the config file
834 #define DEVICE_CHANNELS_REQUEST (1u<<2)
835 // Sample type was requested by the config file
836 #define DEVICE_SAMPLE_TYPE_REQUEST (1u<<3)
838 // Specifies if the DSP is paused at user request
839 #define DEVICE_PAUSED (1u<<30)
841 // Specifies if the device is currently running
842 #define DEVICE_RUNNING (1u<<31)
845 /* Nanosecond resolution for the device clock time. */
846 #define DEVICE_CLOCK_RES U64(1000000000)
849 /* Must be less than 15 characters (16 including terminating null) for
850 * compatibility with pthread_setname_np limitations. */
851 #define MIXER_THREAD_NAME "alsoft-mixer"
853 #define RECORD_THREAD_NAME "alsoft-record"
856 struct ALCcontext_struct {
857 RefCount ref;
859 struct ALlistener *Listener;
861 UIntMap SourceMap;
862 UIntMap EffectSlotMap;
864 ATOMIC(ALenum) LastError;
866 enum DistanceModel DistanceModel;
867 ALboolean SourceDistanceModel;
869 ALfloat DopplerFactor;
870 ALfloat DopplerVelocity;
871 ALfloat SpeedOfSound;
872 ATOMIC(ALenum) DeferUpdates;
874 RWLock PropLock;
876 /* Counter for the pre-mixing updates, in 31.1 fixed point (lowest bit
877 * indicates if updates are currently happening).
879 RefCount UpdateCount;
880 ATOMIC(ALenum) HoldUpdates;
882 ALfloat GainBoost;
884 struct ALvoice **Voices;
885 ALsizei VoiceCount;
886 ALsizei MaxVoices;
888 ATOMIC(struct ALeffectslotArray*) ActiveAuxSlots;
890 ALCdevice *Device;
891 const ALCchar *ExtensionList;
893 ALCcontext *volatile next;
895 /* Memory space used by the listener */
896 alignas(16) ALCbyte _listener_mem[];
899 ALCcontext *GetContextRef(void);
901 void ALCcontext_IncRef(ALCcontext *context);
902 void ALCcontext_DecRef(ALCcontext *context);
904 void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends);
906 void AppendAllDevicesList(const ALCchar *name);
907 void AppendCaptureDeviceList(const ALCchar *name);
909 void ALCdevice_Lock(ALCdevice *device);
910 void ALCdevice_Unlock(ALCdevice *device);
912 void ALCcontext_DeferUpdates(ALCcontext *context);
913 void ALCcontext_ProcessUpdates(ALCcontext *context);
916 typedef struct {
917 #ifdef HAVE_FENV_H
918 DERIVE_FROM_TYPE(fenv_t);
919 #else
920 int state;
921 #endif
922 #ifdef HAVE_SSE
923 int sse_state;
924 #endif
925 } FPUCtl;
926 void SetMixerFPUMode(FPUCtl *ctl);
927 void RestoreFPUMode(const FPUCtl *ctl);
930 typedef struct ll_ringbuffer ll_ringbuffer_t;
931 typedef struct ll_ringbuffer_data {
932 char *buf;
933 size_t len;
934 } ll_ringbuffer_data_t;
935 ll_ringbuffer_t *ll_ringbuffer_create(size_t sz, size_t elem_sz);
936 void ll_ringbuffer_free(ll_ringbuffer_t *rb);
937 void ll_ringbuffer_get_read_vector(const ll_ringbuffer_t *rb, ll_ringbuffer_data_t *vec);
938 void ll_ringbuffer_get_write_vector(const ll_ringbuffer_t *rb, ll_ringbuffer_data_t *vec);
939 size_t ll_ringbuffer_read(ll_ringbuffer_t *rb, char *dest, size_t cnt);
940 size_t ll_ringbuffer_peek(ll_ringbuffer_t *rb, char *dest, size_t cnt);
941 void ll_ringbuffer_read_advance(ll_ringbuffer_t *rb, size_t cnt);
942 size_t ll_ringbuffer_read_space(const ll_ringbuffer_t *rb);
943 int ll_ringbuffer_mlock(ll_ringbuffer_t *rb);
944 void ll_ringbuffer_reset(ll_ringbuffer_t *rb);
945 size_t ll_ringbuffer_write(ll_ringbuffer_t *rb, const char *src, size_t cnt);
946 void ll_ringbuffer_write_advance(ll_ringbuffer_t *rb, size_t cnt);
947 size_t ll_ringbuffer_write_space(const ll_ringbuffer_t *rb);
949 void ReadALConfig(void);
950 void FreeALConfig(void);
951 int ConfigValueExists(const char *devName, const char *blockName, const char *keyName);
952 const char *GetConfigValue(const char *devName, const char *blockName, const char *keyName, const char *def);
953 int GetConfigValueBool(const char *devName, const char *blockName, const char *keyName, int def);
954 int ConfigValueStr(const char *devName, const char *blockName, const char *keyName, const char **ret);
955 int ConfigValueInt(const char *devName, const char *blockName, const char *keyName, int *ret);
956 int ConfigValueUInt(const char *devName, const char *blockName, const char *keyName, unsigned int *ret);
957 int ConfigValueFloat(const char *devName, const char *blockName, const char *keyName, float *ret);
958 int ConfigValueBool(const char *devName, const char *blockName, const char *keyName, int *ret);
960 void SetRTPriority(void);
962 void SetDefaultChannelOrder(ALCdevice *device);
963 void SetDefaultWFXChannelOrder(ALCdevice *device);
965 const ALCchar *DevFmtTypeString(enum DevFmtType type);
966 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans);
969 * GetChannelIdxByName
971 * Returns the index for the given channel name (e.g. FrontCenter), or -1 if it
972 * doesn't exist.
974 inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS], enum Channel chan)
976 ALint i;
977 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
979 if(names[i] == chan)
980 return i;
982 return -1;
984 #define GetChannelIdxByName(x, c) GetChannelIndex((x).ChannelName, (c))
986 extern FILE *LogFile;
988 #if defined(__GNUC__) && !defined(_WIN32) && !defined(IN_IDE_PARSER)
989 #define AL_PRINT(T, MSG, ...) fprintf(LogFile, "AL lib: %s %s: "MSG, T, __FUNCTION__ , ## __VA_ARGS__)
990 #else
991 void al_print(const char *type, const char *func, const char *fmt, ...) DECL_FORMAT(printf, 3,4);
992 #define AL_PRINT(T, ...) al_print((T), __FUNCTION__, __VA_ARGS__)
993 #endif
995 #ifdef __ANDROID__
996 #include <android/log.h>
997 #define LOG_ANDROID(T, MSG, ...) __android_log_print(T, "openal", "AL lib: %s: "MSG, __FUNCTION__ , ## __VA_ARGS__)
998 #else
999 #define LOG_ANDROID(T, MSG, ...) ((void)0)
1000 #endif
1002 enum LogLevel {
1003 NoLog,
1004 LogError,
1005 LogWarning,
1006 LogTrace,
1007 LogRef
1009 extern enum LogLevel LogLevel;
1011 #define TRACEREF(...) do { \
1012 if(LogLevel >= LogRef) \
1013 AL_PRINT("(--)", __VA_ARGS__); \
1014 } while(0)
1016 #define TRACE(...) do { \
1017 if(LogLevel >= LogTrace) \
1018 AL_PRINT("(II)", __VA_ARGS__); \
1019 LOG_ANDROID(ANDROID_LOG_DEBUG, __VA_ARGS__); \
1020 } while(0)
1022 #define WARN(...) do { \
1023 if(LogLevel >= LogWarning) \
1024 AL_PRINT("(WW)", __VA_ARGS__); \
1025 LOG_ANDROID(ANDROID_LOG_WARN, __VA_ARGS__); \
1026 } while(0)
1028 #define ERR(...) do { \
1029 if(LogLevel >= LogError) \
1030 AL_PRINT("(EE)", __VA_ARGS__); \
1031 LOG_ANDROID(ANDROID_LOG_ERROR, __VA_ARGS__); \
1032 } while(0)
1035 extern ALint RTPrioLevel;
1038 extern ALuint CPUCapFlags;
1039 enum {
1040 CPU_CAP_SSE = 1<<0,
1041 CPU_CAP_SSE2 = 1<<1,
1042 CPU_CAP_SSE3 = 1<<2,
1043 CPU_CAP_SSE4_1 = 1<<3,
1044 CPU_CAP_NEON = 1<<4,
1047 void FillCPUCaps(ALuint capfilter);
1049 vector_al_string SearchDataFiles(const char *match, const char *subdir);
1051 /* Small hack to use a pointer-to-array types as a normal argument type.
1052 * Shouldn't be used directly.
1054 typedef ALfloat ALfloatBUFFERSIZE[BUFFERSIZE];
1055 typedef ALfloat ALfloat2[2];
1057 #ifdef __cplusplus
1059 #endif
1061 #endif