Handle EventType_BufferCompleted uniquely
[openal-soft.git] / OpenAL32 / Include / alMain.h
blob75dc6c740e40cb85f86097be12763ef9b6d08e07
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 <array>
20 #include <vector>
21 #include <string>
22 #include <chrono>
23 #include <algorithm>
25 #include "AL/al.h"
26 #include "AL/alc.h"
27 #include "AL/alext.h"
29 #include "inprogext.h"
30 #include "logging.h"
31 #include "polymorphism.h"
32 #include "atomic.h"
33 #include "vector.h"
34 #include "almalloc.h"
35 #include "threads.h"
38 template<typename T, size_t N>
39 constexpr inline size_t countof(const T(&)[N]) noexcept
40 { return N; }
41 #define COUNTOF countof
43 #if defined(_WIN64)
44 #define SZFMT "%I64u"
45 #elif defined(_WIN32)
46 #define SZFMT "%u"
47 #else
48 #define SZFMT "%zu"
49 #endif
51 #ifdef __has_builtin
52 #define HAS_BUILTIN __has_builtin
53 #else
54 #define HAS_BUILTIN(x) (0)
55 #endif
57 #ifdef __GNUC__
58 /* LIKELY optimizes the case where the condition is true. The condition is not
59 * required to be true, but it can result in more optimal code for the true
60 * path at the expense of a less optimal false path.
62 #define LIKELY(x) __builtin_expect(!!(x), !0)
63 /* The opposite of LIKELY, optimizing the case where the condition is false. */
64 #define UNLIKELY(x) __builtin_expect(!!(x), 0)
65 /* Unlike LIKELY, ASSUME requires the condition to be true or else it invokes
66 * undefined behavior. It's essentially an assert without actually checking the
67 * condition at run-time, allowing for stronger optimizations than LIKELY.
69 #if HAS_BUILTIN(__builtin_assume)
70 #define ASSUME __builtin_assume
71 #else
72 #define ASSUME(x) do { if(!(x)) __builtin_unreachable(); } while(0)
73 #endif
75 #else
77 #define LIKELY(x) (!!(x))
78 #define UNLIKELY(x) (!!(x))
79 #ifdef _MSC_VER
80 #define ASSUME __assume
81 #else
82 #define ASSUME(x) ((void)0)
83 #endif
84 #endif
86 #ifndef UINT64_MAX
87 #define UINT64_MAX U64(18446744073709551615)
88 #endif
90 #ifndef UNUSED
91 #if defined(__cplusplus)
92 #define UNUSED(x)
93 #elif defined(__GNUC__)
94 #define UNUSED(x) UNUSED_##x __attribute__((unused))
95 #elif defined(__LCLINT__)
96 #define UNUSED(x) /*@unused@*/ x
97 #else
98 #define UNUSED(x) x
99 #endif
100 #endif
102 /* Calculates the size of a struct with N elements of a flexible array member.
103 * GCC and Clang allow offsetof(Type, fam[N]) for this, but MSVC seems to have
104 * trouble, so a bit more verbose workaround is needed.
106 #define FAM_SIZE(T, M, N) (offsetof(T, M) + sizeof(((T*)NULL)->M[0])*(N))
109 typedef ALint64SOFT ALint64;
110 typedef ALuint64SOFT ALuint64;
112 #ifndef U64
113 #if defined(_MSC_VER)
114 #define U64(x) ((ALuint64)(x##ui64))
115 #elif SIZEOF_LONG == 8
116 #define U64(x) ((ALuint64)(x##ul))
117 #elif SIZEOF_LONG_LONG == 8
118 #define U64(x) ((ALuint64)(x##ull))
119 #endif
120 #endif
122 #ifndef I64
123 #if defined(_MSC_VER)
124 #define I64(x) ((ALint64)(x##i64))
125 #elif SIZEOF_LONG == 8
126 #define I64(x) ((ALint64)(x##l))
127 #elif SIZEOF_LONG_LONG == 8
128 #define I64(x) ((ALint64)(x##ll))
129 #endif
130 #endif
132 /* Define a CTZ64 macro (count trailing zeros, for 64-bit integers). The result
133 * is *UNDEFINED* if the value is 0.
135 #ifdef __GNUC__
137 #if SIZEOF_LONG == 8
138 #define POPCNT64 __builtin_popcountl
139 #define CTZ64 __builtin_ctzl
140 #else
141 #define POPCNT64 __builtin_popcountll
142 #define CTZ64 __builtin_ctzll
143 #endif
145 #elif defined(HAVE_BITSCANFORWARD64_INTRINSIC)
147 inline int msvc64_popcnt64(ALuint64 v)
149 return __popcnt64(v);
151 #define POPCNT64 msvc64_popcnt64
153 inline int msvc64_ctz64(ALuint64 v)
155 unsigned long idx = 64;
156 _BitScanForward64(&idx, v);
157 return (int)idx;
159 #define CTZ64 msvc64_ctz64
161 #elif defined(HAVE_BITSCANFORWARD_INTRINSIC)
163 inline int msvc_popcnt64(ALuint64 v)
165 return __popcnt((ALuint)v) + __popcnt((ALuint)(v>>32));
167 #define POPCNT64 msvc_popcnt64
169 inline int msvc_ctz64(ALuint64 v)
171 unsigned long idx = 64;
172 if(!_BitScanForward(&idx, v&0xffffffff))
174 if(_BitScanForward(&idx, v>>32))
175 idx += 32;
177 return (int)idx;
179 #define CTZ64 msvc_ctz64
181 #else
183 /* There be black magics here. The popcnt64 method is derived from
184 * https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
185 * while the ctz-utilizing-popcnt algorithm is shown here
186 * http://www.hackersdelight.org/hdcodetxt/ntz.c.txt
187 * as the ntz2 variant. These likely aren't the most efficient methods, but
188 * they're good enough if the GCC or MSVC intrinsics aren't available.
190 inline int fallback_popcnt64(ALuint64 v)
192 v = v - ((v >> 1) & U64(0x5555555555555555));
193 v = (v & U64(0x3333333333333333)) + ((v >> 2) & U64(0x3333333333333333));
194 v = (v + (v >> 4)) & U64(0x0f0f0f0f0f0f0f0f);
195 return (int)((v * U64(0x0101010101010101)) >> 56);
197 #define POPCNT64 fallback_popcnt64
199 inline int fallback_ctz64(ALuint64 value)
201 return fallback_popcnt64(~value & (value - 1));
203 #define CTZ64 fallback_ctz64
204 #endif
206 #if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
207 #define IS_LITTLE_ENDIAN (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
208 #else
209 static const union {
210 ALuint u;
211 ALubyte b[sizeof(ALuint)];
212 } EndianTest = { 1 };
213 #define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1)
214 #endif
217 struct Hrtf;
218 struct HrtfEntry;
219 struct DirectHrtfState;
220 struct FrontStablizer;
221 struct Compressor;
222 struct ALCbackend;
223 struct ALbuffer;
224 struct ALeffect;
225 struct ALfilter;
226 struct EffectState;
227 struct Uhj2Encoder;
228 struct BFormatDec;
229 struct AmbiUpsampler;
230 struct bs2b;
233 #define DEFAULT_OUTPUT_RATE (44100)
234 #define MIN_OUTPUT_RATE (8000)
237 /* Find the next power-of-2 for non-power-of-2 numbers. */
238 inline ALuint NextPowerOf2(ALuint value) noexcept
240 if(value > 0)
242 value--;
243 value |= value>>1;
244 value |= value>>2;
245 value |= value>>4;
246 value |= value>>8;
247 value |= value>>16;
249 return value+1;
252 /** Round up a value to the next multiple. */
253 inline size_t RoundUp(size_t value, size_t r) noexcept
255 value += r-1;
256 return value - (value%r);
259 /* Fast float-to-int conversion. No particular rounding mode is assumed; the
260 * IEEE-754 default is round-to-nearest with ties-to-even, though an app could
261 * change it on its own threads. On some systems, a truncating conversion may
262 * always be the fastest method.
264 inline ALint fastf2i(ALfloat f) noexcept
266 #if defined(HAVE_INTRIN_H) && ((defined(_M_IX86_FP) && (_M_IX86_FP > 0)) || defined(_M_X64))
267 return _mm_cvt_ss2si(_mm_set1_ps(f));
269 #elif defined(_MSC_VER) && defined(_M_IX86_FP)
271 ALint i;
272 __asm fld f
273 __asm fistp i
274 return i;
276 #elif (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))
278 ALint i;
279 #ifdef __SSE_MATH__
280 __asm__("cvtss2si %1, %0" : "=r"(i) : "x"(f));
281 #else
282 __asm__ __volatile__("fistpl %0" : "=m"(i) : "t"(f) : "st");
283 #endif
284 return i;
286 /* On GCC when compiling with -fno-math-errno, lrintf can be inlined to
287 * some simple instructions. Clang does not inline it, always generating a
288 * libc call, while MSVC's implementation is horribly slow, so always fall
289 * back to a normal integer conversion for them.
291 #elif !defined(_MSC_VER) && !defined(__clang__)
293 return lrintf(f);
295 #else
297 return (ALint)f;
298 #endif
301 /* Converts float-to-int using standard behavior (truncation). */
302 inline int float2int(float f) noexcept
304 #if ((defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__)) && \
305 !defined(__SSE_MATH__)) || (defined(_MSC_VER) && defined(_M_IX86_FP) && _M_IX86_FP == 0)
306 ALint sign, shift, mant;
307 union {
308 ALfloat f;
309 ALint i;
310 } conv;
312 conv.f = f;
313 sign = (conv.i>>31) | 1;
314 shift = ((conv.i>>23)&0xff) - (127+23);
316 /* Over/underflow */
317 if(UNLIKELY(shift >= 31 || shift < -23))
318 return 0;
320 mant = (conv.i&0x7fffff) | 0x800000;
321 if(LIKELY(shift < 0))
322 return (mant >> -shift) * sign;
323 return (mant << shift) * sign;
325 #else
327 return (ALint)f;
328 #endif
331 /* Rounds a float to the nearest integral value, according to the current
332 * rounding mode. This is essentially an inlined version of rintf, although
333 * makes fewer promises (e.g. -0 or -0.25 rounded to 0 may result in +0).
335 inline float fast_roundf(float f) noexcept
337 #if (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__)) && \
338 !defined(__SSE_MATH__)
340 float out;
341 __asm__ __volatile__("frndint" : "=t"(out) : "0"(f));
342 return out;
344 #else
346 /* Integral limit, where sub-integral precision is not available for
347 * floats.
349 static const float ilim[2] = {
350 8388608.0f /* 0x1.0p+23 */,
351 -8388608.0f /* -0x1.0p+23 */
353 ALuint sign, expo;
354 union {
355 ALfloat f;
356 ALuint i;
357 } conv;
359 conv.f = f;
360 sign = (conv.i>>31)&0x01;
361 expo = (conv.i>>23)&0xff;
363 if(UNLIKELY(expo >= 150/*+23*/))
365 /* An exponent (base-2) of 23 or higher is incapable of sub-integral
366 * precision, so it's already an integral value. We don't need to worry
367 * about infinity or NaN here.
369 return f;
371 /* Adding the integral limit to the value (with a matching sign) forces a
372 * result that has no sub-integral precision, and is consequently forced to
373 * round to an integral value. Removing the integral limit then restores
374 * the initial value rounded to the integral. The compiler should not
375 * optimize this out because of non-associative rules on floating-point
376 * math (as long as you don't use -fassociative-math,
377 * -funsafe-math-optimizations, -ffast-math, or -Ofast, in which case this
378 * may break).
380 f += ilim[sign];
381 return f - ilim[sign];
382 #endif
386 enum DevProbe {
387 ALL_DEVICE_PROBE,
388 CAPTURE_DEVICE_PROBE
392 enum Channel {
393 FrontLeft = 0,
394 FrontRight,
395 FrontCenter,
396 LFE,
397 BackLeft,
398 BackRight,
399 BackCenter,
400 SideLeft,
401 SideRight,
403 UpperFrontLeft,
404 UpperFrontRight,
405 UpperBackLeft,
406 UpperBackRight,
407 LowerFrontLeft,
408 LowerFrontRight,
409 LowerBackLeft,
410 LowerBackRight,
412 Aux0,
413 Aux1,
414 Aux2,
415 Aux3,
416 Aux4,
417 Aux5,
418 Aux6,
419 Aux7,
420 Aux8,
421 Aux9,
422 Aux10,
423 Aux11,
424 Aux12,
425 Aux13,
426 Aux14,
427 Aux15,
429 InvalidChannel
433 /* Device formats */
434 enum DevFmtType {
435 DevFmtByte = ALC_BYTE_SOFT,
436 DevFmtUByte = ALC_UNSIGNED_BYTE_SOFT,
437 DevFmtShort = ALC_SHORT_SOFT,
438 DevFmtUShort = ALC_UNSIGNED_SHORT_SOFT,
439 DevFmtInt = ALC_INT_SOFT,
440 DevFmtUInt = ALC_UNSIGNED_INT_SOFT,
441 DevFmtFloat = ALC_FLOAT_SOFT,
443 DevFmtTypeDefault = DevFmtFloat
445 enum DevFmtChannels {
446 DevFmtMono = ALC_MONO_SOFT,
447 DevFmtStereo = ALC_STEREO_SOFT,
448 DevFmtQuad = ALC_QUAD_SOFT,
449 DevFmtX51 = ALC_5POINT1_SOFT,
450 DevFmtX61 = ALC_6POINT1_SOFT,
451 DevFmtX71 = ALC_7POINT1_SOFT,
452 DevFmtAmbi3D = ALC_BFORMAT3D_SOFT,
454 /* Similar to 5.1, except using rear channels instead of sides */
455 DevFmtX51Rear = 0x80000000,
457 DevFmtChannelsDefault = DevFmtStereo
459 #define MAX_OUTPUT_CHANNELS (16)
461 /* DevFmtType traits, providing the type, etc given a DevFmtType. */
462 template<DevFmtType T>
463 struct DevFmtTypeTraits { };
465 template<>
466 struct DevFmtTypeTraits<DevFmtByte> { using Type = ALbyte; };
467 template<>
468 struct DevFmtTypeTraits<DevFmtUByte> { using Type = ALubyte; };
469 template<>
470 struct DevFmtTypeTraits<DevFmtShort> { using Type = ALshort; };
471 template<>
472 struct DevFmtTypeTraits<DevFmtUShort> { using Type = ALushort; };
473 template<>
474 struct DevFmtTypeTraits<DevFmtInt> { using Type = ALint; };
475 template<>
476 struct DevFmtTypeTraits<DevFmtUInt> { using Type = ALuint; };
477 template<>
478 struct DevFmtTypeTraits<DevFmtFloat> { using Type = ALfloat; };
481 ALsizei BytesFromDevFmt(enum DevFmtType type);
482 ALsizei ChannelsFromDevFmt(enum DevFmtChannels chans, ALsizei ambiorder);
483 inline ALsizei FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type, ALsizei ambiorder)
485 return ChannelsFromDevFmt(chans, ambiorder) * BytesFromDevFmt(type);
488 enum class AmbiLayout {
489 FuMa = ALC_FUMA_SOFT, /* FuMa channel order */
490 ACN = ALC_ACN_SOFT, /* ACN channel order */
492 Default = ACN
495 enum class AmbiNorm {
496 FuMa = ALC_FUMA_SOFT, /* FuMa normalization */
497 SN3D = ALC_SN3D_SOFT, /* SN3D normalization */
498 N3D = ALC_N3D_SOFT, /* N3D normalization */
500 Default = SN3D
504 enum DeviceType {
505 Playback,
506 Capture,
507 Loopback
511 enum RenderMode {
512 NormalRender,
513 StereoPair,
514 HrtfRender
518 /* The maximum number of Ambisonics coefficients. For a given order (o), the
519 * size needed will be (o+1)**2, thus zero-order has 1, first-order has 4,
520 * second-order has 9, third-order has 16, and fourth-order has 25.
522 #define MAX_AMBI_ORDER 3
523 #define MAX_AMBI_COEFFS ((MAX_AMBI_ORDER+1) * (MAX_AMBI_ORDER+1))
525 /* A bitmask of ambisonic channels with height information. If none of these
526 * channels are used/needed, there's no height (e.g. with most surround sound
527 * speaker setups). This only specifies up to 4th order, which is the highest
528 * order a 32-bit mask value can specify (a 64-bit mask could handle up to 7th
529 * order). This is ACN ordering, with bit 0 being ACN 0, etc.
531 #define AMBI_PERIPHONIC_MASK (0xfe7ce4)
533 /* The maximum number of Ambisonic coefficients for 2D (non-periphonic)
534 * representation. This is 2 per each order above zero-order, plus 1 for zero-
535 * order. Or simply, o*2 + 1.
537 #define MAX_AMBI2D_COEFFS (MAX_AMBI_ORDER*2 + 1)
540 typedef ALfloat ChannelConfig[MAX_AMBI_COEFFS];
541 typedef struct BFChannelConfig {
542 ALfloat Scale;
543 ALsizei Index;
544 } BFChannelConfig;
546 typedef union AmbiConfig {
547 /* Ambisonic coefficients for mixing to the dry buffer. */
548 ChannelConfig Coeffs[MAX_OUTPUT_CHANNELS];
549 /* Coefficient channel mapping for mixing to the dry buffer. */
550 BFChannelConfig Map[MAX_OUTPUT_CHANNELS];
551 } AmbiConfig;
554 struct BufferSubList {
555 uint64_t FreeMask{~uint64_t{}};
556 struct ALbuffer *Buffers{nullptr}; /* 64 */
558 BufferSubList() noexcept = default;
559 BufferSubList(const BufferSubList&) = delete;
560 BufferSubList(BufferSubList&& rhs) noexcept : FreeMask{rhs.FreeMask}, Buffers{rhs.Buffers}
561 { rhs.FreeMask = ~uint64_t{}; rhs.Buffers = nullptr; }
562 ~BufferSubList();
564 BufferSubList& operator=(const BufferSubList&) = delete;
565 BufferSubList& operator=(BufferSubList&& rhs) noexcept
566 { std::swap(FreeMask, rhs.FreeMask); std::swap(Buffers, rhs.Buffers); return *this; }
569 struct EffectSubList {
570 uint64_t FreeMask{~uint64_t{}};
571 struct ALeffect *Effects{nullptr}; /* 64 */
573 EffectSubList() noexcept = default;
574 EffectSubList(const EffectSubList&) = delete;
575 EffectSubList(EffectSubList&& rhs) noexcept : FreeMask{rhs.FreeMask}, Effects{rhs.Effects}
576 { rhs.FreeMask = ~uint64_t{}; rhs.Effects = nullptr; }
577 ~EffectSubList();
579 EffectSubList& operator=(const EffectSubList&) = delete;
580 EffectSubList& operator=(EffectSubList&& rhs) noexcept
581 { std::swap(FreeMask, rhs.FreeMask); std::swap(Effects, rhs.Effects); return *this; }
584 struct FilterSubList {
585 uint64_t FreeMask{~uint64_t{}};
586 struct ALfilter *Filters{nullptr}; /* 64 */
588 FilterSubList() noexcept = default;
589 FilterSubList(const FilterSubList&) = delete;
590 FilterSubList(FilterSubList&& rhs) noexcept : FreeMask{rhs.FreeMask}, Filters{rhs.Filters}
591 { rhs.FreeMask = ~uint64_t{}; rhs.Filters = nullptr; }
592 ~FilterSubList();
594 FilterSubList& operator=(const FilterSubList&) = delete;
595 FilterSubList& operator=(FilterSubList&& rhs) noexcept
596 { std::swap(FreeMask, rhs.FreeMask); std::swap(Filters, rhs.Filters); return *this; }
600 typedef struct EnumeratedHrtf {
601 std::string name;
603 struct HrtfEntry *hrtf;
604 } EnumeratedHrtf;
607 /* Maximum delay in samples for speaker distance compensation. */
608 #define MAX_DELAY_LENGTH 1024
610 class DistanceComp {
611 struct DistData {
612 ALfloat Gain{1.0f};
613 ALsizei Length{0}; /* Valid range is [0...MAX_DELAY_LENGTH). */
614 ALfloat *Buffer{nullptr};
615 } mChannel[MAX_OUTPUT_CHANNELS];
616 al::vector<ALfloat,16> mSamples;
618 public:
619 void resize(size_t amt) { mSamples.resize(amt); }
620 void shrink_to_fit() { mSamples.shrink_to_fit(); }
621 void clear() noexcept
623 for(auto &chan : mChannel)
625 chan.Gain = 1.0f;
626 chan.Length = 0;
627 chan.Buffer = nullptr;
629 mSamples.clear();
632 ALfloat *data() noexcept { return mSamples.data(); }
633 const ALfloat *data() const noexcept { return mSamples.data(); }
635 DistData& operator[](size_t o) noexcept { return mChannel[o]; }
636 const DistData& operator[](size_t o) const noexcept { return mChannel[o]; }
639 /* Size for temporary storage of buffer data, in ALfloats. Larger values need
640 * more memory, while smaller values may need more iterations. The value needs
641 * to be a sensible size, however, as it constrains the max stepping value used
642 * for mixing, as well as the maximum number of samples per mixing iteration.
644 #define BUFFERSIZE 2048
646 typedef struct MixParams {
647 AmbiConfig Ambi{};
648 /* Number of coefficients in each Ambi.Coeffs to mix together (4 for first-
649 * order, 9 for second-order, etc). If the count is 0, Ambi.Map is used
650 * instead to map each output to a coefficient index.
652 ALsizei CoeffCount{0};
654 ALfloat (*Buffer)[BUFFERSIZE]{nullptr};
655 ALsizei NumChannels{0};
656 } MixParams;
658 typedef struct RealMixParams {
659 enum Channel ChannelName[MAX_OUTPUT_CHANNELS]{};
661 ALfloat (*Buffer)[BUFFERSIZE]{nullptr};
662 ALsizei NumChannels{0};
663 } RealMixParams;
665 typedef void (*POSTPROCESS)(ALCdevice *device, ALsizei SamplesToDo);
667 struct ALCdevice_struct {
668 RefCount ref{1u};
670 std::atomic<ALenum> Connected{AL_TRUE};
671 DeviceType Type{};
673 ALuint Frequency{};
674 ALuint UpdateSize{};
675 ALuint NumUpdates{};
676 DevFmtChannels FmtChans{};
677 DevFmtType FmtType{};
678 ALboolean IsHeadphones{AL_FALSE};
679 ALsizei mAmbiOrder{0};
680 /* For DevFmtAmbi* output only, specifies the channel order and
681 * normalization.
683 AmbiLayout mAmbiLayout{AmbiLayout::Default};
684 AmbiNorm mAmbiScale{AmbiNorm::Default};
686 ALCenum LimiterState{ALC_DONT_CARE_SOFT};
688 std::string DeviceName;
690 // Device flags
691 ALuint Flags{0u};
693 std::string HrtfName;
694 al::vector<EnumeratedHrtf> HrtfList;
695 ALCenum HrtfStatus{ALC_FALSE};
697 std::atomic<ALCenum> LastError{ALC_NO_ERROR};
699 // Maximum number of sources that can be created
700 ALuint SourcesMax{};
701 // Maximum number of slots that can be created
702 ALuint AuxiliaryEffectSlotMax{};
704 ALCuint NumMonoSources{};
705 ALCuint NumStereoSources{};
706 ALsizei NumAuxSends{};
708 // Map of Buffers for this device
709 al::vector<BufferSubList> BufferList;
710 std::mutex BufferLock;
712 // Map of Effects for this device
713 al::vector<EffectSubList> EffectList;
714 std::mutex EffectLock;
716 // Map of Filters for this device
717 al::vector<FilterSubList> FilterList;
718 std::mutex FilterLock;
720 /* Rendering mode. */
721 RenderMode Render_Mode{NormalRender};
723 /* The average speaker distance as determined by the ambdec configuration
724 * (or alternatively, by the NFC-HOA reference delay). Only used for NFC.
726 ALfloat AvgSpeakerDist{0.0f};
728 ALuint SamplesDone{0u};
729 std::chrono::nanoseconds ClockBase{0};
730 std::chrono::nanoseconds FixedLatency{0};
732 /* Temp storage used for mixer processing. */
733 alignas(16) ALfloat TempBuffer[4][BUFFERSIZE];
735 /* Mixing buffer used by the Dry mix, FOAOut, and Real out. */
736 al::vector<std::array<ALfloat,BUFFERSIZE>, 16> MixBuffer;
738 /* The "dry" path corresponds to the main output. */
739 MixParams Dry;
740 ALsizei NumChannelsPerOrder[MAX_AMBI_ORDER+1]{};
742 /* First-order ambisonics output, to be upsampled to the dry buffer if different. */
743 MixParams FOAOut;
745 /* "Real" output, which will be written to the device buffer. May alias the
746 * dry buffer.
748 RealMixParams RealOut;
750 /* HRTF state and info */
751 std::unique_ptr<DirectHrtfState> mHrtfState;
752 Hrtf *HrtfHandle{nullptr};
754 /* UHJ encoder state */
755 std::unique_ptr<Uhj2Encoder> Uhj_Encoder;
757 /* High quality Ambisonic decoder */
758 std::unique_ptr<BFormatDec> AmbiDecoder;
760 /* Stereo-to-binaural filter */
761 std::unique_ptr<bs2b> Bs2b;
763 /* First-order ambisonic upsampler for higher-order output */
764 std::unique_ptr<AmbiUpsampler> AmbiUp;
766 POSTPROCESS PostProcess{};
768 std::unique_ptr<FrontStablizer> Stablizer;
770 /* Delay buffers used to compensate for speaker distances. */
771 DistanceComp ChannelDelay;
773 std::unique_ptr<Compressor> Limiter;
775 /* Dithering control. */
776 ALfloat DitherDepth{0.0f};
777 ALuint DitherSeed{0u};
779 /* Running count of the mixer invocations, in 31.1 fixed point. This
780 * actually increments *twice* when mixing, first at the start and then at
781 * the end, so the bottom bit indicates if the device is currently mixing
782 * and the upper bits indicates how many mixes have been done.
784 RefCount MixCount{0u};
786 // Contexts created on this device
787 std::atomic<ALCcontext*> ContextList{nullptr};
789 std::mutex BackendLock;
790 ALCbackend *Backend{nullptr};
792 std::atomic<ALCdevice*> next{nullptr};
795 ALCdevice_struct(DeviceType type);
796 ALCdevice_struct(const ALCdevice_struct&) = delete;
797 ALCdevice_struct& operator=(const ALCdevice_struct&) = delete;
798 ~ALCdevice_struct();
800 DEF_NEWDEL(ALCdevice)
803 // Frequency was requested by the app or config file
804 #define DEVICE_FREQUENCY_REQUEST (1u<<1)
805 // Channel configuration was requested by the config file
806 #define DEVICE_CHANNELS_REQUEST (1u<<2)
807 // Sample type was requested by the config file
808 #define DEVICE_SAMPLE_TYPE_REQUEST (1u<<3)
810 // Specifies if the DSP is paused at user request
811 #define DEVICE_PAUSED (1u<<30)
813 // Specifies if the device is currently running
814 #define DEVICE_RUNNING (1u<<31)
817 /* Nanosecond resolution for the device clock time. */
818 #define DEVICE_CLOCK_RES U64(1000000000)
821 /* Must be less than 15 characters (16 including terminating null) for
822 * compatibility with pthread_setname_np limitations. */
823 #define MIXER_THREAD_NAME "alsoft-mixer"
825 #define RECORD_THREAD_NAME "alsoft-record"
828 enum {
829 /* End event thread processing. */
830 EventType_KillThread = 0,
832 /* User event types. */
833 EventType_SourceStateChange = 1<<0,
834 EventType_BufferCompleted = 1<<1,
835 EventType_Error = 1<<2,
836 EventType_Performance = 1<<3,
837 EventType_Deprecated = 1<<4,
838 EventType_Disconnected = 1<<5,
840 /* Internal events. */
841 EventType_ReleaseEffectState = 65536,
844 struct AsyncEvent {
845 unsigned int EnumType;
846 union {
847 char dummy;
848 struct {
849 ALuint id;
850 ALenum state;
851 } srcstate;
852 struct {
853 ALuint id;
854 ALsizei count;
855 } bufcomp;
856 struct {
857 ALenum type;
858 ALuint id;
859 ALuint param;
860 ALchar msg[1008];
861 } user;
862 EffectState *mEffectState;
863 } u;
865 #define ASYNC_EVENT(t) AsyncEvent{ t, { 0 } }
868 void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends);
871 extern ALint RTPrioLevel;
872 void SetRTPriority(void);
874 void SetDefaultChannelOrder(ALCdevice *device);
875 void SetDefaultWFXChannelOrder(ALCdevice *device);
877 const ALCchar *DevFmtTypeString(enum DevFmtType type);
878 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans);
880 inline ALint GetChannelIndex(const enum Channel (&names)[MAX_OUTPUT_CHANNELS], enum Channel chan)
882 auto iter = std::find(std::begin(names), std::end(names), chan);
883 if(iter == std::end(names)) return -1;
884 return std::distance(std::begin(names), iter);
887 * GetChannelIdxByName
889 * Returns the index for the given channel name (e.g. FrontCenter), or -1 if it
890 * doesn't exist.
892 inline ALint GetChannelIdxByName(const RealMixParams *real, enum Channel chan)
893 { return GetChannelIndex(real->ChannelName, chan); }
896 void StartEventThrd(ALCcontext *ctx);
897 void StopEventThrd(ALCcontext *ctx);
900 al::vector<std::string> SearchDataFiles(const char *match, const char *subdir);
902 #endif