Rename EventLock to make it more clear it's protecting the callback
[openal-soft.git] / OpenAL32 / Include / alMain.h
blob6ad67b7bb08cabace54afd832ffff43561424f39
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 "uintmap.h"
30 #include "vector.h"
31 #include "alstring.h"
32 #include "almalloc.h"
33 #include "threads.h"
36 #if defined(_WIN64)
37 #define SZFMT "%I64u"
38 #elif defined(_WIN32)
39 #define SZFMT "%u"
40 #else
41 #define SZFMT "%zu"
42 #endif
45 #ifdef __GNUC__
46 #define LIKELY(x) __builtin_expect(!!(x), !0)
47 #define UNLIKELY(x) __builtin_expect(!!(x), 0)
48 #else
49 #define LIKELY(x) (!!(x))
50 #define UNLIKELY(x) (!!(x))
51 #endif
53 typedef ALint64SOFT ALint64;
54 typedef ALuint64SOFT ALuint64;
56 #ifndef U64
57 #if defined(_MSC_VER)
58 #define U64(x) ((ALuint64)(x##ui64))
59 #elif SIZEOF_LONG == 8
60 #define U64(x) ((ALuint64)(x##ul))
61 #elif SIZEOF_LONG_LONG == 8
62 #define U64(x) ((ALuint64)(x##ull))
63 #endif
64 #endif
66 #ifndef UINT64_MAX
67 #define UINT64_MAX U64(18446744073709551615)
68 #endif
70 #ifndef UNUSED
71 #if defined(__cplusplus)
72 #define UNUSED(x)
73 #elif defined(__GNUC__)
74 #define UNUSED(x) UNUSED_##x __attribute__((unused))
75 #elif defined(__LCLINT__)
76 #define UNUSED(x) /*@unused@*/ x
77 #else
78 #define UNUSED(x) x
79 #endif
80 #endif
82 /* Calculates the size of a struct with N elements of a flexible array member.
83 * GCC and Clang allow offsetof(Type, fam[N]) for this, but MSVC seems to have
84 * trouble, so a bit more verbose workaround is needed.
86 #define FAM_SIZE(T, M, N) (offsetof(T, M) + sizeof(((T*)NULL)->M[0])*(N))
89 /* Define a CTZ64 macro (count trailing zeros, for 64-bit integers). The result
90 * is *UNDEFINED* if the value is 0.
92 #ifdef __GNUC__
94 #if SIZEOF_LONG == 8
95 #define CTZ64(x) __builtin_ctzl(x)
96 #else
97 #define CTZ64(x) __builtin_ctzll(x)
98 #endif
100 #elif defined(HAVE_BITSCANFORWARD64_INTRINSIC)
102 static inline int msvc64_ctz64(ALuint64 v)
104 unsigned long idx = 64;
105 _BitScanForward64(&idx, v);
106 return (int)idx;
108 #define CTZ64(x) msvc64_ctz64(x)
110 #elif defined(HAVE_BITSCANFORWARD_INTRINSIC)
112 static inline int msvc_ctz64(ALuint64 v)
114 unsigned long idx = 64;
115 if(!_BitScanForward(&idx, v&0xffffffff))
117 if(_BitScanForward(&idx, v>>32))
118 idx += 32;
120 return (int)idx;
122 #define CTZ64(x) msvc_ctz64(x)
124 #else
126 /* There be black magics here. The popcnt64 method is derived from
127 * https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
128 * while the ctz-utilizing-popcnt algorithm is shown here
129 * http://www.hackersdelight.org/hdcodetxt/ntz.c.txt
130 * as the ntz2 variant. These likely aren't the most efficient methods, but
131 * they're good enough if the GCC or MSVC intrinsics aren't available.
133 static inline int fallback_popcnt64(ALuint64 v)
135 v = v - ((v >> 1) & U64(0x5555555555555555));
136 v = (v & U64(0x3333333333333333)) + ((v >> 2) & U64(0x3333333333333333));
137 v = (v + (v >> 4)) & U64(0x0f0f0f0f0f0f0f0f);
138 return (int)((v * U64(0x0101010101010101)) >> 56);
141 static inline int fallback_ctz64(ALuint64 value)
143 return fallback_popcnt64(~value & (value - 1));
145 #define CTZ64(x) fallback_ctz64(x)
146 #endif
148 static const union {
149 ALuint u;
150 ALubyte b[sizeof(ALuint)];
151 } EndianTest = { 1 };
152 #define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1)
154 #define COUNTOF(x) (sizeof(x) / sizeof(0[x]))
157 #ifdef __cplusplus
158 extern "C" {
159 #endif
161 struct Hrtf;
162 struct HrtfEntry;
163 struct DirectHrtfState;
164 struct FrontStablizer;
165 struct Compressor;
166 struct ALCbackend;
167 struct ALbuffer;
168 struct ALeffect;
169 struct ALfilter;
170 struct ALsource;
171 struct ALcontextProps;
172 struct ALlistenerProps;
173 struct ALvoiceProps;
174 struct ALeffectslotProps;
177 #define DEFAULT_OUTPUT_RATE (44100)
178 #define MIN_OUTPUT_RATE (8000)
181 /* Find the next power-of-2 for non-power-of-2 numbers. */
182 inline ALuint NextPowerOf2(ALuint value)
184 if(value > 0)
186 value--;
187 value |= value>>1;
188 value |= value>>2;
189 value |= value>>4;
190 value |= value>>8;
191 value |= value>>16;
193 return value+1;
196 /** Round up a value to the next multiple. */
197 inline size_t RoundUp(size_t value, size_t r)
199 value += r-1;
200 return value - (value%r);
203 /* Fast float-to-int conversion. Assumes the FPU is already in round-to-zero
204 * mode. */
205 inline ALint fastf2i(ALfloat f)
207 #ifdef HAVE_LRINTF
208 return lrintf(f);
209 #elif defined(_MSC_VER) && defined(_M_IX86)
210 ALint i;
211 __asm fld f
212 __asm fistp i
213 return i;
214 #else
215 return (ALint)f;
216 #endif
220 enum DevProbe {
221 ALL_DEVICE_PROBE,
222 CAPTURE_DEVICE_PROBE
226 enum DistanceModel {
227 InverseDistanceClamped = AL_INVERSE_DISTANCE_CLAMPED,
228 LinearDistanceClamped = AL_LINEAR_DISTANCE_CLAMPED,
229 ExponentDistanceClamped = AL_EXPONENT_DISTANCE_CLAMPED,
230 InverseDistance = AL_INVERSE_DISTANCE,
231 LinearDistance = AL_LINEAR_DISTANCE,
232 ExponentDistance = AL_EXPONENT_DISTANCE,
233 DisableDistance = AL_NONE,
235 DefaultDistanceModel = InverseDistanceClamped
238 enum Channel {
239 FrontLeft = 0,
240 FrontRight,
241 FrontCenter,
242 LFE,
243 BackLeft,
244 BackRight,
245 BackCenter,
246 SideLeft,
247 SideRight,
249 UpperFrontLeft,
250 UpperFrontRight,
251 UpperBackLeft,
252 UpperBackRight,
253 LowerFrontLeft,
254 LowerFrontRight,
255 LowerBackLeft,
256 LowerBackRight,
258 Aux0,
259 Aux1,
260 Aux2,
261 Aux3,
262 Aux4,
263 Aux5,
264 Aux6,
265 Aux7,
266 Aux8,
267 Aux9,
268 Aux10,
269 Aux11,
270 Aux12,
271 Aux13,
272 Aux14,
273 Aux15,
275 InvalidChannel
279 /* Device formats */
280 enum DevFmtType {
281 DevFmtByte = ALC_BYTE_SOFT,
282 DevFmtUByte = ALC_UNSIGNED_BYTE_SOFT,
283 DevFmtShort = ALC_SHORT_SOFT,
284 DevFmtUShort = ALC_UNSIGNED_SHORT_SOFT,
285 DevFmtInt = ALC_INT_SOFT,
286 DevFmtUInt = ALC_UNSIGNED_INT_SOFT,
287 DevFmtFloat = ALC_FLOAT_SOFT,
289 DevFmtTypeDefault = DevFmtFloat
291 enum DevFmtChannels {
292 DevFmtMono = ALC_MONO_SOFT,
293 DevFmtStereo = ALC_STEREO_SOFT,
294 DevFmtQuad = ALC_QUAD_SOFT,
295 DevFmtX51 = ALC_5POINT1_SOFT,
296 DevFmtX61 = ALC_6POINT1_SOFT,
297 DevFmtX71 = ALC_7POINT1_SOFT,
298 DevFmtAmbi3D = ALC_BFORMAT3D_SOFT,
300 /* Similar to 5.1, except using rear channels instead of sides */
301 DevFmtX51Rear = 0x80000000,
303 DevFmtChannelsDefault = DevFmtStereo
305 #define MAX_OUTPUT_CHANNELS (16)
307 ALsizei BytesFromDevFmt(enum DevFmtType type);
308 ALsizei ChannelsFromDevFmt(enum DevFmtChannels chans, ALsizei ambiorder);
309 inline ALsizei FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type, ALsizei ambiorder)
311 return ChannelsFromDevFmt(chans, ambiorder) * BytesFromDevFmt(type);
314 enum AmbiLayout {
315 AmbiLayout_FuMa = ALC_FUMA_SOFT, /* FuMa channel order */
316 AmbiLayout_ACN = ALC_ACN_SOFT, /* ACN channel order */
318 AmbiLayout_Default = AmbiLayout_ACN
321 enum AmbiNorm {
322 AmbiNorm_FuMa = ALC_FUMA_SOFT, /* FuMa normalization */
323 AmbiNorm_SN3D = ALC_SN3D_SOFT, /* SN3D normalization */
324 AmbiNorm_N3D = ALC_N3D_SOFT, /* N3D normalization */
326 AmbiNorm_Default = AmbiNorm_SN3D
330 enum DeviceType {
331 Playback,
332 Capture,
333 Loopback
337 enum RenderMode {
338 NormalRender,
339 StereoPair,
340 HrtfRender
344 /* The maximum number of Ambisonics coefficients. For a given order (o), the
345 * size needed will be (o+1)**2, thus zero-order has 1, first-order has 4,
346 * second-order has 9, third-order has 16, and fourth-order has 25.
348 #define MAX_AMBI_ORDER 3
349 #define MAX_AMBI_COEFFS ((MAX_AMBI_ORDER+1) * (MAX_AMBI_ORDER+1))
351 /* A bitmask of ambisonic channels with height information. If none of these
352 * channels are used/needed, there's no height (e.g. with most surround sound
353 * speaker setups). This only specifies up to 4th order, which is the highest
354 * order a 32-bit mask value can specify (a 64-bit mask could handle up to 7th
355 * order). This is ACN ordering, with bit 0 being ACN 0, etc.
357 #define AMBI_PERIPHONIC_MASK (0xfe7ce4)
359 /* The maximum number of Ambisonic coefficients for 2D (non-periphonic)
360 * representation. This is 2 per each order above zero-order, plus 1 for zero-
361 * order. Or simply, o*2 + 1.
363 #define MAX_AMBI2D_COEFFS (MAX_AMBI_ORDER*2 + 1)
366 typedef ALfloat ChannelConfig[MAX_AMBI_COEFFS];
367 typedef struct BFChannelConfig {
368 ALfloat Scale;
369 ALsizei Index;
370 } BFChannelConfig;
372 typedef union AmbiConfig {
373 /* Ambisonic coefficients for mixing to the dry buffer. */
374 ChannelConfig Coeffs[MAX_OUTPUT_CHANNELS];
375 /* Coefficient channel mapping for mixing to the dry buffer. */
376 BFChannelConfig Map[MAX_OUTPUT_CHANNELS];
377 } AmbiConfig;
380 typedef struct BufferSubList {
381 ALuint64 FreeMask;
382 struct ALbuffer *Buffers; /* 64 */
383 } BufferSubList;
384 TYPEDEF_VECTOR(BufferSubList, vector_BufferSubList)
386 typedef struct EffectSubList {
387 ALuint64 FreeMask;
388 struct ALeffect *Effects; /* 64 */
389 } EffectSubList;
390 TYPEDEF_VECTOR(EffectSubList, vector_EffectSubList)
392 typedef struct FilterSubList {
393 ALuint64 FreeMask;
394 struct ALfilter *Filters; /* 64 */
395 } FilterSubList;
396 TYPEDEF_VECTOR(FilterSubList, vector_FilterSubList)
398 typedef struct SourceSubList {
399 ALuint64 FreeMask;
400 struct ALsource *Sources; /* 64 */
401 } SourceSubList;
402 TYPEDEF_VECTOR(SourceSubList, vector_SourceSubList)
404 /* Effect slots are rather large, and apps aren't likely to have more than one
405 * or two (let alone 64), so hold them individually.
407 typedef struct ALeffectslot *ALeffectslotPtr;
408 TYPEDEF_VECTOR(ALeffectslotPtr, vector_ALeffectslotPtr)
411 typedef struct EnumeratedHrtf {
412 al_string name;
414 struct HrtfEntry *hrtf;
415 } EnumeratedHrtf;
416 TYPEDEF_VECTOR(EnumeratedHrtf, vector_EnumeratedHrtf)
419 /* Maximum delay in samples for speaker distance compensation. */
420 #define MAX_DELAY_LENGTH 1024
422 typedef struct DistanceComp {
423 ALfloat Gain;
424 ALsizei Length; /* Valid range is [0...MAX_DELAY_LENGTH). */
425 ALfloat *Buffer;
426 } DistanceComp;
428 /* Size for temporary storage of buffer data, in ALfloats. Larger values need
429 * more memory, while smaller values may need more iterations. The value needs
430 * to be a sensible size, however, as it constrains the max stepping value used
431 * for mixing, as well as the maximum number of samples per mixing iteration.
433 #define BUFFERSIZE 2048
435 typedef struct DryMixParams {
436 AmbiConfig Ambi;
437 /* Number of coefficients in each Ambi.Coeffs to mix together (4 for first-
438 * order, 9 for second-order, etc). If the count is 0, Ambi.Map is used
439 * instead to map each output to a coefficient index.
441 ALsizei CoeffCount;
443 ALfloat (*Buffer)[BUFFERSIZE];
444 ALsizei NumChannels;
445 ALsizei NumChannelsPerOrder[MAX_AMBI_ORDER+1];
446 } DryMixParams;
448 typedef struct BFMixParams {
449 AmbiConfig Ambi;
450 /* Will only be 4 or 0. */
451 ALsizei CoeffCount;
453 ALfloat (*Buffer)[BUFFERSIZE];
454 ALsizei NumChannels;
455 } BFMixParams;
457 typedef struct RealMixParams {
458 enum Channel ChannelName[MAX_OUTPUT_CHANNELS];
460 ALfloat (*Buffer)[BUFFERSIZE];
461 ALsizei NumChannels;
462 } RealMixParams;
464 struct ALCdevice_struct
466 RefCount ref;
468 ALCboolean Connected;
469 enum DeviceType Type;
471 ALuint Frequency;
472 ALuint UpdateSize;
473 ALuint NumUpdates;
474 enum DevFmtChannels FmtChans;
475 enum DevFmtType FmtType;
476 ALboolean IsHeadphones;
477 ALsizei AmbiOrder;
478 /* For DevFmtAmbi* output only, specifies the channel order and
479 * normalization.
481 enum AmbiLayout AmbiLayout;
482 enum AmbiNorm AmbiScale;
484 al_string DeviceName;
486 ATOMIC(ALCenum) LastError;
488 // Maximum number of sources that can be created
489 ALuint SourcesMax;
490 // Maximum number of slots that can be created
491 ALuint AuxiliaryEffectSlotMax;
493 ALCuint NumMonoSources;
494 ALCuint NumStereoSources;
495 ALsizei NumAuxSends;
497 // Map of Buffers for this device
498 vector_BufferSubList BufferList;
499 almtx_t BufferLock;
501 // Map of Effects for this device
502 vector_EffectSubList EffectList;
503 almtx_t EffectLock;
505 // Map of Filters for this device
506 vector_FilterSubList FilterList;
507 almtx_t FilterLock;
509 /* HRTF state and info */
510 struct DirectHrtfState *Hrtf;
511 al_string HrtfName;
512 struct Hrtf *HrtfHandle;
513 vector_EnumeratedHrtf HrtfList;
514 ALCenum HrtfStatus;
516 /* UHJ encoder state */
517 struct Uhj2Encoder *Uhj_Encoder;
519 /* High quality Ambisonic decoder */
520 struct BFormatDec *AmbiDecoder;
522 /* Stereo-to-binaural filter */
523 struct bs2b *Bs2b;
525 /* First-order ambisonic upsampler for higher-order output */
526 struct AmbiUpsampler *AmbiUp;
528 /* Rendering mode. */
529 enum RenderMode Render_Mode;
531 // Device flags
532 ALuint Flags;
534 ALuint64 ClockBase;
535 ALuint SamplesDone;
537 /* Temp storage used for mixer processing. */
538 alignas(16) ALfloat TempBuffer[4][BUFFERSIZE];
540 /* The "dry" path corresponds to the main output. */
541 DryMixParams Dry;
543 /* First-order ambisonics output, to be upsampled to the dry buffer if different. */
544 BFMixParams FOAOut;
546 /* "Real" output, which will be written to the device buffer. May alias the
547 * dry buffer.
549 RealMixParams RealOut;
551 struct FrontStablizer *Stablizer;
553 struct Compressor *Limiter;
555 /* The average speaker distance as determined by the ambdec configuration
556 * (or alternatively, by the NFC-HOA reference delay). Only used for NFC.
558 ALfloat AvgSpeakerDist;
560 /* Delay buffers used to compensate for speaker distances. */
561 DistanceComp ChannelDelay[MAX_OUTPUT_CHANNELS];
563 /* Dithering control. */
564 ALfloat DitherDepth;
565 ALuint DitherSeed;
567 /* Running count of the mixer invocations, in 31.1 fixed point. This
568 * actually increments *twice* when mixing, first at the start and then at
569 * the end, so the bottom bit indicates if the device is currently mixing
570 * and the upper bits indicates how many mixes have been done.
572 RefCount MixCount;
574 // Contexts created on this device
575 ATOMIC(ALCcontext*) ContextList;
577 almtx_t BackendLock;
578 struct ALCbackend *Backend;
580 ALCdevice *volatile next;
583 // Frequency was requested by the app or config file
584 #define DEVICE_FREQUENCY_REQUEST (1u<<1)
585 // Channel configuration was requested by the config file
586 #define DEVICE_CHANNELS_REQUEST (1u<<2)
587 // Sample type was requested by the config file
588 #define DEVICE_SAMPLE_TYPE_REQUEST (1u<<3)
590 // Specifies if the DSP is paused at user request
591 #define DEVICE_PAUSED (1u<<30)
593 // Specifies if the device is currently running
594 #define DEVICE_RUNNING (1u<<31)
597 /* Nanosecond resolution for the device clock time. */
598 #define DEVICE_CLOCK_RES U64(1000000000)
601 /* Must be less than 15 characters (16 including terminating null) for
602 * compatibility with pthread_setname_np limitations. */
603 #define MIXER_THREAD_NAME "alsoft-mixer"
605 #define RECORD_THREAD_NAME "alsoft-record"
608 enum {
609 EventType_SourceStateChange = 1<<0,
610 EventType_BufferCompleted = 1<<1,
611 EventType_Error = 1<<2,
612 EventType_Performance = 1<<3,
613 EventType_Deprecated = 1<<4,
616 struct ALCcontext_struct {
617 RefCount ref;
619 struct ALlistener *Listener;
621 vector_SourceSubList SourceList;
622 ALuint NumSources;
623 almtx_t SourceLock;
625 vector_ALeffectslotPtr EffectSlotList;
626 almtx_t EffectSlotLock;
628 ATOMIC(ALenum) LastError;
630 enum DistanceModel DistanceModel;
631 ALboolean SourceDistanceModel;
633 ALfloat DopplerFactor;
634 ALfloat DopplerVelocity;
635 ALfloat SpeedOfSound;
636 ALfloat MetersPerUnit;
638 ATOMIC_FLAG PropsClean;
639 ATOMIC(ALenum) DeferUpdates;
641 RWLock PropLock;
643 /* Counter for the pre-mixing updates, in 31.1 fixed point (lowest bit
644 * indicates if updates are currently happening).
646 RefCount UpdateCount;
647 ATOMIC(ALenum) HoldUpdates;
649 ALfloat GainBoost;
651 ATOMIC(struct ALcontextProps*) Update;
653 /* Linked lists of unused property containers, free to use for future
654 * updates.
656 ATOMIC(struct ALcontextProps*) FreeContextProps;
657 ATOMIC(struct ALlistenerProps*) FreeListenerProps;
658 ATOMIC(struct ALvoiceProps*) FreeVoiceProps;
659 ATOMIC(struct ALeffectslotProps*) FreeEffectslotProps;
661 struct ALvoice **Voices;
662 ALsizei VoiceCount;
663 ALsizei MaxVoices;
665 ATOMIC(struct ALeffectslotArray*) ActiveAuxSlots;
667 almtx_t EventCbLock;
668 ATOMIC(ALbitfieldSOFT) EnabledEvts;
669 ALEVENTPROCSOFT EventCb;
670 void *EventParam;
672 /* Default effect slot */
673 struct ALeffectslot *DefaultSlot;
675 ALCdevice *Device;
676 const ALCchar *ExtensionList;
678 ALCcontext *volatile next;
680 /* Memory space used by the listener (and possibly default effect slot) */
681 alignas(16) ALCbyte _listener_mem[];
684 ALCcontext *GetContextRef(void);
686 void ALCcontext_DecRef(ALCcontext *context);
688 void ALCcontext_DeferUpdates(ALCcontext *context);
689 void ALCcontext_ProcessUpdates(ALCcontext *context);
691 void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends);
693 void AppendAllDevicesList(const ALCchar *name);
694 void AppendCaptureDeviceList(const ALCchar *name);
697 extern ALint RTPrioLevel;
698 void SetRTPriority(void);
700 void SetDefaultChannelOrder(ALCdevice *device);
701 void SetDefaultWFXChannelOrder(ALCdevice *device);
703 const ALCchar *DevFmtTypeString(enum DevFmtType type);
704 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans);
706 inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS], enum Channel chan)
708 ALint i;
709 for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
711 if(names[i] == chan)
712 return i;
714 return -1;
717 * GetChannelIdxByName
719 * Returns the index for the given channel name (e.g. FrontCenter), or -1 if it
720 * doesn't exist.
722 inline ALint GetChannelIdxByName(const RealMixParams *real, enum Channel chan)
723 { return GetChannelIndex(real->ChannelName, chan); }
726 inline void LockBufferList(ALCdevice *device) { almtx_lock(&device->BufferLock); }
727 inline void UnlockBufferList(ALCdevice *device) { almtx_unlock(&device->BufferLock); }
729 inline void LockEffectList(ALCdevice *device) { almtx_lock(&device->EffectLock); }
730 inline void UnlockEffectList(ALCdevice *device) { almtx_unlock(&device->EffectLock); }
732 inline void LockFilterList(ALCdevice *device) { almtx_lock(&device->FilterLock); }
733 inline void UnlockFilterList(ALCdevice *device) { almtx_unlock(&device->FilterLock); }
735 inline void LockEffectSlotList(ALCcontext *context)
736 { almtx_lock(&context->EffectSlotLock); }
737 inline void UnlockEffectSlotList(ALCcontext *context)
738 { almtx_unlock(&context->EffectSlotLock); }
741 vector_al_string SearchDataFiles(const char *match, const char *subdir);
743 #ifdef __cplusplus
745 #endif
747 #endif