Check for GCC's destructor attribute before using it
[openal-soft.git] / OpenAL32 / alBuffer.c
blob53ee128a669cf175f9d8e3ba7ba271672e2b0c86
1 /**
2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2007 by authors.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
21 #define _CRT_SECURE_NO_DEPRECATE // get rid of sprintf security warnings on VS2005
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include "alMain.h"
26 #include "AL/al.h"
27 #include "AL/alc.h"
28 #include "alError.h"
29 #include "alBuffer.h"
31 #ifdef _DEBUG
32 char szDebug[256];
33 #endif
36 * AL Buffer Functions
38 * AL Buffers are shared amoung Contexts, so we store the list of generated Buffers
39 * as a global variable in this module. (A valid context is not required to make
40 * AL Buffer function calls
45 * Global Variables
48 static ALbuffer *g_pBuffers = NULL; // Linked List of Buffers
49 static ALuint g_uiBufferCount = 0; // Buffer Count
51 static const long g_IMAStep_size[89]={ // IMA ADPCM Stepsize table
52 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
53 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
54 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
55 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
56 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493,10442,11487,12635,13899,
57 15289,16818,18500,20350,22358,24633,27086,29794,32767
60 static const long g_IMACodeword_4[16]={ // IMA4 ADPCM Codeword decode table
61 1, 3, 5, 7, 9, 11, 13, 15,
62 -1,-3,-5,-7,-9,-11,-13,-15,
65 static const long g_IMAIndex_adjust_4[16]={ // IMA4 ADPCM Step index adjust decode table
66 -1,-1,-1,-1, 2, 4, 6, 8,
67 -1,-1,-1,-1, 2, 4, 6, 8
71 * alGenBuffers(ALsizei n, ALuint *puiBuffers)
73 * Generates n AL Buffers, and stores the Buffers Names in the array pointed to by puiBuffers
75 ALAPI ALvoid ALAPIENTRY alGenBuffers(ALsizei n,ALuint *puiBuffers)
77 ALCcontext *Context;
78 ALsizei i=0;
80 Context = alcGetCurrentContext();
81 SuspendContext(Context);
83 // Check that we are actually generation some Buffers
84 if (n > 0)
86 // Check the pointer is valid (and points to enough memory to store Buffer Names)
87 if (!IsBadWritePtr((void*)puiBuffers, n * sizeof(ALuint)))
89 ALbuffer **list = &g_pBuffers;
90 while(*list)
91 list = &(*list)->next;
93 // Create all the new Buffers
94 while(i < n)
96 *list = calloc(1, sizeof(ALbuffer));
97 if(*list)
99 puiBuffers[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
100 (*list)->state = UNUSED;
101 g_uiBufferCount++;
102 i++;
104 list = &(*list)->next;
108 // If we didn't create all the Buffers, we must have run out of memory
109 if (i != n)
110 alSetError(AL_OUT_OF_MEMORY);
112 else
114 // Pointer does not point to enough memory to write Buffer names
115 alSetError(AL_INVALID_VALUE);
119 ProcessContext(Context);
121 return;
125 * alDeleteBuffers(ALsizei n, ALuint *puiBuffers)
127 * Deletes the n AL Buffers pointed to by puiBuffers
129 ALAPI ALvoid ALAPIENTRY alDeleteBuffers(ALsizei n, const ALuint *puiBuffers)
131 ALCcontext *Context;
132 ALbuffer *ALBuf;
133 ALsizei i;
134 ALboolean bFailed = AL_FALSE;
136 Context = alcGetCurrentContext();
137 SuspendContext(Context);
139 // Check we are actually Deleting some Buffers
140 if (n >= 0)
142 if ((ALuint)n <= g_uiBufferCount)
144 // Check that all the buffers are valid and can actually be deleted
145 for (i = 0; i < n; i++)
147 // Check for valid Buffer ID (can be NULL buffer)
148 if (alIsBuffer(puiBuffers[i]))
150 // If not the NULL buffer, check that the reference count is 0
151 ALBuf = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
152 if (ALBuf)
154 if (ALBuf->refcount != 0)
156 // Buffer still in use, cannot be deleted
157 alSetError(AL_INVALID_OPERATION);
158 bFailed = AL_TRUE;
162 else
164 // Invalid Buffer
165 alSetError(AL_INVALID_NAME);
166 bFailed = AL_TRUE;
170 // If all the Buffers were valid (and have Reference Counts of 0), then we can delete them
171 if (!bFailed)
173 for (i = 0; i < n; i++)
175 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
176 if (ALBuf)
178 ALbuffer **list = &g_pBuffers;
179 while(*list && *list != ALBuf)
180 list = &(*list)->next;
182 if(*list)
183 *list = (*list)->next;
185 // Release the memory used to store audio data
186 free(ALBuf->data);
188 // Release buffer structure
189 ALTHUNK_REMOVEENTRY(puiBuffers[i]);
190 memset(ALBuf, 0, sizeof(ALbuffer));
191 g_uiBufferCount--;
192 free(ALBuf);
197 else
198 alSetError(AL_INVALID_NAME);
200 else
201 alSetError(AL_INVALID_VALUE);
203 ProcessContext(Context);
205 return;
210 * alIsBuffer(ALuint uiBuffer)
212 * Checks if ulBuffer is a valid Buffer Name
214 ALAPI ALboolean ALAPIENTRY alIsBuffer(ALuint uiBuffer)
216 ALCcontext *Context;
217 ALboolean result=AL_FALSE;
218 ALbuffer *ALBuf;
219 ALbuffer *TgtALBuf;
221 Context = alcGetCurrentContext();
222 SuspendContext(Context);
224 if (uiBuffer)
226 TgtALBuf = (ALbuffer *)ALTHUNK_LOOKUPENTRY(uiBuffer);
228 // Check through list of generated buffers for uiBuffer
229 ALBuf = g_pBuffers;
230 while (ALBuf)
232 if (ALBuf == TgtALBuf)
234 result = AL_TRUE;
235 break;
238 ALBuf = ALBuf->next;
241 else
243 result = AL_TRUE;
247 ProcessContext(Context);
249 return result;
253 * alBufferData(ALuint buffer,ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
255 * Fill buffer with audio data
257 ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq)
259 ALuint *IMAData,IMACode;
260 ALCcontext *Context;
261 ALint Sample,Index;
262 ALint LeftSample,LeftIndex;
263 ALint RightSample,RightIndex;
264 ALuint LeftIMACode,RightIMACode;
265 ALbuffer *ALBuf;
266 ALsizei i,j,k;
268 Context = alcGetCurrentContext();
269 SuspendContext(Context);
271 if (alIsBuffer(buffer) && (buffer != 0))
273 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
274 if ((ALBuf->refcount==0)&&(data))
276 switch(format)
278 case AL_FORMAT_MONO8:
279 if ((size%1) == 0)
281 // 8bit Samples are converted to 16 bit here
282 // Allocate 8 extra samples (16 bytes)
283 ALBuf->data=realloc(ALBuf->data,16+(size/sizeof(ALubyte))*(1*sizeof(ALshort)));
284 if (ALBuf->data)
286 ALBuf->format = AL_FORMAT_MONO16;
287 ALBuf->eOriginalFormat = AL_FORMAT_MONO8;
288 for (i=0;i<(ALsizei)(size/sizeof(ALubyte));i++)
289 ALBuf->data[i]=(ALshort)((((ALubyte *)data)[i]-128)<<8);
290 memset(&(ALBuf->data[size/sizeof(ALubyte)]), 0, 16);
291 ALBuf->size=size/sizeof(ALubyte)*1*sizeof(ALshort);
292 ALBuf->frequency=freq;
294 else
295 alSetError(AL_OUT_OF_MEMORY);
297 else
298 alSetError(AL_INVALID_VALUE);
299 break;
301 case AL_FORMAT_MONO16:
302 if ((size%2) == 0)
304 // Allocate 8 extra samples (16 bytes)
305 ALBuf->data=realloc(ALBuf->data,16+(size/sizeof(ALshort))*(1*sizeof(ALshort)));
306 if (ALBuf->data)
308 ALBuf->format = AL_FORMAT_MONO16;
309 ALBuf->eOriginalFormat = AL_FORMAT_MONO16;
310 memcpy(ALBuf->data,data,size/sizeof(ALshort)*1*sizeof(ALshort));
311 memset(&(ALBuf->data[size/sizeof(ALshort)]), 0, 16);
312 ALBuf->size=size/sizeof(ALshort)*1*sizeof(ALshort);
313 ALBuf->frequency=freq;
315 else
316 alSetError(AL_OUT_OF_MEMORY);
318 else
319 alSetError(AL_INVALID_VALUE);
320 break;
322 case AL_FORMAT_STEREO8:
323 if ((size%2) == 0)
325 // 8bit Samples are converted to 16 bit here
326 // Allocate 8 extra samples (32 bytes)
327 ALBuf->data=realloc(ALBuf->data,32+(size/sizeof(ALubyte))*(1*sizeof(ALshort)));
328 if (ALBuf->data)
330 ALBuf->format = AL_FORMAT_STEREO16;
331 ALBuf->eOriginalFormat = AL_FORMAT_STEREO8;
332 for (i=0;i<(ALsizei)(size/sizeof(ALubyte));i++)
333 ALBuf->data[i]=(ALshort)((((ALubyte *)data)[i]-128)<<8);
334 memset(&(ALBuf->data[size/sizeof(ALubyte)]), 0, 32);
335 ALBuf->size=size/sizeof(ALubyte)*1*sizeof(ALshort);
336 ALBuf->frequency=freq;
338 else
339 alSetError(AL_OUT_OF_MEMORY);
341 else
342 alSetError(AL_INVALID_VALUE);
343 break;
345 case AL_FORMAT_STEREO16:
346 if ((size%4) == 0)
348 // Allocate 8 extra samples (32 bytes)
349 ALBuf->data=realloc(ALBuf->data,32+(size/sizeof(ALshort))*(1*sizeof(ALshort)));
350 if (ALBuf->data)
352 ALBuf->format = AL_FORMAT_STEREO16;
353 ALBuf->eOriginalFormat = AL_FORMAT_STEREO16;
354 memcpy(ALBuf->data,data,size/sizeof(ALshort)*1*sizeof(ALshort));
355 memset(&(ALBuf->data[size/sizeof(ALshort)]), 0, 32);
356 ALBuf->size=size/sizeof(ALshort)*1*sizeof(ALshort);
357 ALBuf->frequency=freq;
359 else
360 alSetError(AL_OUT_OF_MEMORY);
362 else
363 alSetError(AL_INVALID_VALUE);
364 break;
366 case AL_FORMAT_MONO_IMA4:
367 // Here is where things vary:
368 // nVidia and Apple use 64+1 samples per block => block_size=36 bytes
369 // Most PC sound software uses 2040+1 samples per block -> block_size=1024 bytes
370 if ((size%36) == 0)
372 // Allocate 8 extra samples (16 bytes)
373 ALBuf->data=realloc(ALBuf->data,16+(size/36)*(65*sizeof(ALshort)));
374 if (ALBuf->data)
376 ALBuf->format = AL_FORMAT_MONO16;
377 ALBuf->eOriginalFormat = AL_FORMAT_MONO_IMA4;
378 IMAData=(ALuint *)data;
379 for (i=0;i<size/36;i++)
381 Sample=((ALshort *)IMAData)[0];
382 Index=((ALshort *)IMAData)[1];
384 Index=Index<0?0:Index;
385 Index=Index>88?88:Index;
387 ALBuf->data[i*65]=(short)Sample;
389 IMAData++;
391 for (j=1;j<65;j+=8)
393 IMACode=*IMAData;
394 for (k=0;k<8;k+=2)
396 Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8);
397 Index+=g_IMAIndex_adjust_4[IMACode&15];
398 if (Sample<-32768) Sample=-32768;
399 else if (Sample>32767) Sample=32767;
400 if (Index<0) Index=0;
401 else if (Index>88) Index=88;
402 ALBuf->data[i*65+j+k]=(short)Sample;
403 IMACode>>=4;
405 Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8);
406 Index+=g_IMAIndex_adjust_4[IMACode&15];
407 if (Sample<-32768) Sample=-32768;
408 else if (Sample>32767) Sample=32767;
409 if (Index<0) Index=0;
410 else if (Index>88) Index=88;
411 ALBuf->data[i*65+j+k+1]=(short)Sample;
412 IMACode>>=4;
414 IMAData++;
417 memset(&(ALBuf->data[(size/36*65)]), 0, 16);
418 ALBuf->size=size/36*65*sizeof(ALshort);
419 ALBuf->frequency=freq;
421 else
422 alSetError(AL_OUT_OF_MEMORY);
424 else
425 alSetError(AL_INVALID_VALUE);
426 break;
428 case AL_FORMAT_STEREO_IMA4:
429 // Here is where things vary:
430 // nVidia and Apple use 64+1 samples per channel per block => block_size=72 bytes
431 // Most PC sound software uses 2040+1 samples per channel per block -> block_size=2048 bytes
432 if ((size%72) == 0)
434 // Allocate 8 extra samples (32 bytes)
435 ALBuf->data=realloc(ALBuf->data,32+(size/72)*(2*65*sizeof(ALshort)));
436 if (ALBuf->data)
438 ALBuf->format = AL_FORMAT_STEREO16;
439 ALBuf->eOriginalFormat = AL_FORMAT_STEREO_IMA4;
440 IMAData=(ALuint *)data;
441 for (i=0;i<size/72;i++)
443 LeftSample=((ALshort *)IMAData)[0];
444 LeftIndex=((ALshort *)IMAData)[1];
446 LeftIndex=LeftIndex<0?0:LeftIndex;
447 LeftIndex=LeftIndex>88?88:LeftIndex;
449 ALBuf->data[i*2*65]=(short)LeftSample;
451 IMAData++;
453 RightSample=((ALshort *)IMAData)[0];
454 RightIndex=((ALshort *)IMAData)[1];
456 RightIndex=RightIndex<0?0:RightIndex;
457 RightIndex=RightIndex>88?88:RightIndex;
459 ALBuf->data[i*2*65+1]=(short)RightSample;
461 IMAData++;
463 for (j=2;j<130;j+=16)
465 LeftIMACode=IMAData[0];
466 RightIMACode=IMAData[1];
467 for (k=0;k<16;k+=4)
469 LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
470 LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15];
471 if (LeftSample<-32768) LeftSample=-32768;
472 else if (LeftSample>32767) LeftSample=32767;
473 if (LeftIndex<0) LeftIndex=0;
474 else if (LeftIndex>88) LeftIndex=88;
475 ALBuf->data[i*2*65+j+k]=(short)LeftSample;
476 LeftIMACode>>=4;
478 RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
479 RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
480 if (RightSample<-32768) RightSample=-32768;
481 else if (RightSample>32767) RightSample=32767;
482 if (RightIndex<0) RightIndex=0;
483 else if (RightIndex>88) RightIndex=88;
484 ALBuf->data[i*2*65+j+k+1]=(short)RightSample;
485 RightIMACode>>=4;
487 LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
488 LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15];
489 if (LeftSample<-32768) LeftSample=-32768;
490 else if (LeftSample>32767) LeftSample=32767;
491 if (LeftIndex<0) LeftIndex=0;
492 else if (LeftIndex>88) LeftIndex=88;
493 ALBuf->data[i*2*65+j+k+2]=(short)LeftSample;
494 LeftIMACode>>=4;
496 RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
497 RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
498 if (RightSample<-32768) RightSample=-32768;
499 else if (RightSample>32767) RightSample=32767;
500 if (RightIndex<0) RightIndex=0;
501 else if (RightIndex>88) RightIndex=88;
502 ALBuf->data[i*2*65+j+k+3]=(short)RightSample;
503 RightIMACode>>=4;
505 IMAData+=2;
508 memset(&(ALBuf->data[(size/72*2*65)]), 0, 32);
509 ALBuf->size=size/72*2*65*sizeof(ALshort);
510 ALBuf->frequency=freq;
512 else
513 alSetError(AL_OUT_OF_MEMORY);
515 else
516 alSetError(AL_INVALID_VALUE);
517 break;
519 default:
520 alSetError(AL_INVALID_ENUM);
521 break;
524 else
526 // Buffer is in use, or data is a NULL pointer
527 alSetError(AL_INVALID_VALUE);
530 else
532 // Invalid Buffer Name
533 alSetError(AL_INVALID_NAME);
536 ProcessContext(Context);
540 ALAPI void ALAPIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
542 ALCcontext *pContext;
543 ALbuffer *pBuffer;
545 (void)flValue;
547 pContext = alcGetCurrentContext();
548 SuspendContext(pContext);
550 if (alIsBuffer(buffer) && (buffer != 0))
552 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
554 switch(eParam)
556 default:
557 alSetError(AL_INVALID_ENUM);
558 break;
561 else
563 alSetError(AL_INVALID_NAME);
566 ProcessContext(pContext);
570 ALAPI void ALAPIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
572 ALCcontext *pContext;
573 ALbuffer *pBuffer;
575 (void)flValue1;
576 (void)flValue2;
577 (void)flValue3;
579 pContext = alcGetCurrentContext();
580 SuspendContext(pContext);
582 if (alIsBuffer(buffer) && (buffer != 0))
584 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
586 switch(eParam)
588 default:
589 alSetError(AL_INVALID_ENUM);
590 break;
593 else
595 alSetError(AL_INVALID_NAME);
598 ProcessContext(pContext);
602 ALAPI void ALAPIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues)
604 ALCcontext *pContext;
605 ALbuffer *pBuffer;
607 (void)flValues;
609 pContext = alcGetCurrentContext();
610 SuspendContext(pContext);
612 if (alIsBuffer(buffer) && (buffer != 0))
614 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
616 switch(eParam)
618 default:
619 alSetError(AL_INVALID_ENUM);
620 break;
623 else
625 alSetError(AL_INVALID_NAME);
628 ProcessContext(pContext);
632 ALAPI void ALAPIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
634 ALCcontext *pContext;
635 ALbuffer *pBuffer;
637 (void)lValue;
639 pContext = alcGetCurrentContext();
640 SuspendContext(pContext);
642 if (alIsBuffer(buffer) && (buffer != 0))
644 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
646 switch(eParam)
648 default:
649 alSetError(AL_INVALID_ENUM);
650 break;
653 else
655 alSetError(AL_INVALID_NAME);
658 ProcessContext(pContext);
662 ALAPI void ALAPIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
664 ALCcontext *pContext;
665 ALbuffer *pBuffer;
667 (void)lValue1;
668 (void)lValue2;
669 (void)lValue3;
671 pContext = alcGetCurrentContext();
672 SuspendContext(pContext);
674 if (alIsBuffer(buffer) && (buffer != 0))
676 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
678 switch(eParam)
680 default:
681 alSetError(AL_INVALID_ENUM);
682 break;
685 else
687 alSetError(AL_INVALID_NAME);
690 ProcessContext(pContext);
694 ALAPI void ALAPIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues)
696 ALCcontext *pContext;
697 ALbuffer *pBuffer;
699 (void)plValues;
701 pContext = alcGetCurrentContext();
702 SuspendContext(pContext);
704 if (alIsBuffer(buffer) && (buffer != 0))
706 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
708 switch(eParam)
710 default:
711 alSetError(AL_INVALID_ENUM);
712 break;
715 else
717 alSetError(AL_INVALID_NAME);
720 ProcessContext(pContext);
724 ALAPI ALvoid ALAPIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue)
726 ALCcontext *pContext;
727 ALbuffer *pBuffer;
729 pContext = alcGetCurrentContext();
730 SuspendContext(pContext);
732 if (pflValue)
734 if (alIsBuffer(buffer) && (buffer != 0))
736 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
738 switch(eParam)
740 default:
741 alSetError(AL_INVALID_ENUM);
742 break;
745 else
747 alSetError(AL_INVALID_NAME);
750 else
752 alSetError(AL_INVALID_VALUE);
755 ProcessContext(pContext);
759 ALAPI void ALAPIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3)
761 ALCcontext *pContext;
762 ALbuffer *pBuffer;
764 pContext = alcGetCurrentContext();
765 SuspendContext(pContext);
767 if ((pflValue1) && (pflValue2) && (pflValue3))
769 if (alIsBuffer(buffer) && (buffer != 0))
771 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
773 switch(eParam)
775 default:
776 alSetError(AL_INVALID_ENUM);
777 break;
780 else
782 alSetError(AL_INVALID_NAME);
785 else
787 alSetError(AL_INVALID_VALUE);
790 ProcessContext(pContext);
794 ALAPI void ALAPIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues)
796 ALCcontext *pContext;
797 ALbuffer *pBuffer;
799 pContext = alcGetCurrentContext();
800 SuspendContext(pContext);
802 if (pflValues)
804 if (alIsBuffer(buffer) && (buffer != 0))
806 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
808 switch(eParam)
810 default:
811 alSetError(AL_INVALID_ENUM);
812 break;
815 else
817 alSetError(AL_INVALID_NAME);
820 else
822 alSetError(AL_INVALID_VALUE);
825 ProcessContext(pContext);
829 ALAPI ALvoid ALAPIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue)
831 ALCcontext *pContext;
832 ALbuffer *pBuffer;
834 pContext = alcGetCurrentContext();
835 SuspendContext(pContext);
837 if (plValue)
839 if (alIsBuffer(buffer) && (buffer != 0))
841 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
843 switch (eParam)
845 case AL_FREQUENCY:
846 *plValue = pBuffer->frequency;
847 break;
849 case AL_BITS:
850 *plValue= (((pBuffer->format==AL_FORMAT_MONO8)||(pBuffer->format==AL_FORMAT_STEREO8))?8:16);
851 break;
853 case AL_CHANNELS:
854 *plValue = (((pBuffer->format==AL_FORMAT_MONO8)||(pBuffer->format==AL_FORMAT_MONO16))?1:2);
855 break;
857 case AL_SIZE:
858 *plValue = pBuffer->size;
859 break;
861 default:
862 alSetError(AL_INVALID_ENUM);
863 break;
866 else
868 alSetError(AL_INVALID_NAME);
871 else
873 alSetError(AL_INVALID_VALUE);
876 ProcessContext(pContext);
880 ALAPI void ALAPIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3)
882 ALCcontext *pContext;
883 ALbuffer *pBuffer;
885 pContext = alcGetCurrentContext();
886 SuspendContext(pContext);
888 if ((plValue1) && (plValue2) && (plValue3))
890 if (alIsBuffer(buffer) && (buffer != 0))
892 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
894 switch(eParam)
896 default:
897 alSetError(AL_INVALID_ENUM);
898 break;
901 else
903 alSetError(AL_INVALID_NAME);
906 else
908 alSetError(AL_INVALID_VALUE);
911 ProcessContext(pContext);
915 ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues)
917 ALCcontext *pContext;
918 ALbuffer *pBuffer;
920 pContext = alcGetCurrentContext();
921 SuspendContext(pContext);
923 if (plValues)
925 if (alIsBuffer(buffer) && (buffer != 0))
927 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
929 switch (eParam)
931 case AL_FREQUENCY:
932 case AL_BITS:
933 case AL_CHANNELS:
934 case AL_SIZE:
935 alGetBufferi(buffer, eParam, plValues);
936 break;
938 default:
939 alSetError(AL_INVALID_ENUM);
940 break;
943 else
945 alSetError(AL_INVALID_NAME);
948 else
950 alSetError(AL_INVALID_VALUE);
953 ProcessContext(pContext);
958 * ReleaseALBuffers()
960 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
962 ALvoid ReleaseALBuffers(ALvoid)
964 ALbuffer *ALBuffer;
965 ALbuffer *ALBufferTemp;
967 #ifdef _DEBUG
968 if(g_uiBufferCount > 0)
970 sprintf(szDebug, "OpenAL32 : DllMain() %d Buffer(s) NOT deleted\n", g_uiBufferCount);
971 OutputDebugString(szDebug);
973 #endif
975 ALBuffer = g_pBuffers;
976 while(ALBuffer)
978 // Release sample data
979 free(ALBuffer->data);
981 // Release Buffer structure
982 ALBufferTemp = ALBuffer;
983 ALBuffer = ALBuffer->next;
984 memset(ALBufferTemp, 0, sizeof(ALbuffer));
985 free(ALBufferTemp);
987 g_pBuffers = NULL;
988 g_uiBufferCount = 0;