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