Add a lockless ringbuffer
[openal-soft.git] / OpenAL32 / Include / alMain.h
blob9dcaa29bb298befd2fabd3c5cd5d6e13422a258a
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 #endif
47 #ifndef ALC_SOFT_midi_interface
48 #define ALC_SOFT_midi_interface 1
49 /* Global properties */
50 #define AL_MIDI_CLOCK_SOFT 0x9999
51 #define AL_MIDI_STATE_SOFT 0x9986
52 #define AL_MIDI_GAIN_SOFT 0x9998
53 #define AL_SOUNDFONTS_SIZE_SOFT 0x9995
54 #define AL_SOUNDFONTS_SOFT 0x9994
56 /* Soundfont properties */
57 #define AL_PRESETS_SIZE_SOFT 0x9993
58 #define AL_PRESETS_SOFT 0x9992
60 /* Preset properties */
61 #define AL_MIDI_PRESET_SOFT 0x9997
62 #define AL_MIDI_BANK_SOFT 0x9996
63 #define AL_FONTSOUNDS_SIZE_SOFT 0x9991
64 #define AL_FONTSOUNDS_SOFT 0x9990
66 /* Fontsound properties */
67 /* AL_BUFFER */
68 #define AL_SAMPLE_START_SOFT 0x2000
69 #define AL_SAMPLE_END_SOFT 0x2001
70 #define AL_SAMPLE_LOOP_START_SOFT 0x2002
71 #define AL_SAMPLE_LOOP_END_SOFT 0x2003
72 #define AL_SAMPLE_RATE_SOFT 0x2004
73 #define AL_BASE_KEY_SOFT 0x2005
74 #define AL_KEY_CORRECTION_SOFT 0x2006
75 #define AL_SAMPLE_TYPE_SOFT 0x2007
76 #define AL_FONTSOUND_LINK_SOFT 0x2008
77 #define AL_MOD_LFO_TO_PITCH_SOFT 0x0005
78 #define AL_VIBRATO_LFO_TO_PITCH_SOFT 0x0006
79 #define AL_MOD_ENV_TO_PITCH_SOFT 0x0007
80 #define AL_FILTER_CUTOFF_SOFT 0x0008
81 #define AL_FILTER_RESONANCE_SOFT 0x0009
82 #define AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT 0x000A
83 #define AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT 0x000B
84 #define AL_MOD_LFO_TO_VOLUME_SOFT 0x000D
85 #define AL_CHORUS_SEND_SOFT 0x000F
86 #define AL_REVERB_SEND_SOFT 0x0010
87 #define AL_PAN_SOFT 0x0011
88 #define AL_MOD_LFO_DELAY_SOFT 0x0015
89 #define AL_MOD_LFO_FREQUENCY_SOFT 0x0016
90 #define AL_VIBRATO_LFO_DELAY_SOFT 0x0017
91 #define AL_VIBRATO_LFO_FREQUENCY_SOFT 0x0018
92 #define AL_MOD_ENV_DELAYTIME_SOFT 0x0019
93 #define AL_MOD_ENV_ATTACKTIME_SOFT 0x001A
94 #define AL_MOD_ENV_HOLDTIME_SOFT 0x001B
95 #define AL_MOD_ENV_DECAYTIME_SOFT 0x001C
96 #define AL_MOD_ENV_SUSTAINVOLUME_SOFT 0x001D
97 #define AL_MOD_ENV_RELEASETIME_SOFT 0x002E
98 #define AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT 0x001F
99 #define AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT 0x0020
100 #define AL_VOLUME_ENV_DELAYTIME_SOFT 0x0021
101 #define AL_VOLUME_ENV_ATTACKTIME_SOFT 0x0022
102 #define AL_VOLUME_ENV_HOLDTIME_SOFT 0x0023
103 #define AL_VOLUME_ENV_DECAYTIME_SOFT 0x0024
104 #define AL_VOLUME_ENV_SUSTAINVOLUME_SOFT 0x0025
105 #define AL_VOLUME_ENV_RELEASETIME_SOFT 0x0026
106 #define AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT 0x0027
107 #define AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT 0x0028
108 #define AL_KEY_RANGE_SOFT 0x002B
109 #define AL_VELOCITY_RANGE_SOFT 0x002C
110 #define AL_ATTENUATION_SOFT 0x0030
111 #define AL_TUNING_COARSE_SOFT 0x0033
112 #define AL_TUNING_FINE_SOFT 0x0034
113 #define AL_LOOP_MODE_SOFT 0x0036
114 #define AL_TUNING_SCALE_SOFT 0x0038
115 #define AL_EXCLUSIVE_CLASS_SOFT 0x0039
117 /* Sample Types */
118 /* AL_MONO_SOFT */
119 #define AL_RIGHT_SOFT 0x0002
120 #define AL_LEFT_SOFT 0x0004
122 /* Loop Modes */
123 /* AL_NONE */
124 #define AL_LOOP_CONTINUOUS_SOFT 0x0001
125 #define AL_LOOP_UNTIL_RELEASE_SOFT 0x0003
127 /* Fontsound modulator stage properties */
128 #define AL_SOURCE0_INPUT_SOFT 0x998F
129 #define AL_SOURCE0_TYPE_SOFT 0x998E
130 #define AL_SOURCE0_FORM_SOFT 0x998D
131 #define AL_SOURCE1_INPUT_SOFT 0x998C
132 #define AL_SOURCE1_TYPE_SOFT 0x998B
133 #define AL_SOURCE1_FORM_SOFT 0x998A
134 #define AL_AMOUNT_SOFT 0x9989
135 #define AL_TRANSFORM_OP_SOFT 0x9988
136 #define AL_DESTINATION_SOFT 0x9987
138 /* Sounce Inputs */
139 #define AL_ONE_SOFT 0x0080
140 #define AL_NOTEON_VELOCITY_SOFT 0x0082
141 #define AL_NOTEON_KEY_SOFT 0x0083
142 /* AL_KEYPRESSURE_SOFT */
143 /* AL_CHANNELPRESSURE_SOFT */
144 /* AL_PITCHBEND_SOFT */
145 #define AL_PITCHBEND_SENSITIVITY_SOFT 0x0090
146 /* CC 0...127 */
148 /* Source Types */
149 #define AL_UNORM_SOFT 0x0000
150 #define AL_UNORM_REV_SOFT 0x0100
151 #define AL_SNORM_SOFT 0x0200
152 #define AL_SNORM_REV_SOFT 0x0300
154 /* Source Forms */
155 #define AL_LINEAR_SOFT 0x0000
156 #define AL_CONCAVE_SOFT 0x0400
157 #define AL_CONVEX_SOFT 0x0800
158 #define AL_SWITCH_SOFT 0x0C00
160 /* Transform Ops */
161 /* AL_LINEAR_SOFT */
162 #define AL_ABSOLUTE_SOFT 0x0002
164 /* Events */
165 #define AL_NOTEOFF_SOFT 0x0080
166 #define AL_NOTEON_SOFT 0x0090
167 #define AL_KEYPRESSURE_SOFT 0x00A0
168 #define AL_CONTROLLERCHANGE_SOFT 0x00B0
169 #define AL_PROGRAMCHANGE_SOFT 0x00C0
170 #define AL_CHANNELPRESSURE_SOFT 0x00D0
171 #define AL_PITCHBEND_SOFT 0x00E0
173 typedef void (AL_APIENTRY*LPALGENSOUNDFONTSSOFT)(ALsizei n, ALuint *ids);
174 typedef void (AL_APIENTRY*LPALDELETESOUNDFONTSSOFT)(ALsizei n, const ALuint *ids);
175 typedef ALboolean (AL_APIENTRY*LPALISSOUNDFONTSOFT)(ALuint id);
176 typedef void (AL_APIENTRY*LPALGETSOUNDFONTIVSOFT)(ALuint id, ALenum param, ALint *values);
177 typedef void (AL_APIENTRY*LPALSOUNDFONTPRESETSSOFT)(ALuint id, ALsizei count, const ALuint *pids);
178 typedef void (AL_APIENTRY*LPALGENPRESETSSOFT)(ALsizei n, ALuint *ids);
179 typedef void (AL_APIENTRY*LPALDELETEPRESETSSOFT)(ALsizei n, const ALuint *ids);
180 typedef ALboolean (AL_APIENTRY*LPALISPRESETSOFT)(ALuint id);
181 typedef void (AL_APIENTRY*LPALPRESETISOFT)(ALuint id, ALenum param, ALint value);
182 typedef void (AL_APIENTRY*LPALPRESETIVSOFT)(ALuint id, ALenum param, const ALint *values);
183 typedef void (AL_APIENTRY*LPALPRESETFONTSOUNDSSOFT)(ALuint id, ALsizei count, const ALuint *fsids);
184 typedef void (AL_APIENTRY*LPALGETPRESETIVSOFT)(ALuint id, ALenum param, ALint *values);
185 typedef void (AL_APIENTRY*LPALGENFONTSOUNDSSOFT)(ALsizei n, ALuint *ids);
186 typedef void (AL_APIENTRY*LPALDELETEFONTSOUNDSSOFT)(ALsizei n, const ALuint *ids);
187 typedef ALboolean (AL_APIENTRY*LPALISFONTSOUNDSOFT)(ALuint id);
188 typedef void (AL_APIENTRY*LPALFONTSOUNDISOFT)(ALuint id, ALenum param, ALint value);
189 typedef void (AL_APIENTRY*LPALFONTSOUND2ISOFT)(ALuint id, ALenum param, ALint value1, ALint value2);
190 typedef void (AL_APIENTRY*LPALFONTSOUNDIVSOFT)(ALuint id, ALenum param, const ALint *values);
191 typedef void (AL_APIENTRY*LPALGETFONTSOUNDIVSOFT)(ALuint id, ALenum param, ALint *values);
192 typedef void (AL_APIENTRY*LPALFONTSOUNDMOFULATORISOFT)(ALuint id, ALsizei stage, ALenum param, ALint value);
193 typedef void (AL_APIENTRY*LPALGETFONTSOUNDMODULATORIVSOFT)(ALuint id, ALsizei stage, ALenum param, ALint *values);
194 typedef void (AL_APIENTRY*LPALMIDISOUNDFONTSOFT)(ALuint id);
195 typedef void (AL_APIENTRY*LPALMIDISOUNDFONTVSOFT)(ALsizei count, const ALuint *ids);
196 typedef void (AL_APIENTRY*LPALMIDIEVENTSOFT)(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2);
197 typedef void (AL_APIENTRY*LPALMIDISYSEXSOFT)(ALuint64SOFT time, const ALbyte *data, ALsizei size);
198 typedef void (AL_APIENTRY*LPALMIDIPLAYSOFT)(void);
199 typedef void (AL_APIENTRY*LPALMIDIPAUSESOFT)(void);
200 typedef void (AL_APIENTRY*LPALMIDISTOPSOFT)(void);
201 typedef void (AL_APIENTRY*LPALMIDIRESETSOFT)(void);
202 typedef void (AL_APIENTRY*LPALMIDIGAINSOFT)(ALfloat value);
203 typedef ALint64SOFT (AL_APIENTRY*LPALGETINTEGER64SOFT)(ALenum pname);
204 typedef void (AL_APIENTRY*LPALGETINTEGER64VSOFT)(ALenum pname, ALint64SOFT *values);
205 typedef void (AL_APIENTRY*LPALLOADSOUNDFONTSOFT)(ALuint id, size_t(*cb)(ALvoid*,size_t,ALvoid*), ALvoid *user);
206 #ifdef AL_ALEXT_PROTOTYPES
207 AL_API void AL_APIENTRY alGenSoundfontsSOFT(ALsizei n, ALuint *ids);
208 AL_API void AL_APIENTRY alDeleteSoundfontsSOFT(ALsizei n, const ALuint *ids);
209 AL_API ALboolean AL_APIENTRY alIsSoundfontSOFT(ALuint id);
210 AL_API void AL_APIENTRY alGetSoundfontivSOFT(ALuint id, ALenum param, ALint *values);
211 AL_API void AL_APIENTRY alSoundfontPresetsSOFT(ALuint id, ALsizei count, const ALuint *pids);
213 AL_API void AL_APIENTRY alGenPresetsSOFT(ALsizei n, ALuint *ids);
214 AL_API void AL_APIENTRY alDeletePresetsSOFT(ALsizei n, const ALuint *ids);
215 AL_API ALboolean AL_APIENTRY alIsPresetSOFT(ALuint id);
216 AL_API void AL_APIENTRY alPresetiSOFT(ALuint id, ALenum param, ALint value);
217 AL_API void AL_APIENTRY alPresetivSOFT(ALuint id, ALenum param, const ALint *values);
218 AL_API void AL_APIENTRY alGetPresetivSOFT(ALuint id, ALenum param, ALint *values);
219 AL_API void AL_APIENTRY alPresetFontsoundsSOFT(ALuint id, ALsizei count, const ALuint *fsids);
221 AL_API void AL_APIENTRY alGenFontsoundsSOFT(ALsizei n, ALuint *ids);
222 AL_API void AL_APIENTRY alDeleteFontsoundsSOFT(ALsizei n, const ALuint *ids);
223 AL_API ALboolean AL_APIENTRY alIsFontsoundSOFT(ALuint id);
224 AL_API void AL_APIENTRY alFontsoundiSOFT(ALuint id, ALenum param, ALint value);
225 AL_API void AL_APIENTRY alFontsound2iSOFT(ALuint id, ALenum param, ALint value1, ALint value2);
226 AL_API void AL_APIENTRY alFontsoundivSOFT(ALuint id, ALenum param, const ALint *values);
227 AL_API void AL_APIENTRY alGetFontsoundivSOFT(ALuint id, ALenum param, ALint *values);
228 AL_API void AL_APIENTRY alFontsoundModulatoriSOFT(ALuint id, ALsizei stage, ALenum param, ALint value);
229 AL_API void AL_APIENTRY alGetFontsoundModulatorivSOFT(ALuint id, ALsizei stage, ALenum param, ALint *values);
231 AL_API void AL_APIENTRY alMidiSoundfontSOFT(ALuint id);
232 AL_API void AL_APIENTRY alMidiSoundfontvSOFT(ALsizei count, const ALuint *ids);
233 AL_API void AL_APIENTRY alMidiEventSOFT(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2);
234 AL_API void AL_APIENTRY alMidiSysExSOFT(ALuint64SOFT time, const ALbyte *data, ALsizei size);
235 AL_API void AL_APIENTRY alMidiPlaySOFT(void);
236 AL_API void AL_APIENTRY alMidiPauseSOFT(void);
237 AL_API void AL_APIENTRY alMidiStopSOFT(void);
238 AL_API void AL_APIENTRY alMidiResetSOFT(void);
239 AL_API void AL_APIENTRY alMidiGainSOFT(ALfloat value);
240 AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname);
241 AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values);
242 AL_API void AL_APIENTRY alLoadSoundfontSOFT(ALuint id, size_t(*cb)(ALvoid*,size_t,ALvoid*), ALvoid *user);
243 #endif
244 #endif
246 #ifndef ALC_SOFT_device_clock
247 #define ALC_SOFT_device_clock 1
248 typedef int64_t ALCint64SOFT;
249 typedef uint64_t ALCuint64SOFT;
250 #define ALC_DEVICE_CLOCK_SOFT 0x1600
251 typedef void (ALC_APIENTRY*LPALCGETINTEGER64VSOFT)(ALCdevice *device, ALCenum pname, ALsizei size, ALCint64SOFT *values);
252 #ifdef AL_ALEXT_PROTOTYPES
253 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALsizei size, ALCint64SOFT *values);
254 #endif
255 #endif
258 #ifdef IN_IDE_PARSER
259 /* KDevelop's parser doesn't recognize the C99-standard restrict keyword, but
260 * recent versions (at least 4.5.1) do recognize GCC's __restrict. */
261 #define restrict __restrict
262 #endif
265 typedef ALint64SOFT ALint64;
266 typedef ALuint64SOFT ALuint64;
268 #ifndef U64
269 #if defined(_MSC_VER)
270 #define U64(x) ((ALuint64)(x##ui64))
271 #elif SIZEOF_LONG == 8
272 #define U64(x) ((ALuint64)(x##ul))
273 #elif SIZEOF_LONG_LONG == 8
274 #define U64(x) ((ALuint64)(x##ull))
275 #endif
276 #endif
278 #ifndef UINT64_MAX
279 #define UINT64_MAX U64(18446744073709551615)
280 #endif
282 #ifndef UNUSED
283 #if defined(__cplusplus)
284 #define UNUSED(x)
285 #elif defined(__GNUC__)
286 #define UNUSED(x) UNUSED_##x __attribute__((unused))
287 #elif defined(__LCLINT__)
288 #define UNUSED(x) /*@unused@*/ x
289 #else
290 #define UNUSED(x) x
291 #endif
292 #endif
294 #ifdef __GNUC__
295 #define DECL_CONST __attribute__((const))
296 #define DECL_FORMAT(x, y, z) __attribute__((format(x, (y), (z))))
297 #else
298 #define DECL_CONST
299 #define DECL_FORMAT(x, y, z)
300 #endif
302 #if defined(__GNUC__) && defined(__i386__)
303 /* force_align_arg_pointer is required for proper function arguments aligning
304 * when SSE code is used. Some systems (Windows, QNX) do not guarantee our
305 * thread functions will be properly aligned on the stack, even though GCC may
306 * generate code with the assumption that it is. */
307 #define FORCE_ALIGN __attribute__((force_align_arg_pointer))
308 #else
309 #define FORCE_ALIGN
310 #endif
312 #ifdef HAVE_C99_VLA
313 #define DECL_VLA(T, _name, _size) T _name[(_size)]
314 #else
315 #define DECL_VLA(T, _name, _size) T *_name = alloca((_size) * sizeof(T))
316 #endif
318 #ifndef PATH_MAX
319 #ifdef MAX_PATH
320 #define PATH_MAX MAX_PATH
321 #else
322 #define PATH_MAX 4096
323 #endif
324 #endif
327 static const union {
328 ALuint u;
329 ALubyte b[sizeof(ALuint)];
330 } EndianTest = { 1 };
331 #define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1)
333 #define COUNTOF(x) (sizeof((x))/sizeof((x)[0]))
336 #define DERIVE_FROM_TYPE(t) t t##_parent
337 #define STATIC_CAST(to, obj) (&(obj)->to##_parent)
338 #ifdef __GNUC__
339 #define STATIC_UPCAST(to, from, obj) __extension__({ \
340 static_assert(__builtin_types_compatible_p(from, __typeof(*(obj))), \
341 "Invalid upcast object from type"); \
342 (to*)((char*)(obj) - offsetof(to, from##_parent)); \
344 #else
345 #define STATIC_UPCAST(to, from, obj) ((to*)((char*)(obj) - offsetof(to, from##_parent)))
346 #endif
348 #define DECLARE_FORWARD(T1, T2, rettype, func) \
349 rettype T1##_##func(T1 *obj) \
350 { return T2##_##func(STATIC_CAST(T2, obj)); }
352 #define DECLARE_FORWARD1(T1, T2, rettype, func, argtype1) \
353 rettype T1##_##func(T1 *obj, argtype1 a) \
354 { return T2##_##func(STATIC_CAST(T2, obj), a); }
356 #define DECLARE_FORWARD2(T1, T2, rettype, func, argtype1, argtype2) \
357 rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b) \
358 { return T2##_##func(STATIC_CAST(T2, obj), a, b); }
360 #define DECLARE_FORWARD3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
361 rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b, argtype3 c) \
362 { return T2##_##func(STATIC_CAST(T2, obj), a, b, c); }
365 #define GET_VTABLE1(T1) (&(T1##_vtable))
366 #define GET_VTABLE2(T1, T2) (&(T1##_##T2##_vtable))
368 #define SET_VTABLE1(T1, obj) ((obj)->vtbl = GET_VTABLE1(T1))
369 #define SET_VTABLE2(T1, T2, obj) (STATIC_CAST(T2, obj)->vtbl = GET_VTABLE2(T1, T2))
371 #define DECLARE_THUNK(T1, T2, rettype, func) \
372 static rettype T1##_##T2##_##func(T2 *obj) \
373 { return T1##_##func(STATIC_UPCAST(T1, T2, obj)); }
375 #define DECLARE_THUNK1(T1, T2, rettype, func, argtype1) \
376 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a) \
377 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a); }
379 #define DECLARE_THUNK2(T1, T2, rettype, func, argtype1, argtype2) \
380 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b) \
381 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b); }
383 #define DECLARE_THUNK3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
384 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c) \
385 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c); }
387 #define DECLARE_THUNK4(T1, T2, rettype, func, argtype1, argtype2, argtype3, argtype4) \
388 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c, argtype4 d) \
389 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c, d); }
391 #define DECLARE_DEFAULT_ALLOCATORS(T) \
392 static void* T##_New(size_t size) { return al_malloc(16, size); } \
393 static void T##_Delete(void *ptr) { al_free(ptr); }
395 /* Helper to extract an argument list for VCALL. Not used directly. */
396 #define EXTRACT_VCALL_ARGS(...) __VA_ARGS__))
398 /* Call a "virtual" method on an object, with arguments. */
399 #define V(obj, func) ((obj)->vtbl->func((obj), EXTRACT_VCALL_ARGS
400 /* Call a "virtual" method on an object, with no arguments. */
401 #define V0(obj, func) ((obj)->vtbl->func((obj) EXTRACT_VCALL_ARGS
403 #define DELETE_OBJ(obj) do { \
404 if((obj) != NULL) \
406 V0((obj),Destruct)(); \
407 V0((obj),Delete)(); \
409 } while(0)
412 #ifdef __cplusplus
413 extern "C" {
414 #endif
416 struct Hrtf;
419 #define DEFAULT_OUTPUT_RATE (44100)
420 #define MIN_OUTPUT_RATE (8000)
423 /* Find the next power-of-2 for non-power-of-2 numbers. */
424 inline ALuint NextPowerOf2(ALuint value)
426 if(value > 0)
428 value--;
429 value |= value>>1;
430 value |= value>>2;
431 value |= value>>4;
432 value |= value>>8;
433 value |= value>>16;
435 return value+1;
438 /* Fast float-to-int conversion. Assumes the FPU is already in round-to-zero
439 * mode. */
440 inline ALint fastf2i(ALfloat f)
442 #ifdef HAVE_LRINTF
443 return lrintf(f);
444 #elif defined(_MSC_VER) && defined(_M_IX86)
445 ALint i;
446 __asm fld f
447 __asm fistp i
448 return i;
449 #else
450 return (ALint)f;
451 #endif
454 /* Fast float-to-uint conversion. Assumes the FPU is already in round-to-zero
455 * mode. */
456 inline ALuint fastf2u(ALfloat f)
457 { return fastf2i(f); }
460 enum DevProbe {
461 ALL_DEVICE_PROBE,
462 CAPTURE_DEVICE_PROBE
465 typedef struct {
466 ALCenum (*OpenPlayback)(ALCdevice*, const ALCchar*);
467 void (*ClosePlayback)(ALCdevice*);
468 ALCboolean (*ResetPlayback)(ALCdevice*);
469 ALCboolean (*StartPlayback)(ALCdevice*);
470 void (*StopPlayback)(ALCdevice*);
472 ALCenum (*OpenCapture)(ALCdevice*, const ALCchar*);
473 void (*CloseCapture)(ALCdevice*);
474 void (*StartCapture)(ALCdevice*);
475 void (*StopCapture)(ALCdevice*);
476 ALCenum (*CaptureSamples)(ALCdevice*, void*, ALCuint);
477 ALCuint (*AvailableSamples)(ALCdevice*);
478 } BackendFuncs;
480 ALCboolean alc_solaris_init(BackendFuncs *func_list);
481 void alc_solaris_deinit(void);
482 void alc_solaris_probe(enum DevProbe type);
483 ALCboolean alc_sndio_init(BackendFuncs *func_list);
484 void alc_sndio_deinit(void);
485 void alc_sndio_probe(enum DevProbe type);
486 ALCboolean alc_pa_init(BackendFuncs *func_list);
487 void alc_pa_deinit(void);
488 void alc_pa_probe(enum DevProbe type);
489 ALCboolean alc_ca_init(BackendFuncs *func_list);
490 void alc_ca_deinit(void);
491 void alc_ca_probe(enum DevProbe type);
492 ALCboolean alc_opensl_init(BackendFuncs *func_list);
493 void alc_opensl_deinit(void);
494 void alc_opensl_probe(enum DevProbe type);
495 ALCboolean alc_qsa_init(BackendFuncs *func_list);
496 void alc_qsa_deinit(void);
497 void alc_qsa_probe(enum DevProbe type);
499 struct ALCbackend;
502 enum DistanceModel {
503 InverseDistanceClamped = AL_INVERSE_DISTANCE_CLAMPED,
504 LinearDistanceClamped = AL_LINEAR_DISTANCE_CLAMPED,
505 ExponentDistanceClamped = AL_EXPONENT_DISTANCE_CLAMPED,
506 InverseDistance = AL_INVERSE_DISTANCE,
507 LinearDistance = AL_LINEAR_DISTANCE,
508 ExponentDistance = AL_EXPONENT_DISTANCE,
509 DisableDistance = AL_NONE,
511 DefaultDistanceModel = InverseDistanceClamped
514 enum Resampler {
515 PointResampler,
516 LinearResampler,
517 CubicResampler,
519 ResamplerMax,
522 enum Channel {
523 FrontLeft = 0,
524 FrontRight,
525 FrontCenter,
526 LFE,
527 BackLeft,
528 BackRight,
529 BackCenter,
530 SideLeft,
531 SideRight,
533 TopFrontLeft,
534 TopFrontRight,
535 TopBackLeft,
536 TopBackRight,
537 BottomFrontLeft,
538 BottomFrontRight,
539 BottomBackLeft,
540 BottomBackRight,
542 Aux0,
543 Aux1,
544 Aux2,
545 Aux3,
547 InvalidChannel
551 /* Device formats */
552 enum DevFmtType {
553 DevFmtByte = ALC_BYTE_SOFT,
554 DevFmtUByte = ALC_UNSIGNED_BYTE_SOFT,
555 DevFmtShort = ALC_SHORT_SOFT,
556 DevFmtUShort = ALC_UNSIGNED_SHORT_SOFT,
557 DevFmtInt = ALC_INT_SOFT,
558 DevFmtUInt = ALC_UNSIGNED_INT_SOFT,
559 DevFmtFloat = ALC_FLOAT_SOFT,
561 DevFmtTypeDefault = DevFmtFloat
563 enum DevFmtChannels {
564 DevFmtMono = ALC_MONO_SOFT,
565 DevFmtStereo = ALC_STEREO_SOFT,
566 DevFmtQuad = ALC_QUAD_SOFT,
567 DevFmtX51 = ALC_5POINT1_SOFT,
568 DevFmtX61 = ALC_6POINT1_SOFT,
569 DevFmtX71 = ALC_7POINT1_SOFT,
571 /* Similar to 5.1, except using rear channels instead of sides */
572 DevFmtX51Rear = 0x80000000,
574 DevFmtBFormat3D,
576 DevFmtChannelsDefault = DevFmtStereo
578 #define MAX_OUTPUT_CHANNELS (8)
580 ALuint BytesFromDevFmt(enum DevFmtType type) DECL_CONST;
581 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans) DECL_CONST;
582 inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type)
584 return ChannelsFromDevFmt(chans) * BytesFromDevFmt(type);
588 extern const struct EffectList {
589 const char *name;
590 int type;
591 const char *ename;
592 ALenum val;
593 } EffectList[];
596 enum DeviceType {
597 Playback,
598 Capture,
599 Loopback
603 /* The maximum number of Ambisonics coefficients. For a given order (o), the
604 * size needed will be (o+1)**2, thus zero-order has 1, first-order has 4,
605 * second-order has 9, and third-order has 16. */
606 #define MAX_AMBI_COEFFS 16
608 typedef struct ChannelConfig {
609 ALfloat HOACoeff[MAX_AMBI_COEFFS];
610 ALfloat FOACoeff[4];
611 } ChannelConfig;
614 #define HRTF_HISTORY_BITS (6)
615 #define HRTF_HISTORY_LENGTH (1<<HRTF_HISTORY_BITS)
616 #define HRTF_HISTORY_MASK (HRTF_HISTORY_LENGTH-1)
618 typedef struct HrtfState {
619 alignas(16) ALfloat History[HRTF_HISTORY_LENGTH];
620 alignas(16) ALfloat Values[HRIR_LENGTH][2];
621 } HrtfState;
623 typedef struct HrtfParams {
624 alignas(16) ALfloat Coeffs[HRIR_LENGTH][2];
625 alignas(16) ALfloat CoeffStep[HRIR_LENGTH][2];
626 ALuint Delay[2];
627 ALint DelayStep[2];
628 } HrtfParams;
631 /* Size for temporary storage of buffer data, in ALfloats. Larger values need
632 * more memory, while smaller values may need more iterations. The value needs
633 * to be a sensible size, however, as it constrains the max stepping value used
634 * for mixing, as well as the maximum number of samples per mixing iteration.
636 #define BUFFERSIZE (2048u)
638 struct ALCdevice_struct
640 RefCount ref;
642 ALCboolean Connected;
643 enum DeviceType Type;
645 ALuint Frequency;
646 ALuint UpdateSize;
647 ALuint NumUpdates;
648 enum DevFmtChannels FmtChans;
649 enum DevFmtType FmtType;
650 ALboolean IsHeadphones;
652 al_string DeviceName;
654 ATOMIC(ALCenum) LastError;
656 // Maximum number of sources that can be created
657 ALuint MaxNoOfSources;
658 // Maximum number of slots that can be created
659 ALuint AuxiliaryEffectSlotMax;
661 ALCuint NumMonoSources;
662 ALCuint NumStereoSources;
663 ALuint NumAuxSends;
665 // Map of Buffers for this device
666 UIntMap BufferMap;
668 // Map of Effects for this device
669 UIntMap EffectMap;
671 // Map of Filters for this device
672 UIntMap FilterMap;
674 // Map of Soundfonts for this device
675 UIntMap SfontMap;
677 // Map of Presets for this device
678 UIntMap PresetMap;
680 // Map of Fontsounds for this device
681 UIntMap FontsoundMap;
683 /* Default soundfont (accessible as ID 0) */
684 struct ALsoundfont *DefaultSfont;
686 /* MIDI synth engine */
687 struct MidiSynth *Synth;
689 /* HRTF filter tables */
690 const struct Hrtf *Hrtf;
691 HrtfState Hrtf_State[MAX_OUTPUT_CHANNELS];
692 HrtfParams Hrtf_Params[MAX_OUTPUT_CHANNELS];
693 ALuint Hrtf_Offset;
695 // Stereo-to-binaural filter
696 struct bs2b *Bs2b;
698 // Device flags
699 ALuint Flags;
701 enum Channel ChannelName[MAX_OUTPUT_CHANNELS];
702 ChannelConfig Channel[MAX_OUTPUT_CHANNELS];
703 ALuint NumChannels;
705 ALuint64 ClockBase;
706 ALuint SamplesDone;
708 /* Temp storage used for each source when mixing. */
709 alignas(16) ALfloat SourceData[BUFFERSIZE];
710 alignas(16) ALfloat ResampledData[BUFFERSIZE];
711 alignas(16) ALfloat FilteredData[BUFFERSIZE];
713 // Dry path buffer mix
714 alignas(16) ALfloat (*DryBuffer)[BUFFERSIZE];
716 /* Running count of the mixer invocations, in 31.1 fixed point. This
717 * actually increments *twice* when mixing, first at the start and then at
718 * the end, so the bottom bit indicates if the device is currently mixing
719 * and the upper bits indicates how many mixes have been done.
721 RefCount MixCount;
723 /* Default effect slot */
724 struct ALeffectslot *DefaultSlot;
726 // Contexts created on this device
727 ATOMIC(ALCcontext*) ContextList;
729 struct ALCbackend *Backend;
731 void *ExtraData; // For the backend's use
733 ALCdevice *volatile next;
735 /* Memory space used by the default slot (Playback devices only) */
736 alignas(16) ALCbyte _slot_mem[];
739 // Frequency was requested by the app or config file
740 #define DEVICE_FREQUENCY_REQUEST (1<<1)
741 // Channel configuration was requested by the config file
742 #define DEVICE_CHANNELS_REQUEST (1<<2)
743 // Sample type was requested by the config file
744 #define DEVICE_SAMPLE_TYPE_REQUEST (1<<3)
745 // HRTF was requested by the app
746 #define DEVICE_HRTF_REQUEST (1<<4)
748 // Specifies if the DSP is paused at user request
749 #define DEVICE_PAUSED (1<<30)
751 // Specifies if the device is currently running
752 #define DEVICE_RUNNING (1<<31)
755 /* Nanosecond resolution for the device clock time. */
756 #define DEVICE_CLOCK_RES U64(1000000000)
759 /* Must be less than 15 characters (16 including terminating null) for
760 * compatibility with pthread_setname_np limitations. */
761 #define MIXER_THREAD_NAME "alsoft-mixer"
763 #define RECORD_THREAD_NAME "alsoft-record"
766 struct ALCcontext_struct
768 RefCount ref;
770 struct ALlistener *Listener;
772 UIntMap SourceMap;
773 UIntMap EffectSlotMap;
775 ATOMIC(ALenum) LastError;
777 ATOMIC(ALenum) UpdateSources;
779 volatile enum DistanceModel DistanceModel;
780 volatile ALboolean SourceDistanceModel;
782 volatile ALfloat DopplerFactor;
783 volatile ALfloat DopplerVelocity;
784 volatile ALfloat SpeedOfSound;
785 volatile ALenum DeferUpdates;
787 struct ALvoice *Voices;
788 ALsizei VoiceCount;
789 ALsizei MaxVoices;
791 VECTOR(struct ALeffectslot*) ActiveAuxSlots;
793 ALCdevice *Device;
794 const ALCchar *ExtensionList;
796 ALCcontext *volatile next;
798 /* Memory space used by the listener */
799 alignas(16) ALCbyte _listener_mem[];
802 ALCcontext *GetContextRef(void);
804 void ALCcontext_IncRef(ALCcontext *context);
805 void ALCcontext_DecRef(ALCcontext *context);
807 void AppendAllDevicesList(const ALCchar *name);
808 void AppendCaptureDeviceList(const ALCchar *name);
810 void ALCdevice_Lock(ALCdevice *device);
811 void ALCdevice_Unlock(ALCdevice *device);
812 ALint64 ALCdevice_GetLatency(ALCdevice *device);
814 void ALCcontext_DeferUpdates(ALCcontext *context);
815 void ALCcontext_ProcessUpdates(ALCcontext *context);
817 inline void LockContext(ALCcontext *context)
818 { ALCdevice_Lock(context->Device); }
820 inline void UnlockContext(ALCcontext *context)
821 { ALCdevice_Unlock(context->Device); }
824 void *al_malloc(size_t alignment, size_t size);
825 void *al_calloc(size_t alignment, size_t size);
826 void al_free(void *ptr);
829 typedef struct {
830 #ifdef HAVE_FENV_H
831 DERIVE_FROM_TYPE(fenv_t);
832 #else
833 int state;
834 #endif
835 #ifdef HAVE_SSE
836 int sse_state;
837 #endif
838 } FPUCtl;
839 void SetMixerFPUMode(FPUCtl *ctl);
840 void RestoreFPUMode(const FPUCtl *ctl);
843 typedef struct RingBuffer RingBuffer;
844 RingBuffer *CreateRingBuffer(ALsizei frame_size, ALsizei length);
845 void DestroyRingBuffer(RingBuffer *ring);
846 ALsizei RingBufferSize(RingBuffer *ring);
847 void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len);
848 void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len);
850 typedef struct ll_ringbuffer ll_ringbuffer_t;
851 typedef struct ll_ringbuffer_data {
852 char *buf;
853 size_t len;
854 } ll_ringbuffer_data_t;
855 ll_ringbuffer_t *ll_ringbuffer_create(size_t sz, size_t elem_sz);
856 void ll_ringbuffer_free(ll_ringbuffer_t *rb);
857 void ll_ringbuffer_get_read_vector(const ll_ringbuffer_t *rb, ll_ringbuffer_data_t *vec);
858 void ll_ringbuffer_get_write_vector(const ll_ringbuffer_t *rb, ll_ringbuffer_data_t *vec);
859 size_t ll_ringbuffer_read(ll_ringbuffer_t *rb, char *dest, size_t cnt);
860 size_t ll_ringbuffer_peek(ll_ringbuffer_t *rb, char *dest, size_t cnt);
861 void ll_ringbuffer_read_advance(ll_ringbuffer_t *rb, size_t cnt);
862 size_t ll_ringbuffer_read_space(const ll_ringbuffer_t *rb);
863 int ll_ringbuffer_mlock(ll_ringbuffer_t *rb);
864 void ll_ringbuffer_reset(ll_ringbuffer_t *rb);
865 size_t ll_ringbuffer_write(ll_ringbuffer_t *rb, const char *src, size_t cnt);
866 void ll_ringbuffer_write_advance(ll_ringbuffer_t *rb, size_t cnt);
867 size_t ll_ringbuffer_write_space(const ll_ringbuffer_t *rb);
869 void ReadALConfig(void);
870 void FreeALConfig(void);
871 int ConfigValueExists(const char *blockName, const char *keyName);
872 const char *GetConfigValue(const char *blockName, const char *keyName, const char *def);
873 int GetConfigValueBool(const char *blockName, const char *keyName, int def);
874 int ConfigValueStr(const char *blockName, const char *keyName, const char **ret);
875 int ConfigValueInt(const char *blockName, const char *keyName, int *ret);
876 int ConfigValueUInt(const char *blockName, const char *keyName, unsigned int *ret);
877 int ConfigValueFloat(const char *blockName, const char *keyName, float *ret);
878 int ConfigValueBool(const char *blockName, const char *keyName, int *ret);
880 void SetRTPriority(void);
882 void SetDefaultChannelOrder(ALCdevice *device);
883 void SetDefaultWFXChannelOrder(ALCdevice *device);
885 const ALCchar *DevFmtTypeString(enum DevFmtType type) DECL_CONST;
886 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans) DECL_CONST;
889 * GetChannelIdxByName
891 * Returns the device's channel index given a channel name (e.g. FrontCenter),
892 * or -1 if it doesn't exist.
894 inline ALint GetChannelIdxByName(const ALCdevice *device, enum Channel chan)
896 ALint i = 0;
897 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
899 if(device->ChannelName[i] == chan)
900 return i;
902 return -1;
906 extern FILE *LogFile;
908 #if defined(__GNUC__) && !defined(_WIN32) && !defined(IN_IDE_PARSER)
909 #define AL_PRINT(T, MSG, ...) fprintf(LogFile, "AL lib: %s %s: "MSG, T, __FUNCTION__ , ## __VA_ARGS__)
910 #else
911 void al_print(const char *type, const char *func, const char *fmt, ...) DECL_FORMAT(printf, 3,4);
912 #define AL_PRINT(T, ...) al_print((T), __FUNCTION__, __VA_ARGS__)
913 #endif
915 enum LogLevel {
916 NoLog,
917 LogError,
918 LogWarning,
919 LogTrace,
920 LogRef
922 extern enum LogLevel LogLevel;
924 #define TRACEREF(...) do { \
925 if(LogLevel >= LogRef) \
926 AL_PRINT("(--)", __VA_ARGS__); \
927 } while(0)
929 #define TRACE(...) do { \
930 if(LogLevel >= LogTrace) \
931 AL_PRINT("(II)", __VA_ARGS__); \
932 } while(0)
934 #define WARN(...) do { \
935 if(LogLevel >= LogWarning) \
936 AL_PRINT("(WW)", __VA_ARGS__); \
937 } while(0)
939 #define ERR(...) do { \
940 if(LogLevel >= LogError) \
941 AL_PRINT("(EE)", __VA_ARGS__); \
942 } while(0)
945 extern ALint RTPrioLevel;
948 extern ALuint CPUCapFlags;
949 enum {
950 CPU_CAP_SSE = 1<<0,
951 CPU_CAP_SSE2 = 1<<1,
952 CPU_CAP_SSE4_1 = 1<<2,
953 CPU_CAP_NEON = 1<<3,
956 void FillCPUCaps(ALuint capfilter);
958 FILE *OpenDataFile(const char *fname, const char *subdir);
960 /* Small hack to use a pointer-to-array type as a normal argument type.
961 * Shouldn't be used directly. */
962 typedef ALfloat ALfloatBUFFERSIZE[BUFFERSIZE];
965 #ifdef __cplusplus
967 #endif
969 #endif