Disable fast float-to-int hack.
[openal-soft.git] / OpenAL32 / alBuffer.c
blob2bcb6562709f8b15253947b27f263e665ebb0955
1 /**
2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2007 by authors.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
21 #define _CRT_SECURE_NO_DEPRECATE // get rid of sprintf security warnings on VS2005
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include "alMain.h"
26 #include "AL/al.h"
27 #include "AL/alc.h"
28 #include "alError.h"
29 #include "alBuffer.h"
30 #include "alThunk.h"
33 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat);
36 * AL Buffer Functions
38 * AL Buffers are shared amoung Contexts, so we store the list of generated Buffers
39 * as a global variable in this module. (A valid context is not required to make
40 * AL Buffer function calls
45 * Global Variables
48 static ALbuffer *g_pBuffers = NULL; // Linked List of Buffers
49 static ALuint g_uiBufferCount = 0; // Buffer Count
51 static const long g_IMAStep_size[89]={ // IMA ADPCM Stepsize table
52 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
53 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
54 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
55 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
56 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493,10442,11487,12635,13899,
57 15289,16818,18500,20350,22358,24633,27086,29794,32767
60 static const long g_IMACodeword_4[16]={ // IMA4 ADPCM Codeword decode table
61 1, 3, 5, 7, 9, 11, 13, 15,
62 -1,-3,-5,-7,-9,-11,-13,-15,
65 static const long g_IMAIndex_adjust_4[16]={ // IMA4 ADPCM Step index adjust decode table
66 -1,-1,-1,-1, 2, 4, 6, 8,
67 -1,-1,-1,-1, 2, 4, 6, 8
71 * alGenBuffers(ALsizei n, ALuint *puiBuffers)
73 * Generates n AL Buffers, and stores the Buffers Names in the array pointed to by puiBuffers
75 ALAPI ALvoid ALAPIENTRY alGenBuffers(ALsizei n,ALuint *puiBuffers)
77 ALCcontext *Context;
78 ALsizei i=0;
80 Context = alcGetCurrentContext();
81 SuspendContext(Context);
83 // Check that we are actually generation some Buffers
84 if (n > 0)
86 // Check the pointer is valid (and points to enough memory to store Buffer Names)
87 if (!IsBadWritePtr((void*)puiBuffers, n * sizeof(ALuint)))
89 ALbuffer **list = &g_pBuffers;
90 while(*list)
91 list = &(*list)->next;
93 // Create all the new Buffers
94 while(i < n)
96 *list = calloc(1, sizeof(ALbuffer));
97 if(*list)
99 puiBuffers[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
100 (*list)->state = UNUSED;
101 g_uiBufferCount++;
102 i++;
104 list = &(*list)->next;
108 // If we didn't create all the Buffers, we must have run out of memory
109 if (i != n)
110 alSetError(AL_OUT_OF_MEMORY);
112 else
114 // Pointer does not point to enough memory to write Buffer names
115 alSetError(AL_INVALID_VALUE);
119 ProcessContext(Context);
121 return;
125 * alDeleteBuffers(ALsizei n, ALuint *puiBuffers)
127 * Deletes the n AL Buffers pointed to by puiBuffers
129 ALAPI ALvoid ALAPIENTRY alDeleteBuffers(ALsizei n, const ALuint *puiBuffers)
131 ALCcontext *Context;
132 ALbuffer *ALBuf;
133 ALsizei i;
134 ALboolean bFailed = AL_FALSE;
136 Context = alcGetCurrentContext();
137 SuspendContext(Context);
139 // Check we are actually Deleting some Buffers
140 if (n >= 0)
142 if ((ALuint)n <= g_uiBufferCount)
144 // Check that all the buffers are valid and can actually be deleted
145 for (i = 0; i < n; i++)
147 // Check for valid Buffer ID (can be NULL buffer)
148 if (alIsBuffer(puiBuffers[i]))
150 // If not the NULL buffer, check that the reference count is 0
151 ALBuf = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
152 if (ALBuf)
154 if (ALBuf->refcount != 0)
156 // Buffer still in use, cannot be deleted
157 alSetError(AL_INVALID_OPERATION);
158 bFailed = AL_TRUE;
162 else
164 // Invalid Buffer
165 alSetError(AL_INVALID_NAME);
166 bFailed = AL_TRUE;
170 // If all the Buffers were valid (and have Reference Counts of 0), then we can delete them
171 if (!bFailed)
173 for (i = 0; i < n; i++)
175 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
176 if (ALBuf)
178 ALbuffer **list = &g_pBuffers;
179 while(*list && *list != ALBuf)
180 list = &(*list)->next;
182 if(*list)
183 *list = (*list)->next;
185 // Release the memory used to store audio data
186 free(ALBuf->data);
188 // Release buffer structure
189 ALTHUNK_REMOVEENTRY(puiBuffers[i]);
190 memset(ALBuf, 0, sizeof(ALbuffer));
191 g_uiBufferCount--;
192 free(ALBuf);
197 else
198 alSetError(AL_INVALID_NAME);
200 else
201 alSetError(AL_INVALID_VALUE);
203 ProcessContext(Context);
205 return;
210 * alIsBuffer(ALuint uiBuffer)
212 * Checks if ulBuffer is a valid Buffer Name
214 ALAPI ALboolean ALAPIENTRY alIsBuffer(ALuint uiBuffer)
216 ALCcontext *Context;
217 ALboolean result=AL_FALSE;
218 ALbuffer *ALBuf;
219 ALbuffer *TgtALBuf;
221 Context = alcGetCurrentContext();
222 SuspendContext(Context);
224 if (uiBuffer)
226 TgtALBuf = (ALbuffer *)ALTHUNK_LOOKUPENTRY(uiBuffer);
228 // Check through list of generated buffers for uiBuffer
229 ALBuf = g_pBuffers;
230 while (ALBuf)
232 if (ALBuf == TgtALBuf)
234 result = AL_TRUE;
235 break;
238 ALBuf = ALBuf->next;
241 else
243 result = AL_TRUE;
247 ProcessContext(Context);
249 return result;
253 * alBufferData(ALuint buffer,ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
255 * Fill buffer with audio data
257 ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq)
259 ALuint *IMAData,IMACode;
260 ALCcontext *Context;
261 ALint Sample,Index;
262 ALint LeftSample,LeftIndex;
263 ALint RightSample,RightIndex;
264 ALuint LeftIMACode,RightIMACode;
265 ALbuffer *ALBuf;
266 ALsizei i,j,k;
268 Context = alcGetCurrentContext();
269 SuspendContext(Context);
271 if (alIsBuffer(buffer) && (buffer != 0))
273 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
274 if ((ALBuf->refcount==0)&&(data))
276 switch(format)
278 case AL_FORMAT_MONO8:
279 case AL_FORMAT_MONO16:
280 case AL_FORMAT_MONO_FLOAT32:
281 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO16);
282 break;
284 case AL_FORMAT_STEREO8:
285 case AL_FORMAT_STEREO16:
286 case AL_FORMAT_STEREO_FLOAT32:
287 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO16);
288 break;
290 case AL_FORMAT_REAR8:
291 case AL_FORMAT_REAR16:
292 case AL_FORMAT_REAR32: {
293 ALuint NewFormat = AL_FORMAT_QUAD16;
294 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
295 ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
296 ((format==AL_FORMAT_REAR16) ? 2 :
297 4));
298 ALsizei i;
300 assert(aluBytesFromFormat(NewFormat) == 2);
302 if ((size%(OrigBytes*2)) != 0)
304 alSetError(AL_INVALID_VALUE);
305 break;
308 switch(OrigBytes)
310 case 1:
311 size /= sizeof(ALubyte);
312 size *= 2;
314 // 8bit Samples are converted to 16 bit here
315 // Allocate 8 extra samples
316 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
317 if (ALBuf->data)
319 for (i = 0;i < size;i+=4)
321 ALBuf->data[i+0] = 0;
322 ALBuf->data[i+1] = 0;
323 ALBuf->data[i+2] = (ALshort)((((ALubyte*)data)[i/2+0]-128) << 8);
324 ALBuf->data[i+3] = (ALshort)((((ALubyte*)data)[i/2+1]-128) << 8);
326 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
328 ALBuf->format = NewFormat;
329 ALBuf->eOriginalFormat = format;
330 ALBuf->size = size*1*sizeof(ALshort);
331 ALBuf->frequency = freq;
333 else
334 alSetError(AL_OUT_OF_MEMORY);
335 break;
337 case 2:
338 size /= sizeof(ALshort);
339 size *= 2;
341 // Allocate 8 extra samples
342 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
343 if (ALBuf->data)
345 for (i = 0;i < size;i+=4)
347 ALBuf->data[i+0] = 0;
348 ALBuf->data[i+1] = 0;
349 ALBuf->data[i+2] = ((ALshort*)data)[i/2+0];
350 ALBuf->data[i+3] = ((ALshort*)data)[i/2+1];
352 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
354 ALBuf->format = NewFormat;
355 ALBuf->eOriginalFormat = format;
356 ALBuf->size = size*1*sizeof(ALshort);
357 ALBuf->frequency = freq;
359 else
360 alSetError(AL_OUT_OF_MEMORY);
361 break;
363 case 4:
364 size /= sizeof(ALfloat);
365 size *= 2;
367 // Allocate 8 extra samples
368 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
369 if (ALBuf->data)
371 for (i = 0;i < size;i+=4)
373 ALBuf->data[i+0] = 0;
374 ALBuf->data[i+1] = 0;
375 ALBuf->data[i+2] = (ALshort)(((ALfloat*)data)[i/2+0] * 32767.5f - 0.5);
376 ALBuf->data[i+3] = (ALshort)(((ALfloat*)data)[i/2+1] * 32767.5f - 0.5);
378 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
380 ALBuf->format = NewFormat;
381 ALBuf->eOriginalFormat = format;
382 ALBuf->size = size*1*sizeof(ALshort);
383 ALBuf->frequency = freq;
385 else
386 alSetError(AL_OUT_OF_MEMORY);
387 break;
389 default:
390 assert(0);
392 } break;
394 case AL_FORMAT_QUAD8:
395 case AL_FORMAT_QUAD16:
396 case AL_FORMAT_QUAD32:
397 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD16);
398 break;
400 case AL_FORMAT_51CHN8:
401 case AL_FORMAT_51CHN16:
402 case AL_FORMAT_51CHN32:
403 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN16);
404 break;
406 case AL_FORMAT_61CHN8:
407 case AL_FORMAT_61CHN16:
408 case AL_FORMAT_61CHN32:
409 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN16);
410 break;
412 case AL_FORMAT_71CHN8:
413 case AL_FORMAT_71CHN16:
414 case AL_FORMAT_71CHN32:
415 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN16);
416 break;
418 case AL_FORMAT_MONO_IMA4:
419 // Here is where things vary:
420 // nVidia and Apple use 64+1 samples per block => block_size=36 bytes
421 // Most PC sound software uses 2040+1 samples per block -> block_size=1024 bytes
422 if ((size%36) == 0)
424 // Allocate 8 extra samples (16 bytes)
425 ALBuf->data=realloc(ALBuf->data,16+(size/36)*(65*sizeof(ALshort)));
426 if (ALBuf->data)
428 ALBuf->format = AL_FORMAT_MONO16;
429 ALBuf->eOriginalFormat = AL_FORMAT_MONO_IMA4;
430 IMAData=(ALuint *)data;
431 for (i=0;i<size/36;i++)
433 Sample=((ALshort *)IMAData)[0];
434 Index=((ALshort *)IMAData)[1];
436 Index=Index<0?0:Index;
437 Index=Index>88?88:Index;
439 ALBuf->data[i*65]=(short)Sample;
441 IMAData++;
443 for (j=1;j<65;j+=8)
445 IMACode=*IMAData;
446 for (k=0;k<8;k+=2)
448 Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8);
449 Index+=g_IMAIndex_adjust_4[IMACode&15];
450 if (Sample<-32768) Sample=-32768;
451 else if (Sample>32767) Sample=32767;
452 if (Index<0) Index=0;
453 else if (Index>88) Index=88;
454 ALBuf->data[i*65+j+k]=(short)Sample;
455 IMACode>>=4;
457 Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8);
458 Index+=g_IMAIndex_adjust_4[IMACode&15];
459 if (Sample<-32768) Sample=-32768;
460 else if (Sample>32767) Sample=32767;
461 if (Index<0) Index=0;
462 else if (Index>88) Index=88;
463 ALBuf->data[i*65+j+k+1]=(short)Sample;
464 IMACode>>=4;
466 IMAData++;
469 memset(&(ALBuf->data[(size/36*65)]), 0, 16);
470 ALBuf->size=size/36*65*sizeof(ALshort);
471 ALBuf->frequency=freq;
473 else
474 alSetError(AL_OUT_OF_MEMORY);
476 else
477 alSetError(AL_INVALID_VALUE);
478 break;
480 case AL_FORMAT_STEREO_IMA4:
481 // Here is where things vary:
482 // nVidia and Apple use 64+1 samples per channel per block => block_size=72 bytes
483 // Most PC sound software uses 2040+1 samples per channel per block -> block_size=2048 bytes
484 if ((size%72) == 0)
486 // Allocate 8 extra samples (32 bytes)
487 ALBuf->data=realloc(ALBuf->data,32+(size/72)*(2*65*sizeof(ALshort)));
488 if (ALBuf->data)
490 ALBuf->format = AL_FORMAT_STEREO16;
491 ALBuf->eOriginalFormat = AL_FORMAT_STEREO_IMA4;
492 IMAData=(ALuint *)data;
493 for (i=0;i<size/72;i++)
495 LeftSample=((ALshort *)IMAData)[0];
496 LeftIndex=((ALshort *)IMAData)[1];
498 LeftIndex=LeftIndex<0?0:LeftIndex;
499 LeftIndex=LeftIndex>88?88:LeftIndex;
501 ALBuf->data[i*2*65]=(short)LeftSample;
503 IMAData++;
505 RightSample=((ALshort *)IMAData)[0];
506 RightIndex=((ALshort *)IMAData)[1];
508 RightIndex=RightIndex<0?0:RightIndex;
509 RightIndex=RightIndex>88?88:RightIndex;
511 ALBuf->data[i*2*65+1]=(short)RightSample;
513 IMAData++;
515 for (j=2;j<130;j+=16)
517 LeftIMACode=IMAData[0];
518 RightIMACode=IMAData[1];
519 for (k=0;k<16;k+=4)
521 LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
522 LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15];
523 if (LeftSample<-32768) LeftSample=-32768;
524 else if (LeftSample>32767) LeftSample=32767;
525 if (LeftIndex<0) LeftIndex=0;
526 else if (LeftIndex>88) LeftIndex=88;
527 ALBuf->data[i*2*65+j+k]=(short)LeftSample;
528 LeftIMACode>>=4;
530 RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
531 RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
532 if (RightSample<-32768) RightSample=-32768;
533 else if (RightSample>32767) RightSample=32767;
534 if (RightIndex<0) RightIndex=0;
535 else if (RightIndex>88) RightIndex=88;
536 ALBuf->data[i*2*65+j+k+1]=(short)RightSample;
537 RightIMACode>>=4;
539 LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
540 LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15];
541 if (LeftSample<-32768) LeftSample=-32768;
542 else if (LeftSample>32767) LeftSample=32767;
543 if (LeftIndex<0) LeftIndex=0;
544 else if (LeftIndex>88) LeftIndex=88;
545 ALBuf->data[i*2*65+j+k+2]=(short)LeftSample;
546 LeftIMACode>>=4;
548 RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
549 RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
550 if (RightSample<-32768) RightSample=-32768;
551 else if (RightSample>32767) RightSample=32767;
552 if (RightIndex<0) RightIndex=0;
553 else if (RightIndex>88) RightIndex=88;
554 ALBuf->data[i*2*65+j+k+3]=(short)RightSample;
555 RightIMACode>>=4;
557 IMAData+=2;
560 memset(&(ALBuf->data[(size/72*2*65)]), 0, 32);
561 ALBuf->size=size/72*2*65*sizeof(ALshort);
562 ALBuf->frequency=freq;
564 else
565 alSetError(AL_OUT_OF_MEMORY);
567 else
568 alSetError(AL_INVALID_VALUE);
569 break;
571 default:
572 alSetError(AL_INVALID_ENUM);
573 break;
576 else
578 // Buffer is in use, or data is a NULL pointer
579 alSetError(AL_INVALID_VALUE);
582 else
584 // Invalid Buffer Name
585 alSetError(AL_INVALID_NAME);
588 ProcessContext(Context);
592 ALAPI void ALAPIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
594 ALCcontext *pContext;
596 (void)flValue;
598 pContext = alcGetCurrentContext();
599 SuspendContext(pContext);
601 if (alIsBuffer(buffer) && (buffer != 0))
603 switch(eParam)
605 default:
606 alSetError(AL_INVALID_ENUM);
607 break;
610 else
612 alSetError(AL_INVALID_NAME);
615 ProcessContext(pContext);
619 ALAPI void ALAPIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
621 ALCcontext *pContext;
623 (void)flValue1;
624 (void)flValue2;
625 (void)flValue3;
627 pContext = alcGetCurrentContext();
628 SuspendContext(pContext);
630 if (alIsBuffer(buffer) && (buffer != 0))
632 switch(eParam)
634 default:
635 alSetError(AL_INVALID_ENUM);
636 break;
639 else
641 alSetError(AL_INVALID_NAME);
644 ProcessContext(pContext);
648 ALAPI void ALAPIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues)
650 ALCcontext *pContext;
652 (void)flValues;
654 pContext = alcGetCurrentContext();
655 SuspendContext(pContext);
657 if (alIsBuffer(buffer) && (buffer != 0))
659 switch(eParam)
661 default:
662 alSetError(AL_INVALID_ENUM);
663 break;
666 else
668 alSetError(AL_INVALID_NAME);
671 ProcessContext(pContext);
675 ALAPI void ALAPIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
677 ALCcontext *pContext;
679 (void)lValue;
681 pContext = alcGetCurrentContext();
682 SuspendContext(pContext);
684 if (alIsBuffer(buffer) && (buffer != 0))
686 switch(eParam)
688 default:
689 alSetError(AL_INVALID_ENUM);
690 break;
693 else
695 alSetError(AL_INVALID_NAME);
698 ProcessContext(pContext);
702 ALAPI void ALAPIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
704 ALCcontext *pContext;
706 (void)lValue1;
707 (void)lValue2;
708 (void)lValue3;
710 pContext = alcGetCurrentContext();
711 SuspendContext(pContext);
713 if (alIsBuffer(buffer) && (buffer != 0))
715 switch(eParam)
717 default:
718 alSetError(AL_INVALID_ENUM);
719 break;
722 else
724 alSetError(AL_INVALID_NAME);
727 ProcessContext(pContext);
731 ALAPI void ALAPIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues)
733 ALCcontext *pContext;
735 (void)plValues;
737 pContext = alcGetCurrentContext();
738 SuspendContext(pContext);
740 if (alIsBuffer(buffer) && (buffer != 0))
742 switch(eParam)
744 default:
745 alSetError(AL_INVALID_ENUM);
746 break;
749 else
751 alSetError(AL_INVALID_NAME);
754 ProcessContext(pContext);
758 ALAPI ALvoid ALAPIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue)
760 ALCcontext *pContext;
762 pContext = alcGetCurrentContext();
763 SuspendContext(pContext);
765 if (pflValue)
767 if (alIsBuffer(buffer) && (buffer != 0))
769 switch(eParam)
771 default:
772 alSetError(AL_INVALID_ENUM);
773 break;
776 else
778 alSetError(AL_INVALID_NAME);
781 else
783 alSetError(AL_INVALID_VALUE);
786 ProcessContext(pContext);
790 ALAPI void ALAPIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3)
792 ALCcontext *pContext;
794 pContext = alcGetCurrentContext();
795 SuspendContext(pContext);
797 if ((pflValue1) && (pflValue2) && (pflValue3))
799 if (alIsBuffer(buffer) && (buffer != 0))
801 switch(eParam)
803 default:
804 alSetError(AL_INVALID_ENUM);
805 break;
808 else
810 alSetError(AL_INVALID_NAME);
813 else
815 alSetError(AL_INVALID_VALUE);
818 ProcessContext(pContext);
822 ALAPI void ALAPIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues)
824 ALCcontext *pContext;
826 pContext = alcGetCurrentContext();
827 SuspendContext(pContext);
829 if (pflValues)
831 if (alIsBuffer(buffer) && (buffer != 0))
833 switch(eParam)
835 default:
836 alSetError(AL_INVALID_ENUM);
837 break;
840 else
842 alSetError(AL_INVALID_NAME);
845 else
847 alSetError(AL_INVALID_VALUE);
850 ProcessContext(pContext);
854 ALAPI ALvoid ALAPIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue)
856 ALCcontext *pContext;
857 ALbuffer *pBuffer;
859 pContext = alcGetCurrentContext();
860 SuspendContext(pContext);
862 if (plValue)
864 if (alIsBuffer(buffer) && (buffer != 0))
866 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
868 switch (eParam)
870 case AL_FREQUENCY:
871 *plValue = pBuffer->frequency;
872 break;
874 case AL_BITS:
875 *plValue = aluBytesFromFormat(pBuffer->format) * 8;
876 break;
878 case AL_CHANNELS:
879 *plValue = aluChannelsFromFormat(pBuffer->format);
880 break;
882 case AL_SIZE:
883 *plValue = pBuffer->size;
884 break;
886 default:
887 alSetError(AL_INVALID_ENUM);
888 break;
891 else
893 alSetError(AL_INVALID_NAME);
896 else
898 alSetError(AL_INVALID_VALUE);
901 ProcessContext(pContext);
905 ALAPI void ALAPIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3)
907 ALCcontext *pContext;
909 pContext = alcGetCurrentContext();
910 SuspendContext(pContext);
912 if ((plValue1) && (plValue2) && (plValue3))
914 if (alIsBuffer(buffer) && (buffer != 0))
916 switch(eParam)
918 default:
919 alSetError(AL_INVALID_ENUM);
920 break;
923 else
925 alSetError(AL_INVALID_NAME);
928 else
930 alSetError(AL_INVALID_VALUE);
933 ProcessContext(pContext);
937 ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues)
939 ALCcontext *pContext;
941 pContext = alcGetCurrentContext();
942 SuspendContext(pContext);
944 if (plValues)
946 if (alIsBuffer(buffer) && (buffer != 0))
948 switch (eParam)
950 case AL_FREQUENCY:
951 case AL_BITS:
952 case AL_CHANNELS:
953 case AL_SIZE:
954 alGetBufferi(buffer, eParam, plValues);
955 break;
957 default:
958 alSetError(AL_INVALID_ENUM);
959 break;
962 else
964 alSetError(AL_INVALID_NAME);
967 else
969 alSetError(AL_INVALID_VALUE);
972 ProcessContext(pContext);
976 * LoadData
978 * Loads the specified data into the buffer, using the specified formats.
979 * Currently, the new format must be 16-bit, and must have the same channel
980 * configuration as the original format. This does NOT handle compressed
981 * formats (eg. IMA4).
983 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
985 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
986 ALuint OrigBytes = aluBytesFromFormat(OrigFormat);
987 ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
988 ALsizei i;
990 assert(aluBytesFromFormat(NewFormat) == 2);
991 assert(NewChannels == OrigChannels);
993 if ((size%(OrigBytes*OrigChannels)) != 0)
995 alSetError(AL_INVALID_VALUE);
996 return;
999 switch(OrigBytes)
1001 case 1:
1002 size /= sizeof(ALubyte);
1004 // 8bit Samples are converted to 16 bit here
1005 // Allocate 8 extra samples
1006 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
1007 if (ALBuf->data)
1009 for (i = 0;i < size;i++)
1010 ALBuf->data[i] = (ALshort)((data[i]-128) << 8);
1011 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
1013 ALBuf->format = NewFormat;
1014 ALBuf->eOriginalFormat = OrigFormat;
1015 ALBuf->size = size*1*sizeof(ALshort);
1016 ALBuf->frequency = freq;
1018 else
1019 alSetError(AL_OUT_OF_MEMORY);
1020 break;
1022 case 2:
1023 size /= sizeof(ALshort);
1025 // Allocate 8 extra samples
1026 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
1027 if (ALBuf->data)
1029 memcpy(ALBuf->data, data, size*1*sizeof(ALshort));
1030 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
1032 ALBuf->format = NewFormat;
1033 ALBuf->eOriginalFormat = OrigFormat;
1034 ALBuf->size = size*1*sizeof(ALshort);
1035 ALBuf->frequency = freq;
1037 else
1038 alSetError(AL_OUT_OF_MEMORY);
1039 break;
1041 case 4:
1042 size /= sizeof(ALfloat);
1044 // Allocate 8 extra samples
1045 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
1046 if (ALBuf->data)
1048 for (i = 0;i < size;i++)
1049 ALBuf->data[i] = (ALshort)(((ALfloat*)data)[i] * 32767.5f - 0.5);
1050 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
1052 ALBuf->format = NewFormat;
1053 ALBuf->eOriginalFormat = OrigFormat;
1054 ALBuf->size = size*1*sizeof(ALshort);
1055 ALBuf->frequency = freq;
1057 else
1058 alSetError(AL_OUT_OF_MEMORY);
1059 break;
1061 default:
1062 assert(0);
1068 * ReleaseALBuffers()
1070 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
1072 ALvoid ReleaseALBuffers(ALvoid)
1074 ALbuffer *ALBuffer;
1075 ALbuffer *ALBufferTemp;
1077 #ifdef _DEBUG
1078 if(g_uiBufferCount > 0)
1079 AL_PRINT("exit() %d Buffer(s) NOT deleted\n", g_uiBufferCount);
1080 #endif
1082 ALBuffer = g_pBuffers;
1083 while(ALBuffer)
1085 // Release sample data
1086 free(ALBuffer->data);
1088 // Release Buffer structure
1089 ALBufferTemp = ALBuffer;
1090 ALBuffer = ALBuffer->next;
1091 memset(ALBufferTemp, 0, sizeof(ALbuffer));
1092 free(ALBufferTemp);
1094 g_pBuffers = NULL;
1095 g_uiBufferCount = 0;