diff options
Diffstat (limited to 'OpenAL32/alBuffer.c')
-rw-r--r-- | OpenAL32/alBuffer.c | 989 |
1 files changed, 989 insertions, 0 deletions
diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c new file mode 100644 index 00000000..53ee128a --- /dev/null +++ b/OpenAL32/alBuffer.c @@ -0,0 +1,989 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2007 by authors. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#define _CRT_SECURE_NO_DEPRECATE // get rid of sprintf security warnings on VS2005 + +#include <stdlib.h> +#include <stdio.h> +#include "alMain.h" +#include "AL/al.h" +#include "AL/alc.h" +#include "alError.h" +#include "alBuffer.h" + +#ifdef _DEBUG + char szDebug[256]; +#endif + +/* + * AL Buffer Functions + * + * AL Buffers are shared amoung Contexts, so we store the list of generated Buffers + * as a global variable in this module. (A valid context is not required to make + * AL Buffer function calls + * + */ + +/* +* Global Variables +*/ + +static ALbuffer *g_pBuffers = NULL; // Linked List of Buffers +static ALuint g_uiBufferCount = 0; // Buffer Count + +static const long g_IMAStep_size[89]={ // IMA ADPCM Stepsize table + 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, + 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, + 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, + 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, + 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493,10442,11487,12635,13899, + 15289,16818,18500,20350,22358,24633,27086,29794,32767 +}; + +static const long g_IMACodeword_4[16]={ // IMA4 ADPCM Codeword decode table + 1, 3, 5, 7, 9, 11, 13, 15, + -1,-3,-5,-7,-9,-11,-13,-15, +}; + +static const long g_IMAIndex_adjust_4[16]={ // IMA4 ADPCM Step index adjust decode table + -1,-1,-1,-1, 2, 4, 6, 8, + -1,-1,-1,-1, 2, 4, 6, 8 +}; + +/* +* alGenBuffers(ALsizei n, ALuint *puiBuffers) +* +* Generates n AL Buffers, and stores the Buffers Names in the array pointed to by puiBuffers +*/ +ALAPI ALvoid ALAPIENTRY alGenBuffers(ALsizei n,ALuint *puiBuffers) +{ + ALCcontext *Context; + ALsizei i=0; + + Context = alcGetCurrentContext(); + SuspendContext(Context); + + // Check that we are actually generation some Buffers + if (n > 0) + { + // Check the pointer is valid (and points to enough memory to store Buffer Names) + if (!IsBadWritePtr((void*)puiBuffers, n * sizeof(ALuint))) + { + ALbuffer **list = &g_pBuffers; + while(*list) + list = &(*list)->next; + + // Create all the new Buffers + while(i < n) + { + *list = calloc(1, sizeof(ALbuffer)); + if(*list) + { + puiBuffers[i] = (ALuint)ALTHUNK_ADDENTRY(*list); + (*list)->state = UNUSED; + g_uiBufferCount++; + i++; + + list = &(*list)->next; + } + } + + // If we didn't create all the Buffers, we must have run out of memory + if (i != n) + alSetError(AL_OUT_OF_MEMORY); + } + else + { + // Pointer does not point to enough memory to write Buffer names + alSetError(AL_INVALID_VALUE); + } + } + + ProcessContext(Context); + + return; +} + +/* +* 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) + { + if ((ALuint)n <= g_uiBufferCount) + { + // 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++) + { + ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i])); + if (ALBuf) + { + ALbuffer **list = &g_pBuffers; + 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_NAME); + } + else + alSetError(AL_INVALID_VALUE); + + ProcessContext(Context); + + return; + +} + +/* +* 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; +} + +/* +* 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: + if ((size%1) == 0) + { + // 8bit Samples are converted to 16 bit here + // Allocate 8 extra samples (16 bytes) + ALBuf->data=realloc(ALBuf->data,16+(size/sizeof(ALubyte))*(1*sizeof(ALshort))); + if (ALBuf->data) + { + ALBuf->format = AL_FORMAT_MONO16; + ALBuf->eOriginalFormat = AL_FORMAT_MONO8; + for (i=0;i<(ALsizei)(size/sizeof(ALubyte));i++) + ALBuf->data[i]=(ALshort)((((ALubyte *)data)[i]-128)<<8); + memset(&(ALBuf->data[size/sizeof(ALubyte)]), 0, 16); + ALBuf->size=size/sizeof(ALubyte)*1*sizeof(ALshort); + ALBuf->frequency=freq; + } + else + alSetError(AL_OUT_OF_MEMORY); + } + else + alSetError(AL_INVALID_VALUE); + break; + + case AL_FORMAT_MONO16: + if ((size%2) == 0) + { + // Allocate 8 extra samples (16 bytes) + ALBuf->data=realloc(ALBuf->data,16+(size/sizeof(ALshort))*(1*sizeof(ALshort))); + if (ALBuf->data) + { + ALBuf->format = AL_FORMAT_MONO16; + ALBuf->eOriginalFormat = AL_FORMAT_MONO16; + memcpy(ALBuf->data,data,size/sizeof(ALshort)*1*sizeof(ALshort)); + memset(&(ALBuf->data[size/sizeof(ALshort)]), 0, 16); + ALBuf->size=size/sizeof(ALshort)*1*sizeof(ALshort); + ALBuf->frequency=freq; + } + else + alSetError(AL_OUT_OF_MEMORY); + } + else + alSetError(AL_INVALID_VALUE); + break; + + case AL_FORMAT_STEREO8: + if ((size%2) == 0) + { + // 8bit Samples are converted to 16 bit here + // Allocate 8 extra samples (32 bytes) + ALBuf->data=realloc(ALBuf->data,32+(size/sizeof(ALubyte))*(1*sizeof(ALshort))); + if (ALBuf->data) + { + ALBuf->format = AL_FORMAT_STEREO16; + ALBuf->eOriginalFormat = AL_FORMAT_STEREO8; + for (i=0;i<(ALsizei)(size/sizeof(ALubyte));i++) + ALBuf->data[i]=(ALshort)((((ALubyte *)data)[i]-128)<<8); + memset(&(ALBuf->data[size/sizeof(ALubyte)]), 0, 32); + ALBuf->size=size/sizeof(ALubyte)*1*sizeof(ALshort); + ALBuf->frequency=freq; + } + else + alSetError(AL_OUT_OF_MEMORY); + } + else + alSetError(AL_INVALID_VALUE); + break; + + case AL_FORMAT_STEREO16: + if ((size%4) == 0) + { + // Allocate 8 extra samples (32 bytes) + ALBuf->data=realloc(ALBuf->data,32+(size/sizeof(ALshort))*(1*sizeof(ALshort))); + if (ALBuf->data) + { + ALBuf->format = AL_FORMAT_STEREO16; + ALBuf->eOriginalFormat = AL_FORMAT_STEREO16; + memcpy(ALBuf->data,data,size/sizeof(ALshort)*1*sizeof(ALshort)); + memset(&(ALBuf->data[size/sizeof(ALshort)]), 0, 32); + ALBuf->size=size/sizeof(ALshort)*1*sizeof(ALshort); + ALBuf->frequency=freq; + } + else + alSetError(AL_OUT_OF_MEMORY); + } + else + alSetError(AL_INVALID_VALUE); + 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); + } + else + alSetError(AL_INVALID_VALUE); + break; + + case AL_FORMAT_STEREO_IMA4: + // Here is where things vary: + // nVidia and Apple use 64+1 samples per channel per block => block_size=72 bytes + // Most PC sound software uses 2040+1 samples per channel per block -> block_size=2048 bytes + if ((size%72) == 0) + { + // Allocate 8 extra samples (32 bytes) + ALBuf->data=realloc(ALBuf->data,32+(size/72)*(2*65*sizeof(ALshort))); + if (ALBuf->data) + { + ALBuf->format = AL_FORMAT_STEREO16; + ALBuf->eOriginalFormat = AL_FORMAT_STEREO_IMA4; + IMAData=(ALuint *)data; + for (i=0;i<size/72;i++) + { + LeftSample=((ALshort *)IMAData)[0]; + LeftIndex=((ALshort *)IMAData)[1]; + + LeftIndex=LeftIndex<0?0:LeftIndex; + LeftIndex=LeftIndex>88?88:LeftIndex; + + ALBuf->data[i*2*65]=(short)LeftSample; + + IMAData++; + + RightSample=((ALshort *)IMAData)[0]; + RightIndex=((ALshort *)IMAData)[1]; + + RightIndex=RightIndex<0?0:RightIndex; + RightIndex=RightIndex>88?88:RightIndex; + + ALBuf->data[i*2*65+1]=(short)RightSample; + + IMAData++; + + for (j=2;j<130;j+=16) + { + LeftIMACode=IMAData[0]; + RightIMACode=IMAData[1]; + for (k=0;k<16;k+=4) + { + LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8); + LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15]; + if (LeftSample<-32768) LeftSample=-32768; + else if (LeftSample>32767) LeftSample=32767; + if (LeftIndex<0) LeftIndex=0; + else if (LeftIndex>88) LeftIndex=88; + ALBuf->data[i*2*65+j+k]=(short)LeftSample; + LeftIMACode>>=4; + + RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8); + RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15]; + if (RightSample<-32768) RightSample=-32768; + else if (RightSample>32767) RightSample=32767; + if (RightIndex<0) RightIndex=0; + else if (RightIndex>88) RightIndex=88; + ALBuf->data[i*2*65+j+k+1]=(short)RightSample; + RightIMACode>>=4; + + LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8); + LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15]; + if (LeftSample<-32768) LeftSample=-32768; + else if (LeftSample>32767) LeftSample=32767; + if (LeftIndex<0) LeftIndex=0; + else if (LeftIndex>88) LeftIndex=88; + ALBuf->data[i*2*65+j+k+2]=(short)LeftSample; + LeftIMACode>>=4; + + RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8); + RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15]; + if (RightSample<-32768) RightSample=-32768; + else if (RightSample>32767) RightSample=32767; + if (RightIndex<0) RightIndex=0; + else if (RightIndex>88) RightIndex=88; + ALBuf->data[i*2*65+j+k+3]=(short)RightSample; + RightIMACode>>=4; + } + IMAData+=2; + } + } + memset(&(ALBuf->data[(size/72*2*65)]), 0, 32); + ALBuf->size=size/72*2*65*sizeof(ALshort); + ALBuf->frequency=freq; + } + else + alSetError(AL_OUT_OF_MEMORY); + } + else + alSetError(AL_INVALID_VALUE); + 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); +} + + +ALAPI void ALAPIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue) +{ + ALCcontext *pContext; + ALbuffer *pBuffer; + + (void)flValue; + + pContext = alcGetCurrentContext(); + SuspendContext(pContext); + + if (alIsBuffer(buffer) && (buffer != 0)) + { + pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer)); + + switch(eParam) + { + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + { + alSetError(AL_INVALID_NAME); + } + + ProcessContext(pContext); +} + + +ALAPI void ALAPIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3) +{ + ALCcontext *pContext; + ALbuffer *pBuffer; + + (void)flValue1; + (void)flValue2; + (void)flValue3; + + pContext = alcGetCurrentContext(); + SuspendContext(pContext); + + if (alIsBuffer(buffer) && (buffer != 0)) + { + pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer)); + + switch(eParam) + { + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + { + alSetError(AL_INVALID_NAME); + } + + ProcessContext(pContext); +} + + +ALAPI void ALAPIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues) +{ + ALCcontext *pContext; + ALbuffer *pBuffer; + + (void)flValues; + + pContext = alcGetCurrentContext(); + SuspendContext(pContext); + + if (alIsBuffer(buffer) && (buffer != 0)) + { + pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer)); + + switch(eParam) + { + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + { + alSetError(AL_INVALID_NAME); + } + + ProcessContext(pContext); +} + + +ALAPI void ALAPIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue) +{ + ALCcontext *pContext; + ALbuffer *pBuffer; + + (void)lValue; + + pContext = alcGetCurrentContext(); + SuspendContext(pContext); + + if (alIsBuffer(buffer) && (buffer != 0)) + { + pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer)); + + switch(eParam) + { + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + { + alSetError(AL_INVALID_NAME); + } + + ProcessContext(pContext); +} + + +ALAPI void ALAPIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3) +{ + ALCcontext *pContext; + ALbuffer *pBuffer; + + (void)lValue1; + (void)lValue2; + (void)lValue3; + + pContext = alcGetCurrentContext(); + SuspendContext(pContext); + + if (alIsBuffer(buffer) && (buffer != 0)) + { + pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer)); + + switch(eParam) + { + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + { + alSetError(AL_INVALID_NAME); + } + + ProcessContext(pContext); +} + + +ALAPI void ALAPIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues) +{ + ALCcontext *pContext; + ALbuffer *pBuffer; + + (void)plValues; + + pContext = alcGetCurrentContext(); + SuspendContext(pContext); + + if (alIsBuffer(buffer) && (buffer != 0)) + { + pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer)); + + switch(eParam) + { + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + { + alSetError(AL_INVALID_NAME); + } + + ProcessContext(pContext); +} + + +ALAPI ALvoid ALAPIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue) +{ + ALCcontext *pContext; + ALbuffer *pBuffer; + + pContext = alcGetCurrentContext(); + SuspendContext(pContext); + + if (pflValue) + { + if (alIsBuffer(buffer) && (buffer != 0)) + { + pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer)); + + switch(eParam) + { + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + { + alSetError(AL_INVALID_NAME); + } + } + else + { + alSetError(AL_INVALID_VALUE); + } + + ProcessContext(pContext); +} + + +ALAPI void ALAPIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3) +{ + ALCcontext *pContext; + ALbuffer *pBuffer; + + pContext = alcGetCurrentContext(); + SuspendContext(pContext); + + if ((pflValue1) && (pflValue2) && (pflValue3)) + { + if (alIsBuffer(buffer) && (buffer != 0)) + { + pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer)); + + switch(eParam) + { + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + { + alSetError(AL_INVALID_NAME); + } + } + else + { + alSetError(AL_INVALID_VALUE); + } + + ProcessContext(pContext); +} + + +ALAPI void ALAPIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues) +{ + ALCcontext *pContext; + ALbuffer *pBuffer; + + pContext = alcGetCurrentContext(); + SuspendContext(pContext); + + if (pflValues) + { + if (alIsBuffer(buffer) && (buffer != 0)) + { + pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer)); + + switch(eParam) + { + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + { + alSetError(AL_INVALID_NAME); + } + } + else + { + alSetError(AL_INVALID_VALUE); + } + + ProcessContext(pContext); +} + + +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= (((pBuffer->format==AL_FORMAT_MONO8)||(pBuffer->format==AL_FORMAT_STEREO8))?8:16); + break; + + case AL_CHANNELS: + *plValue = (((pBuffer->format==AL_FORMAT_MONO8)||(pBuffer->format==AL_FORMAT_MONO16))?1:2); + 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); +} + + +ALAPI void ALAPIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3) +{ + ALCcontext *pContext; + ALbuffer *pBuffer; + + pContext = alcGetCurrentContext(); + SuspendContext(pContext); + + if ((plValue1) && (plValue2) && (plValue3)) + { + if (alIsBuffer(buffer) && (buffer != 0)) + { + pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer)); + + switch(eParam) + { + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + { + alSetError(AL_INVALID_NAME); + } + } + else + { + alSetError(AL_INVALID_VALUE); + } + + ProcessContext(pContext); +} + + +ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues) +{ + ALCcontext *pContext; + ALbuffer *pBuffer; + + pContext = alcGetCurrentContext(); + SuspendContext(pContext); + + if (plValues) + { + if (alIsBuffer(buffer) && (buffer != 0)) + { + pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer)); + + switch (eParam) + { + case AL_FREQUENCY: + case AL_BITS: + case AL_CHANNELS: + case AL_SIZE: + alGetBufferi(buffer, eParam, plValues); + break; + + default: + alSetError(AL_INVALID_ENUM); + break; + } + } + else + { + alSetError(AL_INVALID_NAME); + } + } + else + { + alSetError(AL_INVALID_VALUE); + } + + ProcessContext(pContext); +} + + +/* +* ReleaseALBuffers() +* +* INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist +*/ +ALvoid ReleaseALBuffers(ALvoid) +{ + ALbuffer *ALBuffer; + ALbuffer *ALBufferTemp; + +#ifdef _DEBUG + if(g_uiBufferCount > 0) + { + sprintf(szDebug, "OpenAL32 : DllMain() %d Buffer(s) NOT deleted\n", g_uiBufferCount); + OutputDebugString(szDebug); + } +#endif + + ALBuffer = g_pBuffers; + while(ALBuffer) + { + // Release sample data + free(ALBuffer->data); + + // Release Buffer structure + ALBufferTemp = ALBuffer; + ALBuffer = ALBuffer->next; + memset(ALBufferTemp, 0, sizeof(ALbuffer)); + free(ALBufferTemp); + } + g_pBuffers = NULL; + g_uiBufferCount = 0; +} |