Update a couple comments
[openal-soft.git] / OpenAL32 / Include / alMain.h
blobcd58496625289674a8f4d73feb610c9a2a4e4e70
1 #ifndef AL_MAIN_H
2 #define AL_MAIN_H
4 #include <string.h>
5 #include <stdio.h>
6 #include <stdarg.h>
7 #include <assert.h>
8 #include <math.h>
9 #include <limits.h>
11 #ifdef HAVE_STRINGS_H
12 #include <strings.h>
13 #endif
15 #ifdef HAVE_FENV_H
16 #include <fenv.h>
17 #endif
19 #include "AL/al.h"
20 #include "AL/alc.h"
21 #include "AL/alext.h"
24 #if defined(_WIN64)
25 #define SZFMT "%I64u"
26 #elif defined(_WIN32)
27 #define SZFMT "%u"
28 #else
29 #define SZFMT "%zu"
30 #endif
33 #include "static_assert.h"
34 #include "align.h"
35 #include "atomic.h"
36 #include "uintmap.h"
37 #include "vector.h"
38 #include "alstring.h"
40 #include "hrtf.h"
42 #ifndef ALC_SOFT_HRTF
43 #define ALC_SOFT_HRTF 1
44 #define ALC_HRTF_SOFT 0x1992
45 #define ALC_HRTF_STATUS_SOFT 0x1993
46 #define ALC_HRTF_DISABLED_SOFT 0x0000
47 #define ALC_HRTF_ENABLED_SOFT 0x0001
48 #define ALC_HRTF_DENIED_SOFT 0x0002
49 #define ALC_HRTF_REQUIRED_SOFT 0x0003
50 #define ALC_HRTF_HEADPHONES_DETECTED_SOFT 0x0004
51 #define ALC_HRTF_UNSUPPORTED_FORMAT_SOFT 0x0005
52 typedef ALCboolean (ALC_APIENTRY*LPALCRESETDEVICESOFT)(ALCdevice *device, const ALCint *attribs);
53 #ifdef AL_ALEXT_PROTOTYPES
54 ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs);
55 #endif
56 #endif
58 #ifndef ALC_SOFT_midi_interface
59 #define ALC_SOFT_midi_interface 1
60 /* Global properties */
61 #define AL_MIDI_CLOCK_SOFT 0x9999
62 #define AL_MIDI_STATE_SOFT 0x9986
63 #define AL_MIDI_GAIN_SOFT 0x9998
64 #define AL_SOUNDFONTS_SIZE_SOFT 0x9995
65 #define AL_SOUNDFONTS_SOFT 0x9994
67 /* Soundfont properties */
68 #define AL_PRESETS_SIZE_SOFT 0x9993
69 #define AL_PRESETS_SOFT 0x9992
71 /* Preset properties */
72 #define AL_MIDI_PRESET_SOFT 0x9997
73 #define AL_MIDI_BANK_SOFT 0x9996
74 #define AL_FONTSOUNDS_SIZE_SOFT 0x9991
75 #define AL_FONTSOUNDS_SOFT 0x9990
77 /* Fontsound properties */
78 /* AL_BUFFER */
79 #define AL_SAMPLE_START_SOFT 0x2000
80 #define AL_SAMPLE_END_SOFT 0x2001
81 #define AL_SAMPLE_LOOP_START_SOFT 0x2002
82 #define AL_SAMPLE_LOOP_END_SOFT 0x2003
83 #define AL_SAMPLE_RATE_SOFT 0x2004
84 #define AL_BASE_KEY_SOFT 0x2005
85 #define AL_KEY_CORRECTION_SOFT 0x2006
86 #define AL_SAMPLE_TYPE_SOFT 0x2007
87 #define AL_FONTSOUND_LINK_SOFT 0x2008
88 #define AL_MOD_LFO_TO_PITCH_SOFT 0x0005
89 #define AL_VIBRATO_LFO_TO_PITCH_SOFT 0x0006
90 #define AL_MOD_ENV_TO_PITCH_SOFT 0x0007
91 #define AL_FILTER_CUTOFF_SOFT 0x0008
92 #define AL_FILTER_RESONANCE_SOFT 0x0009
93 #define AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT 0x000A
94 #define AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT 0x000B
95 #define AL_MOD_LFO_TO_VOLUME_SOFT 0x000D
96 #define AL_CHORUS_SEND_SOFT 0x000F
97 #define AL_REVERB_SEND_SOFT 0x0010
98 #define AL_PAN_SOFT 0x0011
99 #define AL_MOD_LFO_DELAY_SOFT 0x0015
100 #define AL_MOD_LFO_FREQUENCY_SOFT 0x0016
101 #define AL_VIBRATO_LFO_DELAY_SOFT 0x0017
102 #define AL_VIBRATO_LFO_FREQUENCY_SOFT 0x0018
103 #define AL_MOD_ENV_DELAYTIME_SOFT 0x0019
104 #define AL_MOD_ENV_ATTACKTIME_SOFT 0x001A
105 #define AL_MOD_ENV_HOLDTIME_SOFT 0x001B
106 #define AL_MOD_ENV_DECAYTIME_SOFT 0x001C
107 #define AL_MOD_ENV_SUSTAINVOLUME_SOFT 0x001D
108 #define AL_MOD_ENV_RELEASETIME_SOFT 0x002E
109 #define AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT 0x001F
110 #define AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT 0x0020
111 #define AL_VOLUME_ENV_DELAYTIME_SOFT 0x0021
112 #define AL_VOLUME_ENV_ATTACKTIME_SOFT 0x0022
113 #define AL_VOLUME_ENV_HOLDTIME_SOFT 0x0023
114 #define AL_VOLUME_ENV_DECAYTIME_SOFT 0x0024
115 #define AL_VOLUME_ENV_SUSTAINVOLUME_SOFT 0x0025
116 #define AL_VOLUME_ENV_RELEASETIME_SOFT 0x0026
117 #define AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT 0x0027
118 #define AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT 0x0028
119 #define AL_KEY_RANGE_SOFT 0x002B
120 #define AL_VELOCITY_RANGE_SOFT 0x002C
121 #define AL_ATTENUATION_SOFT 0x0030
122 #define AL_TUNING_COARSE_SOFT 0x0033
123 #define AL_TUNING_FINE_SOFT 0x0034
124 #define AL_LOOP_MODE_SOFT 0x0036
125 #define AL_TUNING_SCALE_SOFT 0x0038
126 #define AL_EXCLUSIVE_CLASS_SOFT 0x0039
128 /* Sample Types */
129 /* AL_MONO_SOFT */
130 #define AL_RIGHT_SOFT 0x0002
131 #define AL_LEFT_SOFT 0x0004
133 /* Loop Modes */
134 /* AL_NONE */
135 #define AL_LOOP_CONTINUOUS_SOFT 0x0001
136 #define AL_LOOP_UNTIL_RELEASE_SOFT 0x0003
138 /* Fontsound modulator stage properties */
139 #define AL_SOURCE0_INPUT_SOFT 0x998F
140 #define AL_SOURCE0_TYPE_SOFT 0x998E
141 #define AL_SOURCE0_FORM_SOFT 0x998D
142 #define AL_SOURCE1_INPUT_SOFT 0x998C
143 #define AL_SOURCE1_TYPE_SOFT 0x998B
144 #define AL_SOURCE1_FORM_SOFT 0x998A
145 #define AL_AMOUNT_SOFT 0x9989
146 #define AL_TRANSFORM_OP_SOFT 0x9988
147 #define AL_DESTINATION_SOFT 0x9987
149 /* Sounce Inputs */
150 #define AL_ONE_SOFT 0x0080
151 #define AL_NOTEON_VELOCITY_SOFT 0x0082
152 #define AL_NOTEON_KEY_SOFT 0x0083
153 /* AL_KEYPRESSURE_SOFT */
154 /* AL_CHANNELPRESSURE_SOFT */
155 /* AL_PITCHBEND_SOFT */
156 #define AL_PITCHBEND_SENSITIVITY_SOFT 0x0090
157 /* CC 0...127 */
159 /* Source Types */
160 #define AL_UNORM_SOFT 0x0000
161 #define AL_UNORM_REV_SOFT 0x0100
162 #define AL_SNORM_SOFT 0x0200
163 #define AL_SNORM_REV_SOFT 0x0300
165 /* Source Forms */
166 #define AL_LINEAR_SOFT 0x0000
167 #define AL_CONCAVE_SOFT 0x0400
168 #define AL_CONVEX_SOFT 0x0800
169 #define AL_SWITCH_SOFT 0x0C00
171 /* Transform Ops */
172 /* AL_LINEAR_SOFT */
173 #define AL_ABSOLUTE_SOFT 0x0002
175 /* Events */
176 #define AL_NOTEOFF_SOFT 0x0080
177 #define AL_NOTEON_SOFT 0x0090
178 #define AL_KEYPRESSURE_SOFT 0x00A0
179 #define AL_CONTROLLERCHANGE_SOFT 0x00B0
180 #define AL_PROGRAMCHANGE_SOFT 0x00C0
181 #define AL_CHANNELPRESSURE_SOFT 0x00D0
182 #define AL_PITCHBEND_SOFT 0x00E0
184 typedef void (AL_APIENTRY*LPALGENSOUNDFONTSSOFT)(ALsizei n, ALuint *ids);
185 typedef void (AL_APIENTRY*LPALDELETESOUNDFONTSSOFT)(ALsizei n, const ALuint *ids);
186 typedef ALboolean (AL_APIENTRY*LPALISSOUNDFONTSOFT)(ALuint id);
187 typedef void (AL_APIENTRY*LPALGETSOUNDFONTIVSOFT)(ALuint id, ALenum param, ALint *values);
188 typedef void (AL_APIENTRY*LPALSOUNDFONTPRESETSSOFT)(ALuint id, ALsizei count, const ALuint *pids);
189 typedef void (AL_APIENTRY*LPALGENPRESETSSOFT)(ALsizei n, ALuint *ids);
190 typedef void (AL_APIENTRY*LPALDELETEPRESETSSOFT)(ALsizei n, const ALuint *ids);
191 typedef ALboolean (AL_APIENTRY*LPALISPRESETSOFT)(ALuint id);
192 typedef void (AL_APIENTRY*LPALPRESETISOFT)(ALuint id, ALenum param, ALint value);
193 typedef void (AL_APIENTRY*LPALPRESETIVSOFT)(ALuint id, ALenum param, const ALint *values);
194 typedef void (AL_APIENTRY*LPALPRESETFONTSOUNDSSOFT)(ALuint id, ALsizei count, const ALuint *fsids);
195 typedef void (AL_APIENTRY*LPALGETPRESETIVSOFT)(ALuint id, ALenum param, ALint *values);
196 typedef void (AL_APIENTRY*LPALGENFONTSOUNDSSOFT)(ALsizei n, ALuint *ids);
197 typedef void (AL_APIENTRY*LPALDELETEFONTSOUNDSSOFT)(ALsizei n, const ALuint *ids);
198 typedef ALboolean (AL_APIENTRY*LPALISFONTSOUNDSOFT)(ALuint id);
199 typedef void (AL_APIENTRY*LPALFONTSOUNDISOFT)(ALuint id, ALenum param, ALint value);
200 typedef void (AL_APIENTRY*LPALFONTSOUND2ISOFT)(ALuint id, ALenum param, ALint value1, ALint value2);
201 typedef void (AL_APIENTRY*LPALFONTSOUNDIVSOFT)(ALuint id, ALenum param, const ALint *values);
202 typedef void (AL_APIENTRY*LPALGETFONTSOUNDIVSOFT)(ALuint id, ALenum param, ALint *values);
203 typedef void (AL_APIENTRY*LPALFONTSOUNDMOFULATORISOFT)(ALuint id, ALsizei stage, ALenum param, ALint value);
204 typedef void (AL_APIENTRY*LPALGETFONTSOUNDMODULATORIVSOFT)(ALuint id, ALsizei stage, ALenum param, ALint *values);
205 typedef void (AL_APIENTRY*LPALMIDISOUNDFONTSOFT)(ALuint id);
206 typedef void (AL_APIENTRY*LPALMIDISOUNDFONTVSOFT)(ALsizei count, const ALuint *ids);
207 typedef void (AL_APIENTRY*LPALMIDIEVENTSOFT)(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2);
208 typedef void (AL_APIENTRY*LPALMIDISYSEXSOFT)(ALuint64SOFT time, const ALbyte *data, ALsizei size);
209 typedef void (AL_APIENTRY*LPALMIDIPLAYSOFT)(void);
210 typedef void (AL_APIENTRY*LPALMIDIPAUSESOFT)(void);
211 typedef void (AL_APIENTRY*LPALMIDISTOPSOFT)(void);
212 typedef void (AL_APIENTRY*LPALMIDIRESETSOFT)(void);
213 typedef void (AL_APIENTRY*LPALMIDIGAINSOFT)(ALfloat value);
214 typedef ALint64SOFT (AL_APIENTRY*LPALGETINTEGER64SOFT)(ALenum pname);
215 typedef void (AL_APIENTRY*LPALGETINTEGER64VSOFT)(ALenum pname, ALint64SOFT *values);
216 typedef void (AL_APIENTRY*LPALLOADSOUNDFONTSOFT)(ALuint id, size_t(*cb)(ALvoid*,size_t,ALvoid*), ALvoid *user);
217 #ifdef AL_ALEXT_PROTOTYPES
218 AL_API void AL_APIENTRY alGenSoundfontsSOFT(ALsizei n, ALuint *ids);
219 AL_API void AL_APIENTRY alDeleteSoundfontsSOFT(ALsizei n, const ALuint *ids);
220 AL_API ALboolean AL_APIENTRY alIsSoundfontSOFT(ALuint id);
221 AL_API void AL_APIENTRY alGetSoundfontivSOFT(ALuint id, ALenum param, ALint *values);
222 AL_API void AL_APIENTRY alSoundfontPresetsSOFT(ALuint id, ALsizei count, const ALuint *pids);
224 AL_API void AL_APIENTRY alGenPresetsSOFT(ALsizei n, ALuint *ids);
225 AL_API void AL_APIENTRY alDeletePresetsSOFT(ALsizei n, const ALuint *ids);
226 AL_API ALboolean AL_APIENTRY alIsPresetSOFT(ALuint id);
227 AL_API void AL_APIENTRY alPresetiSOFT(ALuint id, ALenum param, ALint value);
228 AL_API void AL_APIENTRY alPresetivSOFT(ALuint id, ALenum param, const ALint *values);
229 AL_API void AL_APIENTRY alGetPresetivSOFT(ALuint id, ALenum param, ALint *values);
230 AL_API void AL_APIENTRY alPresetFontsoundsSOFT(ALuint id, ALsizei count, const ALuint *fsids);
232 AL_API void AL_APIENTRY alGenFontsoundsSOFT(ALsizei n, ALuint *ids);
233 AL_API void AL_APIENTRY alDeleteFontsoundsSOFT(ALsizei n, const ALuint *ids);
234 AL_API ALboolean AL_APIENTRY alIsFontsoundSOFT(ALuint id);
235 AL_API void AL_APIENTRY alFontsoundiSOFT(ALuint id, ALenum param, ALint value);
236 AL_API void AL_APIENTRY alFontsound2iSOFT(ALuint id, ALenum param, ALint value1, ALint value2);
237 AL_API void AL_APIENTRY alFontsoundivSOFT(ALuint id, ALenum param, const ALint *values);
238 AL_API void AL_APIENTRY alGetFontsoundivSOFT(ALuint id, ALenum param, ALint *values);
239 AL_API void AL_APIENTRY alFontsoundModulatoriSOFT(ALuint id, ALsizei stage, ALenum param, ALint value);
240 AL_API void AL_APIENTRY alGetFontsoundModulatorivSOFT(ALuint id, ALsizei stage, ALenum param, ALint *values);
242 AL_API void AL_APIENTRY alMidiSoundfontSOFT(ALuint id);
243 AL_API void AL_APIENTRY alMidiSoundfontvSOFT(ALsizei count, const ALuint *ids);
244 AL_API void AL_APIENTRY alMidiEventSOFT(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2);
245 AL_API void AL_APIENTRY alMidiSysExSOFT(ALuint64SOFT time, const ALbyte *data, ALsizei size);
246 AL_API void AL_APIENTRY alMidiPlaySOFT(void);
247 AL_API void AL_APIENTRY alMidiPauseSOFT(void);
248 AL_API void AL_APIENTRY alMidiStopSOFT(void);
249 AL_API void AL_APIENTRY alMidiResetSOFT(void);
250 AL_API void AL_APIENTRY alMidiGainSOFT(ALfloat value);
251 AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname);
252 AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values);
253 AL_API void AL_APIENTRY alLoadSoundfontSOFT(ALuint id, size_t(*cb)(ALvoid*,size_t,ALvoid*), ALvoid *user);
254 #endif
255 #endif
257 #ifndef ALC_SOFT_device_clock
258 #define ALC_SOFT_device_clock 1
259 typedef int64_t ALCint64SOFT;
260 typedef uint64_t ALCuint64SOFT;
261 #define ALC_DEVICE_CLOCK_SOFT 0x1600
262 typedef void (ALC_APIENTRY*LPALCGETINTEGER64VSOFT)(ALCdevice *device, ALCenum pname, ALsizei size, ALCint64SOFT *values);
263 #ifdef AL_ALEXT_PROTOTYPES
264 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALsizei size, ALCint64SOFT *values);
265 #endif
266 #endif
269 typedef ALint64SOFT ALint64;
270 typedef ALuint64SOFT ALuint64;
272 #ifndef U64
273 #if defined(_MSC_VER)
274 #define U64(x) ((ALuint64)(x##ui64))
275 #elif SIZEOF_LONG == 8
276 #define U64(x) ((ALuint64)(x##ul))
277 #elif SIZEOF_LONG_LONG == 8
278 #define U64(x) ((ALuint64)(x##ull))
279 #endif
280 #endif
282 #ifndef UINT64_MAX
283 #define UINT64_MAX U64(18446744073709551615)
284 #endif
286 #ifndef UNUSED
287 #if defined(__cplusplus)
288 #define UNUSED(x)
289 #elif defined(__GNUC__)
290 #define UNUSED(x) UNUSED_##x __attribute__((unused))
291 #elif defined(__LCLINT__)
292 #define UNUSED(x) /*@unused@*/ x
293 #else
294 #define UNUSED(x) x
295 #endif
296 #endif
298 #ifdef __GNUC__
299 #define DECL_CONST __attribute__((const))
300 #define DECL_FORMAT(x, y, z) __attribute__((format(x, (y), (z))))
301 #else
302 #define DECL_CONST
303 #define DECL_FORMAT(x, y, z)
304 #endif
306 #if defined(__GNUC__) && defined(__i386__)
307 /* force_align_arg_pointer is required for proper function arguments aligning
308 * when SSE code is used. Some systems (Windows, QNX) do not guarantee our
309 * thread functions will be properly aligned on the stack, even though GCC may
310 * generate code with the assumption that it is. */
311 #define FORCE_ALIGN __attribute__((force_align_arg_pointer))
312 #else
313 #define FORCE_ALIGN
314 #endif
316 #ifdef HAVE_C99_VLA
317 #define DECL_VLA(T, _name, _size) T _name[(_size)]
318 #else
319 #define DECL_VLA(T, _name, _size) T *_name = alloca((_size) * sizeof(T))
320 #endif
322 #ifndef PATH_MAX
323 #ifdef MAX_PATH
324 #define PATH_MAX MAX_PATH
325 #else
326 #define PATH_MAX 4096
327 #endif
328 #endif
331 static const union {
332 ALuint u;
333 ALubyte b[sizeof(ALuint)];
334 } EndianTest = { 1 };
335 #define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1)
337 #define COUNTOF(x) (sizeof((x))/sizeof((x)[0]))
340 #define DERIVE_FROM_TYPE(t) t t##_parent
341 #define STATIC_CAST(to, obj) (&(obj)->to##_parent)
342 #ifdef __GNUC__
343 #define STATIC_UPCAST(to, from, obj) __extension__({ \
344 static_assert(__builtin_types_compatible_p(from, __typeof(*(obj))), \
345 "Invalid upcast object from type"); \
346 (to*)((char*)(obj) - offsetof(to, from##_parent)); \
348 #else
349 #define STATIC_UPCAST(to, from, obj) ((to*)((char*)(obj) - offsetof(to, from##_parent)))
350 #endif
352 #define DECLARE_FORWARD(T1, T2, rettype, func) \
353 rettype T1##_##func(T1 *obj) \
354 { return T2##_##func(STATIC_CAST(T2, obj)); }
356 #define DECLARE_FORWARD1(T1, T2, rettype, func, argtype1) \
357 rettype T1##_##func(T1 *obj, argtype1 a) \
358 { return T2##_##func(STATIC_CAST(T2, obj), a); }
360 #define DECLARE_FORWARD2(T1, T2, rettype, func, argtype1, argtype2) \
361 rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b) \
362 { return T2##_##func(STATIC_CAST(T2, obj), a, b); }
364 #define DECLARE_FORWARD3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
365 rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b, argtype3 c) \
366 { return T2##_##func(STATIC_CAST(T2, obj), a, b, c); }
369 #define GET_VTABLE1(T1) (&(T1##_vtable))
370 #define GET_VTABLE2(T1, T2) (&(T1##_##T2##_vtable))
372 #define SET_VTABLE1(T1, obj) ((obj)->vtbl = GET_VTABLE1(T1))
373 #define SET_VTABLE2(T1, T2, obj) (STATIC_CAST(T2, obj)->vtbl = GET_VTABLE2(T1, T2))
375 #define DECLARE_THUNK(T1, T2, rettype, func) \
376 static rettype T1##_##T2##_##func(T2 *obj) \
377 { return T1##_##func(STATIC_UPCAST(T1, T2, obj)); }
379 #define DECLARE_THUNK1(T1, T2, rettype, func, argtype1) \
380 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a) \
381 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a); }
383 #define DECLARE_THUNK2(T1, T2, rettype, func, argtype1, argtype2) \
384 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b) \
385 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b); }
387 #define DECLARE_THUNK3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
388 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c) \
389 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c); }
391 #define DECLARE_THUNK4(T1, T2, rettype, func, argtype1, argtype2, argtype3, argtype4) \
392 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c, argtype4 d) \
393 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c, d); }
395 #define DECLARE_DEFAULT_ALLOCATORS(T) \
396 static void* T##_New(size_t size) { return al_malloc(16, size); } \
397 static void T##_Delete(void *ptr) { al_free(ptr); }
399 /* Helper to extract an argument list for VCALL. Not used directly. */
400 #define EXTRACT_VCALL_ARGS(...) __VA_ARGS__))
402 /* Call a "virtual" method on an object, with arguments. */
403 #define V(obj, func) ((obj)->vtbl->func((obj), EXTRACT_VCALL_ARGS
404 /* Call a "virtual" method on an object, with no arguments. */
405 #define V0(obj, func) ((obj)->vtbl->func((obj) EXTRACT_VCALL_ARGS
407 #define DELETE_OBJ(obj) do { \
408 if((obj) != NULL) \
410 V0((obj),Destruct)(); \
411 V0((obj),Delete)(); \
413 } while(0)
416 #define EXTRACT_NEW_ARGS(...) __VA_ARGS__); \
418 } while(0)
420 #define NEW_OBJ(_ptr, T) do { \
421 _ptr = T##_New(sizeof(*_ptr)); \
422 if(_ptr) \
424 memset(_ptr, 0, sizeof(*_ptr)); \
425 T##_Construct(_ptr, EXTRACT_NEW_ARGS
428 #ifdef __cplusplus
429 extern "C" {
430 #endif
432 struct Hrtf;
435 #define DEFAULT_OUTPUT_RATE (44100)
436 #define MIN_OUTPUT_RATE (8000)
439 /* Find the next power-of-2 for non-power-of-2 numbers. */
440 inline ALuint NextPowerOf2(ALuint value)
442 if(value > 0)
444 value--;
445 value |= value>>1;
446 value |= value>>2;
447 value |= value>>4;
448 value |= value>>8;
449 value |= value>>16;
451 return value+1;
454 /* Fast float-to-int conversion. Assumes the FPU is already in round-to-zero
455 * mode. */
456 inline ALint fastf2i(ALfloat f)
458 #ifdef HAVE_LRINTF
459 return lrintf(f);
460 #elif defined(_MSC_VER) && defined(_M_IX86)
461 ALint i;
462 __asm fld f
463 __asm fistp i
464 return i;
465 #else
466 return (ALint)f;
467 #endif
470 /* Fast float-to-uint conversion. Assumes the FPU is already in round-to-zero
471 * mode. */
472 inline ALuint fastf2u(ALfloat f)
473 { return fastf2i(f); }
476 enum DevProbe {
477 ALL_DEVICE_PROBE,
478 CAPTURE_DEVICE_PROBE
481 typedef struct {
482 ALCenum (*OpenPlayback)(ALCdevice*, const ALCchar*);
483 void (*ClosePlayback)(ALCdevice*);
484 ALCboolean (*ResetPlayback)(ALCdevice*);
485 ALCboolean (*StartPlayback)(ALCdevice*);
486 void (*StopPlayback)(ALCdevice*);
488 ALCenum (*OpenCapture)(ALCdevice*, const ALCchar*);
489 void (*CloseCapture)(ALCdevice*);
490 void (*StartCapture)(ALCdevice*);
491 void (*StopCapture)(ALCdevice*);
492 ALCenum (*CaptureSamples)(ALCdevice*, void*, ALCuint);
493 ALCuint (*AvailableSamples)(ALCdevice*);
494 } BackendFuncs;
496 ALCboolean alc_sndio_init(BackendFuncs *func_list);
497 void alc_sndio_deinit(void);
498 void alc_sndio_probe(enum DevProbe type);
499 ALCboolean alc_pa_init(BackendFuncs *func_list);
500 void alc_pa_deinit(void);
501 void alc_pa_probe(enum DevProbe type);
502 ALCboolean alc_ca_init(BackendFuncs *func_list);
503 void alc_ca_deinit(void);
504 void alc_ca_probe(enum DevProbe type);
505 ALCboolean alc_opensl_init(BackendFuncs *func_list);
506 void alc_opensl_deinit(void);
507 void alc_opensl_probe(enum DevProbe type);
508 ALCboolean alc_qsa_init(BackendFuncs *func_list);
509 void alc_qsa_deinit(void);
510 void alc_qsa_probe(enum DevProbe type);
512 struct ALCbackend;
515 enum DistanceModel {
516 InverseDistanceClamped = AL_INVERSE_DISTANCE_CLAMPED,
517 LinearDistanceClamped = AL_LINEAR_DISTANCE_CLAMPED,
518 ExponentDistanceClamped = AL_EXPONENT_DISTANCE_CLAMPED,
519 InverseDistance = AL_INVERSE_DISTANCE,
520 LinearDistance = AL_LINEAR_DISTANCE,
521 ExponentDistance = AL_EXPONENT_DISTANCE,
522 DisableDistance = AL_NONE,
524 DefaultDistanceModel = InverseDistanceClamped
527 enum Resampler {
528 PointResampler,
529 LinearResampler,
530 CubicResampler,
532 ResamplerMax,
535 enum Channel {
536 FrontLeft = 0,
537 FrontRight,
538 FrontCenter,
539 LFE,
540 BackLeft,
541 BackRight,
542 BackCenter,
543 SideLeft,
544 SideRight,
546 TopFrontLeft,
547 TopFrontRight,
548 TopBackLeft,
549 TopBackRight,
550 BottomFrontLeft,
551 BottomFrontRight,
552 BottomBackLeft,
553 BottomBackRight,
555 Aux0,
556 Aux1,
557 Aux2,
558 Aux3,
560 InvalidChannel
564 /* Device formats */
565 enum DevFmtType {
566 DevFmtByte = ALC_BYTE_SOFT,
567 DevFmtUByte = ALC_UNSIGNED_BYTE_SOFT,
568 DevFmtShort = ALC_SHORT_SOFT,
569 DevFmtUShort = ALC_UNSIGNED_SHORT_SOFT,
570 DevFmtInt = ALC_INT_SOFT,
571 DevFmtUInt = ALC_UNSIGNED_INT_SOFT,
572 DevFmtFloat = ALC_FLOAT_SOFT,
574 DevFmtTypeDefault = DevFmtFloat
576 enum DevFmtChannels {
577 DevFmtMono = ALC_MONO_SOFT,
578 DevFmtStereo = ALC_STEREO_SOFT,
579 DevFmtQuad = ALC_QUAD_SOFT,
580 DevFmtX51 = ALC_5POINT1_SOFT,
581 DevFmtX61 = ALC_6POINT1_SOFT,
582 DevFmtX71 = ALC_7POINT1_SOFT,
584 /* Similar to 5.1, except using rear channels instead of sides */
585 DevFmtX51Rear = 0x80000000,
587 DevFmtBFormat3D,
589 DevFmtChannelsDefault = DevFmtStereo
591 #define MAX_OUTPUT_CHANNELS (8)
593 ALuint BytesFromDevFmt(enum DevFmtType type) DECL_CONST;
594 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans) DECL_CONST;
595 inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type)
597 return ChannelsFromDevFmt(chans) * BytesFromDevFmt(type);
601 extern const struct EffectList {
602 const char *name;
603 int type;
604 const char *ename;
605 ALenum val;
606 } EffectList[];
609 enum DeviceType {
610 Playback,
611 Capture,
612 Loopback
616 enum HrtfMode {
617 DisabledHrtf,
618 BasicHrtf,
619 FullHrtf
623 /* The maximum number of Ambisonics coefficients. For a given order (o), the
624 * size needed will be (o+1)**2, thus zero-order has 1, first-order has 4,
625 * second-order has 9, and third-order has 16. */
626 #define MAX_AMBI_COEFFS 16
628 typedef struct ChannelConfig {
629 ALfloat HOACoeff[MAX_AMBI_COEFFS];
630 ALfloat FOACoeff[4];
631 } ChannelConfig;
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 typedef struct HrtfState {
639 alignas(16) ALfloat History[HRTF_HISTORY_LENGTH];
640 alignas(16) ALfloat Values[HRIR_LENGTH][2];
641 } HrtfState;
643 typedef struct HrtfParams {
644 alignas(16) ALfloat Coeffs[HRIR_LENGTH][2];
645 alignas(16) ALfloat CoeffStep[HRIR_LENGTH][2];
646 ALuint Delay[2];
647 ALint DelayStep[2];
648 } HrtfParams;
651 /* Size for temporary storage of buffer data, in ALfloats. Larger values need
652 * more memory, while smaller values may need more iterations. The value needs
653 * to be a sensible size, however, as it constrains the max stepping value used
654 * for mixing, as well as the maximum number of samples per mixing iteration.
656 #define BUFFERSIZE (2048u)
658 struct ALCdevice_struct
660 RefCount ref;
662 ALCboolean Connected;
663 enum DeviceType Type;
665 ALuint Frequency;
666 ALuint UpdateSize;
667 ALuint NumUpdates;
668 enum DevFmtChannels FmtChans;
669 enum DevFmtType FmtType;
670 ALboolean IsHeadphones;
672 al_string DeviceName;
674 ATOMIC(ALCenum) LastError;
676 // Maximum number of sources that can be created
677 ALuint MaxNoOfSources;
678 // Maximum number of slots that can be created
679 ALuint AuxiliaryEffectSlotMax;
681 ALCuint NumMonoSources;
682 ALCuint NumStereoSources;
683 ALuint NumAuxSends;
685 // Map of Buffers for this device
686 UIntMap BufferMap;
688 // Map of Effects for this device
689 UIntMap EffectMap;
691 // Map of Filters for this device
692 UIntMap FilterMap;
694 // Map of Soundfonts for this device
695 UIntMap SfontMap;
697 // Map of Presets for this device
698 UIntMap PresetMap;
700 // Map of Fontsounds for this device
701 UIntMap FontsoundMap;
703 /* Default soundfont (accessible as ID 0) */
704 struct ALsoundfont *DefaultSfont;
706 /* MIDI synth engine */
707 struct MidiSynth *Synth;
709 /* HRTF filter tables */
710 const struct Hrtf *Hrtf;
711 ALCenum Hrtf_Status;
712 enum HrtfMode Hrtf_Mode;
713 HrtfState Hrtf_State[MAX_OUTPUT_CHANNELS];
714 HrtfParams Hrtf_Params[MAX_OUTPUT_CHANNELS];
715 ALuint Hrtf_Offset;
717 // Stereo-to-binaural filter
718 struct bs2b *Bs2b;
720 // Device flags
721 ALuint Flags;
723 enum Channel ChannelName[MAX_OUTPUT_CHANNELS];
724 ChannelConfig Channel[MAX_OUTPUT_CHANNELS];
725 ALuint NumChannels;
727 ALuint64 ClockBase;
728 ALuint SamplesDone;
730 /* Temp storage used for each source when mixing. */
731 alignas(16) ALfloat SourceData[BUFFERSIZE];
732 alignas(16) ALfloat ResampledData[BUFFERSIZE];
733 alignas(16) ALfloat FilteredData[BUFFERSIZE];
735 /* Dry path buffer mix. */
736 alignas(16) ALfloat (*DryBuffer)[BUFFERSIZE];
738 /* Running count of the mixer invocations, in 31.1 fixed point. This
739 * actually increments *twice* when mixing, first at the start and then at
740 * the end, so the bottom bit indicates if the device is currently mixing
741 * and the upper bits indicates how many mixes have been done.
743 RefCount MixCount;
745 /* Default effect slot */
746 struct ALeffectslot *DefaultSlot;
748 // Contexts created on this device
749 ATOMIC(ALCcontext*) ContextList;
751 struct ALCbackend *Backend;
753 void *ExtraData; // For the backend's use
755 ALCdevice *volatile next;
757 /* Memory space used by the default slot (Playback devices only) */
758 alignas(16) ALCbyte _slot_mem[];
761 // Frequency was requested by the app or config file
762 #define DEVICE_FREQUENCY_REQUEST (1<<1)
763 // Channel configuration was requested by the config file
764 #define DEVICE_CHANNELS_REQUEST (1<<2)
765 // Sample type was requested by the config file
766 #define DEVICE_SAMPLE_TYPE_REQUEST (1<<3)
767 // HRTF was requested by the app
768 #define DEVICE_HRTF_REQUEST (1<<4)
770 // Specifies if the DSP is paused at user request
771 #define DEVICE_PAUSED (1<<30)
773 // Specifies if the device is currently running
774 #define DEVICE_RUNNING (1<<31)
777 /* Nanosecond resolution for the device clock time. */
778 #define DEVICE_CLOCK_RES U64(1000000000)
781 /* Must be less than 15 characters (16 including terminating null) for
782 * compatibility with pthread_setname_np limitations. */
783 #define MIXER_THREAD_NAME "alsoft-mixer"
785 #define RECORD_THREAD_NAME "alsoft-record"
788 struct ALCcontext_struct
790 RefCount ref;
792 struct ALlistener *Listener;
794 UIntMap SourceMap;
795 UIntMap EffectSlotMap;
797 ATOMIC(ALenum) LastError;
799 ATOMIC(ALenum) UpdateSources;
801 volatile enum DistanceModel DistanceModel;
802 volatile ALboolean SourceDistanceModel;
804 volatile ALfloat DopplerFactor;
805 volatile ALfloat DopplerVelocity;
806 volatile ALfloat SpeedOfSound;
807 volatile ALenum DeferUpdates;
809 struct ALvoice *Voices;
810 ALsizei VoiceCount;
811 ALsizei MaxVoices;
813 VECTOR(struct ALeffectslot*) ActiveAuxSlots;
815 ALCdevice *Device;
816 const ALCchar *ExtensionList;
818 ALCcontext *volatile next;
820 /* Memory space used by the listener */
821 alignas(16) ALCbyte _listener_mem[];
824 ALCcontext *GetContextRef(void);
826 void ALCcontext_IncRef(ALCcontext *context);
827 void ALCcontext_DecRef(ALCcontext *context);
829 void AppendAllDevicesList(const ALCchar *name);
830 void AppendCaptureDeviceList(const ALCchar *name);
832 void ALCdevice_Lock(ALCdevice *device);
833 void ALCdevice_Unlock(ALCdevice *device);
834 ALint64 ALCdevice_GetLatency(ALCdevice *device);
836 void ALCcontext_DeferUpdates(ALCcontext *context);
837 void ALCcontext_ProcessUpdates(ALCcontext *context);
839 inline void LockContext(ALCcontext *context)
840 { ALCdevice_Lock(context->Device); }
842 inline void UnlockContext(ALCcontext *context)
843 { ALCdevice_Unlock(context->Device); }
846 void *al_malloc(size_t alignment, size_t size);
847 void *al_calloc(size_t alignment, size_t size);
848 void al_free(void *ptr);
851 typedef struct {
852 #ifdef HAVE_FENV_H
853 DERIVE_FROM_TYPE(fenv_t);
854 #else
855 int state;
856 #endif
857 #ifdef HAVE_SSE
858 int sse_state;
859 #endif
860 } FPUCtl;
861 void SetMixerFPUMode(FPUCtl *ctl);
862 void RestoreFPUMode(const FPUCtl *ctl);
865 typedef struct RingBuffer RingBuffer;
866 RingBuffer *CreateRingBuffer(ALsizei frame_size, ALsizei length);
867 void DestroyRingBuffer(RingBuffer *ring);
868 ALsizei RingBufferSize(RingBuffer *ring);
869 void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len);
870 void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len);
872 typedef struct ll_ringbuffer ll_ringbuffer_t;
873 typedef struct ll_ringbuffer_data {
874 char *buf;
875 size_t len;
876 } ll_ringbuffer_data_t;
877 ll_ringbuffer_t *ll_ringbuffer_create(size_t sz, size_t elem_sz);
878 void ll_ringbuffer_free(ll_ringbuffer_t *rb);
879 void ll_ringbuffer_get_read_vector(const ll_ringbuffer_t *rb, ll_ringbuffer_data_t *vec);
880 void ll_ringbuffer_get_write_vector(const ll_ringbuffer_t *rb, ll_ringbuffer_data_t *vec);
881 size_t ll_ringbuffer_read(ll_ringbuffer_t *rb, char *dest, size_t cnt);
882 size_t ll_ringbuffer_peek(ll_ringbuffer_t *rb, char *dest, size_t cnt);
883 void ll_ringbuffer_read_advance(ll_ringbuffer_t *rb, size_t cnt);
884 size_t ll_ringbuffer_read_space(const ll_ringbuffer_t *rb);
885 int ll_ringbuffer_mlock(ll_ringbuffer_t *rb);
886 void ll_ringbuffer_reset(ll_ringbuffer_t *rb);
887 size_t ll_ringbuffer_write(ll_ringbuffer_t *rb, const char *src, size_t cnt);
888 void ll_ringbuffer_write_advance(ll_ringbuffer_t *rb, size_t cnt);
889 size_t ll_ringbuffer_write_space(const ll_ringbuffer_t *rb);
891 void ReadALConfig(void);
892 void FreeALConfig(void);
893 int ConfigValueExists(const char *blockName, const char *keyName);
894 const char *GetConfigValue(const char *blockName, const char *keyName, const char *def);
895 int GetConfigValueBool(const char *blockName, const char *keyName, int def);
896 int ConfigValueStr(const char *blockName, const char *keyName, const char **ret);
897 int ConfigValueInt(const char *blockName, const char *keyName, int *ret);
898 int ConfigValueUInt(const char *blockName, const char *keyName, unsigned int *ret);
899 int ConfigValueFloat(const char *blockName, const char *keyName, float *ret);
900 int ConfigValueBool(const char *blockName, const char *keyName, int *ret);
902 void SetRTPriority(void);
904 void SetDefaultChannelOrder(ALCdevice *device);
905 void SetDefaultWFXChannelOrder(ALCdevice *device);
907 const ALCchar *DevFmtTypeString(enum DevFmtType type) DECL_CONST;
908 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans) DECL_CONST;
911 * GetChannelIdxByName
913 * Returns the device's channel index given a channel name (e.g. FrontCenter),
914 * or -1 if it doesn't exist.
916 inline ALint GetChannelIdxByName(const ALCdevice *device, enum Channel chan)
918 ALint i = 0;
919 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
921 if(device->ChannelName[i] == chan)
922 return i;
924 return -1;
928 extern FILE *LogFile;
930 #if defined(__GNUC__) && !defined(_WIN32) && !defined(IN_IDE_PARSER)
931 #define AL_PRINT(T, MSG, ...) fprintf(LogFile, "AL lib: %s %s: "MSG, T, __FUNCTION__ , ## __VA_ARGS__)
932 #else
933 void al_print(const char *type, const char *func, const char *fmt, ...) DECL_FORMAT(printf, 3,4);
934 #define AL_PRINT(T, ...) al_print((T), __FUNCTION__, __VA_ARGS__)
935 #endif
937 enum LogLevel {
938 NoLog,
939 LogError,
940 LogWarning,
941 LogTrace,
942 LogRef
944 extern enum LogLevel LogLevel;
946 #define TRACEREF(...) do { \
947 if(LogLevel >= LogRef) \
948 AL_PRINT("(--)", __VA_ARGS__); \
949 } while(0)
951 #define TRACE(...) do { \
952 if(LogLevel >= LogTrace) \
953 AL_PRINT("(II)", __VA_ARGS__); \
954 } while(0)
956 #define WARN(...) do { \
957 if(LogLevel >= LogWarning) \
958 AL_PRINT("(WW)", __VA_ARGS__); \
959 } while(0)
961 #define ERR(...) do { \
962 if(LogLevel >= LogError) \
963 AL_PRINT("(EE)", __VA_ARGS__); \
964 } while(0)
967 extern ALint RTPrioLevel;
970 extern ALuint CPUCapFlags;
971 enum {
972 CPU_CAP_SSE = 1<<0,
973 CPU_CAP_SSE2 = 1<<1,
974 CPU_CAP_SSE4_1 = 1<<2,
975 CPU_CAP_NEON = 1<<3,
978 void FillCPUCaps(ALuint capfilter);
980 FILE *OpenDataFile(const char *fname, const char *subdir);
982 /* Small hack to use a pointer-to-array type as a normal argument type.
983 * Shouldn't be used directly. */
984 typedef ALfloat ALfloatBUFFERSIZE[BUFFERSIZE];
987 #ifdef __cplusplus
989 #endif
991 #endif