Start an extension to change the source's spatialize property
[openal-soft.git] / OpenAL32 / Include / alMain.h
blob1b1b19092efc6f76b4f3ea021dbb947788058edd
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 0x1213
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;
396 #define DEFAULT_OUTPUT_RATE (44100)
397 #define MIN_OUTPUT_RATE (8000)
400 /* Find the next power-of-2 for non-power-of-2 numbers. */
401 inline ALuint NextPowerOf2(ALuint value)
403 if(value > 0)
405 value--;
406 value |= value>>1;
407 value |= value>>2;
408 value |= value>>4;
409 value |= value>>8;
410 value |= value>>16;
412 return value+1;
415 /** Round up a value to the next multiple. */
416 inline size_t RoundUp(size_t value, size_t r)
418 value += r-1;
419 return value - (value%r);
422 /* Fast float-to-int conversion. Assumes the FPU is already in round-to-zero
423 * mode. */
424 inline ALint fastf2i(ALfloat f)
426 #ifdef HAVE_LRINTF
427 return lrintf(f);
428 #elif defined(_MSC_VER) && defined(_M_IX86)
429 ALint i;
430 __asm fld f
431 __asm fistp i
432 return i;
433 #else
434 return (ALint)f;
435 #endif
438 /* Fast float-to-uint conversion. Assumes the FPU is already in round-to-zero
439 * mode. */
440 inline ALuint fastf2u(ALfloat f)
441 { return fastf2i(f); }
444 enum DevProbe {
445 ALL_DEVICE_PROBE,
446 CAPTURE_DEVICE_PROBE
449 typedef struct {
450 ALCenum (*OpenPlayback)(ALCdevice*, const ALCchar*);
451 void (*ClosePlayback)(ALCdevice*);
452 ALCboolean (*ResetPlayback)(ALCdevice*);
453 ALCboolean (*StartPlayback)(ALCdevice*);
454 void (*StopPlayback)(ALCdevice*);
456 ALCenum (*OpenCapture)(ALCdevice*, const ALCchar*);
457 void (*CloseCapture)(ALCdevice*);
458 void (*StartCapture)(ALCdevice*);
459 void (*StopCapture)(ALCdevice*);
460 ALCenum (*CaptureSamples)(ALCdevice*, void*, ALCuint);
461 ALCuint (*AvailableSamples)(ALCdevice*);
462 } BackendFuncs;
464 ALCboolean alc_qsa_init(BackendFuncs *func_list);
465 void alc_qsa_deinit(void);
466 void alc_qsa_probe(enum DevProbe type);
468 struct ALCbackend;
471 enum DistanceModel {
472 InverseDistanceClamped = AL_INVERSE_DISTANCE_CLAMPED,
473 LinearDistanceClamped = AL_LINEAR_DISTANCE_CLAMPED,
474 ExponentDistanceClamped = AL_EXPONENT_DISTANCE_CLAMPED,
475 InverseDistance = AL_INVERSE_DISTANCE,
476 LinearDistance = AL_LINEAR_DISTANCE,
477 ExponentDistance = AL_EXPONENT_DISTANCE,
478 DisableDistance = AL_NONE,
480 DefaultDistanceModel = InverseDistanceClamped
483 enum Channel {
484 FrontLeft = 0,
485 FrontRight,
486 FrontCenter,
487 LFE,
488 BackLeft,
489 BackRight,
490 BackCenter,
491 SideLeft,
492 SideRight,
494 UpperFrontLeft,
495 UpperFrontRight,
496 UpperBackLeft,
497 UpperBackRight,
498 LowerFrontLeft,
499 LowerFrontRight,
500 LowerBackLeft,
501 LowerBackRight,
503 Aux0,
504 Aux1,
505 Aux2,
506 Aux3,
507 Aux4,
508 Aux5,
509 Aux6,
510 Aux7,
511 Aux8,
512 Aux9,
513 Aux10,
514 Aux11,
515 Aux12,
516 Aux13,
517 Aux14,
518 Aux15,
520 InvalidChannel
524 /* Device formats */
525 enum DevFmtType {
526 DevFmtByte = ALC_BYTE_SOFT,
527 DevFmtUByte = ALC_UNSIGNED_BYTE_SOFT,
528 DevFmtShort = ALC_SHORT_SOFT,
529 DevFmtUShort = ALC_UNSIGNED_SHORT_SOFT,
530 DevFmtInt = ALC_INT_SOFT,
531 DevFmtUInt = ALC_UNSIGNED_INT_SOFT,
532 DevFmtFloat = ALC_FLOAT_SOFT,
534 DevFmtTypeDefault = DevFmtFloat
536 enum DevFmtChannels {
537 DevFmtMono = ALC_MONO_SOFT,
538 DevFmtStereo = ALC_STEREO_SOFT,
539 DevFmtQuad = ALC_QUAD_SOFT,
540 DevFmtX51 = ALC_5POINT1_SOFT,
541 DevFmtX61 = ALC_6POINT1_SOFT,
542 DevFmtX71 = ALC_7POINT1_SOFT,
543 DevFmtAmbi3D = ALC_BFORMAT3D_SOFT,
545 /* Similar to 5.1, except using rear channels instead of sides */
546 DevFmtX51Rear = 0x80000000,
548 DevFmtChannelsDefault = DevFmtStereo
550 #define MAX_OUTPUT_CHANNELS (16)
552 ALsizei BytesFromDevFmt(enum DevFmtType type);
553 ALsizei ChannelsFromDevFmt(enum DevFmtChannels chans, ALsizei ambiorder);
554 inline ALsizei FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type, ALsizei ambiorder)
556 return ChannelsFromDevFmt(chans, ambiorder) * BytesFromDevFmt(type);
559 enum AmbiLayout {
560 AmbiLayout_FuMa = ALC_FUMA_SOFT, /* FuMa channel order */
561 AmbiLayout_ACN = ALC_ACN_SOFT, /* ACN channel order */
563 AmbiLayout_Default = AmbiLayout_ACN
566 enum AmbiNorm {
567 AmbiNorm_FuMa = ALC_FUMA_SOFT, /* FuMa normalization */
568 AmbiNorm_SN3D = ALC_SN3D_SOFT, /* SN3D normalization */
569 AmbiNorm_N3D = ALC_N3D_SOFT, /* N3D normalization */
571 AmbiNorm_Default = AmbiNorm_SN3D
575 extern const struct EffectList {
576 const char *name;
577 int type;
578 const char *ename;
579 ALenum val;
580 } EffectList[];
583 enum DeviceType {
584 Playback,
585 Capture,
586 Loopback
590 enum RenderMode {
591 NormalRender,
592 StereoPair,
593 HrtfRender
597 /* The maximum number of Ambisonics coefficients. For a given order (o), the
598 * size needed will be (o+1)**2, thus zero-order has 1, first-order has 4,
599 * second-order has 9, third-order has 16, and fourth-order has 25.
601 #define MAX_AMBI_ORDER 3
602 #define MAX_AMBI_COEFFS ((MAX_AMBI_ORDER+1) * (MAX_AMBI_ORDER+1))
604 /* A bitmask of ambisonic channels with height information. If none of these
605 * channels are used/needed, there's no height (e.g. with most surround sound
606 * speaker setups). This only specifies up to 4th order, which is the highest
607 * order a 32-bit mask value can specify (a 64-bit mask could handle up to 7th
608 * order). This is ACN ordering, with bit 0 being ACN 0, etc.
610 #define AMBI_PERIPHONIC_MASK (0xfe7ce4)
612 /* The maximum number of Ambisonic coefficients for 2D (non-periphonic)
613 * representation. This is 2 per each order above zero-order, plus 1 for zero-
614 * order. Or simply, o*2 + 1.
616 #define MAX_AMBI2D_COEFFS (MAX_AMBI_ORDER*2 + 1)
619 typedef ALfloat ChannelConfig[MAX_AMBI_COEFFS];
620 typedef struct BFChannelConfig {
621 ALfloat Scale;
622 ALsizei Index;
623 } BFChannelConfig;
625 typedef union AmbiConfig {
626 /* Ambisonic coefficients for mixing to the dry buffer. */
627 ChannelConfig Coeffs[MAX_OUTPUT_CHANNELS];
628 /* Coefficient channel mapping for mixing to the dry buffer. */
629 BFChannelConfig Map[MAX_OUTPUT_CHANNELS];
630 } AmbiConfig;
633 #define HRTF_HISTORY_BITS (6)
634 #define HRTF_HISTORY_LENGTH (1<<HRTF_HISTORY_BITS)
635 #define HRTF_HISTORY_MASK (HRTF_HISTORY_LENGTH-1)
637 #define HRIR_BITS (7)
638 #define HRIR_LENGTH (1<<HRIR_BITS)
639 #define HRIR_MASK (HRIR_LENGTH-1)
641 typedef struct HrtfState {
642 alignas(16) ALfloat History[HRTF_HISTORY_LENGTH];
643 alignas(16) ALfloat Values[HRIR_LENGTH][2];
644 } HrtfState;
646 typedef struct HrtfParams {
647 alignas(16) ALfloat Coeffs[HRIR_LENGTH][2];
648 ALsizei Delay[2];
649 ALfloat Gain;
650 } HrtfParams;
652 typedef struct DirectHrtfState {
653 /* HRTF filter state for dry buffer content */
654 ALsizei Offset;
655 ALsizei IrSize;
656 struct {
657 alignas(16) ALfloat Values[HRIR_LENGTH][2];
658 alignas(16) ALfloat Coeffs[HRIR_LENGTH][2];
659 } Chan[];
660 } DirectHrtfState;
662 typedef struct EnumeratedHrtf {
663 al_string name;
665 struct HrtfEntry *hrtf;
666 } EnumeratedHrtf;
667 TYPEDEF_VECTOR(EnumeratedHrtf, vector_EnumeratedHrtf)
670 /* Maximum delay in samples for speaker distance compensation. */
671 #define MAX_DELAY_LENGTH 1024
673 typedef struct DistanceComp {
674 ALfloat Gain;
675 ALsizei Length; /* Valid range is [0...MAX_DELAY_LENGTH). */
676 ALfloat *Buffer;
677 } DistanceComp;
679 /* Size for temporary storage of buffer data, in ALfloats. Larger values need
680 * more memory, while smaller values may need more iterations. The value needs
681 * to be a sensible size, however, as it constrains the max stepping value used
682 * for mixing, as well as the maximum number of samples per mixing iteration.
684 #define BUFFERSIZE 2048
686 struct ALCdevice_struct
688 RefCount ref;
690 ALCboolean Connected;
691 enum DeviceType Type;
693 ALuint Frequency;
694 ALuint UpdateSize;
695 ALuint NumUpdates;
696 enum DevFmtChannels FmtChans;
697 enum DevFmtType FmtType;
698 ALboolean IsHeadphones;
699 ALsizei AmbiOrder;
700 /* For DevFmtAmbi* output only, specifies the channel order and
701 * normalization.
703 enum AmbiLayout AmbiLayout;
704 enum AmbiNorm AmbiScale;
706 al_string DeviceName;
708 ATOMIC(ALCenum) LastError;
710 // Maximum number of sources that can be created
711 ALuint SourcesMax;
712 // Maximum number of slots that can be created
713 ALuint AuxiliaryEffectSlotMax;
715 ALCuint NumMonoSources;
716 ALCuint NumStereoSources;
717 ALsizei NumAuxSends;
719 // Map of Buffers for this device
720 UIntMap BufferMap;
722 // Map of Effects for this device
723 UIntMap EffectMap;
725 // Map of Filters for this device
726 UIntMap FilterMap;
728 /* HRTF state and info */
729 DirectHrtfState *Hrtf;
730 al_string HrtfName;
731 struct Hrtf *HrtfHandle;
732 vector_EnumeratedHrtf HrtfList;
733 ALCenum HrtfStatus;
735 /* UHJ encoder state */
736 struct Uhj2Encoder *Uhj_Encoder;
738 /* High quality Ambisonic decoder */
739 struct BFormatDec *AmbiDecoder;
741 /* Stereo-to-binaural filter */
742 struct bs2b *Bs2b;
744 /* First-order ambisonic upsampler for higher-order output */
745 struct AmbiUpsampler *AmbiUp;
747 /* Rendering mode. */
748 enum RenderMode Render_Mode;
750 // Device flags
751 ALuint Flags;
753 ALuint64 ClockBase;
754 ALuint SamplesDone;
756 /* Temp storage used for each source when mixing. */
757 alignas(16) ALfloat SourceData[BUFFERSIZE];
758 alignas(16) ALfloat ResampledData[BUFFERSIZE];
759 alignas(16) ALfloat FilteredData[BUFFERSIZE];
760 alignas(16) ALfloat NFCtrlData[BUFFERSIZE];
762 /* The "dry" path corresponds to the main output. */
763 struct {
764 AmbiConfig Ambi;
765 /* Number of coefficients in each Ambi.Coeffs to mix together (4 for
766 * first-order, 9 for second-order, etc). If the count is 0, Ambi.Map
767 * is used instead to map each output to a coefficient index.
769 ALsizei CoeffCount;
771 ALfloat (*Buffer)[BUFFERSIZE];
772 ALsizei NumChannels;
773 ALsizei NumChannelsPerOrder[MAX_AMBI_ORDER+1];
774 } Dry;
776 /* First-order ambisonics output, to be upsampled to the dry buffer if different. */
777 struct {
778 AmbiConfig Ambi;
779 /* Will only be 4 or 0. */
780 ALsizei CoeffCount;
782 ALfloat (*Buffer)[BUFFERSIZE];
783 ALsizei NumChannels;
784 } FOAOut;
786 /* "Real" output, which will be written to the device buffer. May alias the
787 * dry buffer.
789 struct {
790 enum Channel ChannelName[MAX_OUTPUT_CHANNELS];
792 ALfloat (*Buffer)[BUFFERSIZE];
793 ALsizei NumChannels;
794 } RealOut;
796 ALfloat LimiterGain;
798 /* The average speaker distance as determined by the ambdec configuration
799 * (or alternatively, by the NFC-HOA reference delay). Only used for NFC.
801 ALfloat AvgSpeakerDist;
803 /* Delay buffers used to compensate for speaker distances. */
804 DistanceComp ChannelDelay[MAX_OUTPUT_CHANNELS];
806 /* Running count of the mixer invocations, in 31.1 fixed point. This
807 * actually increments *twice* when mixing, first at the start and then at
808 * the end, so the bottom bit indicates if the device is currently mixing
809 * and the upper bits indicates how many mixes have been done.
811 RefCount MixCount;
813 /* Default effect slot */
814 struct ALeffectslot *DefaultSlot;
816 // Contexts created on this device
817 ATOMIC(ALCcontext*) ContextList;
819 almtx_t BackendLock;
820 struct ALCbackend *Backend;
822 void *ExtraData; // For the backend's use
824 ALCdevice *volatile next;
826 /* Memory space used by the default slot (Playback devices only) */
827 alignas(16) ALCbyte _slot_mem[];
830 // Frequency was requested by the app or config file
831 #define DEVICE_FREQUENCY_REQUEST (1u<<1)
832 // Channel configuration was requested by the config file
833 #define DEVICE_CHANNELS_REQUEST (1u<<2)
834 // Sample type was requested by the config file
835 #define DEVICE_SAMPLE_TYPE_REQUEST (1u<<3)
837 // Specifies if the DSP is paused at user request
838 #define DEVICE_PAUSED (1u<<30)
840 // Specifies if the device is currently running
841 #define DEVICE_RUNNING (1u<<31)
844 /* Nanosecond resolution for the device clock time. */
845 #define DEVICE_CLOCK_RES U64(1000000000)
848 /* Must be less than 15 characters (16 including terminating null) for
849 * compatibility with pthread_setname_np limitations. */
850 #define MIXER_THREAD_NAME "alsoft-mixer"
852 #define RECORD_THREAD_NAME "alsoft-record"
855 struct ALCcontext_struct {
856 RefCount ref;
858 struct ALlistener *Listener;
860 UIntMap SourceMap;
861 UIntMap EffectSlotMap;
863 ATOMIC(ALenum) LastError;
865 enum DistanceModel DistanceModel;
866 ALboolean SourceDistanceModel;
868 ALfloat DopplerFactor;
869 ALfloat DopplerVelocity;
870 ALfloat SpeedOfSound;
871 ATOMIC(ALenum) DeferUpdates;
873 RWLock PropLock;
875 /* Counter for the pre-mixing updates, in 31.1 fixed point (lowest bit
876 * indicates if updates are currently happening).
878 RefCount UpdateCount;
879 ATOMIC(ALenum) HoldUpdates;
881 ALfloat GainBoost;
883 struct ALvoice **Voices;
884 ALsizei VoiceCount;
885 ALsizei MaxVoices;
887 ATOMIC(struct ALeffectslotArray*) ActiveAuxSlots;
889 ALCdevice *Device;
890 const ALCchar *ExtensionList;
892 ALCcontext *volatile next;
894 /* Memory space used by the listener */
895 alignas(16) ALCbyte _listener_mem[];
898 ALCcontext *GetContextRef(void);
900 void ALCcontext_IncRef(ALCcontext *context);
901 void ALCcontext_DecRef(ALCcontext *context);
903 void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends);
905 void AppendAllDevicesList(const ALCchar *name);
906 void AppendCaptureDeviceList(const ALCchar *name);
908 void ALCdevice_Lock(ALCdevice *device);
909 void ALCdevice_Unlock(ALCdevice *device);
911 void ALCcontext_DeferUpdates(ALCcontext *context);
912 void ALCcontext_ProcessUpdates(ALCcontext *context);
915 typedef struct {
916 #ifdef HAVE_FENV_H
917 DERIVE_FROM_TYPE(fenv_t);
918 #else
919 int state;
920 #endif
921 #ifdef HAVE_SSE
922 int sse_state;
923 #endif
924 } FPUCtl;
925 void SetMixerFPUMode(FPUCtl *ctl);
926 void RestoreFPUMode(const FPUCtl *ctl);
929 typedef struct ll_ringbuffer ll_ringbuffer_t;
930 typedef struct ll_ringbuffer_data {
931 char *buf;
932 size_t len;
933 } ll_ringbuffer_data_t;
934 ll_ringbuffer_t *ll_ringbuffer_create(size_t sz, size_t elem_sz);
935 void ll_ringbuffer_free(ll_ringbuffer_t *rb);
936 void ll_ringbuffer_get_read_vector(const ll_ringbuffer_t *rb, ll_ringbuffer_data_t *vec);
937 void ll_ringbuffer_get_write_vector(const ll_ringbuffer_t *rb, ll_ringbuffer_data_t *vec);
938 size_t ll_ringbuffer_read(ll_ringbuffer_t *rb, char *dest, size_t cnt);
939 size_t ll_ringbuffer_peek(ll_ringbuffer_t *rb, char *dest, size_t cnt);
940 void ll_ringbuffer_read_advance(ll_ringbuffer_t *rb, size_t cnt);
941 size_t ll_ringbuffer_read_space(const ll_ringbuffer_t *rb);
942 int ll_ringbuffer_mlock(ll_ringbuffer_t *rb);
943 void ll_ringbuffer_reset(ll_ringbuffer_t *rb);
944 size_t ll_ringbuffer_write(ll_ringbuffer_t *rb, const char *src, size_t cnt);
945 void ll_ringbuffer_write_advance(ll_ringbuffer_t *rb, size_t cnt);
946 size_t ll_ringbuffer_write_space(const ll_ringbuffer_t *rb);
948 void ReadALConfig(void);
949 void FreeALConfig(void);
950 int ConfigValueExists(const char *devName, const char *blockName, const char *keyName);
951 const char *GetConfigValue(const char *devName, const char *blockName, const char *keyName, const char *def);
952 int GetConfigValueBool(const char *devName, const char *blockName, const char *keyName, int def);
953 int ConfigValueStr(const char *devName, const char *blockName, const char *keyName, const char **ret);
954 int ConfigValueInt(const char *devName, const char *blockName, const char *keyName, int *ret);
955 int ConfigValueUInt(const char *devName, const char *blockName, const char *keyName, unsigned int *ret);
956 int ConfigValueFloat(const char *devName, const char *blockName, const char *keyName, float *ret);
957 int ConfigValueBool(const char *devName, const char *blockName, const char *keyName, int *ret);
959 void SetRTPriority(void);
961 void SetDefaultChannelOrder(ALCdevice *device);
962 void SetDefaultWFXChannelOrder(ALCdevice *device);
964 const ALCchar *DevFmtTypeString(enum DevFmtType type);
965 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans);
968 * GetChannelIdxByName
970 * Returns the index for the given channel name (e.g. FrontCenter), or -1 if it
971 * doesn't exist.
973 inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS], enum Channel chan)
975 ALint i;
976 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
978 if(names[i] == chan)
979 return i;
981 return -1;
983 #define GetChannelIdxByName(x, c) GetChannelIndex((x).ChannelName, (c))
985 extern FILE *LogFile;
987 #if defined(__GNUC__) && !defined(_WIN32) && !defined(IN_IDE_PARSER)
988 #define AL_PRINT(T, MSG, ...) fprintf(LogFile, "AL lib: %s %s: "MSG, T, __FUNCTION__ , ## __VA_ARGS__)
989 #else
990 void al_print(const char *type, const char *func, const char *fmt, ...) DECL_FORMAT(printf, 3,4);
991 #define AL_PRINT(T, ...) al_print((T), __FUNCTION__, __VA_ARGS__)
992 #endif
994 #ifdef __ANDROID__
995 #include <android/log.h>
996 #define LOG_ANDROID(T, MSG, ...) __android_log_print(T, "openal", "AL lib: %s: "MSG, __FUNCTION__ , ## __VA_ARGS__)
997 #else
998 #define LOG_ANDROID(T, MSG, ...) ((void)0)
999 #endif
1001 enum LogLevel {
1002 NoLog,
1003 LogError,
1004 LogWarning,
1005 LogTrace,
1006 LogRef
1008 extern enum LogLevel LogLevel;
1010 #define TRACEREF(...) do { \
1011 if(LogLevel >= LogRef) \
1012 AL_PRINT("(--)", __VA_ARGS__); \
1013 } while(0)
1015 #define TRACE(...) do { \
1016 if(LogLevel >= LogTrace) \
1017 AL_PRINT("(II)", __VA_ARGS__); \
1018 LOG_ANDROID(ANDROID_LOG_DEBUG, __VA_ARGS__); \
1019 } while(0)
1021 #define WARN(...) do { \
1022 if(LogLevel >= LogWarning) \
1023 AL_PRINT("(WW)", __VA_ARGS__); \
1024 LOG_ANDROID(ANDROID_LOG_WARN, __VA_ARGS__); \
1025 } while(0)
1027 #define ERR(...) do { \
1028 if(LogLevel >= LogError) \
1029 AL_PRINT("(EE)", __VA_ARGS__); \
1030 LOG_ANDROID(ANDROID_LOG_ERROR, __VA_ARGS__); \
1031 } while(0)
1034 extern ALint RTPrioLevel;
1037 extern ALuint CPUCapFlags;
1038 enum {
1039 CPU_CAP_SSE = 1<<0,
1040 CPU_CAP_SSE2 = 1<<1,
1041 CPU_CAP_SSE3 = 1<<2,
1042 CPU_CAP_SSE4_1 = 1<<3,
1043 CPU_CAP_NEON = 1<<4,
1046 void FillCPUCaps(ALuint capfilter);
1048 vector_al_string SearchDataFiles(const char *match, const char *subdir);
1050 /* Small hack to use a pointer-to-array types as a normal argument type.
1051 * Shouldn't be used directly.
1053 typedef ALfloat ALfloatBUFFERSIZE[BUFFERSIZE];
1054 typedef ALfloat ALfloat2[2];
1056 #ifdef __cplusplus
1058 #endif
1060 #endif