Add missing config.h includes
[openal-soft.git] / OpenAL32 / alBuffer.c
blob2b94caf66463d687f2c70a23eb77cdf36ed35852
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 for (i = 0;i < size;i+=4)
376 ALBuf->data[i+0] = 0;
377 ALBuf->data[i+1] = 0;
378 ALBuf->data[i+2] = (ALshort)(((ALfloat*)data)[i/2+0] * 32767.5f - 0.5);
379 ALBuf->data[i+3] = (ALshort)(((ALfloat*)data)[i/2+1] * 32767.5f - 0.5);
381 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
383 ALBuf->format = NewFormat;
384 ALBuf->eOriginalFormat = format;
385 ALBuf->size = size*1*sizeof(ALshort);
386 ALBuf->frequency = freq;
388 else
389 alSetError(AL_OUT_OF_MEMORY);
390 break;
392 default:
393 assert(0);
395 } break;
397 case AL_FORMAT_QUAD8_LOKI:
398 case AL_FORMAT_QUAD16_LOKI:
399 case AL_FORMAT_QUAD8:
400 case AL_FORMAT_QUAD16:
401 case AL_FORMAT_QUAD32:
402 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD16);
403 break;
405 case AL_FORMAT_51CHN8:
406 case AL_FORMAT_51CHN16:
407 case AL_FORMAT_51CHN32:
408 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN16);
409 break;
411 case AL_FORMAT_61CHN8:
412 case AL_FORMAT_61CHN16:
413 case AL_FORMAT_61CHN32:
414 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN16);
415 break;
417 case AL_FORMAT_71CHN8:
418 case AL_FORMAT_71CHN16:
419 case AL_FORMAT_71CHN32:
420 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN16);
421 break;
423 case AL_FORMAT_MONO_IMA4:
424 // Here is where things vary:
425 // nVidia and Apple use 64+1 samples per block => block_size=36 bytes
426 // Most PC sound software uses 2040+1 samples per block -> block_size=1024 bytes
427 if ((size%36) == 0)
429 // Allocate 8 extra samples (16 bytes)
430 ALBuf->data=realloc(ALBuf->data,16+(size/36)*(65*sizeof(ALshort)));
431 if (ALBuf->data)
433 ALBuf->format = AL_FORMAT_MONO16;
434 ALBuf->eOriginalFormat = AL_FORMAT_MONO_IMA4;
435 IMAData=(ALuint *)data;
436 for (i=0;i<size/36;i++)
438 Sample=((ALshort *)IMAData)[0];
439 Index=((ALshort *)IMAData)[1];
441 Index=Index<0?0:Index;
442 Index=Index>88?88:Index;
444 ALBuf->data[i*65]=(short)Sample;
446 IMAData++;
448 for (j=1;j<65;j+=8)
450 IMACode=*IMAData;
451 for (k=0;k<8;k+=2)
453 Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8);
454 Index+=g_IMAIndex_adjust_4[IMACode&15];
455 if (Sample<-32768) Sample=-32768;
456 else if (Sample>32767) Sample=32767;
457 if (Index<0) Index=0;
458 else if (Index>88) Index=88;
459 ALBuf->data[i*65+j+k]=(short)Sample;
460 IMACode>>=4;
462 Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8);
463 Index+=g_IMAIndex_adjust_4[IMACode&15];
464 if (Sample<-32768) Sample=-32768;
465 else if (Sample>32767) Sample=32767;
466 if (Index<0) Index=0;
467 else if (Index>88) Index=88;
468 ALBuf->data[i*65+j+k+1]=(short)Sample;
469 IMACode>>=4;
471 IMAData++;
474 memset(&(ALBuf->data[(size/36*65)]), 0, 16);
475 ALBuf->size=size/36*65*sizeof(ALshort);
476 ALBuf->frequency=freq;
478 else
479 alSetError(AL_OUT_OF_MEMORY);
481 else
482 alSetError(AL_INVALID_VALUE);
483 break;
485 case AL_FORMAT_STEREO_IMA4:
486 // Here is where things vary:
487 // nVidia and Apple use 64+1 samples per channel per block => block_size=72 bytes
488 // Most PC sound software uses 2040+1 samples per channel per block -> block_size=2048 bytes
489 if ((size%72) == 0)
491 // Allocate 8 extra samples (32 bytes)
492 ALBuf->data=realloc(ALBuf->data,32+(size/72)*(2*65*sizeof(ALshort)));
493 if (ALBuf->data)
495 ALBuf->format = AL_FORMAT_STEREO16;
496 ALBuf->eOriginalFormat = AL_FORMAT_STEREO_IMA4;
497 IMAData=(ALuint *)data;
498 for (i=0;i<size/72;i++)
500 LeftSample=((ALshort *)IMAData)[0];
501 LeftIndex=((ALshort *)IMAData)[1];
503 LeftIndex=LeftIndex<0?0:LeftIndex;
504 LeftIndex=LeftIndex>88?88:LeftIndex;
506 ALBuf->data[i*2*65]=(short)LeftSample;
508 IMAData++;
510 RightSample=((ALshort *)IMAData)[0];
511 RightIndex=((ALshort *)IMAData)[1];
513 RightIndex=RightIndex<0?0:RightIndex;
514 RightIndex=RightIndex>88?88:RightIndex;
516 ALBuf->data[i*2*65+1]=(short)RightSample;
518 IMAData++;
520 for (j=2;j<130;j+=16)
522 LeftIMACode=IMAData[0];
523 RightIMACode=IMAData[1];
524 for (k=0;k<16;k+=4)
526 LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
527 LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15];
528 if (LeftSample<-32768) LeftSample=-32768;
529 else if (LeftSample>32767) LeftSample=32767;
530 if (LeftIndex<0) LeftIndex=0;
531 else if (LeftIndex>88) LeftIndex=88;
532 ALBuf->data[i*2*65+j+k]=(short)LeftSample;
533 LeftIMACode>>=4;
535 RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
536 RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
537 if (RightSample<-32768) RightSample=-32768;
538 else if (RightSample>32767) RightSample=32767;
539 if (RightIndex<0) RightIndex=0;
540 else if (RightIndex>88) RightIndex=88;
541 ALBuf->data[i*2*65+j+k+1]=(short)RightSample;
542 RightIMACode>>=4;
544 LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
545 LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15];
546 if (LeftSample<-32768) LeftSample=-32768;
547 else if (LeftSample>32767) LeftSample=32767;
548 if (LeftIndex<0) LeftIndex=0;
549 else if (LeftIndex>88) LeftIndex=88;
550 ALBuf->data[i*2*65+j+k+2]=(short)LeftSample;
551 LeftIMACode>>=4;
553 RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
554 RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
555 if (RightSample<-32768) RightSample=-32768;
556 else if (RightSample>32767) RightSample=32767;
557 if (RightIndex<0) RightIndex=0;
558 else if (RightIndex>88) RightIndex=88;
559 ALBuf->data[i*2*65+j+k+3]=(short)RightSample;
560 RightIMACode>>=4;
562 IMAData+=2;
565 memset(&(ALBuf->data[(size/72*2*65)]), 0, 32);
566 ALBuf->size=size/72*2*65*sizeof(ALshort);
567 ALBuf->frequency=freq;
569 else
570 alSetError(AL_OUT_OF_MEMORY);
572 else
573 alSetError(AL_INVALID_VALUE);
574 break;
576 default:
577 alSetError(AL_INVALID_ENUM);
578 break;
581 else
583 // Buffer is in use, or data is a NULL pointer
584 alSetError(AL_INVALID_VALUE);
587 else
589 // Invalid Buffer Name
590 alSetError(AL_INVALID_NAME);
593 ProcessContext(Context);
597 ALAPI void ALAPIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
599 ALCcontext *pContext;
601 (void)flValue;
603 pContext = alcGetCurrentContext();
604 SuspendContext(pContext);
606 if (alIsBuffer(buffer) && (buffer != 0))
608 switch(eParam)
610 default:
611 alSetError(AL_INVALID_ENUM);
612 break;
615 else
617 alSetError(AL_INVALID_NAME);
620 ProcessContext(pContext);
624 ALAPI void ALAPIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
626 ALCcontext *pContext;
628 (void)flValue1;
629 (void)flValue2;
630 (void)flValue3;
632 pContext = alcGetCurrentContext();
633 SuspendContext(pContext);
635 if (alIsBuffer(buffer) && (buffer != 0))
637 switch(eParam)
639 default:
640 alSetError(AL_INVALID_ENUM);
641 break;
644 else
646 alSetError(AL_INVALID_NAME);
649 ProcessContext(pContext);
653 ALAPI void ALAPIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues)
655 ALCcontext *pContext;
657 (void)flValues;
659 pContext = alcGetCurrentContext();
660 SuspendContext(pContext);
662 if (alIsBuffer(buffer) && (buffer != 0))
664 switch(eParam)
666 default:
667 alSetError(AL_INVALID_ENUM);
668 break;
671 else
673 alSetError(AL_INVALID_NAME);
676 ProcessContext(pContext);
680 ALAPI void ALAPIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
682 ALCcontext *pContext;
684 (void)lValue;
686 pContext = alcGetCurrentContext();
687 SuspendContext(pContext);
689 if (alIsBuffer(buffer) && (buffer != 0))
691 switch(eParam)
693 default:
694 alSetError(AL_INVALID_ENUM);
695 break;
698 else
700 alSetError(AL_INVALID_NAME);
703 ProcessContext(pContext);
707 ALAPI void ALAPIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
709 ALCcontext *pContext;
711 (void)lValue1;
712 (void)lValue2;
713 (void)lValue3;
715 pContext = alcGetCurrentContext();
716 SuspendContext(pContext);
718 if (alIsBuffer(buffer) && (buffer != 0))
720 switch(eParam)
722 default:
723 alSetError(AL_INVALID_ENUM);
724 break;
727 else
729 alSetError(AL_INVALID_NAME);
732 ProcessContext(pContext);
736 ALAPI void ALAPIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues)
738 ALCcontext *pContext;
740 (void)plValues;
742 pContext = alcGetCurrentContext();
743 SuspendContext(pContext);
745 if (alIsBuffer(buffer) && (buffer != 0))
747 switch(eParam)
749 default:
750 alSetError(AL_INVALID_ENUM);
751 break;
754 else
756 alSetError(AL_INVALID_NAME);
759 ProcessContext(pContext);
763 ALAPI ALvoid ALAPIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue)
765 ALCcontext *pContext;
767 pContext = alcGetCurrentContext();
768 SuspendContext(pContext);
770 if (pflValue)
772 if (alIsBuffer(buffer) && (buffer != 0))
774 switch(eParam)
776 default:
777 alSetError(AL_INVALID_ENUM);
778 break;
781 else
783 alSetError(AL_INVALID_NAME);
786 else
788 alSetError(AL_INVALID_VALUE);
791 ProcessContext(pContext);
795 ALAPI void ALAPIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3)
797 ALCcontext *pContext;
799 pContext = alcGetCurrentContext();
800 SuspendContext(pContext);
802 if ((pflValue1) && (pflValue2) && (pflValue3))
804 if (alIsBuffer(buffer) && (buffer != 0))
806 switch(eParam)
808 default:
809 alSetError(AL_INVALID_ENUM);
810 break;
813 else
815 alSetError(AL_INVALID_NAME);
818 else
820 alSetError(AL_INVALID_VALUE);
823 ProcessContext(pContext);
827 ALAPI void ALAPIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues)
829 ALCcontext *pContext;
831 pContext = alcGetCurrentContext();
832 SuspendContext(pContext);
834 if (pflValues)
836 if (alIsBuffer(buffer) && (buffer != 0))
838 switch(eParam)
840 default:
841 alSetError(AL_INVALID_ENUM);
842 break;
845 else
847 alSetError(AL_INVALID_NAME);
850 else
852 alSetError(AL_INVALID_VALUE);
855 ProcessContext(pContext);
859 ALAPI ALvoid ALAPIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue)
861 ALCcontext *pContext;
862 ALbuffer *pBuffer;
864 pContext = alcGetCurrentContext();
865 SuspendContext(pContext);
867 if (plValue)
869 if (alIsBuffer(buffer) && (buffer != 0))
871 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
873 switch (eParam)
875 case AL_FREQUENCY:
876 *plValue = pBuffer->frequency;
877 break;
879 case AL_BITS:
880 *plValue = aluBytesFromFormat(pBuffer->format) * 8;
881 break;
883 case AL_CHANNELS:
884 *plValue = aluChannelsFromFormat(pBuffer->format);
885 break;
887 case AL_SIZE:
888 *plValue = pBuffer->size;
889 break;
891 default:
892 alSetError(AL_INVALID_ENUM);
893 break;
896 else
898 alSetError(AL_INVALID_NAME);
901 else
903 alSetError(AL_INVALID_VALUE);
906 ProcessContext(pContext);
910 ALAPI void ALAPIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3)
912 ALCcontext *pContext;
914 pContext = alcGetCurrentContext();
915 SuspendContext(pContext);
917 if ((plValue1) && (plValue2) && (plValue3))
919 if (alIsBuffer(buffer) && (buffer != 0))
921 switch(eParam)
923 default:
924 alSetError(AL_INVALID_ENUM);
925 break;
928 else
930 alSetError(AL_INVALID_NAME);
933 else
935 alSetError(AL_INVALID_VALUE);
938 ProcessContext(pContext);
942 ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues)
944 ALCcontext *pContext;
946 pContext = alcGetCurrentContext();
947 SuspendContext(pContext);
949 if (plValues)
951 if (alIsBuffer(buffer) && (buffer != 0))
953 switch (eParam)
955 case AL_FREQUENCY:
956 case AL_BITS:
957 case AL_CHANNELS:
958 case AL_SIZE:
959 alGetBufferi(buffer, eParam, plValues);
960 break;
962 default:
963 alSetError(AL_INVALID_ENUM);
964 break;
967 else
969 alSetError(AL_INVALID_NAME);
972 else
974 alSetError(AL_INVALID_VALUE);
977 ProcessContext(pContext);
981 * LoadData
983 * Loads the specified data into the buffer, using the specified formats.
984 * Currently, the new format must be 16-bit, and must have the same channel
985 * configuration as the original format. This does NOT handle compressed
986 * formats (eg. IMA4).
988 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
990 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
991 ALuint OrigBytes = aluBytesFromFormat(OrigFormat);
992 ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
993 ALsizei i;
995 assert(aluBytesFromFormat(NewFormat) == 2);
996 assert(NewChannels == OrigChannels);
998 if ((size%(OrigBytes*OrigChannels)) != 0)
1000 alSetError(AL_INVALID_VALUE);
1001 return;
1004 switch(OrigBytes)
1006 case 1:
1007 size /= sizeof(ALubyte);
1009 // 8bit Samples are converted to 16 bit here
1010 // Allocate 8 extra samples
1011 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
1012 if (ALBuf->data)
1014 for (i = 0;i < size;i++)
1015 ALBuf->data[i] = (ALshort)((data[i]-128) << 8);
1016 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
1018 ALBuf->format = NewFormat;
1019 ALBuf->eOriginalFormat = OrigFormat;
1020 ALBuf->size = size*1*sizeof(ALshort);
1021 ALBuf->frequency = freq;
1023 else
1024 alSetError(AL_OUT_OF_MEMORY);
1025 break;
1027 case 2:
1028 size /= sizeof(ALshort);
1030 // Allocate 8 extra samples
1031 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
1032 if (ALBuf->data)
1034 memcpy(ALBuf->data, data, size*1*sizeof(ALshort));
1035 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
1037 ALBuf->format = NewFormat;
1038 ALBuf->eOriginalFormat = OrigFormat;
1039 ALBuf->size = size*1*sizeof(ALshort);
1040 ALBuf->frequency = freq;
1042 else
1043 alSetError(AL_OUT_OF_MEMORY);
1044 break;
1046 case 4:
1047 size /= sizeof(ALfloat);
1049 // Allocate 8 extra samples
1050 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
1051 if (ALBuf->data)
1053 for (i = 0;i < size;i++)
1054 ALBuf->data[i] = (ALshort)(((ALfloat*)data)[i] * 32767.5f - 0.5);
1055 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
1057 ALBuf->format = NewFormat;
1058 ALBuf->eOriginalFormat = OrigFormat;
1059 ALBuf->size = size*1*sizeof(ALshort);
1060 ALBuf->frequency = freq;
1062 else
1063 alSetError(AL_OUT_OF_MEMORY);
1064 break;
1066 default:
1067 assert(0);
1073 * ReleaseALBuffers()
1075 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
1077 ALvoid ReleaseALBuffers(ALvoid)
1079 ALbuffer *ALBuffer;
1080 ALbuffer *ALBufferTemp;
1082 #ifdef _DEBUG
1083 if(g_uiBufferCount > 0)
1084 AL_PRINT("exit() %d Buffer(s) NOT deleted\n", g_uiBufferCount);
1085 #endif
1087 ALBuffer = g_pBuffers;
1088 while(ALBuffer)
1090 // Release sample data
1091 free(ALBuffer->data);
1093 // Release Buffer structure
1094 ALBufferTemp = ALBuffer;
1095 ALBuffer = ALBuffer->next;
1096 memset(ALBufferTemp, 0, sizeof(ALbuffer));
1097 free(ALBufferTemp);
1099 g_pBuffers = NULL;
1100 g_uiBufferCount = 0;