Use an ambisonics-based panning method
[openal-soft.git] / OpenAL32 / Include / alMain.h
bloba658227b7662876fae9611c367dd14ef99c96445
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 #ifndef ALC_SOFT_HRTF
41 #define ALC_SOFT_HRTF 1
42 #define ALC_HRTF_SOFT 0x1992
43 #endif
45 #ifndef ALC_SOFT_midi_interface
46 #define ALC_SOFT_midi_interface 1
47 /* Global properties */
48 #define AL_MIDI_CLOCK_SOFT 0x9999
49 #define AL_MIDI_STATE_SOFT 0x9986
50 #define AL_MIDI_GAIN_SOFT 0x9998
51 #define AL_SOUNDFONTS_SIZE_SOFT 0x9995
52 #define AL_SOUNDFONTS_SOFT 0x9994
54 /* Soundfont properties */
55 #define AL_PRESETS_SIZE_SOFT 0x9993
56 #define AL_PRESETS_SOFT 0x9992
58 /* Preset properties */
59 #define AL_MIDI_PRESET_SOFT 0x9997
60 #define AL_MIDI_BANK_SOFT 0x9996
61 #define AL_FONTSOUNDS_SIZE_SOFT 0x9991
62 #define AL_FONTSOUNDS_SOFT 0x9990
64 /* Fontsound properties */
65 /* AL_BUFFER */
66 #define AL_SAMPLE_START_SOFT 0x2000
67 #define AL_SAMPLE_END_SOFT 0x2001
68 #define AL_SAMPLE_LOOP_START_SOFT 0x2002
69 #define AL_SAMPLE_LOOP_END_SOFT 0x2003
70 #define AL_SAMPLE_RATE_SOFT 0x2004
71 #define AL_BASE_KEY_SOFT 0x2005
72 #define AL_KEY_CORRECTION_SOFT 0x2006
73 #define AL_SAMPLE_TYPE_SOFT 0x2007
74 #define AL_FONTSOUND_LINK_SOFT 0x2008
75 #define AL_MOD_LFO_TO_PITCH_SOFT 0x0005
76 #define AL_VIBRATO_LFO_TO_PITCH_SOFT 0x0006
77 #define AL_MOD_ENV_TO_PITCH_SOFT 0x0007
78 #define AL_FILTER_CUTOFF_SOFT 0x0008
79 #define AL_FILTER_RESONANCE_SOFT 0x0009
80 #define AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT 0x000A
81 #define AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT 0x000B
82 #define AL_MOD_LFO_TO_VOLUME_SOFT 0x000D
83 #define AL_CHORUS_SEND_SOFT 0x000F
84 #define AL_REVERB_SEND_SOFT 0x0010
85 #define AL_PAN_SOFT 0x0011
86 #define AL_MOD_LFO_DELAY_SOFT 0x0015
87 #define AL_MOD_LFO_FREQUENCY_SOFT 0x0016
88 #define AL_VIBRATO_LFO_DELAY_SOFT 0x0017
89 #define AL_VIBRATO_LFO_FREQUENCY_SOFT 0x0018
90 #define AL_MOD_ENV_DELAYTIME_SOFT 0x0019
91 #define AL_MOD_ENV_ATTACKTIME_SOFT 0x001A
92 #define AL_MOD_ENV_HOLDTIME_SOFT 0x001B
93 #define AL_MOD_ENV_DECAYTIME_SOFT 0x001C
94 #define AL_MOD_ENV_SUSTAINVOLUME_SOFT 0x001D
95 #define AL_MOD_ENV_RELEASETIME_SOFT 0x002E
96 #define AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT 0x001F
97 #define AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT 0x0020
98 #define AL_VOLUME_ENV_DELAYTIME_SOFT 0x0021
99 #define AL_VOLUME_ENV_ATTACKTIME_SOFT 0x0022
100 #define AL_VOLUME_ENV_HOLDTIME_SOFT 0x0023
101 #define AL_VOLUME_ENV_DECAYTIME_SOFT 0x0024
102 #define AL_VOLUME_ENV_SUSTAINVOLUME_SOFT 0x0025
103 #define AL_VOLUME_ENV_RELEASETIME_SOFT 0x0026
104 #define AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT 0x0027
105 #define AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT 0x0028
106 #define AL_KEY_RANGE_SOFT 0x002B
107 #define AL_VELOCITY_RANGE_SOFT 0x002C
108 #define AL_ATTENUATION_SOFT 0x0030
109 #define AL_TUNING_COARSE_SOFT 0x0033
110 #define AL_TUNING_FINE_SOFT 0x0034
111 #define AL_LOOP_MODE_SOFT 0x0036
112 #define AL_TUNING_SCALE_SOFT 0x0038
113 #define AL_EXCLUSIVE_CLASS_SOFT 0x0039
115 /* Sample Types */
116 /* AL_MONO_SOFT */
117 #define AL_RIGHT_SOFT 0x0002
118 #define AL_LEFT_SOFT 0x0004
120 /* Loop Modes */
121 /* AL_NONE */
122 #define AL_LOOP_CONTINUOUS_SOFT 0x0001
123 #define AL_LOOP_UNTIL_RELEASE_SOFT 0x0003
125 /* Fontsound modulator stage properties */
126 #define AL_SOURCE0_INPUT_SOFT 0x998F
127 #define AL_SOURCE0_TYPE_SOFT 0x998E
128 #define AL_SOURCE0_FORM_SOFT 0x998D
129 #define AL_SOURCE1_INPUT_SOFT 0x998C
130 #define AL_SOURCE1_TYPE_SOFT 0x998B
131 #define AL_SOURCE1_FORM_SOFT 0x998A
132 #define AL_AMOUNT_SOFT 0x9989
133 #define AL_TRANSFORM_OP_SOFT 0x9988
134 #define AL_DESTINATION_SOFT 0x9987
136 /* Sounce Inputs */
137 #define AL_ONE_SOFT 0x0080
138 #define AL_NOTEON_VELOCITY_SOFT 0x0082
139 #define AL_NOTEON_KEY_SOFT 0x0083
140 /* AL_KEYPRESSURE_SOFT */
141 /* AL_CHANNELPRESSURE_SOFT */
142 /* AL_PITCHBEND_SOFT */
143 #define AL_PITCHBEND_SENSITIVITY_SOFT 0x0090
144 /* CC 0...127 */
146 /* Source Types */
147 #define AL_UNORM_SOFT 0x0000
148 #define AL_UNORM_REV_SOFT 0x0100
149 #define AL_SNORM_SOFT 0x0200
150 #define AL_SNORM_REV_SOFT 0x0300
152 /* Source Forms */
153 #define AL_LINEAR_SOFT 0x0000
154 #define AL_CONCAVE_SOFT 0x0400
155 #define AL_CONVEX_SOFT 0x0800
156 #define AL_SWITCH_SOFT 0x0C00
158 /* Transform Ops */
159 /* AL_LINEAR_SOFT */
160 #define AL_ABSOLUTE_SOFT 0x0002
162 /* Events */
163 #define AL_NOTEOFF_SOFT 0x0080
164 #define AL_NOTEON_SOFT 0x0090
165 #define AL_KEYPRESSURE_SOFT 0x00A0
166 #define AL_CONTROLLERCHANGE_SOFT 0x00B0
167 #define AL_PROGRAMCHANGE_SOFT 0x00C0
168 #define AL_CHANNELPRESSURE_SOFT 0x00D0
169 #define AL_PITCHBEND_SOFT 0x00E0
171 typedef void (AL_APIENTRY*LPALGENSOUNDFONTSSOFT)(ALsizei n, ALuint *ids);
172 typedef void (AL_APIENTRY*LPALDELETESOUNDFONTSSOFT)(ALsizei n, const ALuint *ids);
173 typedef ALboolean (AL_APIENTRY*LPALISSOUNDFONTSOFT)(ALuint id);
174 typedef void (AL_APIENTRY*LPALGETSOUNDFONTIVSOFT)(ALuint id, ALenum param, ALint *values);
175 typedef void (AL_APIENTRY*LPALSOUNDFONTPRESETSSOFT)(ALuint id, ALsizei count, const ALuint *pids);
176 typedef void (AL_APIENTRY*LPALGENPRESETSSOFT)(ALsizei n, ALuint *ids);
177 typedef void (AL_APIENTRY*LPALDELETEPRESETSSOFT)(ALsizei n, const ALuint *ids);
178 typedef ALboolean (AL_APIENTRY*LPALISPRESETSOFT)(ALuint id);
179 typedef void (AL_APIENTRY*LPALPRESETISOFT)(ALuint id, ALenum param, ALint value);
180 typedef void (AL_APIENTRY*LPALPRESETIVSOFT)(ALuint id, ALenum param, const ALint *values);
181 typedef void (AL_APIENTRY*LPALPRESETFONTSOUNDSSOFT)(ALuint id, ALsizei count, const ALuint *fsids);
182 typedef void (AL_APIENTRY*LPALGETPRESETIVSOFT)(ALuint id, ALenum param, ALint *values);
183 typedef void (AL_APIENTRY*LPALGENFONTSOUNDSSOFT)(ALsizei n, ALuint *ids);
184 typedef void (AL_APIENTRY*LPALDELETEFONTSOUNDSSOFT)(ALsizei n, const ALuint *ids);
185 typedef ALboolean (AL_APIENTRY*LPALISFONTSOUNDSOFT)(ALuint id);
186 typedef void (AL_APIENTRY*LPALFONTSOUNDISOFT)(ALuint id, ALenum param, ALint value);
187 typedef void (AL_APIENTRY*LPALFONTSOUND2ISOFT)(ALuint id, ALenum param, ALint value1, ALint value2);
188 typedef void (AL_APIENTRY*LPALFONTSOUNDIVSOFT)(ALuint id, ALenum param, const ALint *values);
189 typedef void (AL_APIENTRY*LPALGETFONTSOUNDIVSOFT)(ALuint id, ALenum param, ALint *values);
190 typedef void (AL_APIENTRY*LPALFONTSOUNDMOFULATORISOFT)(ALuint id, ALsizei stage, ALenum param, ALint value);
191 typedef void (AL_APIENTRY*LPALGETFONTSOUNDMODULATORIVSOFT)(ALuint id, ALsizei stage, ALenum param, ALint *values);
192 typedef void (AL_APIENTRY*LPALMIDISOUNDFONTSOFT)(ALuint id);
193 typedef void (AL_APIENTRY*LPALMIDISOUNDFONTVSOFT)(ALsizei count, const ALuint *ids);
194 typedef void (AL_APIENTRY*LPALMIDIEVENTSOFT)(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2);
195 typedef void (AL_APIENTRY*LPALMIDISYSEXSOFT)(ALuint64SOFT time, const ALbyte *data, ALsizei size);
196 typedef void (AL_APIENTRY*LPALMIDIPLAYSOFT)(void);
197 typedef void (AL_APIENTRY*LPALMIDIPAUSESOFT)(void);
198 typedef void (AL_APIENTRY*LPALMIDISTOPSOFT)(void);
199 typedef void (AL_APIENTRY*LPALMIDIRESETSOFT)(void);
200 typedef void (AL_APIENTRY*LPALMIDIGAINSOFT)(ALfloat value);
201 typedef ALint64SOFT (AL_APIENTRY*LPALGETINTEGER64SOFT)(ALenum pname);
202 typedef void (AL_APIENTRY*LPALGETINTEGER64VSOFT)(ALenum pname, ALint64SOFT *values);
203 typedef void (AL_APIENTRY*LPALLOADSOUNDFONTSOFT)(ALuint id, size_t(*cb)(ALvoid*,size_t,ALvoid*), ALvoid *user);
204 #ifdef AL_ALEXT_PROTOTYPES
205 AL_API void AL_APIENTRY alGenSoundfontsSOFT(ALsizei n, ALuint *ids);
206 AL_API void AL_APIENTRY alDeleteSoundfontsSOFT(ALsizei n, const ALuint *ids);
207 AL_API ALboolean AL_APIENTRY alIsSoundfontSOFT(ALuint id);
208 AL_API void AL_APIENTRY alGetSoundfontivSOFT(ALuint id, ALenum param, ALint *values);
209 AL_API void AL_APIENTRY alSoundfontPresetsSOFT(ALuint id, ALsizei count, const ALuint *pids);
211 AL_API void AL_APIENTRY alGenPresetsSOFT(ALsizei n, ALuint *ids);
212 AL_API void AL_APIENTRY alDeletePresetsSOFT(ALsizei n, const ALuint *ids);
213 AL_API ALboolean AL_APIENTRY alIsPresetSOFT(ALuint id);
214 AL_API void AL_APIENTRY alPresetiSOFT(ALuint id, ALenum param, ALint value);
215 AL_API void AL_APIENTRY alPresetivSOFT(ALuint id, ALenum param, const ALint *values);
216 AL_API void AL_APIENTRY alGetPresetivSOFT(ALuint id, ALenum param, ALint *values);
217 AL_API void AL_APIENTRY alPresetFontsoundsSOFT(ALuint id, ALsizei count, const ALuint *fsids);
219 AL_API void AL_APIENTRY alGenFontsoundsSOFT(ALsizei n, ALuint *ids);
220 AL_API void AL_APIENTRY alDeleteFontsoundsSOFT(ALsizei n, const ALuint *ids);
221 AL_API ALboolean AL_APIENTRY alIsFontsoundSOFT(ALuint id);
222 AL_API void AL_APIENTRY alFontsoundiSOFT(ALuint id, ALenum param, ALint value);
223 AL_API void AL_APIENTRY alFontsound2iSOFT(ALuint id, ALenum param, ALint value1, ALint value2);
224 AL_API void AL_APIENTRY alFontsoundivSOFT(ALuint id, ALenum param, const ALint *values);
225 AL_API void AL_APIENTRY alGetFontsoundivSOFT(ALuint id, ALenum param, ALint *values);
226 AL_API void AL_APIENTRY alFontsoundModulatoriSOFT(ALuint id, ALsizei stage, ALenum param, ALint value);
227 AL_API void AL_APIENTRY alGetFontsoundModulatorivSOFT(ALuint id, ALsizei stage, ALenum param, ALint *values);
229 AL_API void AL_APIENTRY alMidiSoundfontSOFT(ALuint id);
230 AL_API void AL_APIENTRY alMidiSoundfontvSOFT(ALsizei count, const ALuint *ids);
231 AL_API void AL_APIENTRY alMidiEventSOFT(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2);
232 AL_API void AL_APIENTRY alMidiSysExSOFT(ALuint64SOFT time, const ALbyte *data, ALsizei size);
233 AL_API void AL_APIENTRY alMidiPlaySOFT(void);
234 AL_API void AL_APIENTRY alMidiPauseSOFT(void);
235 AL_API void AL_APIENTRY alMidiStopSOFT(void);
236 AL_API void AL_APIENTRY alMidiResetSOFT(void);
237 AL_API void AL_APIENTRY alMidiGainSOFT(ALfloat value);
238 AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname);
239 AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values);
240 AL_API void AL_APIENTRY alLoadSoundfontSOFT(ALuint id, size_t(*cb)(ALvoid*,size_t,ALvoid*), ALvoid *user);
241 #endif
242 #endif
244 #ifndef ALC_SOFT_device_clock
245 #define ALC_SOFT_device_clock 1
246 typedef int64_t ALCint64SOFT;
247 typedef uint64_t ALCuint64SOFT;
248 #define ALC_DEVICE_CLOCK_SOFT 0x1600
249 typedef void (ALC_APIENTRY*LPALCGETINTEGER64VSOFT)(ALCdevice *device, ALCenum pname, ALsizei size, ALCint64SOFT *values);
250 #ifdef AL_ALEXT_PROTOTYPES
251 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALsizei size, ALCint64SOFT *values);
252 #endif
253 #endif
256 #ifdef IN_IDE_PARSER
257 /* KDevelop's parser doesn't recognize the C99-standard restrict keyword, but
258 * recent versions (at least 4.5.1) do recognize GCC's __restrict. */
259 #define restrict __restrict
260 #endif
263 typedef ALint64SOFT ALint64;
264 typedef ALuint64SOFT ALuint64;
266 #ifndef U64
267 #if defined(_MSC_VER)
268 #define U64(x) ((ALuint64)(x##ui64))
269 #elif SIZEOF_LONG == 8
270 #define U64(x) ((ALuint64)(x##ul))
271 #elif SIZEOF_LONG_LONG == 8
272 #define U64(x) ((ALuint64)(x##ull))
273 #endif
274 #endif
276 #ifndef UINT64_MAX
277 #define UINT64_MAX U64(18446744073709551615)
278 #endif
280 #ifndef UNUSED
281 #if defined(__cplusplus)
282 #define UNUSED(x)
283 #elif defined(__GNUC__)
284 #define UNUSED(x) UNUSED_##x __attribute__((unused))
285 #elif defined(__LCLINT__)
286 #define UNUSED(x) /*@unused@*/ x
287 #else
288 #define UNUSED(x) x
289 #endif
290 #endif
292 #ifdef __GNUC__
293 #define DECL_CONST __attribute__((const))
294 #define DECL_FORMAT(x, y, z) __attribute__((format(x, (y), (z))))
295 #else
296 #define DECL_CONST
297 #define DECL_FORMAT(x, y, z)
298 #endif
300 #if defined(__GNUC__) && defined(__i386__)
301 /* force_align_arg_pointer is required for proper function arguments aligning
302 * when SSE code is used. Some systems (Windows, QNX) do not guarantee our
303 * thread functions will be properly aligned on the stack, even though GCC may
304 * generate code with the assumption that it is. */
305 #define FORCE_ALIGN __attribute__((force_align_arg_pointer))
306 #else
307 #define FORCE_ALIGN
308 #endif
310 #ifdef HAVE_C99_VLA
311 #define DECL_VLA(T, _name, _size) T _name[(_size)]
312 #else
313 #define DECL_VLA(T, _name, _size) T *_name = alloca((_size) * sizeof(T))
314 #endif
316 #ifndef PATH_MAX
317 #ifdef MAX_PATH
318 #define PATH_MAX MAX_PATH
319 #else
320 #define PATH_MAX 4096
321 #endif
322 #endif
325 static const union {
326 ALuint u;
327 ALubyte b[sizeof(ALuint)];
328 } EndianTest = { 1 };
329 #define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1)
331 #define COUNTOF(x) (sizeof((x))/sizeof((x)[0]))
334 #define DERIVE_FROM_TYPE(t) t t##_parent
335 #define STATIC_CAST(to, obj) (&(obj)->to##_parent)
336 #ifdef __GNUC__
337 #define STATIC_UPCAST(to, from, obj) __extension__({ \
338 static_assert(__builtin_types_compatible_p(from, __typeof(*(obj))), \
339 "Invalid upcast object from type"); \
340 (to*)((char*)(obj) - offsetof(to, from##_parent)); \
342 #else
343 #define STATIC_UPCAST(to, from, obj) ((to*)((char*)(obj) - offsetof(to, from##_parent)))
344 #endif
346 #define DECLARE_FORWARD(T1, T2, rettype, func) \
347 rettype T1##_##func(T1 *obj) \
348 { return T2##_##func(STATIC_CAST(T2, obj)); }
350 #define DECLARE_FORWARD1(T1, T2, rettype, func, argtype1) \
351 rettype T1##_##func(T1 *obj, argtype1 a) \
352 { return T2##_##func(STATIC_CAST(T2, obj), a); }
354 #define DECLARE_FORWARD2(T1, T2, rettype, func, argtype1, argtype2) \
355 rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b) \
356 { return T2##_##func(STATIC_CAST(T2, obj), a, b); }
358 #define DECLARE_FORWARD3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
359 rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b, argtype3 c) \
360 { return T2##_##func(STATIC_CAST(T2, obj), a, b, c); }
363 #define GET_VTABLE1(T1) (&(T1##_vtable))
364 #define GET_VTABLE2(T1, T2) (&(T1##_##T2##_vtable))
366 #define SET_VTABLE1(T1, obj) ((obj)->vtbl = GET_VTABLE1(T1))
367 #define SET_VTABLE2(T1, T2, obj) (STATIC_CAST(T2, obj)->vtbl = GET_VTABLE2(T1, T2))
369 #define DECLARE_THUNK(T1, T2, rettype, func) \
370 static rettype T1##_##T2##_##func(T2 *obj) \
371 { return T1##_##func(STATIC_UPCAST(T1, T2, obj)); }
373 #define DECLARE_THUNK1(T1, T2, rettype, func, argtype1) \
374 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a) \
375 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a); }
377 #define DECLARE_THUNK2(T1, T2, rettype, func, argtype1, argtype2) \
378 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b) \
379 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b); }
381 #define DECLARE_THUNK3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
382 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c) \
383 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c); }
385 #define DECLARE_DEFAULT_ALLOCATORS(T) \
386 static void* T##_New(size_t size) { return al_malloc(16, size); } \
387 static void T##_Delete(void *ptr) { al_free(ptr); }
389 /* Helper to extract an argument list for VCALL. Not used directly. */
390 #define EXTRACT_VCALL_ARGS(...) __VA_ARGS__))
392 /* Call a "virtual" method on an object, with arguments. */
393 #define V(obj, func) ((obj)->vtbl->func((obj), EXTRACT_VCALL_ARGS
394 /* Call a "virtual" method on an object, with no arguments. */
395 #define V0(obj, func) ((obj)->vtbl->func((obj) EXTRACT_VCALL_ARGS
397 #define DELETE_OBJ(obj) do { \
398 if((obj) != NULL) \
400 V0((obj),Destruct)(); \
401 V0((obj),Delete)(); \
403 } while(0)
406 #ifdef __cplusplus
407 extern "C" {
408 #endif
410 struct Hrtf;
413 #define DEFAULT_OUTPUT_RATE (44100)
414 #define MIN_OUTPUT_RATE (8000)
417 /* Find the next power-of-2 for non-power-of-2 numbers. */
418 inline ALuint NextPowerOf2(ALuint value)
420 if(value > 0)
422 value--;
423 value |= value>>1;
424 value |= value>>2;
425 value |= value>>4;
426 value |= value>>8;
427 value |= value>>16;
429 return value+1;
432 /* Fast float-to-int conversion. Assumes the FPU is already in round-to-zero
433 * mode. */
434 inline ALint fastf2i(ALfloat f)
436 #ifdef HAVE_LRINTF
437 return lrintf(f);
438 #elif defined(_MSC_VER) && defined(_M_IX86)
439 ALint i;
440 __asm fld f
441 __asm fistp i
442 return i;
443 #else
444 return (ALint)f;
445 #endif
448 /* Fast float-to-uint conversion. Assumes the FPU is already in round-to-zero
449 * mode. */
450 inline ALuint fastf2u(ALfloat f)
451 { return fastf2i(f); }
454 enum DevProbe {
455 ALL_DEVICE_PROBE,
456 CAPTURE_DEVICE_PROBE
459 typedef struct {
460 ALCenum (*OpenPlayback)(ALCdevice*, const ALCchar*);
461 void (*ClosePlayback)(ALCdevice*);
462 ALCboolean (*ResetPlayback)(ALCdevice*);
463 ALCboolean (*StartPlayback)(ALCdevice*);
464 void (*StopPlayback)(ALCdevice*);
466 ALCenum (*OpenCapture)(ALCdevice*, const ALCchar*);
467 void (*CloseCapture)(ALCdevice*);
468 void (*StartCapture)(ALCdevice*);
469 void (*StopCapture)(ALCdevice*);
470 ALCenum (*CaptureSamples)(ALCdevice*, void*, ALCuint);
471 ALCuint (*AvailableSamples)(ALCdevice*);
472 } BackendFuncs;
474 ALCboolean alc_solaris_init(BackendFuncs *func_list);
475 void alc_solaris_deinit(void);
476 void alc_solaris_probe(enum DevProbe type);
477 ALCboolean alc_sndio_init(BackendFuncs *func_list);
478 void alc_sndio_deinit(void);
479 void alc_sndio_probe(enum DevProbe type);
480 ALCboolean alc_pa_init(BackendFuncs *func_list);
481 void alc_pa_deinit(void);
482 void alc_pa_probe(enum DevProbe type);
483 ALCboolean alc_ca_init(BackendFuncs *func_list);
484 void alc_ca_deinit(void);
485 void alc_ca_probe(enum DevProbe type);
486 ALCboolean alc_opensl_init(BackendFuncs *func_list);
487 void alc_opensl_deinit(void);
488 void alc_opensl_probe(enum DevProbe type);
489 ALCboolean alc_qsa_init(BackendFuncs *func_list);
490 void alc_qsa_deinit(void);
491 void alc_qsa_probe(enum DevProbe type);
493 struct ALCbackend;
496 enum DistanceModel {
497 InverseDistanceClamped = AL_INVERSE_DISTANCE_CLAMPED,
498 LinearDistanceClamped = AL_LINEAR_DISTANCE_CLAMPED,
499 ExponentDistanceClamped = AL_EXPONENT_DISTANCE_CLAMPED,
500 InverseDistance = AL_INVERSE_DISTANCE,
501 LinearDistance = AL_LINEAR_DISTANCE,
502 ExponentDistance = AL_EXPONENT_DISTANCE,
503 DisableDistance = AL_NONE,
505 DefaultDistanceModel = InverseDistanceClamped
508 enum Resampler {
509 PointResampler,
510 LinearResampler,
511 CubicResampler,
513 ResamplerMax,
516 enum Channel {
517 FrontLeft = 0,
518 FrontRight,
519 FrontCenter,
520 LFE,
521 BackLeft,
522 BackRight,
523 BackCenter,
524 SideLeft,
525 SideRight,
527 MaxChannels,
528 InvalidChannel = MaxChannels
532 /* Device formats */
533 enum DevFmtType {
534 DevFmtByte = ALC_BYTE_SOFT,
535 DevFmtUByte = ALC_UNSIGNED_BYTE_SOFT,
536 DevFmtShort = ALC_SHORT_SOFT,
537 DevFmtUShort = ALC_UNSIGNED_SHORT_SOFT,
538 DevFmtInt = ALC_INT_SOFT,
539 DevFmtUInt = ALC_UNSIGNED_INT_SOFT,
540 DevFmtFloat = ALC_FLOAT_SOFT,
542 DevFmtTypeDefault = DevFmtFloat
544 enum DevFmtChannels {
545 DevFmtMono = ALC_MONO_SOFT,
546 DevFmtStereo = ALC_STEREO_SOFT,
547 DevFmtQuad = ALC_QUAD_SOFT,
548 DevFmtX51 = ALC_5POINT1_SOFT,
549 DevFmtX61 = ALC_6POINT1_SOFT,
550 DevFmtX71 = ALC_7POINT1_SOFT,
552 /* Similar to 5.1, except using the side channels instead of back */
553 DevFmtX51Side = 0x80000000,
555 DevFmtChannelsDefault = DevFmtStereo
558 ALuint BytesFromDevFmt(enum DevFmtType type) DECL_CONST;
559 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans) DECL_CONST;
560 inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type)
562 return ChannelsFromDevFmt(chans) * BytesFromDevFmt(type);
566 extern const struct EffectList {
567 const char *name;
568 int type;
569 const char *ename;
570 ALenum val;
571 } EffectList[];
574 enum DeviceType {
575 Playback,
576 Capture,
577 Loopback
581 /* Size for temporary storage of buffer data, in ALfloats. Larger values need
582 * more memory, while smaller values may need more iterations. The value needs
583 * to be a sensible size, however, as it constrains the max stepping value used
584 * for mixing, as well as the maximum number of samples per mixing iteration.
586 #define BUFFERSIZE (2048u)
588 /* The maximum number of Ambisonics coefficients. For a given order (o), the
589 * size needed will be (o+1)**2, thus zero-order has 1, first-order has 4,
590 * second-order has 9, and third-order has 16. */
591 #define MAX_AMBI_COEFFS 16
593 struct ALCdevice_struct
595 RefCount ref;
597 ALCboolean Connected;
598 enum DeviceType Type;
600 ALuint Frequency;
601 ALuint UpdateSize;
602 ALuint NumUpdates;
603 enum DevFmtChannels FmtChans;
604 enum DevFmtType FmtType;
606 al_string DeviceName;
608 ATOMIC(ALCenum) LastError;
610 // Maximum number of sources that can be created
611 ALuint MaxNoOfSources;
612 // Maximum number of slots that can be created
613 ALuint AuxiliaryEffectSlotMax;
615 ALCuint NumMonoSources;
616 ALCuint NumStereoSources;
617 ALuint NumAuxSends;
619 // Map of Buffers for this device
620 UIntMap BufferMap;
622 // Map of Effects for this device
623 UIntMap EffectMap;
625 // Map of Filters for this device
626 UIntMap FilterMap;
628 // Map of Soundfonts for this device
629 UIntMap SfontMap;
631 // Map of Presets for this device
632 UIntMap PresetMap;
634 // Map of Fontsounds for this device
635 UIntMap FontsoundMap;
637 /* Default soundfont (accessible as ID 0) */
638 struct ALsoundfont *DefaultSfont;
640 /* MIDI synth engine */
641 struct MidiSynth *Synth;
643 /* HRTF filter tables */
644 const struct Hrtf *Hrtf;
646 // Stereo-to-binaural filter
647 struct bs2b *Bs2b;
648 ALCint Bs2bLevel;
650 // Device flags
651 ALuint Flags;
653 enum Channel ChannelName[MaxChannels];
655 /* This only counts positional speakers, i.e. not including LFE. */
656 struct {
657 enum Channel ChanName;
658 ALfloat Angle;
659 ALfloat Coeff[MAX_AMBI_COEFFS];
660 } Speaker[MaxChannels];
661 ALuint NumSpeakers;
663 ALuint64 ClockBase;
664 ALuint SamplesDone;
666 /* Temp storage used for each source when mixing. */
667 alignas(16) ALfloat SourceData[BUFFERSIZE];
668 alignas(16) ALfloat ResampledData[BUFFERSIZE];
669 alignas(16) ALfloat FilteredData[BUFFERSIZE];
671 // Dry path buffer mix
672 alignas(16) ALfloat DryBuffer[MaxChannels][BUFFERSIZE];
674 /* Running count of the mixer invocations, in 31.1 fixed point. This
675 * actually increments *twice* when mixing, first at the start and then at
676 * the end, so the bottom bit indicates if the device is currently mixing
677 * and the upper bits indicates how many mixes have been done.
679 RefCount MixCount;
681 /* Default effect slot */
682 struct ALeffectslot *DefaultSlot;
684 // Contexts created on this device
685 ATOMIC(ALCcontext*) ContextList;
687 struct ALCbackend *Backend;
689 void *ExtraData; // For the backend's use
691 ALCdevice *volatile next;
693 /* Memory space used by the default slot (Playback devices only) */
694 alignas(16) ALCbyte _slot_mem[];
697 // Frequency was requested by the app or config file
698 #define DEVICE_FREQUENCY_REQUEST (1<<1)
699 // Channel configuration was requested by the config file
700 #define DEVICE_CHANNELS_REQUEST (1<<2)
701 // Sample type was requested by the config file
702 #define DEVICE_SAMPLE_TYPE_REQUEST (1<<3)
703 // HRTF was requested by the app
704 #define DEVICE_HRTF_REQUEST (1<<4)
706 // Stereo sources cover 120-degree angles around +/-90
707 #define DEVICE_WIDE_STEREO (1<<16)
709 // Specifies if the DSP is paused at user request
710 #define DEVICE_PAUSED (1<<30)
712 // Specifies if the device is currently running
713 #define DEVICE_RUNNING (1<<31)
715 /* Invalid channel offset */
716 #define INVALID_OFFSET (~0u)
719 /* Nanosecond resolution for the device clock time. */
720 #define DEVICE_CLOCK_RES U64(1000000000)
723 /* Must be less than 15 characters (16 including terminating null) for
724 * compatibility with pthread_setname_np limitations. */
725 #define MIXER_THREAD_NAME "alsoft-mixer"
728 struct ALCcontext_struct
730 RefCount ref;
732 struct ALlistener *Listener;
734 UIntMap SourceMap;
735 UIntMap EffectSlotMap;
737 ATOMIC(ALenum) LastError;
739 ATOMIC(ALenum) UpdateSources;
741 volatile enum DistanceModel DistanceModel;
742 volatile ALboolean SourceDistanceModel;
744 volatile ALfloat DopplerFactor;
745 volatile ALfloat DopplerVelocity;
746 volatile ALfloat SpeedOfSound;
747 volatile ALenum DeferUpdates;
749 struct ALvoice *Voices;
750 ALsizei VoiceCount;
751 ALsizei MaxVoices;
753 VECTOR(struct ALeffectslot*) ActiveAuxSlots;
755 ALCdevice *Device;
756 const ALCchar *ExtensionList;
758 ALCcontext *volatile next;
760 /* Memory space used by the listener */
761 alignas(16) ALCbyte _listener_mem[];
764 ALCcontext *GetContextRef(void);
766 void ALCcontext_IncRef(ALCcontext *context);
767 void ALCcontext_DecRef(ALCcontext *context);
769 void AppendAllDevicesList(const ALCchar *name);
770 void AppendCaptureDeviceList(const ALCchar *name);
772 void ALCdevice_Lock(ALCdevice *device);
773 void ALCdevice_Unlock(ALCdevice *device);
774 ALint64 ALCdevice_GetLatency(ALCdevice *device);
776 inline void LockContext(ALCcontext *context)
777 { ALCdevice_Lock(context->Device); }
779 inline void UnlockContext(ALCcontext *context)
780 { ALCdevice_Unlock(context->Device); }
783 void *al_malloc(size_t alignment, size_t size);
784 void *al_calloc(size_t alignment, size_t size);
785 void al_free(void *ptr);
788 typedef struct {
789 #ifdef HAVE_FENV_H
790 DERIVE_FROM_TYPE(fenv_t);
791 #else
792 int state;
793 #endif
794 #ifdef HAVE_SSE
795 int sse_state;
796 #endif
797 } FPUCtl;
798 void SetMixerFPUMode(FPUCtl *ctl);
799 void RestoreFPUMode(const FPUCtl *ctl);
802 typedef struct RingBuffer RingBuffer;
803 RingBuffer *CreateRingBuffer(ALsizei frame_size, ALsizei length);
804 void DestroyRingBuffer(RingBuffer *ring);
805 ALsizei RingBufferSize(RingBuffer *ring);
806 void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len);
807 void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len);
809 void ReadALConfig(void);
810 void FreeALConfig(void);
811 int ConfigValueExists(const char *blockName, const char *keyName);
812 const char *GetConfigValue(const char *blockName, const char *keyName, const char *def);
813 int GetConfigValueBool(const char *blockName, const char *keyName, int def);
814 int ConfigValueStr(const char *blockName, const char *keyName, const char **ret);
815 int ConfigValueInt(const char *blockName, const char *keyName, int *ret);
816 int ConfigValueUInt(const char *blockName, const char *keyName, unsigned int *ret);
817 int ConfigValueFloat(const char *blockName, const char *keyName, float *ret);
819 void SetRTPriority(void);
821 void SetDefaultChannelOrder(ALCdevice *device);
822 void SetDefaultWFXChannelOrder(ALCdevice *device);
824 const ALCchar *DevFmtTypeString(enum DevFmtType type) DECL_CONST;
825 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans) DECL_CONST;
828 extern FILE *LogFile;
830 #if defined(__GNUC__) && !defined(IN_IDE_PARSER)
831 #define AL_PRINT(T, MSG, ...) fprintf(LogFile, "AL lib: %s %s: "MSG, T, __FUNCTION__ , ## __VA_ARGS__)
832 #else
833 void al_print(const char *type, const char *func, const char *fmt, ...) DECL_FORMAT(printf, 3,4);
834 #define AL_PRINT(T, ...) al_print((T), __FUNCTION__, __VA_ARGS__)
835 #endif
837 enum LogLevel {
838 NoLog,
839 LogError,
840 LogWarning,
841 LogTrace,
842 LogRef
844 extern enum LogLevel LogLevel;
846 #define TRACEREF(...) do { \
847 if(LogLevel >= LogRef) \
848 AL_PRINT("(--)", __VA_ARGS__); \
849 } while(0)
851 #define TRACE(...) do { \
852 if(LogLevel >= LogTrace) \
853 AL_PRINT("(II)", __VA_ARGS__); \
854 } while(0)
856 #define WARN(...) do { \
857 if(LogLevel >= LogWarning) \
858 AL_PRINT("(WW)", __VA_ARGS__); \
859 } while(0)
861 #define ERR(...) do { \
862 if(LogLevel >= LogError) \
863 AL_PRINT("(EE)", __VA_ARGS__); \
864 } while(0)
867 extern ALint RTPrioLevel;
870 extern ALuint CPUCapFlags;
871 enum {
872 CPU_CAP_SSE = 1<<0,
873 CPU_CAP_SSE2 = 1<<1,
874 CPU_CAP_SSE4_1 = 1<<2,
875 CPU_CAP_NEON = 1<<3,
878 void FillCPUCaps(ALuint capfilter);
880 FILE *OpenDataFile(const char *fname, const char *subdir);
882 /* Small hack to use a pointer-to-array type as a normal argument type.
883 * Shouldn't be used directly. */
884 typedef ALfloat ALfloatBUFFERSIZE[BUFFERSIZE];
887 #ifdef __cplusplus
889 #endif
891 #endif