Fix source and buffer out-of-memory conditions
[openal-soft.git] / OpenAL32 / alBuffer.c
blob2a288b853406f84dadda83243c3d2b1639bfdea4
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 <assert.h>
26 #include "alMain.h"
27 #include "AL/al.h"
28 #include "AL/alc.h"
29 #include "alError.h"
30 #include "alBuffer.h"
31 #include "alThunk.h"
34 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat);
37 * AL Buffer Functions
39 * AL Buffers are shared amoung Contexts, so we store the list of generated Buffers
40 * as a global variable in this module. (A valid context is not required to make
41 * AL Buffer function calls
46 * Global Variables
49 static ALbuffer *g_pBuffers = NULL; // Linked List of Buffers
50 static ALuint g_uiBufferCount = 0; // Buffer Count
52 static const long g_IMAStep_size[89]={ // IMA ADPCM Stepsize table
53 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
54 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
55 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
56 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
57 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493,10442,11487,12635,13899,
58 15289,16818,18500,20350,22358,24633,27086,29794,32767
61 static const long g_IMACodeword_4[16]={ // IMA4 ADPCM Codeword decode table
62 1, 3, 5, 7, 9, 11, 13, 15,
63 -1,-3,-5,-7,-9,-11,-13,-15,
66 static const long g_IMAIndex_adjust_4[16]={ // IMA4 ADPCM Step index adjust decode table
67 -1,-1,-1,-1, 2, 4, 6, 8,
68 -1,-1,-1,-1, 2, 4, 6, 8
72 * alGenBuffers(ALsizei n, ALuint *puiBuffers)
74 * Generates n AL Buffers, and stores the Buffers Names in the array pointed to by puiBuffers
76 ALAPI ALvoid ALAPIENTRY alGenBuffers(ALsizei n,ALuint *puiBuffers)
78 ALCcontext *Context;
79 ALsizei i=0;
81 Context = alcGetCurrentContext();
82 SuspendContext(Context);
84 // Check that we are actually generation some Buffers
85 if (n > 0)
87 // Check the pointer is valid (and points to enough memory to store Buffer Names)
88 if (!IsBadWritePtr((void*)puiBuffers, n * sizeof(ALuint)))
90 ALbuffer **list = &g_pBuffers;
91 while(*list)
92 list = &(*list)->next;
94 // Create all the new Buffers
95 while(i < n)
97 *list = calloc(1, sizeof(ALbuffer));
98 if(!(*list))
100 alDeleteBuffers(i, puiBuffers);
101 alSetError(AL_OUT_OF_MEMORY);
102 break;
105 puiBuffers[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
106 (*list)->state = UNUSED;
107 g_uiBufferCount++;
108 i++;
110 list = &(*list)->next;
113 else
115 // Pointer does not point to enough memory to write Buffer names
116 alSetError(AL_INVALID_VALUE);
120 ProcessContext(Context);
122 return;
126 * alDeleteBuffers(ALsizei n, ALuint *puiBuffers)
128 * Deletes the n AL Buffers pointed to by puiBuffers
130 ALAPI ALvoid ALAPIENTRY alDeleteBuffers(ALsizei n, const ALuint *puiBuffers)
132 ALCcontext *Context;
133 ALbuffer *ALBuf;
134 ALsizei i;
135 ALboolean bFailed = AL_FALSE;
137 Context = alcGetCurrentContext();
138 SuspendContext(Context);
140 // Check we are actually Deleting some Buffers
141 if (n >= 0)
143 if ((ALuint)n <= g_uiBufferCount)
145 // Check that all the buffers are valid and can actually be deleted
146 for (i = 0; i < n; i++)
148 // Check for valid Buffer ID (can be NULL buffer)
149 if (alIsBuffer(puiBuffers[i]))
151 // If not the NULL buffer, check that the reference count is 0
152 ALBuf = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
153 if (ALBuf)
155 if (ALBuf->refcount != 0)
157 // Buffer still in use, cannot be deleted
158 alSetError(AL_INVALID_OPERATION);
159 bFailed = AL_TRUE;
163 else
165 // Invalid Buffer
166 alSetError(AL_INVALID_NAME);
167 bFailed = AL_TRUE;
171 // If all the Buffers were valid (and have Reference Counts of 0), then we can delete them
172 if (!bFailed)
174 for (i = 0; i < n; i++)
176 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
177 if (ALBuf)
179 ALbuffer **list = &g_pBuffers;
180 while(*list && *list != ALBuf)
181 list = &(*list)->next;
183 if(*list)
184 *list = (*list)->next;
186 // Release the memory used to store audio data
187 free(ALBuf->data);
189 // Release buffer structure
190 ALTHUNK_REMOVEENTRY(puiBuffers[i]);
191 memset(ALBuf, 0, sizeof(ALbuffer));
192 g_uiBufferCount--;
193 free(ALBuf);
198 else
199 alSetError(AL_INVALID_NAME);
201 else
202 alSetError(AL_INVALID_VALUE);
204 ProcessContext(Context);
206 return;
211 * alIsBuffer(ALuint uiBuffer)
213 * Checks if ulBuffer is a valid Buffer Name
215 ALAPI ALboolean ALAPIENTRY alIsBuffer(ALuint uiBuffer)
217 ALCcontext *Context;
218 ALboolean result=AL_FALSE;
219 ALbuffer *ALBuf;
220 ALbuffer *TgtALBuf;
222 Context = alcGetCurrentContext();
223 SuspendContext(Context);
225 if (uiBuffer)
227 TgtALBuf = (ALbuffer *)ALTHUNK_LOOKUPENTRY(uiBuffer);
229 // Check through list of generated buffers for uiBuffer
230 ALBuf = g_pBuffers;
231 while (ALBuf)
233 if (ALBuf == TgtALBuf)
235 result = AL_TRUE;
236 break;
239 ALBuf = ALBuf->next;
242 else
244 result = AL_TRUE;
248 ProcessContext(Context);
250 return result;
254 * alBufferData(ALuint buffer,ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
256 * Fill buffer with audio data
258 ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq)
260 ALuint *IMAData,IMACode;
261 ALCcontext *Context;
262 ALint Sample,Index;
263 ALint LeftSample,LeftIndex;
264 ALint RightSample,RightIndex;
265 ALuint LeftIMACode,RightIMACode;
266 ALbuffer *ALBuf;
267 ALsizei i,j,k;
269 Context = alcGetCurrentContext();
270 SuspendContext(Context);
272 if (alIsBuffer(buffer) && (buffer != 0))
274 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
275 if ((ALBuf->refcount==0)&&(data))
277 switch(format)
279 case AL_FORMAT_MONO8:
280 case AL_FORMAT_MONO16:
281 case AL_FORMAT_MONO_FLOAT32:
282 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO16);
283 break;
285 case AL_FORMAT_STEREO8:
286 case AL_FORMAT_STEREO16:
287 case AL_FORMAT_STEREO_FLOAT32:
288 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO16);
289 break;
291 case AL_FORMAT_REAR8:
292 case AL_FORMAT_REAR16:
293 case AL_FORMAT_REAR32: {
294 ALuint NewFormat = AL_FORMAT_QUAD16;
295 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
296 ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
297 ((format==AL_FORMAT_REAR16) ? 2 :
298 4));
299 ALsizei i;
301 assert(aluBytesFromFormat(NewFormat) == 2);
303 if ((size%(OrigBytes*2)) != 0)
305 alSetError(AL_INVALID_VALUE);
306 break;
309 switch(OrigBytes)
311 case 1:
312 size /= sizeof(ALubyte);
313 size *= 2;
315 // 8bit Samples are converted to 16 bit here
316 // Allocate 8 extra samples
317 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
318 if (ALBuf->data)
320 for (i = 0;i < size;i+=4)
322 ALBuf->data[i+0] = 0;
323 ALBuf->data[i+1] = 0;
324 ALBuf->data[i+2] = (ALshort)((((ALubyte*)data)[i/2+0]-128) << 8);
325 ALBuf->data[i+3] = (ALshort)((((ALubyte*)data)[i/2+1]-128) << 8);
327 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
329 ALBuf->format = NewFormat;
330 ALBuf->eOriginalFormat = format;
331 ALBuf->size = size*1*sizeof(ALshort);
332 ALBuf->frequency = freq;
334 else
335 alSetError(AL_OUT_OF_MEMORY);
336 break;
338 case 2:
339 size /= sizeof(ALshort);
340 size *= 2;
342 // Allocate 8 extra samples
343 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
344 if (ALBuf->data)
346 for (i = 0;i < size;i+=4)
348 ALBuf->data[i+0] = 0;
349 ALBuf->data[i+1] = 0;
350 ALBuf->data[i+2] = ((ALshort*)data)[i/2+0];
351 ALBuf->data[i+3] = ((ALshort*)data)[i/2+1];
353 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
355 ALBuf->format = NewFormat;
356 ALBuf->eOriginalFormat = format;
357 ALBuf->size = size*1*sizeof(ALshort);
358 ALBuf->frequency = freq;
360 else
361 alSetError(AL_OUT_OF_MEMORY);
362 break;
364 case 4:
365 size /= sizeof(ALfloat);
366 size *= 2;
368 // Allocate 8 extra samples
369 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
370 if (ALBuf->data)
372 for (i = 0;i < size;i+=4)
374 ALBuf->data[i+0] = 0;
375 ALBuf->data[i+1] = 0;
376 ALBuf->data[i+2] = (ALshort)(((ALfloat*)data)[i/2+0] * 32767.5f - 0.5);
377 ALBuf->data[i+3] = (ALshort)(((ALfloat*)data)[i/2+1] * 32767.5f - 0.5);
379 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
381 ALBuf->format = NewFormat;
382 ALBuf->eOriginalFormat = format;
383 ALBuf->size = size*1*sizeof(ALshort);
384 ALBuf->frequency = freq;
386 else
387 alSetError(AL_OUT_OF_MEMORY);
388 break;
390 default:
391 assert(0);
393 } break;
395 case AL_FORMAT_QUAD8_LOKI:
396 case AL_FORMAT_QUAD16_LOKI:
397 case AL_FORMAT_QUAD8:
398 case AL_FORMAT_QUAD16:
399 case AL_FORMAT_QUAD32:
400 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD16);
401 break;
403 case AL_FORMAT_51CHN8:
404 case AL_FORMAT_51CHN16:
405 case AL_FORMAT_51CHN32:
406 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN16);
407 break;
409 case AL_FORMAT_61CHN8:
410 case AL_FORMAT_61CHN16:
411 case AL_FORMAT_61CHN32:
412 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN16);
413 break;
415 case AL_FORMAT_71CHN8:
416 case AL_FORMAT_71CHN16:
417 case AL_FORMAT_71CHN32:
418 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN16);
419 break;
421 case AL_FORMAT_MONO_IMA4:
422 // Here is where things vary:
423 // nVidia and Apple use 64+1 samples per block => block_size=36 bytes
424 // Most PC sound software uses 2040+1 samples per block -> block_size=1024 bytes
425 if ((size%36) == 0)
427 // Allocate 8 extra samples (16 bytes)
428 ALBuf->data=realloc(ALBuf->data,16+(size/36)*(65*sizeof(ALshort)));
429 if (ALBuf->data)
431 ALBuf->format = AL_FORMAT_MONO16;
432 ALBuf->eOriginalFormat = AL_FORMAT_MONO_IMA4;
433 IMAData=(ALuint *)data;
434 for (i=0;i<size/36;i++)
436 Sample=((ALshort *)IMAData)[0];
437 Index=((ALshort *)IMAData)[1];
439 Index=Index<0?0:Index;
440 Index=Index>88?88:Index;
442 ALBuf->data[i*65]=(short)Sample;
444 IMAData++;
446 for (j=1;j<65;j+=8)
448 IMACode=*IMAData;
449 for (k=0;k<8;k+=2)
451 Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8);
452 Index+=g_IMAIndex_adjust_4[IMACode&15];
453 if (Sample<-32768) Sample=-32768;
454 else if (Sample>32767) Sample=32767;
455 if (Index<0) Index=0;
456 else if (Index>88) Index=88;
457 ALBuf->data[i*65+j+k]=(short)Sample;
458 IMACode>>=4;
460 Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8);
461 Index+=g_IMAIndex_adjust_4[IMACode&15];
462 if (Sample<-32768) Sample=-32768;
463 else if (Sample>32767) Sample=32767;
464 if (Index<0) Index=0;
465 else if (Index>88) Index=88;
466 ALBuf->data[i*65+j+k+1]=(short)Sample;
467 IMACode>>=4;
469 IMAData++;
472 memset(&(ALBuf->data[(size/36*65)]), 0, 16);
473 ALBuf->size=size/36*65*sizeof(ALshort);
474 ALBuf->frequency=freq;
476 else
477 alSetError(AL_OUT_OF_MEMORY);
479 else
480 alSetError(AL_INVALID_VALUE);
481 break;
483 case AL_FORMAT_STEREO_IMA4:
484 // Here is where things vary:
485 // nVidia and Apple use 64+1 samples per channel per block => block_size=72 bytes
486 // Most PC sound software uses 2040+1 samples per channel per block -> block_size=2048 bytes
487 if ((size%72) == 0)
489 // Allocate 8 extra samples (32 bytes)
490 ALBuf->data=realloc(ALBuf->data,32+(size/72)*(2*65*sizeof(ALshort)));
491 if (ALBuf->data)
493 ALBuf->format = AL_FORMAT_STEREO16;
494 ALBuf->eOriginalFormat = AL_FORMAT_STEREO_IMA4;
495 IMAData=(ALuint *)data;
496 for (i=0;i<size/72;i++)
498 LeftSample=((ALshort *)IMAData)[0];
499 LeftIndex=((ALshort *)IMAData)[1];
501 LeftIndex=LeftIndex<0?0:LeftIndex;
502 LeftIndex=LeftIndex>88?88:LeftIndex;
504 ALBuf->data[i*2*65]=(short)LeftSample;
506 IMAData++;
508 RightSample=((ALshort *)IMAData)[0];
509 RightIndex=((ALshort *)IMAData)[1];
511 RightIndex=RightIndex<0?0:RightIndex;
512 RightIndex=RightIndex>88?88:RightIndex;
514 ALBuf->data[i*2*65+1]=(short)RightSample;
516 IMAData++;
518 for (j=2;j<130;j+=16)
520 LeftIMACode=IMAData[0];
521 RightIMACode=IMAData[1];
522 for (k=0;k<16;k+=4)
524 LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
525 LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15];
526 if (LeftSample<-32768) LeftSample=-32768;
527 else if (LeftSample>32767) LeftSample=32767;
528 if (LeftIndex<0) LeftIndex=0;
529 else if (LeftIndex>88) LeftIndex=88;
530 ALBuf->data[i*2*65+j+k]=(short)LeftSample;
531 LeftIMACode>>=4;
533 RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
534 RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
535 if (RightSample<-32768) RightSample=-32768;
536 else if (RightSample>32767) RightSample=32767;
537 if (RightIndex<0) RightIndex=0;
538 else if (RightIndex>88) RightIndex=88;
539 ALBuf->data[i*2*65+j+k+1]=(short)RightSample;
540 RightIMACode>>=4;
542 LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
543 LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15];
544 if (LeftSample<-32768) LeftSample=-32768;
545 else if (LeftSample>32767) LeftSample=32767;
546 if (LeftIndex<0) LeftIndex=0;
547 else if (LeftIndex>88) LeftIndex=88;
548 ALBuf->data[i*2*65+j+k+2]=(short)LeftSample;
549 LeftIMACode>>=4;
551 RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
552 RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
553 if (RightSample<-32768) RightSample=-32768;
554 else if (RightSample>32767) RightSample=32767;
555 if (RightIndex<0) RightIndex=0;
556 else if (RightIndex>88) RightIndex=88;
557 ALBuf->data[i*2*65+j+k+3]=(short)RightSample;
558 RightIMACode>>=4;
560 IMAData+=2;
563 memset(&(ALBuf->data[(size/72*2*65)]), 0, 32);
564 ALBuf->size=size/72*2*65*sizeof(ALshort);
565 ALBuf->frequency=freq;
567 else
568 alSetError(AL_OUT_OF_MEMORY);
570 else
571 alSetError(AL_INVALID_VALUE);
572 break;
574 default:
575 alSetError(AL_INVALID_ENUM);
576 break;
579 else
581 // Buffer is in use, or data is a NULL pointer
582 alSetError(AL_INVALID_VALUE);
585 else
587 // Invalid Buffer Name
588 alSetError(AL_INVALID_NAME);
591 ProcessContext(Context);
595 ALAPI void ALAPIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
597 ALCcontext *pContext;
599 (void)flValue;
601 pContext = alcGetCurrentContext();
602 SuspendContext(pContext);
604 if (alIsBuffer(buffer) && (buffer != 0))
606 switch(eParam)
608 default:
609 alSetError(AL_INVALID_ENUM);
610 break;
613 else
615 alSetError(AL_INVALID_NAME);
618 ProcessContext(pContext);
622 ALAPI void ALAPIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
624 ALCcontext *pContext;
626 (void)flValue1;
627 (void)flValue2;
628 (void)flValue3;
630 pContext = alcGetCurrentContext();
631 SuspendContext(pContext);
633 if (alIsBuffer(buffer) && (buffer != 0))
635 switch(eParam)
637 default:
638 alSetError(AL_INVALID_ENUM);
639 break;
642 else
644 alSetError(AL_INVALID_NAME);
647 ProcessContext(pContext);
651 ALAPI void ALAPIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues)
653 ALCcontext *pContext;
655 (void)flValues;
657 pContext = alcGetCurrentContext();
658 SuspendContext(pContext);
660 if (alIsBuffer(buffer) && (buffer != 0))
662 switch(eParam)
664 default:
665 alSetError(AL_INVALID_ENUM);
666 break;
669 else
671 alSetError(AL_INVALID_NAME);
674 ProcessContext(pContext);
678 ALAPI void ALAPIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
680 ALCcontext *pContext;
682 (void)lValue;
684 pContext = alcGetCurrentContext();
685 SuspendContext(pContext);
687 if (alIsBuffer(buffer) && (buffer != 0))
689 switch(eParam)
691 default:
692 alSetError(AL_INVALID_ENUM);
693 break;
696 else
698 alSetError(AL_INVALID_NAME);
701 ProcessContext(pContext);
705 ALAPI void ALAPIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
707 ALCcontext *pContext;
709 (void)lValue1;
710 (void)lValue2;
711 (void)lValue3;
713 pContext = alcGetCurrentContext();
714 SuspendContext(pContext);
716 if (alIsBuffer(buffer) && (buffer != 0))
718 switch(eParam)
720 default:
721 alSetError(AL_INVALID_ENUM);
722 break;
725 else
727 alSetError(AL_INVALID_NAME);
730 ProcessContext(pContext);
734 ALAPI void ALAPIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues)
736 ALCcontext *pContext;
738 (void)plValues;
740 pContext = alcGetCurrentContext();
741 SuspendContext(pContext);
743 if (alIsBuffer(buffer) && (buffer != 0))
745 switch(eParam)
747 default:
748 alSetError(AL_INVALID_ENUM);
749 break;
752 else
754 alSetError(AL_INVALID_NAME);
757 ProcessContext(pContext);
761 ALAPI ALvoid ALAPIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue)
763 ALCcontext *pContext;
765 pContext = alcGetCurrentContext();
766 SuspendContext(pContext);
768 if (pflValue)
770 if (alIsBuffer(buffer) && (buffer != 0))
772 switch(eParam)
774 default:
775 alSetError(AL_INVALID_ENUM);
776 break;
779 else
781 alSetError(AL_INVALID_NAME);
784 else
786 alSetError(AL_INVALID_VALUE);
789 ProcessContext(pContext);
793 ALAPI void ALAPIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3)
795 ALCcontext *pContext;
797 pContext = alcGetCurrentContext();
798 SuspendContext(pContext);
800 if ((pflValue1) && (pflValue2) && (pflValue3))
802 if (alIsBuffer(buffer) && (buffer != 0))
804 switch(eParam)
806 default:
807 alSetError(AL_INVALID_ENUM);
808 break;
811 else
813 alSetError(AL_INVALID_NAME);
816 else
818 alSetError(AL_INVALID_VALUE);
821 ProcessContext(pContext);
825 ALAPI void ALAPIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues)
827 ALCcontext *pContext;
829 pContext = alcGetCurrentContext();
830 SuspendContext(pContext);
832 if (pflValues)
834 if (alIsBuffer(buffer) && (buffer != 0))
836 switch(eParam)
838 default:
839 alSetError(AL_INVALID_ENUM);
840 break;
843 else
845 alSetError(AL_INVALID_NAME);
848 else
850 alSetError(AL_INVALID_VALUE);
853 ProcessContext(pContext);
857 ALAPI ALvoid ALAPIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue)
859 ALCcontext *pContext;
860 ALbuffer *pBuffer;
862 pContext = alcGetCurrentContext();
863 SuspendContext(pContext);
865 if (plValue)
867 if (alIsBuffer(buffer) && (buffer != 0))
869 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
871 switch (eParam)
873 case AL_FREQUENCY:
874 *plValue = pBuffer->frequency;
875 break;
877 case AL_BITS:
878 *plValue = aluBytesFromFormat(pBuffer->format) * 8;
879 break;
881 case AL_CHANNELS:
882 *plValue = aluChannelsFromFormat(pBuffer->format);
883 break;
885 case AL_SIZE:
886 *plValue = pBuffer->size;
887 break;
889 default:
890 alSetError(AL_INVALID_ENUM);
891 break;
894 else
896 alSetError(AL_INVALID_NAME);
899 else
901 alSetError(AL_INVALID_VALUE);
904 ProcessContext(pContext);
908 ALAPI void ALAPIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3)
910 ALCcontext *pContext;
912 pContext = alcGetCurrentContext();
913 SuspendContext(pContext);
915 if ((plValue1) && (plValue2) && (plValue3))
917 if (alIsBuffer(buffer) && (buffer != 0))
919 switch(eParam)
921 default:
922 alSetError(AL_INVALID_ENUM);
923 break;
926 else
928 alSetError(AL_INVALID_NAME);
931 else
933 alSetError(AL_INVALID_VALUE);
936 ProcessContext(pContext);
940 ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues)
942 ALCcontext *pContext;
944 pContext = alcGetCurrentContext();
945 SuspendContext(pContext);
947 if (plValues)
949 if (alIsBuffer(buffer) && (buffer != 0))
951 switch (eParam)
953 case AL_FREQUENCY:
954 case AL_BITS:
955 case AL_CHANNELS:
956 case AL_SIZE:
957 alGetBufferi(buffer, eParam, plValues);
958 break;
960 default:
961 alSetError(AL_INVALID_ENUM);
962 break;
965 else
967 alSetError(AL_INVALID_NAME);
970 else
972 alSetError(AL_INVALID_VALUE);
975 ProcessContext(pContext);
979 * LoadData
981 * Loads the specified data into the buffer, using the specified formats.
982 * Currently, the new format must be 16-bit, and must have the same channel
983 * configuration as the original format. This does NOT handle compressed
984 * formats (eg. IMA4).
986 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
988 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
989 ALuint OrigBytes = aluBytesFromFormat(OrigFormat);
990 ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
991 ALsizei i;
993 assert(aluBytesFromFormat(NewFormat) == 2);
994 assert(NewChannels == OrigChannels);
996 if ((size%(OrigBytes*OrigChannels)) != 0)
998 alSetError(AL_INVALID_VALUE);
999 return;
1002 switch(OrigBytes)
1004 case 1:
1005 size /= sizeof(ALubyte);
1007 // 8bit Samples are converted to 16 bit here
1008 // Allocate 8 extra samples
1009 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
1010 if (ALBuf->data)
1012 for (i = 0;i < size;i++)
1013 ALBuf->data[i] = (ALshort)((data[i]-128) << 8);
1014 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
1016 ALBuf->format = NewFormat;
1017 ALBuf->eOriginalFormat = OrigFormat;
1018 ALBuf->size = size*1*sizeof(ALshort);
1019 ALBuf->frequency = freq;
1021 else
1022 alSetError(AL_OUT_OF_MEMORY);
1023 break;
1025 case 2:
1026 size /= sizeof(ALshort);
1028 // Allocate 8 extra samples
1029 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
1030 if (ALBuf->data)
1032 memcpy(ALBuf->data, data, size*1*sizeof(ALshort));
1033 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
1035 ALBuf->format = NewFormat;
1036 ALBuf->eOriginalFormat = OrigFormat;
1037 ALBuf->size = size*1*sizeof(ALshort);
1038 ALBuf->frequency = freq;
1040 else
1041 alSetError(AL_OUT_OF_MEMORY);
1042 break;
1044 case 4:
1045 size /= sizeof(ALfloat);
1047 // Allocate 8 extra samples
1048 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
1049 if (ALBuf->data)
1051 for (i = 0;i < size;i++)
1052 ALBuf->data[i] = (ALshort)(((ALfloat*)data)[i] * 32767.5f - 0.5);
1053 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
1055 ALBuf->format = NewFormat;
1056 ALBuf->eOriginalFormat = OrigFormat;
1057 ALBuf->size = size*1*sizeof(ALshort);
1058 ALBuf->frequency = freq;
1060 else
1061 alSetError(AL_OUT_OF_MEMORY);
1062 break;
1064 default:
1065 assert(0);
1071 * ReleaseALBuffers()
1073 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
1075 ALvoid ReleaseALBuffers(ALvoid)
1077 ALbuffer *ALBuffer;
1078 ALbuffer *ALBufferTemp;
1080 #ifdef _DEBUG
1081 if(g_uiBufferCount > 0)
1082 AL_PRINT("exit() %d Buffer(s) NOT deleted\n", g_uiBufferCount);
1083 #endif
1085 ALBuffer = g_pBuffers;
1086 while(ALBuffer)
1088 // Release sample data
1089 free(ALBuffer->data);
1091 // Release Buffer structure
1092 ALBufferTemp = ALBuffer;
1093 ALBuffer = ALBuffer->next;
1094 memset(ALBufferTemp, 0, sizeof(ALbuffer));
1095 free(ALBufferTemp);
1097 g_pBuffers = NULL;
1098 g_uiBufferCount = 0;