Reorder setting of some variables
[openal-soft.git] / OpenAL32 / alBuffer.c
blob1ea54fce200903894085ef586c2850cfcb578b5c
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 puiBuffers[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
101 (*list)->state = UNUSED;
102 g_uiBufferCount++;
103 i++;
105 list = &(*list)->next;
109 // If we didn't create all the Buffers, we must have run out of memory
110 if (i != n)
111 alSetError(AL_OUT_OF_MEMORY);
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:
396 case AL_FORMAT_QUAD16:
397 case AL_FORMAT_QUAD32:
398 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD16);
399 break;
401 case AL_FORMAT_51CHN8:
402 case AL_FORMAT_51CHN16:
403 case AL_FORMAT_51CHN32:
404 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN16);
405 break;
407 case AL_FORMAT_61CHN8:
408 case AL_FORMAT_61CHN16:
409 case AL_FORMAT_61CHN32:
410 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN16);
411 break;
413 case AL_FORMAT_71CHN8:
414 case AL_FORMAT_71CHN16:
415 case AL_FORMAT_71CHN32:
416 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN16);
417 break;
419 case AL_FORMAT_MONO_IMA4:
420 // Here is where things vary:
421 // nVidia and Apple use 64+1 samples per block => block_size=36 bytes
422 // Most PC sound software uses 2040+1 samples per block -> block_size=1024 bytes
423 if ((size%36) == 0)
425 // Allocate 8 extra samples (16 bytes)
426 ALBuf->data=realloc(ALBuf->data,16+(size/36)*(65*sizeof(ALshort)));
427 if (ALBuf->data)
429 ALBuf->format = AL_FORMAT_MONO16;
430 ALBuf->eOriginalFormat = AL_FORMAT_MONO_IMA4;
431 IMAData=(ALuint *)data;
432 for (i=0;i<size/36;i++)
434 Sample=((ALshort *)IMAData)[0];
435 Index=((ALshort *)IMAData)[1];
437 Index=Index<0?0:Index;
438 Index=Index>88?88:Index;
440 ALBuf->data[i*65]=(short)Sample;
442 IMAData++;
444 for (j=1;j<65;j+=8)
446 IMACode=*IMAData;
447 for (k=0;k<8;k+=2)
449 Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8);
450 Index+=g_IMAIndex_adjust_4[IMACode&15];
451 if (Sample<-32768) Sample=-32768;
452 else if (Sample>32767) Sample=32767;
453 if (Index<0) Index=0;
454 else if (Index>88) Index=88;
455 ALBuf->data[i*65+j+k]=(short)Sample;
456 IMACode>>=4;
458 Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8);
459 Index+=g_IMAIndex_adjust_4[IMACode&15];
460 if (Sample<-32768) Sample=-32768;
461 else if (Sample>32767) Sample=32767;
462 if (Index<0) Index=0;
463 else if (Index>88) Index=88;
464 ALBuf->data[i*65+j+k+1]=(short)Sample;
465 IMACode>>=4;
467 IMAData++;
470 memset(&(ALBuf->data[(size/36*65)]), 0, 16);
471 ALBuf->size=size/36*65*sizeof(ALshort);
472 ALBuf->frequency=freq;
474 else
475 alSetError(AL_OUT_OF_MEMORY);
477 else
478 alSetError(AL_INVALID_VALUE);
479 break;
481 case AL_FORMAT_STEREO_IMA4:
482 // Here is where things vary:
483 // nVidia and Apple use 64+1 samples per channel per block => block_size=72 bytes
484 // Most PC sound software uses 2040+1 samples per channel per block -> block_size=2048 bytes
485 if ((size%72) == 0)
487 // Allocate 8 extra samples (32 bytes)
488 ALBuf->data=realloc(ALBuf->data,32+(size/72)*(2*65*sizeof(ALshort)));
489 if (ALBuf->data)
491 ALBuf->format = AL_FORMAT_STEREO16;
492 ALBuf->eOriginalFormat = AL_FORMAT_STEREO_IMA4;
493 IMAData=(ALuint *)data;
494 for (i=0;i<size/72;i++)
496 LeftSample=((ALshort *)IMAData)[0];
497 LeftIndex=((ALshort *)IMAData)[1];
499 LeftIndex=LeftIndex<0?0:LeftIndex;
500 LeftIndex=LeftIndex>88?88:LeftIndex;
502 ALBuf->data[i*2*65]=(short)LeftSample;
504 IMAData++;
506 RightSample=((ALshort *)IMAData)[0];
507 RightIndex=((ALshort *)IMAData)[1];
509 RightIndex=RightIndex<0?0:RightIndex;
510 RightIndex=RightIndex>88?88:RightIndex;
512 ALBuf->data[i*2*65+1]=(short)RightSample;
514 IMAData++;
516 for (j=2;j<130;j+=16)
518 LeftIMACode=IMAData[0];
519 RightIMACode=IMAData[1];
520 for (k=0;k<16;k+=4)
522 LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
523 LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15];
524 if (LeftSample<-32768) LeftSample=-32768;
525 else if (LeftSample>32767) LeftSample=32767;
526 if (LeftIndex<0) LeftIndex=0;
527 else if (LeftIndex>88) LeftIndex=88;
528 ALBuf->data[i*2*65+j+k]=(short)LeftSample;
529 LeftIMACode>>=4;
531 RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
532 RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
533 if (RightSample<-32768) RightSample=-32768;
534 else if (RightSample>32767) RightSample=32767;
535 if (RightIndex<0) RightIndex=0;
536 else if (RightIndex>88) RightIndex=88;
537 ALBuf->data[i*2*65+j+k+1]=(short)RightSample;
538 RightIMACode>>=4;
540 LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
541 LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15];
542 if (LeftSample<-32768) LeftSample=-32768;
543 else if (LeftSample>32767) LeftSample=32767;
544 if (LeftIndex<0) LeftIndex=0;
545 else if (LeftIndex>88) LeftIndex=88;
546 ALBuf->data[i*2*65+j+k+2]=(short)LeftSample;
547 LeftIMACode>>=4;
549 RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
550 RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
551 if (RightSample<-32768) RightSample=-32768;
552 else if (RightSample>32767) RightSample=32767;
553 if (RightIndex<0) RightIndex=0;
554 else if (RightIndex>88) RightIndex=88;
555 ALBuf->data[i*2*65+j+k+3]=(short)RightSample;
556 RightIMACode>>=4;
558 IMAData+=2;
561 memset(&(ALBuf->data[(size/72*2*65)]), 0, 32);
562 ALBuf->size=size/72*2*65*sizeof(ALshort);
563 ALBuf->frequency=freq;
565 else
566 alSetError(AL_OUT_OF_MEMORY);
568 else
569 alSetError(AL_INVALID_VALUE);
570 break;
572 default:
573 alSetError(AL_INVALID_ENUM);
574 break;
577 else
579 // Buffer is in use, or data is a NULL pointer
580 alSetError(AL_INVALID_VALUE);
583 else
585 // Invalid Buffer Name
586 alSetError(AL_INVALID_NAME);
589 ProcessContext(Context);
593 ALAPI void ALAPIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
595 ALCcontext *pContext;
597 (void)flValue;
599 pContext = alcGetCurrentContext();
600 SuspendContext(pContext);
602 if (alIsBuffer(buffer) && (buffer != 0))
604 switch(eParam)
606 default:
607 alSetError(AL_INVALID_ENUM);
608 break;
611 else
613 alSetError(AL_INVALID_NAME);
616 ProcessContext(pContext);
620 ALAPI void ALAPIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
622 ALCcontext *pContext;
624 (void)flValue1;
625 (void)flValue2;
626 (void)flValue3;
628 pContext = alcGetCurrentContext();
629 SuspendContext(pContext);
631 if (alIsBuffer(buffer) && (buffer != 0))
633 switch(eParam)
635 default:
636 alSetError(AL_INVALID_ENUM);
637 break;
640 else
642 alSetError(AL_INVALID_NAME);
645 ProcessContext(pContext);
649 ALAPI void ALAPIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues)
651 ALCcontext *pContext;
653 (void)flValues;
655 pContext = alcGetCurrentContext();
656 SuspendContext(pContext);
658 if (alIsBuffer(buffer) && (buffer != 0))
660 switch(eParam)
662 default:
663 alSetError(AL_INVALID_ENUM);
664 break;
667 else
669 alSetError(AL_INVALID_NAME);
672 ProcessContext(pContext);
676 ALAPI void ALAPIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
678 ALCcontext *pContext;
680 (void)lValue;
682 pContext = alcGetCurrentContext();
683 SuspendContext(pContext);
685 if (alIsBuffer(buffer) && (buffer != 0))
687 switch(eParam)
689 default:
690 alSetError(AL_INVALID_ENUM);
691 break;
694 else
696 alSetError(AL_INVALID_NAME);
699 ProcessContext(pContext);
703 ALAPI void ALAPIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
705 ALCcontext *pContext;
707 (void)lValue1;
708 (void)lValue2;
709 (void)lValue3;
711 pContext = alcGetCurrentContext();
712 SuspendContext(pContext);
714 if (alIsBuffer(buffer) && (buffer != 0))
716 switch(eParam)
718 default:
719 alSetError(AL_INVALID_ENUM);
720 break;
723 else
725 alSetError(AL_INVALID_NAME);
728 ProcessContext(pContext);
732 ALAPI void ALAPIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues)
734 ALCcontext *pContext;
736 (void)plValues;
738 pContext = alcGetCurrentContext();
739 SuspendContext(pContext);
741 if (alIsBuffer(buffer) && (buffer != 0))
743 switch(eParam)
745 default:
746 alSetError(AL_INVALID_ENUM);
747 break;
750 else
752 alSetError(AL_INVALID_NAME);
755 ProcessContext(pContext);
759 ALAPI ALvoid ALAPIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue)
761 ALCcontext *pContext;
763 pContext = alcGetCurrentContext();
764 SuspendContext(pContext);
766 if (pflValue)
768 if (alIsBuffer(buffer) && (buffer != 0))
770 switch(eParam)
772 default:
773 alSetError(AL_INVALID_ENUM);
774 break;
777 else
779 alSetError(AL_INVALID_NAME);
782 else
784 alSetError(AL_INVALID_VALUE);
787 ProcessContext(pContext);
791 ALAPI void ALAPIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3)
793 ALCcontext *pContext;
795 pContext = alcGetCurrentContext();
796 SuspendContext(pContext);
798 if ((pflValue1) && (pflValue2) && (pflValue3))
800 if (alIsBuffer(buffer) && (buffer != 0))
802 switch(eParam)
804 default:
805 alSetError(AL_INVALID_ENUM);
806 break;
809 else
811 alSetError(AL_INVALID_NAME);
814 else
816 alSetError(AL_INVALID_VALUE);
819 ProcessContext(pContext);
823 ALAPI void ALAPIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues)
825 ALCcontext *pContext;
827 pContext = alcGetCurrentContext();
828 SuspendContext(pContext);
830 if (pflValues)
832 if (alIsBuffer(buffer) && (buffer != 0))
834 switch(eParam)
836 default:
837 alSetError(AL_INVALID_ENUM);
838 break;
841 else
843 alSetError(AL_INVALID_NAME);
846 else
848 alSetError(AL_INVALID_VALUE);
851 ProcessContext(pContext);
855 ALAPI ALvoid ALAPIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue)
857 ALCcontext *pContext;
858 ALbuffer *pBuffer;
860 pContext = alcGetCurrentContext();
861 SuspendContext(pContext);
863 if (plValue)
865 if (alIsBuffer(buffer) && (buffer != 0))
867 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
869 switch (eParam)
871 case AL_FREQUENCY:
872 *plValue = pBuffer->frequency;
873 break;
875 case AL_BITS:
876 *plValue = aluBytesFromFormat(pBuffer->format) * 8;
877 break;
879 case AL_CHANNELS:
880 *plValue = aluChannelsFromFormat(pBuffer->format);
881 break;
883 case AL_SIZE:
884 *plValue = pBuffer->size;
885 break;
887 default:
888 alSetError(AL_INVALID_ENUM);
889 break;
892 else
894 alSetError(AL_INVALID_NAME);
897 else
899 alSetError(AL_INVALID_VALUE);
902 ProcessContext(pContext);
906 ALAPI void ALAPIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3)
908 ALCcontext *pContext;
910 pContext = alcGetCurrentContext();
911 SuspendContext(pContext);
913 if ((plValue1) && (plValue2) && (plValue3))
915 if (alIsBuffer(buffer) && (buffer != 0))
917 switch(eParam)
919 default:
920 alSetError(AL_INVALID_ENUM);
921 break;
924 else
926 alSetError(AL_INVALID_NAME);
929 else
931 alSetError(AL_INVALID_VALUE);
934 ProcessContext(pContext);
938 ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues)
940 ALCcontext *pContext;
942 pContext = alcGetCurrentContext();
943 SuspendContext(pContext);
945 if (plValues)
947 if (alIsBuffer(buffer) && (buffer != 0))
949 switch (eParam)
951 case AL_FREQUENCY:
952 case AL_BITS:
953 case AL_CHANNELS:
954 case AL_SIZE:
955 alGetBufferi(buffer, eParam, plValues);
956 break;
958 default:
959 alSetError(AL_INVALID_ENUM);
960 break;
963 else
965 alSetError(AL_INVALID_NAME);
968 else
970 alSetError(AL_INVALID_VALUE);
973 ProcessContext(pContext);
977 * LoadData
979 * Loads the specified data into the buffer, using the specified formats.
980 * Currently, the new format must be 16-bit, and must have the same channel
981 * configuration as the original format. This does NOT handle compressed
982 * formats (eg. IMA4).
984 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
986 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
987 ALuint OrigBytes = aluBytesFromFormat(OrigFormat);
988 ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
989 ALsizei i;
991 assert(aluBytesFromFormat(NewFormat) == 2);
992 assert(NewChannels == OrigChannels);
994 if ((size%(OrigBytes*OrigChannels)) != 0)
996 alSetError(AL_INVALID_VALUE);
997 return;
1000 switch(OrigBytes)
1002 case 1:
1003 size /= sizeof(ALubyte);
1005 // 8bit Samples are converted to 16 bit here
1006 // Allocate 8 extra samples
1007 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
1008 if (ALBuf->data)
1010 for (i = 0;i < size;i++)
1011 ALBuf->data[i] = (ALshort)((data[i]-128) << 8);
1012 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
1014 ALBuf->format = NewFormat;
1015 ALBuf->eOriginalFormat = OrigFormat;
1016 ALBuf->size = size*1*sizeof(ALshort);
1017 ALBuf->frequency = freq;
1019 else
1020 alSetError(AL_OUT_OF_MEMORY);
1021 break;
1023 case 2:
1024 size /= sizeof(ALshort);
1026 // Allocate 8 extra samples
1027 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
1028 if (ALBuf->data)
1030 memcpy(ALBuf->data, data, size*1*sizeof(ALshort));
1031 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
1033 ALBuf->format = NewFormat;
1034 ALBuf->eOriginalFormat = OrigFormat;
1035 ALBuf->size = size*1*sizeof(ALshort);
1036 ALBuf->frequency = freq;
1038 else
1039 alSetError(AL_OUT_OF_MEMORY);
1040 break;
1042 case 4:
1043 size /= sizeof(ALfloat);
1045 // Allocate 8 extra samples
1046 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
1047 if (ALBuf->data)
1049 for (i = 0;i < size;i++)
1050 ALBuf->data[i] = (ALshort)(((ALfloat*)data)[i] * 32767.5f - 0.5);
1051 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
1053 ALBuf->format = NewFormat;
1054 ALBuf->eOriginalFormat = OrigFormat;
1055 ALBuf->size = size*1*sizeof(ALshort);
1056 ALBuf->frequency = freq;
1058 else
1059 alSetError(AL_OUT_OF_MEMORY);
1060 break;
1062 default:
1063 assert(0);
1069 * ReleaseALBuffers()
1071 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
1073 ALvoid ReleaseALBuffers(ALvoid)
1075 ALbuffer *ALBuffer;
1076 ALbuffer *ALBufferTemp;
1078 #ifdef _DEBUG
1079 if(g_uiBufferCount > 0)
1080 AL_PRINT("exit() %d Buffer(s) NOT deleted\n", g_uiBufferCount);
1081 #endif
1083 ALBuffer = g_pBuffers;
1084 while(ALBuffer)
1086 // Release sample data
1087 free(ALBuffer->data);
1089 // Release Buffer structure
1090 ALBufferTemp = ALBuffer;
1091 ALBuffer = ALBuffer->next;
1092 memset(ALBufferTemp, 0, sizeof(ALbuffer));
1093 free(ALBufferTemp);
1095 g_pBuffers = NULL;
1096 g_uiBufferCount = 0;