ALenum eax2BufferGet(ALuint property, ALuint source, ALvoid *value, ALuint size, ALint iSWMixer) { ALsource *pSource; ALuint ulBytes; ALenum ALErrorCode = AL_NO_ERROR; pSource = (ALsource*)ALTHUNK_LOOKUPENTRY(source); if ((pSource->uservalue3) || (iSWMixer)) { if (!bEAX2Initialized) { bEAX2Initialized = AL_TRUE; } if (pSource->uservalue3) { if (FAILED(IKsPropertySet_Get((LPKSPROPERTYSET)pSource->uservalue3, &DSPROPSETID_EAX20_BufferProperties, property, NULL, 0, value, size, &ulBytes))) ALErrorCode = AL_INVALID_OPERATION; } } else { ALErrorCode = AL_INVALID_OPERATION; } return ALErrorCode; }
ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *pflValue) { ALCcontext *Context; Context = GetContextSuspended(); if(!Context) return; if (alIsAuxiliaryEffectSlot(effectslot)) { ALeffectslot *ALEffectSlot = (ALeffectslot*)ALTHUNK_LOOKUPENTRY(effectslot); switch(param) { case AL_EFFECTSLOT_GAIN: *pflValue = ALEffectSlot->Gain; break; default: alSetError(AL_INVALID_ENUM); break; } } else alSetError(AL_INVALID_NAME); ProcessContext(Context); }
ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue) { ALCcontext *Context; Context = alcGetCurrentContext(); SuspendContext(Context); if (filter && alIsFilter(filter)) { ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(filter); switch(param) { case AL_FILTER_TYPE: if(iValue == AL_FILTER_NULL || iValue == AL_FILTER_LOWPASS) InitFilterParams(ALFilter, iValue); else alSetError(AL_INVALID_VALUE); break; default: alSetError(AL_INVALID_ENUM); break; } } else alSetError(AL_INVALID_NAME); ProcessContext(Context); }
ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue) { ALCcontext *Context; Context = alcGetCurrentContext(); SuspendContext(Context); if (filter && alIsFilter(filter)) { ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(filter); switch(param) { case AL_FILTER_TYPE: *piValue = ALFilter->type; break; default: alSetError(AL_INVALID_ENUM); break; } } else alSetError(AL_INVALID_NAME); ProcessContext(Context); }
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue) { ALCcontext *Context; Context = alcGetCurrentContext(); if(!Context) { alSetError(AL_INVALID_OPERATION); return; } SuspendContext(Context); if (alIsAuxiliaryEffectSlot(effectslot)) { ALeffectslot *ALEffectSlot = (ALeffectslot*)ALTHUNK_LOOKUPENTRY(effectslot); switch(param) { case AL_EFFECTSLOT_GAIN: if(flValue >= 0.0f && flValue <= 1.0f) ALEffectSlot->Gain = flValue; else alSetError(AL_INVALID_VALUE); break; default: alSetError(AL_INVALID_ENUM); break; } } else alSetError(AL_INVALID_NAME); ProcessContext(Context); }
ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *piValue) { ALCcontext *Context; Context = GetContextSuspended(); if(!Context) return; if (alIsAuxiliaryEffectSlot(effectslot)) { ALeffectslot *ALEffectSlot = (ALeffectslot*)ALTHUNK_LOOKUPENTRY(effectslot); switch(param) { case AL_EFFECTSLOT_EFFECT: *piValue = ALEffectSlot->effect.effect; break; case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: *piValue = ALEffectSlot->AuxSendAuto; break; default: alSetError(AL_INVALID_ENUM); break; } } else alSetError(AL_INVALID_NAME); ProcessContext(Context); }
ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues) { ALCcontext *Context; Context = alcGetCurrentContext(); SuspendContext(Context); if (effect && alIsEffect(effect)) { ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect); if(param == AL_EFFECT_TYPE) { alGetEffecti(effect, param, piValues); } else if(ALEffect->type == AL_EFFECT_EAXREVERB) { switch(param) { case AL_EAXREVERB_DECAY_HFLIMIT: alGetEffecti(effect, param, piValues); break; default: alSetError(AL_INVALID_ENUM); break; } } else if(ALEffect->type == AL_EFFECT_REVERB) { switch(param) { case AL_REVERB_DECAY_HFLIMIT: alGetEffecti(effect, param, piValues); break; default: alSetError(AL_INVALID_ENUM); break; } } else if(ALEffect->type == AL_EFFECT_ECHO) { switch(param) { default: alSetError(AL_INVALID_ENUM); break; } } else alSetError(AL_INVALID_ENUM); } else alSetError(AL_INVALID_NAME); ProcessContext(Context); }
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue) { ALCcontext *Context; Context = alcGetCurrentContext(); if(!Context) { alSetError(AL_INVALID_OPERATION); return; } SuspendContext(Context); if (alIsAuxiliaryEffectSlot(effectslot)) { ALeffectslot *ALEffectSlot = (ALeffectslot*)ALTHUNK_LOOKUPENTRY(effectslot); switch(param) { case AL_EFFECTSLOT_EFFECT: if(alIsEffect(iValue)) { ALeffect *effect = (ALeffect*)ALTHUNK_LOOKUPENTRY(iValue); InitializeEffect(Context, ALEffectSlot, effect); } else alSetError(AL_INVALID_VALUE); break; case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO: if(iValue == AL_TRUE || iValue == AL_FALSE) ALEffectSlot->AuxSendAuto = iValue; else alSetError(AL_INVALID_VALUE); break; default: alSetError(AL_INVALID_ENUM); break; } } else alSetError(AL_INVALID_NAME); ProcessContext(Context); }
ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, ALuint *filters) { ALCcontext *Context; ALfilter *ALFilter; ALsizei i; Context = alcGetCurrentContext(); SuspendContext(Context); if (n >= 0) { // Check that all filters are valid for (i = 0; i < n; i++) { if (!alIsFilter(filters[i])) { alSetError(AL_INVALID_NAME); break; } } if (i == n) { // All filters are valid for (i = 0; i < n; i++) { // Recheck that the filter is valid, because there could be duplicated names if (filters[i] && alIsFilter(filters[i])) { ALfilter **list; ALFilter = ((ALfilter*)ALTHUNK_LOOKUPENTRY(filters[i])); // Remove Source from list of Sources list = &g_FilterList; while(*list && *list != ALFilter) list = &(*list)->next; if(*list) *list = (*list)->next; ALTHUNK_REMOVEENTRY(ALFilter->filter); memset(ALFilter, 0, sizeof(ALfilter)); free(ALFilter); g_FilterCount--; } } } } else alSetError(AL_INVALID_VALUE); ProcessContext(Context); }
AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, ALuint *effects) { ALCcontext *Context; ALeffect *ALEffect; ALsizei i; Context = alcGetCurrentContext(); SuspendContext(Context); if (n >= 0) { // Check that all effects are valid for (i = 0; i < n; i++) { if (!alIsEffect(effects[i])) { alSetError(AL_INVALID_NAME); break; } } if (i == n) { // All effects are valid for (i = 0; i < n; i++) { // Recheck that the effect is valid, because there could be duplicated names if (effects[i] && alIsEffect(effects[i])) { ALeffect **list; ALEffect = ((ALeffect*)ALTHUNK_LOOKUPENTRY(effects[i])); // Remove Source from list of Sources list = &g_EffectList; while(*list && *list != ALEffect) list = &(*list)->next; if(*list) *list = (*list)->next; ALTHUNK_REMOVEENTRY(ALEffect->effect); memset(ALEffect, 0, sizeof(ALeffect)); free(ALEffect); g_EffectCount--; } } } } else alSetError(AL_INVALID_VALUE); ProcessContext(Context); }
ALAPI ALvoid ALAPIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue) { ALCcontext *pContext; ALbuffer *pBuffer; pContext = alcGetCurrentContext(); SuspendContext(pContext); if (plValue) { if (alIsBuffer(buffer) && (buffer != 0)) { pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer)); switch (eParam) { case AL_FREQUENCY: *plValue = pBuffer->frequency; break; case AL_BITS: *plValue = aluBytesFromFormat(pBuffer->format) * 8; break; case AL_CHANNELS: *plValue = aluChannelsFromFormat(pBuffer->format); break; case AL_SIZE: *plValue = pBuffer->size; break; default: alSetError(AL_INVALID_ENUM); break; } } else { alSetError(AL_INVALID_NAME); } } else { alSetError(AL_INVALID_VALUE); } ProcessContext(pContext); }
ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue) { ALCcontext *Context; Context = alcGetCurrentContext(); SuspendContext(Context); if (filter && alIsFilter(filter)) { ALfilter *ALFilter = (ALfilter*)ALTHUNK_LOOKUPENTRY(filter); switch(ALFilter->type) { case AL_FILTER_LOWPASS: switch(param) { case AL_LOWPASS_GAIN: if(flValue >= 0.0f && flValue <= 1.0f) ALFilter->Gain = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_LOWPASS_GAINHF: if(flValue >= 0.0f && flValue <= 1.0f) ALFilter->GainHF = flValue; else alSetError(AL_INVALID_VALUE); break; default: alSetError(AL_INVALID_ENUM); break; } break; default: alSetError(AL_INVALID_ENUM); break; } } else alSetError(AL_INVALID_NAME); ProcessContext(Context); }
AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues) { ALCcontext *Context; Context = alcGetCurrentContext(); SuspendContext(Context); if (effect && alIsEffect(effect)) { ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect); if(ALEffect->type == AL_EFFECT_REVERB) { switch(param) { case AL_REVERB_DENSITY: case AL_REVERB_DIFFUSION: case AL_REVERB_GAIN: case AL_REVERB_GAINHF: case AL_REVERB_DECAY_TIME: case AL_REVERB_DECAY_HFRATIO: case AL_REVERB_REFLECTIONS_GAIN: case AL_REVERB_REFLECTIONS_DELAY: case AL_REVERB_LATE_REVERB_GAIN: case AL_REVERB_LATE_REVERB_DELAY: case AL_REVERB_AIR_ABSORPTION_GAINHF: case AL_REVERB_ROOM_ROLLOFF_FACTOR: alGetEffectf(effect, param, pflValues); break; default: alSetError(AL_INVALID_ENUM); break; } } else alSetError(AL_INVALID_ENUM); } else alSetError(AL_INVALID_NAME); ProcessContext(Context); }
AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue) { ALCcontext *Context; Context = alcGetCurrentContext(); SuspendContext(Context); if (effect && alIsEffect(effect)) { ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect); if(param == AL_EFFECT_TYPE) { if(iValue == AL_EFFECT_NULL || iValue == AL_EFFECT_REVERB) InitEffectParams(ALEffect, iValue); else alSetError(AL_INVALID_VALUE); } else if(ALEffect->type == AL_EFFECT_REVERB) { switch(param) { case AL_REVERB_DECAY_HFLIMIT: if(iValue == AL_TRUE || iValue == AL_FALSE) ALEffect->Reverb.DecayHFLimit = iValue; else alSetError(AL_INVALID_VALUE); break; default: alSetError(AL_INVALID_ENUM); break; } } else alSetError(AL_INVALID_ENUM); } else alSetError(AL_INVALID_NAME); ProcessContext(Context); }
/* * alIsBuffer(ALuint uiBuffer) * * Checks if ulBuffer is a valid Buffer Name */ ALAPI ALboolean ALAPIENTRY alIsBuffer(ALuint uiBuffer) { ALCcontext *Context; ALboolean result=AL_FALSE; ALbuffer *ALBuf; ALbuffer *TgtALBuf; Context = alcGetCurrentContext(); SuspendContext(Context); if (uiBuffer) { TgtALBuf = (ALbuffer *)ALTHUNK_LOOKUPENTRY(uiBuffer); // Check through list of generated buffers for uiBuffer ALBuf = g_pBuffers; while (ALBuf) { if (ALBuf == TgtALBuf) { result = AL_TRUE; break; } ALBuf = ALBuf->next; } } else { result = AL_TRUE; } ProcessContext(Context); return result; }
ALUAPI ALvoid ALUAPIENTRY aluMixData(ALvoid *context,ALvoid *buffer,ALsizei size,ALenum format) { ALfloat Pitch,DrySend[OUTPUTCHANNELS],WetSend[OUTPUTCHANNELS]; static float DryBuffer[BUFFERSIZE][OUTPUTCHANNELS]; static float WetBuffer[BUFFERSIZE][OUTPUTCHANNELS]; ALuint BlockAlign,BytesPerSample,BufferSize; ALuint DataSize,DataPosInt,DataPosFrac; ALuint Channels,Bits,Frequency,ulExtraSamples; ALint Looping,increment,State; ALuint Buffer,fraction; ALCcontext *ALContext; ALuint SamplesToDo; ALsource *ALSource; ALbuffer *ALBuffer; ALfloat value; ALshort *Data; ALuint i,j,k; ALenum Error; ALbufferlistitem *BufferListItem; ALuint loop; __int64 DataSize64,DataPos64; unsigned int fpuState; if (context) { ALContext=((ALCcontext *)context); SuspendContext(ALContext); //Save FPU state fpuState=_controlfp(0,0); //Change FPU rounding mode _controlfp(_RC_CHOP,_MCW_RC); if ((buffer)&&(size)) { //Figure output format variables switch (format) { case AL_FORMAT_MONO8: BlockAlign=1; BytesPerSample=1; break; case AL_FORMAT_STEREO8: BlockAlign=2; BytesPerSample=1; break; case AL_FORMAT_MONO16: BlockAlign=2; BytesPerSample=2; break; case AL_FORMAT_STEREO16: default: BlockAlign=4; BytesPerSample=2; break; } //Setup variables ALSource=ALContext->Source; SamplesToDo=((size/BlockAlign)<BUFFERSIZE?(size/BlockAlign):BUFFERSIZE); //Clear mixing buffer memset(DryBuffer,0,SamplesToDo*OUTPUTCHANNELS*sizeof(ALfloat)); memset(WetBuffer,0,SamplesToDo*OUTPUTCHANNELS*sizeof(ALfloat)); //Actual mixing loop for (i=0;i<ALContext->SourceCount;i++) { j=0; State = ALSource->state; while ((State==AL_PLAYING)&&(j<SamplesToDo)) { aluCalculateSourceParameters((ALuint)ALSource->source,ALContext->Frequency,ALContext->Channels,DrySend,WetSend,&Pitch); //Get buffer info if (Buffer = ALSource->ulBufferID) { ALBuffer = (ALbuffer*)ALTHUNK_LOOKUPENTRY(Buffer); Data = ALBuffer->data; Bits = (((ALBuffer->format==AL_FORMAT_MONO8)||(ALBuffer->format==AL_FORMAT_STEREO8))?8:16); DataSize = ALBuffer->size; Channels = (((ALBuffer->format==AL_FORMAT_MONO8)||(ALBuffer->format==AL_FORMAT_MONO16))?1:2); Frequency = ALBuffer->frequency; Pitch=((Pitch*Frequency)/ALContext->Frequency); DataSize=(DataSize/(Bits*Channels/8)); //Get source info DataPosInt=ALSource->position; DataPosFrac=ALSource->position_fraction; //Compute 18.14 fixed point step increment=aluF2L(Pitch*(1L<<FRACTIONBITS)); if (increment > (MAX_PITCH<<FRACTIONBITS)) increment=(MAX_PITCH<<FRACTIONBITS); //Figure out how many samples we can mix. //Pitch must be <= 4 (the number below !) DataSize64=DataSize+MAX_PITCH; DataSize64<<=FRACTIONBITS; DataPos64=DataPosInt; DataPos64<<=FRACTIONBITS; DataPos64+=DataPosFrac; //FIX DEVIDE BY ZERO (NUMMER) if (increment == 0) increment = 1; BufferSize=(ALuint)((DataSize64-DataPos64)/increment); BufferListItem = ALSource->queue; for (loop = 0; loop < ALSource->BuffersAddedToDSBuffer; loop++) if (BufferListItem) BufferListItem = BufferListItem->next; if (BufferListItem) { if (BufferListItem->next) { if (Channels==2) { if (((ALbuffer*)ALTHUNK_LOOKUPENTRY(BufferListItem->next->buffer))->data) { ulExtraSamples = min(((ALbuffer*)ALTHUNK_LOOKUPENTRY(BufferListItem->next->buffer))->size, 32); memcpy(&Data[DataSize*2], ((ALbuffer*)ALTHUNK_LOOKUPENTRY(BufferListItem->next->buffer))->data, ulExtraSamples); } } else { if (((ALbuffer*)ALTHUNK_LOOKUPENTRY(BufferListItem->next->buffer))->data) { ulExtraSamples = min(((ALbuffer*)ALTHUNK_LOOKUPENTRY(BufferListItem->next->buffer))->size, 16); memcpy(&Data[DataSize], ((ALbuffer*)ALTHUNK_LOOKUPENTRY(BufferListItem->next->buffer))->data, ulExtraSamples); } } } else if (ALSource->bLooping) { if (ALSource->queue->buffer) { if (Channels==2) { if (((ALbuffer*)ALTHUNK_LOOKUPENTRY(ALSource->queue->buffer))->data) { ulExtraSamples = min(((ALbuffer*)ALTHUNK_LOOKUPENTRY(ALSource->queue->buffer))->size, 32); memcpy(&Data[DataSize*2], ((ALbuffer*)ALTHUNK_LOOKUPENTRY(ALSource->queue->buffer))->data, ulExtraSamples); } } else { if (((ALbuffer*)ALTHUNK_LOOKUPENTRY(ALSource->queue->buffer))->data) { ulExtraSamples = min(((ALbuffer*)ALTHUNK_LOOKUPENTRY(ALSource->queue->buffer))->size, 16); memcpy(&Data[DataSize], ((ALbuffer*)ALTHUNK_LOOKUPENTRY(ALSource->queue->buffer))->data, ulExtraSamples); } } } } } BufferSize=(BufferSize<(SamplesToDo-j)?BufferSize:(SamplesToDo-j)); //Actual sample mixing loop Data+=DataPosInt*Channels; while (BufferSize--) { k=DataPosFrac>>FRACTIONBITS; fraction=DataPosFrac&FRACTIONMASK; if (Channels==1) { //First order interpolator value=(ALfloat)((ALshort)(((Data[k]*((1L<<FRACTIONBITS)-fraction))+(Data[k+1]*(fraction)))>>FRACTIONBITS)); //Direct path final mix buffer and panning DryBuffer[j][0]+=value*DrySend[0]; DryBuffer[j][1]+=value*DrySend[1]; //Room path final mix buffer and panning WetBuffer[j][0]+=value*WetSend[0]; WetBuffer[j][1]+=value*WetSend[1]; } else { //First order interpolator (left) value=(ALfloat)((ALshort)(((Data[k*2 ]*((1L<<FRACTIONBITS)-fraction))+(Data[k*2+2]*(fraction)))>>FRACTIONBITS)); //Direct path final mix buffer and panning (left) DryBuffer[j][0]+=value*DrySend[0]; //Room path final mix buffer and panning (left) WetBuffer[j][0]+=value*WetSend[0]; //First order interpolator (right) value=(ALfloat)((ALshort)(((Data[k*2+1]*((1L<<FRACTIONBITS)-fraction))+(Data[k*2+3]*(fraction)))>>FRACTIONBITS)); //Direct path final mix buffer and panning (right) DryBuffer[j][1]+=value*DrySend[1]; //Room path final mix buffer and panning (right) WetBuffer[j][1]+=value*WetSend[1]; } DataPosFrac+=increment; j++; } DataPosInt+=(DataPosFrac>>FRACTIONBITS); DataPosFrac=(DataPosFrac&FRACTIONMASK); //Update source info ALSource->position=DataPosInt; ALSource->position_fraction=DataPosFrac; } //Handle looping sources if ((!Buffer)||(DataPosInt>=DataSize)) { //queueing if (ALSource->queue) { Looping = ALSource->bLooping; if (ALSource->BuffersAddedToDSBuffer < (ALSource->BuffersInQueue-1)) { BufferListItem = ALSource->queue; for (loop = 0; loop <= ALSource->BuffersAddedToDSBuffer; loop++) { if (BufferListItem) { if (!Looping) BufferListItem->bufferstate=PROCESSED; BufferListItem = BufferListItem->next; } } if (!Looping) ALSource->BuffersProcessed++; if (BufferListItem) ALSource->ulBufferID=BufferListItem->buffer; ALSource->position=DataPosInt-DataSize; ALSource->position_fraction=DataPosFrac; ALSource->BuffersAddedToDSBuffer++; } else { alSourceStop((ALuint)ALSource->source); if (Looping) { alSourceRewind((ALuint)ALSource->source); alSourcePlay((ALuint)ALSource->source); ALSource->position=DataPosInt-DataSize; ALSource->position_fraction=DataPosFrac; } } } } //Get source state State = ALSource->state; } ALSource=ALSource->next; }
AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue) { ALCcontext *Context; Context = alcGetCurrentContext(); SuspendContext(Context); if (effect && alIsEffect(effect)) { ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect); if(ALEffect->type == AL_EFFECT_REVERB) { switch(param) { case AL_REVERB_DENSITY: *pflValue = ALEffect->Reverb.Density; break; case AL_REVERB_DIFFUSION: *pflValue = ALEffect->Reverb.Diffusion; break; case AL_REVERB_GAIN: *pflValue = ALEffect->Reverb.Gain; break; case AL_REVERB_GAINHF: *pflValue = ALEffect->Reverb.GainHF; break; case AL_REVERB_DECAY_TIME: *pflValue = ALEffect->Reverb.DecayTime; break; case AL_REVERB_DECAY_HFRATIO: *pflValue = ALEffect->Reverb.DecayHFRatio; break; case AL_REVERB_REFLECTIONS_GAIN: *pflValue = ALEffect->Reverb.ReflectionsGain; break; case AL_REVERB_REFLECTIONS_DELAY: *pflValue = ALEffect->Reverb.ReflectionsDelay; break; case AL_REVERB_LATE_REVERB_GAIN: *pflValue = ALEffect->Reverb.LateReverbGain; break; case AL_REVERB_LATE_REVERB_DELAY: *pflValue = ALEffect->Reverb.LateReverbDelay; break; case AL_REVERB_AIR_ABSORPTION_GAINHF: *pflValue = ALEffect->Reverb.AirAbsorptionGainHF; break; case AL_REVERB_ROOM_ROLLOFF_FACTOR: *pflValue = ALEffect->Reverb.RoomRolloffFactor; break; default: alSetError(AL_INVALID_ENUM); break; } } else alSetError(AL_INVALID_ENUM); } else alSetError(AL_INVALID_NAME); ProcessContext(Context); }
/* EAXSet(propertySetID, property, source, value, size) propertySetID : GUID of EAX Property Set (defined in eax.h files) property : Property in Property Set to affect (enumerations defined in eax.h files) source : Source to apply EAX affects to (this can be NULL for Listener Property Sets) value : Pointer to value to set size : Size of data pointed to by value Returns AL_INVALID_NAME if a valid Source name was required but not given Returns AL_INVALID_OPERATION if the Source is 2D or the EAX call fails Returns AL_INVALID_VALUE if the GUID is not recognized */ ALAPI ALenum ALAPIENTRY EAXSet(const GUID *propertySetID,ALuint property,ALuint source,ALvoid *pValue,ALuint size) { ALsource *ALSource; ALCcontext *ALContext; ALCcontext *ALCContext; ALuint i; ALenum ALErrorCode = AL_NO_ERROR; EAXGUID eaxGuid; ALboolean bGenSource = AL_FALSE; ALint iSWReverbMixer = 0; ALCdevice *ALDevice = NULL; ALContext=alcGetCurrentContext(); SuspendContext(ALContext); ALCContext = ALContext; eaxGuid = GetEAXGuid(propertySetID); if (eaxGuid & EAXBUFFERGUID) { if (alIsSource(source)) { if (eaxGuid == EAX2B) ALErrorCode = eax2BufferSet(property, source, pValue, size, iSWReverbMixer); } else { ALErrorCode = AL_INVALID_NAME; } } else if (eaxGuid & EAXLISTENERGUID) { // If source is valid use that, otherwise find a source if (alIsSource(source)) { ALSource = (ALsource*)ALTHUNK_LOOKUPENTRY(source); } else { ALSource = ALContext->Source; // See if one has already been created for (i=0;i<ALContext->SourceCount;i++) { if ((ALSource->uservalue3) || (iSWReverbMixer)) break; ALSource = ALSource->next; } // If an appropriate source wasn't created, generate one now if (ALSource == NULL) { ALuint alsource = 0; alGenSources(1, ((ALuint *)(&alsource))); if (alGetError() == AL_NO_ERROR) { ALSource = (ALsource*)ALTHUNK_LOOKUPENTRY(alsource); bGenSource = AL_TRUE; } } } if (ALSource) { if (eaxGuid == EAX2L) ALErrorCode = eax2ListenerSet(property, ALSource, pValue, size, iSWReverbMixer); } else ALErrorCode = AL_INVALID_OPERATION; } else { ALErrorCode = AL_INVALID_VALUE; } // If we generated a source to set the EAX Listener property, release it now if (bGenSource) alDeleteSources(1, (ALuint *)&ALSource->source); ProcessContext(ALCContext); return ALErrorCode; }
/* Test for support of appropriate EAX Version */ ALboolean CheckEAXSupport(const ALchar *szEAXName) { ALCcontext *ALContext; ALCdevice *ALCDevice; ALsource *ALSource; LPKSPROPERTYSET lpPropertySet = NULL; GUID ListenerGuid, BufferGuid; ALuint ListenerProperty, BufferProperty; ALuint i, ulSupport; ALuint property, size; ALint value = 0xFFFFFFFF; ALfloat fvalue; ALboolean bSourceGenerated = AL_FALSE; ALboolean bEAXSupported = AL_FALSE; ALint iSWReverbMixer = 0; ALContext = alcGetCurrentContext(); ALCDevice = alcGetContextsDevice(ALContext); SuspendContext(ALContext); if (iSWReverbMixer) { } else { // To test for EAX support we will need a valid Source ALSource = ALContext->Source; // See if one has already been created for (i=0;i<ALContext->SourceCount;i++) { if (ALSource->uservalue3) { lpPropertySet = ALSource->uservalue3; break; } ALSource = ALSource->next; } // If we didn't find a valid source, create one now if (lpPropertySet == NULL) { ALuint alsource = 0; alGenSources(1, ((ALuint *)(&alsource))); if (alGetError() == AL_NO_ERROR) { ALSource = (ALsource*)ALTHUNK_LOOKUPENTRY(alsource); lpPropertySet = ALSource->uservalue3; bSourceGenerated = AL_TRUE; } } // If Property Set Interface hasn't been obtained, EAX support is not available if (lpPropertySet) { if ( (_stricmp(szEAXName, "EAX") == 0) || (_stricmp(szEAXName, "EAX2.0") == 0) ) { ListenerGuid = DSPROPSETID_EAX20_ListenerProperties; BufferGuid = DSPROPSETID_EAX20_BufferProperties; ListenerProperty = 1; // LISTENER_ALL BufferProperty = 1; // BUFFER_ALL property = 2; // ROOM size = sizeof(ALint); value = -10000; } else { // Unknown EAX Name if (bSourceGenerated) alDeleteSources(1, ((ALuint *)&ALSource->source)); ProcessContext(ALContext); return AL_FALSE; } if (SUCCEEDED(IKsPropertySet_QuerySupport(lpPropertySet, &ListenerGuid, ListenerProperty, &ulSupport))) { if ( (ulSupport & KSPROPERTY_SUPPORT_GET) && (ulSupport & KSPROPERTY_SUPPORT_SET)) { if (SUCCEEDED(IKsPropertySet_QuerySupport(lpPropertySet, &BufferGuid, BufferProperty, &ulSupport))) { if ( (ulSupport & KSPROPERTY_SUPPORT_GET) && (ulSupport & KSPROPERTY_SUPPORT_SET) ) { // Fully supported ! bEAXSupported = AL_TRUE; // Set Default Property if (value != 0xFFFFFFFF) IKsPropertySet_Set(lpPropertySet, &ListenerGuid, property, NULL, 0, &value, sizeof(ALint)); else IKsPropertySet_Set(lpPropertySet, &ListenerGuid, property, NULL, 0, &fvalue, sizeof(ALfloat)); } } } } } if (bSourceGenerated) alDeleteSources(1, ((ALuint *)&ALSource->source)); } ProcessContext(ALContext); return bEAXSupported; }
/* * alBufferData(ALuint buffer,ALenum format,ALvoid *data,ALsizei size,ALsizei freq) * * Fill buffer with audio data */ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq) { ALuint *IMAData,IMACode; ALCcontext *Context; ALint Sample,Index; ALint LeftSample,LeftIndex; ALint RightSample,RightIndex; ALuint LeftIMACode,RightIMACode; ALbuffer *ALBuf; ALsizei i,j,k; Context = alcGetCurrentContext(); SuspendContext(Context); if (alIsBuffer(buffer) && (buffer != 0)) { ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer)); if ((ALBuf->refcount==0)&&(data)) { switch(format) { case AL_FORMAT_MONO8: case AL_FORMAT_MONO16: case AL_FORMAT_MONO_FLOAT32: LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO16); break; case AL_FORMAT_STEREO8: case AL_FORMAT_STEREO16: case AL_FORMAT_STEREO_FLOAT32: LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO16); break; case AL_FORMAT_REAR8: case AL_FORMAT_REAR16: case AL_FORMAT_REAR32: { ALuint NewFormat = AL_FORMAT_QUAD16; ALuint NewChannels = aluChannelsFromFormat(NewFormat); ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 : ((format==AL_FORMAT_REAR16) ? 2 : 4)); ALsizei i; assert(aluBytesFromFormat(NewFormat) == 2); if ((size%(OrigBytes*2)) != 0) { alSetError(AL_INVALID_VALUE); break; } switch(OrigBytes) { case 1: size /= sizeof(ALubyte); size *= 2; // 8bit Samples are converted to 16 bit here // Allocate 8 extra samples ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort))); if (ALBuf->data) { for (i = 0;i < size;i+=4) { ALBuf->data[i+0] = 0; ALBuf->data[i+1] = 0; ALBuf->data[i+2] = (ALshort)((((ALubyte*)data)[i/2+0]-128) << 8); ALBuf->data[i+3] = (ALshort)((((ALubyte*)data)[i/2+1]-128) << 8); } memset(&(ALBuf->data[size]), 0, 16*NewChannels); ALBuf->format = NewFormat; ALBuf->eOriginalFormat = format; ALBuf->size = size*1*sizeof(ALshort); ALBuf->frequency = freq; } else alSetError(AL_OUT_OF_MEMORY); break; case 2: size /= sizeof(ALshort); size *= 2; // Allocate 8 extra samples ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort))); if (ALBuf->data) { for (i = 0;i < size;i+=4) { ALBuf->data[i+0] = 0; ALBuf->data[i+1] = 0; ALBuf->data[i+2] = ((ALshort*)data)[i/2+0]; ALBuf->data[i+3] = ((ALshort*)data)[i/2+1]; } memset(&(ALBuf->data[size]), 0, 16*NewChannels); ALBuf->format = NewFormat; ALBuf->eOriginalFormat = format; ALBuf->size = size*1*sizeof(ALshort); ALBuf->frequency = freq; } else alSetError(AL_OUT_OF_MEMORY); break; case 4: size /= sizeof(ALfloat); size *= 2; // Allocate 8 extra samples ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort))); if (ALBuf->data) { ALint smp; for (i = 0;i < size;i+=4) { ALBuf->data[i+0] = 0; ALBuf->data[i+1] = 0; smp = (((ALfloat*)data)[i/2+0] * 32767.5f - 0.5); smp = min(smp, 32767); smp = max(smp, -32768); ALBuf->data[i+2] = (ALshort)smp; smp = (((ALfloat*)data)[i/2+1] * 32767.5f - 0.5); smp = min(smp, 32767); smp = max(smp, -32768); ALBuf->data[i+3] = (ALshort)smp; } memset(&(ALBuf->data[size]), 0, 16*NewChannels); ALBuf->format = NewFormat; ALBuf->eOriginalFormat = format; ALBuf->size = size*1*sizeof(ALshort); ALBuf->frequency = freq; } else alSetError(AL_OUT_OF_MEMORY); break; default: assert(0); } } break; case AL_FORMAT_QUAD8_LOKI: case AL_FORMAT_QUAD16_LOKI: case AL_FORMAT_QUAD8: case AL_FORMAT_QUAD16: case AL_FORMAT_QUAD32: LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD16); break; case AL_FORMAT_51CHN8: case AL_FORMAT_51CHN16: case AL_FORMAT_51CHN32: LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN16); break; case AL_FORMAT_61CHN8: case AL_FORMAT_61CHN16: case AL_FORMAT_61CHN32: LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN16); break; case AL_FORMAT_71CHN8: case AL_FORMAT_71CHN16: case AL_FORMAT_71CHN32: LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN16); break; case AL_FORMAT_MONO_IMA4: // Here is where things vary: // nVidia and Apple use 64+1 samples per block => block_size=36 bytes // Most PC sound software uses 2040+1 samples per block -> block_size=1024 bytes if ((size%36) == 0) { // Allocate 8 extra samples (16 bytes) ALBuf->data=realloc(ALBuf->data,16+(size/36)*(65*sizeof(ALshort))); if (ALBuf->data) { ALBuf->format = AL_FORMAT_MONO16; ALBuf->eOriginalFormat = AL_FORMAT_MONO_IMA4; IMAData=(ALuint *)data; for (i=0;i<size/36;i++) { Sample=((ALshort *)IMAData)[0]; Index=((ALshort *)IMAData)[1]; Index=Index<0?0:Index; Index=Index>88?88:Index; ALBuf->data[i*65]=(short)Sample; IMAData++; for (j=1;j<65;j+=8) { IMACode=*IMAData; for (k=0;k<8;k+=2) { Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8); Index+=g_IMAIndex_adjust_4[IMACode&15]; if (Sample<-32768) Sample=-32768; else if (Sample>32767) Sample=32767; if (Index<0) Index=0; else if (Index>88) Index=88; ALBuf->data[i*65+j+k]=(short)Sample; IMACode>>=4; Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8); Index+=g_IMAIndex_adjust_4[IMACode&15]; if (Sample<-32768) Sample=-32768; else if (Sample>32767) Sample=32767; if (Index<0) Index=0; else if (Index>88) Index=88; ALBuf->data[i*65+j+k+1]=(short)Sample; IMACode>>=4; } IMAData++; } } memset(&(ALBuf->data[(size/36*65)]), 0, 16); ALBuf->size=size/36*65*sizeof(ALshort); ALBuf->frequency=freq; } else alSetError(AL_OUT_OF_MEMORY); }
/* * alDeleteBuffers(ALsizei n, ALuint *puiBuffers) * * Deletes the n AL Buffers pointed to by puiBuffers */ ALAPI ALvoid ALAPIENTRY alDeleteBuffers(ALsizei n, const ALuint *puiBuffers) { ALCcontext *Context; ALbuffer *ALBuf; ALsizei i; ALboolean bFailed = AL_FALSE; Context = alcGetCurrentContext(); SuspendContext(Context); // Check we are actually Deleting some Buffers if (n >= 0) { // Check that all the buffers are valid and can actually be deleted for (i = 0; i < n; i++) { // Check for valid Buffer ID (can be NULL buffer) if (alIsBuffer(puiBuffers[i])) { // If not the NULL buffer, check that the reference count is 0 ALBuf = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i])); if (ALBuf) { if (ALBuf->refcount != 0) { // Buffer still in use, cannot be deleted alSetError(AL_INVALID_OPERATION); bFailed = AL_TRUE; } } } else { // Invalid Buffer alSetError(AL_INVALID_NAME); bFailed = AL_TRUE; } } // If all the Buffers were valid (and have Reference Counts of 0), then we can delete them if (!bFailed) { for (i = 0; i < n; i++) { if (puiBuffers[i] && alIsBuffer(puiBuffers[i])) { ALbuffer **list = &g_pBuffers; ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i])); while(*list && *list != ALBuf) list = &(*list)->next; if(*list) *list = (*list)->next; // Release the memory used to store audio data free(ALBuf->data); // Release buffer structure ALTHUNK_REMOVEENTRY(puiBuffers[i]); memset(ALBuf, 0, sizeof(ALbuffer)); g_uiBufferCount--; free(ALBuf); } } } } else alSetError(AL_INVALID_VALUE); ProcessContext(Context); return; }
ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue) { ALCcontext *Context; Context = alcGetCurrentContext(); SuspendContext(Context); if (effect && alIsEffect(effect)) { ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect); if(ALEffect->type == AL_EFFECT_EAXREVERB) { switch(param) { case AL_EAXREVERB_DENSITY: *pflValue = ALEffect->Reverb.Density; break; case AL_EAXREVERB_DIFFUSION: *pflValue = ALEffect->Reverb.Diffusion; break; case AL_EAXREVERB_GAIN: *pflValue = ALEffect->Reverb.Gain; break; case AL_EAXREVERB_GAINHF: *pflValue = ALEffect->Reverb.GainHF; break; case AL_EAXREVERB_GAINLF: *pflValue = ALEffect->Reverb.GainLF; break; case AL_EAXREVERB_DECAY_TIME: *pflValue = ALEffect->Reverb.DecayTime; break; case AL_EAXREVERB_DECAY_HFRATIO: *pflValue = ALEffect->Reverb.DecayHFRatio; break; case AL_EAXREVERB_DECAY_LFRATIO: *pflValue = ALEffect->Reverb.DecayLFRatio; break; case AL_EAXREVERB_REFLECTIONS_GAIN: *pflValue = ALEffect->Reverb.ReflectionsGain; break; case AL_EAXREVERB_REFLECTIONS_DELAY: *pflValue = ALEffect->Reverb.ReflectionsDelay; break; case AL_EAXREVERB_LATE_REVERB_GAIN: *pflValue = ALEffect->Reverb.LateReverbGain; break; case AL_EAXREVERB_LATE_REVERB_DELAY: *pflValue = ALEffect->Reverb.LateReverbDelay; break; case AL_EAXREVERB_AIR_ABSORPTION_GAINHF: *pflValue = ALEffect->Reverb.AirAbsorptionGainHF; break; case AL_EAXREVERB_ECHO_TIME: *pflValue = ALEffect->Reverb.EchoTime; break; case AL_EAXREVERB_ECHO_DEPTH: *pflValue = ALEffect->Reverb.EchoDepth; break; case AL_EAXREVERB_MODULATION_TIME: *pflValue = ALEffect->Reverb.ModulationTime; break; case AL_EAXREVERB_MODULATION_DEPTH: *pflValue = ALEffect->Reverb.ModulationDepth; break; case AL_EAXREVERB_HFREFERENCE: *pflValue = ALEffect->Reverb.HFReference; break; case AL_EAXREVERB_LFREFERENCE: *pflValue = ALEffect->Reverb.LFReference; break; case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR: *pflValue = ALEffect->Reverb.RoomRolloffFactor; break; default: alSetError(AL_INVALID_ENUM); break; } } else if(ALEffect->type == AL_EFFECT_REVERB) { switch(param) { case AL_REVERB_DENSITY: *pflValue = ALEffect->Reverb.Density; break; case AL_REVERB_DIFFUSION: *pflValue = ALEffect->Reverb.Diffusion; break; case AL_REVERB_GAIN: *pflValue = ALEffect->Reverb.Gain; break; case AL_REVERB_GAINHF: *pflValue = ALEffect->Reverb.GainHF; break; case AL_REVERB_DECAY_TIME: *pflValue = ALEffect->Reverb.DecayTime; break; case AL_REVERB_DECAY_HFRATIO: *pflValue = ALEffect->Reverb.DecayHFRatio; break; case AL_REVERB_REFLECTIONS_GAIN: *pflValue = ALEffect->Reverb.ReflectionsGain; break; case AL_REVERB_REFLECTIONS_DELAY: *pflValue = ALEffect->Reverb.ReflectionsDelay; break; case AL_REVERB_LATE_REVERB_GAIN: *pflValue = ALEffect->Reverb.LateReverbGain; break; case AL_REVERB_LATE_REVERB_DELAY: *pflValue = ALEffect->Reverb.LateReverbDelay; break; case AL_REVERB_AIR_ABSORPTION_GAINHF: *pflValue = ALEffect->Reverb.AirAbsorptionGainHF; break; case AL_REVERB_ROOM_ROLLOFF_FACTOR: *pflValue = ALEffect->Reverb.RoomRolloffFactor; break; default: alSetError(AL_INVALID_ENUM); break; } } else if(ALEffect->type == AL_EFFECT_ECHO) { switch(param) { case AL_ECHO_DELAY: *pflValue = ALEffect->Echo.Delay; break; case AL_ECHO_LRDELAY: *pflValue = ALEffect->Echo.LRDelay; break; case AL_ECHO_DAMPING: *pflValue = ALEffect->Echo.Damping; break; case AL_ECHO_FEEDBACK: *pflValue = ALEffect->Echo.Feedback; break; case AL_ECHO_SPREAD: *pflValue = ALEffect->Echo.Spread; break; default: alSetError(AL_INVALID_ENUM); break; } } else alSetError(AL_INVALID_ENUM); } else alSetError(AL_INVALID_NAME); ProcessContext(Context); }
ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, ALfloat *pflValues) { ALCcontext *Context; Context = alcGetCurrentContext(); SuspendContext(Context); if (effect && alIsEffect(effect)) { ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect); if(ALEffect->type == AL_EFFECT_EAXREVERB) { switch(param) { case AL_EAXREVERB_DENSITY: case AL_EAXREVERB_DIFFUSION: case AL_EAXREVERB_GAIN: case AL_EAXREVERB_GAINHF: case AL_EAXREVERB_GAINLF: case AL_EAXREVERB_DECAY_TIME: case AL_EAXREVERB_DECAY_HFRATIO: case AL_EAXREVERB_DECAY_LFRATIO: case AL_EAXREVERB_REFLECTIONS_GAIN: case AL_EAXREVERB_REFLECTIONS_DELAY: case AL_EAXREVERB_LATE_REVERB_GAIN: case AL_EAXREVERB_LATE_REVERB_DELAY: case AL_EAXREVERB_AIR_ABSORPTION_GAINHF: case AL_EAXREVERB_ECHO_TIME: case AL_EAXREVERB_ECHO_DEPTH: case AL_EAXREVERB_MODULATION_TIME: case AL_EAXREVERB_MODULATION_DEPTH: case AL_EAXREVERB_HFREFERENCE: case AL_EAXREVERB_LFREFERENCE: case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR: alEffectf(effect, param, pflValues[0]); break; case AL_EAXREVERB_REFLECTIONS_PAN: if(!isnan(pflValues[0]) && !isnan(pflValues[1]) && !isnan(pflValues[2])) { ALEffect->Reverb.ReflectionsPan[0] = pflValues[0]; ALEffect->Reverb.ReflectionsPan[1] = pflValues[1]; ALEffect->Reverb.ReflectionsPan[2] = pflValues[2]; } else alSetError(AL_INVALID_VALUE); break; case AL_EAXREVERB_LATE_REVERB_PAN: if(!isnan(pflValues[0]) && !isnan(pflValues[1]) && !isnan(pflValues[2])) { ALEffect->Reverb.LateReverbPan[0] = pflValues[0]; ALEffect->Reverb.LateReverbPan[1] = pflValues[1]; ALEffect->Reverb.LateReverbPan[2] = pflValues[2]; } else alSetError(AL_INVALID_VALUE); break; default: alSetError(AL_INVALID_ENUM); break; } } else if(ALEffect->type == AL_EFFECT_REVERB) { switch(param) { case AL_REVERB_DENSITY: case AL_REVERB_DIFFUSION: case AL_REVERB_GAIN: case AL_REVERB_GAINHF: case AL_REVERB_DECAY_TIME: case AL_REVERB_DECAY_HFRATIO: case AL_REVERB_REFLECTIONS_GAIN: case AL_REVERB_REFLECTIONS_DELAY: case AL_REVERB_LATE_REVERB_GAIN: case AL_REVERB_LATE_REVERB_DELAY: case AL_REVERB_AIR_ABSORPTION_GAINHF: case AL_REVERB_ROOM_ROLLOFF_FACTOR: alEffectf(effect, param, pflValues[0]); break; default: alSetError(AL_INVALID_ENUM); break; } } else if(ALEffect->type == AL_EFFECT_ECHO) { switch(param) { case AL_ECHO_DELAY: case AL_ECHO_LRDELAY: case AL_ECHO_DAMPING: case AL_ECHO_FEEDBACK: case AL_ECHO_SPREAD: alEffectf(effect, param, pflValues[0]); break; default: alSetError(AL_INVALID_ENUM); break; } } else alSetError(AL_INVALID_ENUM); } else alSetError(AL_INVALID_NAME); ProcessContext(Context); }
/* * alBufferData(ALuint buffer,ALenum format,ALvoid *data,ALsizei size,ALsizei freq) * * Fill buffer with audio data */ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq) { ALCcontext *Context; ALsizei padding = 2; ALbuffer *ALBuf; ALvoid *temp; Context = alcGetCurrentContext(); SuspendContext(Context); if (alIsBuffer(buffer) && (buffer != 0)) { ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer)); if ((ALBuf->refcount==0)&&(data)) { switch(format) { case AL_FORMAT_MONO8: case AL_FORMAT_MONO16: case AL_FORMAT_MONO_FLOAT32: LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO16); break; case AL_FORMAT_STEREO8: case AL_FORMAT_STEREO16: case AL_FORMAT_STEREO_FLOAT32: LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO16); break; case AL_FORMAT_REAR8: case AL_FORMAT_REAR16: case AL_FORMAT_REAR32: { ALuint NewFormat = AL_FORMAT_QUAD16; ALuint NewChannels = aluChannelsFromFormat(NewFormat); ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 : ((format==AL_FORMAT_REAR16) ? 2 : 4)); assert(aluBytesFromFormat(NewFormat) == 2); if((size%(OrigBytes*2)) != 0) { alSetError(AL_INVALID_VALUE); break; } size /= OrigBytes; size *= 2; // Samples are converted to 16 bit here temp = realloc(ALBuf->data, (padding*NewChannels + size) * sizeof(ALshort)); if(temp) { ALBuf->data = temp; ConvertDataRear(ALBuf->data, data, OrigBytes, size); memset(&(ALBuf->data[size]), 0, padding*NewChannels*sizeof(ALshort)); ALBuf->format = NewFormat; ALBuf->eOriginalFormat = format; ALBuf->size = size*sizeof(ALshort); ALBuf->frequency = freq; ALBuf->padding = padding; } else alSetError(AL_OUT_OF_MEMORY); } break; case AL_FORMAT_QUAD8_LOKI: case AL_FORMAT_QUAD16_LOKI: case AL_FORMAT_QUAD8: case AL_FORMAT_QUAD16: case AL_FORMAT_QUAD32: LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD16); break; case AL_FORMAT_51CHN8: case AL_FORMAT_51CHN16: case AL_FORMAT_51CHN32: LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN16); break; case AL_FORMAT_61CHN8: case AL_FORMAT_61CHN16: case AL_FORMAT_61CHN32: LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN16); break; case AL_FORMAT_71CHN8: case AL_FORMAT_71CHN16: case AL_FORMAT_71CHN32: LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN16); break; case AL_FORMAT_MONO_IMA4: case AL_FORMAT_STEREO_IMA4: { int OrigChans = ((format==AL_FORMAT_MONO_IMA4) ? 1 : 2); // Here is where things vary: // nVidia and Apple use 64+1 samples per channel per block => block_size=36*chans bytes // Most PC sound software uses 2040+1 samples per channel per block -> block_size=1024*chans bytes if((size%(36*OrigChans)) != 0) { alSetError(AL_INVALID_VALUE); break; } size /= 36; size *= 65; // Allocate extra padding samples temp = realloc(ALBuf->data, (padding*OrigChans + size)*sizeof(ALshort)); if(temp) { ALBuf->data = temp; ConvertDataIMA4(ALBuf->data, data, OrigChans, size/65); memset(&(ALBuf->data[size]), 0, padding*sizeof(ALshort)*OrigChans); ALBuf->format = ((OrigChans==1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16); ALBuf->eOriginalFormat = format; ALBuf->size = size*sizeof(ALshort); ALBuf->frequency = freq; ALBuf->padding = padding; } else alSetError(AL_OUT_OF_MEMORY); } break; default: alSetError(AL_INVALID_ENUM); break; } } else { // Buffer is in use, or data is a NULL pointer alSetError(AL_INVALID_VALUE); } } else { // Invalid Buffer Name alSetError(AL_INVALID_NAME); } ProcessContext(Context); }
/* * alBufferSubDataEXT(ALuint buffer,ALenum format,ALvoid *data,ALsizei offset,ALsizei length) * * Fill buffer with audio data */ ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length) { ALCcontext *Context; ALbuffer *ALBuf; Context = alcGetCurrentContext(); SuspendContext(Context); if(alIsBuffer(buffer) && buffer != 0) { ALBuf = (ALbuffer*)ALTHUNK_LOOKUPENTRY(buffer); if(ALBuf->data == NULL) { // buffer does not have any data alSetError(AL_INVALID_NAME); } else if(length < 0 || offset < 0 || (length > 0 && data == NULL)) { // data is NULL or offset/length is negative alSetError(AL_INVALID_VALUE); } else { switch(format) { case AL_FORMAT_REAR8: case AL_FORMAT_REAR16: case AL_FORMAT_REAR32: { ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 : ((format==AL_FORMAT_REAR16) ? 2 : 4)); if(ALBuf->eOriginalFormat != AL_FORMAT_REAR8 && ALBuf->eOriginalFormat != AL_FORMAT_REAR16 && ALBuf->eOriginalFormat != AL_FORMAT_REAR32) { alSetError(AL_INVALID_ENUM); break; } if(ALBuf->size/4/sizeof(ALshort) < (ALuint)offset+length) { alSetError(AL_INVALID_VALUE); break; } ConvertDataRear(&ALBuf->data[offset*4], data, OrigBytes, length*2); } break; case AL_FORMAT_MONO_IMA4: case AL_FORMAT_STEREO_IMA4: { int Channels = aluChannelsFromFormat(ALBuf->format); if(ALBuf->eOriginalFormat != format) { alSetError(AL_INVALID_ENUM); break; } if((offset%65) != 0 || (length%65) != 0 || ALBuf->size/Channels/sizeof(ALshort) < (ALuint)offset+length) { alSetError(AL_INVALID_VALUE); break; } ConvertDataIMA4(&ALBuf->data[offset*Channels], data, Channels, length/65*Channels); } break; default: { ALuint Channels = aluChannelsFromFormat(format); ALuint Bytes = aluBytesFromFormat(format); if(Channels != aluChannelsFromFormat(ALBuf->format)) { alSetError(AL_INVALID_ENUM); break; } if(ALBuf->size/Channels/sizeof(ALshort) < (ALuint)offset+length) { alSetError(AL_INVALID_VALUE); break; } ConvertData(&ALBuf->data[offset*Channels], data, Bytes, length*Channels); } break; } } } else { // Invalid Buffer Name alSetError(AL_INVALID_NAME); } ProcessContext(Context); }
ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue) { ALCcontext *Context; Context = alcGetCurrentContext(); SuspendContext(Context); if (effect && alIsEffect(effect)) { ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect); if(param == AL_EFFECT_TYPE) { ALboolean isOk = (iValue == AL_EFFECT_NULL || (iValue == AL_EFFECT_EAXREVERB && !DisabledEffects[EAXREVERB]) || (iValue == AL_EFFECT_REVERB && !DisabledEffects[REVERB]) || (iValue == AL_EFFECT_ECHO && !DisabledEffects[ECHO])); if(isOk) InitEffectParams(ALEffect, iValue); else alSetError(AL_INVALID_VALUE); } else if(ALEffect->type == AL_EFFECT_EAXREVERB) { switch(param) { case AL_EAXREVERB_DECAY_HFLIMIT: if(iValue >= AL_EAXREVERB_MIN_DECAY_HFLIMIT && iValue <= AL_EAXREVERB_MAX_DECAY_HFLIMIT) ALEffect->Reverb.DecayHFLimit = iValue; else alSetError(AL_INVALID_VALUE); break; default: alSetError(AL_INVALID_ENUM); break; } } else if(ALEffect->type == AL_EFFECT_REVERB) { switch(param) { case AL_REVERB_DECAY_HFLIMIT: if(iValue >= AL_REVERB_MIN_DECAY_HFLIMIT && iValue <= AL_REVERB_MAX_DECAY_HFLIMIT) ALEffect->Reverb.DecayHFLimit = iValue; else alSetError(AL_INVALID_VALUE); break; default: alSetError(AL_INVALID_ENUM); break; } } else if(ALEffect->type == AL_EFFECT_ECHO) { switch(param) { default: alSetError(AL_INVALID_ENUM); break; } } else alSetError(AL_INVALID_ENUM); } else alSetError(AL_INVALID_NAME); ProcessContext(Context); }
ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue) { ALCcontext *Context; Context = alcGetCurrentContext(); SuspendContext(Context); if (effect && alIsEffect(effect)) { ALeffect *ALEffect = (ALeffect*)ALTHUNK_LOOKUPENTRY(effect); if(ALEffect->type == AL_EFFECT_EAXREVERB) { switch(param) { case AL_EAXREVERB_DENSITY: if(flValue >= AL_EAXREVERB_MIN_DENSITY && flValue <= AL_EAXREVERB_MAX_DENSITY) ALEffect->Reverb.Density = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_EAXREVERB_DIFFUSION: if(flValue >= AL_EAXREVERB_MIN_DIFFUSION && flValue <= AL_EAXREVERB_MAX_DIFFUSION) ALEffect->Reverb.Diffusion = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_EAXREVERB_GAIN: if(flValue >= AL_EAXREVERB_MIN_GAIN && flValue <= AL_EAXREVERB_MAX_GAIN) ALEffect->Reverb.Gain = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_EAXREVERB_GAINHF: if(flValue >= AL_EAXREVERB_MIN_GAINHF && flValue <= AL_EAXREVERB_MAX_GAIN) ALEffect->Reverb.GainHF = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_EAXREVERB_GAINLF: if(flValue >= AL_EAXREVERB_MIN_GAINLF && flValue <= AL_EAXREVERB_MAX_GAINLF) ALEffect->Reverb.GainLF = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_EAXREVERB_DECAY_TIME: if(flValue >= AL_EAXREVERB_MIN_DECAY_TIME && flValue <= AL_EAXREVERB_MAX_DECAY_TIME) ALEffect->Reverb.DecayTime = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_EAXREVERB_DECAY_HFRATIO: if(flValue >= AL_EAXREVERB_MIN_DECAY_HFRATIO && flValue <= AL_EAXREVERB_MAX_DECAY_HFRATIO) ALEffect->Reverb.DecayHFRatio = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_EAXREVERB_DECAY_LFRATIO: if(flValue >= AL_EAXREVERB_MIN_DECAY_LFRATIO && flValue <= AL_EAXREVERB_MAX_DECAY_LFRATIO) ALEffect->Reverb.DecayLFRatio = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_EAXREVERB_REFLECTIONS_GAIN: if(flValue >= AL_EAXREVERB_MIN_REFLECTIONS_GAIN && flValue <= AL_EAXREVERB_MAX_REFLECTIONS_GAIN) ALEffect->Reverb.ReflectionsGain = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_EAXREVERB_REFLECTIONS_DELAY: if(flValue >= AL_EAXREVERB_MIN_REFLECTIONS_DELAY && flValue <= AL_EAXREVERB_MAX_REFLECTIONS_DELAY) ALEffect->Reverb.ReflectionsDelay = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_EAXREVERB_LATE_REVERB_GAIN: if(flValue >= AL_EAXREVERB_MIN_LATE_REVERB_GAIN && flValue <= AL_EAXREVERB_MAX_LATE_REVERB_GAIN) ALEffect->Reverb.LateReverbGain = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_EAXREVERB_LATE_REVERB_DELAY: if(flValue >= AL_EAXREVERB_MIN_LATE_REVERB_DELAY && flValue <= AL_EAXREVERB_MAX_LATE_REVERB_DELAY) ALEffect->Reverb.LateReverbDelay = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_EAXREVERB_AIR_ABSORPTION_GAINHF: if(flValue >= AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF && flValue <= AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF) ALEffect->Reverb.AirAbsorptionGainHF = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_EAXREVERB_ECHO_TIME: if(flValue >= AL_EAXREVERB_MIN_ECHO_TIME && flValue <= AL_EAXREVERB_MAX_ECHO_TIME) ALEffect->Reverb.EchoTime = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_EAXREVERB_ECHO_DEPTH: if(flValue >= AL_EAXREVERB_MIN_ECHO_DEPTH && flValue <= AL_EAXREVERB_MAX_ECHO_DEPTH) ALEffect->Reverb.EchoDepth = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_EAXREVERB_MODULATION_TIME: if(flValue >= AL_EAXREVERB_MIN_MODULATION_TIME && flValue <= AL_EAXREVERB_MAX_MODULATION_TIME) ALEffect->Reverb.ModulationTime = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_EAXREVERB_MODULATION_DEPTH: if(flValue >= AL_EAXREVERB_MIN_MODULATION_DEPTH && flValue <= AL_EAXREVERB_MAX_MODULATION_DEPTH) ALEffect->Reverb.ModulationDepth = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_EAXREVERB_HFREFERENCE: if(flValue >= AL_EAXREVERB_MIN_HFREFERENCE && flValue <= AL_EAXREVERB_MAX_HFREFERENCE) ALEffect->Reverb.HFReference = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_EAXREVERB_LFREFERENCE: if(flValue >= AL_EAXREVERB_MIN_LFREFERENCE && flValue <= AL_EAXREVERB_MAX_LFREFERENCE) ALEffect->Reverb.LFReference = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR: if(flValue >= 0.0f && flValue <= 10.0f) ALEffect->Reverb.RoomRolloffFactor = flValue; else alSetError(AL_INVALID_VALUE); break; default: alSetError(AL_INVALID_ENUM); break; } } else if(ALEffect->type == AL_EFFECT_REVERB) { switch(param) { case AL_REVERB_DENSITY: if(flValue >= AL_REVERB_MIN_DENSITY && flValue <= AL_REVERB_MAX_DENSITY) ALEffect->Reverb.Density = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_REVERB_DIFFUSION: if(flValue >= AL_REVERB_MIN_DIFFUSION && flValue <= AL_REVERB_MAX_DIFFUSION) ALEffect->Reverb.Diffusion = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_REVERB_GAIN: if(flValue >= AL_REVERB_MIN_GAIN && flValue <= AL_REVERB_MAX_GAIN) ALEffect->Reverb.Gain = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_REVERB_GAINHF: if(flValue >= AL_REVERB_MIN_GAINHF && flValue <= AL_REVERB_MAX_GAINHF) ALEffect->Reverb.GainHF = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_REVERB_DECAY_TIME: if(flValue >= AL_REVERB_MIN_DECAY_TIME && flValue <= AL_REVERB_MAX_DECAY_TIME) ALEffect->Reverb.DecayTime = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_REVERB_DECAY_HFRATIO: if(flValue >= AL_REVERB_MIN_DECAY_HFRATIO && flValue <= AL_REVERB_MAX_DECAY_HFRATIO) ALEffect->Reverb.DecayHFRatio = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_REVERB_REFLECTIONS_GAIN: if(flValue >= AL_REVERB_MIN_REFLECTIONS_GAIN && flValue <= AL_REVERB_MAX_REFLECTIONS_GAIN) ALEffect->Reverb.ReflectionsGain = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_REVERB_REFLECTIONS_DELAY: if(flValue >= AL_REVERB_MIN_REFLECTIONS_DELAY && flValue <= AL_REVERB_MAX_REFLECTIONS_DELAY) ALEffect->Reverb.ReflectionsDelay = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_REVERB_LATE_REVERB_GAIN: if(flValue >= AL_REVERB_MIN_LATE_REVERB_GAIN && flValue <= AL_REVERB_MAX_LATE_REVERB_GAIN) ALEffect->Reverb.LateReverbGain = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_REVERB_LATE_REVERB_DELAY: if(flValue >= AL_REVERB_MIN_LATE_REVERB_DELAY && flValue <= AL_REVERB_MAX_LATE_REVERB_DELAY) ALEffect->Reverb.LateReverbDelay = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_REVERB_AIR_ABSORPTION_GAINHF: if(flValue >= AL_REVERB_MIN_AIR_ABSORPTION_GAINHF && flValue <= AL_REVERB_MAX_AIR_ABSORPTION_GAINHF) ALEffect->Reverb.AirAbsorptionGainHF = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_REVERB_ROOM_ROLLOFF_FACTOR: if(flValue >= AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR && flValue <= AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR) ALEffect->Reverb.RoomRolloffFactor = flValue; else alSetError(AL_INVALID_VALUE); break; default: alSetError(AL_INVALID_ENUM); break; } } else if(ALEffect->type == AL_EFFECT_ECHO) { switch(param) { case AL_ECHO_DELAY: if(flValue >= AL_ECHO_MIN_DELAY && flValue <= AL_ECHO_MAX_DELAY) ALEffect->Echo.Delay = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_ECHO_LRDELAY: if(flValue >= AL_ECHO_MIN_LRDELAY && flValue <= AL_ECHO_MAX_LRDELAY) ALEffect->Echo.LRDelay = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_ECHO_DAMPING: if(flValue >= AL_ECHO_MIN_DAMPING && flValue <= AL_ECHO_MAX_DAMPING) ALEffect->Echo.Damping = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_ECHO_FEEDBACK: if(flValue >= AL_ECHO_MIN_FEEDBACK && flValue <= AL_ECHO_MAX_FEEDBACK) ALEffect->Echo.Feedback = flValue; else alSetError(AL_INVALID_VALUE); break; case AL_ECHO_SPREAD: if(flValue >= AL_ECHO_MIN_SPREAD && flValue <= AL_ECHO_MAX_SPREAD) ALEffect->Echo.Spread = flValue; else alSetError(AL_INVALID_VALUE); break; default: alSetError(AL_INVALID_ENUM); break; } } else alSetError(AL_INVALID_ENUM); } else alSetError(AL_INVALID_NAME); ProcessContext(Context); }
ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots) { ALCcontext *Context; ALeffectslot *ALAuxiliaryEffectSlot; ALsizei i; Context = GetContextSuspended(); if(!Context) return; if (n >= 0) { // Check that all effectslots are valid for (i = 0; i < n; i++) { if (!alIsAuxiliaryEffectSlot(effectslots[i])) { alSetError(AL_INVALID_NAME); break; } else { ALAuxiliaryEffectSlot = (ALeffectslot*)ALTHUNK_LOOKUPENTRY(effectslots[i]); if(ALAuxiliaryEffectSlot->refcount > 0) { alSetError(AL_INVALID_NAME); break; } } } if (i == n) { // All effectslots are valid for (i = 0; i < n; i++) { // Recheck that the effectslot is valid, because there could be duplicated names if (alIsAuxiliaryEffectSlot(effectslots[i])) { ALeffectslot **list; ALAuxiliaryEffectSlot = ((ALeffectslot*)ALTHUNK_LOOKUPENTRY(effectslots[i])); // Remove Source from list of Sources list = &Context->AuxiliaryEffectSlot; while(*list && *list != ALAuxiliaryEffectSlot) list = &(*list)->next; if(*list) *list = (*list)->next; ALTHUNK_REMOVEENTRY(ALAuxiliaryEffectSlot->effectslot); if(ALAuxiliaryEffectSlot->EffectState) ALEffect_Destroy(ALAuxiliaryEffectSlot->EffectState); memset(ALAuxiliaryEffectSlot, 0, sizeof(ALeffectslot)); free(ALAuxiliaryEffectSlot); Context->AuxiliaryEffectSlotCount--; } } } } else alSetError(AL_INVALID_VALUE); ProcessContext(Context); }
ALenum eax2BufferSet(ALuint property, ALuint source, ALvoid *pValue, ALuint size, ALint iSWMixer) { ALsource *pSource; ALboolean bSetValue = AL_FALSE; ALenum ALErrorCode = AL_NO_ERROR; pSource = (ALsource*)ALTHUNK_LOOKUPENTRY(source); if (!bEAX2Initialized) { bEAX2Initialized = AL_TRUE; } switch(property & ~DSPROPERTY_EAXBUFFER_DEFERRED) { case DSPROPERTY_EAXBUFFER_NONE: bSetValue = AL_TRUE; break; case DSPROPERTY_EAXBUFFER_ALLPARAMETERS: if ((pValue) && (size >= sizeof(EAXBUFFERPROPERTIES))) { if (memcmp((void*)(&pSource->EAX20BP), pValue, sizeof(EAXBUFFERPROPERTIES))) { if ( (LongInRange(((LPEAXBUFFERPROPERTIES)pValue)->lDirect, EAXBUFFER_MINDIRECT, EAXBUFFER_MAXDIRECT)) && (LongInRange(((LPEAXBUFFERPROPERTIES)pValue)->lDirectHF, EAXBUFFER_MINDIRECTHF, EAXBUFFER_MAXDIRECTHF)) && (LongInRange(((LPEAXBUFFERPROPERTIES)pValue)->lRoom, EAXBUFFER_MINROOM, EAXBUFFER_MAXROOM)) && (LongInRange(((LPEAXBUFFERPROPERTIES)pValue)->lRoomHF, EAXBUFFER_MINROOMHF, EAXBUFFER_MAXROOMHF)) && (LongInRange(((LPEAXBUFFERPROPERTIES)pValue)->lObstruction, EAXBUFFER_MINOBSTRUCTION, EAXBUFFER_MAXOBSTRUCTION)) && (FloatInRange(((LPEAXBUFFERPROPERTIES)pValue)->flObstructionLFRatio, EAXBUFFER_MINOBSTRUCTIONLFRATIO, EAXBUFFER_MAXOBSTRUCTIONLFRATIO)) && (LongInRange(((LPEAXBUFFERPROPERTIES)pValue)->lOcclusion, EAXBUFFER_MINOCCLUSION, EAXBUFFER_MAXOCCLUSION)) && (FloatInRange(((LPEAXBUFFERPROPERTIES)pValue)->flOcclusionLFRatio, EAXBUFFER_MINOCCLUSIONLFRATIO, EAXBUFFER_MAXOCCLUSIONLFRATIO)) && (FloatInRange(((LPEAXBUFFERPROPERTIES)pValue)->flOcclusionRoomRatio, EAXBUFFER_MINOCCLUSIONROOMRATIO, EAXBUFFER_MAXOCCLUSIONROOMRATIO)) && (LongInRange(((LPEAXBUFFERPROPERTIES)pValue)->lOutsideVolumeHF, EAXBUFFER_MINOUTSIDEVOLUMEHF, EAXBUFFER_MAXOUTSIDEVOLUMEHF)) && (FloatInRange(((LPEAXBUFFERPROPERTIES)pValue)->flRoomRolloffFactor, EAXBUFFER_MINROOMROLLOFFFACTOR, EAXBUFFER_MAXROOMROLLOFFFACTOR)) && (FloatInRange(((LPEAXBUFFERPROPERTIES)pValue)->flAirAbsorptionFactor, EAXBUFFER_MINAIRABSORPTIONFACTOR, EAXBUFFER_MAXAIRABSORPTIONFACTOR)) && (ULongInRange(((LPEAXBUFFERPROPERTIES)pValue)->dwFlags, 0, ~EAXBUFFERFLAGS_RESERVED)) ) { memcpy((void*)(&pSource->EAX20BP), pValue, sizeof(EAXBUFFERPROPERTIES)); bSetValue = AL_TRUE; } else { ALErrorCode = AL_INVALID_OPERATION; } } } else { ALErrorCode = AL_INVALID_OPERATION; } break; case DSPROPERTY_EAXBUFFER_DIRECT: if ((pValue) && (size >= sizeof(long)) && (LongInRange(*((long*)pValue), EAXBUFFER_MINDIRECT, EAXBUFFER_MAXDIRECT))) { bSetValue = (pSource->EAX20BP.lDirect != (*(long*)pValue)); pSource->EAX20BP.lDirect = (*(long*)pValue); } else { ALErrorCode = AL_INVALID_OPERATION; } break; case DSPROPERTY_EAXBUFFER_DIRECTHF: if ((pValue) && (size >= sizeof(long)) && (LongInRange(*((long *)pValue), EAXBUFFER_MINDIRECTHF, EAXBUFFER_MAXDIRECTHF))) { bSetValue = (pSource->EAX20BP.lDirectHF != (*(long*)pValue)); pSource->EAX20BP.lDirectHF = (*(long*)pValue); } else { ALErrorCode = AL_INVALID_OPERATION; } break; case DSPROPERTY_EAXBUFFER_ROOM: if ((pValue) && (size >= sizeof(long)) && (LongInRange(*((long *)pValue), EAXBUFFER_MINROOM, EAXBUFFER_MAXROOM))) { bSetValue = (pSource->EAX20BP.lRoom != (*(long*)pValue)); pSource->EAX20BP.lRoom = (*(long*)pValue); } else { ALErrorCode = AL_INVALID_OPERATION; } break; case DSPROPERTY_EAXBUFFER_ROOMHF: if ((pValue) && (size >= sizeof(long)) && (LongInRange(*((long *)pValue), EAXBUFFER_MINROOMHF, EAXBUFFER_MAXROOMHF))) { bSetValue = (pSource->EAX20BP.lRoomHF != (*(long*)pValue)); pSource->EAX20BP.lRoomHF = (*(long*)pValue); } else { ALErrorCode = AL_INVALID_OPERATION; } break; case DSPROPERTY_EAXBUFFER_OBSTRUCTION: if ((pValue) && (size >= sizeof(long)) && (LongInRange(*((long *)pValue), EAXBUFFER_MINOBSTRUCTION, EAXBUFFER_MAXOBSTRUCTION))) { bSetValue = (pSource->EAX20BP.lObstruction != (*(long*)pValue)); pSource->EAX20BP.lObstruction = (*(long*)pValue); } else { ALErrorCode = AL_INVALID_OPERATION; } break; case DSPROPERTY_EAXBUFFER_OBSTRUCTIONLFRATIO: if ((pValue) && (size >= sizeof(float)) && (FloatInRange(*((float *)pValue), EAXBUFFER_MINOBSTRUCTIONLFRATIO, EAXBUFFER_MAXOBSTRUCTIONLFRATIO))) { bSetValue = (pSource->EAX20BP.flObstructionLFRatio != (*(float*)pValue)); pSource->EAX20BP.flObstructionLFRatio = (*(float*)pValue); } else { ALErrorCode = AL_INVALID_OPERATION; } break; case DSPROPERTY_EAXBUFFER_OCCLUSION: if ((pValue) && (size >= sizeof(long)) && (LongInRange(*((long *)pValue), EAXBUFFER_MINOCCLUSION, EAXBUFFER_MAXOCCLUSION))) { bSetValue = (pSource->EAX20BP.lOcclusion != (*(long*)pValue)); pSource->EAX20BP.lOcclusion = (*(long*)pValue); } else { ALErrorCode = AL_INVALID_OPERATION; } break; case DSPROPERTY_EAXBUFFER_OCCLUSIONLFRATIO: if ((pValue) && (size >= sizeof(float)) && (FloatInRange(*((float *)pValue), EAXBUFFER_MINOCCLUSIONLFRATIO, EAXBUFFER_MAXOCCLUSIONLFRATIO))) { bSetValue = (pSource->EAX20BP.flOcclusionLFRatio != (*(float*)pValue)); pSource->EAX20BP.flOcclusionLFRatio = (*(float*)pValue); } else { ALErrorCode = AL_INVALID_OPERATION; } break; case DSPROPERTY_EAXBUFFER_OCCLUSIONROOMRATIO: if ((pValue) && (size >= sizeof(float)) && (FloatInRange(*((float *)pValue), EAXBUFFER_MINOCCLUSIONROOMRATIO, EAXBUFFER_MAXOCCLUSIONROOMRATIO))) { bSetValue = (pSource->EAX20BP.flOcclusionRoomRatio != (*(float*)pValue)); pSource->EAX20BP.flOcclusionRoomRatio = (*(float*)pValue); } else { ALErrorCode = AL_INVALID_OPERATION; } break; case DSPROPERTY_EAXBUFFER_OUTSIDEVOLUMEHF: if ((pValue) && (size >= sizeof(long)) && (LongInRange(*((long *)pValue), EAXBUFFER_MINOUTSIDEVOLUMEHF, EAXBUFFER_MAXOUTSIDEVOLUMEHF))) { bSetValue = (pSource->EAX20BP.lOutsideVolumeHF != (*(long*)pValue)); pSource->EAX20BP.lOutsideVolumeHF = (*(long*)pValue); } else { ALErrorCode = AL_INVALID_OPERATION; } break; case DSPROPERTY_EAXBUFFER_ROOMROLLOFFFACTOR: if ((pValue) && (size >= sizeof(float)) && (FloatInRange(*((float *)pValue), EAXBUFFER_MINROOMROLLOFFFACTOR, EAXBUFFER_MAXROOMROLLOFFFACTOR))) { bSetValue = (pSource->EAX20BP.flRoomRolloffFactor != (*(float*)pValue)); pSource->EAX20BP.flRoomRolloffFactor = (*(float*)pValue); } else { ALErrorCode = AL_INVALID_OPERATION; } break; case DSPROPERTY_EAXBUFFER_AIRABSORPTIONFACTOR: if ((pValue) && (size >= sizeof(float)) && (FloatInRange(*((float *)pValue), EAXBUFFER_MINAIRABSORPTIONFACTOR, EAXBUFFER_MAXAIRABSORPTIONFACTOR))) { bSetValue = (pSource->EAX20BP.flAirAbsorptionFactor != (*(float*)pValue)); pSource->EAX20BP.flAirAbsorptionFactor = (*(float*)pValue); } else { ALErrorCode = AL_INVALID_OPERATION; } break; case DSPROPERTY_EAXBUFFER_FLAGS: if ((pValue) && (size >= sizeof(unsigned long)) && (ULongInRange(*((unsigned long *)pValue), 0, ~EAXBUFFERFLAGS_RESERVED))) { bSetValue = (pSource->EAX20BP.dwFlags != (*(unsigned long*)pValue)); pSource->EAX20BP.dwFlags = (*(unsigned long*)pValue); } else { ALErrorCode = AL_INVALID_OPERATION; } break; default: ALErrorCode = AL_INVALID_OPERATION; } if (bSetValue) { if (pSource->uservalue3) { if (FAILED(IKsPropertySet_Set((LPKSPROPERTYSET)pSource->uservalue3, &DSPROPSETID_EAX20_BufferProperties, property, NULL, 0, pValue, size))) ALErrorCode = AL_INVALID_OPERATION; } } return ALErrorCode; }