diff options
Diffstat (limited to 'OpenAL32/Include')
-rw-r--r-- | OpenAL32/Include/alAuxEffectSlot.h | 88 | ||||
-rw-r--r-- | OpenAL32/Include/alBuffer.h | 14 | ||||
-rw-r--r-- | OpenAL32/Include/alEffect.h | 127 | ||||
-rw-r--r-- | OpenAL32/Include/alError.h | 15 | ||||
-rw-r--r-- | OpenAL32/Include/alFilter.h | 78 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 759 | ||||
-rw-r--r-- | OpenAL32/Include/alMidi.h | 166 | ||||
-rw-r--r-- | OpenAL32/Include/alSource.h | 31 | ||||
-rw-r--r-- | OpenAL32/Include/alu.h | 76 | ||||
-rw-r--r-- | OpenAL32/Include/threads.h | 14 |
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 */ |