Apply the main reverb gain with the panning
[openal-soft.git] / OpenAL32 / Include / alMain.h
blob8f1fd956ce7f869e58d9485dd1447a6bc2fb0e5d
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_device_clock
43 #define ALC_SOFT_device_clock 1
44 typedef int64_t ALCint64SOFT;
45 typedef uint64_t ALCuint64SOFT;
46 #define ALC_DEVICE_CLOCK_SOFT 0x1600
47 typedef void (ALC_APIENTRY*LPALCGETINTEGER64VSOFT)(ALCdevice *device, ALCenum pname, ALsizei size, ALCint64SOFT *values);
48 #ifdef AL_ALEXT_PROTOTYPES
49 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALsizei size, ALCint64SOFT *values);
50 #endif
51 #endif
54 typedef ALint64SOFT ALint64;
55 typedef ALuint64SOFT ALuint64;
57 #ifndef U64
58 #if defined(_MSC_VER)
59 #define U64(x) ((ALuint64)(x##ui64))
60 #elif SIZEOF_LONG == 8
61 #define U64(x) ((ALuint64)(x##ul))
62 #elif SIZEOF_LONG_LONG == 8
63 #define U64(x) ((ALuint64)(x##ull))
64 #endif
65 #endif
67 #ifndef UINT64_MAX
68 #define UINT64_MAX U64(18446744073709551615)
69 #endif
71 #ifndef UNUSED
72 #if defined(__cplusplus)
73 #define UNUSED(x)
74 #elif defined(__GNUC__)
75 #define UNUSED(x) UNUSED_##x __attribute__((unused))
76 #elif defined(__LCLINT__)
77 #define UNUSED(x) /*@unused@*/ x
78 #else
79 #define UNUSED(x) x
80 #endif
81 #endif
83 #ifdef __GNUC__
84 #define DECL_CONST __attribute__((const))
85 #define DECL_FORMAT(x, y, z) __attribute__((format(x, (y), (z))))
86 #else
87 #define DECL_CONST
88 #define DECL_FORMAT(x, y, z)
89 #endif
91 #if defined(__GNUC__) && defined(__i386__)
92 /* force_align_arg_pointer is required for proper function arguments aligning
93 * when SSE code is used. Some systems (Windows, QNX) do not guarantee our
94 * thread functions will be properly aligned on the stack, even though GCC may
95 * generate code with the assumption that it is. */
96 #define FORCE_ALIGN __attribute__((force_align_arg_pointer))
97 #else
98 #define FORCE_ALIGN
99 #endif
101 #ifdef HAVE_C99_VLA
102 #define DECL_VLA(T, _name, _size) T _name[(_size)]
103 #else
104 #define DECL_VLA(T, _name, _size) T *_name = alloca((_size) * sizeof(T))
105 #endif
107 #ifndef PATH_MAX
108 #ifdef MAX_PATH
109 #define PATH_MAX MAX_PATH
110 #else
111 #define PATH_MAX 4096
112 #endif
113 #endif
116 static const union {
117 ALuint u;
118 ALubyte b[sizeof(ALuint)];
119 } EndianTest = { 1 };
120 #define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1)
122 #define COUNTOF(x) (sizeof((x))/sizeof((x)[0]))
125 #define DERIVE_FROM_TYPE(t) t t##_parent
126 #define STATIC_CAST(to, obj) (&(obj)->to##_parent)
127 #ifdef __GNUC__
128 #define STATIC_UPCAST(to, from, obj) __extension__({ \
129 static_assert(__builtin_types_compatible_p(from, __typeof(*(obj))), \
130 "Invalid upcast object from type"); \
131 (to*)((char*)(obj) - offsetof(to, from##_parent)); \
133 #else
134 #define STATIC_UPCAST(to, from, obj) ((to*)((char*)(obj) - offsetof(to, from##_parent)))
135 #endif
137 #define DECLARE_FORWARD(T1, T2, rettype, func) \
138 rettype T1##_##func(T1 *obj) \
139 { return T2##_##func(STATIC_CAST(T2, obj)); }
141 #define DECLARE_FORWARD1(T1, T2, rettype, func, argtype1) \
142 rettype T1##_##func(T1 *obj, argtype1 a) \
143 { return T2##_##func(STATIC_CAST(T2, obj), a); }
145 #define DECLARE_FORWARD2(T1, T2, rettype, func, argtype1, argtype2) \
146 rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b) \
147 { return T2##_##func(STATIC_CAST(T2, obj), a, b); }
149 #define DECLARE_FORWARD3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
150 rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b, argtype3 c) \
151 { return T2##_##func(STATIC_CAST(T2, obj), a, b, c); }
154 #define GET_VTABLE1(T1) (&(T1##_vtable))
155 #define GET_VTABLE2(T1, T2) (&(T1##_##T2##_vtable))
157 #define SET_VTABLE1(T1, obj) ((obj)->vtbl = GET_VTABLE1(T1))
158 #define SET_VTABLE2(T1, T2, obj) (STATIC_CAST(T2, obj)->vtbl = GET_VTABLE2(T1, T2))
160 #define DECLARE_THUNK(T1, T2, rettype, func) \
161 static rettype T1##_##T2##_##func(T2 *obj) \
162 { return T1##_##func(STATIC_UPCAST(T1, T2, obj)); }
164 #define DECLARE_THUNK1(T1, T2, rettype, func, argtype1) \
165 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a) \
166 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a); }
168 #define DECLARE_THUNK2(T1, T2, rettype, func, argtype1, argtype2) \
169 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b) \
170 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b); }
172 #define DECLARE_THUNK3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
173 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c) \
174 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c); }
176 #define DECLARE_THUNK4(T1, T2, rettype, func, argtype1, argtype2, argtype3, argtype4) \
177 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c, argtype4 d) \
178 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c, d); }
180 #define DECLARE_DEFAULT_ALLOCATORS(T) \
181 static void* T##_New(size_t size) { return al_malloc(16, size); } \
182 static void T##_Delete(void *ptr) { al_free(ptr); }
184 /* Helper to extract an argument list for VCALL. Not used directly. */
185 #define EXTRACT_VCALL_ARGS(...) __VA_ARGS__))
187 /* Call a "virtual" method on an object, with arguments. */
188 #define V(obj, func) ((obj)->vtbl->func((obj), EXTRACT_VCALL_ARGS
189 /* Call a "virtual" method on an object, with no arguments. */
190 #define V0(obj, func) ((obj)->vtbl->func((obj) EXTRACT_VCALL_ARGS
192 #define DELETE_OBJ(obj) do { \
193 if((obj) != NULL) \
195 V0((obj),Destruct)(); \
196 V0((obj),Delete)(); \
198 } while(0)
201 #define EXTRACT_NEW_ARGS(...) __VA_ARGS__); \
203 } while(0)
205 #define NEW_OBJ(_res, T) do { \
206 _res = T##_New(sizeof(T)); \
207 if(_res) \
209 memset(_res, 0, sizeof(T)); \
210 T##_Construct(_res, EXTRACT_NEW_ARGS
213 #ifdef __cplusplus
214 extern "C" {
215 #endif
217 struct Hrtf;
220 #define DEFAULT_OUTPUT_RATE (44100)
221 #define MIN_OUTPUT_RATE (8000)
224 /* Find the next power-of-2 for non-power-of-2 numbers. */
225 inline ALuint NextPowerOf2(ALuint value)
227 if(value > 0)
229 value--;
230 value |= value>>1;
231 value |= value>>2;
232 value |= value>>4;
233 value |= value>>8;
234 value |= value>>16;
236 return value+1;
239 /* Fast float-to-int conversion. Assumes the FPU is already in round-to-zero
240 * mode. */
241 inline ALint fastf2i(ALfloat f)
243 #ifdef HAVE_LRINTF
244 return lrintf(f);
245 #elif defined(_MSC_VER) && defined(_M_IX86)
246 ALint i;
247 __asm fld f
248 __asm fistp i
249 return i;
250 #else
251 return (ALint)f;
252 #endif
255 /* Fast float-to-uint conversion. Assumes the FPU is already in round-to-zero
256 * mode. */
257 inline ALuint fastf2u(ALfloat f)
258 { return fastf2i(f); }
261 enum DevProbe {
262 ALL_DEVICE_PROBE,
263 CAPTURE_DEVICE_PROBE
266 typedef struct {
267 ALCenum (*OpenPlayback)(ALCdevice*, const ALCchar*);
268 void (*ClosePlayback)(ALCdevice*);
269 ALCboolean (*ResetPlayback)(ALCdevice*);
270 ALCboolean (*StartPlayback)(ALCdevice*);
271 void (*StopPlayback)(ALCdevice*);
273 ALCenum (*OpenCapture)(ALCdevice*, const ALCchar*);
274 void (*CloseCapture)(ALCdevice*);
275 void (*StartCapture)(ALCdevice*);
276 void (*StopCapture)(ALCdevice*);
277 ALCenum (*CaptureSamples)(ALCdevice*, void*, ALCuint);
278 ALCuint (*AvailableSamples)(ALCdevice*);
279 } BackendFuncs;
281 ALCboolean alc_sndio_init(BackendFuncs *func_list);
282 void alc_sndio_deinit(void);
283 void alc_sndio_probe(enum DevProbe type);
284 ALCboolean alc_ca_init(BackendFuncs *func_list);
285 void alc_ca_deinit(void);
286 void alc_ca_probe(enum DevProbe type);
287 ALCboolean alc_opensl_init(BackendFuncs *func_list);
288 void alc_opensl_deinit(void);
289 void alc_opensl_probe(enum DevProbe type);
290 ALCboolean alc_qsa_init(BackendFuncs *func_list);
291 void alc_qsa_deinit(void);
292 void alc_qsa_probe(enum DevProbe type);
294 struct ALCbackend;
297 enum DistanceModel {
298 InverseDistanceClamped = AL_INVERSE_DISTANCE_CLAMPED,
299 LinearDistanceClamped = AL_LINEAR_DISTANCE_CLAMPED,
300 ExponentDistanceClamped = AL_EXPONENT_DISTANCE_CLAMPED,
301 InverseDistance = AL_INVERSE_DISTANCE,
302 LinearDistance = AL_LINEAR_DISTANCE,
303 ExponentDistance = AL_EXPONENT_DISTANCE,
304 DisableDistance = AL_NONE,
306 DefaultDistanceModel = InverseDistanceClamped
309 enum Channel {
310 FrontLeft = 0,
311 FrontRight,
312 FrontCenter,
313 LFE,
314 BackLeft,
315 BackRight,
316 BackCenter,
317 SideLeft,
318 SideRight,
320 BFormatW,
321 BFormatX,
322 BFormatY,
323 BFormatZ,
325 InvalidChannel
329 /* Device formats */
330 enum DevFmtType {
331 DevFmtByte = ALC_BYTE_SOFT,
332 DevFmtUByte = ALC_UNSIGNED_BYTE_SOFT,
333 DevFmtShort = ALC_SHORT_SOFT,
334 DevFmtUShort = ALC_UNSIGNED_SHORT_SOFT,
335 DevFmtInt = ALC_INT_SOFT,
336 DevFmtUInt = ALC_UNSIGNED_INT_SOFT,
337 DevFmtFloat = ALC_FLOAT_SOFT,
339 DevFmtTypeDefault = DevFmtFloat
341 enum DevFmtChannels {
342 DevFmtMono = ALC_MONO_SOFT,
343 DevFmtStereo = ALC_STEREO_SOFT,
344 DevFmtQuad = ALC_QUAD_SOFT,
345 DevFmtX51 = ALC_5POINT1_SOFT,
346 DevFmtX61 = ALC_6POINT1_SOFT,
347 DevFmtX71 = ALC_7POINT1_SOFT,
349 /* Similar to 5.1, except using rear channels instead of sides */
350 DevFmtX51Rear = 0x80000000,
352 DevFmtBFormat3D,
354 DevFmtChannelsDefault = DevFmtStereo
356 #define MAX_OUTPUT_CHANNELS (8)
358 ALuint BytesFromDevFmt(enum DevFmtType type) DECL_CONST;
359 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans) DECL_CONST;
360 inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type)
362 return ChannelsFromDevFmt(chans) * BytesFromDevFmt(type);
366 extern const struct EffectList {
367 const char *name;
368 int type;
369 const char *ename;
370 ALenum val;
371 } EffectList[];
374 enum DeviceType {
375 Playback,
376 Capture,
377 Loopback
381 enum HrtfMode {
382 DisabledHrtf,
383 BasicHrtf,
384 FullHrtf
388 /* The maximum number of Ambisonics coefficients. For a given order (o), the
389 * size needed will be (o+1)**2, thus zero-order has 1, first-order has 4,
390 * second-order has 9, and third-order has 16. */
391 #define MAX_AMBI_COEFFS 16
393 typedef ALfloat ChannelConfig[MAX_AMBI_COEFFS];
396 #define HRTF_HISTORY_BITS (6)
397 #define HRTF_HISTORY_LENGTH (1<<HRTF_HISTORY_BITS)
398 #define HRTF_HISTORY_MASK (HRTF_HISTORY_LENGTH-1)
400 typedef struct HrtfState {
401 alignas(16) ALfloat History[HRTF_HISTORY_LENGTH];
402 alignas(16) ALfloat Values[HRIR_LENGTH][2];
403 } HrtfState;
405 typedef struct HrtfParams {
406 alignas(16) ALfloat Coeffs[HRIR_LENGTH][2];
407 alignas(16) ALfloat CoeffStep[HRIR_LENGTH][2];
408 ALuint Delay[2];
409 ALint DelayStep[2];
410 } HrtfParams;
413 /* Size for temporary storage of buffer data, in ALfloats. Larger values need
414 * more memory, while smaller values may need more iterations. The value needs
415 * to be a sensible size, however, as it constrains the max stepping value used
416 * for mixing, as well as the maximum number of samples per mixing iteration.
418 #define BUFFERSIZE (2048u)
420 struct ALCdevice_struct
422 RefCount ref;
424 ALCboolean Connected;
425 enum DeviceType Type;
427 ALuint Frequency;
428 ALuint UpdateSize;
429 ALuint NumUpdates;
430 enum DevFmtChannels FmtChans;
431 enum DevFmtType FmtType;
432 ALboolean IsHeadphones;
434 al_string DeviceName;
436 ATOMIC(ALCenum) LastError;
438 // Maximum number of sources that can be created
439 ALuint MaxNoOfSources;
440 // Maximum number of slots that can be created
441 ALuint AuxiliaryEffectSlotMax;
443 ALCuint NumMonoSources;
444 ALCuint NumStereoSources;
445 ALuint NumAuxSends;
447 // Map of Buffers for this device
448 UIntMap BufferMap;
450 // Map of Effects for this device
451 UIntMap EffectMap;
453 // Map of Filters for this device
454 UIntMap FilterMap;
456 /* HRTF filter tables */
457 vector_HrtfEntry Hrtf_List;
458 al_string Hrtf_Name;
459 const struct Hrtf *Hrtf;
460 ALCenum Hrtf_Status;
461 enum HrtfMode Hrtf_Mode;
462 HrtfState Hrtf_State[MAX_OUTPUT_CHANNELS];
463 HrtfParams Hrtf_Params[MAX_OUTPUT_CHANNELS];
464 ALuint Hrtf_Offset;
466 // Stereo-to-binaural filter
467 struct bs2b *Bs2b;
469 // Device flags
470 ALuint Flags;
472 enum Channel ChannelName[MAX_OUTPUT_CHANNELS];
473 ChannelConfig AmbiCoeffs[MAX_OUTPUT_CHANNELS];
474 ALfloat AmbiScale; /* Scale for first-order XYZ inputs using AmbCoeffs. */
475 ALuint NumChannels;
477 ALuint64 ClockBase;
478 ALuint SamplesDone;
480 /* Temp storage used for each source when mixing. */
481 alignas(16) ALfloat SourceData[BUFFERSIZE];
482 alignas(16) ALfloat ResampledData[BUFFERSIZE];
483 alignas(16) ALfloat FilteredData[BUFFERSIZE];
485 /* Dry path buffer mix. */
486 alignas(16) ALfloat (*DryBuffer)[BUFFERSIZE];
488 /* Running count of the mixer invocations, in 31.1 fixed point. This
489 * actually increments *twice* when mixing, first at the start and then at
490 * the end, so the bottom bit indicates if the device is currently mixing
491 * and the upper bits indicates how many mixes have been done.
493 RefCount MixCount;
495 /* Default effect slot */
496 struct ALeffectslot *DefaultSlot;
498 // Contexts created on this device
499 ATOMIC(ALCcontext*) ContextList;
501 struct ALCbackend *Backend;
503 void *ExtraData; // For the backend's use
505 ALCdevice *volatile next;
507 /* Memory space used by the default slot (Playback devices only) */
508 alignas(16) ALCbyte _slot_mem[];
511 // Frequency was requested by the app or config file
512 #define DEVICE_FREQUENCY_REQUEST (1<<1)
513 // Channel configuration was requested by the config file
514 #define DEVICE_CHANNELS_REQUEST (1<<2)
515 // Sample type was requested by the config file
516 #define DEVICE_SAMPLE_TYPE_REQUEST (1<<3)
518 // Specifies if the DSP is paused at user request
519 #define DEVICE_PAUSED (1<<30)
521 // Specifies if the device is currently running
522 #define DEVICE_RUNNING (1<<31)
525 /* Nanosecond resolution for the device clock time. */
526 #define DEVICE_CLOCK_RES U64(1000000000)
529 /* Must be less than 15 characters (16 including terminating null) for
530 * compatibility with pthread_setname_np limitations. */
531 #define MIXER_THREAD_NAME "alsoft-mixer"
533 #define RECORD_THREAD_NAME "alsoft-record"
536 struct ALCcontext_struct
538 RefCount ref;
540 struct ALlistener *Listener;
542 UIntMap SourceMap;
543 UIntMap EffectSlotMap;
545 ATOMIC(ALenum) LastError;
547 ATOMIC(ALenum) UpdateSources;
549 volatile enum DistanceModel DistanceModel;
550 volatile ALboolean SourceDistanceModel;
552 volatile ALfloat DopplerFactor;
553 volatile ALfloat DopplerVelocity;
554 volatile ALfloat SpeedOfSound;
555 volatile ALenum DeferUpdates;
557 struct ALvoice *Voices;
558 ALsizei VoiceCount;
559 ALsizei MaxVoices;
561 VECTOR(struct ALeffectslot*) ActiveAuxSlots;
563 ALCdevice *Device;
564 const ALCchar *ExtensionList;
566 ALCcontext *volatile next;
568 /* Memory space used by the listener */
569 alignas(16) ALCbyte _listener_mem[];
572 ALCcontext *GetContextRef(void);
574 void ALCcontext_IncRef(ALCcontext *context);
575 void ALCcontext_DecRef(ALCcontext *context);
577 void AppendAllDevicesList(const ALCchar *name);
578 void AppendCaptureDeviceList(const ALCchar *name);
580 void ALCdevice_Lock(ALCdevice *device);
581 void ALCdevice_Unlock(ALCdevice *device);
583 void ALCcontext_DeferUpdates(ALCcontext *context);
584 void ALCcontext_ProcessUpdates(ALCcontext *context);
586 inline void LockContext(ALCcontext *context)
587 { ALCdevice_Lock(context->Device); }
589 inline void UnlockContext(ALCcontext *context)
590 { ALCdevice_Unlock(context->Device); }
593 void *al_malloc(size_t alignment, size_t size);
594 void *al_calloc(size_t alignment, size_t size);
595 void al_free(void *ptr);
598 typedef struct {
599 #ifdef HAVE_FENV_H
600 DERIVE_FROM_TYPE(fenv_t);
601 #else
602 int state;
603 #endif
604 #ifdef HAVE_SSE
605 int sse_state;
606 #endif
607 } FPUCtl;
608 void SetMixerFPUMode(FPUCtl *ctl);
609 void RestoreFPUMode(const FPUCtl *ctl);
612 typedef struct RingBuffer RingBuffer;
613 RingBuffer *CreateRingBuffer(ALsizei frame_size, ALsizei length);
614 void DestroyRingBuffer(RingBuffer *ring);
615 ALsizei RingBufferSize(RingBuffer *ring);
616 void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len);
617 void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len);
619 typedef struct ll_ringbuffer ll_ringbuffer_t;
620 typedef struct ll_ringbuffer_data {
621 char *buf;
622 size_t len;
623 } ll_ringbuffer_data_t;
624 ll_ringbuffer_t *ll_ringbuffer_create(size_t sz, size_t elem_sz);
625 void ll_ringbuffer_free(ll_ringbuffer_t *rb);
626 void ll_ringbuffer_get_read_vector(const ll_ringbuffer_t *rb, ll_ringbuffer_data_t *vec);
627 void ll_ringbuffer_get_write_vector(const ll_ringbuffer_t *rb, ll_ringbuffer_data_t *vec);
628 size_t ll_ringbuffer_read(ll_ringbuffer_t *rb, char *dest, size_t cnt);
629 size_t ll_ringbuffer_peek(ll_ringbuffer_t *rb, char *dest, size_t cnt);
630 void ll_ringbuffer_read_advance(ll_ringbuffer_t *rb, size_t cnt);
631 size_t ll_ringbuffer_read_space(const ll_ringbuffer_t *rb);
632 int ll_ringbuffer_mlock(ll_ringbuffer_t *rb);
633 void ll_ringbuffer_reset(ll_ringbuffer_t *rb);
634 size_t ll_ringbuffer_write(ll_ringbuffer_t *rb, const char *src, size_t cnt);
635 void ll_ringbuffer_write_advance(ll_ringbuffer_t *rb, size_t cnt);
636 size_t ll_ringbuffer_write_space(const ll_ringbuffer_t *rb);
638 void ReadALConfig(void);
639 void FreeALConfig(void);
640 int ConfigValueExists(const char *devName, const char *blockName, const char *keyName);
641 const char *GetConfigValue(const char *devName, const char *blockName, const char *keyName, const char *def);
642 int GetConfigValueBool(const char *devName, const char *blockName, const char *keyName, int def);
643 int ConfigValueStr(const char *devName, const char *blockName, const char *keyName, const char **ret);
644 int ConfigValueInt(const char *devName, const char *blockName, const char *keyName, int *ret);
645 int ConfigValueUInt(const char *devName, const char *blockName, const char *keyName, unsigned int *ret);
646 int ConfigValueFloat(const char *devName, const char *blockName, const char *keyName, float *ret);
647 int ConfigValueBool(const char *devName, const char *blockName, const char *keyName, int *ret);
649 void SetRTPriority(void);
651 void SetDefaultChannelOrder(ALCdevice *device);
652 void SetDefaultWFXChannelOrder(ALCdevice *device);
654 const ALCchar *DevFmtTypeString(enum DevFmtType type) DECL_CONST;
655 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans) DECL_CONST;
658 * GetChannelIdxByName
660 * Returns the device's channel index given a channel name (e.g. FrontCenter),
661 * or -1 if it doesn't exist.
663 inline ALint GetChannelIdxByName(const ALCdevice *device, enum Channel chan)
665 ALint i = 0;
666 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
668 if(device->ChannelName[i] == chan)
669 return i;
671 return -1;
675 extern FILE *LogFile;
677 #if defined(__GNUC__) && !defined(_WIN32) && !defined(IN_IDE_PARSER)
678 #define AL_PRINT(T, MSG, ...) fprintf(LogFile, "AL lib: %s %s: "MSG, T, __FUNCTION__ , ## __VA_ARGS__)
679 #else
680 void al_print(const char *type, const char *func, const char *fmt, ...) DECL_FORMAT(printf, 3,4);
681 #define AL_PRINT(T, ...) al_print((T), __FUNCTION__, __VA_ARGS__)
682 #endif
684 enum LogLevel {
685 NoLog,
686 LogError,
687 LogWarning,
688 LogTrace,
689 LogRef
691 extern enum LogLevel LogLevel;
693 #define TRACEREF(...) do { \
694 if(LogLevel >= LogRef) \
695 AL_PRINT("(--)", __VA_ARGS__); \
696 } while(0)
698 #define TRACE(...) do { \
699 if(LogLevel >= LogTrace) \
700 AL_PRINT("(II)", __VA_ARGS__); \
701 } while(0)
703 #define WARN(...) do { \
704 if(LogLevel >= LogWarning) \
705 AL_PRINT("(WW)", __VA_ARGS__); \
706 } while(0)
708 #define ERR(...) do { \
709 if(LogLevel >= LogError) \
710 AL_PRINT("(EE)", __VA_ARGS__); \
711 } while(0)
714 extern ALint RTPrioLevel;
717 extern ALuint CPUCapFlags;
718 enum {
719 CPU_CAP_SSE = 1<<0,
720 CPU_CAP_SSE2 = 1<<1,
721 CPU_CAP_SSE3 = 1<<2,
722 CPU_CAP_SSE4_1 = 1<<3,
723 CPU_CAP_NEON = 1<<4,
726 void FillCPUCaps(ALuint capfilter);
728 FILE *OpenDataFile(const char *fname, const char *subdir);
730 vector_al_string SearchDataFiles(const char *match, const char *subdir);
732 /* Small hack to use a pointer-to-array type as a normal argument type.
733 * Shouldn't be used directly. */
734 typedef ALfloat ALfloatBUFFERSIZE[BUFFERSIZE];
737 #ifdef __cplusplus
739 #endif
741 #endif