Don't modify the late reverb density with the echo parameters
[openal-soft.git] / OpenAL32 / Include / alMain.h
blob74dba1ad0367cbced7a977b27f3099882544ca50
1 #ifndef AL_MAIN_H
2 #define AL_MAIN_H
4 #include <string.h>
5 #include <stdio.h>
6 #include <stddef.h>
7 #include <stdarg.h>
8 #include <assert.h>
9 #include <math.h>
10 #include <limits.h>
12 #ifdef HAVE_STRINGS_H
13 #include <strings.h>
14 #endif
15 #ifdef HAVE_INTRIN_H
16 #include <intrin.h>
17 #endif
19 #include "AL/al.h"
20 #include "AL/alc.h"
21 #include "AL/alext.h"
23 #include "inprogext.h"
24 #include "logging.h"
25 #include "polymorphism.h"
26 #include "static_assert.h"
27 #include "align.h"
28 #include "atomic.h"
29 #include "vector.h"
30 #include "alstring.h"
31 #include "almalloc.h"
32 #include "threads.h"
35 #if defined(_WIN64)
36 #define SZFMT "%I64u"
37 #elif defined(_WIN32)
38 #define SZFMT "%u"
39 #else
40 #define SZFMT "%zu"
41 #endif
43 #ifdef __has_builtin
44 #define HAS_BUILTIN __has_builtin
45 #else
46 #define HAS_BUILTIN(x) (0)
47 #endif
49 #ifdef __GNUC__
50 /* LIKELY optimizes the case where the condition is true. The condition is not
51 * required to be true, but it can result in more optimal code for the true
52 * path at the expense of a less optimal false path.
54 #define LIKELY(x) __builtin_expect(!!(x), !0)
55 /* The opposite of LIKELY, optimizing the case where the condition is false. */
56 #define UNLIKELY(x) __builtin_expect(!!(x), 0)
57 /* Unlike LIKELY, ASSUME requires the condition to be true or else it invokes
58 * undefined behavior. It's essentially an assert without actually checking the
59 * condition at run-time, allowing for stronger optimizations than LIKELY.
61 #if HAS_BUILTIN(__builtin_assume)
62 #define ASSUME __builtin_assume
63 #else
64 #define ASSUME(x) do { if(!(x)) __builtin_unreachable(); } while(0)
65 #endif
67 #else
69 #define LIKELY(x) (!!(x))
70 #define UNLIKELY(x) (!!(x))
71 #ifdef _MSC_VER
72 #define ASSUME __assume
73 #else
74 #define ASSUME(x) ((void)0)
75 #endif
76 #endif
78 #ifndef UINT64_MAX
79 #define UINT64_MAX U64(18446744073709551615)
80 #endif
82 #ifndef UNUSED
83 #if defined(__cplusplus)
84 #define UNUSED(x)
85 #elif defined(__GNUC__)
86 #define UNUSED(x) UNUSED_##x __attribute__((unused))
87 #elif defined(__LCLINT__)
88 #define UNUSED(x) /*@unused@*/ x
89 #else
90 #define UNUSED(x) x
91 #endif
92 #endif
94 /* Calculates the size of a struct with N elements of a flexible array member.
95 * GCC and Clang allow offsetof(Type, fam[N]) for this, but MSVC seems to have
96 * trouble, so a bit more verbose workaround is needed.
98 #define FAM_SIZE(T, M, N) (offsetof(T, M) + sizeof(((T*)NULL)->M[0])*(N))
101 #ifdef __cplusplus
102 extern "C" {
103 #endif
105 typedef ALint64SOFT ALint64;
106 typedef ALuint64SOFT ALuint64;
108 #ifndef U64
109 #if defined(_MSC_VER)
110 #define U64(x) ((ALuint64)(x##ui64))
111 #elif SIZEOF_LONG == 8
112 #define U64(x) ((ALuint64)(x##ul))
113 #elif SIZEOF_LONG_LONG == 8
114 #define U64(x) ((ALuint64)(x##ull))
115 #endif
116 #endif
118 #ifndef I64
119 #if defined(_MSC_VER)
120 #define I64(x) ((ALint64)(x##i64))
121 #elif SIZEOF_LONG == 8
122 #define I64(x) ((ALint64)(x##l))
123 #elif SIZEOF_LONG_LONG == 8
124 #define I64(x) ((ALint64)(x##ll))
125 #endif
126 #endif
128 /* Define a CTZ64 macro (count trailing zeros, for 64-bit integers). The result
129 * is *UNDEFINED* if the value is 0.
131 #ifdef __GNUC__
133 #if SIZEOF_LONG == 8
134 #define CTZ64 __builtin_ctzl
135 #else
136 #define CTZ64 __builtin_ctzll
137 #endif
139 #elif defined(HAVE_BITSCANFORWARD64_INTRINSIC)
141 inline int msvc64_ctz64(ALuint64 v)
143 unsigned long idx = 64;
144 _BitScanForward64(&idx, v);
145 return (int)idx;
147 #define CTZ64 msvc64_ctz64
149 #elif defined(HAVE_BITSCANFORWARD_INTRINSIC)
151 inline int msvc_ctz64(ALuint64 v)
153 unsigned long idx = 64;
154 if(!_BitScanForward(&idx, v&0xffffffff))
156 if(_BitScanForward(&idx, v>>32))
157 idx += 32;
159 return (int)idx;
161 #define CTZ64 msvc_ctz64
163 #else
165 /* There be black magics here. The popcnt64 method is derived from
166 * https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
167 * while the ctz-utilizing-popcnt algorithm is shown here
168 * http://www.hackersdelight.org/hdcodetxt/ntz.c.txt
169 * as the ntz2 variant. These likely aren't the most efficient methods, but
170 * they're good enough if the GCC or MSVC intrinsics aren't available.
172 inline int fallback_popcnt64(ALuint64 v)
174 v = v - ((v >> 1) & U64(0x5555555555555555));
175 v = (v & U64(0x3333333333333333)) + ((v >> 2) & U64(0x3333333333333333));
176 v = (v + (v >> 4)) & U64(0x0f0f0f0f0f0f0f0f);
177 return (int)((v * U64(0x0101010101010101)) >> 56);
180 inline int fallback_ctz64(ALuint64 value)
182 return fallback_popcnt64(~value & (value - 1));
184 #define CTZ64 fallback_ctz64
185 #endif
187 #if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
188 #define IS_LITTLE_ENDIAN (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
189 #else
190 static const union {
191 ALuint u;
192 ALubyte b[sizeof(ALuint)];
193 } EndianTest = { 1 };
194 #define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1)
195 #endif
197 #define COUNTOF(x) (sizeof(x) / sizeof(0[x]))
200 struct ll_ringbuffer;
201 struct Hrtf;
202 struct HrtfEntry;
203 struct DirectHrtfState;
204 struct FrontStablizer;
205 struct Compressor;
206 struct ALCbackend;
207 struct ALbuffer;
208 struct ALeffect;
209 struct ALfilter;
210 struct ALsource;
211 struct ALcontextProps;
212 struct ALlistenerProps;
213 struct ALvoiceProps;
214 struct ALeffectslotProps;
217 #define DEFAULT_OUTPUT_RATE (44100)
218 #define MIN_OUTPUT_RATE (8000)
221 /* Find the next power-of-2 for non-power-of-2 numbers. */
222 inline ALuint NextPowerOf2(ALuint value)
224 if(value > 0)
226 value--;
227 value |= value>>1;
228 value |= value>>2;
229 value |= value>>4;
230 value |= value>>8;
231 value |= value>>16;
233 return value+1;
236 /** Round up a value to the next multiple. */
237 inline size_t RoundUp(size_t value, size_t r)
239 value += r-1;
240 return value - (value%r);
243 /* Fast float-to-int conversion. No particular rounding mode is assumed; the
244 * IEEE-754 default is round-to-nearest with ties-to-even, though an app could
245 * change it on its own threads. On some systems, a truncating conversion may
246 * always be the fastest method.
248 inline ALint fastf2i(ALfloat f)
250 #if defined(HAVE_INTRIN_H) && ((defined(_M_IX86_FP) && (_M_IX86_FP > 0)) || defined(_M_X64))
251 return _mm_cvt_ss2si(_mm_set1_ps(f));
253 #elif defined(_MSC_VER) && defined(_M_IX86_FP)
255 ALint i;
256 __asm fld f
257 __asm fistp i
258 return i;
260 #elif (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))
262 ALint i;
263 #ifdef __SSE_MATH__
264 __asm__("cvtss2si %1, %0" : "=r"(i) : "x"(f));
265 #else
266 __asm__ __volatile__("fistpl %0" : "=m"(i) : "t"(f) : "st");
267 #endif
268 return i;
270 /* On GCC when compiling with -fno-math-errno, lrintf can be inlined to
271 * some simple instructions. Clang does not inline it, always generating a
272 * libc call, while MSVC's implementation is horribly slow, so always fall
273 * back to a normal integer conversion for them.
275 #elif defined(HAVE_LRINTF) && !defined(_MSC_VER) && !defined(__clang__)
277 return lrintf(f);
279 #else
281 return (ALint)f;
282 #endif
285 /* Converts float-to-int using standard behavior (truncation). */
286 inline int float2int(float f)
288 #if ((defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__)) && \
289 !defined(__SSE_MATH__)) || (defined(_MSC_VER) && defined(_M_IX86_FP) && _M_IX86_FP == 0)
290 ALint sign, shift, mant;
291 union {
292 ALfloat f;
293 ALint i;
294 } conv;
296 conv.f = f;
297 sign = (conv.i>>31) | 1;
298 shift = ((conv.i>>23)&0xff) - (127+23);
300 /* Over/underflow */
301 if(UNLIKELY(shift >= 31 || shift < -23))
302 return 0;
304 mant = (conv.i&0x7fffff) | 0x800000;
305 if(LIKELY(shift < 0))
306 return (mant >> -shift) * sign;
307 return (mant << shift) * sign;
309 #else
311 return (ALint)f;
312 #endif
315 /* Rounds a float to the nearest integral value, according to the current
316 * rounding mode. This is essentially an inlined version of rintf, although
317 * makes fewer promises (e.g. -0 or -0.25 rounded to 0 may result in +0).
319 inline float fast_roundf(float f)
321 #if (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__)) && \
322 !defined(__SSE_MATH__)
324 float out;
325 __asm__ __volatile__("frndint" : "=t"(out) : "0"(f));
326 return out;
328 #else
330 /* Integral limit, where sub-integral precision is not available for
331 * floats.
333 static const float ilim[2] = {
334 8388608.0f /* 0x1.0p+23 */,
335 -8388608.0f /* -0x1.0p+23 */
337 ALuint sign, expo;
338 union {
339 ALfloat f;
340 ALuint i;
341 } conv;
343 conv.f = f;
344 sign = (conv.i>>31)&0x01;
345 expo = (conv.i>>23)&0xff;
347 if(UNLIKELY(expo >= 150/*+23*/))
349 /* An exponent (base-2) of 23 or higher is incapable of sub-integral
350 * precision, so it's already an integral value. We don't need to worry
351 * about infinity or NaN here.
353 return f;
355 /* Adding the integral limit to the value (with a matching sign) forces a
356 * result that has no sub-integral precision, and is consequently forced to
357 * round to an integral value. Removing the integral limit then restores
358 * the initial value rounded to the integral. The compiler should not
359 * optimize this out because of non-associative rules on floating-point
360 * math (as long as you don't use -fassociative-math,
361 * -funsafe-math-optimizations, -ffast-math, or -Ofast, in which case this
362 * may break).
364 f += ilim[sign];
365 return f - ilim[sign];
366 #endif
370 enum DevProbe {
371 ALL_DEVICE_PROBE,
372 CAPTURE_DEVICE_PROBE
376 enum DistanceModel {
377 InverseDistanceClamped = AL_INVERSE_DISTANCE_CLAMPED,
378 LinearDistanceClamped = AL_LINEAR_DISTANCE_CLAMPED,
379 ExponentDistanceClamped = AL_EXPONENT_DISTANCE_CLAMPED,
380 InverseDistance = AL_INVERSE_DISTANCE,
381 LinearDistance = AL_LINEAR_DISTANCE,
382 ExponentDistance = AL_EXPONENT_DISTANCE,
383 DisableDistance = AL_NONE,
385 DefaultDistanceModel = InverseDistanceClamped
388 enum Channel {
389 FrontLeft = 0,
390 FrontRight,
391 FrontCenter,
392 LFE,
393 BackLeft,
394 BackRight,
395 BackCenter,
396 SideLeft,
397 SideRight,
399 UpperFrontLeft,
400 UpperFrontRight,
401 UpperBackLeft,
402 UpperBackRight,
403 LowerFrontLeft,
404 LowerFrontRight,
405 LowerBackLeft,
406 LowerBackRight,
408 Aux0,
409 Aux1,
410 Aux2,
411 Aux3,
412 Aux4,
413 Aux5,
414 Aux6,
415 Aux7,
416 Aux8,
417 Aux9,
418 Aux10,
419 Aux11,
420 Aux12,
421 Aux13,
422 Aux14,
423 Aux15,
425 InvalidChannel
429 /* Device formats */
430 enum DevFmtType {
431 DevFmtByte = ALC_BYTE_SOFT,
432 DevFmtUByte = ALC_UNSIGNED_BYTE_SOFT,
433 DevFmtShort = ALC_SHORT_SOFT,
434 DevFmtUShort = ALC_UNSIGNED_SHORT_SOFT,
435 DevFmtInt = ALC_INT_SOFT,
436 DevFmtUInt = ALC_UNSIGNED_INT_SOFT,
437 DevFmtFloat = ALC_FLOAT_SOFT,
439 DevFmtTypeDefault = DevFmtFloat
441 enum DevFmtChannels {
442 DevFmtMono = ALC_MONO_SOFT,
443 DevFmtStereo = ALC_STEREO_SOFT,
444 DevFmtQuad = ALC_QUAD_SOFT,
445 DevFmtX51 = ALC_5POINT1_SOFT,
446 DevFmtX61 = ALC_6POINT1_SOFT,
447 DevFmtX71 = ALC_7POINT1_SOFT,
448 DevFmtAmbi3D = ALC_BFORMAT3D_SOFT,
450 /* Similar to 5.1, except using rear channels instead of sides */
451 DevFmtX51Rear = 0x80000000,
453 DevFmtChannelsDefault = DevFmtStereo
455 #define MAX_OUTPUT_CHANNELS (16)
457 ALsizei BytesFromDevFmt(enum DevFmtType type);
458 ALsizei ChannelsFromDevFmt(enum DevFmtChannels chans, ALsizei ambiorder);
459 inline ALsizei FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type, ALsizei ambiorder)
461 return ChannelsFromDevFmt(chans, ambiorder) * BytesFromDevFmt(type);
464 enum AmbiLayout {
465 AmbiLayout_FuMa = ALC_FUMA_SOFT, /* FuMa channel order */
466 AmbiLayout_ACN = ALC_ACN_SOFT, /* ACN channel order */
468 AmbiLayout_Default = AmbiLayout_ACN
471 enum AmbiNorm {
472 AmbiNorm_FuMa = ALC_FUMA_SOFT, /* FuMa normalization */
473 AmbiNorm_SN3D = ALC_SN3D_SOFT, /* SN3D normalization */
474 AmbiNorm_N3D = ALC_N3D_SOFT, /* N3D normalization */
476 AmbiNorm_Default = AmbiNorm_SN3D
480 enum DeviceType {
481 Playback,
482 Capture,
483 Loopback
487 enum RenderMode {
488 NormalRender,
489 StereoPair,
490 HrtfRender
494 /* The maximum number of Ambisonics coefficients. For a given order (o), the
495 * size needed will be (o+1)**2, thus zero-order has 1, first-order has 4,
496 * second-order has 9, third-order has 16, and fourth-order has 25.
498 #define MAX_AMBI_ORDER 3
499 #define MAX_AMBI_COEFFS ((MAX_AMBI_ORDER+1) * (MAX_AMBI_ORDER+1))
501 /* A bitmask of ambisonic channels with height information. If none of these
502 * channels are used/needed, there's no height (e.g. with most surround sound
503 * speaker setups). This only specifies up to 4th order, which is the highest
504 * order a 32-bit mask value can specify (a 64-bit mask could handle up to 7th
505 * order). This is ACN ordering, with bit 0 being ACN 0, etc.
507 #define AMBI_PERIPHONIC_MASK (0xfe7ce4)
509 /* The maximum number of Ambisonic coefficients for 2D (non-periphonic)
510 * representation. This is 2 per each order above zero-order, plus 1 for zero-
511 * order. Or simply, o*2 + 1.
513 #define MAX_AMBI2D_COEFFS (MAX_AMBI_ORDER*2 + 1)
516 typedef ALfloat ChannelConfig[MAX_AMBI_COEFFS];
517 typedef struct BFChannelConfig {
518 ALfloat Scale;
519 ALsizei Index;
520 } BFChannelConfig;
522 typedef union AmbiConfig {
523 /* Ambisonic coefficients for mixing to the dry buffer. */
524 ChannelConfig Coeffs[MAX_OUTPUT_CHANNELS];
525 /* Coefficient channel mapping for mixing to the dry buffer. */
526 BFChannelConfig Map[MAX_OUTPUT_CHANNELS];
527 } AmbiConfig;
530 typedef struct BufferSubList {
531 ALuint64 FreeMask;
532 struct ALbuffer *Buffers; /* 64 */
533 } BufferSubList;
534 TYPEDEF_VECTOR(BufferSubList, vector_BufferSubList)
536 typedef struct EffectSubList {
537 ALuint64 FreeMask;
538 struct ALeffect *Effects; /* 64 */
539 } EffectSubList;
540 TYPEDEF_VECTOR(EffectSubList, vector_EffectSubList)
542 typedef struct FilterSubList {
543 ALuint64 FreeMask;
544 struct ALfilter *Filters; /* 64 */
545 } FilterSubList;
546 TYPEDEF_VECTOR(FilterSubList, vector_FilterSubList)
548 typedef struct SourceSubList {
549 ALuint64 FreeMask;
550 struct ALsource *Sources; /* 64 */
551 } SourceSubList;
552 TYPEDEF_VECTOR(SourceSubList, vector_SourceSubList)
554 /* Effect slots are rather large, and apps aren't likely to have more than one
555 * or two (let alone 64), so hold them individually.
557 typedef struct ALeffectslot *ALeffectslotPtr;
558 TYPEDEF_VECTOR(ALeffectslotPtr, vector_ALeffectslotPtr)
561 typedef struct EnumeratedHrtf {
562 al_string name;
564 struct HrtfEntry *hrtf;
565 } EnumeratedHrtf;
566 TYPEDEF_VECTOR(EnumeratedHrtf, vector_EnumeratedHrtf)
569 /* Maximum delay in samples for speaker distance compensation. */
570 #define MAX_DELAY_LENGTH 1024
572 typedef struct DistanceComp {
573 ALfloat Gain;
574 ALsizei Length; /* Valid range is [0...MAX_DELAY_LENGTH). */
575 ALfloat *Buffer;
576 } DistanceComp;
578 /* Size for temporary storage of buffer data, in ALfloats. Larger values need
579 * more memory, while smaller values may need more iterations. The value needs
580 * to be a sensible size, however, as it constrains the max stepping value used
581 * for mixing, as well as the maximum number of samples per mixing iteration.
583 #define BUFFERSIZE 2048
585 typedef struct DryMixParams {
586 AmbiConfig Ambi;
587 /* Number of coefficients in each Ambi.Coeffs to mix together (4 for first-
588 * order, 9 for second-order, etc). If the count is 0, Ambi.Map is used
589 * instead to map each output to a coefficient index.
591 ALsizei CoeffCount;
593 ALfloat (*Buffer)[BUFFERSIZE];
594 ALsizei NumChannels;
595 ALsizei NumChannelsPerOrder[MAX_AMBI_ORDER+1];
596 } DryMixParams;
598 typedef struct BFMixParams {
599 AmbiConfig Ambi;
600 /* Will only be 4 or 0. */
601 ALsizei CoeffCount;
603 ALfloat (*Buffer)[BUFFERSIZE];
604 ALsizei NumChannels;
605 } BFMixParams;
607 typedef struct RealMixParams {
608 enum Channel ChannelName[MAX_OUTPUT_CHANNELS];
610 ALfloat (*Buffer)[BUFFERSIZE];
611 ALsizei NumChannels;
612 } RealMixParams;
614 typedef void (*POSTPROCESS)(ALCdevice *device, ALsizei SamplesToDo);
616 struct ALCdevice_struct {
617 RefCount ref;
619 ATOMIC(ALenum) Connected;
620 enum DeviceType Type;
622 ALuint Frequency;
623 ALuint UpdateSize;
624 ALuint NumUpdates;
625 enum DevFmtChannels FmtChans;
626 enum DevFmtType FmtType;
627 ALboolean IsHeadphones;
628 ALsizei AmbiOrder;
629 /* For DevFmtAmbi* output only, specifies the channel order and
630 * normalization.
632 enum AmbiLayout AmbiLayout;
633 enum AmbiNorm AmbiScale;
635 al_string DeviceName;
637 ATOMIC(ALCenum) LastError;
639 // Maximum number of sources that can be created
640 ALuint SourcesMax;
641 // Maximum number of slots that can be created
642 ALuint AuxiliaryEffectSlotMax;
644 ALCuint NumMonoSources;
645 ALCuint NumStereoSources;
646 ALsizei NumAuxSends;
648 // Map of Buffers for this device
649 vector_BufferSubList BufferList;
650 almtx_t BufferLock;
652 // Map of Effects for this device
653 vector_EffectSubList EffectList;
654 almtx_t EffectLock;
656 // Map of Filters for this device
657 vector_FilterSubList FilterList;
658 almtx_t FilterLock;
660 POSTPROCESS PostProcess;
662 /* HRTF state and info */
663 struct DirectHrtfState *Hrtf;
664 al_string HrtfName;
665 struct Hrtf *HrtfHandle;
666 vector_EnumeratedHrtf HrtfList;
667 ALCenum HrtfStatus;
669 /* UHJ encoder state */
670 struct Uhj2Encoder *Uhj_Encoder;
672 /* High quality Ambisonic decoder */
673 struct BFormatDec *AmbiDecoder;
675 /* Stereo-to-binaural filter */
676 struct bs2b *Bs2b;
678 /* First-order ambisonic upsampler for higher-order output */
679 struct AmbiUpsampler *AmbiUp;
681 /* Rendering mode. */
682 enum RenderMode Render_Mode;
684 // Device flags
685 ALuint Flags;
687 ALuint64 ClockBase;
688 ALuint SamplesDone;
690 /* Temp storage used for mixer processing. */
691 alignas(16) ALfloat TempBuffer[4][BUFFERSIZE];
693 /* The "dry" path corresponds to the main output. */
694 DryMixParams Dry;
696 /* First-order ambisonics output, to be upsampled to the dry buffer if different. */
697 BFMixParams FOAOut;
699 /* "Real" output, which will be written to the device buffer. May alias the
700 * dry buffer.
702 RealMixParams RealOut;
704 struct FrontStablizer *Stablizer;
706 struct Compressor *Limiter;
708 /* The average speaker distance as determined by the ambdec configuration
709 * (or alternatively, by the NFC-HOA reference delay). Only used for NFC.
711 ALfloat AvgSpeakerDist;
713 /* Delay buffers used to compensate for speaker distances. */
714 DistanceComp ChannelDelay[MAX_OUTPUT_CHANNELS];
716 /* Dithering control. */
717 ALfloat DitherDepth;
718 ALuint DitherSeed;
720 /* Running count of the mixer invocations, in 31.1 fixed point. This
721 * actually increments *twice* when mixing, first at the start and then at
722 * the end, so the bottom bit indicates if the device is currently mixing
723 * and the upper bits indicates how many mixes have been done.
725 RefCount MixCount;
727 // Contexts created on this device
728 ATOMIC(ALCcontext*) ContextList;
730 almtx_t BackendLock;
731 struct ALCbackend *Backend;
733 ATOMIC(ALCdevice*) next;
736 // Frequency was requested by the app or config file
737 #define DEVICE_FREQUENCY_REQUEST (1u<<1)
738 // Channel configuration was requested by the config file
739 #define DEVICE_CHANNELS_REQUEST (1u<<2)
740 // Sample type was requested by the config file
741 #define DEVICE_SAMPLE_TYPE_REQUEST (1u<<3)
743 // Specifies if the DSP is paused at user request
744 #define DEVICE_PAUSED (1u<<30)
746 // Specifies if the device is currently running
747 #define DEVICE_RUNNING (1u<<31)
750 /* Nanosecond resolution for the device clock time. */
751 #define DEVICE_CLOCK_RES U64(1000000000)
754 /* Must be less than 15 characters (16 including terminating null) for
755 * compatibility with pthread_setname_np limitations. */
756 #define MIXER_THREAD_NAME "alsoft-mixer"
758 #define RECORD_THREAD_NAME "alsoft-record"
761 enum {
762 EventType_SourceStateChange = 1<<0,
763 EventType_BufferCompleted = 1<<1,
764 EventType_Error = 1<<2,
765 EventType_Performance = 1<<3,
766 EventType_Deprecated = 1<<4,
767 EventType_Disconnected = 1<<5,
770 typedef struct AsyncEvent {
771 unsigned int EnumType;
772 ALenum Type;
773 ALuint ObjectId;
774 ALuint Param;
775 ALchar Message[1008];
776 } AsyncEvent;
778 struct ALCcontext_struct {
779 RefCount ref;
781 struct ALlistener *Listener;
783 vector_SourceSubList SourceList;
784 ALuint NumSources;
785 almtx_t SourceLock;
787 vector_ALeffectslotPtr EffectSlotList;
788 almtx_t EffectSlotLock;
790 ATOMIC(ALenum) LastError;
792 enum DistanceModel DistanceModel;
793 ALboolean SourceDistanceModel;
795 ALfloat DopplerFactor;
796 ALfloat DopplerVelocity;
797 ALfloat SpeedOfSound;
798 ALfloat MetersPerUnit;
800 ATOMIC_FLAG PropsClean;
801 ATOMIC(ALenum) DeferUpdates;
803 almtx_t PropLock;
805 /* Counter for the pre-mixing updates, in 31.1 fixed point (lowest bit
806 * indicates if updates are currently happening).
808 RefCount UpdateCount;
809 ATOMIC(ALenum) HoldUpdates;
811 ALfloat GainBoost;
813 ATOMIC(struct ALcontextProps*) Update;
815 /* Linked lists of unused property containers, free to use for future
816 * updates.
818 ATOMIC(struct ALcontextProps*) FreeContextProps;
819 ATOMIC(struct ALlistenerProps*) FreeListenerProps;
820 ATOMIC(struct ALvoiceProps*) FreeVoiceProps;
821 ATOMIC(struct ALeffectslotProps*) FreeEffectslotProps;
823 struct ALvoice **Voices;
824 ALsizei VoiceCount;
825 ALsizei MaxVoices;
827 ATOMIC(struct ALeffectslotArray*) ActiveAuxSlots;
829 almtx_t EventThrdLock;
830 althrd_t EventThread;
831 alsem_t EventSem;
832 struct ll_ringbuffer *AsyncEvents;
833 ATOMIC(ALbitfieldSOFT) EnabledEvts;
834 almtx_t EventCbLock;
835 ALEVENTPROCSOFT EventCb;
836 void *EventParam;
838 /* Default effect slot */
839 struct ALeffectslot *DefaultSlot;
841 ALCdevice *Device;
842 const ALCchar *ExtensionList;
844 ATOMIC(ALCcontext*) next;
846 /* Memory space used by the listener (and possibly default effect slot) */
847 alignas(16) ALCbyte _listener_mem[];
850 ALCcontext *GetContextRef(void);
852 void ALCcontext_DecRef(ALCcontext *context);
854 void ALCcontext_DeferUpdates(ALCcontext *context);
855 void ALCcontext_ProcessUpdates(ALCcontext *context);
857 void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends);
859 void AppendAllDevicesList(const ALCchar *name);
860 void AppendCaptureDeviceList(const ALCchar *name);
863 extern ALint RTPrioLevel;
864 void SetRTPriority(void);
866 void SetDefaultChannelOrder(ALCdevice *device);
867 void SetDefaultWFXChannelOrder(ALCdevice *device);
869 const ALCchar *DevFmtTypeString(enum DevFmtType type);
870 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans);
872 inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS], enum Channel chan)
874 ALint i;
875 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
877 if(names[i] == chan)
878 return i;
880 return -1;
883 * GetChannelIdxByName
885 * Returns the index for the given channel name (e.g. FrontCenter), or -1 if it
886 * doesn't exist.
888 inline ALint GetChannelIdxByName(const RealMixParams *real, enum Channel chan)
889 { return GetChannelIndex(real->ChannelName, chan); }
892 inline void LockBufferList(ALCdevice *device) { almtx_lock(&device->BufferLock); }
893 inline void UnlockBufferList(ALCdevice *device) { almtx_unlock(&device->BufferLock); }
895 inline void LockEffectList(ALCdevice *device) { almtx_lock(&device->EffectLock); }
896 inline void UnlockEffectList(ALCdevice *device) { almtx_unlock(&device->EffectLock); }
898 inline void LockFilterList(ALCdevice *device) { almtx_lock(&device->FilterLock); }
899 inline void UnlockFilterList(ALCdevice *device) { almtx_unlock(&device->FilterLock); }
901 inline void LockEffectSlotList(ALCcontext *context)
902 { almtx_lock(&context->EffectSlotLock); }
903 inline void UnlockEffectSlotList(ALCcontext *context)
904 { almtx_unlock(&context->EffectSlotLock); }
907 vector_al_string SearchDataFiles(const char *match, const char *subdir);
909 #ifdef __cplusplus
911 #endif
913 #endif