761 lines
19 KiB
C
Raw Normal View History

2007-11-13 18:02:18 -08:00
#ifndef AL_MAIN_H
#define AL_MAIN_H
#include <string.h>
#include <stdio.h>
#include <stddef.h>
#include <stdarg.h>
#include <assert.h>
#include <math.h>
#include <limits.h>
2007-11-13 18:02:18 -08:00
2013-11-05 13:07:46 -08:00
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#ifdef HAVE_INTRIN_H
#include <intrin.h>
#endif
2013-11-05 13:07:46 -08:00
2009-05-16 23:26:39 -07:00
#include "AL/al.h"
#include "AL/alc.h"
#include "AL/alext.h"
2018-01-26 21:32:43 -08:00
#include "inprogext.h"
#include "logging.h"
#include "polymorphism.h"
#include "static_assert.h"
2014-04-19 02:11:04 -07:00
#include "align.h"
2013-10-28 12:48:13 -07:00
#include "atomic.h"
#include "uintmap.h"
#include "vector.h"
2014-03-28 22:11:34 -07:00
#include "alstring.h"
#include "almalloc.h"
#include "threads.h"
2013-10-28 12:48:13 -07:00
#if defined(_WIN64)
#define SZFMT "%I64u"
#elif defined(_WIN32)
#define SZFMT "%u"
#else
#define SZFMT "%zu"
#endif
#ifdef __GNUC__
#define LIKELY(x) __builtin_expect(!!(x), !0)
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
#else
#define LIKELY(x) (!!(x))
#define UNLIKELY(x) (!!(x))
#endif
typedef ALint64SOFT ALint64;
typedef ALuint64SOFT ALuint64;
#ifndef U64
#if defined(_MSC_VER)
#define U64(x) ((ALuint64)(x##ui64))
#elif SIZEOF_LONG == 8
#define U64(x) ((ALuint64)(x##ul))
#elif SIZEOF_LONG_LONG == 8
#define U64(x) ((ALuint64)(x##ull))
#endif
#endif
2013-11-27 05:09:33 -08:00
#ifndef UINT64_MAX
#define UINT64_MAX U64(18446744073709551615)
#endif
#ifndef UNUSED
#if defined(__cplusplus)
#define UNUSED(x)
#elif defined(__GNUC__)
#define UNUSED(x) UNUSED_##x __attribute__((unused))
#elif defined(__LCLINT__)
#define UNUSED(x) /*@unused@*/ x
#else
#define UNUSED(x) x
#endif
#endif
/* Calculates the size of a struct with N elements of a flexible array member.
* GCC and Clang allow offsetof(Type, fam[N]) for this, but MSVC seems to have
* trouble, so a bit more verbose workaround is needed.
*/
#define FAM_SIZE(T, M, N) (offsetof(T, M) + sizeof(((T*)NULL)->M[0])*(N))
/* Define a CTZ64 macro (count trailing zeros, for 64-bit integers). The result
* is *UNDEFINED* if the value is 0.
*/
#ifdef __GNUC__
#if SIZEOF_LONG == 8
#define CTZ64(x) __builtin_ctzl(x)
#else
#define CTZ64(x) __builtin_ctzll(x)
#endif
#elif defined(HAVE_BITSCANFORWARD64_INTRINSIC)
static inline int msvc64_ctz64(ALuint64 v)
{
unsigned long idx = 64;
_BitScanForward64(&idx, v);
return (int)idx;
}
#define CTZ64(x) msvc64_ctz64(x)
#elif defined(HAVE_BITSCANFORWARD_INTRINSIC)
static inline int msvc_ctz64(ALuint64 v)
{
unsigned long idx = 64;
if(!_BitScanForward(&idx, v&0xffffffff))
{
if(_BitScanForward(&idx, v>>32))
idx += 32;
}
return (int)idx;
}
#define CTZ64(x) msvc_ctz64(x)
#else
/* There be black magics here. The popcnt64 method is derived from
* https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
* while the ctz-utilizing-popcnt algorithm is shown here
* http://www.hackersdelight.org/hdcodetxt/ntz.c.txt
* as the ntz2 variant. These likely aren't the most efficient methods, but
* they're good enough if the GCC or MSVC intrinsics aren't available.
*/
static inline int fallback_popcnt64(ALuint64 v)
{
v = v - ((v >> 1) & U64(0x5555555555555555));
v = (v & U64(0x3333333333333333)) + ((v >> 2) & U64(0x3333333333333333));
v = (v + (v >> 4)) & U64(0x0f0f0f0f0f0f0f0f);
return (int)((v * U64(0x0101010101010101)) >> 56);
}
static inline int fallback_ctz64(ALuint64 value)
{
return fallback_popcnt64(~value & (value - 1));
}
#define CTZ64(x) fallback_ctz64(x)
#endif
2012-02-15 21:47:35 -08:00
static const union {
ALuint u;
ALubyte b[sizeof(ALuint)];
} EndianTest = { 1 };
#define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1)
2017-04-16 15:05:57 -07:00
#define COUNTOF(x) (sizeof(x) / sizeof(0[x]))
2012-02-15 21:47:35 -08:00
2007-11-13 18:02:18 -08:00
#ifdef __cplusplus
extern "C" {
2007-11-13 18:02:18 -08:00
#endif
struct ll_ringbuffer;
struct Hrtf;
struct HrtfEntry;
2018-01-11 03:53:25 -08:00
struct DirectHrtfState;
struct FrontStablizer;
struct Compressor;
struct ALCbackend;
2018-01-26 21:32:43 -08:00
struct ALbuffer;
2018-01-27 19:01:25 -08:00
struct ALeffect;
2018-01-27 19:40:47 -08:00
struct ALfilter;
struct ALsource;
struct ALcontextProps;
struct ALlistenerProps;
struct ALvoiceProps;
struct ALeffectslotProps;
#define DEFAULT_OUTPUT_RATE (44100)
#define MIN_OUTPUT_RATE (8000)
2013-11-04 13:44:46 -08:00
/* Find the next power-of-2 for non-power-of-2 numbers. */
inline ALuint NextPowerOf2(ALuint value)
2009-11-19 09:50:15 -08:00
{
if(value > 0)
2009-11-19 09:50:15 -08:00
{
value--;
value |= value>>1;
value |= value>>2;
value |= value>>4;
value |= value>>8;
value |= value>>16;
2009-11-19 09:50:15 -08:00
}
return value+1;
2009-11-19 09:50:15 -08:00
}
/** Round up a value to the next multiple. */
inline size_t RoundUp(size_t value, size_t r)
{
value += r-1;
return value - (value%r);
}
/* Fast float-to-int conversion. Assumes the FPU is already in round-to-zero
* mode. */
2013-11-04 13:44:46 -08:00
inline ALint fastf2i(ALfloat f)
{
#ifdef HAVE_LRINTF
return lrintf(f);
#elif defined(_MSC_VER) && defined(_M_IX86)
ALint i;
__asm fld f
__asm fistp i
return i;
#else
return (ALint)f;
#endif
}
2009-11-19 09:50:15 -08:00
enum DevProbe {
ALL_DEVICE_PROBE,
CAPTURE_DEVICE_PROBE
};
2012-09-14 02:42:36 -07:00
enum DistanceModel {
InverseDistanceClamped = AL_INVERSE_DISTANCE_CLAMPED,
LinearDistanceClamped = AL_LINEAR_DISTANCE_CLAMPED,
ExponentDistanceClamped = AL_EXPONENT_DISTANCE_CLAMPED,
InverseDistance = AL_INVERSE_DISTANCE,
LinearDistance = AL_LINEAR_DISTANCE,
ExponentDistance = AL_EXPONENT_DISTANCE,
DisableDistance = AL_NONE,
DefaultDistanceModel = InverseDistanceClamped
};
2012-09-14 02:14:29 -07:00
enum Channel {
FrontLeft = 0,
FrontRight,
FrontCenter,
LFE,
BackLeft,
BackRight,
BackCenter,
SideLeft,
SideRight,
UpperFrontLeft,
UpperFrontRight,
UpperBackLeft,
UpperBackRight,
LowerFrontLeft,
LowerFrontRight,
LowerBackLeft,
LowerBackRight,
2016-03-16 06:49:35 -07:00
Aux0,
Aux1,
Aux2,
Aux3,
Aux4,
Aux5,
Aux6,
Aux7,
Aux8,
Aux9,
Aux10,
Aux11,
Aux12,
Aux13,
Aux14,
Aux15,
InvalidChannel
2012-09-14 02:14:29 -07:00
};
2014-11-07 15:47:41 -08:00
2012-09-14 02:42:36 -07:00
/* Device formats */
enum DevFmtType {
DevFmtByte = ALC_BYTE_SOFT,
DevFmtUByte = ALC_UNSIGNED_BYTE_SOFT,
DevFmtShort = ALC_SHORT_SOFT,
DevFmtUShort = ALC_UNSIGNED_SHORT_SOFT,
DevFmtInt = ALC_INT_SOFT,
DevFmtUInt = ALC_UNSIGNED_INT_SOFT,
DevFmtFloat = ALC_FLOAT_SOFT,
DevFmtTypeDefault = DevFmtFloat
};
enum DevFmtChannels {
DevFmtMono = ALC_MONO_SOFT,
DevFmtStereo = ALC_STEREO_SOFT,
DevFmtQuad = ALC_QUAD_SOFT,
DevFmtX51 = ALC_5POINT1_SOFT,
DevFmtX61 = ALC_6POINT1_SOFT,
DevFmtX71 = ALC_7POINT1_SOFT,
DevFmtAmbi3D = ALC_BFORMAT3D_SOFT,
/* Similar to 5.1, except using rear channels instead of sides */
DevFmtX51Rear = 0x80000000,
DevFmtChannelsDefault = DevFmtStereo
};
#define MAX_OUTPUT_CHANNELS (16)
2017-01-18 07:13:23 -08:00
ALsizei BytesFromDevFmt(enum DevFmtType type);
ALsizei ChannelsFromDevFmt(enum DevFmtChannels chans, ALsizei ambiorder);
inline ALsizei FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type, ALsizei ambiorder)
{
return ChannelsFromDevFmt(chans, ambiorder) * BytesFromDevFmt(type);
}
enum AmbiLayout {
AmbiLayout_FuMa = ALC_FUMA_SOFT, /* FuMa channel order */
AmbiLayout_ACN = ALC_ACN_SOFT, /* ACN channel order */
AmbiLayout_Default = AmbiLayout_ACN
};
enum AmbiNorm {
AmbiNorm_FuMa = ALC_FUMA_SOFT, /* FuMa normalization */
AmbiNorm_SN3D = ALC_SN3D_SOFT, /* SN3D normalization */
AmbiNorm_N3D = ALC_N3D_SOFT, /* N3D normalization */
AmbiNorm_Default = AmbiNorm_SN3D
};
2012-02-23 15:25:30 -08:00
enum DeviceType {
Playback,
Capture,
Loopback
};
2012-09-14 02:14:29 -07:00
enum RenderMode {
NormalRender,
StereoPair,
HrtfRender
};
/* The maximum number of Ambisonics coefficients. For a given order (o), the
* size needed will be (o+1)**2, thus zero-order has 1, first-order has 4,
* second-order has 9, third-order has 16, and fourth-order has 25.
*/
2016-03-14 09:04:03 -07:00
#define MAX_AMBI_ORDER 3
#define MAX_AMBI_COEFFS ((MAX_AMBI_ORDER+1) * (MAX_AMBI_ORDER+1))
/* A bitmask of ambisonic channels with height information. If none of these
* channels are used/needed, there's no height (e.g. with most surround sound
* speaker setups). This only specifies up to 4th order, which is the highest
* order a 32-bit mask value can specify (a 64-bit mask could handle up to 7th
* order). This is ACN ordering, with bit 0 being ACN 0, etc.
*/
#define AMBI_PERIPHONIC_MASK (0xfe7ce4)
/* The maximum number of Ambisonic coefficients for 2D (non-periphonic)
* representation. This is 2 per each order above zero-order, plus 1 for zero-
* order. Or simply, o*2 + 1.
*/
#define MAX_AMBI2D_COEFFS (MAX_AMBI_ORDER*2 + 1)
typedef ALfloat ChannelConfig[MAX_AMBI_COEFFS];
typedef struct BFChannelConfig {
ALfloat Scale;
ALsizei Index;
} BFChannelConfig;
typedef union AmbiConfig {
/* Ambisonic coefficients for mixing to the dry buffer. */
ChannelConfig Coeffs[MAX_OUTPUT_CHANNELS];
/* Coefficient channel mapping for mixing to the dry buffer. */
BFChannelConfig Map[MAX_OUTPUT_CHANNELS];
} AmbiConfig;
typedef struct BufferSubList {
ALuint64 FreeMask;
struct ALbuffer *Buffers; /* 64 */
} BufferSubList;
TYPEDEF_VECTOR(BufferSubList, vector_BufferSubList)
2018-01-27 19:01:25 -08:00
typedef struct EffectSubList {
ALuint64 FreeMask;
struct ALeffect *Effects; /* 64 */
} EffectSubList;
TYPEDEF_VECTOR(EffectSubList, vector_EffectSubList)
2018-01-27 19:40:47 -08:00
typedef struct FilterSubList {
ALuint64 FreeMask;
struct ALfilter *Filters; /* 64 */
} FilterSubList;
TYPEDEF_VECTOR(FilterSubList, vector_FilterSubList)
typedef struct SourceSubList {
ALuint64 FreeMask;
struct ALsource *Sources; /* 64 */
} SourceSubList;
TYPEDEF_VECTOR(SourceSubList, vector_SourceSubList)
/* Effect slots are rather large, and apps aren't likely to have more than one
* or two (let alone 64), so hold them individually.
*/
typedef struct ALeffectslot *ALeffectslotPtr;
TYPEDEF_VECTOR(ALeffectslotPtr, vector_ALeffectslotPtr)
typedef struct EnumeratedHrtf {
al_string name;
struct HrtfEntry *hrtf;
} EnumeratedHrtf;
TYPEDEF_VECTOR(EnumeratedHrtf, vector_EnumeratedHrtf)
/* Maximum delay in samples for speaker distance compensation. */
#define MAX_DELAY_LENGTH 1024
typedef struct DistanceComp {
ALfloat Gain;
ALsizei Length; /* Valid range is [0...MAX_DELAY_LENGTH). */
ALfloat *Buffer;
} DistanceComp;
2012-09-14 02:14:29 -07:00
/* Size for temporary storage of buffer data, in ALfloats. Larger values need
* more memory, while smaller values may need more iterations. The value needs
2012-09-14 02:14:29 -07:00
* to be a sensible size, however, as it constrains the max stepping value used
* for mixing, as well as the maximum number of samples per mixing iteration.
*/
#define BUFFERSIZE 2048
2012-09-14 02:14:29 -07:00
typedef struct DryMixParams {
AmbiConfig Ambi;
/* Number of coefficients in each Ambi.Coeffs to mix together (4 for first-
* order, 9 for second-order, etc). If the count is 0, Ambi.Map is used
* instead to map each output to a coefficient index.
*/
ALsizei CoeffCount;
ALfloat (*Buffer)[BUFFERSIZE];
ALsizei NumChannels;
ALsizei NumChannelsPerOrder[MAX_AMBI_ORDER+1];
} DryMixParams;
typedef struct BFMixParams {
AmbiConfig Ambi;
/* Will only be 4 or 0. */
ALsizei CoeffCount;
ALfloat (*Buffer)[BUFFERSIZE];
ALsizei NumChannels;
} BFMixParams;
typedef struct RealMixParams {
enum Channel ChannelName[MAX_OUTPUT_CHANNELS];
ALfloat (*Buffer)[BUFFERSIZE];
ALsizei NumChannels;
} RealMixParams;
2007-11-13 18:02:18 -08:00
struct ALCdevice_struct
{
RefCount ref;
2012-02-23 15:25:30 -08:00
ALCboolean Connected;
enum DeviceType Type;
2007-11-13 18:02:18 -08:00
ALuint Frequency;
ALuint UpdateSize;
ALuint NumUpdates;
enum DevFmtChannels FmtChans;
enum DevFmtType FmtType;
ALboolean IsHeadphones;
ALsizei AmbiOrder;
/* For DevFmtAmbi* output only, specifies the channel order and
* normalization.
*/
enum AmbiLayout AmbiLayout;
enum AmbiNorm AmbiScale;
2007-11-13 18:02:18 -08:00
2014-03-28 22:11:34 -07:00
al_string DeviceName;
2007-11-13 18:02:18 -08:00
2014-07-22 18:57:51 -07:00
ATOMIC(ALCenum) LastError;
2007-11-13 18:02:18 -08:00
// Maximum number of sources that can be created
2016-06-08 11:19:33 -07:00
ALuint SourcesMax;
// Maximum number of slots that can be created
ALuint AuxiliaryEffectSlotMax;
2007-11-13 18:02:18 -08:00
ALCuint NumMonoSources;
ALCuint NumStereoSources;
ALsizei NumAuxSends;
// Map of Buffers for this device
vector_BufferSubList BufferList;
almtx_t BufferLock;
2009-08-15 09:14:08 -07:00
2010-05-18 17:41:06 -07:00
// Map of Effects for this device
2018-01-27 19:01:25 -08:00
vector_EffectSubList EffectList;
almtx_t EffectLock;
2010-05-18 17:54:45 -07:00
// Map of Filters for this device
2018-01-27 19:40:47 -08:00
vector_FilterSubList FilterList;
almtx_t FilterLock;
/* HRTF state and info */
2018-01-11 03:53:25 -08:00
struct DirectHrtfState *Hrtf;
al_string HrtfName;
struct Hrtf *HrtfHandle;
vector_EnumeratedHrtf HrtfList;
ALCenum HrtfStatus;
2016-02-26 16:09:06 -08:00
/* UHJ encoder state */
struct Uhj2Encoder *Uhj_Encoder;
/* High quality Ambisonic decoder */
struct BFormatDec *AmbiDecoder;
/* Stereo-to-binaural filter */
struct bs2b *Bs2b;
/* First-order ambisonic upsampler for higher-order output */
struct AmbiUpsampler *AmbiUp;
/* Rendering mode. */
enum RenderMode Render_Mode;
2011-05-01 18:18:37 -07:00
// Device flags
ALuint Flags;
2011-05-01 13:19:23 -07:00
ALuint64 ClockBase;
ALuint SamplesDone;
/* Temp storage used for mixer processing. */
alignas(16) ALfloat TempBuffer[4][BUFFERSIZE];
/* The "dry" path corresponds to the main output. */
DryMixParams Dry;
/* First-order ambisonics output, to be upsampled to the dry buffer if different. */
BFMixParams FOAOut;
2016-07-05 14:18:17 -07:00
/* "Real" output, which will be written to the device buffer. May alias the
* dry buffer.
*/
RealMixParams RealOut;
struct FrontStablizer *Stablizer;
struct Compressor *Limiter;
/* The average speaker distance as determined by the ambdec configuration
* (or alternatively, by the NFC-HOA reference delay). Only used for NFC.
*/
ALfloat AvgSpeakerDist;
/* Delay buffers used to compensate for speaker distances. */
DistanceComp ChannelDelay[MAX_OUTPUT_CHANNELS];
/* Dithering control. */
2017-06-17 23:09:51 -07:00
ALfloat DitherDepth;
ALuint DitherSeed;
/* Running count of the mixer invocations, in 31.1 fixed point. This
* actually increments *twice* when mixing, first at the start and then at
* the end, so the bottom bit indicates if the device is currently mixing
* and the upper bits indicates how many mixes have been done.
*/
RefCount MixCount;
// Contexts created on this device
ATOMIC(ALCcontext*) ContextList;
2007-11-13 18:02:18 -08:00
almtx_t BackendLock;
struct ALCbackend *Backend;
ALCdevice *volatile next;
2007-11-13 18:02:18 -08:00
};
2011-05-03 02:29:26 -07:00
// Frequency was requested by the app or config file
#define DEVICE_FREQUENCY_REQUEST (1u<<1)
// Channel configuration was requested by the config file
#define DEVICE_CHANNELS_REQUEST (1u<<2)
// Sample type was requested by the config file
#define DEVICE_SAMPLE_TYPE_REQUEST (1u<<3)
2011-05-01 18:18:37 -07:00
// Specifies if the DSP is paused at user request
#define DEVICE_PAUSED (1u<<30)
// Specifies if the device is currently running
#define DEVICE_RUNNING (1u<<31)
2011-05-01 18:18:37 -07:00
/* Nanosecond resolution for the device clock time. */
#define DEVICE_CLOCK_RES U64(1000000000)
/* Must be less than 15 characters (16 including terminating null) for
* compatibility with pthread_setname_np limitations. */
#define MIXER_THREAD_NAME "alsoft-mixer"
2014-12-21 10:38:40 -08:00
#define RECORD_THREAD_NAME "alsoft-record"
enum {
EventType_SourceStateChange = 1<<0,
EventType_BufferCompleted = 1<<1,
EventType_Error = 1<<2,
EventType_Performance = 1<<3,
EventType_Deprecated = 1<<4,
};
typedef struct AsyncEvent {
unsigned int EnumType;
ALenum Type;
ALuint ObjectId;
ALuint Param;
ALchar Message[1008];
} AsyncEvent;
struct ALCcontext_struct {
RefCount ref;
struct ALlistener *Listener;
2007-11-13 18:02:18 -08:00
vector_SourceSubList SourceList;
ALuint NumSources;
almtx_t SourceLock;
vector_ALeffectslotPtr EffectSlotList;
almtx_t EffectSlotLock;
2008-01-15 16:22:39 -08:00
2014-07-22 18:57:51 -07:00
ATOMIC(ALenum) LastError;
2007-11-13 18:02:18 -08:00
2016-09-24 14:29:27 -07:00
enum DistanceModel DistanceModel;
ALboolean SourceDistanceModel;
2007-11-13 18:02:18 -08:00
2016-09-24 14:29:27 -07:00
ALfloat DopplerFactor;
ALfloat DopplerVelocity;
ALfloat SpeedOfSound;
ALfloat MetersPerUnit;
ATOMIC_FLAG PropsClean;
2016-05-14 23:43:40 -07:00
ATOMIC(ALenum) DeferUpdates;
2007-11-13 18:02:18 -08:00
RWLock PropLock;
/* Counter for the pre-mixing updates, in 31.1 fixed point (lowest bit
* indicates if updates are currently happening).
*/
RefCount UpdateCount;
ATOMIC(ALenum) HoldUpdates;
ALfloat GainBoost;
ATOMIC(struct ALcontextProps*) Update;
/* Linked lists of unused property containers, free to use for future
* updates.
*/
ATOMIC(struct ALcontextProps*) FreeContextProps;
ATOMIC(struct ALlistenerProps*) FreeListenerProps;
ATOMIC(struct ALvoiceProps*) FreeVoiceProps;
ATOMIC(struct ALeffectslotProps*) FreeEffectslotProps;
struct ALvoice **Voices;
2014-08-21 03:24:48 -07:00
ALsizei VoiceCount;
ALsizei MaxVoices;
ATOMIC(struct ALeffectslotArray*) ActiveAuxSlots;
almtx_t EventThrdLock;
althrd_t EventThread;
alsem_t EventSem;
struct ll_ringbuffer *AsyncEvents;
2018-01-28 16:58:41 -08:00
ATOMIC(ALbitfieldSOFT) EnabledEvts;
almtx_t EventCbLock;
ALEVENTPROCSOFT EventCb;
void *EventParam;
/* Default effect slot */
struct ALeffectslot *DefaultSlot;
2007-11-13 18:02:18 -08:00
ALCdevice *Device;
const ALCchar *ExtensionList;
2007-11-13 18:02:18 -08:00
ALCcontext *volatile next;
/* Memory space used by the listener (and possibly default effect slot) */
2014-04-19 02:11:04 -07:00
alignas(16) ALCbyte _listener_mem[];
2007-11-13 18:02:18 -08:00
};
2011-09-11 09:28:30 -07:00
ALCcontext *GetContextRef(void);
void ALCcontext_DecRef(ALCcontext *context);
2018-01-12 02:37:48 -08:00
void ALCcontext_DeferUpdates(ALCcontext *context);
void ALCcontext_ProcessUpdates(ALCcontext *context);
void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends);
2012-05-09 16:28:16 -07:00
void AppendAllDevicesList(const ALCchar *name);
void AppendCaptureDeviceList(const ALCchar *name);
2007-11-13 18:02:18 -08:00
extern ALint RTPrioLevel;
void SetRTPriority(void);
void SetDefaultChannelOrder(ALCdevice *device);
void SetDefaultWFXChannelOrder(ALCdevice *device);
const ALCchar *DevFmtTypeString(enum DevFmtType type);
const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans);
2016-03-10 14:29:44 -08:00
inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS], enum Channel chan)
{
2016-03-10 14:29:44 -08:00
ALint i;
for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
{
2016-03-10 14:29:44 -08:00
if(names[i] == chan)
return i;
}
return -1;
}
/**
* GetChannelIdxByName
*
* Returns the index for the given channel name (e.g. FrontCenter), or -1 if it
* doesn't exist.
*/
inline ALint GetChannelIdxByName(const RealMixParams *real, enum Channel chan)
{ return GetChannelIndex(real->ChannelName, chan); }
2010-01-12 09:05:57 -08:00
2012-08-13 08:53:36 -07:00
inline void LockBufferList(ALCdevice *device) { almtx_lock(&device->BufferLock); }
inline void UnlockBufferList(ALCdevice *device) { almtx_unlock(&device->BufferLock); }
inline void LockEffectList(ALCdevice *device) { almtx_lock(&device->EffectLock); }
inline void UnlockEffectList(ALCdevice *device) { almtx_unlock(&device->EffectLock); }
inline void LockFilterList(ALCdevice *device) { almtx_lock(&device->FilterLock); }
inline void UnlockFilterList(ALCdevice *device) { almtx_unlock(&device->FilterLock); }
inline void LockEffectSlotList(ALCcontext *context)
{ almtx_lock(&context->EffectSlotLock); }
inline void UnlockEffectSlotList(ALCcontext *context)
{ almtx_unlock(&context->EffectSlotLock); }
2018-01-26 21:32:43 -08:00
vector_al_string SearchDataFiles(const char *match, const char *subdir);
2007-11-13 18:02:18 -08:00
#ifdef __cplusplus
}
#endif
#endif