Move ALfloatBUFFERSIZE to a common location
[openal-soft.git] / OpenAL32 / Include / alMain.h
blobfb0d08bd6e5392f9dc50ab028926dfaf0a3f91b8
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>
10 #ifdef HAVE_STRINGS_H
11 #include <strings.h>
12 #endif
14 #ifdef HAVE_FENV_H
15 #include <fenv.h>
16 #endif
18 #include "AL/al.h"
19 #include "AL/alc.h"
20 #include "AL/alext.h"
22 #include "atomic.h"
23 #include "uintmap.h"
25 #ifndef ALC_SOFT_HRTF
26 #define ALC_SOFT_HRTF 1
27 #define ALC_HRTF_SOFT 0x1992
28 #endif
31 #ifdef IN_IDE_PARSER
32 /* KDevelop's parser doesn't recognize the C99-standard restrict keyword, but
33 * recent versions (at least 4.5.1) do recognize GCC's __restrict. */
34 #define restrict __restrict
35 /* KDevelop won't see the ALIGN macro from config.h when viewing files that
36 * don't include it directly (e.g. headers). */
37 #ifndef ALIGN
38 #define ALIGN(x)
39 #endif
40 #endif
43 typedef ALint64SOFT ALint64;
44 typedef ALuint64SOFT ALuint64;
46 typedef ptrdiff_t ALintptrEXT;
47 typedef ptrdiff_t ALsizeiptrEXT;
49 #ifndef U64
50 #if defined(_MSC_VER)
51 #define U64(x) ((ALuint64)(x##ui64))
52 #elif SIZEOF_LONG == 8
53 #define U64(x) ((ALuint64)(x##ul))
54 #elif SIZEOF_LONG_LONG == 8
55 #define U64(x) ((ALuint64)(x##ull))
56 #endif
57 #endif
59 #ifndef UNUSED
60 #if defined(__cplusplus)
61 #define UNUSED(x)
62 #elif defined(__GNUC__)
63 #define UNUSED(x) UNUSED_##x __attribute__((unused))
64 #elif defined(__LCLINT__)
65 #define UNUSED(x) /*@unused@*/ x
66 #else
67 #define UNUSED(x) x
68 #endif
69 #endif
71 #ifdef HAVE_GCC_FORMAT
72 #define PRINTF_STYLE(x, y) __attribute__((format(printf, (x), (y))))
73 #else
74 #define PRINTF_STYLE(x, y)
75 #endif
77 #if defined(__GNUC__) && defined(__i386__)
78 /* force_align_arg_pointer is required for proper function arguments aligning
79 * when SSE code is used. Some systems (Windows, QNX) do not guarantee our
80 * thread functions will be properly aligned on the stack, even though GCC may
81 * generate code with the assumption that it is. */
82 #define FORCE_ALIGN __attribute__((force_align_arg_pointer))
83 #else
84 #define FORCE_ALIGN
85 #endif
88 static const union {
89 ALuint u;
90 ALubyte b[sizeof(ALuint)];
91 } EndianTest = { 1 };
92 #define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1)
94 #define COUNTOF(x) (sizeof((x))/sizeof((x)[0]))
97 #define DERIVE_FROM_TYPE(t) t t##_parent
98 #define STATIC_CAST(to, obj) (&(obj)->to##_parent)
99 #define STATIC_UPCAST(to, from, obj) ((to*)((char*)(obj) - offsetof(to, from##_parent)))
102 #define DECLARE_FORWARD(T1, T2, rettype, func) \
103 rettype T1##_##func(T1 *obj) \
104 { return T2##_##func(STATIC_CAST(T2, obj)); }
106 #define DECLARE_FORWARD1(T1, T2, rettype, func, argtype1) \
107 rettype T1##_##func(T1 *obj, argtype1 a) \
108 { return T2##_##func(STATIC_CAST(T2, obj), a); }
110 #define DECLARE_FORWARD2(T1, T2, rettype, func, argtype1, argtype2) \
111 rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b) \
112 { return T2##_##func(STATIC_CAST(T2, obj), a, b); }
115 #define GET_VTABLE1(T1) (&(T1##_vtable))
116 #define GET_VTABLE2(T1, T2) (&(T1##_##T2##_vtable))
118 #define SET_VTABLE1(T1, obj) ((obj)->vtbl = GET_VTABLE1(T1))
119 #define SET_VTABLE2(T1, T2, obj) (STATIC_CAST(T2, obj)->vtbl = GET_VTABLE2(T1, T2))
121 #define DECLARE_THUNK(T1, T2, rettype, func) \
122 static rettype T1##_##T2##_##func(T2 *obj) \
123 { return T1##_##func(STATIC_UPCAST(T1, T2, obj)); }
125 #define DECLARE_THUNK1(T1, T2, rettype, func, argtype1) \
126 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a) \
127 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a); }
129 #define DECLARE_THUNK2(T1, T2, rettype, func, argtype1, argtype2) \
130 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b) \
131 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b); }
133 #define DECLARE_THUNK3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
134 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c) \
135 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c); }
138 /* Helper to extract an argument list for VCALL. Not used directly. */
139 #define EXTRACT_VCALL_ARGS(...) __VA_ARGS__))
141 /* Call a "virtual" method on an object, with arguments. */
142 #define V(obj, func) ((obj)->vtbl->func((obj), EXTRACT_VCALL_ARGS
143 /* Call a "virtual" method on an object, with no arguments. */
144 #define V0(obj, func) ((obj)->vtbl->func((obj) EXTRACT_VCALL_ARGS
146 #define DELETE_OBJ(obj) do { \
147 if((obj) != NULL) \
149 V0((obj),Destruct)(); \
150 V0((obj),Delete)(); \
152 } while(0)
155 #ifdef __cplusplus
156 extern "C" {
157 #endif
159 struct Hrtf;
162 #define DEFAULT_OUTPUT_RATE (44100)
163 #define MIN_OUTPUT_RATE (8000)
166 /* Find the next power-of-2 for non-power-of-2 numbers. */
167 inline ALuint NextPowerOf2(ALuint value)
169 if(value > 0)
171 value--;
172 value |= value>>1;
173 value |= value>>2;
174 value |= value>>4;
175 value |= value>>8;
176 value |= value>>16;
178 return value+1;
181 /* Fast float-to-int conversion. Assumes the FPU is already in round-to-zero
182 * mode. */
183 inline ALint fastf2i(ALfloat f)
185 #ifdef HAVE_LRINTF
186 return lrintf(f);
187 #elif defined(_MSC_VER) && defined(_M_IX86)
188 ALint i;
189 __asm fld f
190 __asm fistp i
191 return i;
192 #else
193 return (ALint)f;
194 #endif
197 /* Fast float-to-uint conversion. Assumes the FPU is already in round-to-zero
198 * mode. */
199 inline ALuint fastf2u(ALfloat f)
200 { return fastf2i(f); }
203 enum DevProbe {
204 ALL_DEVICE_PROBE,
205 CAPTURE_DEVICE_PROBE
208 typedef struct {
209 ALCenum (*OpenPlayback)(ALCdevice*, const ALCchar*);
210 void (*ClosePlayback)(ALCdevice*);
211 ALCboolean (*ResetPlayback)(ALCdevice*);
212 ALCboolean (*StartPlayback)(ALCdevice*);
213 void (*StopPlayback)(ALCdevice*);
215 ALCenum (*OpenCapture)(ALCdevice*, const ALCchar*);
216 void (*CloseCapture)(ALCdevice*);
217 void (*StartCapture)(ALCdevice*);
218 void (*StopCapture)(ALCdevice*);
219 ALCenum (*CaptureSamples)(ALCdevice*, void*, ALCuint);
220 ALCuint (*AvailableSamples)(ALCdevice*);
222 ALint64 (*GetLatency)(ALCdevice*);
223 } BackendFuncs;
225 ALCboolean alc_solaris_init(BackendFuncs *func_list);
226 void alc_solaris_deinit(void);
227 void alc_solaris_probe(enum DevProbe type);
228 ALCboolean alc_sndio_init(BackendFuncs *func_list);
229 void alc_sndio_deinit(void);
230 void alc_sndio_probe(enum DevProbe type);
231 ALCboolean alcMMDevApiInit(BackendFuncs *func_list);
232 void alcMMDevApiDeinit(void);
233 void alcMMDevApiProbe(enum DevProbe type);
234 ALCboolean alcDSoundInit(BackendFuncs *func_list);
235 void alcDSoundDeinit(void);
236 void alcDSoundProbe(enum DevProbe type);
237 ALCboolean alcWinMMInit(BackendFuncs *FuncList);
238 void alcWinMMDeinit(void);
239 void alcWinMMProbe(enum DevProbe type);
240 ALCboolean alc_pa_init(BackendFuncs *func_list);
241 void alc_pa_deinit(void);
242 void alc_pa_probe(enum DevProbe type);
243 ALCboolean alc_wave_init(BackendFuncs *func_list);
244 void alc_wave_deinit(void);
245 void alc_wave_probe(enum DevProbe type);
246 ALCboolean alc_ca_init(BackendFuncs *func_list);
247 void alc_ca_deinit(void);
248 void alc_ca_probe(enum DevProbe type);
249 ALCboolean alc_opensl_init(BackendFuncs *func_list);
250 void alc_opensl_deinit(void);
251 void alc_opensl_probe(enum DevProbe type);
252 ALCboolean alc_qsa_init(BackendFuncs *func_list);
253 void alc_qsa_deinit(void);
254 void alc_qsa_probe(enum DevProbe type);
256 struct ALCbackend;
259 enum DistanceModel {
260 InverseDistanceClamped = AL_INVERSE_DISTANCE_CLAMPED,
261 LinearDistanceClamped = AL_LINEAR_DISTANCE_CLAMPED,
262 ExponentDistanceClamped = AL_EXPONENT_DISTANCE_CLAMPED,
263 InverseDistance = AL_INVERSE_DISTANCE,
264 LinearDistance = AL_LINEAR_DISTANCE,
265 ExponentDistance = AL_EXPONENT_DISTANCE,
266 DisableDistance = AL_NONE,
268 DefaultDistanceModel = InverseDistanceClamped
271 enum Resampler {
272 PointResampler,
273 LinearResampler,
274 CubicResampler,
276 ResamplerMax,
279 enum Channel {
280 FrontLeft = 0,
281 FrontRight,
282 FrontCenter,
283 LFE,
284 BackLeft,
285 BackRight,
286 BackCenter,
287 SideLeft,
288 SideRight,
290 MaxChannels,
294 /* Device formats */
295 enum DevFmtType {
296 DevFmtByte = ALC_BYTE_SOFT,
297 DevFmtUByte = ALC_UNSIGNED_BYTE_SOFT,
298 DevFmtShort = ALC_SHORT_SOFT,
299 DevFmtUShort = ALC_UNSIGNED_SHORT_SOFT,
300 DevFmtInt = ALC_INT_SOFT,
301 DevFmtUInt = ALC_UNSIGNED_INT_SOFT,
302 DevFmtFloat = ALC_FLOAT_SOFT,
304 DevFmtTypeDefault = DevFmtFloat
306 enum DevFmtChannels {
307 DevFmtMono = ALC_MONO_SOFT,
308 DevFmtStereo = ALC_STEREO_SOFT,
309 DevFmtQuad = ALC_QUAD_SOFT,
310 DevFmtX51 = ALC_5POINT1_SOFT,
311 DevFmtX61 = ALC_6POINT1_SOFT,
312 DevFmtX71 = ALC_7POINT1_SOFT,
314 /* Similar to 5.1, except using the side channels instead of back */
315 DevFmtX51Side = 0x80000000,
317 DevFmtChannelsDefault = DevFmtStereo
320 ALuint BytesFromDevFmt(enum DevFmtType type);
321 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans);
322 inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type)
324 return ChannelsFromDevFmt(chans) * BytesFromDevFmt(type);
328 extern const struct EffectList {
329 const char *name;
330 int type;
331 const char *ename;
332 ALenum val;
333 } EffectList[];
336 enum DeviceType {
337 Playback,
338 Capture,
339 Loopback
343 /* Size for temporary storage of buffer data, in ALfloats. Larger values need
344 * more memory, while smaller values may need more iterations. The value needs
345 * to be a sensible size, however, as it constrains the max stepping value used
346 * for mixing, as well as the maximum number of samples per mixing iteration.
348 #define BUFFERSIZE (2048u)
351 struct ALCdevice_struct
353 volatile RefCount ref;
355 ALCboolean Connected;
356 enum DeviceType Type;
358 ALuint Frequency;
359 ALuint UpdateSize;
360 ALuint NumUpdates;
361 enum DevFmtChannels FmtChans;
362 enum DevFmtType FmtType;
364 ALCchar *DeviceName;
366 volatile ALCenum LastError;
368 // Maximum number of sources that can be created
369 ALuint MaxNoOfSources;
370 // Maximum number of slots that can be created
371 ALuint AuxiliaryEffectSlotMax;
373 ALCuint NumMonoSources;
374 ALCuint NumStereoSources;
375 ALuint NumAuxSends;
377 // Map of Buffers for this device
378 UIntMap BufferMap;
380 // Map of Effects for this device
381 UIntMap EffectMap;
383 // Map of Filters for this device
384 UIntMap FilterMap;
386 /* HRTF filter tables */
387 const struct Hrtf *Hrtf;
389 // Stereo-to-binaural filter
390 struct bs2b *Bs2b;
391 ALCint Bs2bLevel;
393 // Device flags
394 ALuint Flags;
396 ALuint ChannelOffsets[MaxChannels];
398 enum Channel Speaker2Chan[MaxChannels];
399 ALfloat SpeakerAngle[MaxChannels];
400 ALuint NumChan;
402 /* Temp storage used for mixing. +1 for the predictive sample. */
403 ALIGN(16) ALfloat SampleData1[BUFFERSIZE+1];
404 ALIGN(16) ALfloat SampleData2[BUFFERSIZE+1];
406 // Dry path buffer mix
407 ALIGN(16) ALfloat DryBuffer[MaxChannels][BUFFERSIZE];
409 ALIGN(16) ALfloat ClickRemoval[MaxChannels];
410 ALIGN(16) ALfloat PendingClicks[MaxChannels];
412 /* Default effect slot */
413 struct ALeffectslot *DefaultSlot;
415 // Contexts created on this device
416 ALCcontext *volatile ContextList;
418 struct ALCbackend *Backend;
420 BackendFuncs *Funcs;
421 void *ExtraData; // For the backend's use
423 ALCdevice *volatile next;
426 // Frequency was requested by the app or config file
427 #define DEVICE_FREQUENCY_REQUEST (1<<1)
428 // Channel configuration was requested by the config file
429 #define DEVICE_CHANNELS_REQUEST (1<<2)
430 // Sample type was requested by the config file
431 #define DEVICE_SAMPLE_TYPE_REQUEST (1<<3)
432 // HRTF was requested by the app
433 #define DEVICE_HRTF_REQUEST (1<<4)
435 // Stereo sources cover 120-degree angles around +/-90
436 #define DEVICE_WIDE_STEREO (1<<16)
438 // Specifies if the device is currently running
439 #define DEVICE_RUNNING (1<<31)
441 /* Invalid channel offset */
442 #define INVALID_OFFSET (~0u)
445 /* Must be less than 15 characters (16 including terminating null) for
446 * compatibility with pthread_setname_np limitations. */
447 #define MIXER_THREAD_NAME "alsoft-mixer"
450 struct ALCcontext_struct
452 volatile RefCount ref;
454 struct ALlistener *Listener;
456 UIntMap SourceMap;
457 UIntMap EffectSlotMap;
459 volatile ALenum LastError;
461 volatile ALenum UpdateSources;
463 volatile enum DistanceModel DistanceModel;
464 volatile ALboolean SourceDistanceModel;
466 volatile ALfloat DopplerFactor;
467 volatile ALfloat DopplerVelocity;
468 volatile ALfloat SpeedOfSound;
469 volatile ALenum DeferUpdates;
471 struct ALsource **ActiveSources;
472 ALsizei ActiveSourceCount;
473 ALsizei MaxActiveSources;
475 struct ALeffectslot **ActiveEffectSlots;
476 ALsizei ActiveEffectSlotCount;
477 ALsizei MaxActiveEffectSlots;
479 ALCdevice *Device;
480 const ALCchar *ExtensionList;
482 ALCcontext *volatile next;
485 ALCcontext *GetContextRef(void);
487 void ALCcontext_IncRef(ALCcontext *context);
488 void ALCcontext_DecRef(ALCcontext *context);
490 void AppendAllDevicesList(const ALCchar *name);
491 void AppendCaptureDeviceList(const ALCchar *name);
493 ALint64 ALCdevice_GetLatencyDefault(ALCdevice *device);
495 void ALCdevice_Lock(ALCdevice *device);
496 void ALCdevice_Unlock(ALCdevice *device);
497 ALint64 ALCdevice_GetLatency(ALCdevice *device);
499 inline void LockContext(ALCcontext *context)
500 { ALCdevice_Lock(context->Device); }
502 inline void UnlockContext(ALCcontext *context)
503 { ALCdevice_Unlock(context->Device); }
506 void *al_malloc(size_t alignment, size_t size);
507 void *al_calloc(size_t alignment, size_t size);
508 void al_free(void *ptr);
511 typedef struct {
512 #ifdef HAVE_FENV_H
513 DERIVE_FROM_TYPE(fenv_t);
514 #else
515 int state;
516 #endif
517 #ifdef HAVE_SSE
518 int sse_state;
519 #endif
520 } FPUCtl;
521 void SetMixerFPUMode(FPUCtl *ctl);
522 void RestoreFPUMode(const FPUCtl *ctl);
525 typedef struct RingBuffer RingBuffer;
526 RingBuffer *CreateRingBuffer(ALsizei frame_size, ALsizei length);
527 void DestroyRingBuffer(RingBuffer *ring);
528 ALsizei RingBufferSize(RingBuffer *ring);
529 void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len);
530 void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len);
532 void ReadALConfig(void);
533 void FreeALConfig(void);
534 int ConfigValueExists(const char *blockName, const char *keyName);
535 const char *GetConfigValue(const char *blockName, const char *keyName, const char *def);
536 int GetConfigValueBool(const char *blockName, const char *keyName, int def);
537 int ConfigValueStr(const char *blockName, const char *keyName, const char **ret);
538 int ConfigValueInt(const char *blockName, const char *keyName, int *ret);
539 int ConfigValueUInt(const char *blockName, const char *keyName, unsigned int *ret);
540 int ConfigValueFloat(const char *blockName, const char *keyName, float *ret);
542 void SetRTPriority(void);
544 void SetDefaultChannelOrder(ALCdevice *device);
545 void SetDefaultWFXChannelOrder(ALCdevice *device);
547 const ALCchar *DevFmtTypeString(enum DevFmtType type);
548 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans);
550 #define HRIR_BITS (7)
551 #define HRIR_LENGTH (1<<HRIR_BITS)
552 #define HRIR_MASK (HRIR_LENGTH-1)
553 #define HRTFDELAY_BITS (20)
554 #define HRTFDELAY_FRACONE (1<<HRTFDELAY_BITS)
555 #define HRTFDELAY_MASK (HRTFDELAY_FRACONE-1)
556 const struct Hrtf *GetHrtf(ALCdevice *device);
557 void FindHrtfFormat(const ALCdevice *device, enum DevFmtChannels *chans, ALCuint *srate);
558 void FreeHrtfs(void);
559 ALuint GetHrtfIrSize(const struct Hrtf *Hrtf);
560 ALfloat CalcHrtfDelta(ALfloat oldGain, ALfloat newGain, const ALfloat olddir[3], const ALfloat newdir[3]);
561 void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays);
562 ALuint GetMovingHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat delta, ALint counter, ALfloat (*coeffs)[2], ALuint *delays, ALfloat (*coeffStep)[2], ALint *delayStep);
565 extern FILE *LogFile;
567 #ifdef __GNUC__
568 #define AL_PRINT(T, MSG, ...) fprintf(LogFile, "AL lib: %s %s: "MSG, T, __FUNCTION__ , ## __VA_ARGS__)
569 #else
570 void al_print(const char *type, const char *func, const char *fmt, ...) PRINTF_STYLE(3,4);
571 #define AL_PRINT(T, MSG, ...) al_print((T), __FUNCTION__, MSG, __VA_ARGS__)
572 #endif
574 enum LogLevel {
575 NoLog,
576 LogError,
577 LogWarning,
578 LogTrace,
579 LogRef
581 extern enum LogLevel LogLevel;
583 #define TRACEREF(...) do { \
584 if(LogLevel >= LogRef) \
585 AL_PRINT("(--)", __VA_ARGS__); \
586 } while(0)
588 #define TRACE(...) do { \
589 if(LogLevel >= LogTrace) \
590 AL_PRINT("(II)", __VA_ARGS__); \
591 } while(0)
593 #define WARN(...) do { \
594 if(LogLevel >= LogWarning) \
595 AL_PRINT("(WW)", __VA_ARGS__); \
596 } while(0)
598 #define ERR(...) do { \
599 if(LogLevel >= LogError) \
600 AL_PRINT("(EE)", __VA_ARGS__); \
601 } while(0)
604 extern ALint RTPrioLevel;
607 extern ALuint CPUCapFlags;
608 enum {
609 CPU_CAP_SSE = 1<<0,
610 CPU_CAP_SSE2 = 1<<1,
611 CPU_CAP_NEON = 1<<2,
614 void FillCPUCaps(ALuint capfilter);
617 #define SET_ERROR_AND_RETURN(ctx, err) do { \
618 alSetError((ctx), (err)); \
619 return; \
620 } while(0)
622 #define SET_ERROR_AND_RETURN_VALUE(ctx, err, val) do { \
623 alSetError((ctx), (err)); \
624 return (val); \
625 } while(0)
627 #define SET_ERROR_AND_GOTO(ctx, err, lbl) do { \
628 alSetError((ctx), (err)); \
629 goto lbl; \
630 } while(0)
633 /* Small hack to use a pointer-to-array type as a normal argument type.
634 * Shouldn't be used directly. */
635 typedef ALfloat ALfloatBUFFERSIZE[BUFFERSIZE];
638 #ifdef __cplusplus
640 #endif
642 #endif