diff options
Diffstat (limited to 'OpenAL32')
-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 | ||||
-rw-r--r-- | OpenAL32/alAuxEffectSlot.c | 625 | ||||
-rw-r--r-- | OpenAL32/alBuffer.c | 1398 | ||||
-rw-r--r-- | OpenAL32/alEffect.c | 1232 | ||||
-rw-r--r-- | OpenAL32/alError.c | 5 | ||||
-rw-r--r-- | OpenAL32/alExtension.c | 62 | ||||
-rw-r--r-- | OpenAL32/alFilter.c | 296 | ||||
-rw-r--r-- | OpenAL32/alFontsound.c | 972 | ||||
-rw-r--r-- | OpenAL32/alListener.c | 562 | ||||
-rw-r--r-- | OpenAL32/alMidi.c | 221 | ||||
-rw-r--r-- | OpenAL32/alPreset.c | 340 | ||||
-rw-r--r-- | OpenAL32/alSoundfont.c | 563 | ||||
-rw-r--r-- | OpenAL32/alSource.c | 885 | ||||
-rw-r--r-- | OpenAL32/alState.c | 796 |
23 files changed, 5520 insertions, 3805 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 */ diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 230fe5fc..aa071de2 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -32,538 +32,491 @@ #include "alSource.h" +extern inline struct ALeffectslot *LookupEffectSlot(ALCcontext *context, ALuint id); +extern inline struct ALeffectslot *RemoveEffectSlot(ALCcontext *context, ALuint id); + static ALenum AddEffectSlotArray(ALCcontext *Context, ALsizei count, const ALuint *slots); static ALvoid RemoveEffectSlotArray(ALCcontext *Context, ALeffectslot *slot); +static UIntMap EffectStateFactoryMap; +static inline ALeffectStateFactory *getFactoryByType(ALenum type) +{ + ALeffectStateFactory* (*getFactory)(void) = LookupUIntMapKey(&EffectStateFactoryMap, type); + if(getFactory != NULL) + return getFactory(); + return NULL; +} + + AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots) { - ALCcontext *Context; - ALsizei cur = 0; + ALCcontext *context; + ALsizei cur; + ALenum err; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + for(cur = 0;cur < n;cur++) { - ALenum err; - - CHECK_VALUE(Context, n >= 0); - for(cur = 0;cur < n;cur++) + ALeffectslot *slot = al_calloc(16, sizeof(ALeffectslot)); + err = AL_OUT_OF_MEMORY; + if(!slot || (err=InitEffectSlot(slot)) != AL_NO_ERROR) { - ALeffectslot *slot = al_calloc(16, sizeof(ALeffectslot)); - err = AL_OUT_OF_MEMORY; - if(!slot || (err=InitEffectSlot(slot)) != AL_NO_ERROR) - { - al_free(slot); - al_throwerr(Context, err); - break; - } - - err = NewThunkEntry(&slot->id); - if(err == AL_NO_ERROR) - err = InsertUIntMapEntry(&Context->EffectSlotMap, slot->id, slot); - if(err != AL_NO_ERROR) - { - FreeThunkEntry(slot->id); - ALeffectState_Destroy(slot->EffectState); - al_free(slot); - - al_throwerr(Context, err); - } - - effectslots[cur] = slot->id; + al_free(slot); + alDeleteAuxiliaryEffectSlots(cur, effectslots); + SET_ERROR_AND_GOTO(context, err, done); } - err = AddEffectSlotArray(Context, n, effectslots); + + err = NewThunkEntry(&slot->id); + if(err == AL_NO_ERROR) + err = InsertUIntMapEntry(&context->EffectSlotMap, slot->id, slot); if(err != AL_NO_ERROR) - al_throwerr(Context, err); + { + FreeThunkEntry(slot->id); + DELETE_OBJ(slot->EffectState); + al_free(slot); + + alDeleteAuxiliaryEffectSlots(cur, effectslots); + SET_ERROR_AND_GOTO(context, err, done); + } + + effectslots[cur] = slot->id; } - al_catchany() + err = AddEffectSlotArray(context, n, effectslots); + if(err != AL_NO_ERROR) { - if(cur > 0) - alDeleteAuxiliaryEffectSlots(cur, effectslots); + alDeleteAuxiliaryEffectSlots(cur, effectslots); + SET_ERROR_AND_GOTO(context, err, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *effectslots) { - ALCcontext *Context; + ALCcontext *context; ALeffectslot *slot; ALsizei i; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + for(i = 0;i < n;i++) { - CHECK_VALUE(Context, n >= 0); - for(i = 0;i < n;i++) - { - if((slot=LookupEffectSlot(Context, effectslots[i])) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - if(slot->ref != 0) - al_throwerr(Context, AL_INVALID_OPERATION); - } + if((slot=LookupEffectSlot(context, effectslots[i])) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(slot->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + } - // All effectslots are valid - for(i = 0;i < n;i++) - { - if((slot=RemoveEffectSlot(Context, effectslots[i])) == NULL) - continue; - FreeThunkEntry(slot->id); + // All effectslots are valid + for(i = 0;i < n;i++) + { + if((slot=RemoveEffectSlot(context, effectslots[i])) == NULL) + continue; + FreeThunkEntry(slot->id); - RemoveEffectSlotArray(Context, slot); - ALeffectState_Destroy(slot->EffectState); + RemoveEffectSlotArray(context, slot); + DELETE_OBJ(slot->EffectState); - memset(slot, 0, sizeof(*slot)); - al_free(slot); - } + memset(slot, 0, sizeof(*slot)); + al_free(slot); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot) { - ALCcontext *Context; - ALboolean result; + ALCcontext *context; + ALboolean ret; - Context = GetContextRef(); - if(!Context) return AL_FALSE; + context = GetContextRef(); + if(!context) return AL_FALSE; - result = (LookupEffectSlot(Context, effectslot) ? AL_TRUE : AL_FALSE); + ret = (LookupEffectSlot(context, effectslot) ? AL_TRUE : AL_FALSE); - ALCcontext_DecRef(Context); + ALCcontext_DecRef(context); - return result; + return ret; } AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint value) { - ALCcontext *Context; - ALeffectslot *Slot; + ALCdevice *device; + ALCcontext *context; + ALeffectslot *slot; ALeffect *effect = NULL; ALenum err; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + device = context->Device; + if((slot=LookupEffectSlot(context, effectslot)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) { - ALCdevice *device = Context->Device; - if((Slot=LookupEffectSlot(Context, effectslot)) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - switch(param) - { - case AL_EFFECTSLOT_EFFECT: - CHECK_VALUE(Context, value == 0 || (effect=LookupEffect(device, value)) != NULL); + case AL_EFFECTSLOT_EFFECT: + effect = (value ? LookupEffect(device, value) : NULL); + if(!(value == 0 || effect != NULL)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - err = InitializeEffect(device, Slot, effect); - if(err != AL_NO_ERROR) - al_throwerr(Context, err); - Context->UpdateSources = AL_TRUE; - break; + err = InitializeEffect(device, slot, effect); + if(err != AL_NO_ERROR) + SET_ERROR_AND_GOTO(context, err, done); + context->UpdateSources = AL_TRUE; + break; - case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: - CHECK_VALUE(Context, value == AL_TRUE || value == AL_FALSE); + case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: + if(!(value == AL_TRUE || value == AL_FALSE)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - Slot->AuxSendAuto = value; - Context->UpdateSources = AL_TRUE; - break; + slot->AuxSendAuto = value; + context->UpdateSources = AL_TRUE; + break; - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, const ALint *values) { - ALCcontext *Context; + ALCcontext *context; switch(param) { - case AL_EFFECTSLOT_EFFECT: - case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: - alAuxiliaryEffectSloti(effectslot, param, values[0]); - return; + case AL_EFFECTSLOT_EFFECT: + case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: + alAuxiliaryEffectSloti(effectslot, param, values[0]); + return; } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(LookupEffectSlot(context, effectslot) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) { - if(LookupEffectSlot(Context, effectslot) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - switch(param) - { - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat value) { - ALCcontext *Context; - ALeffectslot *Slot; + ALCcontext *context; + ALeffectslot *slot; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if((slot=LookupEffectSlot(context, effectslot)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) { - if((Slot=LookupEffectSlot(Context, effectslot)) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - switch(param) - { - case AL_EFFECTSLOT_GAIN: - CHECK_VALUE(Context, value >= 0.0f && value <= 1.0f); + case AL_EFFECTSLOT_GAIN: + if(!(value >= 0.0f && value <= 1.0f)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - Slot->Gain = value; - Slot->NeedsUpdate = AL_TRUE; - break; + slot->Gain = value; + slot->NeedsUpdate = AL_TRUE; + break; - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, const ALfloat *values) { - ALCcontext *Context; + ALCcontext *context; switch(param) { - case AL_EFFECTSLOT_GAIN: - alAuxiliaryEffectSlotf(effectslot, param, values[0]); - return; + case AL_EFFECTSLOT_GAIN: + alAuxiliaryEffectSlotf(effectslot, param, values[0]); + return; } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(LookupEffectSlot(context, effectslot) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) { - if(LookupEffectSlot(Context, effectslot) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - switch(param) - { - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *value) { - ALCcontext *Context; - ALeffectslot *Slot; + ALCcontext *context; + ALeffectslot *slot; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if((slot=LookupEffectSlot(context, effectslot)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) { - if((Slot=LookupEffectSlot(Context, effectslot)) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - switch(param) - { - case AL_EFFECTSLOT_EFFECT: - *value = Slot->effect.id; - break; - - case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: - *value = Slot->AuxSendAuto; - break; + case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: + *value = slot->AuxSendAuto; + break; - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *values) { - ALCcontext *Context; + ALCcontext *context; switch(param) { - case AL_EFFECTSLOT_EFFECT: - case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: - alGetAuxiliaryEffectSloti(effectslot, param, values); - return; + case AL_EFFECTSLOT_EFFECT: + case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: + alGetAuxiliaryEffectSloti(effectslot, param, values); + return; } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(LookupEffectSlot(context, effectslot) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) { - if(LookupEffectSlot(Context, effectslot) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - switch(param) - { - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *value) { - ALCcontext *Context; - ALeffectslot *Slot; + ALCcontext *context; + ALeffectslot *slot; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if((slot=LookupEffectSlot(context, effectslot)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) { - if((Slot=LookupEffectSlot(Context, effectslot)) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - switch(param) - { - case AL_EFFECTSLOT_GAIN: - *value = Slot->Gain; - break; + case AL_EFFECTSLOT_GAIN: + *value = slot->Gain; + break; - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *values) { - ALCcontext *Context; + ALCcontext *context; switch(param) { - case AL_EFFECTSLOT_GAIN: - alGetAuxiliaryEffectSlotf(effectslot, param, values); - return; + case AL_EFFECTSLOT_GAIN: + alGetAuxiliaryEffectSlotf(effectslot, param, values); + return; } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(LookupEffectSlot(context, effectslot) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) { - if(LookupEffectSlot(Context, effectslot) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - switch(param) - { - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - - ALCcontext_DecRef(Context); -} - - -static ALvoid NoneDestroy(ALeffectState *State) -{ free(State); } -static ALboolean NoneDeviceUpdate(ALeffectState *State, ALCdevice *Device) -{ - return AL_TRUE; - (void)State; - (void)Device; -} -static ALvoid NoneUpdate(ALeffectState *State, ALCdevice *Device, const ALeffectslot *Slot) -{ - (void)State; - (void)Device; - (void)Slot; -} -static ALvoid NoneProcess(ALeffectState *State, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) -{ - (void)State; - (void)SamplesToDo; - (void)SamplesIn; - (void)SamplesOut; -} -ALeffectState *NoneCreate(void) -{ - ALeffectState *state; - - state = calloc(1, sizeof(*state)); - if(!state) - return NULL; - - state->Destroy = NoneDestroy; - state->DeviceUpdate = NoneDeviceUpdate; - state->Update = NoneUpdate; - state->Process = NoneProcess; - return state; +done: + ALCcontext_DecRef(context); } -static ALvoid RemoveEffectSlotArray(ALCcontext *Context, ALeffectslot *slot) +static ALvoid RemoveEffectSlotArray(ALCcontext *context, ALeffectslot *slot) { ALeffectslot **slotlist, **slotlistend; - LockContext(Context); - slotlist = Context->ActiveEffectSlots; - slotlistend = slotlist + Context->ActiveEffectSlotCount; + LockContext(context); + slotlist = context->ActiveEffectSlots; + slotlistend = slotlist + context->ActiveEffectSlotCount; while(slotlist != slotlistend) { if(*slotlist == slot) { *slotlist = *(--slotlistend); - Context->ActiveEffectSlotCount--; + context->ActiveEffectSlotCount--; break; } slotlist++; } - UnlockContext(Context); + UnlockContext(context); } -static ALenum AddEffectSlotArray(ALCcontext *Context, ALsizei count, const ALuint *slots) +static ALenum AddEffectSlotArray(ALCcontext *context, ALsizei count, const ALuint *slots) { ALsizei i; - LockContext(Context); - if(count > Context->MaxActiveEffectSlots-Context->ActiveEffectSlotCount) + LockContext(context); + if(count > context->MaxActiveEffectSlots-context->ActiveEffectSlotCount) { ALsizei newcount; void *temp = NULL; - newcount = Context->MaxActiveEffectSlots ? (Context->MaxActiveEffectSlots<<1) : 1; - if(newcount > Context->MaxActiveEffectSlots) - temp = realloc(Context->ActiveEffectSlots, - newcount * sizeof(*Context->ActiveEffectSlots)); + newcount = context->MaxActiveEffectSlots ? (context->MaxActiveEffectSlots<<1) : 1; + if(newcount > context->MaxActiveEffectSlots) + temp = realloc(context->ActiveEffectSlots, + newcount * sizeof(*context->ActiveEffectSlots)); if(!temp) { - UnlockContext(Context); + UnlockContext(context); return AL_OUT_OF_MEMORY; } - Context->ActiveEffectSlots = temp; - Context->MaxActiveEffectSlots = newcount; + context->ActiveEffectSlots = temp; + context->MaxActiveEffectSlots = newcount; } for(i = 0;i < count;i++) { - ALeffectslot *slot = LookupEffectSlot(Context, slots[i]); + ALeffectslot *slot = LookupEffectSlot(context, slots[i]); assert(slot != NULL); - Context->ActiveEffectSlots[Context->ActiveEffectSlotCount++] = slot; + context->ActiveEffectSlots[context->ActiveEffectSlotCount++] = slot; } - UnlockContext(Context); + UnlockContext(context); return AL_NO_ERROR; } + +void InitEffectFactoryMap(void) +{ + InitUIntMap(&EffectStateFactoryMap, ~0); + + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_NULL, ALnullStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_EAXREVERB, ALreverbStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_REVERB, ALreverbStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_AUTOWAH, ALautowahStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_CHORUS, ALchorusStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_COMPRESSOR, ALcompressorStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_DISTORTION, ALdistortionStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_ECHO, ALechoStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_EQUALIZER, ALequalizerStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_FLANGER, ALflangerStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_RING_MODULATOR, ALmodulatorStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_DEDICATED_DIALOGUE, ALdedicatedStateFactory_getFactory); + InsertUIntMapEntry(&EffectStateFactoryMap, AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT, ALdedicatedStateFactory_getFactory); +} + +void DeinitEffectFactoryMap(void) +{ + ResetUIntMap(&EffectStateFactoryMap); +} + + ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *effect) { ALenum newtype = (effect ? effect->type : AL_EFFECT_NULL); - ALeffectState *State = NULL; - ALenum err = AL_NO_ERROR; + ALeffectStateFactory *factory; - ALCdevice_Lock(Device); - if(newtype == AL_EFFECT_NULL && EffectSlot->effect.type != AL_EFFECT_NULL) - { - State = NoneCreate(); - if(!State) err = AL_OUT_OF_MEMORY; - } - else if(newtype == AL_EFFECT_EAXREVERB || newtype == AL_EFFECT_REVERB) - { - if(EffectSlot->effect.type != AL_EFFECT_EAXREVERB && EffectSlot->effect.type != AL_EFFECT_REVERB) - { - State = ReverbCreate(); - if(!State) err = AL_OUT_OF_MEMORY; - } - } - else if(newtype == AL_EFFECT_ECHO && EffectSlot->effect.type != AL_EFFECT_ECHO) - { - State = EchoCreate(); - if(!State) err = AL_OUT_OF_MEMORY; - } - else if(newtype == AL_EFFECT_RING_MODULATOR && EffectSlot->effect.type != AL_EFFECT_RING_MODULATOR) - { - State = ModulatorCreate(); - if(!State) err = AL_OUT_OF_MEMORY; - } - else if(newtype == AL_EFFECT_DEDICATED_DIALOGUE || newtype == AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT) + if(newtype != EffectSlot->EffectType) { - if(EffectSlot->effect.type != AL_EFFECT_DEDICATED_DIALOGUE && EffectSlot->effect.type != AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT) + ALeffectState *State; + FPUCtl oldMode; + + factory = getFactoryByType(newtype); + if(!factory) { - State = DedicatedCreate(); - if(!State) err = AL_OUT_OF_MEMORY; + ERR("Failed to find factory for effect type 0x%04x\n", newtype); + return AL_INVALID_ENUM; } - } - - if(err != AL_NO_ERROR) - { - ALCdevice_Unlock(Device); - return err; - } + State = V0(factory,create)(); + if(!State) + return AL_OUT_OF_MEMORY; - if(State) - { - FPUCtl oldMode; SetMixerFPUMode(&oldMode); - if(ALeffectState_DeviceUpdate(State, Device) == AL_FALSE) + ALCdevice_Lock(Device); + if(V(State,deviceUpdate)(Device) == AL_FALSE) { - RestoreFPUMode(&oldMode); ALCdevice_Unlock(Device); - ALeffectState_Destroy(State); + RestoreFPUMode(&oldMode); + DELETE_OBJ(State); return AL_OUT_OF_MEMORY; } - State = ExchangePtr((XchgPtr*)&EffectSlot->EffectState, State); + State = ExchangePtr((XchgPtr*)&EffectSlot->EffectState, State); if(!effect) - memset(&EffectSlot->effect, 0, sizeof(EffectSlot->effect)); + { + memset(&EffectSlot->EffectProps, 0, sizeof(EffectSlot->EffectProps)); + EffectSlot->EffectType = AL_EFFECT_NULL; + } else - memcpy(&EffectSlot->effect, effect, sizeof(*effect)); + { + memcpy(&EffectSlot->EffectProps, &effect->Props, sizeof(effect->Props)); + EffectSlot->EffectType = effect->type; + } + /* FIXME: This should be done asynchronously, but since the EffectState * object was changed, it needs an update before its Process method can * be called. */ EffectSlot->NeedsUpdate = AL_FALSE; - ALeffectState_Update(EffectSlot->EffectState, Device, EffectSlot); + V(EffectSlot->EffectState,update)(Device, EffectSlot); ALCdevice_Unlock(Device); RestoreFPUMode(&oldMode); - ALeffectState_Destroy(State); + DELETE_OBJ(State); State = NULL; } else { - if(!effect) - memset(&EffectSlot->effect, 0, sizeof(EffectSlot->effect)); - else - memcpy(&EffectSlot->effect, effect, sizeof(*effect)); - ALCdevice_Unlock(Device); - EffectSlot->NeedsUpdate = AL_TRUE; + if(effect) + { + ALCdevice_Lock(Device); + memcpy(&EffectSlot->EffectProps, &effect->Props, sizeof(effect->Props)); + ALCdevice_Unlock(Device); + EffectSlot->NeedsUpdate = AL_TRUE; + } } return AL_NO_ERROR; @@ -572,9 +525,13 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e ALenum InitEffectSlot(ALeffectslot *slot) { - ALint i, c; + ALeffectStateFactory *factory; + ALuint i, c; + + slot->EffectType = AL_EFFECT_NULL; - if(!(slot->EffectState=NoneCreate())) + factory = getFactoryByType(AL_EFFECT_NULL); + if(!(slot->EffectState=V0(factory,create)())) return AL_OUT_OF_MEMORY; slot->Gain = 1.0; @@ -600,7 +557,7 @@ ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context) ALeffectslot *temp = Context->EffectSlotMap.array[pos].value; Context->EffectSlotMap.array[pos].value = NULL; - ALeffectState_Destroy(temp->EffectState); + DELETE_OBJ(temp->EffectState); FreeThunkEntry(temp->id); memset(temp, 0, sizeof(ALeffectslot)); diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c index 29f3e617..d9c91c2f 100644 --- a/OpenAL32/alBuffer.c +++ b/OpenAL32/alBuffer.c @@ -32,6 +32,11 @@ #include "alThunk.h" +extern inline struct ALbuffer *LookupBuffer(ALCdevice *device, ALuint id); +extern inline struct ALbuffer *RemoveBuffer(ALCdevice *device, ALuint id); +extern inline ALuint FrameSizeFromUserFmt(enum UserFmtChannels chans, enum UserFmtType type); +extern inline ALuint FrameSizeFromFmt(enum FmtChannels chans, enum FmtType type); + static ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei frames, enum UserFmtChannels chans, enum UserFmtType type, const ALvoid *data, ALboolean storesrc); static void ConvertData(ALvoid *dst, enum UserFmtType dstType, const ALvoid *src, enum UserFmtType srcType, ALsizei numchans, ALsizei len); static ALboolean IsValidType(ALenum type); @@ -182,287 +187,285 @@ static const char aLawCompressTable[128] = { AL_API ALvoid AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers) { - ALCcontext *Context; - ALsizei cur = 0; + ALCdevice *device; + ALCcontext *context; + ALsizei cur = 0; + ALenum err; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try - { - ALCdevice *device = Context->Device; - ALenum err; + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - CHECK_VALUE(Context, n >= 0); - for(cur = 0;cur < n;cur++) + device = context->Device; + for(cur = 0;cur < n;cur++) + { + ALbuffer *buffer = calloc(1, sizeof(ALbuffer)); + if(!buffer) { - ALbuffer *buffer = calloc(1, sizeof(ALbuffer)); - if(!buffer) - al_throwerr(Context, AL_OUT_OF_MEMORY); - RWLockInit(&buffer->lock); - - err = NewThunkEntry(&buffer->id); - if(err == AL_NO_ERROR) - err = InsertUIntMapEntry(&device->BufferMap, buffer->id, buffer); - if(err != AL_NO_ERROR) - { - FreeThunkEntry(buffer->id); - memset(buffer, 0, sizeof(ALbuffer)); - free(buffer); + alDeleteBuffers(cur, buffers); + SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); + } + RWLockInit(&buffer->lock); - al_throwerr(Context, err); - } + err = NewThunkEntry(&buffer->id); + if(err == AL_NO_ERROR) + err = InsertUIntMapEntry(&device->BufferMap, buffer->id, buffer); + if(err != AL_NO_ERROR) + { + FreeThunkEntry(buffer->id); + memset(buffer, 0, sizeof(ALbuffer)); + free(buffer); - buffers[cur] = buffer->id; - } - } - al_catchany() - { - if(cur > 0) alDeleteBuffers(cur, buffers); + SET_ERROR_AND_GOTO(context, err, done); + } + + buffers[cur] = buffer->id; } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers) { - ALCcontext *Context; + ALCdevice *device; + ALCcontext *context; ALbuffer *ALBuf; ALsizei i; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try - { - ALCdevice *device = Context->Device; + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - CHECK_VALUE(Context, n >= 0); - for(i = 0;i < n;i++) - { - if(!buffers[i]) - continue; - - /* Check for valid Buffer ID */ - if((ALBuf=LookupBuffer(device, buffers[i])) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - if(ALBuf->ref != 0) - al_throwerr(Context, AL_INVALID_OPERATION); - } + device = context->Device; + for(i = 0;i < n;i++) + { + if(!buffers[i]) + continue; + + /* Check for valid Buffer ID */ + if((ALBuf=LookupBuffer(device, buffers[i])) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(ALBuf->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + } - for(i = 0;i < n;i++) - { - if((ALBuf=RemoveBuffer(device, buffers[i])) == NULL) - continue; - FreeThunkEntry(ALBuf->id); + for(i = 0;i < n;i++) + { + if((ALBuf=RemoveBuffer(device, buffers[i])) == NULL) + continue; + FreeThunkEntry(ALBuf->id); - free(ALBuf->data); + free(ALBuf->data); - memset(ALBuf, 0, sizeof(*ALBuf)); - free(ALBuf); - } + memset(ALBuf, 0, sizeof(*ALBuf)); + free(ALBuf); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALboolean AL_APIENTRY alIsBuffer(ALuint buffer) { - ALCcontext *Context; - ALboolean result; + ALCcontext *context; + ALboolean ret; - Context = GetContextRef(); - if(!Context) return AL_FALSE; + context = GetContextRef(); + if(!context) return AL_FALSE; - result = ((!buffer || LookupBuffer(Context->Device, buffer)) ? - AL_TRUE : AL_FALSE); + ret = ((!buffer || LookupBuffer(context->Device, buffer)) ? + AL_TRUE : AL_FALSE); - ALCcontext_DecRef(Context); + ALCcontext_DecRef(context); - return result; + return ret; } AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei freq) { - enum UserFmtChannels SrcChannels; - enum UserFmtType SrcType; - ALCcontext *Context; - ALuint FrameSize; - ALenum NewFormat; - ALbuffer *ALBuf; + enum UserFmtChannels srcchannels; + enum UserFmtType srctype; + ALCdevice *device; + ALCcontext *context; + ALuint framesize; + ALenum newformat; + ALbuffer *albuf; ALenum err; - Context = GetContextRef(); - if(!Context) return; - - al_try + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if((albuf=LookupBuffer(device, buffer)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(!(size >= 0 && freq > 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(DecomposeUserFormat(format, &srcchannels, &srctype) == AL_FALSE) + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + switch(srctype) { - ALCdevice *device = Context->Device; - if((ALBuf=LookupBuffer(device, buffer)) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - CHECK_VALUE(Context, size >= 0 && freq >= 0); - if(DecomposeUserFormat(format, &SrcChannels, &SrcType) == AL_FALSE) - al_throwerr(Context, AL_INVALID_ENUM); - switch(SrcType) - { - case UserFmtByte: - case UserFmtUByte: - case UserFmtShort: - case UserFmtUShort: - case UserFmtFloat: - FrameSize = FrameSizeFromUserFmt(SrcChannels, SrcType); - CHECK_VALUE(Context, (size%FrameSize) == 0); - - err = LoadData(ALBuf, freq, format, size/FrameSize, - SrcChannels, SrcType, data, AL_TRUE); - if(err != AL_NO_ERROR) - al_throwerr(Context, err); - break; - - case UserFmtInt: - case UserFmtUInt: - case UserFmtByte3: - case UserFmtUByte3: - case UserFmtDouble: - FrameSize = FrameSizeFromUserFmt(SrcChannels, SrcType); - CHECK_VALUE(Context, (size%FrameSize) == 0); - - NewFormat = AL_FORMAT_MONO_FLOAT32; - switch(SrcChannels) - { - case UserFmtMono: NewFormat = AL_FORMAT_MONO_FLOAT32; break; - case UserFmtStereo: NewFormat = AL_FORMAT_STEREO_FLOAT32; break; - case UserFmtRear: NewFormat = AL_FORMAT_REAR32; break; - case UserFmtQuad: NewFormat = AL_FORMAT_QUAD32; break; - case UserFmtX51: NewFormat = AL_FORMAT_51CHN32; break; - case UserFmtX61: NewFormat = AL_FORMAT_61CHN32; break; - case UserFmtX71: NewFormat = AL_FORMAT_71CHN32; break; - } - err = LoadData(ALBuf, freq, NewFormat, size/FrameSize, - SrcChannels, SrcType, data, AL_TRUE); - if(err != AL_NO_ERROR) - al_throwerr(Context, err); - break; - - case UserFmtMulaw: - case UserFmtAlaw: - FrameSize = FrameSizeFromUserFmt(SrcChannels, SrcType); - CHECK_VALUE(Context, (size%FrameSize) == 0); - - NewFormat = AL_FORMAT_MONO16; - switch(SrcChannels) - { - case UserFmtMono: NewFormat = AL_FORMAT_MONO16; break; - case UserFmtStereo: NewFormat = AL_FORMAT_STEREO16; break; - case UserFmtRear: NewFormat = AL_FORMAT_REAR16; break; - case UserFmtQuad: NewFormat = AL_FORMAT_QUAD16; break; - case UserFmtX51: NewFormat = AL_FORMAT_51CHN16; break; - case UserFmtX61: NewFormat = AL_FORMAT_61CHN16; break; - case UserFmtX71: NewFormat = AL_FORMAT_71CHN16; break; - } - err = LoadData(ALBuf, freq, NewFormat, size/FrameSize, - SrcChannels, SrcType, data, AL_TRUE); - if(err != AL_NO_ERROR) - al_throwerr(Context, err); - break; - - case UserFmtIMA4: - /* Here is where things vary: - * nVidia and Apple use 64+1 sample frames per block -> block_size=36 bytes per channel - * Most PC sound software uses 2040+1 sample frames per block -> block_size=1024 bytes per channel - */ - FrameSize = ChannelsFromUserFmt(SrcChannels) * 36; - CHECK_VALUE(Context, (size%FrameSize) == 0); - - NewFormat = AL_FORMAT_MONO16; - switch(SrcChannels) - { - case UserFmtMono: NewFormat = AL_FORMAT_MONO16; break; - case UserFmtStereo: NewFormat = AL_FORMAT_STEREO16; break; - case UserFmtRear: NewFormat = AL_FORMAT_REAR16; break; - case UserFmtQuad: NewFormat = AL_FORMAT_QUAD16; break; - case UserFmtX51: NewFormat = AL_FORMAT_51CHN16; break; - case UserFmtX61: NewFormat = AL_FORMAT_61CHN16; break; - case UserFmtX71: NewFormat = AL_FORMAT_71CHN16; break; - } - err = LoadData(ALBuf, freq, NewFormat, size/FrameSize*65, - SrcChannels, SrcType, data, AL_TRUE); - if(err != AL_NO_ERROR) - al_throwerr(Context, err); - break; - } + case UserFmtByte: + case UserFmtUByte: + case UserFmtShort: + case UserFmtUShort: + case UserFmtFloat: + framesize = FrameSizeFromUserFmt(srcchannels, srctype); + if(!((size%framesize) == 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + err = LoadData(albuf, freq, format, size/framesize, + srcchannels, srctype, data, AL_TRUE); + if(err != AL_NO_ERROR) + SET_ERROR_AND_GOTO(context, err, done); + break; + + case UserFmtInt: + case UserFmtUInt: + case UserFmtByte3: + case UserFmtUByte3: + case UserFmtDouble: + framesize = FrameSizeFromUserFmt(srcchannels, srctype); + if(!((size%framesize) == 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + newformat = AL_FORMAT_MONO_FLOAT32; + switch(srcchannels) + { + case UserFmtMono: newformat = AL_FORMAT_MONO_FLOAT32; break; + case UserFmtStereo: newformat = AL_FORMAT_STEREO_FLOAT32; break; + case UserFmtRear: newformat = AL_FORMAT_REAR32; break; + case UserFmtQuad: newformat = AL_FORMAT_QUAD32; break; + case UserFmtX51: newformat = AL_FORMAT_51CHN32; break; + case UserFmtX61: newformat = AL_FORMAT_61CHN32; break; + case UserFmtX71: newformat = AL_FORMAT_71CHN32; break; + } + err = LoadData(albuf, freq, newformat, size/framesize, + srcchannels, srctype, data, AL_TRUE); + if(err != AL_NO_ERROR) + SET_ERROR_AND_GOTO(context, err, done); + break; + + case UserFmtMulaw: + case UserFmtAlaw: + framesize = FrameSizeFromUserFmt(srcchannels, srctype); + if(!((size%framesize) == 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + newformat = AL_FORMAT_MONO16; + switch(srcchannels) + { + case UserFmtMono: newformat = AL_FORMAT_MONO16; break; + case UserFmtStereo: newformat = AL_FORMAT_STEREO16; break; + case UserFmtRear: newformat = AL_FORMAT_REAR16; break; + case UserFmtQuad: newformat = AL_FORMAT_QUAD16; break; + case UserFmtX51: newformat = AL_FORMAT_51CHN16; break; + case UserFmtX61: newformat = AL_FORMAT_61CHN16; break; + case UserFmtX71: newformat = AL_FORMAT_71CHN16; break; + } + err = LoadData(albuf, freq, newformat, size/framesize, + srcchannels, srctype, data, AL_TRUE); + if(err != AL_NO_ERROR) + SET_ERROR_AND_GOTO(context, err, done); + break; + + case UserFmtIMA4: + /* Here is where things vary: + * nVidia and Apple use 64+1 sample frames per block -> block_size=36 bytes per channel + * Most PC sound software uses 2040+1 sample frames per block -> block_size=1024 bytes per channel + */ + framesize = ChannelsFromUserFmt(srcchannels) * 36; + if(!((size%framesize) == 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + newformat = AL_FORMAT_MONO16; + switch(srcchannels) + { + case UserFmtMono: newformat = AL_FORMAT_MONO16; break; + case UserFmtStereo: newformat = AL_FORMAT_STEREO16; break; + case UserFmtRear: newformat = AL_FORMAT_REAR16; break; + case UserFmtQuad: newformat = AL_FORMAT_QUAD16; break; + case UserFmtX51: newformat = AL_FORMAT_51CHN16; break; + case UserFmtX61: newformat = AL_FORMAT_61CHN16; break; + case UserFmtX71: newformat = AL_FORMAT_71CHN16; break; + } + err = LoadData(albuf, freq, newformat, size/framesize*65, + srcchannels, srctype, data, AL_TRUE); + if(err != AL_NO_ERROR) + SET_ERROR_AND_GOTO(context, err, done); + break; } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, const ALvoid *data, ALsizei offset, ALsizei length) { - enum UserFmtChannels SrcChannels; - enum UserFmtType SrcType; - ALCcontext *Context; - ALbuffer *ALBuf; - - Context = GetContextRef(); - if(!Context) return; - - al_try + enum UserFmtChannels srcchannels; + enum UserFmtType srctype; + ALCdevice *device; + ALCcontext *context; + ALbuffer *albuf; + ALuint original_align; + ALuint channels; + ALuint bytes; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if((albuf=LookupBuffer(device, buffer)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(!(length >= 0 && offset >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(DecomposeUserFormat(format, &srcchannels, &srctype) == AL_FALSE) + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + + WriteLock(&albuf->lock); + original_align = ((albuf->OriginalType == UserFmtIMA4) ? + (ChannelsFromUserFmt(albuf->OriginalChannels)*36) : + FrameSizeFromUserFmt(albuf->OriginalChannels, + albuf->OriginalType)); + + if(srcchannels != albuf->OriginalChannels || srctype != albuf->OriginalType) { - ALCdevice *device = Context->Device; - ALuint original_align; - ALuint Channels; - ALuint Bytes; - - if((ALBuf=LookupBuffer(device, buffer)) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - CHECK_VALUE(Context, length >= 0 && offset >= 0); - if(DecomposeUserFormat(format, &SrcChannels, &SrcType) == AL_FALSE) - al_throwerr(Context, AL_INVALID_ENUM); - - WriteLock(&ALBuf->lock); - original_align = ((ALBuf->OriginalType == UserFmtIMA4) ? - (ChannelsFromUserFmt(ALBuf->OriginalChannels)*36) : - FrameSizeFromUserFmt(ALBuf->OriginalChannels, - ALBuf->OriginalType)); - - if(SrcChannels != ALBuf->OriginalChannels || SrcType != ALBuf->OriginalType) - { - WriteUnlock(&ALBuf->lock); - al_throwerr(Context, AL_INVALID_ENUM); - } - if(offset > ALBuf->OriginalSize || length > ALBuf->OriginalSize-offset || - (offset%original_align) != 0 || (length%original_align) != 0) - { - WriteUnlock(&ALBuf->lock); - al_throwerr(Context, AL_INVALID_VALUE); - } + WriteUnlock(&albuf->lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + if(offset > albuf->OriginalSize || length > albuf->OriginalSize-offset || + (offset%original_align) != 0 || (length%original_align) != 0) + { + WriteUnlock(&albuf->lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + } - Channels = ChannelsFromFmt(ALBuf->FmtChannels); - Bytes = BytesFromFmt(ALBuf->FmtType); - /* offset -> byte offset, length -> sample count */ - if(SrcType == UserFmtIMA4) - { - offset = offset/36*65 * Bytes; - length = length/original_align * 65; - } - else - { - ALuint OldBytes = BytesFromUserFmt(SrcType); - offset = offset/OldBytes * Bytes; - length = length/OldBytes/Channels; - } - ConvertData(&((ALubyte*)ALBuf->data)[offset], ALBuf->FmtType, - data, SrcType, Channels, length); - WriteUnlock(&ALBuf->lock); + channels = ChannelsFromFmt(albuf->FmtChannels); + bytes = BytesFromFmt(albuf->FmtType); + /* offset -> byte offset, length -> sample count */ + if(srctype == UserFmtIMA4) + { + offset = offset/36*65 * bytes; + length = length/original_align * 65; + } + else + { + ALuint OldBytes = BytesFromUserFmt(srctype); + offset = offset/OldBytes * bytes; + length = length/OldBytes/channels; } - al_endtry; + ConvertData((char*)albuf->data+offset, (enum UserFmtType)albuf->FmtType, + data, srctype, channels, length); + WriteUnlock(&albuf->lock); - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } @@ -470,394 +473,366 @@ AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer, ALuint samplerate, ALenum internalformat, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data) { - ALCcontext *Context; - ALbuffer *ALBuf; + ALCdevice *device; + ALCcontext *context; + ALbuffer *albuf; ALenum err; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try - { - ALCdevice *device = Context->Device; - if((ALBuf=LookupBuffer(device, buffer)) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - CHECK_VALUE(Context, samples >= 0 && samplerate != 0); - if(IsValidType(type) == AL_FALSE || IsValidChannels(channels) == AL_FALSE) - al_throwerr(Context, AL_INVALID_ENUM); - - err = LoadData(ALBuf, samplerate, internalformat, samples, - channels, type, data, AL_FALSE); - if(err != AL_NO_ERROR) - al_throwerr(Context, err); - } - al_endtry; + device = context->Device; + if((albuf=LookupBuffer(device, buffer)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(!(samples >= 0 && samplerate != 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(IsValidType(type) == AL_FALSE || IsValidChannels(channels) == AL_FALSE) + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + + err = LoadData(albuf, samplerate, internalformat, samples, + channels, type, data, AL_FALSE); + if(err != AL_NO_ERROR) + SET_ERROR_AND_GOTO(context, err, done); - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data) { - ALCcontext *Context; - ALbuffer *ALBuf; - - Context = GetContextRef(); - if(!Context) return; - - al_try + ALCdevice *device; + ALCcontext *context; + ALuint framesize; + ALbuffer *albuf; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if((albuf=LookupBuffer(device, buffer)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(!(samples >= 0 && offset >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(IsValidType(type) == AL_FALSE) + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + + WriteLock(&albuf->lock); + framesize = FrameSizeFromFmt(albuf->FmtChannels, albuf->FmtType); + if(channels != (ALenum)albuf->FmtChannels) { - ALCdevice *device = Context->Device; - ALuint FrameSize; - - if((ALBuf=LookupBuffer(device, buffer)) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - CHECK_VALUE(Context, samples >= 0 && offset >= 0); - if(IsValidType(type) == AL_FALSE) - al_throwerr(Context, AL_INVALID_ENUM); - - WriteLock(&ALBuf->lock); - FrameSize = FrameSizeFromFmt(ALBuf->FmtChannels, ALBuf->FmtType); - if(channels != (ALenum)ALBuf->FmtChannels) - { - WriteUnlock(&ALBuf->lock); - al_throwerr(Context, AL_INVALID_ENUM); - } - else if(offset > ALBuf->SampleLen || samples > ALBuf->SampleLen-offset) - { - WriteUnlock(&ALBuf->lock); - al_throwerr(Context,AL_INVALID_VALUE); - } - - /* offset -> byte offset */ - offset *= FrameSize; - ConvertData(&((ALubyte*)ALBuf->data)[offset], ALBuf->FmtType, - data, type, ChannelsFromFmt(ALBuf->FmtChannels), samples); - WriteUnlock(&ALBuf->lock); + WriteUnlock(&albuf->lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; + else if(offset > albuf->SampleLen || samples > albuf->SampleLen-offset) + { + WriteUnlock(&albuf->lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + } + + /* offset -> byte offset */ + offset *= framesize; + ConvertData((char*)albuf->data+offset, (enum UserFmtType)albuf->FmtType, + data, type, ChannelsFromFmt(albuf->FmtChannels), samples); + WriteUnlock(&albuf->lock); - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, ALvoid *data) { - ALCcontext *Context; - ALbuffer *ALBuf; - - Context = GetContextRef(); - if(!Context) return; - - al_try + ALCdevice *device; + ALCcontext *context; + ALuint framesize; + ALbuffer *albuf; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if((albuf=LookupBuffer(device, buffer)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(!(samples >= 0 && offset >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(IsValidType(type) == AL_FALSE) + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + + ReadLock(&albuf->lock); + framesize = FrameSizeFromFmt(albuf->FmtChannels, albuf->FmtType); + if(channels != (ALenum)albuf->FmtChannels) { - ALCdevice *device = Context->Device; - ALuint FrameSize; - - if((ALBuf=LookupBuffer(device, buffer)) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - CHECK_VALUE(Context, samples >= 0 && offset >= 0); - if(IsValidType(type) == AL_FALSE) - al_throwerr(Context, AL_INVALID_ENUM); - - ReadLock(&ALBuf->lock); - FrameSize = FrameSizeFromFmt(ALBuf->FmtChannels, ALBuf->FmtType); - if(channels != (ALenum)ALBuf->FmtChannels) - { - ReadUnlock(&ALBuf->lock); - al_throwerr(Context, AL_INVALID_ENUM); - } - if(offset > ALBuf->SampleLen || samples > ALBuf->SampleLen-offset) - { - ReadUnlock(&ALBuf->lock); - al_throwerr(Context,AL_INVALID_VALUE); - } - if(type == UserFmtIMA4 && (samples%65) != 0) - { - ReadUnlock(&ALBuf->lock); - al_throwerr(Context, AL_INVALID_VALUE); - } - - /* offset -> byte offset */ - offset *= FrameSize; - ConvertData(data, type, &((ALubyte*)ALBuf->data)[offset], ALBuf->FmtType, - ChannelsFromFmt(ALBuf->FmtChannels), samples); - ReadUnlock(&ALBuf->lock); + ReadUnlock(&albuf->lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + if(offset > albuf->SampleLen || samples > albuf->SampleLen-offset) + { + ReadUnlock(&albuf->lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + } + if(type == UserFmtIMA4 && (samples%65) != 0) + { + ReadUnlock(&albuf->lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); } - al_endtry; - ALCcontext_DecRef(Context); + /* offset -> byte offset */ + offset *= framesize; + ConvertData(data, type, (char*)albuf->data+offset, (enum UserFmtType)albuf->FmtType, + ChannelsFromFmt(albuf->FmtChannels), samples); + ReadUnlock(&albuf->lock); + +done: + ALCcontext_DecRef(context); } AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum format) { - enum FmtChannels DstChannels; - enum FmtType DstType; - ALCcontext *Context; + enum FmtChannels dstchannels; + enum FmtType dsttype; + ALCcontext *context; ALboolean ret; - Context = GetContextRef(); - if(!Context) return AL_FALSE; + context = GetContextRef(); + if(!context) return AL_FALSE; - ret = DecomposeFormat(format, &DstChannels, &DstType); + ret = DecomposeFormat(format, &dstchannels, &dsttype); - ALCcontext_DecRef(Context); + ALCcontext_DecRef(context); return ret; } -AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum param, ALfloat value) +AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum param, ALfloat UNUSED(value)) { - ALCcontext *Context; + ALCdevice *device; + ALCcontext *context; - (void)value; + context = GetContextRef(); + if(!context) return; - Context = GetContextRef(); - if(!Context) return; + device = context->Device; + if(LookupBuffer(device, buffer) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - al_try + switch(param) { - ALCdevice *device = Context->Device; - if(LookupBuffer(device, buffer) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - - switch(param) - { - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } -AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3) +AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum param, ALfloat UNUSED(value1), ALfloat UNUSED(value2), ALfloat UNUSED(value3)) { - ALCcontext *Context; + ALCdevice *device; + ALCcontext *context; - (void)value1; - (void)value2; - (void)value3; + context = GetContextRef(); + if(!context) return; - Context = GetContextRef(); - if(!Context) return; + device = context->Device; + if(LookupBuffer(device, buffer) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - al_try + switch(param) { - ALCdevice *device = Context->Device; - if(LookupBuffer(device, buffer) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - - switch(param) - { - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum param, const ALfloat *values) { - ALCcontext *Context; + ALCdevice *device; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try - { - ALCdevice *device = Context->Device; - if(LookupBuffer(device, buffer) == NULL) - al_throwerr(Context, AL_INVALID_NAME); + device = context->Device; + if(LookupBuffer(device, buffer) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - CHECK_VALUE(Context, values); - switch(param) - { - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) + { + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } -AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint value) +AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint UNUSED(value)) { - ALCcontext *Context; + ALCdevice *device; + ALCcontext *context; - (void)value; + context = GetContextRef(); + if(!context) return; - Context = GetContextRef(); - if(!Context) return; + device = context->Device; + if(LookupBuffer(device, buffer) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - al_try + switch(param) { - ALCdevice *device = Context->Device; - if(LookupBuffer(device, buffer) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - - switch(param) - { - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } -AL_API void AL_APIENTRY alBuffer3i(ALuint buffer, ALenum param, ALint value1, ALint value2, ALint value3) +AL_API void AL_APIENTRY alBuffer3i(ALuint buffer, ALenum param, ALint UNUSED(value1), ALint UNUSED(value2), ALint UNUSED(value3)) { - ALCcontext *Context; + ALCdevice *device; + ALCcontext *context; - (void)value1; - (void)value2; - (void)value3; + context = GetContextRef(); + if(!context) return; - Context = GetContextRef(); - if(!Context) return; + device = context->Device; + if(LookupBuffer(device, buffer) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - al_try + switch(param) { - ALCdevice *device = Context->Device; - if(LookupBuffer(device, buffer) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - - switch(param) - { - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *values) { - ALCcontext *Context; - ALbuffer *ALBuf; + ALCdevice *device; + ALCcontext *context; + ALbuffer *albuf; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try - { - ALCdevice *device = Context->Device; - if((ALBuf=LookupBuffer(device, buffer)) == NULL) - al_throwerr(Context, AL_INVALID_NAME); + device = context->Device; + if((albuf=LookupBuffer(device, buffer)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - CHECK_VALUE(Context, values); - switch(param) + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) + { + case AL_LOOP_POINTS_SOFT: + WriteLock(&albuf->lock); + if(albuf->ref != 0) { - case AL_LOOP_POINTS_SOFT: - WriteLock(&ALBuf->lock); - if(ALBuf->ref != 0) - { - WriteUnlock(&ALBuf->lock); - al_throwerr(Context, AL_INVALID_OPERATION); - } - if(values[0] >= values[1] || values[0] < 0 || - values[1] > ALBuf->SampleLen) - { - WriteUnlock(&ALBuf->lock); - al_throwerr(Context, AL_INVALID_VALUE); - } + WriteUnlock(&albuf->lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + } + if(values[0] >= values[1] || values[0] < 0 || + values[1] > albuf->SampleLen) + { + WriteUnlock(&albuf->lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + } - ALBuf->LoopStart = values[0]; - ALBuf->LoopEnd = values[1]; - WriteUnlock(&ALBuf->lock); - break; + albuf->LoopStart = values[0]; + albuf->LoopEnd = values[1]; + WriteUnlock(&albuf->lock); + break; - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alGetBufferf(ALuint buffer, ALenum param, ALfloat *value) { - ALCcontext *Context; - ALbuffer *Buffer; + ALCdevice *device; + ALCcontext *context; + ALbuffer *albuf; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try - { - ALCdevice *device = Context->Device; - if((Buffer=LookupBuffer(device, buffer)) == NULL) - al_throwerr(Context, AL_INVALID_NAME); + device = context->Device; + if((albuf=LookupBuffer(device, buffer)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - CHECK_VALUE(Context, value); - switch(param) - { - case AL_SEC_LENGTH_SOFT: - ReadLock(&Buffer->lock); - if(Buffer->SampleLen != 0) - *value = Buffer->SampleLen / (ALfloat)Buffer->Frequency; - else - *value = 0.0f; - ReadUnlock(&Buffer->lock); - break; + if(!(value)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) + { + case AL_SEC_LENGTH_SOFT: + ReadLock(&albuf->lock); + if(albuf->SampleLen != 0) + *value = albuf->SampleLen / (ALfloat)albuf->Frequency; + else + *value = 0.0f; + ReadUnlock(&albuf->lock); + break; - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API void AL_APIENTRY alGetBuffer3f(ALuint buffer, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3) { - ALCcontext *Context; + ALCdevice *device; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try - { - ALCdevice *device = Context->Device; - if(LookupBuffer(device, buffer) == NULL) - al_throwerr(Context, AL_INVALID_NAME); + device = context->Device; + if(LookupBuffer(device, buffer) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - CHECK_VALUE(Context, value1 && value2 && value3); - switch(param) - { - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + if(!(value1 && value2 && value3)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) + { + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API void AL_APIENTRY alGetBufferfv(ALuint buffer, ALenum param, ALfloat *values) { - ALCcontext *Context; + ALCdevice *device; + ALCcontext *context; switch(param) { @@ -866,116 +841,113 @@ AL_API void AL_APIENTRY alGetBufferfv(ALuint buffer, ALenum param, ALfloat *valu return; } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try - { - ALCdevice *device = Context->Device; - if(LookupBuffer(device, buffer) == NULL) - al_throwerr(Context, AL_INVALID_NAME); + device = context->Device; + if(LookupBuffer(device, buffer) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - CHECK_VALUE(Context, values); - switch(param) - { - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) + { + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value) { - ALCcontext *Context; - ALbuffer *Buffer; + ALCdevice *device; + ALCcontext *context; + ALbuffer *albuf; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try - { - ALCdevice *device = Context->Device; - if((Buffer=LookupBuffer(device, buffer)) == NULL) - al_throwerr(Context, AL_INVALID_NAME); + device = context->Device; + if((albuf=LookupBuffer(device, buffer)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - CHECK_VALUE(Context, value); - switch(param) - { - case AL_FREQUENCY: - *value = Buffer->Frequency; - break; + if(!(value)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) + { + case AL_FREQUENCY: + *value = albuf->Frequency; + break; - case AL_BITS: - *value = BytesFromFmt(Buffer->FmtType) * 8; - break; + case AL_BITS: + *value = BytesFromFmt(albuf->FmtType) * 8; + break; - case AL_CHANNELS: - *value = ChannelsFromFmt(Buffer->FmtChannels); - break; + case AL_CHANNELS: + *value = ChannelsFromFmt(albuf->FmtChannels); + break; - case AL_SIZE: - ReadLock(&Buffer->lock); - *value = Buffer->SampleLen * FrameSizeFromFmt(Buffer->FmtChannels, - Buffer->FmtType); - ReadUnlock(&Buffer->lock); - break; + case AL_SIZE: + ReadLock(&albuf->lock); + *value = albuf->SampleLen * FrameSizeFromFmt(albuf->FmtChannels, + albuf->FmtType); + ReadUnlock(&albuf->lock); + break; - case AL_INTERNAL_FORMAT_SOFT: - *value = Buffer->Format; - break; + case AL_INTERNAL_FORMAT_SOFT: + *value = albuf->Format; + break; - case AL_BYTE_LENGTH_SOFT: - *value = Buffer->OriginalSize; - break; + case AL_BYTE_LENGTH_SOFT: + *value = albuf->OriginalSize; + break; - case AL_SAMPLE_LENGTH_SOFT: - *value = Buffer->SampleLen; - break; + case AL_SAMPLE_LENGTH_SOFT: + *value = albuf->SampleLen; + break; - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum param, ALint *value1, ALint *value2, ALint *value3) { - ALCcontext *Context; + ALCdevice *device; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try - { - ALCdevice *device = Context->Device; - if(LookupBuffer(device, buffer) == NULL) - al_throwerr(Context, AL_INVALID_NAME); + device = context->Device; + if(LookupBuffer(device, buffer) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - CHECK_VALUE(Context, value1 && value2 && value3); - switch(param) - { - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + if(!(value1 && value2 && value3)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) + { + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values) { - ALCcontext *Context; - ALbuffer *ALBuf; + ALCdevice *device; + ALCcontext *context; + ALbuffer *albuf; switch(param) { @@ -990,32 +962,30 @@ AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values return; } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try - { - ALCdevice *device = Context->Device; - if((ALBuf=LookupBuffer(device, buffer)) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - - CHECK_VALUE(Context, values); - switch(param) - { - case AL_LOOP_POINTS_SOFT: - ReadLock(&ALBuf->lock); - values[0] = ALBuf->LoopStart; - values[1] = ALBuf->LoopEnd; - ReadUnlock(&ALBuf->lock); - break; + device = context->Device; + if((albuf=LookupBuffer(device, buffer)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) + { + case AL_LOOP_POINTS_SOFT: + ReadLock(&albuf->lock); + values[0] = albuf->LoopStart; + values[1] = albuf->LoopEnd; + ReadUnlock(&albuf->lock); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } @@ -1031,7 +1001,7 @@ typedef struct { } ALubyte3; extern ALbyte ALubyte3_size_is_not_3[(sizeof(ALubyte3)==sizeof(ALubyte[3]))?1:-1]; -static __inline ALshort DecodeMuLaw(ALmulaw val) +static inline ALshort DecodeMuLaw(ALmulaw val) { return muLawDecompressionTable[val]; } static ALmulaw EncodeMuLaw(ALshort val) @@ -1056,7 +1026,7 @@ static ALmulaw EncodeMuLaw(ALshort val) return ~(sign | (exp<<4) | mant); } -static __inline ALshort DecodeALaw(ALalaw val) +static inline ALshort DecodeALaw(ALalaw val) { return aLawDecompressionTable[val]; } static ALalaw EncodeALaw(ALshort val) @@ -1087,8 +1057,8 @@ static ALalaw EncodeALaw(ALshort val) static void DecodeIMA4Block(ALshort *dst, const ALima4 *src, ALint numchans) { - ALint sample[MaxChannels], index[MaxChannels]; - ALuint code[MaxChannels]; + ALint sample[MAX_INPUT_CHANNELS], index[MAX_INPUT_CHANNELS]; + ALuint code[MAX_INPUT_CHANNELS]; ALsizei j,k,c; for(c = 0;c < numchans;c++) @@ -1203,14 +1173,14 @@ static void EncodeIMA4Block(ALima4 *dst, const ALshort *src, ALint *sample, ALin } -static __inline ALint DecodeByte3(ALbyte3 val) +static inline ALint DecodeByte3(ALbyte3 val) { if(IS_LITTLE_ENDIAN) return (val.b[2]<<16) | (((ALubyte)val.b[1])<<8) | ((ALubyte)val.b[0]); return (val.b[0]<<16) | (((ALubyte)val.b[1])<<8) | ((ALubyte)val.b[2]); } -static __inline ALbyte3 EncodeByte3(ALint val) +static inline ALbyte3 EncodeByte3(ALint val) { if(IS_LITTLE_ENDIAN) { @@ -1224,14 +1194,14 @@ static __inline ALbyte3 EncodeByte3(ALint val) } } -static __inline ALint DecodeUByte3(ALubyte3 val) +static inline ALint DecodeUByte3(ALubyte3 val) { if(IS_LITTLE_ENDIAN) return (val.b[2]<<16) | (val.b[1]<<8) | (val.b[0]); return (val.b[0]<<16) | (val.b[1]<<8) | val.b[2]; } -static __inline ALubyte3 EncodeUByte3(ALint val) +static inline ALubyte3 EncodeUByte3(ALint val) { if(IS_LITTLE_ENDIAN) { @@ -1246,256 +1216,256 @@ static __inline ALubyte3 EncodeUByte3(ALint val) } -static __inline ALbyte Conv_ALbyte_ALbyte(ALbyte val) +static inline ALbyte Conv_ALbyte_ALbyte(ALbyte val) { return val; } -static __inline ALbyte Conv_ALbyte_ALubyte(ALubyte val) +static inline ALbyte Conv_ALbyte_ALubyte(ALubyte val) { return val-128; } -static __inline ALbyte Conv_ALbyte_ALshort(ALshort val) +static inline ALbyte Conv_ALbyte_ALshort(ALshort val) { return val>>8; } -static __inline ALbyte Conv_ALbyte_ALushort(ALushort val) +static inline ALbyte Conv_ALbyte_ALushort(ALushort val) { return (val>>8)-128; } -static __inline ALbyte Conv_ALbyte_ALint(ALint val) +static inline ALbyte Conv_ALbyte_ALint(ALint val) { return val>>24; } -static __inline ALbyte Conv_ALbyte_ALuint(ALuint val) +static inline ALbyte Conv_ALbyte_ALuint(ALuint val) { return (val>>24)-128; } -static __inline ALbyte Conv_ALbyte_ALfloat(ALfloat val) +static inline ALbyte Conv_ALbyte_ALfloat(ALfloat val) { if(val > 1.0f) return 127; if(val < -1.0f) return -128; return (ALint)(val * 127.0f); } -static __inline ALbyte Conv_ALbyte_ALdouble(ALdouble val) +static inline ALbyte Conv_ALbyte_ALdouble(ALdouble val) { if(val > 1.0) return 127; if(val < -1.0) return -128; return (ALint)(val * 127.0); } -static __inline ALbyte Conv_ALbyte_ALmulaw(ALmulaw val) +static inline ALbyte Conv_ALbyte_ALmulaw(ALmulaw val) { return Conv_ALbyte_ALshort(DecodeMuLaw(val)); } -static __inline ALbyte Conv_ALbyte_ALalaw(ALalaw val) +static inline ALbyte Conv_ALbyte_ALalaw(ALalaw val) { return Conv_ALbyte_ALshort(DecodeALaw(val)); } -static __inline ALbyte Conv_ALbyte_ALbyte3(ALbyte3 val) +static inline ALbyte Conv_ALbyte_ALbyte3(ALbyte3 val) { return DecodeByte3(val)>>16; } -static __inline ALbyte Conv_ALbyte_ALubyte3(ALubyte3 val) +static inline ALbyte Conv_ALbyte_ALubyte3(ALubyte3 val) { return (DecodeUByte3(val)>>16)-128; } -static __inline ALubyte Conv_ALubyte_ALbyte(ALbyte val) +static inline ALubyte Conv_ALubyte_ALbyte(ALbyte val) { return val+128; } -static __inline ALubyte Conv_ALubyte_ALubyte(ALubyte val) +static inline ALubyte Conv_ALubyte_ALubyte(ALubyte val) { return val; } -static __inline ALubyte Conv_ALubyte_ALshort(ALshort val) +static inline ALubyte Conv_ALubyte_ALshort(ALshort val) { return (val>>8)+128; } -static __inline ALubyte Conv_ALubyte_ALushort(ALushort val) +static inline ALubyte Conv_ALubyte_ALushort(ALushort val) { return val>>8; } -static __inline ALubyte Conv_ALubyte_ALint(ALint val) +static inline ALubyte Conv_ALubyte_ALint(ALint val) { return (val>>24)+128; } -static __inline ALubyte Conv_ALubyte_ALuint(ALuint val) +static inline ALubyte Conv_ALubyte_ALuint(ALuint val) { return val>>24; } -static __inline ALubyte Conv_ALubyte_ALfloat(ALfloat val) +static inline ALubyte Conv_ALubyte_ALfloat(ALfloat val) { if(val > 1.0f) return 255; if(val < -1.0f) return 0; return (ALint)(val * 127.0f) + 128; } -static __inline ALubyte Conv_ALubyte_ALdouble(ALdouble val) +static inline ALubyte Conv_ALubyte_ALdouble(ALdouble val) { if(val > 1.0) return 255; if(val < -1.0) return 0; return (ALint)(val * 127.0) + 128; } -static __inline ALubyte Conv_ALubyte_ALmulaw(ALmulaw val) +static inline ALubyte Conv_ALubyte_ALmulaw(ALmulaw val) { return Conv_ALubyte_ALshort(DecodeMuLaw(val)); } -static __inline ALubyte Conv_ALubyte_ALalaw(ALalaw val) +static inline ALubyte Conv_ALubyte_ALalaw(ALalaw val) { return Conv_ALubyte_ALshort(DecodeALaw(val)); } -static __inline ALubyte Conv_ALubyte_ALbyte3(ALbyte3 val) +static inline ALubyte Conv_ALubyte_ALbyte3(ALbyte3 val) { return (DecodeByte3(val)>>16)+128; } -static __inline ALubyte Conv_ALubyte_ALubyte3(ALubyte3 val) +static inline ALubyte Conv_ALubyte_ALubyte3(ALubyte3 val) { return DecodeUByte3(val)>>16; } -static __inline ALshort Conv_ALshort_ALbyte(ALbyte val) +static inline ALshort Conv_ALshort_ALbyte(ALbyte val) { return val<<8; } -static __inline ALshort Conv_ALshort_ALubyte(ALubyte val) +static inline ALshort Conv_ALshort_ALubyte(ALubyte val) { return (val-128)<<8; } -static __inline ALshort Conv_ALshort_ALshort(ALshort val) +static inline ALshort Conv_ALshort_ALshort(ALshort val) { return val; } -static __inline ALshort Conv_ALshort_ALushort(ALushort val) +static inline ALshort Conv_ALshort_ALushort(ALushort val) { return val-32768; } -static __inline ALshort Conv_ALshort_ALint(ALint val) +static inline ALshort Conv_ALshort_ALint(ALint val) { return val>>16; } -static __inline ALshort Conv_ALshort_ALuint(ALuint val) +static inline ALshort Conv_ALshort_ALuint(ALuint val) { return (val>>16)-32768; } -static __inline ALshort Conv_ALshort_ALfloat(ALfloat val) +static inline ALshort Conv_ALshort_ALfloat(ALfloat val) { if(val > 1.0f) return 32767; if(val < -1.0f) return -32768; return (ALint)(val * 32767.0f); } -static __inline ALshort Conv_ALshort_ALdouble(ALdouble val) +static inline ALshort Conv_ALshort_ALdouble(ALdouble val) { if(val > 1.0) return 32767; if(val < -1.0) return -32768; return (ALint)(val * 32767.0); } -static __inline ALshort Conv_ALshort_ALmulaw(ALmulaw val) +static inline ALshort Conv_ALshort_ALmulaw(ALmulaw val) { return Conv_ALshort_ALshort(DecodeMuLaw(val)); } -static __inline ALshort Conv_ALshort_ALalaw(ALalaw val) +static inline ALshort Conv_ALshort_ALalaw(ALalaw val) { return Conv_ALshort_ALshort(DecodeALaw(val)); } -static __inline ALshort Conv_ALshort_ALbyte3(ALbyte3 val) +static inline ALshort Conv_ALshort_ALbyte3(ALbyte3 val) { return DecodeByte3(val)>>8; } -static __inline ALshort Conv_ALshort_ALubyte3(ALubyte3 val) +static inline ALshort Conv_ALshort_ALubyte3(ALubyte3 val) { return (DecodeUByte3(val)>>8)-32768; } -static __inline ALushort Conv_ALushort_ALbyte(ALbyte val) +static inline ALushort Conv_ALushort_ALbyte(ALbyte val) { return (val+128)<<8; } -static __inline ALushort Conv_ALushort_ALubyte(ALubyte val) +static inline ALushort Conv_ALushort_ALubyte(ALubyte val) { return val<<8; } -static __inline ALushort Conv_ALushort_ALshort(ALshort val) +static inline ALushort Conv_ALushort_ALshort(ALshort val) { return val+32768; } -static __inline ALushort Conv_ALushort_ALushort(ALushort val) +static inline ALushort Conv_ALushort_ALushort(ALushort val) { return val; } -static __inline ALushort Conv_ALushort_ALint(ALint val) +static inline ALushort Conv_ALushort_ALint(ALint val) { return (val>>16)+32768; } -static __inline ALushort Conv_ALushort_ALuint(ALuint val) +static inline ALushort Conv_ALushort_ALuint(ALuint val) { return val>>16; } -static __inline ALushort Conv_ALushort_ALfloat(ALfloat val) +static inline ALushort Conv_ALushort_ALfloat(ALfloat val) { if(val > 1.0f) return 65535; if(val < -1.0f) return 0; return (ALint)(val * 32767.0f) + 32768; } -static __inline ALushort Conv_ALushort_ALdouble(ALdouble val) +static inline ALushort Conv_ALushort_ALdouble(ALdouble val) { if(val > 1.0) return 65535; if(val < -1.0) return 0; return (ALint)(val * 32767.0) + 32768; } -static __inline ALushort Conv_ALushort_ALmulaw(ALmulaw val) +static inline ALushort Conv_ALushort_ALmulaw(ALmulaw val) { return Conv_ALushort_ALshort(DecodeMuLaw(val)); } -static __inline ALushort Conv_ALushort_ALalaw(ALalaw val) +static inline ALushort Conv_ALushort_ALalaw(ALalaw val) { return Conv_ALushort_ALshort(DecodeALaw(val)); } -static __inline ALushort Conv_ALushort_ALbyte3(ALbyte3 val) +static inline ALushort Conv_ALushort_ALbyte3(ALbyte3 val) { return (DecodeByte3(val)>>8)+32768; } -static __inline ALushort Conv_ALushort_ALubyte3(ALubyte3 val) +static inline ALushort Conv_ALushort_ALubyte3(ALubyte3 val) { return DecodeUByte3(val)>>8; } -static __inline ALint Conv_ALint_ALbyte(ALbyte val) +static inline ALint Conv_ALint_ALbyte(ALbyte val) { return val<<24; } -static __inline ALint Conv_ALint_ALubyte(ALubyte val) +static inline ALint Conv_ALint_ALubyte(ALubyte val) { return (val-128)<<24; } -static __inline ALint Conv_ALint_ALshort(ALshort val) +static inline ALint Conv_ALint_ALshort(ALshort val) { return val<<16; } -static __inline ALint Conv_ALint_ALushort(ALushort val) +static inline ALint Conv_ALint_ALushort(ALushort val) { return (val-32768)<<16; } -static __inline ALint Conv_ALint_ALint(ALint val) +static inline ALint Conv_ALint_ALint(ALint val) { return val; } -static __inline ALint Conv_ALint_ALuint(ALuint val) +static inline ALint Conv_ALint_ALuint(ALuint val) { return val-2147483648u; } -static __inline ALint Conv_ALint_ALfloat(ALfloat val) +static inline ALint Conv_ALint_ALfloat(ALfloat val) { if(val > 1.0f) return 2147483647; if(val < -1.0f) return -2147483647-1; - return (ALint)(val * 2147483647.0); + return (ALint)(val*16777215.0f) << 7; } -static __inline ALint Conv_ALint_ALdouble(ALdouble val) +static inline ALint Conv_ALint_ALdouble(ALdouble val) { if(val > 1.0) return 2147483647; if(val < -1.0) return -2147483647-1; return (ALint)(val * 2147483647.0); } -static __inline ALint Conv_ALint_ALmulaw(ALmulaw val) +static inline ALint Conv_ALint_ALmulaw(ALmulaw val) { return Conv_ALint_ALshort(DecodeMuLaw(val)); } -static __inline ALint Conv_ALint_ALalaw(ALalaw val) +static inline ALint Conv_ALint_ALalaw(ALalaw val) { return Conv_ALint_ALshort(DecodeALaw(val)); } -static __inline ALint Conv_ALint_ALbyte3(ALbyte3 val) +static inline ALint Conv_ALint_ALbyte3(ALbyte3 val) { return DecodeByte3(val)<<8; } -static __inline ALint Conv_ALint_ALubyte3(ALubyte3 val) +static inline ALint Conv_ALint_ALubyte3(ALubyte3 val) { return (DecodeUByte3(val)-8388608)<<8; } -static __inline ALuint Conv_ALuint_ALbyte(ALbyte val) +static inline ALuint Conv_ALuint_ALbyte(ALbyte val) { return (val+128)<<24; } -static __inline ALuint Conv_ALuint_ALubyte(ALubyte val) +static inline ALuint Conv_ALuint_ALubyte(ALubyte val) { return val<<24; } -static __inline ALuint Conv_ALuint_ALshort(ALshort val) +static inline ALuint Conv_ALuint_ALshort(ALshort val) { return (val+32768)<<16; } -static __inline ALuint Conv_ALuint_ALushort(ALushort val) +static inline ALuint Conv_ALuint_ALushort(ALushort val) { return val<<16; } -static __inline ALuint Conv_ALuint_ALint(ALint val) +static inline ALuint Conv_ALuint_ALint(ALint val) { return val+2147483648u; } -static __inline ALuint Conv_ALuint_ALuint(ALuint val) +static inline ALuint Conv_ALuint_ALuint(ALuint val) { return val; } -static __inline ALuint Conv_ALuint_ALfloat(ALfloat val) +static inline ALuint Conv_ALuint_ALfloat(ALfloat val) { if(val > 1.0f) return 4294967295u; if(val < -1.0f) return 0; - return (ALint)(val * 2147483647.0) + 2147483648u; + return ((ALint)(val*16777215.0f)<<7) + 2147483648u; } -static __inline ALuint Conv_ALuint_ALdouble(ALdouble val) +static inline ALuint Conv_ALuint_ALdouble(ALdouble val) { if(val > 1.0) return 4294967295u; if(val < -1.0) return 0; return (ALint)(val * 2147483647.0) + 2147483648u; } -static __inline ALuint Conv_ALuint_ALmulaw(ALmulaw val) +static inline ALuint Conv_ALuint_ALmulaw(ALmulaw val) { return Conv_ALuint_ALshort(DecodeMuLaw(val)); } -static __inline ALuint Conv_ALuint_ALalaw(ALalaw val) +static inline ALuint Conv_ALuint_ALalaw(ALalaw val) { return Conv_ALuint_ALshort(DecodeALaw(val)); } -static __inline ALuint Conv_ALuint_ALbyte3(ALbyte3 val) +static inline ALuint Conv_ALuint_ALbyte3(ALbyte3 val) { return (DecodeByte3(val)+8388608)<<8; } -static __inline ALuint Conv_ALuint_ALubyte3(ALubyte3 val) +static inline ALuint Conv_ALuint_ALubyte3(ALubyte3 val) { return DecodeUByte3(val)<<8; } -static __inline ALfloat Conv_ALfloat_ALbyte(ALbyte val) +static inline ALfloat Conv_ALfloat_ALbyte(ALbyte val) { return val * (1.0f/127.0f); } -static __inline ALfloat Conv_ALfloat_ALubyte(ALubyte val) +static inline ALfloat Conv_ALfloat_ALubyte(ALubyte val) { return (val-128) * (1.0f/127.0f); } -static __inline ALfloat Conv_ALfloat_ALshort(ALshort val) +static inline ALfloat Conv_ALfloat_ALshort(ALshort val) { return val * (1.0f/32767.0f); } -static __inline ALfloat Conv_ALfloat_ALushort(ALushort val) +static inline ALfloat Conv_ALfloat_ALushort(ALushort val) { return (val-32768) * (1.0f/32767.0f); } -static __inline ALfloat Conv_ALfloat_ALint(ALint val) +static inline ALfloat Conv_ALfloat_ALint(ALint val) { return (ALfloat)(val * (1.0/2147483647.0)); } -static __inline ALfloat Conv_ALfloat_ALuint(ALuint val) +static inline ALfloat Conv_ALfloat_ALuint(ALuint val) { return (ALfloat)((ALint)(val-2147483648u) * (1.0/2147483647.0)); } -static __inline ALfloat Conv_ALfloat_ALfloat(ALfloat val) +static inline ALfloat Conv_ALfloat_ALfloat(ALfloat val) { return (val==val) ? val : 0.0f; } -static __inline ALfloat Conv_ALfloat_ALdouble(ALdouble val) +static inline ALfloat Conv_ALfloat_ALdouble(ALdouble val) { return (val==val) ? (ALfloat)val : 0.0f; } -static __inline ALfloat Conv_ALfloat_ALmulaw(ALmulaw val) +static inline ALfloat Conv_ALfloat_ALmulaw(ALmulaw val) { return Conv_ALfloat_ALshort(DecodeMuLaw(val)); } -static __inline ALfloat Conv_ALfloat_ALalaw(ALalaw val) +static inline ALfloat Conv_ALfloat_ALalaw(ALalaw val) { return Conv_ALfloat_ALshort(DecodeALaw(val)); } -static __inline ALfloat Conv_ALfloat_ALbyte3(ALbyte3 val) +static inline ALfloat Conv_ALfloat_ALbyte3(ALbyte3 val) { return (ALfloat)(DecodeByte3(val) * (1.0/8388607.0)); } -static __inline ALfloat Conv_ALfloat_ALubyte3(ALubyte3 val) +static inline ALfloat Conv_ALfloat_ALubyte3(ALubyte3 val) { return (ALfloat)((DecodeUByte3(val)-8388608) * (1.0/8388607.0)); } -static __inline ALdouble Conv_ALdouble_ALbyte(ALbyte val) +static inline ALdouble Conv_ALdouble_ALbyte(ALbyte val) { return val * (1.0/127.0); } -static __inline ALdouble Conv_ALdouble_ALubyte(ALubyte val) +static inline ALdouble Conv_ALdouble_ALubyte(ALubyte val) { return (val-128) * (1.0/127.0); } -static __inline ALdouble Conv_ALdouble_ALshort(ALshort val) +static inline ALdouble Conv_ALdouble_ALshort(ALshort val) { return val * (1.0/32767.0); } -static __inline ALdouble Conv_ALdouble_ALushort(ALushort val) +static inline ALdouble Conv_ALdouble_ALushort(ALushort val) { return (val-32768) * (1.0/32767.0); } -static __inline ALdouble Conv_ALdouble_ALint(ALint val) +static inline ALdouble Conv_ALdouble_ALint(ALint val) { return val * (1.0/2147483647.0); } -static __inline ALdouble Conv_ALdouble_ALuint(ALuint val) +static inline ALdouble Conv_ALdouble_ALuint(ALuint val) { return (ALint)(val-2147483648u) * (1.0/2147483647.0); } -static __inline ALdouble Conv_ALdouble_ALfloat(ALfloat val) +static inline ALdouble Conv_ALdouble_ALfloat(ALfloat val) { return (val==val) ? val : 0.0f; } -static __inline ALdouble Conv_ALdouble_ALdouble(ALdouble val) +static inline ALdouble Conv_ALdouble_ALdouble(ALdouble val) { return (val==val) ? val : 0.0; } -static __inline ALdouble Conv_ALdouble_ALmulaw(ALmulaw val) +static inline ALdouble Conv_ALdouble_ALmulaw(ALmulaw val) { return Conv_ALdouble_ALshort(DecodeMuLaw(val)); } -static __inline ALdouble Conv_ALdouble_ALalaw(ALalaw val) +static inline ALdouble Conv_ALdouble_ALalaw(ALalaw val) { return Conv_ALdouble_ALshort(DecodeALaw(val)); } -static __inline ALdouble Conv_ALdouble_ALbyte3(ALbyte3 val) +static inline ALdouble Conv_ALdouble_ALbyte3(ALbyte3 val) { return DecodeByte3(val) * (1.0/8388607.0); } -static __inline ALdouble Conv_ALdouble_ALubyte3(ALubyte3 val) +static inline ALdouble Conv_ALdouble_ALubyte3(ALubyte3 val) { return (DecodeUByte3(val)-8388608) * (1.0/8388607.0); } #define DECL_TEMPLATE(T) \ -static __inline ALmulaw Conv_ALmulaw_##T(T val) \ +static inline ALmulaw Conv_ALmulaw_##T(T val) \ { return EncodeMuLaw(Conv_ALshort_##T(val)); } DECL_TEMPLATE(ALbyte) @@ -1506,7 +1476,7 @@ DECL_TEMPLATE(ALint) DECL_TEMPLATE(ALuint) DECL_TEMPLATE(ALfloat) DECL_TEMPLATE(ALdouble) -static __inline ALmulaw Conv_ALmulaw_ALmulaw(ALmulaw val) +static inline ALmulaw Conv_ALmulaw_ALmulaw(ALmulaw val) { return val; } DECL_TEMPLATE(ALalaw) DECL_TEMPLATE(ALbyte3) @@ -1515,7 +1485,7 @@ DECL_TEMPLATE(ALubyte3) #undef DECL_TEMPLATE #define DECL_TEMPLATE(T) \ -static __inline ALalaw Conv_ALalaw_##T(T val) \ +static inline ALalaw Conv_ALalaw_##T(T val) \ { return EncodeALaw(Conv_ALshort_##T(val)); } DECL_TEMPLATE(ALbyte) @@ -1527,7 +1497,7 @@ DECL_TEMPLATE(ALuint) DECL_TEMPLATE(ALfloat) DECL_TEMPLATE(ALdouble) DECL_TEMPLATE(ALmulaw) -static __inline ALalaw Conv_ALalaw_ALalaw(ALalaw val) +static inline ALalaw Conv_ALalaw_ALalaw(ALalaw val) { return val; } DECL_TEMPLATE(ALbyte3) DECL_TEMPLATE(ALubyte3) @@ -1535,7 +1505,7 @@ DECL_TEMPLATE(ALubyte3) #undef DECL_TEMPLATE #define DECL_TEMPLATE(T) \ -static __inline ALbyte3 Conv_ALbyte3_##T(T val) \ +static inline ALbyte3 Conv_ALbyte3_##T(T val) \ { return EncodeByte3(Conv_ALint_##T(val)>>8); } DECL_TEMPLATE(ALbyte) @@ -1548,14 +1518,14 @@ DECL_TEMPLATE(ALfloat) DECL_TEMPLATE(ALdouble) DECL_TEMPLATE(ALmulaw) DECL_TEMPLATE(ALalaw) -static __inline ALbyte3 Conv_ALbyte3_ALbyte3(ALbyte3 val) +static inline ALbyte3 Conv_ALbyte3_ALbyte3(ALbyte3 val) { return val; } DECL_TEMPLATE(ALubyte3) #undef DECL_TEMPLATE #define DECL_TEMPLATE(T) \ -static __inline ALubyte3 Conv_ALubyte3_##T(T val) \ +static inline ALubyte3 Conv_ALubyte3_##T(T val) \ { return EncodeUByte3(Conv_ALuint_##T(val)>>8); } DECL_TEMPLATE(ALbyte) @@ -1569,7 +1539,7 @@ DECL_TEMPLATE(ALdouble) DECL_TEMPLATE(ALmulaw) DECL_TEMPLATE(ALalaw) DECL_TEMPLATE(ALbyte3) -static __inline ALubyte3 Conv_ALubyte3_ALubyte3(ALubyte3 val) +static inline ALubyte3 Conv_ALubyte3_ALubyte3(ALubyte3 val) { return val; } #undef DECL_TEMPLATE @@ -1749,7 +1719,7 @@ DECL_TEMPLATE(ALubyte3, ALubyte3) static void Convert_##T##_ALima4(T *dst, const ALima4 *src, ALuint numchans, \ ALuint len) \ { \ - ALshort tmp[65*MaxChannels]; /* Max samples an IMA4 frame can be */ \ + ALshort tmp[65*MAX_INPUT_CHANNELS]; /* Max samples an IMA4 frame can be */\ ALuint i, j, k; \ \ i = 0; \ @@ -1785,7 +1755,7 @@ DECL_TEMPLATE(ALubyte3) static void Convert_ALima4_##T(ALima4 *dst, const T *src, ALuint numchans, \ ALuint len) \ { \ - ALshort tmp[65*MaxChannels]; /* Max samples an IMA4 frame can be */ \ + ALshort tmp[65*MAX_INPUT_CHANNELS]; /* Max samples an IMA4 frame can be */\ ALint sample[MaxChannels] = {0,0,0,0,0,0,0,0}; \ ALint index[MaxChannels] = {0,0,0,0,0,0,0,0}; \ ALuint i, j; \ @@ -1973,7 +1943,7 @@ static ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei f ALBuf->data = temp; if(data != NULL) - ConvertData(ALBuf->data, DstType, data, SrcType, NewChannels, frames); + ConvertData(ALBuf->data, (enum UserFmtType)DstType, data, SrcType, NewChannels, frames); if(storesrc) { @@ -1986,8 +1956,8 @@ static ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei f } else { - ALBuf->OriginalChannels = DstChannels; - ALBuf->OriginalType = DstType; + ALBuf->OriginalChannels = (enum UserFmtChannels)DstChannels; + ALBuf->OriginalType = (enum UserFmtType)DstType; ALBuf->OriginalSize = frames * NewBytes * NewChannels; } diff --git a/OpenAL32/alEffect.c b/OpenAL32/alEffect.c index 4d257641..c9e5928f 100644 --- a/OpenAL32/alEffect.c +++ b/OpenAL32/alEffect.c @@ -34,91 +34,88 @@ ALboolean DisabledEffects[MAX_EFFECTS]; +extern inline struct ALeffect *LookupEffect(ALCdevice *device, ALuint id); +extern inline struct ALeffect *RemoveEffect(ALCdevice *device, ALuint id); +extern inline ALboolean IsReverbEffect(ALenum type); static void InitEffectParams(ALeffect *effect, ALenum type); AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects) { - ALCcontext *Context; - ALsizei cur = 0; + ALCdevice *device; + ALCcontext *context; + ALsizei cur; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try - { - ALCdevice *device = Context->Device; - ALenum err; + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - CHECK_VALUE(Context, n >= 0); - for(cur = 0;cur < n;cur++) + device = context->Device; + for(cur = 0;cur < n;cur++) + { + ALeffect *effect = calloc(1, sizeof(ALeffect)); + ALenum err = AL_OUT_OF_MEMORY; + if(!effect || (err=InitEffect(effect)) != AL_NO_ERROR) { - ALeffect *effect = calloc(1, sizeof(ALeffect)); - err = AL_OUT_OF_MEMORY; - if(!effect || (err=InitEffect(effect)) != AL_NO_ERROR) - { - free(effect); - al_throwerr(Context, err); - } - - err = NewThunkEntry(&effect->id); - if(err == AL_NO_ERROR) - err = InsertUIntMapEntry(&device->EffectMap, effect->id, effect); - if(err != AL_NO_ERROR) - { - FreeThunkEntry(effect->id); - memset(effect, 0, sizeof(ALeffect)); - free(effect); + free(effect); + alDeleteEffects(cur, effects); + SET_ERROR_AND_GOTO(context, err, done); + } - al_throwerr(Context, err); - } + err = NewThunkEntry(&effect->id); + if(err == AL_NO_ERROR) + err = InsertUIntMapEntry(&device->EffectMap, effect->id, effect); + if(err != AL_NO_ERROR) + { + FreeThunkEntry(effect->id); + memset(effect, 0, sizeof(ALeffect)); + free(effect); - effects[cur] = effect->id; - } - } - al_catchany() - { - if(cur > 0) alDeleteEffects(cur, effects); + SET_ERROR_AND_GOTO(context, err, done); + } + + effects[cur] = effect->id; } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects) { - ALCcontext *Context; - ALeffect *Effect; + ALCdevice *device; + ALCcontext *context; + ALeffect *effect; ALsizei i; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try - { - ALCdevice *device = Context->Device; - CHECK_VALUE(Context, n >= 0); - for(i = 0;i < n;i++) - { - if(effects[i] && LookupEffect(device, effects[i]) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - } + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - for(i = 0;i < n;i++) - { - if((Effect=RemoveEffect(device, effects[i])) == NULL) - continue; - FreeThunkEntry(Effect->id); + device = context->Device; + for(i = 0;i < n;i++) + { + if(effects[i] && LookupEffect(device, effects[i]) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + } + for(i = 0;i < n;i++) + { + if((effect=RemoveEffect(device, effects[i])) == NULL) + continue; + FreeThunkEntry(effect->id); - memset(Effect, 0, sizeof(*Effect)); - free(Effect); - } + memset(effect, 0, sizeof(*effect)); + free(effect); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect) @@ -170,7 +167,7 @@ AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint value) else { /* Call the appropriate handler */ - ALeffect_SetParami(ALEffect, Context, param, value); + V(ALEffect,setParami)(Context, param, value); } } @@ -199,7 +196,7 @@ AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *v else { /* Call the appropriate handler */ - ALeffect_SetParamiv(ALEffect, Context, param, values); + V(ALEffect,setParamiv)(Context, param, values); } ALCcontext_DecRef(Context); @@ -220,7 +217,7 @@ AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat value) else { /* Call the appropriate handler */ - ALeffect_SetParamf(ALEffect, Context, param, value); + V(ALEffect,setParamf)(Context, param, value); } ALCcontext_DecRef(Context); @@ -241,7 +238,7 @@ AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat else { /* Call the appropriate handler */ - ALeffect_SetParamfv(ALEffect, Context, param, values); + V(ALEffect,setParamfv)(Context, param, values); } ALCcontext_DecRef(Context); @@ -266,7 +263,7 @@ AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *value else { /* Call the appropriate handler */ - ALeffect_GetParami(ALEffect, Context, param, value); + V(ALEffect,getParami)(Context, param, value); } } @@ -295,7 +292,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *valu else { /* Call the appropriate handler */ - ALeffect_GetParamiv(ALEffect, Context, param, values); + V(ALEffect,getParamiv)(Context, param, values); } ALCcontext_DecRef(Context); @@ -316,7 +313,7 @@ AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *val else { /* Call the appropriate handler */ - ALeffect_GetParamf(ALEffect, Context, param, value); + V(ALEffect,getParamf)(Context, param, value); } ALCcontext_DecRef(Context); @@ -337,847 +334,13 @@ AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *va else { /* Call the appropriate handler */ - ALeffect_GetParamfv(ALEffect, Context, param, values); + V(ALEffect,getParamfv)(Context, param, values); } ALCcontext_DecRef(Context); } -static void eaxreverb_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) -{ - switch(param) - { - case AL_EAXREVERB_DECAY_HFLIMIT: - if(val >= AL_EAXREVERB_MIN_DECAY_HFLIMIT && val <= AL_EAXREVERB_MAX_DECAY_HFLIMIT) - effect->Reverb.DecayHFLimit = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void eaxreverb_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - eaxreverb_SetParami(effect, context, param, vals[0]); -} -static void eaxreverb_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ - switch(param) - { - case AL_EAXREVERB_DENSITY: - if(val >= AL_EAXREVERB_MIN_DENSITY && - val <= AL_EAXREVERB_MAX_DENSITY) - effect->Reverb.Density = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_DIFFUSION: - if(val >= AL_EAXREVERB_MIN_DIFFUSION && - val <= AL_EAXREVERB_MAX_DIFFUSION) - effect->Reverb.Diffusion = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_GAIN: - if(val >= AL_EAXREVERB_MIN_GAIN && - val <= AL_EAXREVERB_MAX_GAIN) - effect->Reverb.Gain = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_GAINHF: - if(val >= AL_EAXREVERB_MIN_GAINHF && - val <= AL_EAXREVERB_MAX_GAINHF) - effect->Reverb.GainHF = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_GAINLF: - if(val >= AL_EAXREVERB_MIN_GAINLF && - val <= AL_EAXREVERB_MAX_GAINLF) - effect->Reverb.GainLF = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_DECAY_TIME: - if(val >= AL_EAXREVERB_MIN_DECAY_TIME && - val <= AL_EAXREVERB_MAX_DECAY_TIME) - effect->Reverb.DecayTime = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_DECAY_HFRATIO: - if(val >= AL_EAXREVERB_MIN_DECAY_HFRATIO && - val <= AL_EAXREVERB_MAX_DECAY_HFRATIO) - effect->Reverb.DecayHFRatio = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_DECAY_LFRATIO: - if(val >= AL_EAXREVERB_MIN_DECAY_LFRATIO && - val <= AL_EAXREVERB_MAX_DECAY_LFRATIO) - effect->Reverb.DecayLFRatio = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_REFLECTIONS_GAIN: - if(val >= AL_EAXREVERB_MIN_REFLECTIONS_GAIN && - val <= AL_EAXREVERB_MAX_REFLECTIONS_GAIN) - effect->Reverb.ReflectionsGain = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_REFLECTIONS_DELAY: - if(val >= AL_EAXREVERB_MIN_REFLECTIONS_DELAY && - val <= AL_EAXREVERB_MAX_REFLECTIONS_DELAY) - effect->Reverb.ReflectionsDelay = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_LATE_REVERB_GAIN: - if(val >= AL_EAXREVERB_MIN_LATE_REVERB_GAIN && - val <= AL_EAXREVERB_MAX_LATE_REVERB_GAIN) - effect->Reverb.LateReverbGain = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_LATE_REVERB_DELAY: - if(val >= AL_EAXREVERB_MIN_LATE_REVERB_DELAY && - val <= AL_EAXREVERB_MAX_LATE_REVERB_DELAY) - effect->Reverb.LateReverbDelay = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_AIR_ABSORPTION_GAINHF: - if(val >= AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF && - val <= AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF) - effect->Reverb.AirAbsorptionGainHF = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_ECHO_TIME: - if(val >= AL_EAXREVERB_MIN_ECHO_TIME && - val <= AL_EAXREVERB_MAX_ECHO_TIME) - effect->Reverb.EchoTime = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_ECHO_DEPTH: - if(val >= AL_EAXREVERB_MIN_ECHO_DEPTH && - val <= AL_EAXREVERB_MAX_ECHO_DEPTH) - effect->Reverb.EchoDepth = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_MODULATION_TIME: - if(val >= AL_EAXREVERB_MIN_MODULATION_TIME && - val <= AL_EAXREVERB_MAX_MODULATION_TIME) - effect->Reverb.ModulationTime = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_MODULATION_DEPTH: - if(val >= AL_EAXREVERB_MIN_MODULATION_DEPTH && - val <= AL_EAXREVERB_MAX_MODULATION_DEPTH) - effect->Reverb.ModulationDepth = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_HFREFERENCE: - if(val >= AL_EAXREVERB_MIN_HFREFERENCE && - val <= AL_EAXREVERB_MAX_HFREFERENCE) - effect->Reverb.HFReference = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_LFREFERENCE: - if(val >= AL_EAXREVERB_MIN_LFREFERENCE && - val <= AL_EAXREVERB_MAX_LFREFERENCE) - effect->Reverb.LFReference = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR: - if(val >= 0.0f && val <= 10.0f) - effect->Reverb.RoomRolloffFactor = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void eaxreverb_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - switch(param) - { - case AL_EAXREVERB_REFLECTIONS_PAN: - if(isfinite(vals[0]) && isfinite(vals[1]) && isfinite(vals[2])) - { - LockContext(context); - effect->Reverb.ReflectionsPan[0] = vals[0]; - effect->Reverb.ReflectionsPan[1] = vals[1]; - effect->Reverb.ReflectionsPan[2] = vals[2]; - UnlockContext(context); - } - else - alSetError(context, AL_INVALID_VALUE); - break; - case AL_EAXREVERB_LATE_REVERB_PAN: - if(isfinite(vals[0]) && isfinite(vals[1]) && isfinite(vals[2])) - { - LockContext(context); - effect->Reverb.LateReverbPan[0] = vals[0]; - effect->Reverb.LateReverbPan[1] = vals[1]; - effect->Reverb.LateReverbPan[2] = vals[2]; - UnlockContext(context); - } - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - eaxreverb_SetParamf(effect, context, param, vals[0]); - break; - } -} - -static void eaxreverb_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) -{ - switch(param) - { - case AL_EAXREVERB_DECAY_HFLIMIT: - *val = effect->Reverb.DecayHFLimit; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void eaxreverb_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - eaxreverb_GetParami(effect, context, param, vals); -} -static void eaxreverb_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ - switch(param) - { - case AL_EAXREVERB_DENSITY: - *val = effect->Reverb.Density; - break; - - case AL_EAXREVERB_DIFFUSION: - *val = effect->Reverb.Diffusion; - break; - - case AL_EAXREVERB_GAIN: - *val = effect->Reverb.Gain; - break; - - case AL_EAXREVERB_GAINHF: - *val = effect->Reverb.GainHF; - break; - - case AL_EAXREVERB_GAINLF: - *val = effect->Reverb.GainLF; - break; - - case AL_EAXREVERB_DECAY_TIME: - *val = effect->Reverb.DecayTime; - break; - - case AL_EAXREVERB_DECAY_HFRATIO: - *val = effect->Reverb.DecayHFRatio; - break; - - case AL_EAXREVERB_DECAY_LFRATIO: - *val = effect->Reverb.DecayLFRatio; - break; - - case AL_EAXREVERB_REFLECTIONS_GAIN: - *val = effect->Reverb.ReflectionsGain; - break; - - case AL_EAXREVERB_REFLECTIONS_DELAY: - *val = effect->Reverb.ReflectionsDelay; - break; - - case AL_EAXREVERB_LATE_REVERB_GAIN: - *val = effect->Reverb.LateReverbGain; - break; - - case AL_EAXREVERB_LATE_REVERB_DELAY: - *val = effect->Reverb.LateReverbDelay; - break; - - case AL_EAXREVERB_AIR_ABSORPTION_GAINHF: - *val = effect->Reverb.AirAbsorptionGainHF; - break; - - case AL_EAXREVERB_ECHO_TIME: - *val = effect->Reverb.EchoTime; - break; - - case AL_EAXREVERB_ECHO_DEPTH: - *val = effect->Reverb.EchoDepth; - break; - - case AL_EAXREVERB_MODULATION_TIME: - *val = effect->Reverb.ModulationTime; - break; - - case AL_EAXREVERB_MODULATION_DEPTH: - *val = effect->Reverb.ModulationDepth; - break; - - case AL_EAXREVERB_HFREFERENCE: - *val = effect->Reverb.HFReference; - break; - - case AL_EAXREVERB_LFREFERENCE: - *val = effect->Reverb.LFReference; - break; - - case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR: - *val = effect->Reverb.RoomRolloffFactor; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void eaxreverb_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - switch(param) - { - case AL_EAXREVERB_REFLECTIONS_PAN: - LockContext(context); - vals[0] = effect->Reverb.ReflectionsPan[0]; - vals[1] = effect->Reverb.ReflectionsPan[1]; - vals[2] = effect->Reverb.ReflectionsPan[2]; - UnlockContext(context); - break; - case AL_EAXREVERB_LATE_REVERB_PAN: - LockContext(context); - vals[0] = effect->Reverb.LateReverbPan[0]; - vals[1] = effect->Reverb.LateReverbPan[1]; - vals[2] = effect->Reverb.LateReverbPan[2]; - UnlockContext(context); - break; - - default: - eaxreverb_GetParamf(effect, context, param, vals); - break; - } -} - - -static void reverb_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) -{ - switch(param) - { - case AL_REVERB_DECAY_HFLIMIT: - if(val >= AL_REVERB_MIN_DECAY_HFLIMIT && - val <= AL_REVERB_MAX_DECAY_HFLIMIT) - effect->Reverb.DecayHFLimit = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void reverb_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - reverb_SetParami(effect, context, param, vals[0]); -} -static void reverb_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ - switch(param) - { - case AL_REVERB_DENSITY: - if(val >= AL_REVERB_MIN_DENSITY && - val <= AL_REVERB_MAX_DENSITY) - effect->Reverb.Density = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_DIFFUSION: - if(val >= AL_REVERB_MIN_DIFFUSION && - val <= AL_REVERB_MAX_DIFFUSION) - effect->Reverb.Diffusion = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_GAIN: - if(val >= AL_REVERB_MIN_GAIN && - val <= AL_REVERB_MAX_GAIN) - effect->Reverb.Gain = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_GAINHF: - if(val >= AL_REVERB_MIN_GAINHF && - val <= AL_REVERB_MAX_GAINHF) - effect->Reverb.GainHF = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_DECAY_TIME: - if(val >= AL_REVERB_MIN_DECAY_TIME && - val <= AL_REVERB_MAX_DECAY_TIME) - effect->Reverb.DecayTime = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_DECAY_HFRATIO: - if(val >= AL_REVERB_MIN_DECAY_HFRATIO && - val <= AL_REVERB_MAX_DECAY_HFRATIO) - effect->Reverb.DecayHFRatio = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_REFLECTIONS_GAIN: - if(val >= AL_REVERB_MIN_REFLECTIONS_GAIN && - val <= AL_REVERB_MAX_REFLECTIONS_GAIN) - effect->Reverb.ReflectionsGain = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_REFLECTIONS_DELAY: - if(val >= AL_REVERB_MIN_REFLECTIONS_DELAY && - val <= AL_REVERB_MAX_REFLECTIONS_DELAY) - effect->Reverb.ReflectionsDelay = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_LATE_REVERB_GAIN: - if(val >= AL_REVERB_MIN_LATE_REVERB_GAIN && - val <= AL_REVERB_MAX_LATE_REVERB_GAIN) - effect->Reverb.LateReverbGain = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_LATE_REVERB_DELAY: - if(val >= AL_REVERB_MIN_LATE_REVERB_DELAY && - val <= AL_REVERB_MAX_LATE_REVERB_DELAY) - effect->Reverb.LateReverbDelay = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_AIR_ABSORPTION_GAINHF: - if(val >= AL_REVERB_MIN_AIR_ABSORPTION_GAINHF && - val <= AL_REVERB_MAX_AIR_ABSORPTION_GAINHF) - effect->Reverb.AirAbsorptionGainHF = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_REVERB_ROOM_ROLLOFF_FACTOR: - if(val >= AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR && - val <= AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR) - effect->Reverb.RoomRolloffFactor = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void reverb_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - reverb_SetParamf(effect, context, param, vals[0]); -} - -static void reverb_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) -{ - switch(param) - { - case AL_REVERB_DECAY_HFLIMIT: - *val = effect->Reverb.DecayHFLimit; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void reverb_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - reverb_GetParami(effect, context, param, vals); -} -static void reverb_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ - switch(param) - { - case AL_REVERB_DENSITY: - *val = effect->Reverb.Density; - break; - - case AL_REVERB_DIFFUSION: - *val = effect->Reverb.Diffusion; - break; - - case AL_REVERB_GAIN: - *val = effect->Reverb.Gain; - break; - - case AL_REVERB_GAINHF: - *val = effect->Reverb.GainHF; - break; - - case AL_REVERB_DECAY_TIME: - *val = effect->Reverb.DecayTime; - break; - - case AL_REVERB_DECAY_HFRATIO: - *val = effect->Reverb.DecayHFRatio; - break; - - case AL_REVERB_REFLECTIONS_GAIN: - *val = effect->Reverb.ReflectionsGain; - break; - - case AL_REVERB_REFLECTIONS_DELAY: - *val = effect->Reverb.ReflectionsDelay; - break; - - case AL_REVERB_LATE_REVERB_GAIN: - *val = effect->Reverb.LateReverbGain; - break; - - case AL_REVERB_LATE_REVERB_DELAY: - *val = effect->Reverb.LateReverbDelay; - break; - - case AL_REVERB_AIR_ABSORPTION_GAINHF: - *val = effect->Reverb.AirAbsorptionGainHF; - break; - - case AL_REVERB_ROOM_ROLLOFF_FACTOR: - *val = effect->Reverb.RoomRolloffFactor; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void reverb_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - reverb_GetParamf(effect, context, param, vals); -} - - -static void echo_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) -{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void echo_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - echo_SetParami(effect, context, param, vals[0]); -} -static void echo_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ - switch(param) - { - case AL_ECHO_DELAY: - if(val >= AL_ECHO_MIN_DELAY && val <= AL_ECHO_MAX_DELAY) - effect->Echo.Delay = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_ECHO_LRDELAY: - if(val >= AL_ECHO_MIN_LRDELAY && val <= AL_ECHO_MAX_LRDELAY) - effect->Echo.LRDelay = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_ECHO_DAMPING: - if(val >= AL_ECHO_MIN_DAMPING && val <= AL_ECHO_MAX_DAMPING) - effect->Echo.Damping = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_ECHO_FEEDBACK: - if(val >= AL_ECHO_MIN_FEEDBACK && val <= AL_ECHO_MAX_FEEDBACK) - effect->Echo.Feedback = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_ECHO_SPREAD: - if(val >= AL_ECHO_MIN_SPREAD && val <= AL_ECHO_MAX_SPREAD) - effect->Echo.Spread = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void echo_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - echo_SetParamf(effect, context, param, vals[0]); -} - -static void echo_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) -{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void echo_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - echo_GetParami(effect, context, param, vals); -} -static void echo_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ - switch(param) - { - case AL_ECHO_DELAY: - *val = effect->Echo.Delay; - break; - - case AL_ECHO_LRDELAY: - *val = effect->Echo.LRDelay; - break; - - case AL_ECHO_DAMPING: - *val = effect->Echo.Damping; - break; - - case AL_ECHO_FEEDBACK: - *val = effect->Echo.Feedback; - break; - - case AL_ECHO_SPREAD: - *val = effect->Echo.Spread; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void echo_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - echo_GetParamf(effect, context, param, vals); -} - - -static void mod_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ - switch(param) - { - case AL_RING_MODULATOR_FREQUENCY: - if(val >= AL_RING_MODULATOR_MIN_FREQUENCY && - val <= AL_RING_MODULATOR_MAX_FREQUENCY) - effect->Modulator.Frequency = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - case AL_RING_MODULATOR_HIGHPASS_CUTOFF: - if(val >= AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF && - val <= AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF) - effect->Modulator.HighPassCutoff = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void mod_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - mod_SetParamf(effect, context, param, vals[0]); -} -static void mod_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) -{ - switch(param) - { - case AL_RING_MODULATOR_FREQUENCY: - case AL_RING_MODULATOR_HIGHPASS_CUTOFF: - mod_SetParamf(effect, context, param, (ALfloat)val); - break; - - case AL_RING_MODULATOR_WAVEFORM: - if(val >= AL_RING_MODULATOR_MIN_WAVEFORM && - val <= AL_RING_MODULATOR_MAX_WAVEFORM) - effect->Modulator.Waveform = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void mod_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - mod_SetParami(effect, context, param, vals[0]); -} - -static void mod_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) -{ - switch(param) - { - case AL_RING_MODULATOR_FREQUENCY: - *val = (ALint)effect->Modulator.Frequency; - break; - case AL_RING_MODULATOR_HIGHPASS_CUTOFF: - *val = (ALint)effect->Modulator.HighPassCutoff; - break; - case AL_RING_MODULATOR_WAVEFORM: - *val = effect->Modulator.Waveform; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void mod_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - mod_GetParami(effect, context, param, vals); -} -static void mod_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ - switch(param) - { - case AL_RING_MODULATOR_FREQUENCY: - *val = effect->Modulator.Frequency; - break; - case AL_RING_MODULATOR_HIGHPASS_CUTOFF: - *val = effect->Modulator.HighPassCutoff; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void mod_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - mod_GetParamf(effect, context, param, vals); -} - - -static void ded_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) -{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void ded_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - ded_SetParami(effect, context, param, vals[0]); -} -static void ded_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ - switch(param) - { - case AL_DEDICATED_GAIN: - if(val >= 0.0f && isfinite(val)) - effect->Dedicated.Gain = val; - else - alSetError(context, AL_INVALID_VALUE); - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void ded_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - ded_SetParamf(effect, context, param, vals[0]); -} - -static void ded_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) -{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void ded_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - ded_GetParami(effect, context, param, vals); -} -static void ded_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ - switch(param) - { - case AL_DEDICATED_GAIN: - *val = effect->Dedicated.Gain; - break; - - default: - alSetError(context, AL_INVALID_ENUM); - break; - } -} -static void ded_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - ded_GetParamf(effect, context, param, vals); -} - - -static void null_SetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) -{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void null_SetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ (void)effect;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); } -static void null_SetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void null_SetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ (void)effect;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); } - -static void null_GetParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) -{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void null_GetParamiv(ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ (void)effect;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); } -static void null_GetParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ (void)effect;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void null_GetParamfv(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ (void)effect;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); } - - ALenum InitEffect(ALeffect *effect) { InitEffectParams(effect, AL_EFFECT_NULL); @@ -1205,114 +368,122 @@ static void InitEffectParams(ALeffect *effect, ALenum type) switch(type) { case AL_EFFECT_EAXREVERB: - effect->Reverb.Density = AL_EAXREVERB_DEFAULT_DENSITY; - effect->Reverb.Diffusion = AL_EAXREVERB_DEFAULT_DIFFUSION; - effect->Reverb.Gain = AL_EAXREVERB_DEFAULT_GAIN; - effect->Reverb.GainHF = AL_EAXREVERB_DEFAULT_GAINHF; - effect->Reverb.GainLF = AL_EAXREVERB_DEFAULT_GAINLF; - effect->Reverb.DecayTime = AL_EAXREVERB_DEFAULT_DECAY_TIME; - effect->Reverb.DecayHFRatio = AL_EAXREVERB_DEFAULT_DECAY_HFRATIO; - effect->Reverb.DecayLFRatio = AL_EAXREVERB_DEFAULT_DECAY_LFRATIO; - effect->Reverb.ReflectionsGain = AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN; - effect->Reverb.ReflectionsDelay = AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY; - effect->Reverb.ReflectionsPan[0] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ; - effect->Reverb.ReflectionsPan[1] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ; - effect->Reverb.ReflectionsPan[2] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ; - effect->Reverb.LateReverbGain = AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN; - effect->Reverb.LateReverbDelay = AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY; - effect->Reverb.LateReverbPan[0] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ; - effect->Reverb.LateReverbPan[1] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ; - effect->Reverb.LateReverbPan[2] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ; - effect->Reverb.EchoTime = AL_EAXREVERB_DEFAULT_ECHO_TIME; - effect->Reverb.EchoDepth = AL_EAXREVERB_DEFAULT_ECHO_DEPTH; - effect->Reverb.ModulationTime = AL_EAXREVERB_DEFAULT_MODULATION_TIME; - effect->Reverb.ModulationDepth = AL_EAXREVERB_DEFAULT_MODULATION_DEPTH; - effect->Reverb.AirAbsorptionGainHF = AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF; - effect->Reverb.HFReference = AL_EAXREVERB_DEFAULT_HFREFERENCE; - effect->Reverb.LFReference = AL_EAXREVERB_DEFAULT_LFREFERENCE; - effect->Reverb.RoomRolloffFactor = AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR; - effect->Reverb.DecayHFLimit = AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT; - effect->SetParami = eaxreverb_SetParami; - effect->SetParamiv = eaxreverb_SetParamiv; - effect->SetParamf = eaxreverb_SetParamf; - effect->SetParamfv = eaxreverb_SetParamfv; - effect->GetParami = eaxreverb_GetParami; - effect->GetParamiv = eaxreverb_GetParamiv; - effect->GetParamf = eaxreverb_GetParamf; - effect->GetParamfv = eaxreverb_GetParamfv; + effect->Props.Reverb.Density = AL_EAXREVERB_DEFAULT_DENSITY; + effect->Props.Reverb.Diffusion = AL_EAXREVERB_DEFAULT_DIFFUSION; + effect->Props.Reverb.Gain = AL_EAXREVERB_DEFAULT_GAIN; + effect->Props.Reverb.GainHF = AL_EAXREVERB_DEFAULT_GAINHF; + effect->Props.Reverb.GainLF = AL_EAXREVERB_DEFAULT_GAINLF; + effect->Props.Reverb.DecayTime = AL_EAXREVERB_DEFAULT_DECAY_TIME; + effect->Props.Reverb.DecayHFRatio = AL_EAXREVERB_DEFAULT_DECAY_HFRATIO; + effect->Props.Reverb.DecayLFRatio = AL_EAXREVERB_DEFAULT_DECAY_LFRATIO; + effect->Props.Reverb.ReflectionsGain = AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN; + effect->Props.Reverb.ReflectionsDelay = AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY; + effect->Props.Reverb.ReflectionsPan[0] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ; + effect->Props.Reverb.ReflectionsPan[1] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ; + effect->Props.Reverb.ReflectionsPan[2] = AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ; + effect->Props.Reverb.LateReverbGain = AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN; + effect->Props.Reverb.LateReverbDelay = AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY; + effect->Props.Reverb.LateReverbPan[0] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ; + effect->Props.Reverb.LateReverbPan[1] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ; + effect->Props.Reverb.LateReverbPan[2] = AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ; + effect->Props.Reverb.EchoTime = AL_EAXREVERB_DEFAULT_ECHO_TIME; + effect->Props.Reverb.EchoDepth = AL_EAXREVERB_DEFAULT_ECHO_DEPTH; + effect->Props.Reverb.ModulationTime = AL_EAXREVERB_DEFAULT_MODULATION_TIME; + effect->Props.Reverb.ModulationDepth = AL_EAXREVERB_DEFAULT_MODULATION_DEPTH; + effect->Props.Reverb.AirAbsorptionGainHF = AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF; + effect->Props.Reverb.HFReference = AL_EAXREVERB_DEFAULT_HFREFERENCE; + effect->Props.Reverb.LFReference = AL_EAXREVERB_DEFAULT_LFREFERENCE; + effect->Props.Reverb.RoomRolloffFactor = AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR; + effect->Props.Reverb.DecayHFLimit = AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT; + SET_VTABLE1(ALeaxreverb, effect); break; case AL_EFFECT_REVERB: - effect->Reverb.Density = AL_REVERB_DEFAULT_DENSITY; - effect->Reverb.Diffusion = AL_REVERB_DEFAULT_DIFFUSION; - effect->Reverb.Gain = AL_REVERB_DEFAULT_GAIN; - effect->Reverb.GainHF = AL_REVERB_DEFAULT_GAINHF; - effect->Reverb.DecayTime = AL_REVERB_DEFAULT_DECAY_TIME; - effect->Reverb.DecayHFRatio = AL_REVERB_DEFAULT_DECAY_HFRATIO; - effect->Reverb.ReflectionsGain = AL_REVERB_DEFAULT_REFLECTIONS_GAIN; - effect->Reverb.ReflectionsDelay = AL_REVERB_DEFAULT_REFLECTIONS_DELAY; - effect->Reverb.LateReverbGain = AL_REVERB_DEFAULT_LATE_REVERB_GAIN; - effect->Reverb.LateReverbDelay = AL_REVERB_DEFAULT_LATE_REVERB_DELAY; - effect->Reverb.AirAbsorptionGainHF = AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF; - effect->Reverb.RoomRolloffFactor = AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR; - effect->Reverb.DecayHFLimit = AL_REVERB_DEFAULT_DECAY_HFLIMIT; - effect->SetParami = reverb_SetParami; - effect->SetParamiv = reverb_SetParamiv; - effect->SetParamf = reverb_SetParamf; - effect->SetParamfv = reverb_SetParamfv; - effect->GetParami = reverb_GetParami; - effect->GetParamiv = reverb_GetParamiv; - effect->GetParamf = reverb_GetParamf; - effect->GetParamfv = reverb_GetParamfv; + effect->Props.Reverb.Density = AL_REVERB_DEFAULT_DENSITY; + effect->Props.Reverb.Diffusion = AL_REVERB_DEFAULT_DIFFUSION; + effect->Props.Reverb.Gain = AL_REVERB_DEFAULT_GAIN; + effect->Props.Reverb.GainHF = AL_REVERB_DEFAULT_GAINHF; + effect->Props.Reverb.DecayTime = AL_REVERB_DEFAULT_DECAY_TIME; + effect->Props.Reverb.DecayHFRatio = AL_REVERB_DEFAULT_DECAY_HFRATIO; + effect->Props.Reverb.ReflectionsGain = AL_REVERB_DEFAULT_REFLECTIONS_GAIN; + effect->Props.Reverb.ReflectionsDelay = AL_REVERB_DEFAULT_REFLECTIONS_DELAY; + effect->Props.Reverb.LateReverbGain = AL_REVERB_DEFAULT_LATE_REVERB_GAIN; + effect->Props.Reverb.LateReverbDelay = AL_REVERB_DEFAULT_LATE_REVERB_DELAY; + effect->Props.Reverb.AirAbsorptionGainHF = AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF; + effect->Props.Reverb.RoomRolloffFactor = AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR; + effect->Props.Reverb.DecayHFLimit = AL_REVERB_DEFAULT_DECAY_HFLIMIT; + SET_VTABLE1(ALreverb, effect); + break; + case AL_EFFECT_AUTOWAH: + effect->Props.Autowah.AttackTime = AL_AUTOWAH_DEFAULT_ATTACK_TIME; + effect->Props.Autowah.PeakGain = AL_AUTOWAH_DEFAULT_PEAK_GAIN; + effect->Props.Autowah.ReleaseTime = AL_AUTOWAH_DEFAULT_RELEASE_TIME; + effect->Props.Autowah.Resonance = AL_AUTOWAH_DEFAULT_RESONANCE; + SET_VTABLE1(ALautowah, effect); + break; + case AL_EFFECT_CHORUS: + effect->Props.Chorus.Waveform = AL_CHORUS_DEFAULT_WAVEFORM; + effect->Props.Chorus.Phase = AL_CHORUS_DEFAULT_PHASE; + effect->Props.Chorus.Rate = AL_CHORUS_DEFAULT_RATE; + effect->Props.Chorus.Depth = AL_CHORUS_DEFAULT_DEPTH; + effect->Props.Chorus.Feedback = AL_CHORUS_DEFAULT_FEEDBACK; + effect->Props.Chorus.Delay = AL_CHORUS_DEFAULT_DELAY; + SET_VTABLE1(ALchorus, effect); + break; + case AL_EFFECT_COMPRESSOR: + effect->Props.Compressor.OnOff = AL_COMPRESSOR_DEFAULT_ONOFF; + SET_VTABLE1(ALcompressor, effect); + break; + case AL_EFFECT_DISTORTION: + effect->Props.Distortion.Edge = AL_DISTORTION_DEFAULT_EDGE; + effect->Props.Distortion.Gain = AL_DISTORTION_DEFAULT_GAIN; + effect->Props.Distortion.LowpassCutoff = AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF; + effect->Props.Distortion.EQCenter = AL_DISTORTION_DEFAULT_EQCENTER; + effect->Props.Distortion.EQBandwidth = AL_DISTORTION_DEFAULT_EQBANDWIDTH; + SET_VTABLE1(ALdistortion, effect); break; case AL_EFFECT_ECHO: - effect->Echo.Delay = AL_ECHO_DEFAULT_DELAY; - effect->Echo.LRDelay = AL_ECHO_DEFAULT_LRDELAY; - effect->Echo.Damping = AL_ECHO_DEFAULT_DAMPING; - effect->Echo.Feedback = AL_ECHO_DEFAULT_FEEDBACK; - effect->Echo.Spread = AL_ECHO_DEFAULT_SPREAD; - effect->SetParami = echo_SetParami; - effect->SetParamiv = echo_SetParamiv; - effect->SetParamf = echo_SetParamf; - effect->SetParamfv = echo_SetParamfv; - effect->GetParami = echo_GetParami; - effect->GetParamiv = echo_GetParamiv; - effect->GetParamf = echo_GetParamf; - effect->GetParamfv = echo_GetParamfv; + effect->Props.Echo.Delay = AL_ECHO_DEFAULT_DELAY; + effect->Props.Echo.LRDelay = AL_ECHO_DEFAULT_LRDELAY; + effect->Props.Echo.Damping = AL_ECHO_DEFAULT_DAMPING; + effect->Props.Echo.Feedback = AL_ECHO_DEFAULT_FEEDBACK; + effect->Props.Echo.Spread = AL_ECHO_DEFAULT_SPREAD; + SET_VTABLE1(ALecho, effect); + break; + case AL_EFFECT_EQUALIZER: + effect->Props.Equalizer.LowCutoff = AL_EQUALIZER_DEFAULT_LOW_CUTOFF; + effect->Props.Equalizer.LowGain = AL_EQUALIZER_DEFAULT_LOW_GAIN; + effect->Props.Equalizer.Mid1Center = AL_EQUALIZER_DEFAULT_MID1_CENTER; + effect->Props.Equalizer.Mid1Gain = AL_EQUALIZER_DEFAULT_MID1_GAIN; + effect->Props.Equalizer.Mid1Width = AL_EQUALIZER_DEFAULT_MID1_WIDTH; + effect->Props.Equalizer.Mid2Center = AL_EQUALIZER_DEFAULT_MID2_CENTER; + effect->Props.Equalizer.Mid2Gain = AL_EQUALIZER_DEFAULT_MID2_GAIN; + effect->Props.Equalizer.Mid2Width = AL_EQUALIZER_DEFAULT_MID2_WIDTH; + effect->Props.Equalizer.HighCutoff = AL_EQUALIZER_DEFAULT_HIGH_CUTOFF; + effect->Props.Equalizer.HighGain = AL_EQUALIZER_DEFAULT_HIGH_GAIN; + SET_VTABLE1(ALequalizer, effect); + break; + case AL_EFFECT_FLANGER: + effect->Props.Flanger.Waveform = AL_FLANGER_DEFAULT_WAVEFORM; + effect->Props.Flanger.Phase = AL_FLANGER_DEFAULT_PHASE; + effect->Props.Flanger.Rate = AL_FLANGER_DEFAULT_RATE; + effect->Props.Flanger.Depth = AL_FLANGER_DEFAULT_DEPTH; + effect->Props.Flanger.Feedback = AL_FLANGER_DEFAULT_FEEDBACK; + effect->Props.Flanger.Delay = AL_FLANGER_DEFAULT_DELAY; + SET_VTABLE1(ALflanger, effect); break; case AL_EFFECT_RING_MODULATOR: - effect->Modulator.Frequency = AL_RING_MODULATOR_DEFAULT_FREQUENCY; - effect->Modulator.HighPassCutoff = AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF; - effect->Modulator.Waveform = AL_RING_MODULATOR_DEFAULT_WAVEFORM; - effect->SetParami = mod_SetParami; - effect->SetParamiv = mod_SetParamiv; - effect->SetParamf = mod_SetParamf; - effect->SetParamfv = mod_SetParamfv; - effect->GetParami = mod_GetParami; - effect->GetParamiv = mod_GetParamiv; - effect->GetParamf = mod_GetParamf; - effect->GetParamfv = mod_GetParamfv; + effect->Props.Modulator.Frequency = AL_RING_MODULATOR_DEFAULT_FREQUENCY; + effect->Props.Modulator.HighPassCutoff = AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF; + effect->Props.Modulator.Waveform = AL_RING_MODULATOR_DEFAULT_WAVEFORM; + SET_VTABLE1(ALmodulator, effect); break; case AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT: case AL_EFFECT_DEDICATED_DIALOGUE: - effect->Dedicated.Gain = 1.0f; - effect->SetParami = ded_SetParami; - effect->SetParamiv = ded_SetParamiv; - effect->SetParamf = ded_SetParamf; - effect->SetParamfv = ded_SetParamfv; - effect->GetParami = ded_GetParami; - effect->GetParamiv = ded_GetParamiv; - effect->GetParamf = ded_GetParamf; - effect->GetParamfv = ded_GetParamfv; + effect->Props.Dedicated.Gain = 1.0f; + SET_VTABLE1(ALdedicated, effect); break; default: - effect->SetParami = null_SetParami; - effect->SetParamiv = null_SetParamiv; - effect->SetParamf = null_SetParamf; - effect->SetParamfv = null_SetParamfv; - effect->GetParami = null_GetParami; - effect->GetParamiv = null_GetParamiv; - effect->GetParamf = null_GetParamf; - effect->GetParamfv = null_GetParamfv; + SET_VTABLE1(ALnull, effect); break; } effect->type = type; @@ -1454,11 +625,10 @@ static const struct { DECL(SMALLWATERROOM), }; #undef DECL -static const ALsizei reverblistsize = COUNTOF(reverblist); ALvoid LoadReverbPreset(const char *name, ALeffect *effect) { - int i; + size_t i; if(strcasecmp(name, "NONE") == 0) { @@ -1473,7 +643,7 @@ ALvoid LoadReverbPreset(const char *name, ALeffect *effect) InitEffectParams(effect, AL_EFFECT_REVERB); else InitEffectParams(effect, AL_EFFECT_NULL); - for(i = 0;i < reverblistsize;i++) + for(i = 0;i < COUNTOF(reverblist);i++) { const EFXEAXREVERBPROPERTIES *props; @@ -1482,35 +652,35 @@ ALvoid LoadReverbPreset(const char *name, ALeffect *effect) TRACE("Loading reverb '%s'\n", reverblist[i].name); props = &reverblist[i].props; - effect->Reverb.Density = props->flDensity; - effect->Reverb.Diffusion = props->flDiffusion; - effect->Reverb.Gain = props->flGain; - effect->Reverb.GainHF = props->flGainHF; - effect->Reverb.GainLF = props->flGainLF; - effect->Reverb.DecayTime = props->flDecayTime; - effect->Reverb.DecayHFRatio = props->flDecayHFRatio; - effect->Reverb.DecayLFRatio = props->flDecayLFRatio; - effect->Reverb.ReflectionsGain = props->flReflectionsGain; - effect->Reverb.ReflectionsDelay = props->flReflectionsDelay; - effect->Reverb.ReflectionsPan[0] = props->flReflectionsPan[0]; - effect->Reverb.ReflectionsPan[1] = props->flReflectionsPan[1]; - effect->Reverb.ReflectionsPan[2] = props->flReflectionsPan[2]; - effect->Reverb.LateReverbGain = props->flLateReverbGain; - effect->Reverb.LateReverbDelay = props->flLateReverbDelay; - effect->Reverb.LateReverbPan[0] = props->flLateReverbPan[0]; - effect->Reverb.LateReverbPan[1] = props->flLateReverbPan[1]; - effect->Reverb.LateReverbPan[2] = props->flLateReverbPan[2]; - effect->Reverb.EchoTime = props->flEchoTime; - effect->Reverb.EchoDepth = props->flEchoDepth; - effect->Reverb.ModulationTime = props->flModulationTime; - effect->Reverb.ModulationDepth = props->flModulationDepth; - effect->Reverb.AirAbsorptionGainHF = props->flAirAbsorptionGainHF; - effect->Reverb.HFReference = props->flHFReference; - effect->Reverb.LFReference = props->flLFReference; - effect->Reverb.RoomRolloffFactor = props->flRoomRolloffFactor; - effect->Reverb.DecayHFLimit = props->iDecayHFLimit; - break; + effect->Props.Reverb.Density = props->flDensity; + effect->Props.Reverb.Diffusion = props->flDiffusion; + effect->Props.Reverb.Gain = props->flGain; + effect->Props.Reverb.GainHF = props->flGainHF; + effect->Props.Reverb.GainLF = props->flGainLF; + effect->Props.Reverb.DecayTime = props->flDecayTime; + effect->Props.Reverb.DecayHFRatio = props->flDecayHFRatio; + effect->Props.Reverb.DecayLFRatio = props->flDecayLFRatio; + effect->Props.Reverb.ReflectionsGain = props->flReflectionsGain; + effect->Props.Reverb.ReflectionsDelay = props->flReflectionsDelay; + effect->Props.Reverb.ReflectionsPan[0] = props->flReflectionsPan[0]; + effect->Props.Reverb.ReflectionsPan[1] = props->flReflectionsPan[1]; + effect->Props.Reverb.ReflectionsPan[2] = props->flReflectionsPan[2]; + effect->Props.Reverb.LateReverbGain = props->flLateReverbGain; + effect->Props.Reverb.LateReverbDelay = props->flLateReverbDelay; + effect->Props.Reverb.LateReverbPan[0] = props->flLateReverbPan[0]; + effect->Props.Reverb.LateReverbPan[1] = props->flLateReverbPan[1]; + effect->Props.Reverb.LateReverbPan[2] = props->flLateReverbPan[2]; + effect->Props.Reverb.EchoTime = props->flEchoTime; + effect->Props.Reverb.EchoDepth = props->flEchoDepth; + effect->Props.Reverb.ModulationTime = props->flModulationTime; + effect->Props.Reverb.ModulationDepth = props->flModulationDepth; + effect->Props.Reverb.AirAbsorptionGainHF = props->flAirAbsorptionGainHF; + effect->Props.Reverb.HFReference = props->flHFReference; + effect->Props.Reverb.LFReference = props->flLFReference; + effect->Props.Reverb.RoomRolloffFactor = props->flRoomRolloffFactor; + effect->Props.Reverb.DecayHFLimit = props->iDecayHFLimit; + return; } - if(i == reverblistsize) - WARN("Reverb preset '%s' not found\n", name); + + WARN("Reverb preset '%s' not found\n", name); } diff --git a/OpenAL32/alError.c b/OpenAL32/alError.c index d18c1867..b557532e 100644 --- a/OpenAL32/alError.c +++ b/OpenAL32/alError.c @@ -22,6 +22,11 @@ #include <signal.h> +#ifdef HAVE_WINDOWS_H +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#endif + #include "alMain.h" #include "AL/alc.h" #include "alError.h" diff --git a/OpenAL32/alExtension.c b/OpenAL32/alExtension.c index c73200d0..fc23a932 100644 --- a/OpenAL32/alExtension.c +++ b/OpenAL32/alExtension.c @@ -36,12 +36,18 @@ const struct EffectList EffectList[] = { - { "eaxreverb", EAXREVERB, "AL_EFFECT_EAXREVERB", AL_EFFECT_EAXREVERB }, - { "reverb", REVERB, "AL_EFFECT_REVERB", AL_EFFECT_REVERB }, - { "echo", ECHO, "AL_EFFECT_ECHO", AL_EFFECT_ECHO }, - { "modulator", MODULATOR, "AL_EFFECT_RING_MODULATOR", AL_EFFECT_RING_MODULATOR }, - { "dedicated", DEDICATED, "AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT", AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT }, - { "dedicated", DEDICATED, "AL_EFFECT_DEDICATED_DIALOGUE", AL_EFFECT_DEDICATED_DIALOGUE }, + { "eaxreverb", EAXREVERB, "AL_EFFECT_EAXREVERB", AL_EFFECT_EAXREVERB }, + { "reverb", REVERB, "AL_EFFECT_REVERB", AL_EFFECT_REVERB }, + { "autowah", AUTOWAH, "AL_EFFECT_AUTOWAH", AL_EFFECT_AUTOWAH }, + { "chorus", CHORUS, "AL_EFFECT_CHORUS", AL_EFFECT_CHORUS }, + { "compressor", COMPRESSOR, "AL_EFFECT_COMPRESSOR", AL_EFFECT_COMPRESSOR }, + { "distortion", DISTORTION, "AL_EFFECT_DISTORTION", AL_EFFECT_DISTORTION }, + { "echo", ECHO, "AL_EFFECT_ECHO", AL_EFFECT_ECHO }, + { "equalizer", EQUALIZER, "AL_EFFECT_EQUALIZER", AL_EFFECT_EQUALIZER }, + { "flanger", FLANGER, "AL_EFFECT_FLANGER", AL_EFFECT_FLANGER }, + { "modulator", MODULATOR, "AL_EFFECT_RING_MODULATOR", AL_EFFECT_RING_MODULATOR }, + { "dedicated", DEDICATED, "AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT", AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT }, + { "dedicated", DEDICATED, "AL_EFFECT_DEDICATED_DIALOGUE", AL_EFFECT_DEDICATED_DIALOGUE }, { NULL, 0, NULL, (ALenum)0 } }; @@ -49,38 +55,36 @@ const struct EffectList EffectList[] = { AL_API ALboolean AL_APIENTRY alIsExtensionPresent(const ALchar *extName) { ALboolean ret = AL_FALSE; - ALCcontext *Context; + ALCcontext *context; const char *ptr; size_t len; - Context = GetContextRef(); - if(!Context) return AL_FALSE; + context = GetContextRef(); + if(!context) return AL_FALSE; - al_try - { - CHECK_VALUE(Context, extName); + if(!(extName)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - len = strlen(extName); - ptr = Context->ExtensionList; - while(ptr && *ptr) + len = strlen(extName); + ptr = context->ExtensionList; + while(ptr && *ptr) + { + if(strncasecmp(ptr, extName, len) == 0 && + (ptr[len] == '\0' || isspace(ptr[len]))) + { + ret = AL_TRUE; + break; + } + if((ptr=strchr(ptr, ' ')) != NULL) { - if(strncasecmp(ptr, extName, len) == 0 && - (ptr[len] == '\0' || isspace(ptr[len]))) - { - ret = AL_TRUE; - break; - } - if((ptr=strchr(ptr, ' ')) != NULL) - { - do { - ++ptr; - } while(isspace(*ptr)); - } + do { + ++ptr; + } while(isspace(*ptr)); } } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); return ret; } diff --git a/OpenAL32/alFilter.c b/OpenAL32/alFilter.c index a03ee2d8..692109f5 100644 --- a/OpenAL32/alFilter.c +++ b/OpenAL32/alFilter.c @@ -29,87 +29,89 @@ #include "alError.h" +extern inline struct ALfilter *LookupFilter(ALCdevice *device, ALuint id); +extern inline struct ALfilter *RemoveFilter(ALCdevice *device, ALuint id); +extern inline ALfloat ALfilterState_processSingle(ALfilterState *filter, ALfloat sample); +extern inline ALfloat ALfilterState_processSingleC(const ALfilterState *filter, ALfloat sample); + static void InitFilterParams(ALfilter *filter, ALenum type); AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters) { - ALCcontext *Context; - ALsizei cur = 0; + ALCdevice *device; + ALCcontext *context; + ALsizei cur = 0; + ALenum err; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try - { - ALCdevice *device = Context->Device; - ALenum err; + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - CHECK_VALUE(Context, n >= 0); - for(cur = 0;cur < n;cur++) + device = context->Device; + for(cur = 0;cur < n;cur++) + { + ALfilter *filter = calloc(1, sizeof(ALfilter)); + if(!filter) { - ALfilter *filter = calloc(1, sizeof(ALfilter)); - if(!filter) - al_throwerr(Context, AL_OUT_OF_MEMORY); - InitFilterParams(filter, AL_FILTER_NULL); - - err = NewThunkEntry(&filter->id); - if(err == AL_NO_ERROR) - err = InsertUIntMapEntry(&device->FilterMap, filter->id, filter); - if(err != AL_NO_ERROR) - { - FreeThunkEntry(filter->id); - memset(filter, 0, sizeof(ALfilter)); - free(filter); - - al_throwerr(Context, err); - } - - filters[cur] = filter->id; + alDeleteFilters(cur, filters); + SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); } - } - al_catchany() - { - if(cur > 0) + InitFilterParams(filter, AL_FILTER_NULL); + + err = NewThunkEntry(&filter->id); + if(err == AL_NO_ERROR) + err = InsertUIntMapEntry(&device->FilterMap, filter->id, filter); + if(err != AL_NO_ERROR) + { + FreeThunkEntry(filter->id); + memset(filter, 0, sizeof(ALfilter)); + free(filter); + alDeleteFilters(cur, filters); + SET_ERROR_AND_GOTO(context, err, done); + } + + filters[cur] = filter->id; } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint *filters) { - ALCcontext *Context; - ALfilter *Filter; + ALCdevice *device; + ALCcontext *context; + ALfilter *filter; ALsizei i; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try - { - ALCdevice *device = Context->Device; - CHECK_VALUE(Context, n >= 0); - for(i = 0;i < n;i++) - { - if(filters[i] && LookupFilter(device, filters[i]) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - } + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - for(i = 0;i < n;i++) - { - if((Filter=RemoveFilter(device, filters[i])) == NULL) - continue; - FreeThunkEntry(Filter->id); + device = context->Device; + for(i = 0;i < n;i++) + { + if(filters[i] && LookupFilter(device, filters[i]) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + } + for(i = 0;i < n;i++) + { + if((filter=RemoveFilter(device, filters[i])) == NULL) + continue; + FreeThunkEntry(filter->id); - memset(Filter, 0, sizeof(*Filter)); - free(Filter); - } + memset(filter, 0, sizeof(*filter)); + free(filter); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter) @@ -326,48 +328,137 @@ AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *va } -ALfloat lpCoeffCalc(ALfloat g, ALfloat cw) +void ALfilterState_clear(ALfilterState *filter) { - ALfloat a = 0.0f; + filter->x[0] = 0.0f; + filter->x[1] = 0.0f; + filter->y[0] = 0.0f; + filter->y[1] = 0.0f; +} - if(g < 0.9999f) /* 1-epsilon */ +void ALfilterState_setParams(ALfilterState *filter, ALfilterType type, ALfloat gain, ALfloat freq_scale, ALfloat bandwidth) +{ + ALfloat alpha; + ALfloat w0; + + // Limit gain to -100dB + gain = maxf(gain, 0.00001f); + + w0 = F_2PI * freq_scale; + + /* Calculate filter coefficients depending on filter type */ + switch(type) { - /* Be careful with gains < 0.001, as that causes the coefficient head - * towards 1, which will flatten the signal */ - g = maxf(g, 0.001f); - a = (1 - g*cw - sqrtf(2*g*(1-cw) - g*g*(1 - cw*cw))) / - (1 - g); + case ALfilterType_HighShelf: + alpha = sinf(w0) / 2.0f * sqrtf((gain + 1.0f/gain) * + (1.0f/0.75f - 1.0f) + 2.0f); + filter->b[0] = gain * ((gain + 1.0f) + + (gain - 1.0f) * cosf(w0) + + 2.0f * sqrtf(gain) * alpha); + filter->b[1] = -2.0f * gain * ((gain - 1.0f) + + (gain + 1.0f) * cosf(w0)); + filter->b[2] = gain * ((gain + 1.0f) + + (gain - 1.0f) * cosf(w0) - + 2.0f * sqrtf(gain) * alpha); + filter->a[0] = (gain + 1.0f) - + (gain - 1.0f) * cosf(w0) + + 2.0f * sqrtf(gain) * alpha; + filter->a[1] = 2.0f * ((gain - 1.0f) - + (gain + 1.0f) * cosf(w0)); + filter->a[2] = (gain + 1.0f) - + (gain - 1.0f) * cosf(w0) - + 2.0f * sqrtf(gain) * alpha; + break; + case ALfilterType_LowShelf: + alpha = sinf(w0) / 2.0f * sqrtf((gain + 1.0f / gain) * + (1.0f / 0.75f - 1.0f) + 2.0f); + filter->b[0] = gain * ((gain + 1.0f) - + (gain - 1.0f) * cosf(w0) + + 2.0f * sqrtf(gain) * alpha); + filter->b[1] = 2.0f * gain * ((gain - 1.0f) - + (gain + 1.0f) * cosf(w0)); + filter->b[2] = gain * ((gain + 1.0f) - + (gain - 1.0f) * cosf(w0) - + 2.0f * sqrtf(gain) * alpha); + filter->a[0] = (gain + 1.0f) + + (gain - 1.0f) * cosf(w0) + + 2.0f * sqrtf(gain) * alpha; + filter->a[1] = -2.0f * ((gain - 1.0f) + + (gain + 1.0f) * cosf(w0)); + filter->a[2] = (gain + 1.0f) + + (gain - 1.0f) * cosf(w0) - + 2.0f * sqrtf(gain) * alpha; + break; + case ALfilterType_Peaking: + alpha = sinf(w0) * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sinf(w0)); + filter->b[0] = 1.0f + alpha * gain; + filter->b[1] = -2.0f * cosf(w0); + filter->b[2] = 1.0f - alpha * gain; + filter->a[0] = 1.0f + alpha / gain; + filter->a[1] = -2.0f * cosf(w0); + filter->a[2] = 1.0f - alpha / gain; + break; + + case ALfilterType_LowPass: + alpha = sinf(w0) * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sinf(w0)); + filter->b[0] = (1.0f - cosf(w0)) / 2.0f; + filter->b[1] = 1.0f - cosf(w0); + filter->b[2] = (1.0f - cosf(w0)) / 2.0f; + filter->a[0] = 1.0f + alpha; + filter->a[1] = -2.0f * cosf(w0); + filter->a[2] = 1.0f - alpha; + break; + case ALfilterType_HighPass: + alpha = sinf(w0) * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sinf(w0)); + filter->b[0] = (1.0f + cosf(w0)) / 2.0f; + filter->b[1] = 1.0f + cosf(w0); + filter->b[2] = (1.0f + cosf(w0)) / 2.0f; + filter->a[0] = 1.0f + alpha; + filter->a[1] = -2.0f * cosf(w0); + filter->a[2] = 1.0f - alpha; + break; + case ALfilterType_BandPass: + alpha = sinf(w0) * sinhf(logf(2.0f) / 2.0f * bandwidth * w0 / sinf(w0)); + filter->b[0] = alpha; + filter->b[1] = 0; + filter->b[2] = -alpha; + filter->a[0] = 1.0f + alpha; + filter->a[1] = -2.0f * cosf(w0); + filter->a[2] = 1.0f - alpha; + break; } - return a; + filter->b[2] /= filter->a[0]; + filter->b[1] /= filter->a[0]; + filter->b[0] /= filter->a[0]; + filter->a[2] /= filter->a[0]; + filter->a[1] /= filter->a[0]; + filter->a[0] /= filter->a[0]; } -static void lp_SetParami(ALfilter *filter, ALCcontext *context, ALenum param, ALint val) -{ (void)filter;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void lp_SetParamiv(ALfilter *filter, ALCcontext *context, ALenum param, const ALint *vals) -{ (void)filter;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); } +static void lp_SetParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void lp_SetParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } static void lp_SetParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val) { switch(param) { case AL_LOWPASS_GAIN: - if(val >= AL_LOWPASS_MIN_GAIN && val <= AL_LOWPASS_MAX_GAIN) - filter->Gain = val; - else - alSetError(context, AL_INVALID_VALUE); + if(!(val >= AL_LOWPASS_MIN_GAIN && val <= AL_LOWPASS_MAX_GAIN)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + filter->Gain = val; break; case AL_LOWPASS_GAINHF: - if(val >= AL_LOWPASS_MIN_GAINHF && val <= AL_LOWPASS_MAX_GAINHF) - filter->GainHF = val; - else - alSetError(context, AL_INVALID_VALUE); + if(!(val >= AL_LOWPASS_MIN_GAINHF && val <= AL_LOWPASS_MAX_GAINHF)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + filter->GainHF = val; break; default: - alSetError(context, AL_INVALID_ENUM); - break; + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } } static void lp_SetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, const ALfloat *vals) @@ -375,10 +466,10 @@ static void lp_SetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, c lp_SetParamf(filter, context, param, vals[0]); } -static void lp_GetParami(ALfilter *filter, ALCcontext *context, ALenum param, ALint *val) -{ (void)filter;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void lp_GetParamiv(ALfilter *filter, ALCcontext *context, ALenum param, ALint *vals) -{ (void)filter;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); } +static void lp_GetParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void lp_GetParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } static void lp_GetParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val) { switch(param) @@ -392,8 +483,7 @@ static void lp_GetParamf(ALfilter *filter, ALCcontext *context, ALenum param, AL break; default: - alSetError(context, AL_INVALID_ENUM); - break; + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } } static void lp_GetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals) @@ -402,23 +492,23 @@ static void lp_GetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, A } -static void null_SetParami(ALfilter *filter, ALCcontext *context, ALenum param, ALint val) -{ (void)filter;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void null_SetParamiv(ALfilter *filter, ALCcontext *context, ALenum param, const ALint *vals) -{ (void)filter;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); } -static void null_SetParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val) -{ (void)filter;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void null_SetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, const ALfloat *vals) -{ (void)filter;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); } - -static void null_GetParami(ALfilter *filter, ALCcontext *context, ALenum param, ALint *val) -{ (void)filter;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void null_GetParamiv(ALfilter *filter, ALCcontext *context, ALenum param, ALint *vals) -{ (void)filter;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); } -static void null_GetParamf(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val) -{ (void)filter;(void)param;(void)val; alSetError(context, AL_INVALID_ENUM); } -static void null_GetParamfv(ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals) -{ (void)filter;(void)param;(void)vals; alSetError(context, AL_INVALID_ENUM); } +static void null_SetParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void null_SetParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), const ALint *UNUSED(vals)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void null_SetParamf(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALfloat UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void null_SetParamfv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), const ALfloat *UNUSED(vals)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } + +static void null_GetParami(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void null_GetParamiv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(vals)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void null_GetParamf(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALfloat *UNUSED(val)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } +static void null_GetParamfv(ALfilter *UNUSED(filter), ALCcontext *context, ALenum UNUSED(param), ALfloat *UNUSED(vals)) +{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } ALvoid ReleaseALFilters(ALCdevice *device) diff --git a/OpenAL32/alFontsound.c b/OpenAL32/alFontsound.c new file mode 100644 index 00000000..94cf3064 --- /dev/null +++ b/OpenAL32/alFontsound.c @@ -0,0 +1,972 @@ + +#include "config.h" + +#include <stdlib.h> +#include <string.h> + +#include "alMain.h" +#include "alMidi.h" +#include "alError.h" +#include "alThunk.h" + +#include "midi/base.h" + + +extern inline struct ALfontsound *LookupFontsound(ALCdevice *device, ALuint id); +extern inline struct ALfontsound *RemoveFontsound(ALCdevice *device, ALuint id); + +static void ALfontsound_Construct(ALfontsound *self); +void ALfontsound_Destruct(ALfontsound *self); +void ALfontsound_setPropi(ALfontsound *self, ALCcontext *context, ALenum param, ALint value); +static ALsfmodulator *ALfontsound_getModStage(ALfontsound *self, ALsizei stage); +void ALfontsound_setModStagei(ALfontsound *self, ALCcontext *context, ALsizei stage, ALenum param, ALint value); +static void ALfontsound_getModStagei(ALfontsound *self, ALCcontext *context, ALsizei stage, ALenum param, ALint *values); + + +AL_API void AL_APIENTRY alGenFontsoundsSOFT(ALsizei n, ALuint *ids) +{ + ALCcontext *context; + ALsizei cur = 0; + + context = GetContextRef(); + if(!context) return; + + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + for(cur = 0;cur < n;cur++) + { + ALfontsound *sound = NewFontsound(context); + if(!sound) + { + alDeleteFontsoundsSOFT(cur, ids); + break; + } + + ids[cur] = sound->id; + } + +done: + ALCcontext_DecRef(context); +} + +AL_API ALvoid AL_APIENTRY alDeleteFontsoundsSOFT(ALsizei n, const ALuint *ids) +{ + ALCdevice *device; + ALCcontext *context; + ALfontsound *inst; + ALsizei i; + + context = GetContextRef(); + if(!context) return; + + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + for(i = 0;i < n;i++) + { + /* Check for valid ID */ + if((inst=LookupFontsound(device, ids[i])) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(inst->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + } + + for(i = 0;i < n;i++) + { + if((inst=RemoveFontsound(device, ids[i])) == NULL) + continue; + + ALfontsound_Destruct(inst); + + memset(inst, 0, sizeof(*inst)); + free(inst); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API ALboolean AL_APIENTRY alIsFontsoundSOFT(ALuint id) +{ + ALCcontext *context; + ALboolean ret; + + context = GetContextRef(); + if(!context) return AL_FALSE; + + ret = LookupFontsound(context->Device, id) ? AL_TRUE : AL_FALSE; + + ALCcontext_DecRef(context); + + return ret; +} + +AL_API void AL_APIENTRY alFontsoundiSOFT(ALuint id, ALenum param, ALint value) +{ + ALCdevice *device; + ALCcontext *context; + ALfontsound *sound; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(!(sound=LookupFontsound(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(sound->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + + ALfontsound_setPropi(sound, context, param, value); + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alFontsound2iSOFT(ALuint id, ALenum param, ALint value1, ALint value2) +{ + ALCdevice *device; + ALCcontext *context; + ALfontsound *sound; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(!(sound=LookupFontsound(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(sound->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + switch(param) + { + case AL_KEY_RANGE_SOFT: + if(!(value1 >= 0 && value1 <= 127 && value2 >= 0 && value2 <= 127 && value2 >= value1)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + sound->MinKey = value1; + sound->MaxKey = value2; + break; + + case AL_VELOCITY_RANGE_SOFT: + if(!(value1 >= 0 && value1 <= 127 && value2 >= 0 && value2 <= 127 && value2 >= value1)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + sound->MinVelocity = value1; + sound->MaxVelocity = value2; + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alFontsoundivSOFT(ALuint id, ALenum param, const ALint *values) +{ + ALCdevice *device; + ALCcontext *context; + ALfontsound *sound; + + switch(param) + { + case AL_KEY_RANGE_SOFT: + case AL_VELOCITY_RANGE_SOFT: + alFontsound2iSOFT(id, param, values[0], values[1]); + return; + + case AL_MOD_LFO_TO_PITCH_SOFT: + case AL_VIBRATO_LFO_TO_PITCH_SOFT: + case AL_MOD_ENV_TO_PITCH_SOFT: + case AL_FILTER_CUTOFF_SOFT: + case AL_FILTER_RESONANCE_SOFT: + case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT: + case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT: + case AL_MOD_LFO_TO_VOLUME_SOFT: + case AL_CHORUS_SEND_SOFT: + case AL_REVERB_SEND_SOFT: + case AL_PAN_SOFT: + case AL_MOD_LFO_DELAY_SOFT: + case AL_MOD_LFO_FREQUENCY_SOFT: + case AL_VIBRATO_LFO_DELAY_SOFT: + case AL_VIBRATO_LFO_FREQUENCY_SOFT: + case AL_MOD_ENV_DELAYTIME_SOFT: + case AL_MOD_ENV_ATTACKTIME_SOFT: + case AL_MOD_ENV_HOLDTIME_SOFT: + case AL_MOD_ENV_DECAYTIME_SOFT: + case AL_MOD_ENV_SUSTAINVOLUME_SOFT: + case AL_MOD_ENV_RELEASETIME_SOFT: + case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT: + case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT: + case AL_VOLUME_ENV_DELAYTIME_SOFT: + case AL_VOLUME_ENV_ATTACKTIME_SOFT: + case AL_VOLUME_ENV_HOLDTIME_SOFT: + case AL_VOLUME_ENV_DECAYTIME_SOFT: + case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT: + case AL_VOLUME_ENV_RELEASETIME_SOFT: + case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT: + case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT: + case AL_ATTENUATION_SOFT: + case AL_TUNING_COARSE_SOFT: + case AL_TUNING_FINE_SOFT: + case AL_LOOP_MODE_SOFT: + case AL_TUNING_SCALE_SOFT: + case AL_EXCLUSIVE_CLASS_SOFT: + case AL_SAMPLE_START_SOFT: + case AL_SAMPLE_END_SOFT: + case AL_SAMPLE_LOOP_START_SOFT: + case AL_SAMPLE_LOOP_END_SOFT: + case AL_SAMPLE_RATE_SOFT: + case AL_BASE_KEY_SOFT: + case AL_KEY_CORRECTION_SOFT: + case AL_SAMPLE_TYPE_SOFT: + case AL_FONTSOUND_LINK_SOFT: + alFontsoundiSOFT(id, param, values[0]); + return; + } + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(!(sound=LookupFontsound(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(sound->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + switch(param) + { + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alGetFontsoundivSOFT(ALuint id, ALenum param, ALint *values) +{ + ALCdevice *device; + ALCcontext *context; + const ALfontsound *sound; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(!(sound=LookupFontsound(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) + { + case AL_MOD_LFO_TO_PITCH_SOFT: + values[0] = sound->ModLfoToPitch; + break; + + case AL_VIBRATO_LFO_TO_PITCH_SOFT: + values[0] = sound->VibratoLfoToPitch; + break; + + case AL_MOD_ENV_TO_PITCH_SOFT: + values[0] = sound->ModEnvToPitch; + break; + + case AL_FILTER_CUTOFF_SOFT: + values[0] = sound->FilterCutoff; + break; + + case AL_FILTER_RESONANCE_SOFT: + values[0] = sound->FilterQ; + break; + + case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT: + values[0] = sound->ModLfoToFilterCutoff; + break; + + case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT: + values[0] = sound->ModEnvToFilterCutoff; + break; + + case AL_MOD_LFO_TO_VOLUME_SOFT: + values[0] = sound->ModLfoToVolume; + break; + + case AL_CHORUS_SEND_SOFT: + values[0] = sound->ChorusSend; + break; + + case AL_REVERB_SEND_SOFT: + values[0] = sound->ReverbSend; + break; + + case AL_PAN_SOFT: + values[0] = sound->Pan; + break; + + case AL_MOD_LFO_DELAY_SOFT: + values[0] = sound->ModLfo.Delay; + break; + case AL_MOD_LFO_FREQUENCY_SOFT: + values[0] = sound->ModLfo.Frequency; + break; + + case AL_VIBRATO_LFO_DELAY_SOFT: + values[0] = sound->VibratoLfo.Delay; + break; + case AL_VIBRATO_LFO_FREQUENCY_SOFT: + values[0] = sound->VibratoLfo.Frequency; + break; + + case AL_MOD_ENV_DELAYTIME_SOFT: + values[0] = sound->ModEnv.DelayTime; + break; + case AL_MOD_ENV_ATTACKTIME_SOFT: + values[0] = sound->ModEnv.AttackTime; + break; + case AL_MOD_ENV_HOLDTIME_SOFT: + values[0] = sound->ModEnv.HoldTime; + break; + case AL_MOD_ENV_DECAYTIME_SOFT: + values[0] = sound->ModEnv.DecayTime; + break; + case AL_MOD_ENV_SUSTAINVOLUME_SOFT: + values[0] = sound->ModEnv.SustainAttn; + break; + case AL_MOD_ENV_RELEASETIME_SOFT: + values[0] = sound->ModEnv.ReleaseTime; + break; + case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT: + values[0] = sound->ModEnv.KeyToHoldTime; + break; + case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT: + values[0] = sound->ModEnv.KeyToDecayTime; + break; + + case AL_VOLUME_ENV_DELAYTIME_SOFT: + values[0] = sound->VolEnv.DelayTime; + break; + case AL_VOLUME_ENV_ATTACKTIME_SOFT: + values[0] = sound->VolEnv.AttackTime; + break; + case AL_VOLUME_ENV_HOLDTIME_SOFT: + values[0] = sound->VolEnv.HoldTime; + break; + case AL_VOLUME_ENV_DECAYTIME_SOFT: + values[0] = sound->VolEnv.DecayTime; + break; + case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT: + values[0] = sound->VolEnv.SustainAttn; + break; + case AL_VOLUME_ENV_RELEASETIME_SOFT: + values[0] = sound->VolEnv.ReleaseTime; + break; + case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT: + values[0] = sound->VolEnv.KeyToHoldTime; + break; + case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT: + values[0] = sound->VolEnv.KeyToDecayTime; + break; + + case AL_KEY_RANGE_SOFT: + values[0] = sound->MinKey; + values[1] = sound->MaxKey; + break; + + case AL_VELOCITY_RANGE_SOFT: + values[0] = sound->MinVelocity; + values[1] = sound->MaxVelocity; + break; + + case AL_ATTENUATION_SOFT: + values[0] = sound->Attenuation; + break; + + case AL_TUNING_COARSE_SOFT: + values[0] = sound->CoarseTuning; + break; + case AL_TUNING_FINE_SOFT: + values[0] = sound->FineTuning; + break; + + case AL_LOOP_MODE_SOFT: + values[0] = sound->LoopMode; + break; + + case AL_TUNING_SCALE_SOFT: + values[0] = sound->TuningScale; + break; + + case AL_EXCLUSIVE_CLASS_SOFT: + values[0] = sound->ExclusiveClass; + break; + + case AL_SAMPLE_START_SOFT: + values[0] = sound->Start; + break; + + case AL_SAMPLE_END_SOFT: + values[0] = sound->End; + break; + + case AL_SAMPLE_LOOP_START_SOFT: + values[0] = sound->LoopStart; + break; + + case AL_SAMPLE_LOOP_END_SOFT: + values[0] = sound->LoopEnd; + break; + + case AL_SAMPLE_RATE_SOFT: + values[0] = sound->SampleRate; + break; + + case AL_BASE_KEY_SOFT: + values[0] = sound->PitchKey; + break; + + case AL_KEY_CORRECTION_SOFT: + values[0] = sound->PitchCorrection; + break; + + case AL_SAMPLE_TYPE_SOFT: + values[0] = sound->SampleType; + break; + + case AL_FONTSOUND_LINK_SOFT: + values[0] = (sound->Link ? sound->Link->id : 0); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alFontsoundModulatoriSOFT(ALuint id, ALsizei stage, ALenum param, ALint value) +{ + ALCdevice *device; + ALCcontext *context; + ALfontsound *sound; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(!(sound=LookupFontsound(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + ALfontsound_setModStagei(sound, context, stage, param, value); + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alGetFontsoundModulatorivSOFT(ALuint id, ALsizei stage, ALenum param, ALint *values) +{ + ALCdevice *device; + ALCcontext *context; + ALfontsound *sound; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(!(sound=LookupFontsound(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + ALfontsound_getModStagei(sound, context, stage, param, values); + +done: + ALCcontext_DecRef(context); +} + + +ALfontsound *NewFontsound(ALCcontext *context) +{ + ALCdevice *device = context->Device; + ALfontsound *sound; + ALenum err; + + sound = calloc(1, sizeof(*sound)); + if(!sound) + SET_ERROR_AND_RETURN_VALUE(context, AL_OUT_OF_MEMORY, NULL); + ALfontsound_Construct(sound); + + err = NewThunkEntry(&sound->id); + if(err == AL_NO_ERROR) + err = InsertUIntMapEntry(&device->FontsoundMap, sound->id, sound); + if(err != AL_NO_ERROR) + { + ALfontsound_Destruct(sound); + memset(sound, 0, sizeof(*sound)); + free(sound); + + SET_ERROR_AND_RETURN_VALUE(context, err, NULL); + } + + return sound; +} + + +static void ALfontsound_Construct(ALfontsound *self) +{ + self->ref = 0; + + self->MinKey = 0; + self->MaxKey = 127; + self->MinVelocity = 0; + self->MaxVelocity = 127; + + self->ModLfoToPitch = 0; + self->VibratoLfoToPitch = 0; + self->ModEnvToPitch = 0; + + self->FilterCutoff = 13500; + self->FilterQ = 0; + self->ModLfoToFilterCutoff = 0; + self->ModEnvToFilterCutoff = 0; + self->ModLfoToVolume = 0; + + self->ChorusSend = 0; + self->ReverbSend = 0; + + self->Pan = 0; + + self->ModLfo.Delay = 0; + self->ModLfo.Frequency = 0; + + self->VibratoLfo.Delay = 0; + self->VibratoLfo.Frequency = 0; + + self->ModEnv.DelayTime = -12000; + self->ModEnv.AttackTime = -12000; + self->ModEnv.HoldTime = -12000; + self->ModEnv.DecayTime = -12000; + self->ModEnv.SustainAttn = 0; + self->ModEnv.ReleaseTime = -12000; + self->ModEnv.KeyToHoldTime = 0; + self->ModEnv.KeyToDecayTime = 0; + + self->VolEnv.DelayTime = -12000; + self->VolEnv.AttackTime = -12000; + self->VolEnv.HoldTime = -12000; + self->VolEnv.DecayTime = -12000; + self->VolEnv.SustainAttn = 0; + self->VolEnv.ReleaseTime = -12000; + self->VolEnv.KeyToHoldTime = 0; + self->VolEnv.KeyToDecayTime = 0; + + self->Attenuation = 0; + + self->CoarseTuning = 0; + self->FineTuning = 0; + + self->LoopMode = AL_NONE; + + self->TuningScale = 100; + + self->ExclusiveClass = 0; + + self->Start = 0; + self->End = 0; + self->LoopStart = 0; + self->LoopEnd = 0; + self->SampleRate = 0; + self->PitchKey = 0; + self->PitchCorrection = 0; + self->SampleType = AL_MONO_SOFT; + self->Link = NULL; + + InitUIntMap(&self->ModulatorMap, ~0); + + self->id = 0; +} + +void ALfontsound_Destruct(ALfontsound *self) +{ + ALsizei i; + + FreeThunkEntry(self->id); + self->id = 0; + + if(self->Link) + DecrementRef(&self->Link->ref); + self->Link = NULL; + + for(i = 0;i < self->ModulatorMap.size;i++) + { + free(self->ModulatorMap.array[i].value); + self->ModulatorMap.array[i].value = NULL; + } + ResetUIntMap(&self->ModulatorMap); +} + +void ALfontsound_setPropi(ALfontsound *self, ALCcontext *context, ALenum param, ALint value) +{ + ALfontsound *link; + + switch(param) + { + case AL_MOD_LFO_TO_PITCH_SOFT: + self->ModLfoToPitch = value; + break; + + case AL_VIBRATO_LFO_TO_PITCH_SOFT: + self->VibratoLfoToPitch = value; + break; + + case AL_MOD_ENV_TO_PITCH_SOFT: + self->ModEnvToPitch = value; + break; + + case AL_FILTER_CUTOFF_SOFT: + self->FilterCutoff = value; + break; + + case AL_FILTER_RESONANCE_SOFT: + if(!(value >= 0)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + self->FilterQ = value; + break; + + case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT: + self->ModLfoToFilterCutoff = value; + break; + + case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT: + self->ModEnvToFilterCutoff = value; + break; + + case AL_MOD_LFO_TO_VOLUME_SOFT: + self->ModLfoToVolume = value; + break; + + case AL_CHORUS_SEND_SOFT: + if(!(value >= 0 && value <= 1000)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + self->ChorusSend = value; + break; + case AL_REVERB_SEND_SOFT: + if(!(value >= 0 && value <= 1000)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + self->ReverbSend = value; + break; + + case AL_PAN_SOFT: + self->Pan = value; + break; + + case AL_MOD_LFO_DELAY_SOFT: + self->ModLfo.Delay = value; + break; + case AL_MOD_LFO_FREQUENCY_SOFT: + self->ModLfo.Frequency = value; + break; + + case AL_VIBRATO_LFO_DELAY_SOFT: + self->VibratoLfo.Delay = value; + break; + case AL_VIBRATO_LFO_FREQUENCY_SOFT: + self->VibratoLfo.Frequency = value; + break; + + case AL_MOD_ENV_DELAYTIME_SOFT: + self->ModEnv.DelayTime = value; + break; + case AL_MOD_ENV_ATTACKTIME_SOFT: + self->ModEnv.AttackTime = value; + break; + case AL_MOD_ENV_HOLDTIME_SOFT: + self->ModEnv.HoldTime = value; + break; + case AL_MOD_ENV_DECAYTIME_SOFT: + self->ModEnv.DecayTime = value; + break; + case AL_MOD_ENV_SUSTAINVOLUME_SOFT: + self->ModEnv.SustainAttn = value; + break; + case AL_MOD_ENV_RELEASETIME_SOFT: + self->ModEnv.ReleaseTime = value; + break; + case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT: + self->ModEnv.KeyToHoldTime = value; + break; + case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT: + self->ModEnv.KeyToDecayTime = value; + break; + + case AL_VOLUME_ENV_DELAYTIME_SOFT: + self->VolEnv.DelayTime = value; + break; + case AL_VOLUME_ENV_ATTACKTIME_SOFT: + self->VolEnv.AttackTime = value; + break; + case AL_VOLUME_ENV_HOLDTIME_SOFT: + self->VolEnv.HoldTime = value; + break; + case AL_VOLUME_ENV_DECAYTIME_SOFT: + self->VolEnv.DecayTime = value; + break; + case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT: + self->VolEnv.SustainAttn = value; + break; + case AL_VOLUME_ENV_RELEASETIME_SOFT: + self->VolEnv.ReleaseTime = value; + break; + case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT: + self->VolEnv.KeyToHoldTime = value; + break; + case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT: + self->VolEnv.KeyToDecayTime = value; + break; + + case AL_ATTENUATION_SOFT: + if(!(value >= 0)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + self->Attenuation = value; + break; + + case AL_TUNING_COARSE_SOFT: + self->CoarseTuning = value; + break; + case AL_TUNING_FINE_SOFT: + self->FineTuning = value; + break; + + case AL_LOOP_MODE_SOFT: + if(!(value == AL_NONE || value == AL_LOOP_CONTINUOUS_SOFT || + value == AL_LOOP_UNTIL_RELEASE_SOFT)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + self->LoopMode = value; + break; + + case AL_TUNING_SCALE_SOFT: + self->TuningScale = value; + break; + + case AL_EXCLUSIVE_CLASS_SOFT: + self->ExclusiveClass = value; + break; + + case AL_SAMPLE_START_SOFT: + self->Start = value; + break; + + case AL_SAMPLE_END_SOFT: + self->End = value; + break; + + case AL_SAMPLE_LOOP_START_SOFT: + self->LoopStart = value; + break; + + case AL_SAMPLE_LOOP_END_SOFT: + self->LoopEnd = value; + break; + + case AL_SAMPLE_RATE_SOFT: + if(!(value > 0)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + self->SampleRate = value; + break; + + case AL_BASE_KEY_SOFT: + if(!((value >= 0 && value <= 127) || value == 255)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + self->PitchKey = value; + break; + + case AL_KEY_CORRECTION_SOFT: + if(!(value >= -99 && value <= 99)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + self->PitchCorrection = value; + break; + + case AL_SAMPLE_TYPE_SOFT: + if(!(value == AL_MONO_SOFT || value == AL_RIGHT_SOFT || value == AL_LEFT_SOFT)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + self->SampleType = value; + break; + + case AL_FONTSOUND_LINK_SOFT: + if(!value) + link = NULL; + else + { + link = LookupFontsound(context->Device, value); + if(!link) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + } + if(link) IncrementRef(&link->ref); + link = ExchangePtr((XchgPtr*)&self->Link, link); + if(link) DecrementRef(&link->ref); + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} + +static ALsfmodulator *ALfontsound_getModStage(ALfontsound *self, ALsizei stage) +{ + ALsfmodulator *ret = LookupModulator(self, stage); + if(!ret) + { + static const ALsfmodulator moddef = { + { { AL_ONE_SOFT, AL_UNORM_SOFT, AL_LINEAR_SOFT }, + { AL_ONE_SOFT, AL_UNORM_SOFT, AL_LINEAR_SOFT } + }, + 0, + AL_LINEAR_SOFT, + AL_NONE + }; + ret = malloc(sizeof(*ret)); + *ret = moddef; + InsertUIntMapEntry(&self->ModulatorMap, stage, ret); + } + return ret; +} + +void ALfontsound_setModStagei(ALfontsound *self, ALCcontext *context, ALsizei stage, ALenum param, ALint value) +{ + ALint srcidx = 0; + + if(self->ref != 0) + SET_ERROR_AND_RETURN(context, AL_INVALID_OPERATION); + switch(param) + { + case AL_SOURCE1_INPUT_SOFT: + srcidx++; + /* fall-through */ + case AL_SOURCE0_INPUT_SOFT: + if(!(value == AL_ONE_SOFT || value == AL_NOTEON_VELOCITY_SOFT || + value == AL_NOTEON_KEY_SOFT || value == AL_KEYPRESSURE_SOFT || + value == AL_CHANNELPRESSURE_SOFT || value == AL_PITCHBEND_SOFT || + value == AL_PITCHBEND_SENSITIVITY_SOFT || + (value > 0 && value < 120 && !(value == 6 || (value >= 32 && value <= 63) || + (value >= 98 && value <= 101)) + ) + )) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + ALfontsound_getModStage(self, stage)->Source[srcidx].Input = value; + break; + + case AL_SOURCE1_TYPE_SOFT: + srcidx++; + /* fall-through */ + case AL_SOURCE0_TYPE_SOFT: + if(!(value == AL_UNORM_SOFT || value == AL_UNORM_REV_SOFT || + value == AL_SNORM_SOFT || value == AL_SNORM_REV_SOFT)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + ALfontsound_getModStage(self, stage)->Source[srcidx].Type = value; + break; + + case AL_SOURCE1_FORM_SOFT: + srcidx++; + /* fall-through */ + case AL_SOURCE0_FORM_SOFT: + if(!(value == AL_LINEAR_SOFT || value == AL_CONCAVE_SOFT || + value == AL_CONVEX_SOFT || value == AL_SWITCH_SOFT)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + ALfontsound_getModStage(self, stage)->Source[srcidx].Form = value; + break; + + case AL_AMOUNT_SOFT: + ALfontsound_getModStage(self, stage)->Amount = value; + break; + + case AL_TRANSFORM_OP_SOFT: + if(!(value == AL_LINEAR_SOFT || value == AL_ABSOLUTE_SOFT)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + ALfontsound_getModStage(self, stage)->TransformOp = value; + break; + + case AL_DESTINATION_SOFT: + if(!(value == AL_MOD_LFO_TO_PITCH_SOFT || value == AL_VIBRATO_LFO_TO_PITCH_SOFT || + value == AL_MOD_ENV_TO_PITCH_SOFT || value == AL_FILTER_CUTOFF_SOFT || + value == AL_FILTER_RESONANCE_SOFT || value == AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT || + value == AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT || value == AL_MOD_LFO_TO_VOLUME_SOFT || + value == AL_CHORUS_SEND_SOFT || value == AL_REVERB_SEND_SOFT || value == AL_PAN_SOFT || + value == AL_MOD_LFO_DELAY_SOFT || value == AL_MOD_LFO_FREQUENCY_SOFT || + value == AL_VIBRATO_LFO_DELAY_SOFT || value == AL_VIBRATO_LFO_FREQUENCY_SOFT || + value == AL_MOD_ENV_DELAYTIME_SOFT || value == AL_MOD_ENV_ATTACKTIME_SOFT || + value == AL_MOD_ENV_HOLDTIME_SOFT || value == AL_MOD_ENV_DECAYTIME_SOFT || + value == AL_MOD_ENV_SUSTAINVOLUME_SOFT || value == AL_MOD_ENV_RELEASETIME_SOFT || + value == AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT || value == AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT || + value == AL_VOLUME_ENV_DELAYTIME_SOFT || value == AL_VOLUME_ENV_ATTACKTIME_SOFT || + value == AL_VOLUME_ENV_HOLDTIME_SOFT || value == AL_VOLUME_ENV_DECAYTIME_SOFT || + value == AL_VOLUME_ENV_SUSTAINVOLUME_SOFT || value == AL_VOLUME_ENV_RELEASETIME_SOFT || + value == AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT || value == AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT || + value == AL_ATTENUATION_SOFT || value == AL_TUNING_COARSE_SOFT || + value == AL_TUNING_FINE_SOFT || value == AL_TUNING_SCALE_SOFT)) + SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); + ALfontsound_getModStage(self, stage)->Dest = value; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} + +static void ALfontsound_getModStagei(ALfontsound *self, ALCcontext *context, ALsizei stage, ALenum param, ALint *values) +{ + ALsfmodulator *mod = LookupModulator(self, stage); + ALint srcidx = 0; + + switch(param) + { + case AL_SOURCE1_INPUT_SOFT: + srcidx++; + /* fall-through */ + case AL_SOURCE0_INPUT_SOFT: + values[0] = mod ? mod->Source[srcidx].Input : AL_ONE_SOFT; + break; + + case AL_SOURCE1_TYPE_SOFT: + srcidx++; + /* fall-through */ + case AL_SOURCE0_TYPE_SOFT: + values[0] = mod ? mod->Source[srcidx].Type : AL_UNORM_SOFT; + break; + + case AL_SOURCE1_FORM_SOFT: + srcidx++; + /* fall-through */ + case AL_SOURCE0_FORM_SOFT: + values[0] = mod ? mod->Source[srcidx].Form : AL_LINEAR_SOFT; + break; + + case AL_AMOUNT_SOFT: + values[0] = mod ? mod->Amount : 0; + break; + + case AL_TRANSFORM_OP_SOFT: + values[0] = mod ? mod->TransformOp : AL_LINEAR_SOFT; + break; + + case AL_DESTINATION_SOFT: + values[0] = mod ? mod->Dest : AL_NONE; + break; + + default: + SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); + } +} + + +/* ReleaseALFontsounds + * + * Called to destroy any fontsounds that still exist on the device + */ +void ReleaseALFontsounds(ALCdevice *device) +{ + ALsizei i; + for(i = 0;i < device->FontsoundMap.size;i++) + { + ALfontsound *temp = device->FontsoundMap.array[i].value; + device->FontsoundMap.array[i].value = NULL; + + ALfontsound_Destruct(temp); + + memset(temp, 0, sizeof(*temp)); + free(temp); + } +} diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index 682acbb5..87cd3c61 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -28,445 +28,419 @@ AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + switch(param) { - switch(param) - { - case AL_GAIN: - CHECK_VALUE(Context, value >= 0.0f && isfinite(value)); + case AL_GAIN: + if(!(value >= 0.0f && isfinite(value))) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - Context->Listener->Gain = value; - Context->UpdateSources = AL_TRUE; - break; + context->Listener->Gain = value; + context->UpdateSources = AL_TRUE; + break; - case AL_METERS_PER_UNIT: - CHECK_VALUE(Context, value >= 0.0f && isfinite(value)); + case AL_METERS_PER_UNIT: + if(!(value >= 0.0f && isfinite(value))) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - Context->Listener->MetersPerUnit = value; - Context->UpdateSources = AL_TRUE; - break; + context->Listener->MetersPerUnit = value; + context->UpdateSources = AL_TRUE; + break; - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + switch(param) { - switch(param) - { - case AL_POSITION: - CHECK_VALUE(Context, isfinite(value1) && isfinite(value2) && isfinite(value3)); - - LockContext(Context); - Context->Listener->Position[0] = value1; - Context->Listener->Position[1] = value2; - Context->Listener->Position[2] = value3; - Context->UpdateSources = AL_TRUE; - UnlockContext(Context); - break; - - case AL_VELOCITY: - CHECK_VALUE(Context, isfinite(value1) && isfinite(value2) && isfinite(value3)); - - LockContext(Context); - Context->Listener->Velocity[0] = value1; - Context->Listener->Velocity[1] = value2; - Context->Listener->Velocity[2] = value3; - Context->UpdateSources = AL_TRUE; - UnlockContext(Context); - break; - - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + case AL_POSITION: + if(!(isfinite(value1) && isfinite(value2) && isfinite(value3))) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + LockContext(context); + context->Listener->Position[0] = value1; + context->Listener->Position[1] = value2; + context->Listener->Position[2] = value3; + context->UpdateSources = AL_TRUE; + UnlockContext(context); + break; + + case AL_VELOCITY: + if(!(isfinite(value1) && isfinite(value2) && isfinite(value3))) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + LockContext(context); + context->Listener->Velocity[0] = value1; + context->Listener->Velocity[1] = value2; + context->Listener->Velocity[2] = value3; + context->UpdateSources = AL_TRUE; + UnlockContext(context); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values) { - ALCcontext *Context; + ALCcontext *context; if(values) { switch(param) { - case AL_GAIN: - case AL_METERS_PER_UNIT: - alListenerf(param, values[0]); - return; - - case AL_POSITION: - case AL_VELOCITY: - alListener3f(param, values[0], values[1], values[2]); - return; + case AL_GAIN: + case AL_METERS_PER_UNIT: + alListenerf(param, values[0]); + return; + + case AL_POSITION: + case AL_VELOCITY: + alListener3f(param, values[0], values[1], values[2]); + return; } } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) { - CHECK_VALUE(Context, values); - switch(param) - { - case AL_ORIENTATION: - CHECK_VALUE(Context, isfinite(values[0]) && isfinite(values[1]) && - isfinite(values[2]) && isfinite(values[3]) && - isfinite(values[4]) && isfinite(values[5])); - - LockContext(Context); - /* AT then UP */ - Context->Listener->Forward[0] = values[0]; - Context->Listener->Forward[1] = values[1]; - Context->Listener->Forward[2] = values[2]; - Context->Listener->Up[0] = values[3]; - Context->Listener->Up[1] = values[4]; - Context->Listener->Up[2] = values[5]; - Context->UpdateSources = AL_TRUE; - UnlockContext(Context); - break; - - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + case AL_ORIENTATION: + if(!(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2]) && + isfinite(values[3]) && isfinite(values[4]) && isfinite(values[5]))) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + LockContext(context); + /* AT then UP */ + context->Listener->Forward[0] = values[0]; + context->Listener->Forward[1] = values[1]; + context->Listener->Forward[2] = values[2]; + context->Listener->Up[0] = values[3]; + context->Listener->Up[1] = values[4]; + context->Listener->Up[2] = values[5]; + context->UpdateSources = AL_TRUE; + UnlockContext(context); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } -AL_API ALvoid AL_APIENTRY alListeneri(ALenum param, ALint value) +AL_API ALvoid AL_APIENTRY alListeneri(ALenum param, ALint UNUSED(value)) { - ALCcontext *Context; - - (void)value; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + switch(param) { - switch(param) - { - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, ALint value3) { - ALCcontext *Context; + ALCcontext *context; switch(param) { - case AL_POSITION: - case AL_VELOCITY: - alListener3f(param, (ALfloat)value1, (ALfloat)value2, (ALfloat)value3); - return; + case AL_POSITION: + case AL_VELOCITY: + alListener3f(param, (ALfloat)value1, (ALfloat)value2, (ALfloat)value3); + return; } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + switch(param) { - switch(param) - { - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values) { - ALCcontext *Context; + ALCcontext *context; if(values) { ALfloat fvals[6]; switch(param) { - case AL_POSITION: - case AL_VELOCITY: - alListener3f(param, (ALfloat)values[0], (ALfloat)values[1], (ALfloat)values[2]); - return; - - case AL_ORIENTATION: - fvals[0] = (ALfloat)values[0]; - fvals[1] = (ALfloat)values[1]; - fvals[2] = (ALfloat)values[2]; - fvals[3] = (ALfloat)values[3]; - fvals[4] = (ALfloat)values[4]; - fvals[5] = (ALfloat)values[5]; - alListenerfv(param, fvals); - return; + case AL_POSITION: + case AL_VELOCITY: + alListener3f(param, (ALfloat)values[0], (ALfloat)values[1], (ALfloat)values[2]); + return; + + case AL_ORIENTATION: + fvals[0] = (ALfloat)values[0]; + fvals[1] = (ALfloat)values[1]; + fvals[2] = (ALfloat)values[2]; + fvals[3] = (ALfloat)values[3]; + fvals[4] = (ALfloat)values[4]; + fvals[5] = (ALfloat)values[5]; + alListenerfv(param, fvals); + return; } } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) { - CHECK_VALUE(Context, values); - switch(param) - { - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(!(value)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) { - CHECK_VALUE(Context, value); - switch(param) - { - case AL_GAIN: - *value = Context->Listener->Gain; - break; + case AL_GAIN: + *value = context->Listener->Gain; + break; - case AL_METERS_PER_UNIT: - *value = Context->Listener->MetersPerUnit; - break; + case AL_METERS_PER_UNIT: + *value = context->Listener->MetersPerUnit; + break; - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alGetListener3f(ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(!(value1 && value2 && value3)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) { - CHECK_VALUE(Context, value1 && value2 && value3); - switch(param) - { - case AL_POSITION: - LockContext(Context); - *value1 = Context->Listener->Position[0]; - *value2 = Context->Listener->Position[1]; - *value3 = Context->Listener->Position[2]; - UnlockContext(Context); - break; - - case AL_VELOCITY: - LockContext(Context); - *value1 = Context->Listener->Velocity[0]; - *value2 = Context->Listener->Velocity[1]; - *value3 = Context->Listener->Velocity[2]; - UnlockContext(Context); - break; - - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + case AL_POSITION: + LockContext(context); + *value1 = context->Listener->Position[0]; + *value2 = context->Listener->Position[1]; + *value3 = context->Listener->Position[2]; + UnlockContext(context); + break; + + case AL_VELOCITY: + LockContext(context); + *value1 = context->Listener->Velocity[0]; + *value2 = context->Listener->Velocity[1]; + *value3 = context->Listener->Velocity[2]; + UnlockContext(context); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values) { - ALCcontext *Context; + ALCcontext *context; switch(param) { - case AL_GAIN: - case AL_METERS_PER_UNIT: - alGetListenerf(param, values); - return; - - case AL_POSITION: - case AL_VELOCITY: - alGetListener3f(param, values+0, values+1, values+2); - return; + case AL_GAIN: + case AL_METERS_PER_UNIT: + alGetListenerf(param, values); + return; + + case AL_POSITION: + case AL_VELOCITY: + alGetListener3f(param, values+0, values+1, values+2); + return; } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) { - CHECK_VALUE(Context, values); - switch(param) - { - case AL_ORIENTATION: - LockContext(Context); - // AT then UP - values[0] = Context->Listener->Forward[0]; - values[1] = Context->Listener->Forward[1]; - values[2] = Context->Listener->Forward[2]; - values[3] = Context->Listener->Up[0]; - values[4] = Context->Listener->Up[1]; - values[5] = Context->Listener->Up[2]; - UnlockContext(Context); - break; - - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + case AL_ORIENTATION: + LockContext(context); + // AT then UP + values[0] = context->Listener->Forward[0]; + values[1] = context->Listener->Forward[1]; + values[2] = context->Listener->Forward[2]; + values[3] = context->Listener->Up[0]; + values[4] = context->Listener->Up[1]; + values[5] = context->Listener->Up[2]; + UnlockContext(context); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alGetListeneri(ALenum param, ALint *value) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(!(value)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) { - CHECK_VALUE(Context, value); - switch(param) - { - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API void AL_APIENTRY alGetListener3i(ALenum param, ALint *value1, ALint *value2, ALint *value3) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(!(value1 && value2 && value3)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch (param) { - CHECK_VALUE(Context, value1 && value2 && value3); - switch (param) - { - case AL_POSITION: - LockContext(Context); - *value1 = (ALint)Context->Listener->Position[0]; - *value2 = (ALint)Context->Listener->Position[1]; - *value3 = (ALint)Context->Listener->Position[2]; - UnlockContext(Context); - break; - - case AL_VELOCITY: - LockContext(Context); - *value1 = (ALint)Context->Listener->Velocity[0]; - *value2 = (ALint)Context->Listener->Velocity[1]; - *value3 = (ALint)Context->Listener->Velocity[2]; - UnlockContext(Context); - break; - - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + case AL_POSITION: + LockContext(context); + *value1 = (ALint)context->Listener->Position[0]; + *value2 = (ALint)context->Listener->Position[1]; + *value3 = (ALint)context->Listener->Position[2]; + UnlockContext(context); + break; + + case AL_VELOCITY: + LockContext(context); + *value1 = (ALint)context->Listener->Velocity[0]; + *value2 = (ALint)context->Listener->Velocity[1]; + *value3 = (ALint)context->Listener->Velocity[2]; + UnlockContext(context); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API void AL_APIENTRY alGetListeneriv(ALenum param, ALint* values) { - ALCcontext *Context; + ALCcontext *context; switch(param) { - case AL_POSITION: - case AL_VELOCITY: - alGetListener3i(param, values+0, values+1, values+2); - return; + case AL_POSITION: + case AL_VELOCITY: + alGetListener3i(param, values+0, values+1, values+2); + return; } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(param) { - CHECK_VALUE(Context, values); - switch(param) - { - case AL_ORIENTATION: - LockContext(Context); - // AT then UP - values[0] = (ALint)Context->Listener->Forward[0]; - values[1] = (ALint)Context->Listener->Forward[1]; - values[2] = (ALint)Context->Listener->Forward[2]; - values[3] = (ALint)Context->Listener->Up[0]; - values[4] = (ALint)Context->Listener->Up[1]; - values[5] = (ALint)Context->Listener->Up[2]; - UnlockContext(Context); - break; - - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + case AL_ORIENTATION: + LockContext(context); + // AT then UP + values[0] = (ALint)context->Listener->Forward[0]; + values[1] = (ALint)context->Listener->Forward[1]; + values[2] = (ALint)context->Listener->Forward[2]; + values[3] = (ALint)context->Listener->Up[0]; + values[4] = (ALint)context->Listener->Up[1]; + values[5] = (ALint)context->Listener->Up[2]; + UnlockContext(context); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } diff --git a/OpenAL32/alMidi.c b/OpenAL32/alMidi.c new file mode 100644 index 00000000..0679b64c --- /dev/null +++ b/OpenAL32/alMidi.c @@ -0,0 +1,221 @@ + +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> + +#include "alMain.h" +#include "alMidi.h" +#include "alError.h" +#include "alThunk.h" +#include "evtqueue.h" +#include "rwlock.h" +#include "alu.h" + +#include "midi/base.h" + + +MidiSynth *SynthCreate(ALCdevice *device) +{ + MidiSynth *synth = FSynth_create(device); + if(!synth) synth = DSynth_create(device); + return synth; +} + + +AL_API void AL_APIENTRY alMidiSoundfontSOFT(ALuint id) +{ + alMidiSoundfontvSOFT(1, &id); +} + +AL_API void AL_APIENTRY alMidiSoundfontvSOFT(ALsizei count, const ALuint *ids) +{ + ALCdevice *device; + ALCcontext *context; + MidiSynth *synth; + ALenum err; + + context = GetContextRef(); + if(!context) return; + + if(count < 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + synth = device->Synth; + + WriteLock(&synth->Lock); + if(synth->State == AL_PLAYING || synth->State == AL_PAUSED) + alSetError(context, AL_INVALID_OPERATION); + else + { + err = V(synth,selectSoundfonts)(context, count, ids); + if(err != AL_NO_ERROR) + alSetError(context, err); + } + WriteUnlock(&synth->Lock); + +done: + ALCcontext_DecRef(context); +} + + +AL_API void AL_APIENTRY alMidiEventSOFT(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2) +{ + ALCdevice *device; + ALCcontext *context; + ALenum err; + + context = GetContextRef(); + if(!context) return; + + if(!(event == AL_NOTEOFF_SOFT || event == AL_NOTEON_SOFT || + event == AL_KEYPRESSURE_SOFT || event == AL_CONTROLLERCHANGE_SOFT || + event == AL_PROGRAMCHANGE_SOFT || event == AL_CHANNELPRESSURE_SOFT || + event == AL_PITCHBEND_SOFT)) + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + if(!(channel >= 0 && channel <= 15)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(!(param1 >= 0 && param1 <= 127)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(!(param2 >= 0 && param2 <= 127)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + ALCdevice_Lock(device); + err = MidiSynth_insertEvent(device->Synth, time, event|channel, param1, param2); + ALCdevice_Unlock(device); + if(err != AL_NO_ERROR) + alSetError(context, err); + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alMidiSysExSOFT(ALuint64SOFT time, const ALbyte *data, ALsizei size) +{ + ALCdevice *device; + ALCcontext *context; + ALenum err; + ALsizei i; + + context = GetContextRef(); + if(!context) return; + + if(!data || size < 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + for(i = 0;i < size;i++) + { + if((data[i]&0x80)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + } + + device = context->Device; + ALCdevice_Lock(device); + err = MidiSynth_insertSysExEvent(device->Synth, time, data, size); + ALCdevice_Unlock(device); + if(err != AL_NO_ERROR) + alSetError(context, err); + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alMidiPlaySOFT(void) +{ + ALCcontext *context; + MidiSynth *synth; + + context = GetContextRef(); + if(!context) return; + + synth = context->Device->Synth; + WriteLock(&synth->Lock); + V(synth,setState)(AL_PLAYING); + WriteUnlock(&synth->Lock); + + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alMidiPauseSOFT(void) +{ + ALCcontext *context; + MidiSynth *synth; + + context = GetContextRef(); + if(!context) return; + + synth = context->Device->Synth; + WriteLock(&synth->Lock); + V(synth,setState)(AL_PAUSED); + WriteUnlock(&synth->Lock); + + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alMidiStopSOFT(void) +{ + ALCdevice *device; + ALCcontext *context; + MidiSynth *synth; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + synth = device->Synth; + + WriteLock(&synth->Lock); + V(synth,setState)(AL_STOPPED); + + ALCdevice_Lock(device); + V0(synth,stop)(); + ALCdevice_Unlock(device); + WriteUnlock(&synth->Lock); + + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alMidiResetSOFT(void) +{ + ALCdevice *device; + ALCcontext *context; + MidiSynth *synth; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + synth = device->Synth; + + WriteLock(&synth->Lock); + V(synth,setState)(AL_INITIAL); + + ALCdevice_Lock(device); + V0(synth,reset)(); + ALCdevice_Unlock(device); + WriteUnlock(&synth->Lock); + + ALCcontext_DecRef(context); +} + + +AL_API void AL_APIENTRY alMidiGainSOFT(ALfloat value) +{ + ALCdevice *device; + ALCcontext *context; + + context = GetContextRef(); + if(!context) return; + + if(!(value >= 0.0f && isfinite(value))) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + V(device->Synth,setGain)(value); + +done: + ALCcontext_DecRef(context); +} diff --git a/OpenAL32/alPreset.c b/OpenAL32/alPreset.c new file mode 100644 index 00000000..d34772a4 --- /dev/null +++ b/OpenAL32/alPreset.c @@ -0,0 +1,340 @@ + +#include "config.h" + +#include <stdlib.h> +#include <string.h> + +#include "alMain.h" +#include "alMidi.h" +#include "alError.h" +#include "alThunk.h" + +#include "midi/base.h" + + +extern inline struct ALsfpreset *LookupPreset(ALCdevice *device, ALuint id); +extern inline struct ALsfpreset *RemovePreset(ALCdevice *device, ALuint id); + +static void ALsfpreset_Construct(ALsfpreset *self); +void ALsfpreset_Destruct(ALsfpreset *self); + + +AL_API void AL_APIENTRY alGenPresetsSOFT(ALsizei n, ALuint *ids) +{ + ALCcontext *context; + ALsizei cur = 0; + + context = GetContextRef(); + if(!context) return; + + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + for(cur = 0;cur < n;cur++) + { + ALsfpreset *preset = NewPreset(context); + if(!preset) + { + alDeletePresetsSOFT(cur, ids); + break; + } + + ids[cur] = preset->id; + } + +done: + ALCcontext_DecRef(context); +} + +AL_API ALvoid AL_APIENTRY alDeletePresetsSOFT(ALsizei n, const ALuint *ids) +{ + ALCdevice *device; + ALCcontext *context; + ALsfpreset *preset; + ALsizei i; + + context = GetContextRef(); + if(!context) return; + + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + for(i = 0;i < n;i++) + { + /* Check for valid ID */ + if((preset=LookupPreset(device, ids[i])) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(preset->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + } + + for(i = 0;i < n;i++) + { + if((preset=LookupPreset(device, ids[i])) == NULL) + continue; + DeletePreset(preset, device); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API ALboolean AL_APIENTRY alIsPresetSOFT(ALuint id) +{ + ALCcontext *context; + ALboolean ret; + + context = GetContextRef(); + if(!context) return AL_FALSE; + + ret = LookupPreset(context->Device, id) ? AL_TRUE : AL_FALSE; + + ALCcontext_DecRef(context); + + return ret; +} + +AL_API void AL_APIENTRY alPresetiSOFT(ALuint id, ALenum param, ALint value) +{ + ALCdevice *device; + ALCcontext *context; + ALsfpreset *preset; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if((preset=LookupPreset(device, id)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(preset->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + switch(param) + { + case AL_MIDI_PRESET_SOFT: + if(!(value >= 0 && value <= 127)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + preset->Preset = value; + break; + + case AL_MIDI_BANK_SOFT: + if(!(value >= 0 && value <= 128)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + preset->Bank = value; + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alPresetivSOFT(ALuint id, ALenum param, const ALint *values) +{ + ALCdevice *device; + ALCcontext *context; + ALsfpreset *preset; + + switch(param) + { + case AL_MIDI_PRESET_SOFT: + case AL_MIDI_BANK_SOFT: + alPresetiSOFT(id, param, values[0]); + return; + } + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if((preset=LookupPreset(device, id)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(preset->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + switch(param) + { + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alGetPresetivSOFT(ALuint id, ALenum param, ALint *values) +{ + ALCdevice *device; + ALCcontext *context; + ALsfpreset *preset; + ALsizei i; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if((preset=LookupPreset(device, id)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) + { + case AL_MIDI_PRESET_SOFT: + values[0] = preset->Preset; + break; + + case AL_MIDI_BANK_SOFT: + values[0] = preset->Bank; + break; + + case AL_FONTSOUNDS_SIZE_SOFT: + values[0] = preset->NumSounds; + break; + + case AL_FONTSOUNDS_SOFT: + for(i = 0;i < preset->NumSounds;i++) + values[i] = preset->Sounds[i]->id; + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alPresetFontsoundsSOFT(ALuint id, ALsizei count, const ALuint *fsids) +{ + ALCdevice *device; + ALCcontext *context; + ALsfpreset *preset; + ALfontsound **sounds; + ALsizei i; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(!(preset=LookupPreset(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(count < 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + if(preset->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + + if(count == 0) + sounds = NULL; + else + { + sounds = calloc(count, sizeof(sounds[0])); + if(!sounds) + SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); + + for(i = 0;i < count;i++) + { + if(!(sounds[i]=LookupFontsound(device, fsids[i]))) + { + free(sounds); + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + } + } + } + + for(i = 0;i < count;i++) + IncrementRef(&sounds[i]->ref); + + sounds = ExchangePtr((XchgPtr*)&preset->Sounds, sounds); + count = ExchangeInt(&preset->NumSounds, count); + + for(i = 0;i < count;i++) + DecrementRef(&sounds[i]->ref); + free(sounds); + +done: + ALCcontext_DecRef(context); +} + + +ALsfpreset *NewPreset(ALCcontext *context) +{ + ALCdevice *device = context->Device; + ALsfpreset *preset; + ALenum err; + + preset = calloc(1, sizeof(*preset)); + if(!preset) + SET_ERROR_AND_RETURN_VALUE(context, AL_OUT_OF_MEMORY, NULL); + ALsfpreset_Construct(preset); + + err = NewThunkEntry(&preset->id); + if(err == AL_NO_ERROR) + err = InsertUIntMapEntry(&device->PresetMap, preset->id, preset); + if(err != AL_NO_ERROR) + { + ALsfpreset_Destruct(preset); + memset(preset, 0, sizeof(*preset)); + free(preset); + + SET_ERROR_AND_RETURN_VALUE(context, err, NULL); + } + + return preset; +} + +void DeletePreset(ALsfpreset *preset, ALCdevice *device) +{ + RemovePreset(device, preset->id); + + ALsfpreset_Destruct(preset); + memset(preset, 0, sizeof(*preset)); + free(preset); +} + + +static void ALsfpreset_Construct(ALsfpreset *self) +{ + self->ref = 0; + + self->Preset = 0; + self->Bank = 0; + + self->Sounds = NULL; + self->NumSounds = 0; + + self->id = 0; +} + +void ALsfpreset_Destruct(ALsfpreset *self) +{ + ALsizei i; + + FreeThunkEntry(self->id); + self->id = 0; + + for(i = 0;i < self->NumSounds;i++) + DecrementRef(&self->Sounds[i]->ref); + free(self->Sounds); + self->Sounds = NULL; + self->NumSounds = 0; +} + + +/* ReleaseALPresets + * + * Called to destroy any presets that still exist on the device + */ +void ReleaseALPresets(ALCdevice *device) +{ + ALsizei i; + for(i = 0;i < device->PresetMap.size;i++) + { + ALsfpreset *temp = device->PresetMap.array[i].value; + device->PresetMap.array[i].value = NULL; + + ALsfpreset_Destruct(temp); + + memset(temp, 0, sizeof(*temp)); + free(temp); + } +} diff --git a/OpenAL32/alSoundfont.c b/OpenAL32/alSoundfont.c new file mode 100644 index 00000000..355c5b41 --- /dev/null +++ b/OpenAL32/alSoundfont.c @@ -0,0 +1,563 @@ + +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "alMain.h" +#include "alMidi.h" +#include "alThunk.h" +#include "alError.h" + +#include "midi/base.h" + + +extern inline struct ALsoundfont *LookupSfont(ALCdevice *device, ALuint id); +extern inline struct ALsoundfont *RemoveSfont(ALCdevice *device, ALuint id); + +void ALsoundfont_Construct(ALsoundfont *self); +void ALsoundfont_Destruct(ALsoundfont *self); +void ALsoundfont_deleteSoundfont(ALsoundfont *self, ALCdevice *device); +ALsoundfont *ALsoundfont_getDefSoundfont(ALCcontext *context); +static size_t ALsoundfont_read(ALvoid *buf, size_t bytes, ALvoid *ptr); + + +AL_API void AL_APIENTRY alGenSoundfontsSOFT(ALsizei n, ALuint *ids) +{ + ALCdevice *device; + ALCcontext *context; + ALsizei cur = 0; + ALenum err; + + context = GetContextRef(); + if(!context) return; + + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + for(cur = 0;cur < n;cur++) + { + ALsoundfont *sfont = calloc(1, sizeof(ALsoundfont)); + if(!sfont) + { + alDeleteSoundfontsSOFT(cur, ids); + SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); + } + ALsoundfont_Construct(sfont); + + err = NewThunkEntry(&sfont->id); + if(err == AL_NO_ERROR) + err = InsertUIntMapEntry(&device->SfontMap, sfont->id, sfont); + if(err != AL_NO_ERROR) + { + ALsoundfont_Destruct(sfont); + memset(sfont, 0, sizeof(ALsoundfont)); + free(sfont); + + alDeleteSoundfontsSOFT(cur, ids); + SET_ERROR_AND_GOTO(context, err, done); + } + + ids[cur] = sfont->id; + } + +done: + ALCcontext_DecRef(context); +} + +AL_API ALvoid AL_APIENTRY alDeleteSoundfontsSOFT(ALsizei n, const ALuint *ids) +{ + ALCdevice *device; + ALCcontext *context; + ALsoundfont *sfont; + ALsizei i; + + context = GetContextRef(); + if(!context) return; + + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + device = context->Device; + for(i = 0;i < n;i++) + { + /* Check for valid soundfont ID */ + if(ids[i] == 0) + { + if(!(sfont=device->DefaultSfont)) + continue; + } + else if((sfont=LookupSfont(device, ids[i])) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(sfont->Mapped != AL_FALSE || sfont->ref != 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + } + + for(i = 0;i < n;i++) + { + if(ids[i] == 0) + { + MidiSynth *synth = device->Synth; + WriteLock(&synth->Lock); + if(device->DefaultSfont != NULL) + ALsoundfont_deleteSoundfont(device->DefaultSfont, device); + device->DefaultSfont = NULL; + WriteUnlock(&synth->Lock); + continue; + } + else if((sfont=RemoveSfont(device, ids[i])) == NULL) + continue; + + ALsoundfont_Destruct(sfont); + + memset(sfont, 0, sizeof(*sfont)); + free(sfont); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API ALboolean AL_APIENTRY alIsSoundfontSOFT(ALuint id) +{ + ALCcontext *context; + ALboolean ret; + + context = GetContextRef(); + if(!context) return AL_FALSE; + + ret = ((!id || LookupSfont(context->Device, id)) ? + AL_TRUE : AL_FALSE); + + ALCcontext_DecRef(context); + + return ret; +} + +AL_API ALvoid AL_APIENTRY alSoundfontSamplesSOFT(ALuint id, ALenum type, ALsizei count, const ALvoid *samples) +{ + ALCdevice *device; + ALCcontext *context; + ALsoundfont *sfont; + void *ptr; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(id == 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + if(!(sfont=LookupSfont(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(type != AL_SHORT_SOFT) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(count <= 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + WriteLock(&sfont->Lock); + if(sfont->ref != 0) + alSetError(context, AL_INVALID_OPERATION); + else if(sfont->Mapped) + alSetError(context, AL_INVALID_OPERATION); + else if(!(ptr=realloc(sfont->Samples, count * sizeof(ALshort)))) + alSetError(context, AL_OUT_OF_MEMORY); + else + { + sfont->Samples = ptr; + sfont->NumSamples = count; + if(samples != NULL) + memcpy(sfont->Samples, samples, count * sizeof(ALshort)); + } + WriteUnlock(&sfont->Lock); + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alGetSoundfontSamplesSOFT(ALuint id, ALsizei offset, ALsizei count, ALenum type, ALvoid *samples) +{ + ALCdevice *device; + ALCcontext *context; + ALsoundfont *sfont; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(id == 0) + sfont = ALsoundfont_getDefSoundfont(context); + else if(!(sfont=LookupSfont(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(type != AL_SHORT_SOFT) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(offset < 0 || count <= 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + ReadLock(&sfont->Lock); + if(offset >= sfont->NumSamples || count > (sfont->NumSamples-offset)) + alSetError(context, AL_INVALID_VALUE); + else if(sfont->Mapped) + alSetError(context, AL_INVALID_OPERATION); + else + { + /* TODO: Allow conversion. */ + memcpy(samples, sfont->Samples + offset*sizeof(ALshort), count * sizeof(ALshort)); + } + ReadUnlock(&sfont->Lock); + +done: + ALCcontext_DecRef(context); +} + +AL_API ALvoid* AL_APIENTRY alSoundfontMapSamplesSOFT(ALuint id, ALsizei offset, ALsizei length) +{ + ALCdevice *device; + ALCcontext *context; + ALsoundfont *sfont; + ALvoid *ptr = NULL; + + context = GetContextRef(); + if(!context) return NULL; + + device = context->Device; + if(id == 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + if(!(sfont=LookupSfont(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(offset < 0 || (ALuint)offset > sfont->NumSamples*sizeof(ALshort)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if(length <= 0 || (ALuint)length > (sfont->NumSamples*sizeof(ALshort) - offset)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + ReadLock(&sfont->Lock); + if(sfont->ref != 0) + alSetError(context, AL_INVALID_OPERATION); + else if(ExchangeInt(&sfont->Mapped, AL_TRUE) == AL_TRUE) + alSetError(context, AL_INVALID_OPERATION); + else + ptr = (ALbyte*)sfont->Samples + offset; + ReadUnlock(&sfont->Lock); + +done: + ALCcontext_DecRef(context); + + return ptr; +} + +AL_API ALvoid AL_APIENTRY alSoundfontUnmapSamplesSOFT(ALuint id) +{ + ALCdevice *device; + ALCcontext *context; + ALsoundfont *sfont; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(id == 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + if(!(sfont=LookupSfont(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(ExchangeInt(&sfont->Mapped, AL_FALSE) == AL_FALSE) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alGetSoundfontivSOFT(ALuint id, ALenum param, ALint *values) +{ + ALCdevice *device; + ALCcontext *context; + ALsoundfont *sfont; + ALsizei i; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(id == 0) + sfont = ALsoundfont_getDefSoundfont(context); + else if(!(sfont=LookupSfont(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + switch(param) + { + case AL_PRESETS_SIZE_SOFT: + values[0] = sfont->NumPresets; + break; + + case AL_PRESETS_SOFT: + for(i = 0;i < sfont->NumPresets;i++) + values[i] = sfont->Presets[i]->id; + break; + + case AL_SAMPLE_LENGTH_SOFT: + values[0] = sfont->NumSamples; + break; + + case AL_FORMAT_TYPE_SOFT: + values[0] = AL_SHORT_SOFT; + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alSoundfontPresetsSOFT(ALuint id, ALsizei count, const ALuint *pids) +{ + ALCdevice *device; + ALCcontext *context; + ALsoundfont *sfont; + ALsfpreset **presets; + ALsizei i; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(id == 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + if(!(sfont=LookupSfont(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + if(count < 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + WriteLock(&sfont->Lock); + if(sfont->ref != 0) + { + WriteUnlock(&sfont->Lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + } + + if(count == 0) + presets = NULL; + else + { + presets = calloc(count, sizeof(presets[0])); + if(!presets) + { + WriteUnlock(&sfont->Lock); + SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); + } + + for(i = 0;i < count;i++) + { + if(!(presets[i]=LookupPreset(device, pids[i]))) + { + WriteUnlock(&sfont->Lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + } + } + } + + for(i = 0;i < count;i++) + IncrementRef(&presets[i]->ref); + + presets = ExchangePtr((XchgPtr*)&sfont->Presets, presets); + count = ExchangeInt(&sfont->NumPresets, count); + WriteUnlock(&sfont->Lock); + + for(i = 0;i < count;i++) + DecrementRef(&presets[i]->ref); + free(presets); + +done: + ALCcontext_DecRef(context); +} + + +AL_API void AL_APIENTRY alLoadSoundfontSOFT(ALuint id, size_t(*cb)(ALvoid*,size_t,ALvoid*), ALvoid *user) +{ + ALCdevice *device; + ALCcontext *context; + ALsoundfont *sfont; + Reader reader; + + context = GetContextRef(); + if(!context) return; + + device = context->Device; + if(id == 0) + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + if(!(sfont=LookupSfont(device, id))) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + + WriteLock(&sfont->Lock); + if(sfont->ref != 0) + { + WriteUnlock(&sfont->Lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + } + if(sfont->Mapped) + { + WriteUnlock(&sfont->Lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + } + if(sfont->NumPresets > 0) + { + WriteUnlock(&sfont->Lock); + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + } + + reader.cb = cb; + reader.ptr = user; + reader.error = 0; + loadSf2(&reader, sfont, context); + WriteUnlock(&sfont->Lock); + +done: + ALCcontext_DecRef(context); +} + + +void ALsoundfont_Construct(ALsoundfont *self) +{ + self->ref = 0; + + self->Presets = NULL; + self->NumPresets = 0; + + self->Samples = NULL; + self->NumSamples = 0; + + RWLockInit(&self->Lock); + self->Mapped = AL_FALSE; + + self->id = 0; +} + +void ALsoundfont_Destruct(ALsoundfont *self) +{ + ALsizei i; + + FreeThunkEntry(self->id); + self->id = 0; + + for(i = 0;i < self->NumPresets;i++) + { + DecrementRef(&self->Presets[i]->ref); + self->Presets[i] = NULL; + } + free(self->Presets); + self->Presets = NULL; + self->NumPresets = 0; + + free(self->Samples); + self->Samples = NULL; + self->NumSamples = 0; +} + +ALsoundfont *ALsoundfont_getDefSoundfont(ALCcontext *context) +{ + ALCdevice *device = context->Device; + const char *fname; + + if(device->DefaultSfont) + return device->DefaultSfont; + + device->DefaultSfont = calloc(1, sizeof(device->DefaultSfont[0])); + ALsoundfont_Construct(device->DefaultSfont); + + fname = getenv("ALSOFT_SOUNDFONT"); + if((fname && fname[0]) || ConfigValueStr("midi", "soundfont", &fname)) + { + FILE *f; + + f = fopen(fname, "rb"); + if(f == NULL) + ERR("Failed to open %s\n", fname); + else + { + Reader reader; + reader.cb = ALsoundfont_read; + reader.ptr = f; + reader.error = 0; + TRACE("Loading %s\n", fname); + loadSf2(&reader, device->DefaultSfont, context); + fclose(f); + } + } + + return device->DefaultSfont; +} + +void ALsoundfont_deleteSoundfont(ALsoundfont *self, ALCdevice *device) +{ + ALsfpreset **presets; + ALsizei num_presets; + ALsizei i; + + presets = ExchangePtr((XchgPtr*)&self->Presets, NULL); + num_presets = ExchangeInt(&self->NumPresets, 0); + + for(i = 0;i < num_presets;i++) + { + ALsfpreset *preset = presets[i]; + ALfontsound **sounds; + ALsizei num_sounds; + ALboolean deleting; + ALsizei j; + + sounds = ExchangePtr((XchgPtr*)&preset->Sounds, NULL); + num_sounds = ExchangeInt(&preset->NumSounds, 0); + DeletePreset(preset, device); + preset = NULL; + + for(j = 0;j < num_sounds;j++) + DecrementRef(&sounds[j]->ref); + /* Some fontsounds may not be immediately deletable because they're + * linked to another fontsound. When those fontsounds are deleted + * they should become deletable, so use a loop until all fontsounds + * are deleted. */ + do { + deleting = AL_FALSE; + for(j = 0;j < num_sounds;j++) + { + if(sounds[j] && sounds[j]->ref == 0) + { + deleting = AL_TRUE; + RemoveFontsound(device, sounds[j]->id); + ALfontsound_Destruct(sounds[j]); + free(sounds[j]); + sounds[j] = NULL; + } + } + } while(deleting); + free(sounds); + } + + ALsoundfont_Destruct(self); + free(self); +} + + +static size_t ALsoundfont_read(ALvoid *buf, size_t bytes, ALvoid *ptr) +{ + return fread(buf, 1, bytes, (FILE*)ptr); +} + + +/* ReleaseALSoundfonts + * + * Called to destroy any soundfonts that still exist on the device + */ +void ReleaseALSoundfonts(ALCdevice *device) +{ + ALsizei i; + for(i = 0;i < device->SfontMap.size;i++) + { + ALsoundfont *temp = device->SfontMap.array[i].value; + device->SfontMap.array[i].value = NULL; + + ALsoundfont_Destruct(temp); + + memset(temp, 0, sizeof(*temp)); + free(temp); + } +} diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 5dbea314..543910db 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -47,6 +47,9 @@ const ALsizei ResamplerPrePadding[ResamplerMax] = { }; +extern inline struct ALsource *LookupSource(ALCcontext *context, ALuint id); +extern inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id); + static ALvoid InitSourceParams(ALsource *Source); static ALint64 GetSourceOffset(const ALsource *Source); static ALdouble GetSourceSecOffset(const ALsource *Source); @@ -145,13 +148,13 @@ typedef enum SrcIntProp { siSampleOffsetLatencySOFT = AL_SAMPLE_OFFSET_LATENCY_SOFT, } SrcIntProp; -static ALenum SetSourcefv(ALsource *Source, ALCcontext *Context, SrcFloatProp prop, const ALfloat *values); -static ALenum SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint *values); -static ALenum SetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint64SOFT *values); +static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SrcFloatProp prop, const ALfloat *values); +static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint *values); +static ALboolean SetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint64SOFT *values); -static ALenum GetSourcedv(const ALsource *Source, ALCcontext *Context, SrcFloatProp prop, ALdouble *values); -static ALenum GetSourceiv(const ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint *values); -static ALenum GetSourcei64v(const ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint64 *values); +static ALboolean GetSourcedv(const ALsource *Source, ALCcontext *Context, SrcFloatProp prop, ALdouble *values); +static ALboolean GetSourceiv(const ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint *values); +static ALboolean GetSourcei64v(const ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint64 *values); static ALint FloatValsByProp(ALenum prop) { @@ -344,17 +347,12 @@ static ALint Int64ValsByProp(ALenum prop) } -#define RETERR(x) do { \ - alSetError(Context, (x)); \ - return (x); \ -} while(0) - #define CHECKVAL(x) do { \ if(!(x)) \ - RETERR(AL_INVALID_VALUE); \ + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); \ } while(0) -static ALenum SetSourcefv(ALsource *Source, ALCcontext *Context, SrcFloatProp prop, const ALfloat *values) +static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SrcFloatProp prop, const ALfloat *values) { ALint ival; @@ -365,98 +363,98 @@ static ALenum SetSourcefv(ALsource *Source, ALCcontext *Context, SrcFloatProp pr Source->Pitch = *values; Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_CONE_INNER_ANGLE: CHECKVAL(*values >= 0.0f && *values <= 360.0f); Source->InnerAngle = *values; Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_CONE_OUTER_ANGLE: CHECKVAL(*values >= 0.0f && *values <= 360.0f); Source->OuterAngle = *values; Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_GAIN: CHECKVAL(*values >= 0.0f); Source->Gain = *values; Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_MAX_DISTANCE: CHECKVAL(*values >= 0.0f); Source->MaxDistance = *values; Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_ROLLOFF_FACTOR: CHECKVAL(*values >= 0.0f); Source->RollOffFactor = *values; Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_REFERENCE_DISTANCE: CHECKVAL(*values >= 0.0f); Source->RefDistance = *values; Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_MIN_GAIN: CHECKVAL(*values >= 0.0f && *values <= 1.0f); Source->MinGain = *values; Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_MAX_GAIN: CHECKVAL(*values >= 0.0f && *values <= 1.0f); Source->MaxGain = *values; Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_CONE_OUTER_GAIN: CHECKVAL(*values >= 0.0f && *values <= 1.0f); Source->OuterGain = *values; Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_CONE_OUTER_GAINHF: CHECKVAL(*values >= 0.0f && *values <= 1.0f); Source->OuterGainHF = *values; Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_AIR_ABSORPTION_FACTOR: CHECKVAL(*values >= 0.0f && *values <= 10.0f); Source->AirAbsorptionFactor = *values; Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_ROOM_ROLLOFF_FACTOR: CHECKVAL(*values >= 0.0f && *values <= 10.0f); Source->RoomRolloffFactor = *values; Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_DOPPLER_FACTOR: CHECKVAL(*values >= 0.0f && *values <= 1.0f); Source->DopplerFactor = *values; Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_SEC_OFFSET: case AL_SAMPLE_OFFSET: @@ -473,16 +471,16 @@ static ALenum SetSourcefv(ALsource *Source, ALCcontext *Context, SrcFloatProp pr if(ApplyOffset(Source) == AL_FALSE) { UnlockContext(Context); - RETERR(AL_INVALID_VALUE); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); } } UnlockContext(Context); - return AL_NO_ERROR; + return AL_TRUE; case AL_SEC_OFFSET_LATENCY_SOFT: /* Query only */ - RETERR(AL_INVALID_OPERATION); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); case AL_POSITION: @@ -494,7 +492,7 @@ static ALenum SetSourcefv(ALsource *Source, ALCcontext *Context, SrcFloatProp pr Source->Position[2] = values[2]; UnlockContext(Context); Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_VELOCITY: CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2])); @@ -505,7 +503,7 @@ static ALenum SetSourcefv(ALsource *Source, ALCcontext *Context, SrcFloatProp pr Source->Velocity[2] = values[2]; UnlockContext(Context); Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_DIRECTION: CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2])); @@ -516,12 +514,12 @@ static ALenum SetSourcefv(ALsource *Source, ALCcontext *Context, SrcFloatProp pr Source->Orientation[2] = values[2]; UnlockContext(Context); Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case sfSampleRWOffsetsSOFT: case sfByteRWOffsetsSOFT: - RETERR(AL_INVALID_OPERATION); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); case sfSourceRelative: @@ -534,20 +532,20 @@ static ALenum SetSourcefv(ALsource *Source, ALCcontext *Context, SrcFloatProp pr case sfAuxSendFilterGainHFAuto: case sfDirectChannelsSOFT: ival = (ALint)values[0]; - return SetSourceiv(Source, Context, prop, &ival); + return SetSourceiv(Source, Context, (SrcIntProp)prop, &ival); case sfBuffer: case sfBuffersQueued: case sfBuffersProcessed: ival = (ALint)((ALuint)values[0]); - return SetSourceiv(Source, Context, prop, &ival); + return SetSourceiv(Source, Context, (SrcIntProp)prop, &ival); } ERR("Unexpected property: 0x%04x\n", prop); - RETERR(AL_INVALID_ENUM); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); } -static ALenum SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint *values) +static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint *values) { ALCdevice *device = Context->Device; ALbuffer *buffer = NULL; @@ -563,13 +561,13 @@ static ALenum SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop Source->HeadRelative = (ALboolean)*values; Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_LOOPING: CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); Source->Looping = (ALboolean)*values; - return AL_NO_ERROR; + return AL_TRUE; case AL_BUFFER: CHECKVAL(*values == 0 || (buffer=LookupBuffer(device, *values)) != NULL); @@ -578,7 +576,7 @@ static ALenum SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop if(!(Source->state == AL_STOPPED || Source->state == AL_INITIAL)) { UnlockContext(Context); - RETERR(AL_INVALID_OPERATION); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); } Source->BuffersInQueue = 0; @@ -629,14 +627,14 @@ static ALenum SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop free(temp); } UnlockContext(Context); - return AL_NO_ERROR; + return AL_TRUE; case siSourceState: case siSourceType: case siBuffersQueued: case siBuffersProcessed: /* Query only */ - RETERR(AL_INVALID_OPERATION); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); case AL_SEC_OFFSET: case AL_SAMPLE_OFFSET: @@ -653,17 +651,17 @@ static ALenum SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop if(ApplyOffset(Source) == AL_FALSE) { UnlockContext(Context); - RETERR(AL_INVALID_VALUE); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); } } UnlockContext(Context); - return AL_NO_ERROR; + return AL_TRUE; case siSampleRWOffsetsSOFT: case siByteRWOffsetsSOFT: /* Query only */ - RETERR(AL_INVALID_OPERATION); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); case AL_DIRECT_FILTER: @@ -682,35 +680,35 @@ static ALenum SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop } UnlockContext(Context); Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_DIRECT_FILTER_GAINHF_AUTO: CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); Source->DryGainHFAuto = *values; Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO: CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); Source->WetGainAuto = *values; Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); Source->WetGainHFAuto = *values; Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_DIRECT_CHANNELS_SOFT: CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); Source->DirectChannels = *values; Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_DISTANCE_MODEL: CHECKVAL(*values == AL_NONE || @@ -724,7 +722,7 @@ static ALenum SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop Source->DistanceModel = *values; if(Context->SourceDistanceModel) Source->NeedsUpdate = AL_TRUE; - return AL_NO_ERROR; + return AL_TRUE; case AL_AUXILIARY_SEND_FILTER: @@ -734,7 +732,7 @@ static ALenum SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop (values[2] == 0 || (filter=LookupFilter(device, values[2])) != NULL))) { UnlockContext(Context); - RETERR(AL_INVALID_VALUE); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); } /* Add refcount on the new slot, and release the previous slot */ @@ -755,7 +753,7 @@ static ALenum SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop } Source->NeedsUpdate = AL_TRUE; UnlockContext(Context); - return AL_NO_ERROR; + return AL_TRUE; case AL_MAX_DISTANCE: @@ -781,10 +779,10 @@ static ALenum SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop } ERR("Unexpected property: 0x%04x\n", prop); - RETERR(AL_INVALID_ENUM); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); } -static ALenum SetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint64SOFT *values) +static ALboolean SetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint64SOFT *values) { ALfloat fvals[3]; ALint ivals[3]; @@ -795,7 +793,7 @@ static ALenum SetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp pr case siByteRWOffsetsSOFT: case siSampleOffsetLatencySOFT: /* Query only */ - RETERR(AL_INVALID_OPERATION); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); /* 1x int */ @@ -858,60 +856,60 @@ static ALenum SetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp pr } ERR("Unexpected property: 0x%04x\n", prop); - RETERR(AL_INVALID_ENUM); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); } #undef CHECKVAL -static ALenum GetSourcedv(const ALsource *Source, ALCcontext *Context, SrcFloatProp prop, ALdouble *values) +static ALboolean GetSourcedv(const ALsource *Source, ALCcontext *Context, SrcFloatProp prop, ALdouble *values) { ALdouble offsets[2]; ALdouble updateLen; - ALint ivals[3]; - ALenum err; + ALint ivals[3]; + ALboolean err; switch(prop) { case AL_GAIN: *values = Source->Gain; - return AL_NO_ERROR; + return AL_TRUE; case AL_PITCH: *values = Source->Pitch; - return AL_NO_ERROR; + return AL_TRUE; case AL_MAX_DISTANCE: *values = Source->MaxDistance; - return AL_NO_ERROR; + return AL_TRUE; case AL_ROLLOFF_FACTOR: *values = Source->RollOffFactor; - return AL_NO_ERROR; + return AL_TRUE; case AL_REFERENCE_DISTANCE: *values = Source->RefDistance; - return AL_NO_ERROR; + return AL_TRUE; case AL_CONE_INNER_ANGLE: *values = Source->InnerAngle; - return AL_NO_ERROR; + return AL_TRUE; case AL_CONE_OUTER_ANGLE: *values = Source->OuterAngle; - return AL_NO_ERROR; + return AL_TRUE; case AL_MIN_GAIN: *values = Source->MinGain; - return AL_NO_ERROR; + return AL_TRUE; case AL_MAX_GAIN: *values = Source->MaxGain; - return AL_NO_ERROR; + return AL_TRUE; case AL_CONE_OUTER_GAIN: *values = Source->OuterGain; - return AL_NO_ERROR; + return AL_TRUE; case AL_SEC_OFFSET: case AL_SAMPLE_OFFSET: @@ -922,23 +920,23 @@ static ALenum GetSourcedv(const ALsource *Source, ALCcontext *Context, SrcFloatP GetSourceOffsets(Source, prop, offsets, updateLen); UnlockContext(Context); *values = offsets[0]; - return AL_NO_ERROR; + return AL_TRUE; case AL_CONE_OUTER_GAINHF: *values = Source->OuterGainHF; - return AL_NO_ERROR; + return AL_TRUE; case AL_AIR_ABSORPTION_FACTOR: *values = Source->AirAbsorptionFactor; - return AL_NO_ERROR; + return AL_TRUE; case AL_ROOM_ROLLOFF_FACTOR: *values = Source->RoomRolloffFactor; - return AL_NO_ERROR; + return AL_TRUE; case AL_DOPPLER_FACTOR: *values = Source->DopplerFactor; - return AL_NO_ERROR; + return AL_TRUE; case AL_SAMPLE_RW_OFFSETS_SOFT: case AL_BYTE_RW_OFFSETS_SOFT: @@ -947,7 +945,7 @@ static ALenum GetSourcedv(const ALsource *Source, ALCcontext *Context, SrcFloatP Context->Device->Frequency; GetSourceOffsets(Source, prop, values, updateLen); UnlockContext(Context); - return AL_NO_ERROR; + return AL_TRUE; case AL_SEC_OFFSET_LATENCY_SOFT: LockContext(Context); @@ -955,7 +953,7 @@ static ALenum GetSourcedv(const ALsource *Source, ALCcontext *Context, SrcFloatP values[1] = (ALdouble)ALCdevice_GetLatency(Context->Device) / 1000000000.0; UnlockContext(Context); - return AL_NO_ERROR; + return AL_TRUE; case AL_POSITION: LockContext(Context); @@ -963,7 +961,7 @@ static ALenum GetSourcedv(const ALsource *Source, ALCcontext *Context, SrcFloatP values[1] = Source->Position[1]; values[2] = Source->Position[2]; UnlockContext(Context); - return AL_NO_ERROR; + return AL_TRUE; case AL_VELOCITY: LockContext(Context); @@ -971,7 +969,7 @@ static ALenum GetSourcedv(const ALsource *Source, ALCcontext *Context, SrcFloatP values[1] = Source->Velocity[1]; values[2] = Source->Velocity[2]; UnlockContext(Context); - return AL_NO_ERROR; + return AL_TRUE; case AL_DIRECTION: LockContext(Context); @@ -979,7 +977,7 @@ static ALenum GetSourcedv(const ALsource *Source, ALCcontext *Context, SrcFloatP values[1] = Source->Orientation[1]; values[2] = Source->Orientation[2]; UnlockContext(Context); - return AL_NO_ERROR; + return AL_TRUE; case AL_SOURCE_RELATIVE: case AL_LOOPING: @@ -993,30 +991,30 @@ static ALenum GetSourcedv(const ALsource *Source, ALCcontext *Context, SrcFloatP case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: case AL_DIRECT_CHANNELS_SOFT: case AL_DISTANCE_MODEL: - if((err=GetSourceiv(Source, Context, (int)prop, ivals)) == AL_NO_ERROR) + if((err=GetSourceiv(Source, Context, (int)prop, ivals)) != AL_FALSE) *values = (ALdouble)ivals[0]; return err; } ERR("Unexpected property: 0x%04x\n", prop); - RETERR(AL_INVALID_ENUM); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); } -static ALenum GetSourceiv(const ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint *values) +static ALboolean GetSourceiv(const ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint *values) { ALbufferlistitem *BufferList; ALdouble dvals[3]; - ALenum err; + ALboolean err; switch(prop) { case AL_SOURCE_RELATIVE: *values = Source->HeadRelative; - return AL_NO_ERROR; + return AL_TRUE; case AL_LOOPING: *values = Source->Looping; - return AL_NO_ERROR; + return AL_TRUE; case AL_BUFFER: LockContext(Context); @@ -1033,15 +1031,15 @@ static ALenum GetSourceiv(const ALsource *Source, ALCcontext *Context, SrcIntPro *values = ((BufferList && BufferList->buffer) ? BufferList->buffer->id : 0); UnlockContext(Context); - return AL_NO_ERROR; + return AL_TRUE; case AL_SOURCE_STATE: *values = Source->state; - return AL_NO_ERROR; + return AL_TRUE; case AL_BUFFERS_QUEUED: *values = Source->BuffersInQueue; - return AL_NO_ERROR; + return AL_TRUE; case AL_BUFFERS_PROCESSED: LockContext(Context); @@ -1054,31 +1052,31 @@ static ALenum GetSourceiv(const ALsource *Source, ALCcontext *Context, SrcIntPro else *values = Source->BuffersPlayed; UnlockContext(Context); - return AL_NO_ERROR; + return AL_TRUE; case AL_SOURCE_TYPE: *values = Source->SourceType; - return AL_NO_ERROR; + return AL_TRUE; case AL_DIRECT_FILTER_GAINHF_AUTO: *values = Source->DryGainHFAuto; - return AL_NO_ERROR; + return AL_TRUE; case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO: *values = Source->WetGainAuto; - return AL_NO_ERROR; + return AL_TRUE; case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: *values = Source->WetGainHFAuto; - return AL_NO_ERROR; + return AL_TRUE; case AL_DIRECT_CHANNELS_SOFT: *values = Source->DirectChannels; - return AL_NO_ERROR; + return AL_TRUE; case AL_DISTANCE_MODEL: *values = Source->DistanceModel; - return AL_NO_ERROR; + return AL_TRUE; case AL_MAX_DISTANCE: case AL_ROLLOFF_FACTOR: @@ -1089,13 +1087,13 @@ static ALenum GetSourceiv(const ALsource *Source, ALCcontext *Context, SrcIntPro case AL_SAMPLE_OFFSET: case AL_BYTE_OFFSET: case AL_DOPPLER_FACTOR: - if((err=GetSourcedv(Source, Context, (int)prop, dvals)) == AL_NO_ERROR) + if((err=GetSourcedv(Source, Context, (int)prop, dvals)) != AL_FALSE) *values = (ALint)dvals[0]; return err; case AL_SAMPLE_RW_OFFSETS_SOFT: case AL_BYTE_RW_OFFSETS_SOFT: - if((err=GetSourcedv(Source, Context, (int)prop, dvals)) == AL_NO_ERROR) + if((err=GetSourcedv(Source, Context, (int)prop, dvals)) != AL_FALSE) { values[0] = (ALint)dvals[0]; values[1] = (ALint)dvals[1]; @@ -1105,7 +1103,7 @@ static ALenum GetSourceiv(const ALsource *Source, ALCcontext *Context, SrcIntPro case AL_POSITION: case AL_VELOCITY: case AL_DIRECTION: - if((err=GetSourcedv(Source, Context, (int)prop, dvals)) == AL_NO_ERROR) + if((err=GetSourcedv(Source, Context, (int)prop, dvals)) != AL_FALSE) { values[0] = (ALint)dvals[0]; values[1] = (ALint)dvals[1]; @@ -1124,14 +1122,14 @@ static ALenum GetSourceiv(const ALsource *Source, ALCcontext *Context, SrcIntPro } ERR("Unexpected property: 0x%04x\n", prop); - RETERR(AL_INVALID_ENUM); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); } -static ALenum GetSourcei64v(const ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint64 *values) +static ALboolean GetSourcei64v(const ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint64 *values) { ALdouble dvals[3]; - ALint ivals[3]; - ALenum err; + ALint ivals[3]; + ALboolean err; switch(prop) { @@ -1140,7 +1138,7 @@ static ALenum GetSourcei64v(const ALsource *Source, ALCcontext *Context, SrcIntP values[0] = GetSourceOffset(Source); values[1] = ALCdevice_GetLatency(Context->Device); UnlockContext(Context); - return AL_NO_ERROR; + return AL_TRUE; case AL_MAX_DISTANCE: case AL_ROLLOFF_FACTOR: @@ -1151,13 +1149,13 @@ static ALenum GetSourcei64v(const ALsource *Source, ALCcontext *Context, SrcIntP case AL_SAMPLE_OFFSET: case AL_BYTE_OFFSET: case AL_DOPPLER_FACTOR: - if((err=GetSourcedv(Source, Context, (int)prop, dvals)) == AL_NO_ERROR) + if((err=GetSourcedv(Source, Context, (int)prop, dvals)) != AL_FALSE) *values = (ALint64)dvals[0]; return err; case AL_SAMPLE_RW_OFFSETS_SOFT: case AL_BYTE_RW_OFFSETS_SOFT: - if((err=GetSourcedv(Source, Context, (int)prop, dvals)) == AL_NO_ERROR) + if((err=GetSourcedv(Source, Context, (int)prop, dvals)) != AL_FALSE) { values[0] = (ALint64)dvals[0]; values[1] = (ALint64)dvals[1]; @@ -1167,7 +1165,7 @@ static ALenum GetSourcei64v(const ALsource *Source, ALCcontext *Context, SrcIntP case AL_POSITION: case AL_VELOCITY: case AL_DIRECTION: - if((err=GetSourcedv(Source, Context, (int)prop, dvals)) == AL_NO_ERROR) + if((err=GetSourcedv(Source, Context, (int)prop, dvals)) != AL_FALSE) { values[0] = (ALint64)dvals[0]; values[1] = (ALint64)dvals[1]; @@ -1186,18 +1184,18 @@ static ALenum GetSourcei64v(const ALsource *Source, ALCcontext *Context, SrcIntP case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: case AL_DIRECT_CHANNELS_SOFT: case AL_DISTANCE_MODEL: - if((err=GetSourceiv(Source, Context, (int)prop, ivals)) == AL_NO_ERROR) + if((err=GetSourceiv(Source, Context, (int)prop, ivals)) != AL_FALSE) *values = ivals[0]; return err; case siBuffer: case siDirectFilter: - if((err=GetSourceiv(Source, Context, (int)prop, ivals)) == AL_NO_ERROR) + if((err=GetSourceiv(Source, Context, (int)prop, ivals)) != AL_FALSE) *values = ((ALuint*)ivals)[0]; return err; case siAuxSendFilter: - if((err=GetSourceiv(Source, Context, (int)prop, ivals)) == AL_NO_ERROR) + if((err=GetSourceiv(Source, Context, (int)prop, ivals)) != AL_FALSE) { values[0] = ((ALuint*)ivals)[0]; values[1] = ((ALuint*)ivals)[1]; @@ -1207,143 +1205,133 @@ static ALenum GetSourcei64v(const ALsource *Source, ALCcontext *Context, SrcIntP } ERR("Unexpected property: 0x%04x\n", prop); - RETERR(AL_INVALID_ENUM); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); } -#undef RETERR - AL_API ALvoid AL_APIENTRY alGenSources(ALsizei n, ALuint *sources) { - ALCcontext *Context; - ALsizei cur = 0; + ALCcontext *context; + ALsizei cur = 0; + ALenum err; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + for(cur = 0;cur < n;cur++) { - ALenum err; - - CHECK_VALUE(Context, n >= 0); - for(cur = 0;cur < n;cur++) + ALsource *source = al_calloc(16, sizeof(ALsource)); + if(!source) { - ALsource *source = al_calloc(16, sizeof(ALsource)); - if(!source) - al_throwerr(Context, AL_OUT_OF_MEMORY); - InitSourceParams(source); - - err = NewThunkEntry(&source->id); - if(err == AL_NO_ERROR) - err = InsertUIntMapEntry(&Context->SourceMap, source->id, source); - if(err != AL_NO_ERROR) - { - FreeThunkEntry(source->id); - memset(source, 0, sizeof(ALsource)); - al_free(source); + alDeleteSources(cur, sources); + SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); + } + InitSourceParams(source); - al_throwerr(Context, err); - } + err = NewThunkEntry(&source->id); + if(err == AL_NO_ERROR) + err = InsertUIntMapEntry(&context->SourceMap, source->id, source); + if(err != AL_NO_ERROR) + { + FreeThunkEntry(source->id); + memset(source, 0, sizeof(ALsource)); + al_free(source); - sources[cur] = source->id; - } - } - al_catchany() - { - if(cur > 0) alDeleteSources(cur, sources); + SET_ERROR_AND_GOTO(context, err, done); + } + + sources[cur] = source->id; } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources) { - ALCcontext *Context; + ALCcontext *context; + ALbufferlistitem *BufferList; + ALsource *Source; + ALsizei i, j; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try - { - ALbufferlistitem *BufferList; - ALsource *Source; - ALsizei i, j; + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - CHECK_VALUE(Context, n >= 0); + /* Check that all Sources are valid */ + for(i = 0;i < n;i++) + { + if(LookupSource(context, sources[i]) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + } + for(i = 0;i < n;i++) + { + ALsource **srclist, **srclistend; - /* Check that all Sources are valid */ - for(i = 0;i < n;i++) - { - if(LookupSource(Context, sources[i]) == NULL) - al_throwerr(Context, AL_INVALID_NAME); - } + if((Source=RemoveSource(context, sources[i])) == NULL) + continue; + FreeThunkEntry(Source->id); - for(i = 0;i < n;i++) + LockContext(context); + srclist = context->ActiveSources; + srclistend = srclist + context->ActiveSourceCount; + while(srclist != srclistend) { - ALsource **srclist, **srclistend; - - if((Source=RemoveSource(Context, sources[i])) == NULL) - continue; - FreeThunkEntry(Source->id); - - LockContext(Context); - srclist = Context->ActiveSources; - srclistend = srclist + Context->ActiveSourceCount; - while(srclist != srclistend) + if(*srclist == Source) { - if(*srclist == Source) - { - Context->ActiveSourceCount--; - *srclist = *(--srclistend); - break; - } - srclist++; + context->ActiveSourceCount--; + *srclist = *(--srclistend); + break; } - UnlockContext(Context); - - while(Source->queue != NULL) - { - BufferList = Source->queue; - Source->queue = BufferList->next; + srclist++; + } + UnlockContext(context); - if(BufferList->buffer != NULL) - DecrementRef(&BufferList->buffer->ref); - free(BufferList); - } + while(Source->queue != NULL) + { + BufferList = Source->queue; + Source->queue = BufferList->next; - for(j = 0;j < MAX_SENDS;++j) - { - if(Source->Send[j].Slot) - DecrementRef(&Source->Send[j].Slot->ref); - Source->Send[j].Slot = NULL; - } + if(BufferList->buffer != NULL) + DecrementRef(&BufferList->buffer->ref); + free(BufferList); + } - memset(Source, 0, sizeof(*Source)); - al_free(Source); + for(j = 0;j < MAX_SENDS;++j) + { + if(Source->Send[j].Slot) + DecrementRef(&Source->Send[j].Slot->ref); + Source->Send[j].Slot = NULL; } + + memset(Source, 0, sizeof(*Source)); + al_free(Source); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALboolean AL_APIENTRY alIsSource(ALuint source) { - ALCcontext *Context; - ALboolean result; + ALCcontext *context; + ALboolean ret; - Context = GetContextRef(); - if(!Context) return AL_FALSE; + context = GetContextRef(); + if(!context) return AL_FALSE; - result = (LookupSource(Context, source) ? AL_TRUE : AL_FALSE); + ret = (LookupSource(context, source) ? AL_TRUE : AL_FALSE); - ALCcontext_DecRef(Context); + ALCcontext_DecRef(context); - return result; + return ret; } @@ -1615,7 +1603,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *val else { ALdouble dval; - if(GetSourcedv(Source, Context, param, &dval) == AL_NO_ERROR) + if(GetSourcedv(Source, Context, param, &dval)) *value = (ALfloat)dval; } @@ -1640,7 +1628,7 @@ AL_API ALvoid AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *va else { ALdouble dvals[3]; - if(GetSourcedv(Source, Context, param, dvals) == AL_NO_ERROR) + if(GetSourcedv(Source, Context, param, dvals)) { *value1 = (ALfloat)dvals[0]; *value2 = (ALfloat)dvals[1]; @@ -1670,7 +1658,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *va else { ALdouble dvals[3]; - if(GetSourcedv(Source, Context, param, dvals) == AL_NO_ERROR) + if(GetSourcedv(Source, Context, param, dvals)) { ALint i; for(i = 0;i < count;i++) @@ -1719,7 +1707,7 @@ AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble else { ALdouble dvals[3]; - if(GetSourcedv(Source, Context, param, dvals) == AL_NO_ERROR) + if(GetSourcedv(Source, Context, param, dvals)) { *value1 = dvals[0]; *value2 = dvals[1]; @@ -1789,7 +1777,7 @@ AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1 else { ALint ivals[3]; - if(GetSourceiv(Source, Context, param, ivals) == AL_NO_ERROR) + if(GetSourceiv(Source, Context, param, ivals)) { *value1 = ivals[0]; *value2 = ivals[1]; @@ -1859,7 +1847,7 @@ AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64 else { ALint64 i64vals[3]; - if(GetSourcei64v(Source, Context, param, i64vals) == AL_NO_ERROR) + if(GetSourcei64v(Source, Context, param, i64vals)) { *value1 = i64vals[0]; *value2 = i64vals[1]; @@ -1897,53 +1885,51 @@ AL_API ALvoid AL_APIENTRY alSourcePlay(ALuint source) } AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) { - ALCcontext *Context; - ALsource *Source; - ALsizei i; + ALCcontext *context; + ALsource *source; + ALsizei i; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + for(i = 0;i < n;i++) { - CHECK_VALUE(Context, n >= 0); - for(i = 0;i < n;i++) - { - if(!LookupSource(Context, sources[i])) - al_throwerr(Context, AL_INVALID_NAME); - } + if(!LookupSource(context, sources[i])) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + } - LockContext(Context); - while(Context->MaxActiveSources-Context->ActiveSourceCount < n) + LockContext(context); + while(n > context->MaxActiveSources-context->ActiveSourceCount) + { + void *temp = NULL; + ALsizei newcount; + + newcount = context->MaxActiveSources << 1; + if(newcount > 0) + temp = realloc(context->ActiveSources, + sizeof(*context->ActiveSources) * newcount); + if(!temp) { - void *temp = NULL; - ALsizei newcount; - - newcount = Context->MaxActiveSources << 1; - if(newcount > 0) - temp = realloc(Context->ActiveSources, - sizeof(*Context->ActiveSources) * newcount); - if(!temp) - { - UnlockContext(Context); - al_throwerr(Context, AL_OUT_OF_MEMORY); - } - - Context->ActiveSources = temp; - Context->MaxActiveSources = newcount; + UnlockContext(context); + SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); } - for(i = 0;i < n;i++) - { - Source = LookupSource(Context, sources[i]); - if(Context->DeferUpdates) Source->new_state = AL_PLAYING; - else SetSourceState(Source, Context, AL_PLAYING); - } - UnlockContext(Context); + context->ActiveSources = temp; + context->MaxActiveSources = newcount; } - al_endtry; - ALCcontext_DecRef(Context); + for(i = 0;i < n;i++) + { + source = LookupSource(context, sources[i]); + if(context->DeferUpdates) source->new_state = AL_PLAYING; + else SetSourceState(source, context, AL_PLAYING); + } + UnlockContext(context); + +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alSourcePause(ALuint source) @@ -1952,34 +1938,32 @@ AL_API ALvoid AL_APIENTRY alSourcePause(ALuint source) } AL_API ALvoid AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources) { - ALCcontext *Context; - ALsource *Source; - ALsizei i; + ALCcontext *context; + ALsource *source; + ALsizei i; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + for(i = 0;i < n;i++) { - CHECK_VALUE(Context, n >= 0); - for(i = 0;i < n;i++) - { - if(!LookupSource(Context, sources[i])) - al_throwerr(Context, AL_INVALID_NAME); - } + if(!LookupSource(context, sources[i])) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + } - LockContext(Context); - for(i = 0;i < n;i++) - { - Source = LookupSource(Context, sources[i]); - if(Context->DeferUpdates) Source->new_state = AL_PAUSED; - else SetSourceState(Source, Context, AL_PAUSED); - } - UnlockContext(Context); + LockContext(context); + for(i = 0;i < n;i++) + { + source = LookupSource(context, sources[i]); + if(context->DeferUpdates) source->new_state = AL_PAUSED; + else SetSourceState(source, context, AL_PAUSED); } - al_endtry; + UnlockContext(context); - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alSourceStop(ALuint source) @@ -1988,34 +1972,32 @@ AL_API ALvoid AL_APIENTRY alSourceStop(ALuint source) } AL_API ALvoid AL_APIENTRY alSourceStopv(ALsizei n, const ALuint *sources) { - ALCcontext *Context; - ALsource *Source; - ALsizei i; + ALCcontext *context; + ALsource *source; + ALsizei i; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + for(i = 0;i < n;i++) { - CHECK_VALUE(Context, n >= 0); - for(i = 0;i < n;i++) - { - if(!LookupSource(Context, sources[i])) - al_throwerr(Context, AL_INVALID_NAME); - } + if(!LookupSource(context, sources[i])) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + } - LockContext(Context); - for(i = 0;i < n;i++) - { - Source = LookupSource(Context, sources[i]); - Source->new_state = AL_NONE; - SetSourceState(Source, Context, AL_STOPPED); - } - UnlockContext(Context); + LockContext(context); + for(i = 0;i < n;i++) + { + source = LookupSource(context, sources[i]); + source->new_state = AL_NONE; + SetSourceState(source, context, AL_STOPPED); } - al_endtry; + UnlockContext(context); - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alSourceRewind(ALuint source) @@ -2024,226 +2006,217 @@ AL_API ALvoid AL_APIENTRY alSourceRewind(ALuint source) } AL_API ALvoid AL_APIENTRY alSourceRewindv(ALsizei n, const ALuint *sources) { - ALCcontext *Context; - ALsource *Source; - ALsizei i; + ALCcontext *context; + ALsource *source; + ALsizei i; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(!(n >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + for(i = 0;i < n;i++) { - CHECK_VALUE(Context, n >= 0); - for(i = 0;i < n;i++) - { - if(!LookupSource(Context, sources[i])) - al_throwerr(Context, AL_INVALID_NAME); - } + if(!LookupSource(context, sources[i])) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + } - LockContext(Context); - for(i = 0;i < n;i++) - { - Source = LookupSource(Context, sources[i]); - Source->new_state = AL_NONE; - SetSourceState(Source, Context, AL_INITIAL); - } - UnlockContext(Context); + LockContext(context); + for(i = 0;i < n;i++) + { + source = LookupSource(context, sources[i]); + source->new_state = AL_NONE; + SetSourceState(source, context, AL_INITIAL); } - al_endtry; + UnlockContext(context); - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } -AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint source, ALsizei nb, const ALuint *buffers) +AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALuint *buffers) { - ALCcontext *Context; - ALsource *Source; - ALsizei i; + ALCdevice *device; + ALCcontext *context; + ALsource *source; + ALsizei i; ALbufferlistitem *BufferListStart = NULL; ALbufferlistitem *BufferList; - ALbuffer *BufferFmt; + ALbuffer *BufferFmt = NULL; if(nb == 0) return; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try - { - ALCdevice *device = Context->Device; + device = context->Device; - CHECK_VALUE(Context, nb >= 0); + if(!(nb >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + if((source=LookupSource(context, src)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - if((Source=LookupSource(Context, source)) == NULL) - al_throwerr(Context, AL_INVALID_NAME); + LockContext(context); + if(source->SourceType == AL_STATIC) + { + UnlockContext(context); + /* Can't queue on a Static Source */ + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); + } - LockContext(Context); - if(Source->SourceType == AL_STATIC) + /* Check for a valid Buffer, for its frequency and format */ + BufferList = source->queue; + while(BufferList) + { + if(BufferList->buffer) { - UnlockContext(Context); - /* Can't queue on a Static Source */ - al_throwerr(Context, AL_INVALID_OPERATION); + BufferFmt = BufferList->buffer; + break; } + BufferList = BufferList->next; + } - BufferFmt = NULL; + for(i = 0;i < nb;i++) + { + ALbuffer *buffer = NULL; + if(buffers[i] && (buffer=LookupBuffer(device, buffers[i])) == NULL) + { + UnlockContext(context); + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + } - /* Check for a valid Buffer, for its frequency and format */ - BufferList = Source->queue; - while(BufferList) + if(!BufferListStart) { - if(BufferList->buffer) - { - BufferFmt = BufferList->buffer; - break; - } + BufferListStart = malloc(sizeof(ALbufferlistitem)); + BufferListStart->buffer = buffer; + BufferListStart->next = NULL; + BufferListStart->prev = NULL; + BufferList = BufferListStart; + } + else + { + BufferList->next = malloc(sizeof(ALbufferlistitem)); + BufferList->next->buffer = buffer; + BufferList->next->next = NULL; + BufferList->next->prev = BufferList; BufferList = BufferList->next; } + if(!buffer) continue; + IncrementRef(&buffer->ref); - for(i = 0;i < nb;i++) + ReadLock(&buffer->lock); + if(BufferFmt == NULL) { - ALbuffer *buffer = NULL; - if(buffers[i] && (buffer=LookupBuffer(device, buffers[i])) == NULL) - { - UnlockContext(Context); - al_throwerr(Context, AL_INVALID_NAME); - } + BufferFmt = buffer; - if(!BufferListStart) - { - BufferListStart = malloc(sizeof(ALbufferlistitem)); - BufferListStart->buffer = buffer; - BufferListStart->next = NULL; - BufferListStart->prev = NULL; - BufferList = BufferListStart; - } + source->NumChannels = ChannelsFromFmt(buffer->FmtChannels); + source->SampleSize = BytesFromFmt(buffer->FmtType); + if(buffer->FmtChannels == FmtMono) + source->Update = CalcSourceParams; else - { - BufferList->next = malloc(sizeof(ALbufferlistitem)); - BufferList->next->buffer = buffer; - BufferList->next->next = NULL; - BufferList->next->prev = BufferList; - BufferList = BufferList->next; - } - if(!buffer) continue; - IncrementRef(&buffer->ref); - - ReadLock(&buffer->lock); - if(BufferFmt == NULL) - { - BufferFmt = buffer; + source->Update = CalcNonAttnSourceParams; - Source->NumChannels = ChannelsFromFmt(buffer->FmtChannels); - Source->SampleSize = BytesFromFmt(buffer->FmtType); - if(buffer->FmtChannels == FmtMono) - Source->Update = CalcSourceParams; - else - Source->Update = CalcNonAttnSourceParams; - - Source->NeedsUpdate = AL_TRUE; - } - else if(BufferFmt->Frequency != buffer->Frequency || - BufferFmt->OriginalChannels != buffer->OriginalChannels || - BufferFmt->OriginalType != buffer->OriginalType) - { - ReadUnlock(&buffer->lock); - UnlockContext(Context); - al_throwerr(Context, AL_INVALID_OPERATION); - } + source->NeedsUpdate = AL_TRUE; + } + else if(BufferFmt->Frequency != buffer->Frequency || + BufferFmt->OriginalChannels != buffer->OriginalChannels || + BufferFmt->OriginalType != buffer->OriginalType) + { ReadUnlock(&buffer->lock); + UnlockContext(context); + SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); } + ReadUnlock(&buffer->lock); + } - /* Source is now streaming */ - Source->SourceType = AL_STREAMING; + /* Source is now streaming */ + source->SourceType = AL_STREAMING; - if(Source->queue == NULL) - Source->queue = BufferListStart; - else - { - /* Append to the end of the queue */ - BufferList = Source->queue; - while(BufferList->next != NULL) - BufferList = BufferList->next; + if(source->queue == NULL) + source->queue = BufferListStart; + else + { + /* Append to the end of the queue */ + BufferList = source->queue; + while(BufferList->next != NULL) + BufferList = BufferList->next; - BufferListStart->prev = BufferList; - BufferList->next = BufferListStart; - } + BufferListStart->prev = BufferList; + BufferList->next = BufferListStart; + } + BufferListStart = NULL; - Source->BuffersInQueue += nb; + source->BuffersInQueue += nb; - UnlockContext(Context); - } - al_catchany() + UnlockContext(context); + +done: + while(BufferListStart) { - while(BufferListStart) - { - BufferList = BufferListStart; - BufferListStart = BufferList->next; + BufferList = BufferListStart; + BufferListStart = BufferList->next; - if(BufferList->buffer) - DecrementRef(&BufferList->buffer->ref); - free(BufferList); - } + if(BufferList->buffer) + DecrementRef(&BufferList->buffer->ref); + free(BufferList); } - al_endtry; - ALCcontext_DecRef(Context); + ALCcontext_DecRef(context); } -AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint source, ALsizei nb, ALuint *buffers) +AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint *buffers) { - ALCcontext *Context; - ALsource *Source; - ALsizei i; + ALCcontext *context; + ALsource *source; + ALsizei i; ALbufferlistitem *BufferList; if(nb == 0) return; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; + + if(!(nb >= 0)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - al_try + if((source=LookupSource(context, src)) == NULL) + SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + + LockContext(context); + if(source->Looping || source->SourceType != AL_STREAMING || + (ALuint)nb > source->BuffersPlayed) { - CHECK_VALUE(Context, nb >= 0); + UnlockContext(context); + /* Trying to unqueue pending buffers, or a buffer that wasn't queued. */ + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + } - if((Source=LookupSource(Context, source)) == NULL) - al_throwerr(Context, AL_INVALID_NAME); + for(i = 0;i < nb;i++) + { + BufferList = source->queue; + source->queue = BufferList->next; + source->BuffersInQueue--; + source->BuffersPlayed--; - LockContext(Context); - if(Source->Looping || Source->SourceType != AL_STREAMING || - (ALuint)nb > Source->BuffersPlayed) + if(BufferList->buffer) { - UnlockContext(Context); - /* Trying to unqueue pending buffers, or a buffer that wasn't queued. */ - al_throwerr(Context, AL_INVALID_VALUE); + buffers[i] = BufferList->buffer->id; + DecrementRef(&BufferList->buffer->ref); } + else + buffers[i] = 0; - for(i = 0;i < nb;i++) - { - BufferList = Source->queue; - Source->queue = BufferList->next; - Source->BuffersInQueue--; - Source->BuffersPlayed--; - - if(BufferList->buffer) - { - buffers[i] = BufferList->buffer->id; - DecrementRef(&BufferList->buffer->ref); - } - else - buffers[i] = 0; - - free(BufferList); - } - if(Source->queue) - Source->queue->prev = NULL; - UnlockContext(Context); + free(BufferList); } - al_endtry; + if(source->queue) + source->queue->prev = NULL; + UnlockContext(context); - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } @@ -2328,7 +2301,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) if(Source->state != AL_PLAYING) { - for(j = 0;j < MaxChannels;j++) + for(j = 0;j < MAX_INPUT_CHANNELS;j++) { for(k = 0;k < SRC_HISTORY_LENGTH;k++) Source->Hrtf.History[j][k] = 0.0f; @@ -2432,7 +2405,7 @@ static ALint64 GetSourceOffset(const ALsource *Source) BufferList = BufferList->next; } - return (ALint64)minu64(readPos, MAKEU64(0x7fffffff,0xffffffff)); + return (ALint64)minu64(readPos, U64(0x7fffffffffffffff)); } /* GetSourceSecOffset diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c index 678e9e94..280dd896 100644 --- a/OpenAL32/alState.c +++ b/OpenAL32/alState.c @@ -23,10 +23,14 @@ #include <stdlib.h> #include "alMain.h" #include "AL/alc.h" +#include "AL/al.h" #include "AL/alext.h" #include "alError.h" #include "alSource.h" #include "alAuxEffectSlot.h" +#include "alMidi.h" + +#include "midi/base.h" static const ALchar alVendor[] = "OpenAL Community"; @@ -43,260 +47,334 @@ static const ALchar alErrOutOfMemory[] = "Out of Memory"; AL_API ALvoid AL_APIENTRY alEnable(ALenum capability) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + switch(capability) { - switch(capability) - { - case AL_SOURCE_DISTANCE_MODEL: - Context->SourceDistanceModel = AL_TRUE; - Context->UpdateSources = AL_TRUE; - break; + case AL_SOURCE_DISTANCE_MODEL: + context->SourceDistanceModel = AL_TRUE; + context->UpdateSources = AL_TRUE; + break; - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alDisable(ALenum capability) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + switch(capability) { - switch(capability) - { - case AL_SOURCE_DISTANCE_MODEL: - Context->SourceDistanceModel = AL_FALSE; - Context->UpdateSources = AL_TRUE; - break; + case AL_SOURCE_DISTANCE_MODEL: + context->SourceDistanceModel = AL_FALSE; + context->UpdateSources = AL_TRUE; + break; - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability) { - ALCcontext *Context; + ALCcontext *context; ALboolean value=AL_FALSE; - Context = GetContextRef(); - if(!Context) return AL_FALSE; + context = GetContextRef(); + if(!context) return AL_FALSE; - al_try + switch(capability) { - switch(capability) - { - case AL_SOURCE_DISTANCE_MODEL: - value = Context->SourceDistanceModel; - break; + case AL_SOURCE_DISTANCE_MODEL: + value = context->SourceDistanceModel; + break; - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); return value; } AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum pname) { - ALCcontext *Context; + ALCcontext *context; ALboolean value=AL_FALSE; - Context = GetContextRef(); - if(!Context) return AL_FALSE; + context = GetContextRef(); + if(!context) return AL_FALSE; - al_try + switch(pname) { - switch(pname) - { - case AL_DOPPLER_FACTOR: - if(Context->DopplerFactor != 0.0f) - value = AL_TRUE; - break; - - case AL_DOPPLER_VELOCITY: - if(Context->DopplerVelocity != 0.0f) - value = AL_TRUE; - break; - - case AL_DISTANCE_MODEL: - if(Context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED) - value = AL_TRUE; - break; - - case AL_SPEED_OF_SOUND: - if(Context->SpeedOfSound != 0.0f) - value = AL_TRUE; - break; - - case AL_DEFERRED_UPDATES_SOFT: - value = Context->DeferUpdates; - break; - - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + case AL_DOPPLER_FACTOR: + if(context->DopplerFactor != 0.0f) + value = AL_TRUE; + break; + + case AL_DOPPLER_VELOCITY: + if(context->DopplerVelocity != 0.0f) + value = AL_TRUE; + break; + + case AL_DISTANCE_MODEL: + if(context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED) + value = AL_TRUE; + break; + + case AL_SPEED_OF_SOUND: + if(context->SpeedOfSound != 0.0f) + value = AL_TRUE; + break; + + case AL_DEFERRED_UPDATES_SOFT: + value = context->DeferUpdates; + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); return value; } AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname) { - ALCcontext *Context; + ALCdevice *device; + ALCcontext *context; ALdouble value = 0.0; - Context = GetContextRef(); - if(!Context) return 0.0; + context = GetContextRef(); + if(!context) return 0.0; - al_try + switch(pname) { - switch(pname) - { - case AL_DOPPLER_FACTOR: - value = (ALdouble)Context->DopplerFactor; - break; - - case AL_DOPPLER_VELOCITY: - value = (ALdouble)Context->DopplerVelocity; - break; - - case AL_DISTANCE_MODEL: - value = (ALdouble)Context->DistanceModel; - break; - - case AL_SPEED_OF_SOUND: - value = (ALdouble)Context->SpeedOfSound; - break; - - case AL_DEFERRED_UPDATES_SOFT: - value = (ALdouble)Context->DeferUpdates; - break; - - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + case AL_DOPPLER_FACTOR: + value = (ALdouble)context->DopplerFactor; + break; + + case AL_DOPPLER_VELOCITY: + value = (ALdouble)context->DopplerVelocity; + break; + + case AL_DISTANCE_MODEL: + value = (ALdouble)context->DistanceModel; + break; + + case AL_SPEED_OF_SOUND: + value = (ALdouble)context->SpeedOfSound; + break; + + case AL_DEFERRED_UPDATES_SOFT: + value = (ALdouble)context->DeferUpdates; + break; + + case AL_MIDI_GAIN_SOFT: + device = context->Device; + value = (ALdouble)MidiSynth_getGain(device->Synth); + break; + + case AL_MIDI_STATE_SOFT: + device = context->Device; + value = (ALdouble)MidiSynth_getState(device->Synth); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); return value; } AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname) { - ALCcontext *Context; + ALCdevice *device; + ALCcontext *context; ALfloat value = 0.0f; - Context = GetContextRef(); - if(!Context) return 0.0f; + context = GetContextRef(); + if(!context) return 0.0f; - al_try + switch(pname) { - switch(pname) - { - case AL_DOPPLER_FACTOR: - value = Context->DopplerFactor; - break; - - case AL_DOPPLER_VELOCITY: - value = Context->DopplerVelocity; - break; - - case AL_DISTANCE_MODEL: - value = (ALfloat)Context->DistanceModel; - break; - - case AL_SPEED_OF_SOUND: - value = Context->SpeedOfSound; - break; - - case AL_DEFERRED_UPDATES_SOFT: - value = (ALfloat)Context->DeferUpdates; - break; - - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + case AL_DOPPLER_FACTOR: + value = context->DopplerFactor; + break; + + case AL_DOPPLER_VELOCITY: + value = context->DopplerVelocity; + break; + + case AL_DISTANCE_MODEL: + value = (ALfloat)context->DistanceModel; + break; + + case AL_SPEED_OF_SOUND: + value = context->SpeedOfSound; + break; + + case AL_DEFERRED_UPDATES_SOFT: + value = (ALfloat)context->DeferUpdates; + break; + + case AL_MIDI_GAIN_SOFT: + device = context->Device; + value = MidiSynth_getGain(device->Synth); + break; + + case AL_MIDI_STATE_SOFT: + device = context->Device; + value = (ALfloat)MidiSynth_getState(device->Synth); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); return value; } AL_API ALint AL_APIENTRY alGetInteger(ALenum pname) { - ALCcontext *Context; + ALCcontext *context; + ALCdevice *device; + MidiSynth *synth; ALint value = 0; - Context = GetContextRef(); - if(!Context) return 0; + context = GetContextRef(); + if(!context) return 0; - al_try + switch(pname) { - switch(pname) - { - case AL_DOPPLER_FACTOR: - value = (ALint)Context->DopplerFactor; - break; + case AL_DOPPLER_FACTOR: + value = (ALint)context->DopplerFactor; + break; + + case AL_DOPPLER_VELOCITY: + value = (ALint)context->DopplerVelocity; + break; + + case AL_DISTANCE_MODEL: + value = (ALint)context->DistanceModel; + break; + + case AL_SPEED_OF_SOUND: + value = (ALint)context->SpeedOfSound; + break; + + case AL_DEFERRED_UPDATES_SOFT: + value = (ALint)context->DeferUpdates; + break; + + case AL_SOUNDFONTS_SIZE_SOFT: + device = context->Device; + synth = device->Synth; + value = synth->NumSoundfonts; + break; + + case AL_MIDI_STATE_SOFT: + device = context->Device; + value = MidiSynth_getState(device->Synth); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } - case AL_DOPPLER_VELOCITY: - value = (ALint)Context->DopplerVelocity; - break; +done: + ALCcontext_DecRef(context); - case AL_DISTANCE_MODEL: - value = (ALint)Context->DistanceModel; - break; + return value; +} - case AL_SPEED_OF_SOUND: - value = (ALint)Context->SpeedOfSound; - break; +AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname) +{ + ALCcontext *context; + ALCdevice *device; + MidiSynth *synth; + ALint64SOFT value = 0; - case AL_DEFERRED_UPDATES_SOFT: - value = (ALint)Context->DeferUpdates; - break; + context = GetContextRef(); + if(!context) return 0; - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + switch(pname) + { + case AL_DOPPLER_FACTOR: + value = (ALint64SOFT)context->DopplerFactor; + break; + + case AL_DOPPLER_VELOCITY: + value = (ALint64SOFT)context->DopplerVelocity; + break; + + case AL_DISTANCE_MODEL: + value = (ALint64SOFT)context->DistanceModel; + break; + + case AL_SPEED_OF_SOUND: + value = (ALint64SOFT)context->SpeedOfSound; + break; + + case AL_DEFERRED_UPDATES_SOFT: + value = (ALint64SOFT)context->DeferUpdates; + break; + + case AL_MIDI_CLOCK_SOFT: + device = context->Device; + ALCdevice_Lock(device); + value = MidiSynth_getTime(device->Synth); + ALCdevice_Unlock(device); + break; + + case AL_SOUNDFONTS_SIZE_SOFT: + device = context->Device; + synth = device->Synth; + value = (ALint64SOFT)synth->NumSoundfonts; + break; + + case AL_MIDI_STATE_SOFT: + device = context->Device; + value = (ALint64SOFT)MidiSynth_getState(device->Synth); + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); return value; } AL_API ALvoid AL_APIENTRY alGetBooleanv(ALenum pname, ALboolean *values) { - ALCcontext *Context; + ALCcontext *context; if(values) { @@ -312,26 +390,24 @@ AL_API ALvoid AL_APIENTRY alGetBooleanv(ALenum pname, ALboolean *values) } } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(pname) { - CHECK_VALUE(Context, values); - switch(pname) - { - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alGetDoublev(ALenum pname, ALdouble *values) { - ALCcontext *Context; + ALCcontext *context; if(values) { @@ -342,31 +418,31 @@ AL_API ALvoid AL_APIENTRY alGetDoublev(ALenum pname, ALdouble *values) case AL_DISTANCE_MODEL: case AL_SPEED_OF_SOUND: case AL_DEFERRED_UPDATES_SOFT: + case AL_MIDI_GAIN_SOFT: + case AL_MIDI_STATE_SOFT: values[0] = alGetDouble(pname); return; } } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(pname) { - CHECK_VALUE(Context, values); - switch(pname) - { - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alGetFloatv(ALenum pname, ALfloat *values) { - ALCcontext *Context; + ALCcontext *context; if(values) { @@ -377,31 +453,34 @@ AL_API ALvoid AL_APIENTRY alGetFloatv(ALenum pname, ALfloat *values) case AL_DISTANCE_MODEL: case AL_SPEED_OF_SOUND: case AL_DEFERRED_UPDATES_SOFT: + case AL_MIDI_GAIN_SOFT: + case AL_MIDI_STATE_SOFT: values[0] = alGetFloat(pname); return; } } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + switch(pname) { - CHECK_VALUE(Context, values); - switch(pname) - { - default: - al_throwerr(Context, AL_INVALID_ENUM); - } + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname, ALint *values) { - ALCcontext *Context; + ALCcontext *context; + ALCdevice *device; + MidiSynth *synth; + ALsizei i; if(values) { @@ -412,187 +491,228 @@ AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname, ALint *values) case AL_DISTANCE_MODEL: case AL_SPEED_OF_SOUND: case AL_DEFERRED_UPDATES_SOFT: + case AL_SOUNDFONTS_SIZE_SOFT: + case AL_MIDI_STATE_SOFT: values[0] = alGetInteger(pname); return; } } - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try + switch(pname) + { + case AL_SOUNDFONTS_SOFT: + device = context->Device; + synth = device->Synth; + if(synth->NumSoundfonts > 0) + { + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + for(i = 0;i < synth->NumSoundfonts;i++) + values[i] = synth->Soundfonts[i]->id; + } + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); +} + +AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values) +{ + ALCcontext *context; + ALCdevice *device; + MidiSynth *synth; + ALsizei i; + + if(values) { - CHECK_VALUE(Context, values); switch(pname) { - default: - al_throwerr(Context, AL_INVALID_ENUM); + case AL_DOPPLER_FACTOR: + case AL_DOPPLER_VELOCITY: + case AL_DISTANCE_MODEL: + case AL_SPEED_OF_SOUND: + case AL_DEFERRED_UPDATES_SOFT: + case AL_MIDI_CLOCK_SOFT: + case AL_SOUNDFONTS_SIZE_SOFT: + case AL_MIDI_STATE_SOFT: + values[0] = alGetInteger64SOFT(pname); + return; } } - al_endtry; - ALCcontext_DecRef(Context); + context = GetContextRef(); + if(!context) return; + + switch(pname) + { + case AL_SOUNDFONTS_SOFT: + device = context->Device; + synth = device->Synth; + if(synth->NumSoundfonts > 0) + { + if(!(values)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + for(i = 0;i < synth->NumSoundfonts;i++) + values[i] = (ALint64SOFT)synth->Soundfonts[i]->id; + } + break; + + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); + } + +done: + ALCcontext_DecRef(context); } AL_API const ALchar* AL_APIENTRY alGetString(ALenum pname) { - const ALchar *value; - ALCcontext *Context; + const ALchar *value = NULL; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return NULL; + context = GetContextRef(); + if(!context) return NULL; - al_try + switch(pname) { - switch(pname) - { - case AL_VENDOR: - value = alVendor; - break; + case AL_VENDOR: + value = alVendor; + break; - case AL_VERSION: - value = alVersion; - break; + case AL_VERSION: + value = alVersion; + break; - case AL_RENDERER: - value = alRenderer; - break; + case AL_RENDERER: + value = alRenderer; + break; - case AL_EXTENSIONS: - value = Context->ExtensionList; - break; + case AL_EXTENSIONS: + value = context->ExtensionList; + break; - case AL_NO_ERROR: - value = alNoError; - break; + case AL_NO_ERROR: + value = alNoError; + break; - case AL_INVALID_NAME: - value = alErrInvalidName; - break; + case AL_INVALID_NAME: + value = alErrInvalidName; + break; - case AL_INVALID_ENUM: - value = alErrInvalidEnum; - break; + case AL_INVALID_ENUM: + value = alErrInvalidEnum; + break; - case AL_INVALID_VALUE: - value = alErrInvalidValue; - break; + case AL_INVALID_VALUE: + value = alErrInvalidValue; + break; - case AL_INVALID_OPERATION: - value = alErrInvalidOp; - break; + case AL_INVALID_OPERATION: + value = alErrInvalidOp; + break; - case AL_OUT_OF_MEMORY: - value = alErrOutOfMemory; - break; + case AL_OUT_OF_MEMORY: + value = alErrOutOfMemory; + break; - default: - al_throwerr(Context, AL_INVALID_ENUM); - } - } - al_catchany() - { - value = NULL; + default: + SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - al_endtry; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); return value; } AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try - { - CHECK_VALUE(Context, value >= 0.0f && isfinite(value)); + if(!(value >= 0.0f && isfinite(value))) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - Context->DopplerFactor = value; - Context->UpdateSources = AL_TRUE; - } - al_endtry; + context->DopplerFactor = value; + context->UpdateSources = AL_TRUE; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try - { - CHECK_VALUE(Context, value >= 0.0f && isfinite(value)); + if(!(value >= 0.0f && isfinite(value))) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - Context->DopplerVelocity = value; - Context->UpdateSources = AL_TRUE; - } - al_endtry; + context->DopplerVelocity = value; + context->UpdateSources = AL_TRUE; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try - { - CHECK_VALUE(Context, value > 0.0f && isfinite(value)); + if(!(value > 0.0f && isfinite(value))) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - Context->SpeedOfSound = value; - Context->UpdateSources = AL_TRUE; - } - al_endtry; + context->SpeedOfSound = value; + context->UpdateSources = AL_TRUE; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - al_try - { - CHECK_VALUE(Context, value == AL_NONE || - value == AL_INVERSE_DISTANCE || - value == AL_INVERSE_DISTANCE_CLAMPED || - value == AL_LINEAR_DISTANCE || - value == AL_LINEAR_DISTANCE_CLAMPED || - value == AL_EXPONENT_DISTANCE || - value == AL_EXPONENT_DISTANCE_CLAMPED); - - Context->DistanceModel = value; - if(!Context->SourceDistanceModel) - Context->UpdateSources = AL_TRUE; - } - al_endtry; + if(!(value == AL_INVERSE_DISTANCE || value == AL_INVERSE_DISTANCE_CLAMPED || + value == AL_LINEAR_DISTANCE || value == AL_LINEAR_DISTANCE_CLAMPED || + value == AL_EXPONENT_DISTANCE || value == AL_EXPONENT_DISTANCE_CLAMPED || + value == AL_NONE)) + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + + context->DistanceModel = value; + if(!context->SourceDistanceModel) + context->UpdateSources = AL_TRUE; - ALCcontext_DecRef(Context); +done: + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(!Context->DeferUpdates) + if(!context->DeferUpdates) { ALboolean UpdateSources; ALsource **src, **src_end; @@ -601,61 +721,61 @@ AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void) SetMixerFPUMode(&oldMode); - LockContext(Context); - Context->DeferUpdates = AL_TRUE; + LockContext(context); + context->DeferUpdates = AL_TRUE; /* Make sure all pending updates are performed */ - UpdateSources = ExchangeInt(&Context->UpdateSources, AL_FALSE); + UpdateSources = ExchangeInt(&context->UpdateSources, AL_FALSE); - src = Context->ActiveSources; - src_end = src + Context->ActiveSourceCount; + src = context->ActiveSources; + src_end = src + context->ActiveSourceCount; while(src != src_end) { if((*src)->state != AL_PLAYING) { - Context->ActiveSourceCount--; + context->ActiveSourceCount--; *src = *(--src_end); continue; } if(ExchangeInt(&(*src)->NeedsUpdate, AL_FALSE) || UpdateSources) - ALsource_Update(*src, Context); + ALsource_Update(*src, context); src++; } - slot = Context->ActiveEffectSlots; - slot_end = slot + Context->ActiveEffectSlotCount; + slot = context->ActiveEffectSlots; + slot_end = slot + context->ActiveEffectSlotCount; while(slot != slot_end) { if(ExchangeInt(&(*slot)->NeedsUpdate, AL_FALSE)) - ALeffectState_Update((*slot)->EffectState, Context->Device, *slot); + V((*slot)->EffectState,update)(context->Device, *slot); slot++; } - UnlockContext(Context); + UnlockContext(context); RestoreFPUMode(&oldMode); } - ALCcontext_DecRef(Context); + ALCcontext_DecRef(context); } AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void) { - ALCcontext *Context; + ALCcontext *context; - Context = GetContextRef(); - if(!Context) return; + context = GetContextRef(); + if(!context) return; - if(ExchangeInt(&Context->DeferUpdates, AL_FALSE)) + if(ExchangeInt(&context->DeferUpdates, AL_FALSE)) { ALsizei pos; - LockContext(Context); - LockUIntMapRead(&Context->SourceMap); - for(pos = 0;pos < Context->SourceMap.size;pos++) + LockContext(context); + LockUIntMapRead(&context->SourceMap); + for(pos = 0;pos < context->SourceMap.size;pos++) { - ALsource *Source = Context->SourceMap.array[pos].value; + ALsource *Source = context->SourceMap.array[pos].value; ALenum new_state; if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) && @@ -664,11 +784,11 @@ AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void) new_state = ExchangeInt(&Source->new_state, AL_NONE); if(new_state) - SetSourceState(Source, Context, new_state); + SetSourceState(Source, context, new_state); } - UnlockUIntMapRead(&Context->SourceMap); - UnlockContext(Context); + UnlockUIntMapRead(&context->SourceMap); + UnlockContext(context); } - ALCcontext_DecRef(Context); + ALCcontext_DecRef(context); } |