33 #include "static_assert.h"
44 #ifndef ALC_SOFT_device_clock
45 #define ALC_SOFT_device_clock 1
46 typedef int64_t ALCint64SOFT
;
47 typedef uint64_t ALCuint64SOFT
;
48 #define ALC_DEVICE_CLOCK_SOFT 0x1600
49 typedef void (ALC_APIENTRY
*LPALCGETINTEGER64VSOFT
)(ALCdevice
*device
, ALCenum pname
, ALsizei size
, ALCint64SOFT
*values
);
50 #ifdef AL_ALEXT_PROTOTYPES
51 ALC_API
void ALC_APIENTRY
alcGetInteger64vSOFT(ALCdevice
*device
, ALCenum pname
, ALsizei size
, ALCint64SOFT
*values
);
55 #ifndef AL_SOFT_buffer_samples2
56 #define AL_SOFT_buffer_samples2 1
57 /* Channel configurations */
58 #define AL_MONO_SOFT 0x1500
59 #define AL_STEREO_SOFT 0x1501
60 #define AL_REAR_SOFT 0x1502
61 #define AL_QUAD_SOFT 0x1503
62 #define AL_5POINT1_SOFT 0x1504
63 #define AL_6POINT1_SOFT 0x1505
64 #define AL_7POINT1_SOFT 0x1506
65 #define AL_BFORMAT2D_SOFT 0x1507
66 #define AL_BFORMAT3D_SOFT 0x1508
69 #define AL_BYTE_SOFT 0x1400
70 #define AL_UNSIGNED_BYTE_SOFT 0x1401
71 #define AL_SHORT_SOFT 0x1402
72 #define AL_UNSIGNED_SHORT_SOFT 0x1403
73 #define AL_INT_SOFT 0x1404
74 #define AL_UNSIGNED_INT_SOFT 0x1405
75 #define AL_FLOAT_SOFT 0x1406
76 #define AL_DOUBLE_SOFT 0x1407
77 #define AL_BYTE3_SOFT 0x1408
78 #define AL_UNSIGNED_BYTE3_SOFT 0x1409
79 #define AL_MULAW_SOFT 0x140A
82 #define AL_MONO8_SOFT 0x1100
83 #define AL_MONO16_SOFT 0x1101
84 #define AL_MONO32F_SOFT 0x10010
85 #define AL_STEREO8_SOFT 0x1102
86 #define AL_STEREO16_SOFT 0x1103
87 #define AL_STEREO32F_SOFT 0x10011
88 #define AL_QUAD8_SOFT 0x1204
89 #define AL_QUAD16_SOFT 0x1205
90 #define AL_QUAD32F_SOFT 0x1206
91 #define AL_REAR8_SOFT 0x1207
92 #define AL_REAR16_SOFT 0x1208
93 #define AL_REAR32F_SOFT 0x1209
94 #define AL_5POINT1_8_SOFT 0x120A
95 #define AL_5POINT1_16_SOFT 0x120B
96 #define AL_5POINT1_32F_SOFT 0x120C
97 #define AL_6POINT1_8_SOFT 0x120D
98 #define AL_6POINT1_16_SOFT 0x120E
99 #define AL_6POINT1_32F_SOFT 0x120F
100 #define AL_7POINT1_8_SOFT 0x1210
101 #define AL_7POINT1_16_SOFT 0x1211
102 #define AL_7POINT1_32F_SOFT 0x1212
103 #define AL_BFORMAT2D_8_SOFT 0x20021
104 #define AL_BFORMAT2D_16_SOFT 0x20022
105 #define AL_BFORMAT2D_32F_SOFT 0x20023
106 #define AL_BFORMAT3D_8_SOFT 0x20031
107 #define AL_BFORMAT3D_16_SOFT 0x20032
108 #define AL_BFORMAT3D_32F_SOFT 0x20033
110 /* Buffer attributes */
111 #define AL_INTERNAL_FORMAT_SOFT 0x2008
112 #define AL_BYTE_LENGTH_SOFT 0x2009
113 #define AL_SAMPLE_LENGTH_SOFT 0x200A
114 #define AL_SEC_LENGTH_SOFT 0x200B
117 typedef void (AL_APIENTRY
*LPALBUFFERSAMPLESSOFT
)(ALuint
,ALuint
,ALenum
,ALsizei
,ALenum
,ALenum
,const ALvoid
*);
118 typedef void (AL_APIENTRY
*LPALGETBUFFERSAMPLESSOFT
)(ALuint
,ALsizei
,ALsizei
,ALenum
,ALenum
,ALvoid
*);
119 typedef ALboolean (AL_APIENTRY
*LPALISBUFFERFORMATSUPPORTEDSOFT
)(ALenum
);
120 #ifdef AL_ALEXT_PROTOTYPES
121 AL_API
void AL_APIENTRY
alBufferSamplesSOFT(ALuint buffer
, ALuint samplerate
, ALenum internalformat
, ALsizei samples
, ALenum channels
, ALenum type
, const ALvoid
*data
);
122 AL_API
void AL_APIENTRY
alGetBufferSamplesSOFT(ALuint buffer
, ALsizei offset
, ALsizei samples
, ALenum channels
, ALenum type
, ALvoid
*data
);
123 AL_API ALboolean AL_APIENTRY
alIsBufferFormatSupportedSOFT(ALenum format
);
129 typedef ALint64SOFT ALint64
;
130 typedef ALuint64SOFT ALuint64
;
133 #if defined(_MSC_VER)
134 #define U64(x) ((ALuint64)(x##ui64))
135 #elif SIZEOF_LONG == 8
136 #define U64(x) ((ALuint64)(x##ul))
137 #elif SIZEOF_LONG_LONG == 8
138 #define U64(x) ((ALuint64)(x##ull))
143 #define UINT64_MAX U64(18446744073709551615)
147 #if defined(__cplusplus)
149 #elif defined(__GNUC__)
150 #define UNUSED(x) UNUSED_##x __attribute__((unused))
151 #elif defined(__LCLINT__)
152 #define UNUSED(x) /*@unused@*/ x
159 #define DECL_CONST __attribute__((const))
160 #define DECL_FORMAT(x, y, z) __attribute__((format(x, (y), (z))))
163 #define DECL_FORMAT(x, y, z)
166 #if defined(__GNUC__) && defined(__i386__)
167 /* force_align_arg_pointer is required for proper function arguments aligning
168 * when SSE code is used. Some systems (Windows, QNX) do not guarantee our
169 * thread functions will be properly aligned on the stack, even though GCC may
170 * generate code with the assumption that it is. */
171 #define FORCE_ALIGN __attribute__((force_align_arg_pointer))
177 #define DECL_VLA(T, _name, _size) T _name[(_size)]
179 #define DECL_VLA(T, _name, _size) T *_name = alloca((_size) * sizeof(T))
184 #define PATH_MAX MAX_PATH
186 #define PATH_MAX 4096
193 ALubyte b
[sizeof(ALuint
)];
194 } EndianTest
= { 1 };
195 #define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1)
197 #define COUNTOF(x) (sizeof((x))/sizeof((x)[0]))
200 #define DERIVE_FROM_TYPE(t) t t##_parent
201 #define STATIC_CAST(to, obj) (&(obj)->to##_parent)
203 #define STATIC_UPCAST(to, from, obj) __extension__({ \
204 static_assert(__builtin_types_compatible_p(from, __typeof(*(obj))), \
205 "Invalid upcast object from type"); \
206 (to*)((char*)(obj) - offsetof(to, from##_parent)); \
209 #define STATIC_UPCAST(to, from, obj) ((to*)((char*)(obj) - offsetof(to, from##_parent)))
212 #define DECLARE_FORWARD(T1, T2, rettype, func) \
213 rettype T1##_##func(T1 *obj) \
214 { return T2##_##func(STATIC_CAST(T2, obj)); }
216 #define DECLARE_FORWARD1(T1, T2, rettype, func, argtype1) \
217 rettype T1##_##func(T1 *obj, argtype1 a) \
218 { return T2##_##func(STATIC_CAST(T2, obj), a); }
220 #define DECLARE_FORWARD2(T1, T2, rettype, func, argtype1, argtype2) \
221 rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b) \
222 { return T2##_##func(STATIC_CAST(T2, obj), a, b); }
224 #define DECLARE_FORWARD3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
225 rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b, argtype3 c) \
226 { return T2##_##func(STATIC_CAST(T2, obj), a, b, c); }
229 #define GET_VTABLE1(T1) (&(T1##_vtable))
230 #define GET_VTABLE2(T1, T2) (&(T1##_##T2##_vtable))
232 #define SET_VTABLE1(T1, obj) ((obj)->vtbl = GET_VTABLE1(T1))
233 #define SET_VTABLE2(T1, T2, obj) (STATIC_CAST(T2, obj)->vtbl = GET_VTABLE2(T1, T2))
235 #define DECLARE_THUNK(T1, T2, rettype, func) \
236 static rettype T1##_##T2##_##func(T2 *obj) \
237 { return T1##_##func(STATIC_UPCAST(T1, T2, obj)); }
239 #define DECLARE_THUNK1(T1, T2, rettype, func, argtype1) \
240 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a) \
241 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a); }
243 #define DECLARE_THUNK2(T1, T2, rettype, func, argtype1, argtype2) \
244 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b) \
245 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b); }
247 #define DECLARE_THUNK3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
248 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c) \
249 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c); }
251 #define DECLARE_THUNK4(T1, T2, rettype, func, argtype1, argtype2, argtype3, argtype4) \
252 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c, argtype4 d) \
253 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c, d); }
255 #define DECLARE_DEFAULT_ALLOCATORS(T) \
256 static void* T##_New(size_t size) { return al_malloc(16, size); } \
257 static void T##_Delete(void *ptr) { al_free(ptr); }
259 /* Helper to extract an argument list for VCALL. Not used directly. */
260 #define EXTRACT_VCALL_ARGS(...) __VA_ARGS__))
262 /* Call a "virtual" method on an object, with arguments. */
263 #define V(obj, func) ((obj)->vtbl->func((obj), EXTRACT_VCALL_ARGS
264 /* Call a "virtual" method on an object, with no arguments. */
265 #define V0(obj, func) ((obj)->vtbl->func((obj) EXTRACT_VCALL_ARGS
267 #define DELETE_OBJ(obj) do { \
270 V0((obj),Destruct)(); \
271 V0((obj),Delete)(); \
276 #define EXTRACT_NEW_ARGS(...) __VA_ARGS__); \
280 #define NEW_OBJ(_res, T) do { \
281 _res = T##_New(sizeof(T)); \
284 memset(_res, 0, sizeof(T)); \
285 T##_Construct(_res, EXTRACT_NEW_ARGS
295 #define DEFAULT_OUTPUT_RATE (44100)
296 #define MIN_OUTPUT_RATE (8000)
299 /* Find the next power-of-2 for non-power-of-2 numbers. */
300 inline ALuint
NextPowerOf2(ALuint value
)
314 /* Fast float-to-int conversion. Assumes the FPU is already in round-to-zero
316 inline ALint
fastf2i(ALfloat f
)
320 #elif defined(_MSC_VER) && defined(_M_IX86)
330 /* Fast float-to-uint conversion. Assumes the FPU is already in round-to-zero
332 inline ALuint
fastf2u(ALfloat f
)
333 { return fastf2i(f
); }
342 ALCenum (*OpenPlayback
)(ALCdevice
*, const ALCchar
*);
343 void (*ClosePlayback
)(ALCdevice
*);
344 ALCboolean (*ResetPlayback
)(ALCdevice
*);
345 ALCboolean (*StartPlayback
)(ALCdevice
*);
346 void (*StopPlayback
)(ALCdevice
*);
348 ALCenum (*OpenCapture
)(ALCdevice
*, const ALCchar
*);
349 void (*CloseCapture
)(ALCdevice
*);
350 void (*StartCapture
)(ALCdevice
*);
351 void (*StopCapture
)(ALCdevice
*);
352 ALCenum (*CaptureSamples
)(ALCdevice
*, void*, ALCuint
);
353 ALCuint (*AvailableSamples
)(ALCdevice
*);
356 ALCboolean
alc_sndio_init(BackendFuncs
*func_list
);
357 void alc_sndio_deinit(void);
358 void alc_sndio_probe(enum DevProbe type
);
359 ALCboolean
alc_ca_init(BackendFuncs
*func_list
);
360 void alc_ca_deinit(void);
361 void alc_ca_probe(enum DevProbe type
);
362 ALCboolean
alc_opensl_init(BackendFuncs
*func_list
);
363 void alc_opensl_deinit(void);
364 void alc_opensl_probe(enum DevProbe type
);
365 ALCboolean
alc_qsa_init(BackendFuncs
*func_list
);
366 void alc_qsa_deinit(void);
367 void alc_qsa_probe(enum DevProbe type
);
373 InverseDistanceClamped
= AL_INVERSE_DISTANCE_CLAMPED
,
374 LinearDistanceClamped
= AL_LINEAR_DISTANCE_CLAMPED
,
375 ExponentDistanceClamped
= AL_EXPONENT_DISTANCE_CLAMPED
,
376 InverseDistance
= AL_INVERSE_DISTANCE
,
377 LinearDistance
= AL_LINEAR_DISTANCE
,
378 ExponentDistance
= AL_EXPONENT_DISTANCE
,
379 DisableDistance
= AL_NONE
,
381 DefaultDistanceModel
= InverseDistanceClamped
427 DevFmtByte
= ALC_BYTE_SOFT
,
428 DevFmtUByte
= ALC_UNSIGNED_BYTE_SOFT
,
429 DevFmtShort
= ALC_SHORT_SOFT
,
430 DevFmtUShort
= ALC_UNSIGNED_SHORT_SOFT
,
431 DevFmtInt
= ALC_INT_SOFT
,
432 DevFmtUInt
= ALC_UNSIGNED_INT_SOFT
,
433 DevFmtFloat
= ALC_FLOAT_SOFT
,
435 DevFmtTypeDefault
= DevFmtFloat
437 enum DevFmtChannels
{
438 DevFmtMono
= ALC_MONO_SOFT
,
439 DevFmtStereo
= ALC_STEREO_SOFT
,
440 DevFmtQuad
= ALC_QUAD_SOFT
,
441 DevFmtX51
= ALC_5POINT1_SOFT
,
442 DevFmtX61
= ALC_6POINT1_SOFT
,
443 DevFmtX71
= ALC_7POINT1_SOFT
,
445 /* Similar to 5.1, except using rear channels instead of sides */
446 DevFmtX51Rear
= 0x80000000,
450 DevFmtChannelsDefault
= DevFmtStereo
452 #define MAX_OUTPUT_CHANNELS (16)
454 ALuint
BytesFromDevFmt(enum DevFmtType type
) DECL_CONST
;
455 ALuint
ChannelsFromDevFmt(enum DevFmtChannels chans
) DECL_CONST
;
456 inline ALuint
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
)
458 return ChannelsFromDevFmt(chans
) * BytesFromDevFmt(type
);
462 extern const struct EffectList
{
484 /* The maximum number of Ambisonics coefficients. For a given order (o), the
485 * size needed will be (o+1)**2, thus zero-order has 1, first-order has 4,
486 * second-order has 9, and third-order has 16. */
487 #define MAX_AMBI_ORDER 3
488 #define MAX_AMBI_COEFFS ((MAX_AMBI_ORDER+1) * (MAX_AMBI_ORDER+1))
490 typedef ALfloat ChannelConfig
[MAX_AMBI_COEFFS
];
491 typedef struct BFChannelConfig
{
497 #define HRTF_HISTORY_BITS (6)
498 #define HRTF_HISTORY_LENGTH (1<<HRTF_HISTORY_BITS)
499 #define HRTF_HISTORY_MASK (HRTF_HISTORY_LENGTH-1)
501 typedef struct HrtfState
{
502 alignas(16) ALfloat History
[HRTF_HISTORY_LENGTH
];
503 alignas(16) ALfloat Values
[HRIR_LENGTH
][2];
506 typedef struct HrtfParams
{
507 alignas(16) ALfloat Coeffs
[HRIR_LENGTH
][2];
512 /* Size for temporary storage of buffer data, in ALfloats. Larger values need
513 * more memory, while smaller values may need more iterations. The value needs
514 * to be a sensible size, however, as it constrains the max stepping value used
515 * for mixing, as well as the maximum number of samples per mixing iteration.
517 #define BUFFERSIZE (2048u)
519 struct ALCdevice_struct
523 ALCboolean Connected
;
524 enum DeviceType Type
;
529 enum DevFmtChannels FmtChans
;
530 enum DevFmtType FmtType
;
531 ALboolean IsHeadphones
;
533 al_string DeviceName
;
535 ATOMIC(ALCenum
) LastError
;
537 // Maximum number of sources that can be created
538 ALuint MaxNoOfSources
;
539 // Maximum number of slots that can be created
540 ALuint AuxiliaryEffectSlotMax
;
542 ALCuint NumMonoSources
;
543 ALCuint NumStereoSources
;
546 // Map of Buffers for this device
549 // Map of Effects for this device
552 // Map of Filters for this device
555 /* HRTF filter tables */
556 vector_HrtfEntry Hrtf_List
;
558 const struct Hrtf
*Hrtf
;
561 /* HRTF filter state for dry buffer content */
562 HrtfState Hrtf_State
[MAX_OUTPUT_CHANNELS
];
563 HrtfParams Hrtf_Params
[MAX_OUTPUT_CHANNELS
];
566 /* UHJ encoder state */
567 struct Uhj2Encoder
*Uhj_Encoder
;
569 /* High quality Ambisonic decoder */
570 struct BFormatDec
*AmbiDecoder
;
572 // Stereo-to-binaural filter
575 /* Rendering mode. */
576 enum RenderMode Render_Mode
;
584 /* Temp storage used for each source when mixing. */
585 alignas(16) ALfloat SourceData
[BUFFERSIZE
];
586 alignas(16) ALfloat ResampledData
[BUFFERSIZE
];
587 alignas(16) ALfloat FilteredData
[BUFFERSIZE
];
589 /* The "dry" path corresponds to the main output. */
592 /* Ambisonic coefficients for mixing to the dry buffer. */
593 ChannelConfig Coeffs
[MAX_OUTPUT_CHANNELS
];
594 /* Coefficient channel mapping for mixing to the dry buffer. */
595 BFChannelConfig Map
[MAX_OUTPUT_CHANNELS
];
597 /* Number of coefficients in each ChannelConfig to mix together (4 for
598 * first-order, 9 for second-order, etc). If the count is 0, the
599 * BFChannelConfig is used instead to map each output to a coefficient
604 /* Dry buffer will be aliased by the virtual or real output. */
605 ALfloat (*Buffer
)[BUFFERSIZE
];
609 /* First-order ambisonics output, to be upsampled to the dry buffer if different. */
612 ChannelConfig Coeffs
[MAX_OUTPUT_CHANNELS
];
613 BFChannelConfig Map
[MAX_OUTPUT_CHANNELS
];
615 /* Will only be 4 or 0. */
618 ALfloat (*Buffer
)[BUFFERSIZE
];
622 /* Virtual output, to be post-processed to the real output. */
624 ALfloat (*Buffer
)[BUFFERSIZE
];
627 /* "Real" output, which will be written to the device buffer. */
629 enum Channel ChannelName
[MAX_OUTPUT_CHANNELS
];
631 ALfloat (*Buffer
)[BUFFERSIZE
];
635 /* Running count of the mixer invocations, in 31.1 fixed point. This
636 * actually increments *twice* when mixing, first at the start and then at
637 * the end, so the bottom bit indicates if the device is currently mixing
638 * and the upper bits indicates how many mixes have been done.
642 /* Default effect slot */
643 struct ALeffectslot
*DefaultSlot
;
645 // Contexts created on this device
646 ATOMIC(ALCcontext
*) ContextList
;
649 struct ALCbackend
*Backend
;
651 void *ExtraData
; // For the backend's use
653 ALCdevice
*volatile next
;
655 /* Memory space used by the default slot (Playback devices only) */
656 alignas(16) ALCbyte _slot_mem
[];
659 // Frequency was requested by the app or config file
660 #define DEVICE_FREQUENCY_REQUEST (1<<1)
661 // Channel configuration was requested by the config file
662 #define DEVICE_CHANNELS_REQUEST (1<<2)
663 // Sample type was requested by the config file
664 #define DEVICE_SAMPLE_TYPE_REQUEST (1<<3)
666 // Specifies if the DSP is paused at user request
667 #define DEVICE_PAUSED (1<<30)
669 // Specifies if the device is currently running
670 #define DEVICE_RUNNING (1<<31)
673 /* Nanosecond resolution for the device clock time. */
674 #define DEVICE_CLOCK_RES U64(1000000000)
677 /* Must be less than 15 characters (16 including terminating null) for
678 * compatibility with pthread_setname_np limitations. */
679 #define MIXER_THREAD_NAME "alsoft-mixer"
681 #define RECORD_THREAD_NAME "alsoft-record"
684 struct ALCcontext_struct
{
687 struct ALlistener
*Listener
;
690 UIntMap EffectSlotMap
;
692 ATOMIC(ALenum
) LastError
;
694 volatile enum DistanceModel DistanceModel
;
695 volatile ALboolean SourceDistanceModel
;
697 volatile ALfloat DopplerFactor
;
698 volatile ALfloat DopplerVelocity
;
699 volatile ALfloat SpeedOfSound
;
700 ATOMIC(ALenum
) DeferUpdates
;
704 /* Counter for the pre-mixing updates, in 31.1 fixed point (lowest bit
705 * indicates if updates are currently happening).
707 RefCount UpdateCount
;
708 ATOMIC(ALenum
) HoldUpdates
;
710 struct ALvoice
*Voices
;
714 VECTOR(struct ALeffectslot
*) ActiveAuxSlots
;
717 const ALCchar
*ExtensionList
;
719 ALCcontext
*volatile next
;
721 /* Memory space used by the listener */
722 alignas(16) ALCbyte _listener_mem
[];
725 ALCcontext
*GetContextRef(void);
727 void ALCcontext_IncRef(ALCcontext
*context
);
728 void ALCcontext_DecRef(ALCcontext
*context
);
730 void AppendAllDevicesList(const ALCchar
*name
);
731 void AppendCaptureDeviceList(const ALCchar
*name
);
733 void ALCdevice_Lock(ALCdevice
*device
);
734 void ALCdevice_Unlock(ALCdevice
*device
);
736 void ALCcontext_DeferUpdates(ALCcontext
*context
);
737 void ALCcontext_ProcessUpdates(ALCcontext
*context
);
739 inline void LockContext(ALCcontext
*context
)
740 { ALCdevice_Lock(context
->Device
); }
742 inline void UnlockContext(ALCcontext
*context
)
743 { ALCdevice_Unlock(context
->Device
); }
748 DERIVE_FROM_TYPE(fenv_t
);
756 void SetMixerFPUMode(FPUCtl
*ctl
);
757 void RestoreFPUMode(const FPUCtl
*ctl
);
760 typedef struct ll_ringbuffer ll_ringbuffer_t
;
761 typedef struct ll_ringbuffer_data
{
764 } ll_ringbuffer_data_t
;
765 ll_ringbuffer_t
*ll_ringbuffer_create(size_t sz
, size_t elem_sz
);
766 void ll_ringbuffer_free(ll_ringbuffer_t
*rb
);
767 void ll_ringbuffer_get_read_vector(const ll_ringbuffer_t
*rb
, ll_ringbuffer_data_t
*vec
);
768 void ll_ringbuffer_get_write_vector(const ll_ringbuffer_t
*rb
, ll_ringbuffer_data_t
*vec
);
769 size_t ll_ringbuffer_read(ll_ringbuffer_t
*rb
, char *dest
, size_t cnt
);
770 size_t ll_ringbuffer_peek(ll_ringbuffer_t
*rb
, char *dest
, size_t cnt
);
771 void ll_ringbuffer_read_advance(ll_ringbuffer_t
*rb
, size_t cnt
);
772 size_t ll_ringbuffer_read_space(const ll_ringbuffer_t
*rb
);
773 int ll_ringbuffer_mlock(ll_ringbuffer_t
*rb
);
774 void ll_ringbuffer_reset(ll_ringbuffer_t
*rb
);
775 size_t ll_ringbuffer_write(ll_ringbuffer_t
*rb
, const char *src
, size_t cnt
);
776 void ll_ringbuffer_write_advance(ll_ringbuffer_t
*rb
, size_t cnt
);
777 size_t ll_ringbuffer_write_space(const ll_ringbuffer_t
*rb
);
779 void ReadALConfig(void);
780 void FreeALConfig(void);
781 int ConfigValueExists(const char *devName
, const char *blockName
, const char *keyName
);
782 const char *GetConfigValue(const char *devName
, const char *blockName
, const char *keyName
, const char *def
);
783 int GetConfigValueBool(const char *devName
, const char *blockName
, const char *keyName
, int def
);
784 int ConfigValueStr(const char *devName
, const char *blockName
, const char *keyName
, const char **ret
);
785 int ConfigValueInt(const char *devName
, const char *blockName
, const char *keyName
, int *ret
);
786 int ConfigValueUInt(const char *devName
, const char *blockName
, const char *keyName
, unsigned int *ret
);
787 int ConfigValueFloat(const char *devName
, const char *blockName
, const char *keyName
, float *ret
);
788 int ConfigValueBool(const char *devName
, const char *blockName
, const char *keyName
, int *ret
);
790 void SetRTPriority(void);
792 void SetDefaultChannelOrder(ALCdevice
*device
);
793 void SetDefaultWFXChannelOrder(ALCdevice
*device
);
795 const ALCchar
*DevFmtTypeString(enum DevFmtType type
) DECL_CONST
;
796 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
) DECL_CONST
;
799 * GetChannelIdxByName
801 * Returns the index for the given channel name (e.g. FrontCenter), or -1 if it
804 inline ALint
GetChannelIndex(const enum Channel names
[MAX_OUTPUT_CHANNELS
], enum Channel chan
)
807 for(i
= 0;i
< MAX_OUTPUT_CHANNELS
;i
++)
814 #define GetChannelIdxByName(x, c) GetChannelIndex((x).ChannelName, (c))
816 extern FILE *LogFile
;
818 #if defined(__GNUC__) && !defined(_WIN32) && !defined(IN_IDE_PARSER)
819 #define AL_PRINT(T, MSG, ...) fprintf(LogFile, "AL lib: %s %s: "MSG, T, __FUNCTION__ , ## __VA_ARGS__)
821 void al_print(const char *type
, const char *func
, const char *fmt
, ...) DECL_FORMAT(printf
, 3,4);
822 #define AL_PRINT(T, ...) al_print((T), __FUNCTION__, __VA_ARGS__)
832 extern enum LogLevel LogLevel
;
834 #define TRACEREF(...) do { \
835 if(LogLevel >= LogRef) \
836 AL_PRINT("(--)", __VA_ARGS__); \
839 #define TRACE(...) do { \
840 if(LogLevel >= LogTrace) \
841 AL_PRINT("(II)", __VA_ARGS__); \
844 #define WARN(...) do { \
845 if(LogLevel >= LogWarning) \
846 AL_PRINT("(WW)", __VA_ARGS__); \
849 #define ERR(...) do { \
850 if(LogLevel >= LogError) \
851 AL_PRINT("(EE)", __VA_ARGS__); \
855 extern ALint RTPrioLevel
;
858 extern ALuint CPUCapFlags
;
863 CPU_CAP_SSE4_1
= 1<<3,
867 void FillCPUCaps(ALuint capfilter
);
869 vector_al_string
SearchDataFiles(const char *match
, const char *subdir
);
871 /* Small hack to use a pointer-to-array type as a normal argument type.
872 * Shouldn't be used directly. */
873 typedef ALfloat ALfloatBUFFERSIZE
[BUFFERSIZE
];