More overflow protection
[openal-soft.git] / OpenAL32 / alBuffer.c
blob84f29508560ecdfca51d6d0fc3ddcd13e55138ce
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 "config.h"
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <assert.h>
28 #include "alMain.h"
29 #include "AL/al.h"
30 #include "AL/alc.h"
31 #include "alError.h"
32 #include "alBuffer.h"
33 #include "alThunk.h"
36 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat);
39 * AL Buffer Functions
41 * AL Buffers are shared amoung Contexts, so we store the list of generated Buffers
42 * as a global variable in this module. (A valid context is not required to make
43 * AL Buffer function calls
48 * Global Variables
51 static ALbuffer *g_pBuffers = NULL; // Linked List of Buffers
52 static ALuint g_uiBufferCount = 0; // Buffer Count
54 static const long g_IMAStep_size[89]={ // IMA ADPCM Stepsize table
55 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
56 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
57 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
58 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
59 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493,10442,11487,12635,13899,
60 15289,16818,18500,20350,22358,24633,27086,29794,32767
63 static const long g_IMACodeword_4[16]={ // IMA4 ADPCM Codeword decode table
64 1, 3, 5, 7, 9, 11, 13, 15,
65 -1,-3,-5,-7,-9,-11,-13,-15,
68 static const long g_IMAIndex_adjust_4[16]={ // IMA4 ADPCM Step index adjust decode table
69 -1,-1,-1,-1, 2, 4, 6, 8,
70 -1,-1,-1,-1, 2, 4, 6, 8
74 * alGenBuffers(ALsizei n, ALuint *puiBuffers)
76 * Generates n AL Buffers, and stores the Buffers Names in the array pointed to by puiBuffers
78 ALAPI ALvoid ALAPIENTRY alGenBuffers(ALsizei n,ALuint *puiBuffers)
80 ALCcontext *Context;
81 ALsizei i=0;
83 Context = alcGetCurrentContext();
84 SuspendContext(Context);
86 // Check that we are actually generation some Buffers
87 if (n > 0)
89 // Check the pointer is valid (and points to enough memory to store Buffer Names)
90 if (!IsBadWritePtr((void*)puiBuffers, n * sizeof(ALuint)))
92 ALbuffer **list = &g_pBuffers;
93 while(*list)
94 list = &(*list)->next;
96 // Create all the new Buffers
97 while(i < n)
99 *list = calloc(1, sizeof(ALbuffer));
100 if(!(*list))
102 alDeleteBuffers(i, puiBuffers);
103 alSetError(AL_OUT_OF_MEMORY);
104 break;
107 puiBuffers[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
108 (*list)->state = UNUSED;
109 g_uiBufferCount++;
110 i++;
112 list = &(*list)->next;
115 else
117 // Pointer does not point to enough memory to write Buffer names
118 alSetError(AL_INVALID_VALUE);
122 ProcessContext(Context);
124 return;
128 * alDeleteBuffers(ALsizei n, ALuint *puiBuffers)
130 * Deletes the n AL Buffers pointed to by puiBuffers
132 ALAPI ALvoid ALAPIENTRY alDeleteBuffers(ALsizei n, const ALuint *puiBuffers)
134 ALCcontext *Context;
135 ALbuffer *ALBuf;
136 ALsizei i;
137 ALboolean bFailed = AL_FALSE;
139 Context = alcGetCurrentContext();
140 SuspendContext(Context);
142 // Check we are actually Deleting some Buffers
143 if (n >= 0)
145 if ((ALuint)n <= g_uiBufferCount)
147 // Check that all the buffers are valid and can actually be deleted
148 for (i = 0; i < n; i++)
150 // Check for valid Buffer ID (can be NULL buffer)
151 if (alIsBuffer(puiBuffers[i]))
153 // If not the NULL buffer, check that the reference count is 0
154 ALBuf = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
155 if (ALBuf)
157 if (ALBuf->refcount != 0)
159 // Buffer still in use, cannot be deleted
160 alSetError(AL_INVALID_OPERATION);
161 bFailed = AL_TRUE;
165 else
167 // Invalid Buffer
168 alSetError(AL_INVALID_NAME);
169 bFailed = AL_TRUE;
173 // If all the Buffers were valid (and have Reference Counts of 0), then we can delete them
174 if (!bFailed)
176 for (i = 0; i < n; i++)
178 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
179 if (ALBuf)
181 ALbuffer **list = &g_pBuffers;
182 while(*list && *list != ALBuf)
183 list = &(*list)->next;
185 if(*list)
186 *list = (*list)->next;
188 // Release the memory used to store audio data
189 free(ALBuf->data);
191 // Release buffer structure
192 ALTHUNK_REMOVEENTRY(puiBuffers[i]);
193 memset(ALBuf, 0, sizeof(ALbuffer));
194 g_uiBufferCount--;
195 free(ALBuf);
200 else
201 alSetError(AL_INVALID_NAME);
203 else
204 alSetError(AL_INVALID_VALUE);
206 ProcessContext(Context);
208 return;
213 * alIsBuffer(ALuint uiBuffer)
215 * Checks if ulBuffer is a valid Buffer Name
217 ALAPI ALboolean ALAPIENTRY alIsBuffer(ALuint uiBuffer)
219 ALCcontext *Context;
220 ALboolean result=AL_FALSE;
221 ALbuffer *ALBuf;
222 ALbuffer *TgtALBuf;
224 Context = alcGetCurrentContext();
225 SuspendContext(Context);
227 if (uiBuffer)
229 TgtALBuf = (ALbuffer *)ALTHUNK_LOOKUPENTRY(uiBuffer);
231 // Check through list of generated buffers for uiBuffer
232 ALBuf = g_pBuffers;
233 while (ALBuf)
235 if (ALBuf == TgtALBuf)
237 result = AL_TRUE;
238 break;
241 ALBuf = ALBuf->next;
244 else
246 result = AL_TRUE;
250 ProcessContext(Context);
252 return result;
256 * alBufferData(ALuint buffer,ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
258 * Fill buffer with audio data
260 ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq)
262 ALuint *IMAData,IMACode;
263 ALCcontext *Context;
264 ALint Sample,Index;
265 ALint LeftSample,LeftIndex;
266 ALint RightSample,RightIndex;
267 ALuint LeftIMACode,RightIMACode;
268 ALbuffer *ALBuf;
269 ALsizei i,j,k;
271 Context = alcGetCurrentContext();
272 SuspendContext(Context);
274 if (alIsBuffer(buffer) && (buffer != 0))
276 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
277 if ((ALBuf->refcount==0)&&(data))
279 switch(format)
281 case AL_FORMAT_MONO8:
282 case AL_FORMAT_MONO16:
283 case AL_FORMAT_MONO_FLOAT32:
284 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO16);
285 break;
287 case AL_FORMAT_STEREO8:
288 case AL_FORMAT_STEREO16:
289 case AL_FORMAT_STEREO_FLOAT32:
290 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO16);
291 break;
293 case AL_FORMAT_REAR8:
294 case AL_FORMAT_REAR16:
295 case AL_FORMAT_REAR32: {
296 ALuint NewFormat = AL_FORMAT_QUAD16;
297 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
298 ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
299 ((format==AL_FORMAT_REAR16) ? 2 :
300 4));
301 ALsizei i;
303 assert(aluBytesFromFormat(NewFormat) == 2);
305 if ((size%(OrigBytes*2)) != 0)
307 alSetError(AL_INVALID_VALUE);
308 break;
311 switch(OrigBytes)
313 case 1:
314 size /= sizeof(ALubyte);
315 size *= 2;
317 // 8bit Samples are converted to 16 bit here
318 // Allocate 8 extra samples
319 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
320 if (ALBuf->data)
322 for (i = 0;i < size;i+=4)
324 ALBuf->data[i+0] = 0;
325 ALBuf->data[i+1] = 0;
326 ALBuf->data[i+2] = (ALshort)((((ALubyte*)data)[i/2+0]-128) << 8);
327 ALBuf->data[i+3] = (ALshort)((((ALubyte*)data)[i/2+1]-128) << 8);
329 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
331 ALBuf->format = NewFormat;
332 ALBuf->eOriginalFormat = format;
333 ALBuf->size = size*1*sizeof(ALshort);
334 ALBuf->frequency = freq;
336 else
337 alSetError(AL_OUT_OF_MEMORY);
338 break;
340 case 2:
341 size /= sizeof(ALshort);
342 size *= 2;
344 // Allocate 8 extra samples
345 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
346 if (ALBuf->data)
348 for (i = 0;i < size;i+=4)
350 ALBuf->data[i+0] = 0;
351 ALBuf->data[i+1] = 0;
352 ALBuf->data[i+2] = ((ALshort*)data)[i/2+0];
353 ALBuf->data[i+3] = ((ALshort*)data)[i/2+1];
355 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
357 ALBuf->format = NewFormat;
358 ALBuf->eOriginalFormat = format;
359 ALBuf->size = size*1*sizeof(ALshort);
360 ALBuf->frequency = freq;
362 else
363 alSetError(AL_OUT_OF_MEMORY);
364 break;
366 case 4:
367 size /= sizeof(ALfloat);
368 size *= 2;
370 // Allocate 8 extra samples
371 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
372 if (ALBuf->data)
374 ALint smp;
375 for (i = 0;i < size;i+=4)
377 ALBuf->data[i+0] = 0;
378 ALBuf->data[i+1] = 0;
379 smp = (((ALfloat*)data)[i/2+0] * 32767.5f - 0.5);
380 smp = min(smp, 32767);
381 smp = max(smp, -32768);
382 ALBuf->data[i+2] = (ALshort)smp;
383 smp = (((ALfloat*)data)[i/2+1] * 32767.5f - 0.5);
384 smp = min(smp, 32767);
385 smp = max(smp, -32768);
386 ALBuf->data[i+3] = (ALshort)smp;
388 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
390 ALBuf->format = NewFormat;
391 ALBuf->eOriginalFormat = format;
392 ALBuf->size = size*1*sizeof(ALshort);
393 ALBuf->frequency = freq;
395 else
396 alSetError(AL_OUT_OF_MEMORY);
397 break;
399 default:
400 assert(0);
402 } break;
404 case AL_FORMAT_QUAD8_LOKI:
405 case AL_FORMAT_QUAD16_LOKI:
406 case AL_FORMAT_QUAD8:
407 case AL_FORMAT_QUAD16:
408 case AL_FORMAT_QUAD32:
409 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD16);
410 break;
412 case AL_FORMAT_51CHN8:
413 case AL_FORMAT_51CHN16:
414 case AL_FORMAT_51CHN32:
415 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN16);
416 break;
418 case AL_FORMAT_61CHN8:
419 case AL_FORMAT_61CHN16:
420 case AL_FORMAT_61CHN32:
421 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN16);
422 break;
424 case AL_FORMAT_71CHN8:
425 case AL_FORMAT_71CHN16:
426 case AL_FORMAT_71CHN32:
427 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN16);
428 break;
430 case AL_FORMAT_MONO_IMA4:
431 // Here is where things vary:
432 // nVidia and Apple use 64+1 samples per block => block_size=36 bytes
433 // Most PC sound software uses 2040+1 samples per block -> block_size=1024 bytes
434 if ((size%36) == 0)
436 // Allocate 8 extra samples (16 bytes)
437 ALBuf->data=realloc(ALBuf->data,16+(size/36)*(65*sizeof(ALshort)));
438 if (ALBuf->data)
440 ALBuf->format = AL_FORMAT_MONO16;
441 ALBuf->eOriginalFormat = AL_FORMAT_MONO_IMA4;
442 IMAData=(ALuint *)data;
443 for (i=0;i<size/36;i++)
445 Sample=((ALshort *)IMAData)[0];
446 Index=((ALshort *)IMAData)[1];
448 Index=Index<0?0:Index;
449 Index=Index>88?88:Index;
451 ALBuf->data[i*65]=(short)Sample;
453 IMAData++;
455 for (j=1;j<65;j+=8)
457 IMACode=*IMAData;
458 for (k=0;k<8;k+=2)
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]=(short)Sample;
467 IMACode>>=4;
469 Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8);
470 Index+=g_IMAIndex_adjust_4[IMACode&15];
471 if (Sample<-32768) Sample=-32768;
472 else if (Sample>32767) Sample=32767;
473 if (Index<0) Index=0;
474 else if (Index>88) Index=88;
475 ALBuf->data[i*65+j+k+1]=(short)Sample;
476 IMACode>>=4;
478 IMAData++;
481 memset(&(ALBuf->data[(size/36*65)]), 0, 16);
482 ALBuf->size=size/36*65*sizeof(ALshort);
483 ALBuf->frequency=freq;
485 else
486 alSetError(AL_OUT_OF_MEMORY);
488 else
489 alSetError(AL_INVALID_VALUE);
490 break;
492 case AL_FORMAT_STEREO_IMA4:
493 // Here is where things vary:
494 // nVidia and Apple use 64+1 samples per channel per block => block_size=72 bytes
495 // Most PC sound software uses 2040+1 samples per channel per block -> block_size=2048 bytes
496 if ((size%72) == 0)
498 // Allocate 8 extra samples (32 bytes)
499 ALBuf->data=realloc(ALBuf->data,32+(size/72)*(2*65*sizeof(ALshort)));
500 if (ALBuf->data)
502 ALBuf->format = AL_FORMAT_STEREO16;
503 ALBuf->eOriginalFormat = AL_FORMAT_STEREO_IMA4;
504 IMAData=(ALuint *)data;
505 for (i=0;i<size/72;i++)
507 LeftSample=((ALshort *)IMAData)[0];
508 LeftIndex=((ALshort *)IMAData)[1];
510 LeftIndex=LeftIndex<0?0:LeftIndex;
511 LeftIndex=LeftIndex>88?88:LeftIndex;
513 ALBuf->data[i*2*65]=(short)LeftSample;
515 IMAData++;
517 RightSample=((ALshort *)IMAData)[0];
518 RightIndex=((ALshort *)IMAData)[1];
520 RightIndex=RightIndex<0?0:RightIndex;
521 RightIndex=RightIndex>88?88:RightIndex;
523 ALBuf->data[i*2*65+1]=(short)RightSample;
525 IMAData++;
527 for (j=2;j<130;j+=16)
529 LeftIMACode=IMAData[0];
530 RightIMACode=IMAData[1];
531 for (k=0;k<16;k+=4)
533 LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
534 LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15];
535 if (LeftSample<-32768) LeftSample=-32768;
536 else if (LeftSample>32767) LeftSample=32767;
537 if (LeftIndex<0) LeftIndex=0;
538 else if (LeftIndex>88) LeftIndex=88;
539 ALBuf->data[i*2*65+j+k]=(short)LeftSample;
540 LeftIMACode>>=4;
542 RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
543 RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
544 if (RightSample<-32768) RightSample=-32768;
545 else if (RightSample>32767) RightSample=32767;
546 if (RightIndex<0) RightIndex=0;
547 else if (RightIndex>88) RightIndex=88;
548 ALBuf->data[i*2*65+j+k+1]=(short)RightSample;
549 RightIMACode>>=4;
551 LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
552 LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15];
553 if (LeftSample<-32768) LeftSample=-32768;
554 else if (LeftSample>32767) LeftSample=32767;
555 if (LeftIndex<0) LeftIndex=0;
556 else if (LeftIndex>88) LeftIndex=88;
557 ALBuf->data[i*2*65+j+k+2]=(short)LeftSample;
558 LeftIMACode>>=4;
560 RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
561 RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
562 if (RightSample<-32768) RightSample=-32768;
563 else if (RightSample>32767) RightSample=32767;
564 if (RightIndex<0) RightIndex=0;
565 else if (RightIndex>88) RightIndex=88;
566 ALBuf->data[i*2*65+j+k+3]=(short)RightSample;
567 RightIMACode>>=4;
569 IMAData+=2;
572 memset(&(ALBuf->data[(size/72*2*65)]), 0, 32);
573 ALBuf->size=size/72*2*65*sizeof(ALshort);
574 ALBuf->frequency=freq;
576 else
577 alSetError(AL_OUT_OF_MEMORY);
579 else
580 alSetError(AL_INVALID_VALUE);
581 break;
583 default:
584 alSetError(AL_INVALID_ENUM);
585 break;
588 else
590 // Buffer is in use, or data is a NULL pointer
591 alSetError(AL_INVALID_VALUE);
594 else
596 // Invalid Buffer Name
597 alSetError(AL_INVALID_NAME);
600 ProcessContext(Context);
604 ALAPI void ALAPIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
606 ALCcontext *pContext;
608 (void)flValue;
610 pContext = alcGetCurrentContext();
611 SuspendContext(pContext);
613 if (alIsBuffer(buffer) && (buffer != 0))
615 switch(eParam)
617 default:
618 alSetError(AL_INVALID_ENUM);
619 break;
622 else
624 alSetError(AL_INVALID_NAME);
627 ProcessContext(pContext);
631 ALAPI void ALAPIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
633 ALCcontext *pContext;
635 (void)flValue1;
636 (void)flValue2;
637 (void)flValue3;
639 pContext = alcGetCurrentContext();
640 SuspendContext(pContext);
642 if (alIsBuffer(buffer) && (buffer != 0))
644 switch(eParam)
646 default:
647 alSetError(AL_INVALID_ENUM);
648 break;
651 else
653 alSetError(AL_INVALID_NAME);
656 ProcessContext(pContext);
660 ALAPI void ALAPIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues)
662 ALCcontext *pContext;
664 (void)flValues;
666 pContext = alcGetCurrentContext();
667 SuspendContext(pContext);
669 if (alIsBuffer(buffer) && (buffer != 0))
671 switch(eParam)
673 default:
674 alSetError(AL_INVALID_ENUM);
675 break;
678 else
680 alSetError(AL_INVALID_NAME);
683 ProcessContext(pContext);
687 ALAPI void ALAPIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
689 ALCcontext *pContext;
691 (void)lValue;
693 pContext = alcGetCurrentContext();
694 SuspendContext(pContext);
696 if (alIsBuffer(buffer) && (buffer != 0))
698 switch(eParam)
700 default:
701 alSetError(AL_INVALID_ENUM);
702 break;
705 else
707 alSetError(AL_INVALID_NAME);
710 ProcessContext(pContext);
714 ALAPI void ALAPIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
716 ALCcontext *pContext;
718 (void)lValue1;
719 (void)lValue2;
720 (void)lValue3;
722 pContext = alcGetCurrentContext();
723 SuspendContext(pContext);
725 if (alIsBuffer(buffer) && (buffer != 0))
727 switch(eParam)
729 default:
730 alSetError(AL_INVALID_ENUM);
731 break;
734 else
736 alSetError(AL_INVALID_NAME);
739 ProcessContext(pContext);
743 ALAPI void ALAPIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues)
745 ALCcontext *pContext;
747 (void)plValues;
749 pContext = alcGetCurrentContext();
750 SuspendContext(pContext);
752 if (alIsBuffer(buffer) && (buffer != 0))
754 switch(eParam)
756 default:
757 alSetError(AL_INVALID_ENUM);
758 break;
761 else
763 alSetError(AL_INVALID_NAME);
766 ProcessContext(pContext);
770 ALAPI ALvoid ALAPIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue)
772 ALCcontext *pContext;
774 pContext = alcGetCurrentContext();
775 SuspendContext(pContext);
777 if (pflValue)
779 if (alIsBuffer(buffer) && (buffer != 0))
781 switch(eParam)
783 default:
784 alSetError(AL_INVALID_ENUM);
785 break;
788 else
790 alSetError(AL_INVALID_NAME);
793 else
795 alSetError(AL_INVALID_VALUE);
798 ProcessContext(pContext);
802 ALAPI void ALAPIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3)
804 ALCcontext *pContext;
806 pContext = alcGetCurrentContext();
807 SuspendContext(pContext);
809 if ((pflValue1) && (pflValue2) && (pflValue3))
811 if (alIsBuffer(buffer) && (buffer != 0))
813 switch(eParam)
815 default:
816 alSetError(AL_INVALID_ENUM);
817 break;
820 else
822 alSetError(AL_INVALID_NAME);
825 else
827 alSetError(AL_INVALID_VALUE);
830 ProcessContext(pContext);
834 ALAPI void ALAPIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues)
836 ALCcontext *pContext;
838 pContext = alcGetCurrentContext();
839 SuspendContext(pContext);
841 if (pflValues)
843 if (alIsBuffer(buffer) && (buffer != 0))
845 switch(eParam)
847 default:
848 alSetError(AL_INVALID_ENUM);
849 break;
852 else
854 alSetError(AL_INVALID_NAME);
857 else
859 alSetError(AL_INVALID_VALUE);
862 ProcessContext(pContext);
866 ALAPI ALvoid ALAPIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue)
868 ALCcontext *pContext;
869 ALbuffer *pBuffer;
871 pContext = alcGetCurrentContext();
872 SuspendContext(pContext);
874 if (plValue)
876 if (alIsBuffer(buffer) && (buffer != 0))
878 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
880 switch (eParam)
882 case AL_FREQUENCY:
883 *plValue = pBuffer->frequency;
884 break;
886 case AL_BITS:
887 *plValue = aluBytesFromFormat(pBuffer->format) * 8;
888 break;
890 case AL_CHANNELS:
891 *plValue = aluChannelsFromFormat(pBuffer->format);
892 break;
894 case AL_SIZE:
895 *plValue = pBuffer->size;
896 break;
898 default:
899 alSetError(AL_INVALID_ENUM);
900 break;
903 else
905 alSetError(AL_INVALID_NAME);
908 else
910 alSetError(AL_INVALID_VALUE);
913 ProcessContext(pContext);
917 ALAPI void ALAPIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3)
919 ALCcontext *pContext;
921 pContext = alcGetCurrentContext();
922 SuspendContext(pContext);
924 if ((plValue1) && (plValue2) && (plValue3))
926 if (alIsBuffer(buffer) && (buffer != 0))
928 switch(eParam)
930 default:
931 alSetError(AL_INVALID_ENUM);
932 break;
935 else
937 alSetError(AL_INVALID_NAME);
940 else
942 alSetError(AL_INVALID_VALUE);
945 ProcessContext(pContext);
949 ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues)
951 ALCcontext *pContext;
953 pContext = alcGetCurrentContext();
954 SuspendContext(pContext);
956 if (plValues)
958 if (alIsBuffer(buffer) && (buffer != 0))
960 switch (eParam)
962 case AL_FREQUENCY:
963 case AL_BITS:
964 case AL_CHANNELS:
965 case AL_SIZE:
966 alGetBufferi(buffer, eParam, plValues);
967 break;
969 default:
970 alSetError(AL_INVALID_ENUM);
971 break;
974 else
976 alSetError(AL_INVALID_NAME);
979 else
981 alSetError(AL_INVALID_VALUE);
984 ProcessContext(pContext);
988 * LoadData
990 * Loads the specified data into the buffer, using the specified formats.
991 * Currently, the new format must be 16-bit, and must have the same channel
992 * configuration as the original format. This does NOT handle compressed
993 * formats (eg. IMA4).
995 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
997 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
998 ALuint OrigBytes = aluBytesFromFormat(OrigFormat);
999 ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
1000 ALsizei i;
1002 assert(aluBytesFromFormat(NewFormat) == 2);
1003 assert(NewChannels == OrigChannels);
1005 if ((size%(OrigBytes*OrigChannels)) != 0)
1007 alSetError(AL_INVALID_VALUE);
1008 return;
1011 switch(OrigBytes)
1013 case 1:
1014 size /= sizeof(ALubyte);
1016 // 8bit Samples are converted to 16 bit here
1017 // Allocate 8 extra samples
1018 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
1019 if (ALBuf->data)
1021 for (i = 0;i < size;i++)
1022 ALBuf->data[i] = (ALshort)((data[i]-128) << 8);
1023 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
1025 ALBuf->format = NewFormat;
1026 ALBuf->eOriginalFormat = OrigFormat;
1027 ALBuf->size = size*1*sizeof(ALshort);
1028 ALBuf->frequency = freq;
1030 else
1031 alSetError(AL_OUT_OF_MEMORY);
1032 break;
1034 case 2:
1035 size /= sizeof(ALshort);
1037 // Allocate 8 extra samples
1038 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
1039 if (ALBuf->data)
1041 memcpy(ALBuf->data, data, size*1*sizeof(ALshort));
1042 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
1044 ALBuf->format = NewFormat;
1045 ALBuf->eOriginalFormat = OrigFormat;
1046 ALBuf->size = size*1*sizeof(ALshort);
1047 ALBuf->frequency = freq;
1049 else
1050 alSetError(AL_OUT_OF_MEMORY);
1051 break;
1053 case 4:
1054 size /= sizeof(ALfloat);
1056 // Allocate 8 extra samples
1057 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
1058 if (ALBuf->data)
1060 ALint smp;
1061 for (i = 0;i < size;i++)
1063 smp = (((ALfloat*)data)[i] * 32767.5f - 0.5f);
1064 smp = min(smp, 32767);
1065 smp = max(smp, -32768);
1066 ALBuf->data[i] = (ALshort)smp;
1068 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
1070 ALBuf->format = NewFormat;
1071 ALBuf->eOriginalFormat = OrigFormat;
1072 ALBuf->size = size*1*sizeof(ALshort);
1073 ALBuf->frequency = freq;
1075 else
1076 alSetError(AL_OUT_OF_MEMORY);
1077 break;
1079 default:
1080 assert(0);
1086 * ReleaseALBuffers()
1088 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
1090 ALvoid ReleaseALBuffers(ALvoid)
1092 ALbuffer *ALBuffer;
1093 ALbuffer *ALBufferTemp;
1095 #ifdef _DEBUG
1096 if(g_uiBufferCount > 0)
1097 AL_PRINT("exit() %d Buffer(s) NOT deleted\n", g_uiBufferCount);
1098 #endif
1100 ALBuffer = g_pBuffers;
1101 while(ALBuffer)
1103 // Release sample data
1104 free(ALBuffer->data);
1106 // Release Buffer structure
1107 ALBufferTemp = ALBuffer;
1108 ALBuffer = ALBuffer->next;
1109 memset(ALBufferTemp, 0, sizeof(ALbuffer));
1110 free(ALBufferTemp);
1112 g_pBuffers = NULL;
1113 g_uiBufferCount = 0;