aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32/Include
diff options
context:
space:
mode:
Diffstat (limited to 'OpenAL32/Include')
-rw-r--r--OpenAL32/Include/alAuxEffectSlot.h88
-rw-r--r--OpenAL32/Include/alBuffer.h14
-rw-r--r--OpenAL32/Include/alEffect.h127
-rw-r--r--OpenAL32/Include/alError.h15
-rw-r--r--OpenAL32/Include/alFilter.h78
-rw-r--r--OpenAL32/Include/alMain.h759
-rw-r--r--OpenAL32/Include/alMidi.h166
-rw-r--r--OpenAL32/Include/alSource.h31
-rw-r--r--OpenAL32/Include/alu.h76
-rw-r--r--OpenAL32/Include/threads.h14
10 files changed, 862 insertions, 506 deletions
diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h
index 4c14b1f7..c7182d9b 100644
--- a/OpenAL32/Include/alAuxEffectSlot.h
+++ b/OpenAL32/Include/alAuxEffectSlot.h
@@ -8,17 +8,62 @@
extern "C" {
#endif
+struct ALeffectStateVtable;
+struct ALeffectslot;
+
typedef struct ALeffectState {
- ALvoid (*Destroy)(struct ALeffectState *State);
- ALboolean (*DeviceUpdate)(struct ALeffectState *State, ALCdevice *Device);
- ALvoid (*Update)(struct ALeffectState *State, ALCdevice *Device, const struct ALeffectslot *Slot);
- ALvoid (*Process)(struct ALeffectState *State, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]);
+ const struct ALeffectStateVtable *vtbl;
} ALeffectState;
+struct ALeffectStateVtable {
+ void (*const Destruct)(ALeffectState *state);
+
+ ALboolean (*const deviceUpdate)(ALeffectState *state, ALCdevice *device);
+ void (*const update)(ALeffectState *state, ALCdevice *device, const struct ALeffectslot *slot);
+ void (*const process)(ALeffectState *state, ALuint samplesToDo, const ALfloat *restrict samplesIn, ALfloat (*restrict samplesOut)[BUFFERSIZE]);
+
+ void (*const Delete)(struct ALeffectState *state);
+};
+
+#define DEFINE_ALEFFECTSTATE_VTABLE(T) \
+DECLARE_THUNK(T, ALeffectState, void, Destruct) \
+DECLARE_THUNK1(T, ALeffectState, ALboolean, deviceUpdate, ALCdevice*) \
+DECLARE_THUNK2(T, ALeffectState, void, update, ALCdevice*, const ALeffectslot*) \
+DECLARE_THUNK3(T, ALeffectState, void, process, ALuint, const ALfloat*restrict, ALfloatBUFFERSIZE*restrict) \
+DECLARE_THUNK(T, ALeffectState, void, Delete) \
+ \
+static const struct ALeffectStateVtable T##_ALeffectState_vtable = { \
+ T##_ALeffectState_Destruct, \
+ \
+ T##_ALeffectState_deviceUpdate, \
+ T##_ALeffectState_update, \
+ T##_ALeffectState_process, \
+ \
+ T##_ALeffectState_Delete, \
+}
+
+
+struct ALeffectStateFactoryVtable;
+
+typedef struct ALeffectStateFactory {
+ const struct ALeffectStateFactoryVtable *vtbl;
+} ALeffectStateFactory;
+
+struct ALeffectStateFactoryVtable {
+ ALeffectState *(*const create)(ALeffectStateFactory *factory);
+};
-typedef struct ALeffectslot
-{
- ALeffect effect;
+#define DEFINE_ALEFFECTSTATEFACTORY_VTABLE(T) \
+DECLARE_THUNK(T, ALeffectStateFactory, ALeffectState*, create) \
+ \
+static const struct ALeffectStateFactoryVtable T##_ALeffectStateFactory_vtable = { \
+ T##_ALeffectStateFactory_create, \
+}
+
+
+typedef struct ALeffectslot {
+ ALenum EffectType;
+ ALeffectProps EffectProps;
volatile ALfloat Gain;
volatile ALboolean AuxSendAuto;
@@ -37,23 +82,34 @@ typedef struct ALeffectslot
ALuint id;
} ALeffectslot;
+inline struct ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id)
+{ return (struct ALeffectslot*)LookupUIntMapKey(&context->EffectSlotMap, id); }
+inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id)
+{ return (struct ALeffectslot*)RemoveUIntMapKey(&context->EffectSlotMap, id); }
ALenum InitEffectSlot(ALeffectslot *slot);
ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context);
-ALeffectState *NoneCreate(void);
-ALeffectState *ReverbCreate(void);
-ALeffectState *EchoCreate(void);
-ALeffectState *ModulatorCreate(void);
-ALeffectState *DedicatedCreate(void);
-#define ALeffectState_Destroy(a) ((a)->Destroy((a)))
-#define ALeffectState_DeviceUpdate(a,b) ((a)->DeviceUpdate((a),(b)))
-#define ALeffectState_Update(a,b,c) ((a)->Update((a),(b),(c)))
-#define ALeffectState_Process(a,b,c,d) ((a)->Process((a),(b),(c),(d)))
+ALeffectStateFactory *ALnullStateFactory_getFactory(void);
+ALeffectStateFactory *ALreverbStateFactory_getFactory(void);
+ALeffectStateFactory *ALautowahStateFactory_getFactory(void);
+ALeffectStateFactory *ALchorusStateFactory_getFactory(void);
+ALeffectStateFactory *ALcompressorStateFactory_getFactory(void);
+ALeffectStateFactory *ALdistortionStateFactory_getFactory(void);
+ALeffectStateFactory *ALechoStateFactory_getFactory(void);
+ALeffectStateFactory *ALequalizerStateFactory_getFactory(void);
+ALeffectStateFactory *ALflangerStateFactory_getFactory(void);
+ALeffectStateFactory *ALmodulatorStateFactory_getFactory(void);
+
+ALeffectStateFactory *ALdedicatedStateFactory_getFactory(void);
+
ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect);
+void InitEffectFactoryMap(void);
+void DeinitEffectFactoryMap(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/OpenAL32/Include/alBuffer.h b/OpenAL32/Include/alBuffer.h
index 8ecc4dd8..d22b3b9b 100644
--- a/OpenAL32/Include/alBuffer.h
+++ b/OpenAL32/Include/alBuffer.h
@@ -35,8 +35,7 @@ enum UserFmtChannels {
ALuint BytesFromUserFmt(enum UserFmtType type);
ALuint ChannelsFromUserFmt(enum UserFmtChannels chans);
-static __inline ALuint FrameSizeFromUserFmt(enum UserFmtChannels chans,
- enum UserFmtType type)
+inline ALuint FrameSizeFromUserFmt(enum UserFmtChannels chans, enum UserFmtType type)
{
return ChannelsFromUserFmt(chans) * BytesFromUserFmt(type);
}
@@ -57,17 +56,17 @@ enum FmtChannels {
FmtX61 = UserFmtX61,
FmtX71 = UserFmtX71,
};
+#define MAX_INPUT_CHANNELS (8)
ALuint BytesFromFmt(enum FmtType type);
ALuint ChannelsFromFmt(enum FmtChannels chans);
-static __inline ALuint FrameSizeFromFmt(enum FmtChannels chans, enum FmtType type)
+inline ALuint FrameSizeFromFmt(enum FmtChannels chans, enum FmtType type)
{
return ChannelsFromFmt(chans) * BytesFromFmt(type);
}
-typedef struct ALbuffer
-{
+typedef struct ALbuffer {
ALvoid *data;
ALsizei Frequency;
@@ -93,6 +92,11 @@ typedef struct ALbuffer
ALuint id;
} ALbuffer;
+inline struct ALbuffer *LookupBuffer(ALCdevice *device, ALuint id)
+{ return (struct ALbuffer*)LookupUIntMapKey(&device->BufferMap, id); }
+inline struct ALbuffer *RemoveBuffer(ALCdevice *device, ALuint id)
+{ return (struct ALbuffer*)RemoveUIntMapKey(&device->BufferMap, id); }
+
ALvoid ReleaseALBuffers(ALCdevice *device);
#ifdef __cplusplus
diff --git a/OpenAL32/Include/alEffect.h b/OpenAL32/Include/alEffect.h
index ba894c8b..f656c56a 100644
--- a/OpenAL32/Include/alEffect.h
+++ b/OpenAL32/Include/alEffect.h
@@ -7,10 +7,18 @@
extern "C" {
#endif
+struct ALeffect;
+
enum {
EAXREVERB = 0,
REVERB,
+ AUTOWAH,
+ CHORUS,
+ COMPRESSOR,
+ DISTORTION,
ECHO,
+ EQUALIZER,
+ FLANGER,
MODULATOR,
DEDICATED,
@@ -21,11 +29,41 @@ extern ALboolean DisabledEffects[MAX_EFFECTS];
extern ALfloat ReverbBoost;
extern ALboolean EmulateEAXReverb;
-typedef struct ALeffect
-{
- // Effect type (AL_EFFECT_NULL, ...)
- ALenum type;
+struct ALeffectVtable {
+ void (*const setParami)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALint val);
+ void (*const setParamiv)(struct ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals);
+ void (*const setParamf)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val);
+ void (*const setParamfv)(struct ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals);
+
+ void (*const getParami)(const struct ALeffect *effect, ALCcontext *context, ALenum param, ALint *val);
+ void (*const getParamiv)(const struct ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals);
+ void (*const getParamf)(const struct ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val);
+ void (*const getParamfv)(const struct ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals);
+};
+
+#define DEFINE_ALEFFECT_VTABLE(T) \
+const struct ALeffectVtable T##_vtable = { \
+ T##_setParami, T##_setParamiv, \
+ T##_setParamf, T##_setParamfv, \
+ T##_getParami, T##_getParamiv, \
+ T##_getParamf, T##_getParamfv, \
+}
+extern const struct ALeffectVtable ALeaxreverb_vtable;
+extern const struct ALeffectVtable ALreverb_vtable;
+extern const struct ALeffectVtable ALautowah_vtable;
+extern const struct ALeffectVtable ALchorus_vtable;
+extern const struct ALeffectVtable ALcompressor_vtable;
+extern const struct ALeffectVtable ALdistortion_vtable;
+extern const struct ALeffectVtable ALecho_vtable;
+extern const struct ALeffectVtable ALequalizer_vtable;
+extern const struct ALeffectVtable ALflanger_vtable;
+extern const struct ALeffectVtable ALmodulator_vtable;
+extern const struct ALeffectVtable ALnull_vtable;
+extern const struct ALeffectVtable ALdedicated_vtable;
+
+
+typedef union ALeffectProps {
struct {
// Shared Reverb Properties
ALfloat Density;
@@ -56,6 +94,34 @@ typedef struct ALeffect
} Reverb;
struct {
+ ALfloat AttackTime;
+ ALfloat ReleaseTime;
+ ALfloat PeakGain;
+ ALfloat Resonance;
+ } Autowah;
+
+ struct {
+ ALint Waveform;
+ ALint Phase;
+ ALfloat Rate;
+ ALfloat Depth;
+ ALfloat Feedback;
+ ALfloat Delay;
+ } Chorus;
+
+ struct {
+ ALboolean OnOff;
+ } Compressor;
+
+ struct {
+ ALfloat Edge;
+ ALfloat Gain;
+ ALfloat LowpassCutoff;
+ ALfloat EQCenter;
+ ALfloat EQBandwidth;
+ } Distortion;
+
+ struct {
ALfloat Delay;
ALfloat LRDelay;
@@ -66,6 +132,29 @@ typedef struct ALeffect
} Echo;
struct {
+ ALfloat Delay;
+ ALfloat LowCutoff;
+ ALfloat LowGain;
+ ALfloat Mid1Center;
+ ALfloat Mid1Gain;
+ ALfloat Mid1Width;
+ ALfloat Mid2Center;
+ ALfloat Mid2Gain;
+ ALfloat Mid2Width;
+ ALfloat HighCutoff;
+ ALfloat HighGain;
+ } Equalizer;
+
+ struct {
+ ALint Waveform;
+ ALint Phase;
+ ALfloat Rate;
+ ALfloat Depth;
+ ALfloat Feedback;
+ ALfloat Delay;
+ } Flanger;
+
+ struct {
ALfloat Frequency;
ALfloat HighPassCutoff;
ALint Waveform;
@@ -74,32 +163,26 @@ typedef struct ALeffect
struct {
ALfloat Gain;
} Dedicated;
+} ALeffectProps;
- void (*SetParami)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALint val);
- void (*SetParamiv)(struct ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals);
- void (*SetParamf)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val);
- void (*SetParamfv)(struct ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals);
+typedef struct ALeffect {
+ // Effect type (AL_EFFECT_NULL, ...)
+ ALenum type;
+
+ ALeffectProps Props;
- void (*GetParami)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALint *val);
- void (*GetParamiv)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals);
- void (*GetParamf)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val);
- void (*GetParamfv)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals);
+ const struct ALeffectVtable *vtbl;
/* Self ID */
ALuint id;
} ALeffect;
-#define ALeffect_SetParami(x, c, p, v) ((x)->SetParami((x),(c),(p),(v)))
-#define ALeffect_SetParamiv(x, c, p, v) ((x)->SetParamiv((x),(c),(p),(v)))
-#define ALeffect_SetParamf(x, c, p, v) ((x)->SetParamf((x),(c),(p),(v)))
-#define ALeffect_SetParamfv(x, c, p, v) ((x)->SetParamfv((x),(c),(p),(v)))
-
-#define ALeffect_GetParami(x, c, p, v) ((x)->GetParami((x),(c),(p),(v)))
-#define ALeffect_GetParamiv(x, c, p, v) ((x)->GetParamiv((x),(c),(p),(v)))
-#define ALeffect_GetParamf(x, c, p, v) ((x)->GetParamf((x),(c),(p),(v)))
-#define ALeffect_GetParamfv(x, c, p, v) ((x)->GetParamfv((x),(c),(p),(v)))
+inline struct ALeffect *LookupEffect(ALCdevice *device, ALuint id)
+{ return (struct ALeffect*)LookupUIntMapKey(&device->EffectMap, id); }
+inline struct ALeffect *RemoveEffect(ALCdevice *device, ALuint id)
+{ return (struct ALeffect*)RemoveUIntMapKey(&device->EffectMap, id); }
-static __inline ALboolean IsReverbEffect(ALenum type)
+inline ALboolean IsReverbEffect(ALenum type)
{ return type == AL_EFFECT_REVERB || type == AL_EFFECT_EAXREVERB; }
ALenum InitEffect(ALeffect *effect);
diff --git a/OpenAL32/Include/alError.h b/OpenAL32/Include/alError.h
index 0ade342d..ab91d27b 100644
--- a/OpenAL32/Include/alError.h
+++ b/OpenAL32/Include/alError.h
@@ -11,6 +11,21 @@ extern ALboolean TrapALError;
ALvoid alSetError(ALCcontext *Context, ALenum errorCode);
+#define SET_ERROR_AND_RETURN(ctx, err) do { \
+ alSetError((ctx), (err)); \
+ return; \
+} while(0)
+
+#define SET_ERROR_AND_RETURN_VALUE(ctx, err, val) do { \
+ alSetError((ctx), (err)); \
+ return (val); \
+} while(0)
+
+#define SET_ERROR_AND_GOTO(ctx, err, lbl) do { \
+ alSetError((ctx), (err)); \
+ goto lbl; \
+} while(0)
+
#ifdef __cplusplus
}
#endif
diff --git a/OpenAL32/Include/alFilter.h b/OpenAL32/Include/alFilter.h
index 09cef93c..5167c125 100644
--- a/OpenAL32/Include/alFilter.h
+++ b/OpenAL32/Include/alFilter.h
@@ -9,45 +9,56 @@ extern "C" {
#define LOWPASSFREQREF (5000)
-typedef struct {
- ALfloat coeff;
-#ifndef _MSC_VER
- ALfloat history[0];
-#else
- ALfloat history[1];
-#endif
-} FILTER;
-static __inline ALfloat lpFilter2P(FILTER *iir, ALuint offset, ALfloat input)
-{
- ALfloat *history = &iir->history[offset*2];
- ALfloat a = iir->coeff;
- ALfloat output = input;
+/* Filters implementation is based on the "Cookbook formulae for audio *
+ * EQ biquad filter coefficients" by Robert Bristow-Johnson *
+ * http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt */
- output = output + (history[0]-output)*a;
- history[0] = output;
- output = output + (history[1]-output)*a;
- history[1] = output;
+typedef enum ALfilterType {
+ ALfilterType_HighShelf,
+ ALfilterType_LowShelf,
+ ALfilterType_Peaking,
- return output;
-}
+ ALfilterType_LowPass,
+ ALfilterType_HighPass,
+ ALfilterType_BandPass,
+} ALfilterType;
-static __inline ALfloat lpFilter2PC(const FILTER *iir, ALuint offset, ALfloat input)
-{
- const ALfloat *history = &iir->history[offset*2];
- ALfloat a = iir->coeff;
- ALfloat output = input;
+typedef struct ALfilterState {
+ ALfloat x[2]; /* History of two last input samples */
+ ALfloat y[2]; /* History of two last output samples */
+ ALfloat a[3]; /* Transfer function coefficients "a" */
+ ALfloat b[3]; /* Transfer function coefficients "b" */
+} ALfilterState;
- output = output + (history[0]-output)*a;
- output = output + (history[1]-output)*a;
+void ALfilterState_clear(ALfilterState *filter);
+void ALfilterState_setParams(ALfilterState *filter, ALfilterType type, ALfloat gain, ALfloat freq_scale, ALfloat bandwidth);
- return output;
+inline ALfloat ALfilterState_processSingle(ALfilterState *filter, ALfloat sample)
+{
+ ALfloat outsmp;
+
+ outsmp = filter->b[0] * sample +
+ filter->b[1] * filter->x[0] +
+ filter->b[2] * filter->x[1] -
+ filter->a[1] * filter->y[0] -
+ filter->a[2] * filter->y[1];
+ filter->x[1] = filter->x[0];
+ filter->x[0] = sample;
+ filter->y[1] = filter->y[0];
+ filter->y[0] = outsmp;
+
+ return outsmp;
}
-/* Calculates the low-pass filter coefficient given the pre-scaled gain and
- * cos(w) value. Note that g should be pre-scaled (sqr(gain) for one-pole,
- * sqrt(gain) for four-pole, etc) */
-ALfloat lpCoeffCalc(ALfloat g, ALfloat cw);
+inline ALfloat ALfilterState_processSingleC(const ALfilterState *filter, ALfloat sample)
+{
+ return filter->b[0] * sample +
+ filter->b[1] * filter->x[0] +
+ filter->b[2] * filter->x[1] -
+ filter->a[1] * filter->y[0] -
+ filter->a[2] * filter->y[1];
+}
typedef struct ALfilter {
@@ -81,6 +92,11 @@ typedef struct ALfilter {
#define ALfilter_GetParamf(x, c, p, v) ((x)->GetParamf((x),(c),(p),(v)))
#define ALfilter_GetParamfv(x, c, p, v) ((x)->GetParamfv((x),(c),(p),(v)))
+inline struct ALfilter *LookupFilter(ALCdevice *device, ALuint id)
+{ return (struct ALfilter*)LookupUIntMapKey(&device->FilterMap, id); }
+inline struct ALfilter *RemoveFilter(ALCdevice *device, ALuint id)
+{ return (struct ALfilter*)RemoveUIntMapKey(&device->FilterMap, id); }
+
ALvoid ReleaseALFilters(ALCdevice *device);
#ifdef __cplusplus
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 1110e89e..b6a9f0ae 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -7,6 +7,10 @@
#include <assert.h>
#include <math.h>
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
#ifdef HAVE_FENV_H
#include <fenv.h>
#endif
@@ -15,37 +19,259 @@
#include "AL/alc.h"
#include "AL/alext.h"
-#ifndef AL_SOFT_deferred_updates
-#define AL_SOFT_deferred_updates 1
-#define AL_DEFERRED_UPDATES_SOFT 0xC002
-typedef ALvoid (AL_APIENTRY*LPALDEFERUPDATESSOFT)(void);
-typedef ALvoid (AL_APIENTRY*LPALPROCESSUPDATESSOFT)(void);
+#include "atomic.h"
+#include "uintmap.h"
+
+#ifndef ALC_SOFT_HRTF
+#define ALC_SOFT_HRTF 1
+#define ALC_HRTF_SOFT 0x1992
+#endif
+
+#ifndef ALC_SOFT_midi_interface
+#define ALC_SOFT_midi_interface 1
+#define AL_MIDI_CLOCK_SOFT 0x9999
+#define AL_MIDI_STATE_SOFT 0x9986
+#define AL_MIDI_GAIN_SOFT 0x9998
+#define AL_MIDI_PRESET_SOFT 0x9997
+#define AL_MIDI_BANK_SOFT 0x9996
+#define AL_SOUNDFONTS_SIZE_SOFT 0x9995
+#define AL_SOUNDFONTS_SOFT 0x9994
+#define AL_PRESETS_SIZE_SOFT 0x9993
+#define AL_PRESETS_SOFT 0x9992
+#define AL_FONTSOUNDS_SIZE_SOFT 0x9991
+#define AL_FONTSOUNDS_SOFT 0x9990
+
+#define AL_SOURCE0_INPUT_SOFT 0x998F
+#define AL_SOURCE0_TYPE_SOFT 0x998E
+#define AL_SOURCE0_FORM_SOFT 0x998D
+#define AL_SOURCE1_INPUT_SOFT 0x998C
+#define AL_SOURCE1_TYPE_SOFT 0x998B
+#define AL_SOURCE1_FORM_SOFT 0x998A
+#define AL_AMOUNT_SOFT 0x9989
+#define AL_TRANSFORM_OP_SOFT 0x9988
+#define AL_DESTINATION_SOFT 0x9987
+
+/* Sounce Input */
+#define AL_ONE_SOFT 0x0080
+#define AL_NOTEON_VELOCITY_SOFT 0x0082
+#define AL_NOTEON_KEY_SOFT 0x0083
+/* AL_KEYPRESSURE_SOFT */
+/* AL_CHANNELPRESSURE_SOFT */
+/* AL_PITCHBEND_SOFT */
+#define AL_PITCHBEND_SENSITIVITY_SOFT 0x0090
+/* CC 0...127 */
+
+/* Source Type */
+#define AL_UNORM_SOFT 0x0000
+#define AL_UNORM_REV_SOFT 0x0100
+#define AL_SNORM_SOFT 0x0200
+#define AL_SNORM_REV_SOFT 0x0300
+
+/* Source Form */
+#define AL_LINEAR_SOFT 0x0000
+#define AL_CONCAVE_SOFT 0x0400
+#define AL_CONVEX_SOFT 0x0800
+#define AL_SWITCH_SOFT 0x0C00
+
+/* Transform op */
+/* AL_LINEAR_SOFT */
+#define AL_ABSOLUTE_SOFT 0x0002
+
+#define AL_SAMPLE_START_SOFT 0x2000
+#define AL_SAMPLE_END_SOFT 0x2001
+#define AL_SAMPLE_LOOP_START_SOFT 0x2002
+#define AL_SAMPLE_LOOP_END_SOFT 0x2003
+#define AL_SAMPLE_RATE_SOFT 0x2004
+#define AL_BASE_KEY_SOFT 0x2005
+#define AL_KEY_CORRECTION_SOFT 0x2006
+#define AL_SAMPLE_TYPE_SOFT 0x2007
+#define AL_FONTSOUND_LINK_SOFT 0x2008
+#define AL_MOD_LFO_TO_PITCH_SOFT 0x0005
+#define AL_VIBRATO_LFO_TO_PITCH_SOFT 0x0006
+#define AL_MOD_ENV_TO_PITCH_SOFT 0x0007
+#define AL_FILTER_CUTOFF_SOFT 0x0008
+#define AL_FILTER_RESONANCE_SOFT 0x0009
+#define AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT 0x000A
+#define AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT 0x000B
+#define AL_MOD_LFO_TO_VOLUME_SOFT 0x000D
+#define AL_CHORUS_SEND_SOFT 0x000F
+#define AL_REVERB_SEND_SOFT 0x0010
+#define AL_PAN_SOFT 0x0011
+#define AL_MOD_LFO_DELAY_SOFT 0x0015
+#define AL_MOD_LFO_FREQUENCY_SOFT 0x0016
+#define AL_VIBRATO_LFO_DELAY_SOFT 0x0017
+#define AL_VIBRATO_LFO_FREQUENCY_SOFT 0x0018
+#define AL_MOD_ENV_DELAYTIME_SOFT 0x0019
+#define AL_MOD_ENV_ATTACKTIME_SOFT 0x001A
+#define AL_MOD_ENV_HOLDTIME_SOFT 0x001B
+#define AL_MOD_ENV_DECAYTIME_SOFT 0x001C
+#define AL_MOD_ENV_SUSTAINVOLUME_SOFT 0x001D
+#define AL_MOD_ENV_RELEASETIME_SOFT 0x002E
+#define AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT 0x001F
+#define AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT 0x0020
+#define AL_VOLUME_ENV_DELAYTIME_SOFT 0x0021
+#define AL_VOLUME_ENV_ATTACKTIME_SOFT 0x0022
+#define AL_VOLUME_ENV_HOLDTIME_SOFT 0x0023
+#define AL_VOLUME_ENV_DECAYTIME_SOFT 0x0024
+#define AL_VOLUME_ENV_SUSTAINVOLUME_SOFT 0x0025
+#define AL_VOLUME_ENV_RELEASETIME_SOFT 0x0026
+#define AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT 0x0027
+#define AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT 0x0028
+#define AL_KEY_RANGE_SOFT 0x002B
+#define AL_VELOCITY_RANGE_SOFT 0x002C
+#define AL_ATTENUATION_SOFT 0x0030
+#define AL_TUNING_COARSE_SOFT 0x0033
+#define AL_TUNING_FINE_SOFT 0x0034
+#define AL_LOOP_MODE_SOFT 0x0036
+#define AL_TUNING_SCALE_SOFT 0x0038
+#define AL_EXCLUSIVE_CLASS_SOFT 0x0039
+#define AL_LOOP_CONTINUOUS_SOFT 0x0001
+#define AL_LOOP_UNTIL_RELEASE_SOFT 0x0003
+#define AL_RIGHT_SOFT 0x0002
+#define AL_LEFT_SOFT 0x0004
+#define AL_FORMAT_TYPE_SOFT 0x1991
+#define AL_NOTEOFF_SOFT 0x0080
+#define AL_NOTEON_SOFT 0x0090
+#define AL_KEYPRESSURE_SOFT 0x00A0
+#define AL_CONTROLLERCHANGE_SOFT 0x00B0
+#define AL_PROGRAMCHANGE_SOFT 0x00C0
+#define AL_CHANNELPRESSURE_SOFT 0x00D0
+#define AL_PITCHBEND_SOFT 0x00E0
+typedef void (AL_APIENTRY*LPALGENSOUNDFONTSSOFT)(ALsizei n, ALuint *ids);
+typedef void (AL_APIENTRY*LPALDELETESOUNDFONTSSOFT)(ALsizei n, const ALuint *ids);
+typedef ALboolean (AL_APIENTRY*LPALISSOUNDFONTSOFT)(ALuint id);
+typedef void (AL_APIENTRY*LPALSOUNDFONTSAMPLESSOFT)(ALuint sfid, ALenum type, ALsizei count, const ALvoid *samples);
+typedef void (AL_APIENTRY*LPALGETSOUNDFONTSAMPLESSOFT)(ALuint id, ALsizei offset, ALsizei count, ALenum type, ALvoid *samples);
+typedef ALvoid* (AL_APIENTRY*LPALSOUNDFONTMAPSAMPLESSOFT)(ALuint sfid, ALsizei offset, ALsizei length);
+typedef void (AL_APIENTRY*LPALSOUNDFONTUNMAPSAMPLESSOFT)(ALuint sfid);
+typedef void (AL_APIENTRY*LPALGETSOUNDFONTIVSOFT)(ALuint id, ALenum param, ALint *values);
+typedef void (AL_APIENTRY*LPALSOUNDFONTPRESETSSOFT)(ALuint id, ALsizei count, const ALuint *pids);
+typedef void (AL_APIENTRY*LPALGENPRESETSSOFT)(ALsizei n, ALuint *ids);
+typedef void (AL_APIENTRY*LPALDELETEPRESETSSOFT)(ALsizei n, const ALuint *ids);
+typedef ALboolean (AL_APIENTRY*LPALISPRESETSOFT)(ALuint id);
+typedef void (AL_APIENTRY*LPALPRESETISOFT)(ALuint id, ALenum param, ALint value);
+typedef void (AL_APIENTRY*LPALPRESETIVSOFT)(ALuint id, ALenum param, const ALint *values);
+typedef void (AL_APIENTRY*LPALPRESETFONTSOUNDSSOFT)(ALuint id, ALsizei count, const ALuint *fsids);
+typedef void (AL_APIENTRY*LPALGETPRESETIVSOFT)(ALuint id, ALenum param, ALint *values);
+typedef void (AL_APIENTRY*LPALGENFONTSOUNDSSOFT)(ALsizei n, ALuint *ids);
+typedef void (AL_APIENTRY*LPALDELETEFONTSOUNDSSOFT)(ALsizei n, const ALuint *ids);
+typedef ALboolean (AL_APIENTRY*LPALISFONTSOUNDSOFT)(ALuint id);
+typedef void (AL_APIENTRY*LPALFONTSOUNDISOFT)(ALuint id, ALenum param, ALint value);
+typedef void (AL_APIENTRY*LPALFONTSOUND2ISOFT)(ALuint id, ALenum param, ALint value1, ALint value2);
+typedef void (AL_APIENTRY*LPALFONTSOUNDIVSOFT)(ALuint id, ALenum param, const ALint *values);
+typedef void (AL_APIENTRY*LPALGETFONTSOUNDIVSOFT)(ALuint id, ALenum param, ALint *values);
+typedef void (AL_APIENTRY*LPALFONTSOUNDMOFULATORISOFT)(ALuint id, ALsizei stage, ALenum param, ALint value);
+typedef void (AL_APIENTRY*LPALGETFONTSOUNDMODULATORIVSOFT)(ALuint id, ALsizei stage, ALenum param, ALint *values);
+typedef void (AL_APIENTRY*LPALMIDISOUNDFONTSOFT)(ALuint id);
+typedef void (AL_APIENTRY*LPALMIDISOUNDFONTVSOFT)(ALsizei count, const ALuint *ids);
+typedef void (AL_APIENTRY*LPALMIDIEVENTSOFT)(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2);
+typedef void (AL_APIENTRY*LPALMIDISYSEXSOFT)(ALuint64SOFT time, const ALbyte *data, ALsizei size);
+typedef void (AL_APIENTRY*LPALMIDIPLAYSOFT)(void);
+typedef void (AL_APIENTRY*LPALMIDIPAUSESOFT)(void);
+typedef void (AL_APIENTRY*LPALMIDISTOPSOFT)(void);
+typedef void (AL_APIENTRY*LPALMIDIRESETSOFT)(void);
+typedef void (AL_APIENTRY*LPALMIDIGAINSOFT)(ALfloat value);
+typedef ALint64SOFT (AL_APIENTRY*LPALGETINTEGER64SOFT)(ALenum pname);
+typedef void (AL_APIENTRY*LPALGETINTEGER64VSOFT)(ALenum pname, ALint64SOFT *values);
+typedef void (AL_APIENTRY*LPALLOADSOUNDFONTSOFT)(ALuint id, size_t(*cb)(ALvoid*,size_t,ALvoid*), ALvoid *user);
#ifdef AL_ALEXT_PROTOTYPES
-AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void);
-AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void);
+AL_API void AL_APIENTRY alGenSoundfontsSOFT(ALsizei n, ALuint *ids);
+AL_API void AL_APIENTRY alDeleteSoundfontsSOFT(ALsizei n, const ALuint *ids);
+AL_API ALboolean AL_APIENTRY alIsSoundfontSOFT(ALuint id);
+AL_API void AL_APIENTRY alSoundfontSamplesSOFT(ALuint sfid, ALenum type, ALsizei count, const ALvoid *samples);
+AL_API void AL_APIENTRY alGetSoundfontSamplesSOFT(ALuint id, ALsizei offset, ALsizei count, ALenum type, ALvoid *samples);
+AL_API ALvoid* AL_APIENTRY alSoundfontMapSamplesSOFT(ALuint sfid, ALsizei offset, ALsizei length);
+AL_API void AL_APIENTRY alSoundfontUnmapSamplesSOFT(ALuint sfid);
+AL_API void AL_APIENTRY alGetSoundfontivSOFT(ALuint id, ALenum param, ALint *values);
+AL_API void AL_APIENTRY alSoundfontPresetsSOFT(ALuint id, ALsizei count, const ALuint *pids);
+
+AL_API void AL_APIENTRY alGenPresetsSOFT(ALsizei n, ALuint *ids);
+AL_API void AL_APIENTRY alDeletePresetsSOFT(ALsizei n, const ALuint *ids);
+AL_API ALboolean AL_APIENTRY alIsPresetSOFT(ALuint id);
+AL_API void AL_APIENTRY alPresetiSOFT(ALuint id, ALenum param, ALint value);
+AL_API void AL_APIENTRY alPresetivSOFT(ALuint id, ALenum param, const ALint *values);
+AL_API void AL_APIENTRY alGetPresetivSOFT(ALuint id, ALenum param, ALint *values);
+AL_API void AL_APIENTRY alPresetFontsoundsSOFT(ALuint id, ALsizei count, const ALuint *fsids);
+
+AL_API void AL_APIENTRY alGenFontsoundsSOFT(ALsizei n, ALuint *ids);
+AL_API void AL_APIENTRY alDeleteFontsoundsSOFT(ALsizei n, const ALuint *ids);
+AL_API ALboolean AL_APIENTRY alIsFontsoundSOFT(ALuint id);
+AL_API void AL_APIENTRY alFontsoundiSOFT(ALuint id, ALenum param, ALint value);
+AL_API void AL_APIENTRY alFontsound2iSOFT(ALuint id, ALenum param, ALint value1, ALint value2);
+AL_API void AL_APIENTRY alFontsoundivSOFT(ALuint id, ALenum param, const ALint *values);
+AL_API void AL_APIENTRY alGetFontsoundivSOFT(ALuint id, ALenum param, ALint *values);
+AL_API void AL_APIENTRY alFontsoundModulatoriSOFT(ALuint id, ALsizei stage, ALenum param, ALint value);
+AL_API void AL_APIENTRY alGetFontsoundModulatorivSOFT(ALuint id, ALsizei stage, ALenum param, ALint *values);
+
+AL_API void AL_APIENTRY alMidiSoundfontSOFT(ALuint id);
+AL_API void AL_APIENTRY alMidiSoundfontvSOFT(ALsizei count, const ALuint *ids);
+AL_API void AL_APIENTRY alMidiEventSOFT(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2);
+AL_API void AL_APIENTRY alMidiSysExSOFT(ALuint64SOFT time, const ALbyte *data, ALsizei size);
+AL_API void AL_APIENTRY alMidiPlaySOFT(void);
+AL_API void AL_APIENTRY alMidiPauseSOFT(void);
+AL_API void AL_APIENTRY alMidiStopSOFT(void);
+AL_API void AL_APIENTRY alMidiResetSOFT(void);
+AL_API void AL_APIENTRY alMidiGainSOFT(ALfloat value);
+AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname);
+AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values);
+AL_API void AL_APIENTRY alLoadSoundfontSOFT(ALuint id, size_t(*cb)(ALvoid*,size_t,ALvoid*), ALvoid *user);
#endif
#endif
+#ifndef ALC_SOFT_pause_device
+#define ALC_SOFT_pause_device 1
+typedef void (ALC_APIENTRY*LPALCDEVICEPAUSESOFT)(ALCdevice *device);
+typedef void (ALC_APIENTRY*LPALCDEVICERESUMESOFT)(ALCdevice *device);
+#ifdef AL_ALEXT_PROTOTYPES
+ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device);
+ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device);
+#endif
+#endif
-#if defined(HAVE_STDINT_H)
-#include <stdint.h>
-typedef int64_t ALint64;
-typedef uint64_t ALuint64;
-#elif defined(HAVE___INT64)
-typedef __int64 ALint64;
-typedef unsigned __int64 ALuint64;
-#elif (SIZEOF_LONG == 8)
-typedef long ALint64;
-typedef unsigned long ALuint64;
-#elif (SIZEOF_LONG_LONG == 8)
-typedef long long ALint64;
-typedef unsigned long long ALuint64;
+
+#ifdef IN_IDE_PARSER
+/* KDevelop's parser doesn't recognize the C99-standard restrict keyword, but
+ * recent versions (at least 4.5.1) do recognize GCC's __restrict. */
+#define restrict __restrict
+/* KDevelop won't see the ALIGN macro from config.h when viewing files that
+ * don't include it directly (e.g. headers). */
+#ifndef ALIGN
+#define ALIGN(x)
+#endif
#endif
+
+typedef ALint64SOFT ALint64;
+typedef ALuint64SOFT ALuint64;
+
typedef ptrdiff_t ALintptrEXT;
typedef ptrdiff_t ALsizeiptrEXT;
-#define MAKEU64(x,y) (((ALuint64)(x)<<32)|(ALuint64)(y))
+#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
+
+#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
#ifdef HAVE_GCC_FORMAT
#define PRINTF_STYLE(x, y) __attribute__((format(printf, (x), (y))))
@@ -53,6 +279,16 @@ typedef ptrdiff_t ALsizeiptrEXT;
#define PRINTF_STYLE(x, y)
#endif
+#if defined(__GNUC__) && defined(__i386__)
+/* force_align_arg_pointer is required for proper function arguments aligning
+ * when SSE code is used. Some systems (Windows, QNX) do not guarantee our
+ * thread functions will be properly aligned on the stack, even though GCC may
+ * generate code with the assumption that it is. */
+#define FORCE_ALIGN __attribute__((force_align_arg_pointer))
+#else
+#define FORCE_ALIGN
+#endif
+
static const union {
ALuint u;
@@ -62,274 +298,67 @@ static const union {
#define COUNTOF(x) (sizeof((x))/sizeof((x)[0]))
-#ifdef _WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-typedef DWORD pthread_key_t;
-int pthread_key_create(pthread_key_t *key, void (*callback)(void*));
-int pthread_key_delete(pthread_key_t key);
-void *pthread_getspecific(pthread_key_t key);
-int pthread_setspecific(pthread_key_t key, void *val);
-
-#define HAVE_DYNLOAD 1
-void *LoadLib(const char *name);
-void CloseLib(void *handle);
-void *GetSymbol(void *handle, const char *name);
-
-WCHAR *strdupW(const WCHAR *str);
-
-typedef LONG pthread_once_t;
-#define PTHREAD_ONCE_INIT 0
-void pthread_once(pthread_once_t *once, void (*callback)(void));
-
-static __inline int sched_yield(void)
-{ SwitchToThread(); return 0; }
-
-#else
+#define DERIVE_FROM_TYPE(t) t t##_parent
+#define STATIC_CAST(to, obj) (&(obj)->to##_parent)
+#define STATIC_UPCAST(to, from, obj) ((to*)((char*)(obj) - offsetof(to, from##_parent)))
-#include <unistd.h>
-#include <assert.h>
-#include <pthread.h>
-#include <sys/time.h>
-#include <time.h>
-#include <errno.h>
-
-#define IsBadWritePtr(a,b) ((a) == NULL && (b) != 0)
-
-typedef pthread_mutex_t CRITICAL_SECTION;
-void InitializeCriticalSection(CRITICAL_SECTION *cs);
-void DeleteCriticalSection(CRITICAL_SECTION *cs);
-void EnterCriticalSection(CRITICAL_SECTION *cs);
-void LeaveCriticalSection(CRITICAL_SECTION *cs);
-
-ALuint timeGetTime(void);
-void Sleep(ALuint t);
-
-#if defined(HAVE_DLFCN_H)
-#define HAVE_DYNLOAD 1
-void *LoadLib(const char *name);
-void CloseLib(void *handle);
-void *GetSymbol(void *handle, const char *name);
-#endif
-#endif
+#define DECLARE_FORWARD(T1, T2, rettype, func) \
+rettype T1##_##func(T1 *obj) \
+{ return T2##_##func(STATIC_CAST(T2, obj)); }
-typedef void *volatile XchgPtr;
+#define DECLARE_FORWARD1(T1, T2, rettype, func, argtype1) \
+rettype T1##_##func(T1 *obj, argtype1 a) \
+{ return T2##_##func(STATIC_CAST(T2, obj), a); }
-#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
-typedef ALuint RefCount;
-static __inline RefCount IncrementRef(volatile RefCount *ptr)
-{ return __sync_add_and_fetch(ptr, 1); }
-static __inline RefCount DecrementRef(volatile RefCount *ptr)
-{ return __sync_sub_and_fetch(ptr, 1); }
+#define DECLARE_FORWARD2(T1, T2, rettype, func, argtype1, argtype2) \
+rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b) \
+{ return T2##_##func(STATIC_CAST(T2, obj), a, b); }
-static __inline int ExchangeInt(volatile int *ptr, int newval)
-{
- return __sync_lock_test_and_set(ptr, newval);
-}
-static __inline void *ExchangePtr(XchgPtr *ptr, void *newval)
-{
- return __sync_lock_test_and_set(ptr, newval);
-}
-static __inline ALboolean CompExchangeInt(volatile int *ptr, int oldval, int newval)
-{
- return __sync_bool_compare_and_swap(ptr, oldval, newval);
-}
-static __inline ALboolean CompExchangePtr(XchgPtr *ptr, void *oldval, void *newval)
-{
- return __sync_bool_compare_and_swap(ptr, oldval, newval);
-}
+#define DECLARE_FORWARD3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
+rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b, argtype3 c) \
+{ return T2##_##func(STATIC_CAST(T2, obj), a, b, c); }
-#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
-static __inline int xaddl(volatile int *dest, int incr)
-{
- int ret;
- __asm__ __volatile__("lock; xaddl %0,(%1)"
- : "=r" (ret)
- : "r" (dest), "0" (incr)
- : "memory");
- return ret;
-}
+#define GET_VTABLE1(T1) (&(T1##_vtable))
+#define GET_VTABLE2(T1, T2) (&(T1##_##T2##_vtable))
-typedef int RefCount;
-static __inline RefCount IncrementRef(volatile RefCount *ptr)
-{ return xaddl(ptr, 1)+1; }
-static __inline RefCount DecrementRef(volatile RefCount *ptr)
-{ return xaddl(ptr, -1)-1; }
+#define SET_VTABLE1(T1, obj) ((obj)->vtbl = GET_VTABLE1(T1))
+#define SET_VTABLE2(T1, T2, obj) (STATIC_CAST(T2, obj)->vtbl = GET_VTABLE2(T1, T2))
-static __inline int ExchangeInt(volatile int *dest, int newval)
-{
- int ret;
- __asm__ __volatile__("lock; xchgl %0,(%1)"
- : "=r" (ret)
- : "r" (dest), "0" (newval)
- : "memory");
- return ret;
-}
+#define DECLARE_THUNK(T1, T2, rettype, func) \
+static rettype T1##_##T2##_##func(T2 *obj) \
+{ return T1##_##func(STATIC_UPCAST(T1, T2, obj)); }
-static __inline ALboolean CompExchangeInt(volatile int *dest, int oldval, int newval)
-{
- int ret;
- __asm__ __volatile__("lock; cmpxchgl %2,(%1)"
- : "=a" (ret)
- : "r" (dest), "r" (newval), "0" (oldval)
- : "memory");
- return ret == oldval;
-}
+#define DECLARE_THUNK1(T1, T2, rettype, func, argtype1) \
+static rettype T1##_##T2##_##func(T2 *obj, argtype1 a) \
+{ return T1##_##func(STATIC_UPCAST(T1, T2, obj), a); }
-static __inline void *ExchangePtr(XchgPtr *dest, void *newval)
-{
- void *ret;
- __asm__ __volatile__(
-#ifdef __i386__
- "lock; xchgl %0,(%1)"
-#else
- "lock; xchgq %0,(%1)"
-#endif
- : "=r" (ret)
- : "r" (dest), "0" (newval)
- : "memory"
- );
- return ret;
-}
+#define DECLARE_THUNK2(T1, T2, rettype, func, argtype1, argtype2) \
+static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b) \
+{ return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b); }
-static __inline ALboolean CompExchangePtr(XchgPtr *dest, void *oldval, void *newval)
-{
- void *ret;
- __asm__ __volatile__(
-#ifdef __i386__
- "lock; cmpxchgl %2,(%1)"
-#else
- "lock; cmpxchgq %2,(%1)"
-#endif
- : "=a" (ret)
- : "r" (dest), "r" (newval), "0" (oldval)
- : "memory"
- );
- return ret == oldval;
-}
+#define DECLARE_THUNK3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
+static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c) \
+{ return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c); }
-#elif defined(_WIN32)
-typedef LONG RefCount;
-static __inline RefCount IncrementRef(volatile RefCount *ptr)
-{ return InterlockedIncrement(ptr); }
-static __inline RefCount DecrementRef(volatile RefCount *ptr)
-{ return InterlockedDecrement(ptr); }
+/* Helper to extract an argument list for VCALL. Not used directly. */
+#define EXTRACT_VCALL_ARGS(...) __VA_ARGS__))
-extern ALbyte LONG_size_does_not_match_int[(sizeof(LONG)==sizeof(int))?1:-1];
+/* Call a "virtual" method on an object, with arguments. */
+#define V(obj, func) ((obj)->vtbl->func((obj), EXTRACT_VCALL_ARGS
+/* Call a "virtual" method on an object, with no arguments. */
+#define V0(obj, func) ((obj)->vtbl->func((obj) EXTRACT_VCALL_ARGS
-static __inline int ExchangeInt(volatile int *ptr, int newval)
-{
- union {
- volatile int *i;
- volatile LONG *l;
- } u = { ptr };
- return InterlockedExchange(u.l, newval);
-}
-static __inline void *ExchangePtr(XchgPtr *ptr, void *newval)
-{
- return InterlockedExchangePointer(ptr, newval);
-}
-static __inline ALboolean CompExchangeInt(volatile int *ptr, int oldval, int newval)
-{
- union {
- volatile int *i;
- volatile LONG *l;
- } u = { ptr };
- return InterlockedCompareExchange(u.l, newval, oldval) == oldval;
-}
-static __inline ALboolean CompExchangePtr(XchgPtr *ptr, void *oldval, void *newval)
-{
- return InterlockedCompareExchangePointer(ptr, newval, oldval) == oldval;
-}
-
-#elif defined(__APPLE__)
-
-#include <libkern/OSAtomic.h>
-
-typedef int32_t RefCount;
-static __inline RefCount IncrementRef(volatile RefCount *ptr)
-{ return OSAtomicIncrement32Barrier(ptr); }
-static __inline RefCount DecrementRef(volatile RefCount *ptr)
-{ return OSAtomicDecrement32Barrier(ptr); }
-
-static __inline int ExchangeInt(volatile int *ptr, int newval)
-{
- /* Really? No regular old atomic swap? */
- int oldval;
- do {
- oldval = *ptr;
- } while(!OSAtomicCompareAndSwap32Barrier(oldval, newval, ptr));
- return oldval;
-}
-static __inline void *ExchangePtr(XchgPtr *ptr, void *newval)
-{
- void *oldval;
- do {
- oldval = *ptr;
- } while(!OSAtomicCompareAndSwapPtrBarrier(oldval, newval, ptr));
- return oldval;
-}
-static __inline ALboolean CompExchangeInt(volatile int *ptr, int oldval, int newval)
-{
- return OSAtomicCompareAndSwap32Barrier(oldval, newval, ptr);
-}
-static __inline ALboolean CompExchangePtr(XchgPtr *ptr, void *oldval, void *newval)
-{
- return OSAtomicCompareAndSwapPtrBarrier(oldval, newval, ptr);
-}
-
-#else
-#error "No atomic functions available on this platform!"
-typedef ALuint RefCount;
-#endif
-
-
-typedef struct {
- volatile RefCount read_count;
- volatile RefCount write_count;
- volatile ALenum read_lock;
- volatile ALenum read_entry_lock;
- volatile ALenum write_lock;
-} RWLock;
-
-void RWLockInit(RWLock *lock);
-void ReadLock(RWLock *lock);
-void ReadUnlock(RWLock *lock);
-void WriteLock(RWLock *lock);
-void WriteUnlock(RWLock *lock);
-
-
-typedef struct UIntMap {
- struct {
- ALuint key;
- ALvoid *value;
- } *array;
- ALsizei size;
- ALsizei maxsize;
- ALsizei limit;
- RWLock lock;
-} UIntMap;
-extern UIntMap TlsDestructor;
-
-void InitUIntMap(UIntMap *map, ALsizei limit);
-void ResetUIntMap(UIntMap *map);
-ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value);
-ALvoid *RemoveUIntMapKey(UIntMap *map, ALuint key);
-ALvoid *LookupUIntMapKey(UIntMap *map, ALuint key);
-
-static __inline void LockUIntMapRead(UIntMap *map)
-{ ReadLock(&map->lock); }
-static __inline void UnlockUIntMapRead(UIntMap *map)
-{ ReadUnlock(&map->lock); }
-static __inline void LockUIntMapWrite(UIntMap *map)
-{ WriteLock(&map->lock); }
-static __inline void UnlockUIntMapWrite(UIntMap *map)
-{ WriteUnlock(&map->lock); }
+#define DELETE_OBJ(obj) do { \
+ if((obj) != NULL) \
+ { \
+ V0((obj),Destruct)(); \
+ V0((obj),Delete)(); \
+ } \
+} while(0)
#ifdef __cplusplus
@@ -343,8 +372,8 @@ struct Hrtf;
#define MIN_OUTPUT_RATE (8000)
-// Find the next power-of-2 for non-power-of-2 numbers.
-static __inline ALuint NextPowerOf2(ALuint value)
+/* Find the next power-of-2 for non-power-of-2 numbers. */
+inline ALuint NextPowerOf2(ALuint value)
{
if(value > 0)
{
@@ -360,7 +389,7 @@ static __inline ALuint NextPowerOf2(ALuint value)
/* Fast float-to-int conversion. Assumes the FPU is already in round-to-zero
* mode. */
-static __inline ALint fastf2i(ALfloat f)
+inline ALint fastf2i(ALfloat f)
{
#ifdef HAVE_LRINTF
return lrintf(f);
@@ -376,7 +405,7 @@ static __inline ALint fastf2i(ALfloat f)
/* Fast float-to-uint conversion. Assumes the FPU is already in round-to-zero
* mode. */
-static __inline ALuint fastf2u(ALfloat f)
+inline ALuint fastf2u(ALfloat f)
{ return fastf2i(f); }
@@ -399,26 +428,9 @@ typedef struct {
ALCenum (*CaptureSamples)(ALCdevice*, void*, ALCuint);
ALCuint (*AvailableSamples)(ALCdevice*);
- void (*Lock)(ALCdevice*);
- void (*Unlock)(ALCdevice*);
-
ALint64 (*GetLatency)(ALCdevice*);
} BackendFuncs;
-struct BackendInfo {
- const char *name;
- ALCboolean (*Init)(BackendFuncs*);
- void (*Deinit)(void);
- void (*Probe)(enum DevProbe);
- BackendFuncs Funcs;
-};
-
-ALCboolean alc_alsa_init(BackendFuncs *func_list);
-void alc_alsa_deinit(void);
-void alc_alsa_probe(enum DevProbe type);
-ALCboolean alc_oss_init(BackendFuncs *func_list);
-void alc_oss_deinit(void);
-void alc_oss_probe(enum DevProbe type);
ALCboolean alc_solaris_init(BackendFuncs *func_list);
void alc_solaris_deinit(void);
void alc_solaris_probe(enum DevProbe type);
@@ -440,21 +452,17 @@ void alc_pa_probe(enum DevProbe type);
ALCboolean alc_wave_init(BackendFuncs *func_list);
void alc_wave_deinit(void);
void alc_wave_probe(enum DevProbe type);
-ALCboolean alc_pulse_init(BackendFuncs *func_list);
-void alc_pulse_deinit(void);
-void alc_pulse_probe(enum DevProbe type);
ALCboolean alc_ca_init(BackendFuncs *func_list);
void alc_ca_deinit(void);
void alc_ca_probe(enum DevProbe type);
ALCboolean alc_opensl_init(BackendFuncs *func_list);
void alc_opensl_deinit(void);
void alc_opensl_probe(enum DevProbe type);
-ALCboolean alc_null_init(BackendFuncs *func_list);
-void alc_null_deinit(void);
-void alc_null_probe(enum DevProbe type);
-ALCboolean alc_loopback_init(BackendFuncs *func_list);
-void alc_loopback_deinit(void);
-void alc_loopback_probe(enum DevProbe type);
+ALCboolean alc_qsa_init(BackendFuncs *func_list);
+void alc_qsa_deinit(void);
+void alc_qsa_probe(enum DevProbe type);
+
+struct ALCbackend;
enum DistanceModel {
@@ -520,8 +528,7 @@ enum DevFmtChannels {
ALuint BytesFromDevFmt(enum DevFmtType type);
ALuint ChannelsFromDevFmt(enum DevFmtChannels chans);
-static __inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans,
- enum DevFmtType type)
+inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type)
{
return ChannelsFromDevFmt(chans) * BytesFromDevFmt(type);
}
@@ -546,15 +553,8 @@ enum DeviceType {
* more memory, while smaller values may need more iterations. The value needs
* 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.
- *
- * The mixer requires being able to do two samplings per mixing loop. With the
- * cubic resampler (which requires 3 padding samples), this limits a 2048
- * buffer size to about 2044. This means that buffer_freq*source_pitch cannot
- * exceed device_freq*2044 for a 32-bit buffer.
*/
-#ifndef BUFFERSIZE
-#define BUFFERSIZE 2048
-#endif
+#define BUFFERSIZE (2048u)
struct ALCdevice_struct
@@ -564,8 +564,6 @@ struct ALCdevice_struct
ALCboolean Connected;
enum DeviceType Type;
- CRITICAL_SECTION Mutex;
-
ALuint Frequency;
ALuint UpdateSize;
ALuint NumUpdates;
@@ -594,6 +592,21 @@ struct ALCdevice_struct
// Map of Filters for this device
UIntMap FilterMap;
+ // Map of Soundfonts for this device
+ UIntMap SfontMap;
+
+ // Map of Presets for this device
+ UIntMap PresetMap;
+
+ // Map of Fontsounds for this device
+ UIntMap FontsoundMap;
+
+ /* Default soundfont (accessible as ID 0) */
+ struct ALsoundfont *DefaultSfont;
+
+ /* MIDI synth engine */
+ struct MidiSynth *Synth;
+
/* HRTF filter tables */
const struct Hrtf *Hrtf;
@@ -626,37 +639,29 @@ struct ALCdevice_struct
// Contexts created on this device
ALCcontext *volatile ContextList;
+ struct ALCbackend *Backend;
+
BackendFuncs *Funcs;
void *ExtraData; // For the backend's use
ALCdevice *volatile next;
};
-#define ALCdevice_OpenPlayback(a,b) ((a)->Funcs->OpenPlayback((a), (b)))
-#define ALCdevice_ClosePlayback(a) ((a)->Funcs->ClosePlayback((a)))
-#define ALCdevice_ResetPlayback(a) ((a)->Funcs->ResetPlayback((a)))
-#define ALCdevice_StartPlayback(a) ((a)->Funcs->StartPlayback((a)))
-#define ALCdevice_StopPlayback(a) ((a)->Funcs->StopPlayback((a)))
-#define ALCdevice_OpenCapture(a,b) ((a)->Funcs->OpenCapture((a), (b)))
-#define ALCdevice_CloseCapture(a) ((a)->Funcs->CloseCapture((a)))
-#define ALCdevice_StartCapture(a) ((a)->Funcs->StartCapture((a)))
-#define ALCdevice_StopCapture(a) ((a)->Funcs->StopCapture((a)))
-#define ALCdevice_CaptureSamples(a,b,c) ((a)->Funcs->CaptureSamples((a), (b), (c)))
-#define ALCdevice_AvailableSamples(a) ((a)->Funcs->AvailableSamples((a)))
-#define ALCdevice_Lock(a) ((a)->Funcs->Lock((a)))
-#define ALCdevice_Unlock(a) ((a)->Funcs->Unlock((a)))
-#define ALCdevice_GetLatency(a) ((a)->Funcs->GetLatency((a)))
-
// Frequency was requested by the app or config file
#define DEVICE_FREQUENCY_REQUEST (1<<1)
// Channel configuration was requested by the config file
#define DEVICE_CHANNELS_REQUEST (1<<2)
// Sample type was requested by the config file
#define DEVICE_SAMPLE_TYPE_REQUEST (1<<3)
+// HRTF was requested by the app
+#define DEVICE_HRTF_REQUEST (1<<4)
// Stereo sources cover 120-degree angles around +/-90
#define DEVICE_WIDE_STEREO (1<<16)
+// Specifies if the DSP is paused at user request
+#define DEVICE_PAUSED (1<<30)
+
// Specifies if the device is currently running
#define DEVICE_RUNNING (1<<31)
@@ -664,12 +669,9 @@ struct ALCdevice_struct
#define INVALID_OFFSET (~0u)
-#define LookupBuffer(m, k) ((struct ALbuffer*)LookupUIntMapKey(&(m)->BufferMap, (k)))
-#define LookupEffect(m, k) ((struct ALeffect*)LookupUIntMapKey(&(m)->EffectMap, (k)))
-#define LookupFilter(m, k) ((struct ALfilter*)LookupUIntMapKey(&(m)->FilterMap, (k)))
-#define RemoveBuffer(m, k) ((struct ALbuffer*)RemoveUIntMapKey(&(m)->BufferMap, (k)))
-#define RemoveEffect(m, k) ((struct ALeffect*)RemoveUIntMapKey(&(m)->EffectMap, (k)))
-#define RemoveFilter(m, k) ((struct ALfilter*)RemoveUIntMapKey(&(m)->FilterMap, (k)))
+/* Must be less than 15 characters (16 including terminating null) for
+ * compatibility with pthread_setname_np limitations. */
+#define MIXER_THREAD_NAME "alsoft-mixer"
struct ALCcontext_struct
@@ -707,12 +709,6 @@ struct ALCcontext_struct
ALCcontext *volatile next;
};
-#define LookupSource(m, k) ((struct ALsource*)LookupUIntMapKey(&(m)->SourceMap, (k)))
-#define LookupEffectSlot(m, k) ((struct ALeffectslot*)LookupUIntMapKey(&(m)->EffectSlotMap, (k)))
-#define RemoveSource(m, k) ((struct ALsource*)RemoveUIntMapKey(&(m)->SourceMap, (k)))
-#define RemoveEffectSlot(m, k) ((struct ALeffectslot*)RemoveUIntMapKey(&(m)->EffectSlotMap, (k)))
-
-
ALCcontext *GetContextRef(void);
void ALCcontext_IncRef(ALCcontext *context);
@@ -721,13 +717,16 @@ void ALCcontext_DecRef(ALCcontext *context);
void AppendAllDevicesList(const ALCchar *name);
void AppendCaptureDeviceList(const ALCchar *name);
-void ALCdevice_LockDefault(ALCdevice *device);
-void ALCdevice_UnlockDefault(ALCdevice *device);
ALint64 ALCdevice_GetLatencyDefault(ALCdevice *device);
-static __inline void LockContext(ALCcontext *context)
+void ALCdevice_Lock(ALCdevice *device);
+void ALCdevice_Unlock(ALCdevice *device);
+ALint64 ALCdevice_GetLatency(ALCdevice *device);
+
+inline void LockContext(ALCcontext *context)
{ ALCdevice_Lock(context->Device); }
-static __inline void UnlockContext(ALCcontext *context)
+
+inline void UnlockContext(ALCcontext *context)
{ ALCdevice_Unlock(context->Device); }
@@ -735,8 +734,13 @@ void *al_malloc(size_t alignment, size_t size);
void *al_calloc(size_t alignment, size_t size);
void al_free(void *ptr);
+
typedef struct {
+#ifdef HAVE_FENV_H
+ DERIVE_FROM_TYPE(fenv_t);
+#else
int state;
+#endif
#ifdef HAVE_SSE
int sse_state;
#endif
@@ -744,8 +748,6 @@ typedef struct {
void SetMixerFPUMode(FPUCtl *ctl);
void RestoreFPUMode(const FPUCtl *ctl);
-ALvoid *StartThread(ALuint (*func)(ALvoid*), ALvoid *ptr);
-ALuint StopThread(ALvoid *thread);
typedef struct RingBuffer RingBuffer;
RingBuffer *CreateRingBuffer(ALsizei frame_size, ALsizei length);
@@ -779,16 +781,23 @@ const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans);
#define HRTFDELAY_FRACONE (1<<HRTFDELAY_BITS)
#define HRTFDELAY_MASK (HRTFDELAY_FRACONE-1)
const struct Hrtf *GetHrtf(ALCdevice *device);
+void FindHrtfFormat(const ALCdevice *device, enum DevFmtChannels *chans, ALCuint *srate);
void FreeHrtfs(void);
-ALuint GetHrtfIrSize (const struct Hrtf *Hrtf);
+ALuint GetHrtfIrSize(const struct Hrtf *Hrtf);
ALfloat CalcHrtfDelta(ALfloat oldGain, ALfloat newGain, const ALfloat olddir[3], const ALfloat newdir[3]);
void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays);
ALuint GetMovingHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat delta, ALint counter, ALfloat (*coeffs)[2], ALuint *delays, ALfloat (*coeffStep)[2], ALint *delayStep);
-void al_print(const char *type, const char *func, const char *fmt, ...) PRINTF_STYLE(3,4);
-#define AL_PRINT(T, ...) al_print((T), __FUNCTION__, __VA_ARGS__)
extern FILE *LogFile;
+
+#ifdef __GNUC__
+#define AL_PRINT(T, MSG, ...) fprintf(LogFile, "AL lib: %s %s: "MSG, T, __FUNCTION__ , ## __VA_ARGS__)
+#else
+void al_print(const char *type, const char *func, const char *fmt, ...) PRINTF_STYLE(3,4);
+#define AL_PRINT(T, MSG, ...) al_print((T), __FUNCTION__, MSG, __VA_ARGS__)
+#endif
+
enum LogLevel {
NoLog,
LogError,
@@ -825,57 +834,17 @@ extern ALint RTPrioLevel;
extern ALuint CPUCapFlags;
enum {
CPU_CAP_SSE = 1<<0,
- CPU_CAP_NEON = 1<<1,
+ CPU_CAP_SSE2 = 1<<1,
+ CPU_CAP_NEON = 1<<2,
};
void FillCPUCaps(ALuint capfilter);
-/**
- * Starts a try block. Must not be nested within another try block within the
- * same function.
- */
-#define al_try do { \
- int _al_err=0; \
-_al_try_label: \
- if(_al_err == 0)
-/**
- * After a try or another catch block, runs the next block if the given value
- * was thrown.
- */
-#define al_catch(val) else if(_al_err == (val))
-/**
- * After a try or catch block, runs the next block for any value thrown and not
- * caught.
- */
-#define al_catchany() else
-/** Marks the end of the final catch (or the try) block. */
-#define al_endtry } while(0)
-
-/**
- * The given integer value is "thrown" so as to be caught by a catch block.
- * Must be called in a try block within the same function. The value must not
- * be 0.
- */
-#define al_throw(e) do { \
- _al_err = (e); \
- assert(_al_err != 0); \
- goto _al_try_label; \
-} while(0)
-/** Sets an AL error on the given context, before throwing the error code. */
-#define al_throwerr(ctx, err) do { \
- alSetError((ctx), (err)); \
- al_throw((err)); \
-} while(0)
+/* Small hack to use a pointer-to-array type as a normal argument type.
+ * Shouldn't be used directly. */
+typedef ALfloat ALfloatBUFFERSIZE[BUFFERSIZE];
-/**
- * Throws an AL_INVALID_VALUE error with the given ctx if the given condition
- * is false.
- */
-#define CHECK_VALUE(ctx, cond) do { \
- if(!(cond)) \
- al_throwerr((ctx), AL_INVALID_VALUE); \
-} while(0)
#ifdef __cplusplus
}
diff --git a/OpenAL32/Include/alMidi.h b/OpenAL32/Include/alMidi.h
new file mode 100644
index 00000000..24e6675f
--- /dev/null
+++ b/OpenAL32/Include/alMidi.h
@@ -0,0 +1,166 @@
+#ifndef ALMIDI_H
+#define ALMIDI_H
+
+#include "alMain.h"
+#include "atomic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct ALsfmodulator {
+ struct {
+ ALenum Input;
+ ALenum Type;
+ ALenum Form;
+ } Source[2];
+ ALint Amount;
+ ALenum TransformOp;
+ ALenum Dest;
+} ALsfmodulator;
+
+typedef struct ALenvelope {
+ ALint DelayTime;
+ ALint AttackTime;
+ ALint HoldTime;
+ ALint DecayTime;
+ ALint SustainAttn;
+ ALint ReleaseTime;
+ ALint KeyToHoldTime;
+ ALint KeyToDecayTime;
+} ALenvelope;
+
+
+typedef struct ALfontsound {
+ volatile RefCount ref;
+
+ ALint MinKey, MaxKey;
+ ALint MinVelocity, MaxVelocity;
+
+ ALint ModLfoToPitch;
+ ALint VibratoLfoToPitch;
+ ALint ModEnvToPitch;
+
+ ALint FilterCutoff;
+ ALint FilterQ;
+ ALint ModLfoToFilterCutoff;
+ ALint ModEnvToFilterCutoff;
+ ALint ModLfoToVolume;
+
+ ALint ChorusSend;
+ ALint ReverbSend;
+
+ ALint Pan;
+
+ struct {
+ ALint Delay;
+ ALint Frequency;
+ } ModLfo;
+ struct {
+ ALint Delay;
+ ALint Frequency;
+ } VibratoLfo;
+
+ ALenvelope ModEnv;
+ ALenvelope VolEnv;
+
+ ALint Attenuation;
+
+ ALint CoarseTuning;
+ ALint FineTuning;
+
+ ALenum LoopMode;
+
+ ALint TuningScale;
+
+ ALint ExclusiveClass;
+
+ ALuint Start;
+ ALuint End;
+ ALuint LoopStart;
+ ALuint LoopEnd;
+ ALuint SampleRate;
+ ALubyte PitchKey;
+ ALbyte PitchCorrection;
+ ALenum SampleType;
+ struct ALfontsound *Link;
+
+ UIntMap ModulatorMap;
+
+ ALuint id;
+} ALfontsound;
+
+void ALfontsound_Destruct(ALfontsound *self);
+void ALfontsound_setPropi(ALfontsound *self, ALCcontext *context, ALenum param, ALint value);
+void ALfontsound_setModStagei(ALfontsound *self, ALCcontext *context, ALsizei stage, ALenum param, ALint value);
+
+ALfontsound *NewFontsound(ALCcontext *context);
+
+inline struct ALfontsound *LookupFontsound(ALCdevice *device, ALuint id)
+{ return (struct ALfontsound*)LookupUIntMapKey(&device->FontsoundMap, id); }
+inline struct ALfontsound *RemoveFontsound(ALCdevice *device, ALuint id)
+{ return (struct ALfontsound*)RemoveUIntMapKey(&device->FontsoundMap, id); }
+
+inline struct ALsfmodulator *LookupModulator(ALfontsound *sound, ALuint id)
+{ return (struct ALsfmodulator*)LookupUIntMapKey(&sound->ModulatorMap, id); }
+inline struct ALsfmodulator *RemoveModulator(ALfontsound *sound, ALuint id)
+{ return (struct ALsfmodulator*)RemoveUIntMapKey(&sound->ModulatorMap, id); }
+
+void ReleaseALFontsounds(ALCdevice *device);
+
+
+typedef struct ALsfpreset {
+ volatile RefCount ref;
+
+ ALint Preset; /* a.k.a. MIDI program number */
+ ALint Bank; /* MIDI bank 0...127, or percussion (bank 128) */
+
+ ALfontsound **Sounds;
+ ALsizei NumSounds;
+
+ ALuint id;
+} ALsfpreset;
+
+ALsfpreset *NewPreset(ALCcontext *context);
+void DeletePreset(ALsfpreset *preset, ALCdevice *device);
+
+inline struct ALsfpreset *LookupPreset(ALCdevice *device, ALuint id)
+{ return (struct ALsfpreset*)LookupUIntMapKey(&device->PresetMap, id); }
+inline struct ALsfpreset *RemovePreset(ALCdevice *device, ALuint id)
+{ return (struct ALsfpreset*)RemoveUIntMapKey(&device->PresetMap, id); }
+
+void ReleaseALPresets(ALCdevice *device);
+
+
+typedef struct ALsoundfont {
+ volatile RefCount ref;
+
+ ALsfpreset **Presets;
+ ALsizei NumPresets;
+
+ ALshort *Samples;
+ ALint NumSamples;
+
+ RWLock Lock;
+ volatile ALenum Mapped;
+
+ ALuint id;
+} ALsoundfont;
+
+void ALsoundfont_Construct(ALsoundfont *self);
+void ALsoundfont_Destruct(ALsoundfont *self);
+ALsoundfont *ALsoundfont_getDefSoundfont(ALCcontext *context);
+void ALsoundfont_deleteSoundfont(ALsoundfont *self, ALCdevice *device);
+
+inline struct ALsoundfont *LookupSfont(ALCdevice *device, ALuint id)
+{ return (struct ALsoundfont*)LookupUIntMapKey(&device->SfontMap, id); }
+inline struct ALsoundfont *RemoveSfont(ALCdevice *device, ALuint id)
+{ return (struct ALsoundfont*)RemoveUIntMapKey(&device->SfontMap, id); }
+
+void ReleaseALSoundfonts(ALCdevice *device);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ALMIDI_H */
diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h
index d8ffc9aa..31a0d229 100644
--- a/OpenAL32/Include/alSource.h
+++ b/OpenAL32/Include/alSource.h
@@ -6,6 +6,7 @@
#include "alMain.h"
#include "alu.h"
#include "alFilter.h"
+#include "alBuffer.h"
#ifdef __cplusplus
extern "C" {
@@ -21,8 +22,7 @@ extern const ALsizei ResamplerPadding[ResamplerMax];
extern const ALsizei ResamplerPrePadding[ResamplerMax];
-typedef struct ALbufferlistitem
-{
+typedef struct ALbufferlistitem {
struct ALbuffer *buffer;
struct ALbufferlistitem *next;
struct ALbufferlistitem *prev;
@@ -31,17 +31,17 @@ typedef struct ALbufferlistitem
typedef struct HrtfState {
ALboolean Moving;
ALuint Counter;
- ALIGN(16) ALfloat History[MaxChannels][SRC_HISTORY_LENGTH];
- ALIGN(16) ALfloat Values[MaxChannels][HRIR_LENGTH][2];
+ ALIGN(16) ALfloat History[MAX_INPUT_CHANNELS][SRC_HISTORY_LENGTH];
+ ALIGN(16) ALfloat Values[MAX_INPUT_CHANNELS][HRIR_LENGTH][2];
ALuint Offset;
} HrtfState;
typedef struct HrtfParams {
ALfloat Gain;
ALfloat Dir[3];
- ALIGN(16) ALfloat Coeffs[MaxChannels][HRIR_LENGTH][2];
+ ALIGN(16) ALfloat Coeffs[MAX_INPUT_CHANNELS][HRIR_LENGTH][2];
ALIGN(16) ALfloat CoeffStep[HRIR_LENGTH][2];
- ALuint Delay[MaxChannels][2];
+ ALuint Delay[MAX_INPUT_CHANNELS][2];
ALint DelayStep[2];
ALuint IrSize;
} HrtfParams;
@@ -59,23 +59,21 @@ typedef struct DirectParams {
/* A mixing matrix. First subscript is the channel number of the input data
* (regardless of channel configuration) and the second is the channel
* target (eg. FrontLeft). Not used with HRTF. */
- ALfloat Gains[MaxChannels][MaxChannels];
+ ALfloat Gains[MAX_INPUT_CHANNELS][MaxChannels];
- /* A low-pass filter, using 2 chained one-pole filters. */
- FILTER iirFilter;
- ALfloat history[MaxChannels*2];
+ ALfilterState LpFilter[MAX_INPUT_CHANNELS];
} DirectParams;
typedef struct SendParams {
- struct ALeffectslot *Slot;
+ ALfloat (*OutBuffer)[BUFFERSIZE];
+ ALfloat *ClickRemoval;
+ ALfloat *PendingClicks;
/* Gain control, which applies to all input channels to a single (mono)
* output buffer. */
ALfloat Gain;
- /* A low-pass filter, using 2 chained one-pole filters. */
- FILTER iirFilter;
- ALfloat history[MaxChannels*2];
+ ALfilterState LpFilter[MAX_INPUT_CHANNELS];
} SendParams;
@@ -178,6 +176,11 @@ typedef struct ALsource
} ALsource;
#define ALsource_Update(s,a) ((s)->Update(s,a))
+inline struct ALsource *LookupSource(ALCcontext *context, ALuint id)
+{ return (struct ALsource*)LookupUIntMapKey(&context->SourceMap, id); }
+inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id)
+{ return (struct ALsource*)RemoveUIntMapKey(&context->SourceMap, id); }
+
ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state);
ALboolean ApplyOffset(ALsource *Source);
diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h
index 01d3ca29..d88e860c 100644
--- a/OpenAL32/Include/alu.h
+++ b/OpenAL32/Include/alu.h
@@ -13,13 +13,17 @@
#endif
-#define F_PI (3.14159265358979323846f) /* pi */
-#define F_PI_2 (1.57079632679489661923f) /* pi/2 */
+#define F_PI (3.14159265358979323846f)
+#define F_PI_2 (1.57079632679489661923f)
+#define F_2PI (6.28318530717958647692f)
#ifndef FLT_EPSILON
#define FLT_EPSILON (1.19209290e-07f)
#endif
+#define DEG2RAD(x) ((ALfloat)(x) * (F_PI/180.0f))
+#define RAD2DEG(x) ((ALfloat)(x) * (180.0f/F_PI))
+
#ifdef __cplusplus
extern "C" {
@@ -31,18 +35,20 @@ struct DirectParams;
struct SendParams;
typedef void (*ResamplerFunc)(const ALfloat *src, ALuint frac, ALuint increment,
- ALfloat *RESTRICT dst, ALuint dstlen);
+ ALfloat *restrict dst, ALuint dstlen);
typedef ALvoid (*DryMixerFunc)(const struct DirectParams *params,
- const ALfloat *RESTRICT data, ALuint srcchan,
+ const ALfloat *restrict data, ALuint srcchan,
ALuint OutPos, ALuint SamplesToDo,
ALuint BufferSize);
typedef ALvoid (*WetMixerFunc)(const struct SendParams *params,
- const ALfloat *RESTRICT data,
+ const ALfloat *restrict data,
ALuint OutPos, ALuint SamplesToDo,
ALuint BufferSize);
+#define GAIN_SILENCE_THRESHOLD (0.00001f)
+
#define SPEEDOFSOUNDMETRESPERSEC (343.3f)
#define AIRABSORBGAINHF (0.99426f) /* -0.05dB */
@@ -51,47 +57,54 @@ typedef ALvoid (*WetMixerFunc)(const struct SendParams *params,
#define FRACTIONMASK (FRACTIONONE-1)
-static __inline ALfloat minf(ALfloat a, ALfloat b)
+inline ALfloat minf(ALfloat a, ALfloat b)
{ return ((a > b) ? b : a); }
-static __inline ALfloat maxf(ALfloat a, ALfloat b)
+inline ALfloat maxf(ALfloat a, ALfloat b)
{ return ((a > b) ? a : b); }
-static __inline ALfloat clampf(ALfloat val, ALfloat min, ALfloat max)
+inline ALfloat clampf(ALfloat val, ALfloat min, ALfloat max)
{ return minf(max, maxf(min, val)); }
-static __inline ALuint minu(ALuint a, ALuint b)
+inline ALdouble mind(ALdouble a, ALdouble b)
+{ return ((a > b) ? b : a); }
+inline ALdouble maxd(ALdouble a, ALdouble b)
+{ return ((a > b) ? a : b); }
+inline ALdouble clampd(ALdouble val, ALdouble min, ALdouble max)
+{ return mind(max, maxd(min, val)); }
+
+inline ALuint minu(ALuint a, ALuint b)
{ return ((a > b) ? b : a); }
-static __inline ALuint maxu(ALuint a, ALuint b)
+inline ALuint maxu(ALuint a, ALuint b)
{ return ((a > b) ? a : b); }
-static __inline ALuint clampu(ALuint val, ALuint min, ALuint max)
+inline ALuint clampu(ALuint val, ALuint min, ALuint max)
{ return minu(max, maxu(min, val)); }
-static __inline ALint mini(ALint a, ALint b)
+inline ALint mini(ALint a, ALint b)
{ return ((a > b) ? b : a); }
-static __inline ALint maxi(ALint a, ALint b)
+inline ALint maxi(ALint a, ALint b)
{ return ((a > b) ? a : b); }
-static __inline ALint clampi(ALint val, ALint min, ALint max)
+inline ALint clampi(ALint val, ALint min, ALint max)
{ return mini(max, maxi(min, val)); }
-static __inline ALint64 mini64(ALint64 a, ALint64 b)
+inline ALint64 mini64(ALint64 a, ALint64 b)
{ return ((a > b) ? b : a); }
-static __inline ALint64 maxi64(ALint64 a, ALint64 b)
+inline ALint64 maxi64(ALint64 a, ALint64 b)
{ return ((a > b) ? a : b); }
-static __inline ALint64 clampi64(ALint64 val, ALint64 min, ALint64 max)
+inline ALint64 clampi64(ALint64 val, ALint64 min, ALint64 max)
{ return mini64(max, maxi64(min, val)); }
-static __inline ALuint64 minu64(ALuint64 a, ALuint64 b)
+inline ALuint64 minu64(ALuint64 a, ALuint64 b)
{ return ((a > b) ? b : a); }
-static __inline ALuint64 maxu64(ALuint64 a, ALuint64 b)
+inline ALuint64 maxu64(ALuint64 a, ALuint64 b)
{ return ((a > b) ? a : b); }
-static __inline ALuint64 clampu64(ALuint64 val, ALuint64 min, ALuint64 max)
+inline ALuint64 clampu64(ALuint64 val, ALuint64 min, ALuint64 max)
{ return minu64(max, maxu64(min, val)); }
-static __inline ALfloat lerp(ALfloat val1, ALfloat val2, ALfloat mu)
+inline ALfloat lerp(ALfloat val1, ALfloat val2, ALfloat mu)
{
return val1 + (val2-val1)*mu;
}
-static __inline ALfloat cubic(ALfloat val0, ALfloat val1, ALfloat val2, ALfloat val3, ALfloat mu)
+inline ALfloat cubic(ALfloat val0, ALfloat val1, ALfloat val2, ALfloat val3, ALfloat mu)
{
ALfloat mu2 = mu*mu;
ALfloat a0 = -0.5f*val0 + 1.5f*val1 + -1.5f*val2 + 0.5f*val3;
@@ -105,7 +118,24 @@ static __inline ALfloat cubic(ALfloat val0, ALfloat val1, ALfloat val2, ALfloat
ALvoid aluInitPanning(ALCdevice *Device);
-ALvoid ComputeAngleGains(const ALCdevice *device, ALfloat angle, ALfloat hwidth, ALfloat ingain, ALfloat *gains);
+/**
+ * ComputeAngleGains
+ *
+ * Sets channel gains based on a given source's angle and its half-width. The
+ * angle and hwidth parameters are in radians.
+ */
+void ComputeAngleGains(const ALCdevice *device, ALfloat angle, ALfloat hwidth, ALfloat ingain, ALfloat gains[MaxChannels]);
+
+/**
+ * SetGains
+ *
+ * Helper to set the appropriate channels to the specified gain.
+ */
+inline void SetGains(const ALCdevice *device, ALfloat ingain, ALfloat gains[MaxChannels])
+{
+ ComputeAngleGains(device, 0.0f, F_PI, ingain, gains);
+}
+
ALvoid CalcSourceParams(struct ALsource *ALSource, const ALCcontext *ALContext);
ALvoid CalcNonAttnSourceParams(struct ALsource *ALSource, const ALCcontext *ALContext);
diff --git a/OpenAL32/Include/threads.h b/OpenAL32/Include/threads.h
new file mode 100644
index 00000000..26493101
--- /dev/null
+++ b/OpenAL32/Include/threads.h
@@ -0,0 +1,14 @@
+#ifndef AL_THREADS_H
+#define AL_THREADS_H
+
+#include "alMain.h"
+
+struct althread_info;
+typedef struct althread_info* althread_t;
+
+ALboolean StartThread(althread_t *out, ALuint (*func)(ALvoid*), ALvoid *ptr);
+ALuint StopThread(althread_t thread);
+
+void SetThreadName(const char *name);
+
+#endif /* AL_THREADS_H */