Add SSE2 and SSE4.1 linear resamplers
[openal-soft.git] / OpenAL32 / Include / alMain.h
blob232c438c2c06470b6471ccf5f689044cbf74fc19
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 #define AL_MIDI_CLOCK_SOFT 0x9999
48 #define AL_MIDI_STATE_SOFT 0x9986
49 #define AL_MIDI_GAIN_SOFT 0x9998
50 #define AL_MIDI_PRESET_SOFT 0x9997
51 #define AL_MIDI_BANK_SOFT 0x9996
52 #define AL_SOUNDFONTS_SIZE_SOFT 0x9995
53 #define AL_SOUNDFONTS_SOFT 0x9994
54 #define AL_PRESETS_SIZE_SOFT 0x9993
55 #define AL_PRESETS_SOFT 0x9992
56 #define AL_FONTSOUNDS_SIZE_SOFT 0x9991
57 #define AL_FONTSOUNDS_SOFT 0x9990
59 #define AL_SOURCE0_INPUT_SOFT 0x998F
60 #define AL_SOURCE0_TYPE_SOFT 0x998E
61 #define AL_SOURCE0_FORM_SOFT 0x998D
62 #define AL_SOURCE1_INPUT_SOFT 0x998C
63 #define AL_SOURCE1_TYPE_SOFT 0x998B
64 #define AL_SOURCE1_FORM_SOFT 0x998A
65 #define AL_AMOUNT_SOFT 0x9989
66 #define AL_TRANSFORM_OP_SOFT 0x9988
67 #define AL_DESTINATION_SOFT 0x9987
69 /* Sounce Input */
70 #define AL_ONE_SOFT 0x0080
71 #define AL_NOTEON_VELOCITY_SOFT 0x0082
72 #define AL_NOTEON_KEY_SOFT 0x0083
73 /* AL_KEYPRESSURE_SOFT */
74 /* AL_CHANNELPRESSURE_SOFT */
75 /* AL_PITCHBEND_SOFT */
76 #define AL_PITCHBEND_SENSITIVITY_SOFT 0x0090
77 /* CC 0...127 */
79 /* Source Type */
80 #define AL_UNORM_SOFT 0x0000
81 #define AL_UNORM_REV_SOFT 0x0100
82 #define AL_SNORM_SOFT 0x0200
83 #define AL_SNORM_REV_SOFT 0x0300
85 /* Source Form */
86 #define AL_LINEAR_SOFT 0x0000
87 #define AL_CONCAVE_SOFT 0x0400
88 #define AL_CONVEX_SOFT 0x0800
89 #define AL_SWITCH_SOFT 0x0C00
91 /* Transform op */
92 /* AL_LINEAR_SOFT */
93 #define AL_ABSOLUTE_SOFT 0x0002
95 #define AL_SAMPLE_START_SOFT 0x2000
96 #define AL_SAMPLE_END_SOFT 0x2001
97 #define AL_SAMPLE_LOOP_START_SOFT 0x2002
98 #define AL_SAMPLE_LOOP_END_SOFT 0x2003
99 #define AL_SAMPLE_RATE_SOFT 0x2004
100 #define AL_BASE_KEY_SOFT 0x2005
101 #define AL_KEY_CORRECTION_SOFT 0x2006
102 #define AL_SAMPLE_TYPE_SOFT 0x2007
103 #define AL_FONTSOUND_LINK_SOFT 0x2008
104 #define AL_MOD_LFO_TO_PITCH_SOFT 0x0005
105 #define AL_VIBRATO_LFO_TO_PITCH_SOFT 0x0006
106 #define AL_MOD_ENV_TO_PITCH_SOFT 0x0007
107 #define AL_FILTER_CUTOFF_SOFT 0x0008
108 #define AL_FILTER_RESONANCE_SOFT 0x0009
109 #define AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT 0x000A
110 #define AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT 0x000B
111 #define AL_MOD_LFO_TO_VOLUME_SOFT 0x000D
112 #define AL_CHORUS_SEND_SOFT 0x000F
113 #define AL_REVERB_SEND_SOFT 0x0010
114 #define AL_PAN_SOFT 0x0011
115 #define AL_MOD_LFO_DELAY_SOFT 0x0015
116 #define AL_MOD_LFO_FREQUENCY_SOFT 0x0016
117 #define AL_VIBRATO_LFO_DELAY_SOFT 0x0017
118 #define AL_VIBRATO_LFO_FREQUENCY_SOFT 0x0018
119 #define AL_MOD_ENV_DELAYTIME_SOFT 0x0019
120 #define AL_MOD_ENV_ATTACKTIME_SOFT 0x001A
121 #define AL_MOD_ENV_HOLDTIME_SOFT 0x001B
122 #define AL_MOD_ENV_DECAYTIME_SOFT 0x001C
123 #define AL_MOD_ENV_SUSTAINVOLUME_SOFT 0x001D
124 #define AL_MOD_ENV_RELEASETIME_SOFT 0x002E
125 #define AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT 0x001F
126 #define AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT 0x0020
127 #define AL_VOLUME_ENV_DELAYTIME_SOFT 0x0021
128 #define AL_VOLUME_ENV_ATTACKTIME_SOFT 0x0022
129 #define AL_VOLUME_ENV_HOLDTIME_SOFT 0x0023
130 #define AL_VOLUME_ENV_DECAYTIME_SOFT 0x0024
131 #define AL_VOLUME_ENV_SUSTAINVOLUME_SOFT 0x0025
132 #define AL_VOLUME_ENV_RELEASETIME_SOFT 0x0026
133 #define AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT 0x0027
134 #define AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT 0x0028
135 #define AL_KEY_RANGE_SOFT 0x002B
136 #define AL_VELOCITY_RANGE_SOFT 0x002C
137 #define AL_ATTENUATION_SOFT 0x0030
138 #define AL_TUNING_COARSE_SOFT 0x0033
139 #define AL_TUNING_FINE_SOFT 0x0034
140 #define AL_LOOP_MODE_SOFT 0x0036
141 #define AL_TUNING_SCALE_SOFT 0x0038
142 #define AL_EXCLUSIVE_CLASS_SOFT 0x0039
143 #define AL_LOOP_CONTINUOUS_SOFT 0x0001
144 #define AL_LOOP_UNTIL_RELEASE_SOFT 0x0003
145 #define AL_RIGHT_SOFT 0x0002
146 #define AL_LEFT_SOFT 0x0004
147 #define AL_FORMAT_TYPE_SOFT 0x1991
148 #define AL_NOTEOFF_SOFT 0x0080
149 #define AL_NOTEON_SOFT 0x0090
150 #define AL_KEYPRESSURE_SOFT 0x00A0
151 #define AL_CONTROLLERCHANGE_SOFT 0x00B0
152 #define AL_PROGRAMCHANGE_SOFT 0x00C0
153 #define AL_CHANNELPRESSURE_SOFT 0x00D0
154 #define AL_PITCHBEND_SOFT 0x00E0
155 typedef void (AL_APIENTRY*LPALGENSOUNDFONTSSOFT)(ALsizei n, ALuint *ids);
156 typedef void (AL_APIENTRY*LPALDELETESOUNDFONTSSOFT)(ALsizei n, const ALuint *ids);
157 typedef ALboolean (AL_APIENTRY*LPALISSOUNDFONTSOFT)(ALuint id);
158 typedef void (AL_APIENTRY*LPALSOUNDFONTSAMPLESSOFT)(ALuint sfid, ALenum type, ALsizei count, const ALvoid *samples);
159 typedef void (AL_APIENTRY*LPALGETSOUNDFONTSAMPLESSOFT)(ALuint id, ALsizei offset, ALsizei count, ALenum type, ALvoid *samples);
160 typedef ALvoid* (AL_APIENTRY*LPALSOUNDFONTMAPSAMPLESSOFT)(ALuint sfid, ALsizei offset, ALsizei length);
161 typedef void (AL_APIENTRY*LPALSOUNDFONTUNMAPSAMPLESSOFT)(ALuint sfid);
162 typedef void (AL_APIENTRY*LPALGETSOUNDFONTIVSOFT)(ALuint id, ALenum param, ALint *values);
163 typedef void (AL_APIENTRY*LPALSOUNDFONTPRESETSSOFT)(ALuint id, ALsizei count, const ALuint *pids);
164 typedef void (AL_APIENTRY*LPALGENPRESETSSOFT)(ALsizei n, ALuint *ids);
165 typedef void (AL_APIENTRY*LPALDELETEPRESETSSOFT)(ALsizei n, const ALuint *ids);
166 typedef ALboolean (AL_APIENTRY*LPALISPRESETSOFT)(ALuint id);
167 typedef void (AL_APIENTRY*LPALPRESETISOFT)(ALuint id, ALenum param, ALint value);
168 typedef void (AL_APIENTRY*LPALPRESETIVSOFT)(ALuint id, ALenum param, const ALint *values);
169 typedef void (AL_APIENTRY*LPALPRESETFONTSOUNDSSOFT)(ALuint id, ALsizei count, const ALuint *fsids);
170 typedef void (AL_APIENTRY*LPALGETPRESETIVSOFT)(ALuint id, ALenum param, ALint *values);
171 typedef void (AL_APIENTRY*LPALGENFONTSOUNDSSOFT)(ALsizei n, ALuint *ids);
172 typedef void (AL_APIENTRY*LPALDELETEFONTSOUNDSSOFT)(ALsizei n, const ALuint *ids);
173 typedef ALboolean (AL_APIENTRY*LPALISFONTSOUNDSOFT)(ALuint id);
174 typedef void (AL_APIENTRY*LPALFONTSOUNDISOFT)(ALuint id, ALenum param, ALint value);
175 typedef void (AL_APIENTRY*LPALFONTSOUND2ISOFT)(ALuint id, ALenum param, ALint value1, ALint value2);
176 typedef void (AL_APIENTRY*LPALFONTSOUNDIVSOFT)(ALuint id, ALenum param, const ALint *values);
177 typedef void (AL_APIENTRY*LPALGETFONTSOUNDIVSOFT)(ALuint id, ALenum param, ALint *values);
178 typedef void (AL_APIENTRY*LPALFONTSOUNDMOFULATORISOFT)(ALuint id, ALsizei stage, ALenum param, ALint value);
179 typedef void (AL_APIENTRY*LPALGETFONTSOUNDMODULATORIVSOFT)(ALuint id, ALsizei stage, ALenum param, ALint *values);
180 typedef void (AL_APIENTRY*LPALMIDISOUNDFONTSOFT)(ALuint id);
181 typedef void (AL_APIENTRY*LPALMIDISOUNDFONTVSOFT)(ALsizei count, const ALuint *ids);
182 typedef void (AL_APIENTRY*LPALMIDIEVENTSOFT)(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2);
183 typedef void (AL_APIENTRY*LPALMIDISYSEXSOFT)(ALuint64SOFT time, const ALbyte *data, ALsizei size);
184 typedef void (AL_APIENTRY*LPALMIDIPLAYSOFT)(void);
185 typedef void (AL_APIENTRY*LPALMIDIPAUSESOFT)(void);
186 typedef void (AL_APIENTRY*LPALMIDISTOPSOFT)(void);
187 typedef void (AL_APIENTRY*LPALMIDIRESETSOFT)(void);
188 typedef void (AL_APIENTRY*LPALMIDIGAINSOFT)(ALfloat value);
189 typedef ALint64SOFT (AL_APIENTRY*LPALGETINTEGER64SOFT)(ALenum pname);
190 typedef void (AL_APIENTRY*LPALGETINTEGER64VSOFT)(ALenum pname, ALint64SOFT *values);
191 typedef void (AL_APIENTRY*LPALLOADSOUNDFONTSOFT)(ALuint id, size_t(*cb)(ALvoid*,size_t,ALvoid*), ALvoid *user);
192 #ifdef AL_ALEXT_PROTOTYPES
193 AL_API void AL_APIENTRY alGenSoundfontsSOFT(ALsizei n, ALuint *ids);
194 AL_API void AL_APIENTRY alDeleteSoundfontsSOFT(ALsizei n, const ALuint *ids);
195 AL_API ALboolean AL_APIENTRY alIsSoundfontSOFT(ALuint id);
196 AL_API void AL_APIENTRY alSoundfontSamplesSOFT(ALuint sfid, ALenum type, ALsizei count, const ALvoid *samples);
197 AL_API void AL_APIENTRY alGetSoundfontSamplesSOFT(ALuint id, ALsizei offset, ALsizei count, ALenum type, ALvoid *samples);
198 AL_API ALvoid* AL_APIENTRY alSoundfontMapSamplesSOFT(ALuint sfid, ALsizei offset, ALsizei length);
199 AL_API void AL_APIENTRY alSoundfontUnmapSamplesSOFT(ALuint sfid);
200 AL_API void AL_APIENTRY alGetSoundfontivSOFT(ALuint id, ALenum param, ALint *values);
201 AL_API void AL_APIENTRY alSoundfontPresetsSOFT(ALuint id, ALsizei count, const ALuint *pids);
203 AL_API void AL_APIENTRY alGenPresetsSOFT(ALsizei n, ALuint *ids);
204 AL_API void AL_APIENTRY alDeletePresetsSOFT(ALsizei n, const ALuint *ids);
205 AL_API ALboolean AL_APIENTRY alIsPresetSOFT(ALuint id);
206 AL_API void AL_APIENTRY alPresetiSOFT(ALuint id, ALenum param, ALint value);
207 AL_API void AL_APIENTRY alPresetivSOFT(ALuint id, ALenum param, const ALint *values);
208 AL_API void AL_APIENTRY alGetPresetivSOFT(ALuint id, ALenum param, ALint *values);
209 AL_API void AL_APIENTRY alPresetFontsoundsSOFT(ALuint id, ALsizei count, const ALuint *fsids);
211 AL_API void AL_APIENTRY alGenFontsoundsSOFT(ALsizei n, ALuint *ids);
212 AL_API void AL_APIENTRY alDeleteFontsoundsSOFT(ALsizei n, const ALuint *ids);
213 AL_API ALboolean AL_APIENTRY alIsFontsoundSOFT(ALuint id);
214 AL_API void AL_APIENTRY alFontsoundiSOFT(ALuint id, ALenum param, ALint value);
215 AL_API void AL_APIENTRY alFontsound2iSOFT(ALuint id, ALenum param, ALint value1, ALint value2);
216 AL_API void AL_APIENTRY alFontsoundivSOFT(ALuint id, ALenum param, const ALint *values);
217 AL_API void AL_APIENTRY alGetFontsoundivSOFT(ALuint id, ALenum param, ALint *values);
218 AL_API void AL_APIENTRY alFontsoundModulatoriSOFT(ALuint id, ALsizei stage, ALenum param, ALint value);
219 AL_API void AL_APIENTRY alGetFontsoundModulatorivSOFT(ALuint id, ALsizei stage, ALenum param, ALint *values);
221 AL_API void AL_APIENTRY alMidiSoundfontSOFT(ALuint id);
222 AL_API void AL_APIENTRY alMidiSoundfontvSOFT(ALsizei count, const ALuint *ids);
223 AL_API void AL_APIENTRY alMidiEventSOFT(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2);
224 AL_API void AL_APIENTRY alMidiSysExSOFT(ALuint64SOFT time, const ALbyte *data, ALsizei size);
225 AL_API void AL_APIENTRY alMidiPlaySOFT(void);
226 AL_API void AL_APIENTRY alMidiPauseSOFT(void);
227 AL_API void AL_APIENTRY alMidiStopSOFT(void);
228 AL_API void AL_APIENTRY alMidiResetSOFT(void);
229 AL_API void AL_APIENTRY alMidiGainSOFT(ALfloat value);
230 AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname);
231 AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values);
232 AL_API void AL_APIENTRY alLoadSoundfontSOFT(ALuint id, size_t(*cb)(ALvoid*,size_t,ALvoid*), ALvoid *user);
233 #endif
234 #endif
236 #ifndef ALC_SOFT_pause_device
237 #define ALC_SOFT_pause_device 1
238 typedef void (ALC_APIENTRY*LPALCDEVICEPAUSESOFT)(ALCdevice *device);
239 typedef void (ALC_APIENTRY*LPALCDEVICERESUMESOFT)(ALCdevice *device);
240 #ifdef AL_ALEXT_PROTOTYPES
241 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device);
242 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device);
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
257 #ifndef AL_SOFT_MSADPCM
258 #define AL_SOFT_MSADPCM 1
259 #define AL_FORMAT_MONO_MSADPCM_SOFT 0x1302
260 #define AL_FORMAT_STEREO_MSADPCM_SOFT 0x1303
261 #endif
264 #ifdef IN_IDE_PARSER
265 /* KDevelop's parser doesn't recognize the C99-standard restrict keyword, but
266 * recent versions (at least 4.5.1) do recognize GCC's __restrict. */
267 #define restrict __restrict
268 #endif
271 typedef ALint64SOFT ALint64;
272 typedef ALuint64SOFT ALuint64;
274 typedef ptrdiff_t ALintptrEXT;
275 typedef ptrdiff_t ALsizeiptrEXT;
277 #ifndef U64
278 #if defined(_MSC_VER)
279 #define U64(x) ((ALuint64)(x##ui64))
280 #elif SIZEOF_LONG == 8
281 #define U64(x) ((ALuint64)(x##ul))
282 #elif SIZEOF_LONG_LONG == 8
283 #define U64(x) ((ALuint64)(x##ull))
284 #endif
285 #endif
287 #ifndef UINT64_MAX
288 #define UINT64_MAX U64(18446744073709551615)
289 #endif
291 #ifndef UNUSED
292 #if defined(__cplusplus)
293 #define UNUSED(x)
294 #elif defined(__GNUC__)
295 #define UNUSED(x) UNUSED_##x __attribute__((unused))
296 #elif defined(__LCLINT__)
297 #define UNUSED(x) /*@unused@*/ x
298 #else
299 #define UNUSED(x) x
300 #endif
301 #endif
303 #ifdef __GNUC__
304 #define DECL_CONST __attribute__((const))
305 #define DECL_FORMAT(x, y, z) __attribute__((format(x, (y), (z))))
306 #else
307 #define DECL_CONST
308 #define DECL_FORMAT(x, y, z)
309 #endif
311 #if defined(__GNUC__) && defined(__i386__)
312 /* force_align_arg_pointer is required for proper function arguments aligning
313 * when SSE code is used. Some systems (Windows, QNX) do not guarantee our
314 * thread functions will be properly aligned on the stack, even though GCC may
315 * generate code with the assumption that it is. */
316 #define FORCE_ALIGN __attribute__((force_align_arg_pointer))
317 #else
318 #define FORCE_ALIGN
319 #endif
321 #ifdef HAVE_C99_VLA
322 #define DECL_VLA(T, _name, _size) T _name[(_size)]
323 #else
324 #define DECL_VLA(T, _name, _size) T *_name = alloca((_size) * sizeof(T))
325 #endif
327 #ifndef PATH_MAX
328 #ifdef MAX_PATH
329 #define PATH_MAX MAX_PATH
330 #else
331 #define PATH_MAX 4096
332 #endif
333 #endif
336 static const union {
337 ALuint u;
338 ALubyte b[sizeof(ALuint)];
339 } EndianTest = { 1 };
340 #define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1)
342 #define COUNTOF(x) (sizeof((x))/sizeof((x)[0]))
345 #define DERIVE_FROM_TYPE(t) t t##_parent
346 #define STATIC_CAST(to, obj) (&(obj)->to##_parent)
347 #ifdef __GNUC__
348 #define STATIC_UPCAST(to, from, obj) __extension__({ \
349 static_assert(__builtin_types_compatible_p(from, __typeof(*(obj))), \
350 "Invalid upcast object from type"); \
351 (to*)((char*)(obj) - offsetof(to, from##_parent)); \
353 #else
354 #define STATIC_UPCAST(to, from, obj) ((to*)((char*)(obj) - offsetof(to, from##_parent)))
355 #endif
357 #define DECLARE_FORWARD(T1, T2, rettype, func) \
358 rettype T1##_##func(T1 *obj) \
359 { return T2##_##func(STATIC_CAST(T2, obj)); }
361 #define DECLARE_FORWARD1(T1, T2, rettype, func, argtype1) \
362 rettype T1##_##func(T1 *obj, argtype1 a) \
363 { return T2##_##func(STATIC_CAST(T2, obj), a); }
365 #define DECLARE_FORWARD2(T1, T2, rettype, func, argtype1, argtype2) \
366 rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b) \
367 { return T2##_##func(STATIC_CAST(T2, obj), a, b); }
369 #define DECLARE_FORWARD3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
370 rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b, argtype3 c) \
371 { return T2##_##func(STATIC_CAST(T2, obj), a, b, c); }
374 #define GET_VTABLE1(T1) (&(T1##_vtable))
375 #define GET_VTABLE2(T1, T2) (&(T1##_##T2##_vtable))
377 #define SET_VTABLE1(T1, obj) ((obj)->vtbl = GET_VTABLE1(T1))
378 #define SET_VTABLE2(T1, T2, obj) (STATIC_CAST(T2, obj)->vtbl = GET_VTABLE2(T1, T2))
380 #define DECLARE_THUNK(T1, T2, rettype, func) \
381 static rettype T1##_##T2##_##func(T2 *obj) \
382 { return T1##_##func(STATIC_UPCAST(T1, T2, obj)); }
384 #define DECLARE_THUNK1(T1, T2, rettype, func, argtype1) \
385 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a) \
386 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a); }
388 #define DECLARE_THUNK2(T1, T2, rettype, func, argtype1, argtype2) \
389 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b) \
390 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b); }
392 #define DECLARE_THUNK3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
393 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c) \
394 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c); }
396 #define DECLARE_DEFAULT_ALLOCATORS(T) \
397 static void* T##_New(size_t size) { return malloc(size); } \
398 static void T##_Delete(void *ptr) { 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 #ifdef __cplusplus
418 extern "C" {
419 #endif
421 struct Hrtf;
424 #define DEFAULT_OUTPUT_RATE (44100)
425 #define MIN_OUTPUT_RATE (8000)
428 /* Find the next power-of-2 for non-power-of-2 numbers. */
429 inline ALuint NextPowerOf2(ALuint value)
431 if(value > 0)
433 value--;
434 value |= value>>1;
435 value |= value>>2;
436 value |= value>>4;
437 value |= value>>8;
438 value |= value>>16;
440 return value+1;
443 /* Fast float-to-int conversion. Assumes the FPU is already in round-to-zero
444 * mode. */
445 inline ALint fastf2i(ALfloat f)
447 #ifdef HAVE_LRINTF
448 return lrintf(f);
449 #elif defined(_MSC_VER) && defined(_M_IX86)
450 ALint i;
451 __asm fld f
452 __asm fistp i
453 return i;
454 #else
455 return (ALint)f;
456 #endif
459 /* Fast float-to-uint conversion. Assumes the FPU is already in round-to-zero
460 * mode. */
461 inline ALuint fastf2u(ALfloat f)
462 { return fastf2i(f); }
465 enum DevProbe {
466 ALL_DEVICE_PROBE,
467 CAPTURE_DEVICE_PROBE
470 typedef struct {
471 ALCenum (*OpenPlayback)(ALCdevice*, const ALCchar*);
472 void (*ClosePlayback)(ALCdevice*);
473 ALCboolean (*ResetPlayback)(ALCdevice*);
474 ALCboolean (*StartPlayback)(ALCdevice*);
475 void (*StopPlayback)(ALCdevice*);
477 ALCenum (*OpenCapture)(ALCdevice*, const ALCchar*);
478 void (*CloseCapture)(ALCdevice*);
479 void (*StartCapture)(ALCdevice*);
480 void (*StopCapture)(ALCdevice*);
481 ALCenum (*CaptureSamples)(ALCdevice*, void*, ALCuint);
482 ALCuint (*AvailableSamples)(ALCdevice*);
484 ALint64 (*GetLatency)(ALCdevice*);
485 } BackendFuncs;
487 ALCboolean alc_solaris_init(BackendFuncs *func_list);
488 void alc_solaris_deinit(void);
489 void alc_solaris_probe(enum DevProbe type);
490 ALCboolean alc_sndio_init(BackendFuncs *func_list);
491 void alc_sndio_deinit(void);
492 void alc_sndio_probe(enum DevProbe type);
493 ALCboolean alcWinMMInit(BackendFuncs *FuncList);
494 void alcWinMMDeinit(void);
495 void alcWinMMProbe(enum DevProbe type);
496 ALCboolean alc_pa_init(BackendFuncs *func_list);
497 void alc_pa_deinit(void);
498 void alc_pa_probe(enum DevProbe type);
499 ALCboolean alc_wave_init(BackendFuncs *func_list);
500 void alc_wave_deinit(void);
501 void alc_wave_probe(enum DevProbe type);
502 ALCboolean alc_ca_init(BackendFuncs *func_list);
503 void alc_ca_deinit(void);
504 void alc_ca_probe(enum DevProbe type);
505 ALCboolean alc_opensl_init(BackendFuncs *func_list);
506 void alc_opensl_deinit(void);
507 void alc_opensl_probe(enum DevProbe type);
508 ALCboolean alc_qsa_init(BackendFuncs *func_list);
509 void alc_qsa_deinit(void);
510 void alc_qsa_probe(enum DevProbe type);
512 struct ALCbackend;
515 enum DistanceModel {
516 InverseDistanceClamped = AL_INVERSE_DISTANCE_CLAMPED,
517 LinearDistanceClamped = AL_LINEAR_DISTANCE_CLAMPED,
518 ExponentDistanceClamped = AL_EXPONENT_DISTANCE_CLAMPED,
519 InverseDistance = AL_INVERSE_DISTANCE,
520 LinearDistance = AL_LINEAR_DISTANCE,
521 ExponentDistance = AL_EXPONENT_DISTANCE,
522 DisableDistance = AL_NONE,
524 DefaultDistanceModel = InverseDistanceClamped
527 enum Resampler {
528 PointResampler,
529 LinearResampler,
530 CubicResampler,
532 ResamplerMax,
535 enum Channel {
536 FrontLeft = 0,
537 FrontRight,
538 FrontCenter,
539 LFE,
540 BackLeft,
541 BackRight,
542 BackCenter,
543 SideLeft,
544 SideRight,
546 MaxChannels,
550 /* Device formats */
551 enum DevFmtType {
552 DevFmtByte = ALC_BYTE_SOFT,
553 DevFmtUByte = ALC_UNSIGNED_BYTE_SOFT,
554 DevFmtShort = ALC_SHORT_SOFT,
555 DevFmtUShort = ALC_UNSIGNED_SHORT_SOFT,
556 DevFmtInt = ALC_INT_SOFT,
557 DevFmtUInt = ALC_UNSIGNED_INT_SOFT,
558 DevFmtFloat = ALC_FLOAT_SOFT,
560 DevFmtTypeDefault = DevFmtFloat
562 enum DevFmtChannels {
563 DevFmtMono = ALC_MONO_SOFT,
564 DevFmtStereo = ALC_STEREO_SOFT,
565 DevFmtQuad = ALC_QUAD_SOFT,
566 DevFmtX51 = ALC_5POINT1_SOFT,
567 DevFmtX61 = ALC_6POINT1_SOFT,
568 DevFmtX71 = ALC_7POINT1_SOFT,
570 /* Similar to 5.1, except using the side channels instead of back */
571 DevFmtX51Side = 0x80000000,
573 DevFmtChannelsDefault = DevFmtStereo
576 ALuint BytesFromDevFmt(enum DevFmtType type) DECL_CONST;
577 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans) DECL_CONST;
578 inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type)
580 return ChannelsFromDevFmt(chans) * BytesFromDevFmt(type);
584 extern const struct EffectList {
585 const char *name;
586 int type;
587 const char *ename;
588 ALenum val;
589 } EffectList[];
592 enum DeviceType {
593 Playback,
594 Capture,
595 Loopback
599 /* Size for temporary storage of buffer data, in ALfloats. Larger values need
600 * more memory, while smaller values may need more iterations. The value needs
601 * to be a sensible size, however, as it constrains the max stepping value used
602 * for mixing, as well as the maximum number of samples per mixing iteration.
604 #define BUFFERSIZE (2048u)
607 struct ALCdevice_struct
609 RefCount ref;
611 ALCboolean Connected;
612 enum DeviceType Type;
614 ALuint Frequency;
615 ALuint UpdateSize;
616 ALuint NumUpdates;
617 enum DevFmtChannels FmtChans;
618 enum DevFmtType FmtType;
620 al_string DeviceName;
622 volatile ALCenum LastError;
624 // Maximum number of sources that can be created
625 ALuint MaxNoOfSources;
626 // Maximum number of slots that can be created
627 ALuint AuxiliaryEffectSlotMax;
629 ALCuint NumMonoSources;
630 ALCuint NumStereoSources;
631 ALuint NumAuxSends;
633 // Map of Buffers for this device
634 UIntMap BufferMap;
636 // Map of Effects for this device
637 UIntMap EffectMap;
639 // Map of Filters for this device
640 UIntMap FilterMap;
642 // Map of Soundfonts for this device
643 UIntMap SfontMap;
645 // Map of Presets for this device
646 UIntMap PresetMap;
648 // Map of Fontsounds for this device
649 UIntMap FontsoundMap;
651 /* Default soundfont (accessible as ID 0) */
652 struct ALsoundfont *DefaultSfont;
654 /* MIDI synth engine */
655 struct MidiSynth *Synth;
657 /* HRTF filter tables */
658 const struct Hrtf *Hrtf;
660 // Stereo-to-binaural filter
661 struct bs2b *Bs2b;
662 ALCint Bs2bLevel;
664 // Device flags
665 ALuint Flags;
667 ALuint ChannelOffsets[MaxChannels];
669 enum Channel Speaker2Chan[MaxChannels];
670 ALfloat SpeakerAngle[MaxChannels];
671 ALuint NumChan;
673 ALuint64 ClockBase;
674 ALuint SamplesDone;
676 /* Temp storage used for each source when mixing. */
677 alignas(16) ALfloat SourceData[BUFFERSIZE];
678 alignas(16) ALfloat ResampledData[BUFFERSIZE];
679 alignas(16) ALfloat FilteredData[BUFFERSIZE];
681 // Dry path buffer mix
682 alignas(16) ALfloat DryBuffer[MaxChannels][BUFFERSIZE];
684 /* Running count of the mixer invocations, in 31.1 fixed point. This
685 * actually increments *twice* when mixing, first at the start and then at
686 * the end, so the bottom bit indicates if the device is currently mixing
687 * and the upper bits indicates how many mixes have been done.
689 RefCount MixCount;
691 /* Default effect slot */
692 struct ALeffectslot *DefaultSlot;
694 // Contexts created on this device
695 ALCcontext *volatile ContextList;
697 struct ALCbackend *Backend;
699 void *ExtraData; // For the backend's use
701 ALCdevice *volatile next;
703 /* Memory space used by the default slot (Playback devices only) */
704 alignas(16) ALCbyte _slot_mem[];
707 // Frequency was requested by the app or config file
708 #define DEVICE_FREQUENCY_REQUEST (1<<1)
709 // Channel configuration was requested by the config file
710 #define DEVICE_CHANNELS_REQUEST (1<<2)
711 // Sample type was requested by the config file
712 #define DEVICE_SAMPLE_TYPE_REQUEST (1<<3)
713 // HRTF was requested by the app
714 #define DEVICE_HRTF_REQUEST (1<<4)
716 // Stereo sources cover 120-degree angles around +/-90
717 #define DEVICE_WIDE_STEREO (1<<16)
719 // Specifies if the DSP is paused at user request
720 #define DEVICE_PAUSED (1<<30)
722 // Specifies if the device is currently running
723 #define DEVICE_RUNNING (1<<31)
725 /* Invalid channel offset */
726 #define INVALID_OFFSET (~0u)
729 /* Nanosecond resolution for the device clock time. */
730 #define DEVICE_CLOCK_RES U64(1000000000)
733 /* Must be less than 15 characters (16 including terminating null) for
734 * compatibility with pthread_setname_np limitations. */
735 #define MIXER_THREAD_NAME "alsoft-mixer"
738 typedef struct ALeffectslot *ALeffectslotPtr;
739 DECL_VECTOR(ALeffectslotPtr)
742 struct ALCcontext_struct
744 RefCount ref;
746 struct ALlistener *Listener;
748 UIntMap SourceMap;
749 UIntMap EffectSlotMap;
751 volatile ALenum LastError;
753 volatile ALenum UpdateSources;
755 volatile enum DistanceModel DistanceModel;
756 volatile ALboolean SourceDistanceModel;
758 volatile ALfloat DopplerFactor;
759 volatile ALfloat DopplerVelocity;
760 volatile ALfloat SpeedOfSound;
761 volatile ALenum DeferUpdates;
763 struct ALactivesource **ActiveSources;
764 ALsizei ActiveSourceCount;
765 ALsizei MaxActiveSources;
767 vector_ALeffectslotPtr ActiveAuxSlots;
769 ALCdevice *Device;
770 const ALCchar *ExtensionList;
772 ALCcontext *volatile next;
774 /* Memory space used by the listener */
775 alignas(16) ALCbyte _listener_mem[];
778 ALCcontext *GetContextRef(void);
780 void ALCcontext_IncRef(ALCcontext *context);
781 void ALCcontext_DecRef(ALCcontext *context);
783 void AppendAllDevicesList(const ALCchar *name);
784 void AppendCaptureDeviceList(const ALCchar *name);
786 ALint64 ALCdevice_GetLatencyDefault(ALCdevice *device);
788 void ALCdevice_Lock(ALCdevice *device);
789 void ALCdevice_Unlock(ALCdevice *device);
790 ALint64 ALCdevice_GetLatency(ALCdevice *device);
792 inline void LockContext(ALCcontext *context)
793 { ALCdevice_Lock(context->Device); }
795 inline void UnlockContext(ALCcontext *context)
796 { ALCdevice_Unlock(context->Device); }
799 void *al_malloc(size_t alignment, size_t size);
800 void *al_calloc(size_t alignment, size_t size);
801 void al_free(void *ptr);
804 typedef struct {
805 #ifdef HAVE_FENV_H
806 DERIVE_FROM_TYPE(fenv_t);
807 #else
808 int state;
809 #endif
810 #ifdef HAVE_SSE
811 int sse_state;
812 #endif
813 } FPUCtl;
814 void SetMixerFPUMode(FPUCtl *ctl);
815 void RestoreFPUMode(const FPUCtl *ctl);
818 typedef struct RingBuffer RingBuffer;
819 RingBuffer *CreateRingBuffer(ALsizei frame_size, ALsizei length);
820 void DestroyRingBuffer(RingBuffer *ring);
821 ALsizei RingBufferSize(RingBuffer *ring);
822 void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len);
823 void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len);
825 void ReadALConfig(void);
826 void FreeALConfig(void);
827 int ConfigValueExists(const char *blockName, const char *keyName);
828 const char *GetConfigValue(const char *blockName, const char *keyName, const char *def);
829 int GetConfigValueBool(const char *blockName, const char *keyName, int def);
830 int ConfigValueStr(const char *blockName, const char *keyName, const char **ret);
831 int ConfigValueInt(const char *blockName, const char *keyName, int *ret);
832 int ConfigValueUInt(const char *blockName, const char *keyName, unsigned int *ret);
833 int ConfigValueFloat(const char *blockName, const char *keyName, float *ret);
835 void SetRTPriority(void);
837 void SetDefaultChannelOrder(ALCdevice *device);
838 void SetDefaultWFXChannelOrder(ALCdevice *device);
840 const ALCchar *DevFmtTypeString(enum DevFmtType type) DECL_CONST;
841 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans) DECL_CONST;
844 extern FILE *LogFile;
846 #if defined(__GNUC__) && !defined(IN_IDE_PARSER)
847 #define AL_PRINT(T, MSG, ...) fprintf(LogFile, "AL lib: %s %s: "MSG, T, __FUNCTION__ , ## __VA_ARGS__)
848 #else
849 void al_print(const char *type, const char *func, const char *fmt, ...) DECL_FORMAT(printf, 3,4);
850 #define AL_PRINT(T, ...) al_print((T), __FUNCTION__, __VA_ARGS__)
851 #endif
853 enum LogLevel {
854 NoLog,
855 LogError,
856 LogWarning,
857 LogTrace,
858 LogRef
860 extern enum LogLevel LogLevel;
862 #define TRACEREF(...) do { \
863 if(LogLevel >= LogRef) \
864 AL_PRINT("(--)", __VA_ARGS__); \
865 } while(0)
867 #define TRACE(...) do { \
868 if(LogLevel >= LogTrace) \
869 AL_PRINT("(II)", __VA_ARGS__); \
870 } while(0)
872 #define WARN(...) do { \
873 if(LogLevel >= LogWarning) \
874 AL_PRINT("(WW)", __VA_ARGS__); \
875 } while(0)
877 #define ERR(...) do { \
878 if(LogLevel >= LogError) \
879 AL_PRINT("(EE)", __VA_ARGS__); \
880 } while(0)
883 extern ALint RTPrioLevel;
886 extern ALuint CPUCapFlags;
887 enum {
888 CPU_CAP_SSE = 1<<0,
889 CPU_CAP_SSE2 = 1<<1,
890 CPU_CAP_SSE4_1 = 1<<2,
891 CPU_CAP_NEON = 1<<3,
894 void FillCPUCaps(ALuint capfilter);
896 FILE *OpenDataFile(const char *fname, const char *subdir);
898 /* Small hack to use a pointer-to-array type as a normal argument type.
899 * Shouldn't be used directly. */
900 typedef ALfloat ALfloatBUFFERSIZE[BUFFERSIZE];
903 #ifdef __cplusplus
905 #endif
907 #endif