Clarify implicit destruction warnings
[openal-soft/openal-hmr.git] / OpenAL32 / alBuffer.c
blob15fe4184c12dd3462e936656d1e81c465f2b80c0
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 // 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 if (puiBuffers[i] && alIsBuffer(puiBuffers[i]))
178 ALbuffer **list = &g_pBuffers;
180 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
181 while(*list && *list != ALBuf)
182 list = &(*list)->next;
184 if(*list)
185 *list = (*list)->next;
187 // Release the memory used to store audio data
188 free(ALBuf->data);
190 // Release buffer structure
191 ALTHUNK_REMOVEENTRY(puiBuffers[i]);
192 memset(ALBuf, 0, sizeof(ALbuffer));
193 g_uiBufferCount--;
194 free(ALBuf);
199 else
200 alSetError(AL_INVALID_VALUE);
202 ProcessContext(Context);
204 return;
209 * alIsBuffer(ALuint uiBuffer)
211 * Checks if ulBuffer is a valid Buffer Name
213 ALAPI ALboolean ALAPIENTRY alIsBuffer(ALuint uiBuffer)
215 ALCcontext *Context;
216 ALboolean result=AL_FALSE;
217 ALbuffer *ALBuf;
218 ALbuffer *TgtALBuf;
220 Context = alcGetCurrentContext();
221 SuspendContext(Context);
223 if (uiBuffer)
225 TgtALBuf = (ALbuffer *)ALTHUNK_LOOKUPENTRY(uiBuffer);
227 // Check through list of generated buffers for uiBuffer
228 ALBuf = g_pBuffers;
229 while (ALBuf)
231 if (ALBuf == TgtALBuf)
233 result = AL_TRUE;
234 break;
237 ALBuf = ALBuf->next;
240 else
242 result = AL_TRUE;
246 ProcessContext(Context);
248 return result;
252 * alBufferData(ALuint buffer,ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
254 * Fill buffer with audio data
256 ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq)
258 ALuint *IMAData,IMACode;
259 ALCcontext *Context;
260 ALint Sample,Index;
261 ALint LeftSample,LeftIndex;
262 ALint RightSample,RightIndex;
263 ALuint LeftIMACode,RightIMACode;
264 ALbuffer *ALBuf;
265 ALsizei i,j,k;
267 Context = alcGetCurrentContext();
268 SuspendContext(Context);
270 if (alIsBuffer(buffer) && (buffer != 0))
272 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
273 if ((ALBuf->refcount==0)&&(data))
275 switch(format)
277 case AL_FORMAT_MONO8:
278 case AL_FORMAT_MONO16:
279 case AL_FORMAT_MONO_FLOAT32:
280 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO16);
281 break;
283 case AL_FORMAT_STEREO8:
284 case AL_FORMAT_STEREO16:
285 case AL_FORMAT_STEREO_FLOAT32:
286 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO16);
287 break;
289 case AL_FORMAT_REAR8:
290 case AL_FORMAT_REAR16:
291 case AL_FORMAT_REAR32: {
292 ALuint NewFormat = AL_FORMAT_QUAD16;
293 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
294 ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
295 ((format==AL_FORMAT_REAR16) ? 2 :
296 4));
297 ALsizei i;
299 assert(aluBytesFromFormat(NewFormat) == 2);
301 if ((size%(OrigBytes*2)) != 0)
303 alSetError(AL_INVALID_VALUE);
304 break;
307 switch(OrigBytes)
309 case 1:
310 size /= sizeof(ALubyte);
311 size *= 2;
313 // 8bit Samples are converted to 16 bit here
314 // Allocate 8 extra samples
315 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
316 if (ALBuf->data)
318 for (i = 0;i < size;i+=4)
320 ALBuf->data[i+0] = 0;
321 ALBuf->data[i+1] = 0;
322 ALBuf->data[i+2] = (ALshort)((((ALubyte*)data)[i/2+0]-128) << 8);
323 ALBuf->data[i+3] = (ALshort)((((ALubyte*)data)[i/2+1]-128) << 8);
325 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
327 ALBuf->format = NewFormat;
328 ALBuf->eOriginalFormat = format;
329 ALBuf->size = size*1*sizeof(ALshort);
330 ALBuf->frequency = freq;
332 else
333 alSetError(AL_OUT_OF_MEMORY);
334 break;
336 case 2:
337 size /= sizeof(ALshort);
338 size *= 2;
340 // Allocate 8 extra samples
341 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
342 if (ALBuf->data)
344 for (i = 0;i < size;i+=4)
346 ALBuf->data[i+0] = 0;
347 ALBuf->data[i+1] = 0;
348 ALBuf->data[i+2] = ((ALshort*)data)[i/2+0];
349 ALBuf->data[i+3] = ((ALshort*)data)[i/2+1];
351 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
353 ALBuf->format = NewFormat;
354 ALBuf->eOriginalFormat = format;
355 ALBuf->size = size*1*sizeof(ALshort);
356 ALBuf->frequency = freq;
358 else
359 alSetError(AL_OUT_OF_MEMORY);
360 break;
362 case 4:
363 size /= sizeof(ALfloat);
364 size *= 2;
366 // Allocate 8 extra samples
367 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
368 if (ALBuf->data)
370 ALint smp;
371 for (i = 0;i < size;i+=4)
373 ALBuf->data[i+0] = 0;
374 ALBuf->data[i+1] = 0;
375 smp = (((ALfloat*)data)[i/2+0] * 32767.5f - 0.5);
376 smp = min(smp, 32767);
377 smp = max(smp, -32768);
378 ALBuf->data[i+2] = (ALshort)smp;
379 smp = (((ALfloat*)data)[i/2+1] * 32767.5f - 0.5);
380 smp = min(smp, 32767);
381 smp = max(smp, -32768);
382 ALBuf->data[i+3] = (ALshort)smp;
384 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
386 ALBuf->format = NewFormat;
387 ALBuf->eOriginalFormat = format;
388 ALBuf->size = size*1*sizeof(ALshort);
389 ALBuf->frequency = freq;
391 else
392 alSetError(AL_OUT_OF_MEMORY);
393 break;
395 default:
396 assert(0);
398 } break;
400 case AL_FORMAT_QUAD8_LOKI:
401 case AL_FORMAT_QUAD16_LOKI:
402 case AL_FORMAT_QUAD8:
403 case AL_FORMAT_QUAD16:
404 case AL_FORMAT_QUAD32:
405 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD16);
406 break;
408 case AL_FORMAT_51CHN8:
409 case AL_FORMAT_51CHN16:
410 case AL_FORMAT_51CHN32:
411 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN16);
412 break;
414 case AL_FORMAT_61CHN8:
415 case AL_FORMAT_61CHN16:
416 case AL_FORMAT_61CHN32:
417 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN16);
418 break;
420 case AL_FORMAT_71CHN8:
421 case AL_FORMAT_71CHN16:
422 case AL_FORMAT_71CHN32:
423 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN16);
424 break;
426 case AL_FORMAT_MONO_IMA4:
427 // Here is where things vary:
428 // nVidia and Apple use 64+1 samples per block => block_size=36 bytes
429 // Most PC sound software uses 2040+1 samples per block -> block_size=1024 bytes
430 if ((size%36) == 0)
432 // Allocate 8 extra samples (16 bytes)
433 ALBuf->data=realloc(ALBuf->data,16+(size/36)*(65*sizeof(ALshort)));
434 if (ALBuf->data)
436 ALBuf->format = AL_FORMAT_MONO16;
437 ALBuf->eOriginalFormat = AL_FORMAT_MONO_IMA4;
438 IMAData=(ALuint *)data;
439 for (i=0;i<size/36;i++)
441 Sample=((ALshort *)IMAData)[0];
442 Index=((ALshort *)IMAData)[1];
444 Index=Index<0?0:Index;
445 Index=Index>88?88:Index;
447 ALBuf->data[i*65]=(short)Sample;
449 IMAData++;
451 for (j=1;j<65;j+=8)
453 IMACode=*IMAData;
454 for (k=0;k<8;k+=2)
456 Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8);
457 Index+=g_IMAIndex_adjust_4[IMACode&15];
458 if (Sample<-32768) Sample=-32768;
459 else if (Sample>32767) Sample=32767;
460 if (Index<0) Index=0;
461 else if (Index>88) Index=88;
462 ALBuf->data[i*65+j+k]=(short)Sample;
463 IMACode>>=4;
465 Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8);
466 Index+=g_IMAIndex_adjust_4[IMACode&15];
467 if (Sample<-32768) Sample=-32768;
468 else if (Sample>32767) Sample=32767;
469 if (Index<0) Index=0;
470 else if (Index>88) Index=88;
471 ALBuf->data[i*65+j+k+1]=(short)Sample;
472 IMACode>>=4;
474 IMAData++;
477 memset(&(ALBuf->data[(size/36*65)]), 0, 16);
478 ALBuf->size=size/36*65*sizeof(ALshort);
479 ALBuf->frequency=freq;
481 else
482 alSetError(AL_OUT_OF_MEMORY);
484 else
485 alSetError(AL_INVALID_VALUE);
486 break;
488 case AL_FORMAT_STEREO_IMA4:
489 // Here is where things vary:
490 // nVidia and Apple use 64+1 samples per channel per block => block_size=72 bytes
491 // Most PC sound software uses 2040+1 samples per channel per block -> block_size=2048 bytes
492 if ((size%72) == 0)
494 // Allocate 8 extra samples (32 bytes)
495 ALBuf->data=realloc(ALBuf->data,32+(size/72)*(2*65*sizeof(ALshort)));
496 if (ALBuf->data)
498 ALBuf->format = AL_FORMAT_STEREO16;
499 ALBuf->eOriginalFormat = AL_FORMAT_STEREO_IMA4;
500 IMAData=(ALuint *)data;
501 for (i=0;i<size/72;i++)
503 LeftSample=((ALshort *)IMAData)[0];
504 LeftIndex=((ALshort *)IMAData)[1];
506 LeftIndex=LeftIndex<0?0:LeftIndex;
507 LeftIndex=LeftIndex>88?88:LeftIndex;
509 ALBuf->data[i*2*65]=(short)LeftSample;
511 IMAData++;
513 RightSample=((ALshort *)IMAData)[0];
514 RightIndex=((ALshort *)IMAData)[1];
516 RightIndex=RightIndex<0?0:RightIndex;
517 RightIndex=RightIndex>88?88:RightIndex;
519 ALBuf->data[i*2*65+1]=(short)RightSample;
521 IMAData++;
523 for (j=2;j<130;j+=16)
525 LeftIMACode=IMAData[0];
526 RightIMACode=IMAData[1];
527 for (k=0;k<16;k+=4)
529 LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
530 LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15];
531 if (LeftSample<-32768) LeftSample=-32768;
532 else if (LeftSample>32767) LeftSample=32767;
533 if (LeftIndex<0) LeftIndex=0;
534 else if (LeftIndex>88) LeftIndex=88;
535 ALBuf->data[i*2*65+j+k]=(short)LeftSample;
536 LeftIMACode>>=4;
538 RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
539 RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
540 if (RightSample<-32768) RightSample=-32768;
541 else if (RightSample>32767) RightSample=32767;
542 if (RightIndex<0) RightIndex=0;
543 else if (RightIndex>88) RightIndex=88;
544 ALBuf->data[i*2*65+j+k+1]=(short)RightSample;
545 RightIMACode>>=4;
547 LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
548 LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15];
549 if (LeftSample<-32768) LeftSample=-32768;
550 else if (LeftSample>32767) LeftSample=32767;
551 if (LeftIndex<0) LeftIndex=0;
552 else if (LeftIndex>88) LeftIndex=88;
553 ALBuf->data[i*2*65+j+k+2]=(short)LeftSample;
554 LeftIMACode>>=4;
556 RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
557 RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
558 if (RightSample<-32768) RightSample=-32768;
559 else if (RightSample>32767) RightSample=32767;
560 if (RightIndex<0) RightIndex=0;
561 else if (RightIndex>88) RightIndex=88;
562 ALBuf->data[i*2*65+j+k+3]=(short)RightSample;
563 RightIMACode>>=4;
565 IMAData+=2;
568 memset(&(ALBuf->data[(size/72*2*65)]), 0, 32);
569 ALBuf->size=size/72*2*65*sizeof(ALshort);
570 ALBuf->frequency=freq;
572 else
573 alSetError(AL_OUT_OF_MEMORY);
575 else
576 alSetError(AL_INVALID_VALUE);
577 break;
579 default:
580 alSetError(AL_INVALID_ENUM);
581 break;
584 else
586 // Buffer is in use, or data is a NULL pointer
587 alSetError(AL_INVALID_VALUE);
590 else
592 // Invalid Buffer Name
593 alSetError(AL_INVALID_NAME);
596 ProcessContext(Context);
600 ALAPI void ALAPIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
602 ALCcontext *pContext;
604 (void)flValue;
606 pContext = alcGetCurrentContext();
607 SuspendContext(pContext);
609 if (alIsBuffer(buffer) && (buffer != 0))
611 switch(eParam)
613 default:
614 alSetError(AL_INVALID_ENUM);
615 break;
618 else
620 alSetError(AL_INVALID_NAME);
623 ProcessContext(pContext);
627 ALAPI void ALAPIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
629 ALCcontext *pContext;
631 (void)flValue1;
632 (void)flValue2;
633 (void)flValue3;
635 pContext = alcGetCurrentContext();
636 SuspendContext(pContext);
638 if (alIsBuffer(buffer) && (buffer != 0))
640 switch(eParam)
642 default:
643 alSetError(AL_INVALID_ENUM);
644 break;
647 else
649 alSetError(AL_INVALID_NAME);
652 ProcessContext(pContext);
656 ALAPI void ALAPIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues)
658 ALCcontext *pContext;
660 (void)flValues;
662 pContext = alcGetCurrentContext();
663 SuspendContext(pContext);
665 if (alIsBuffer(buffer) && (buffer != 0))
667 switch(eParam)
669 default:
670 alSetError(AL_INVALID_ENUM);
671 break;
674 else
676 alSetError(AL_INVALID_NAME);
679 ProcessContext(pContext);
683 ALAPI void ALAPIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
685 ALCcontext *pContext;
687 (void)lValue;
689 pContext = alcGetCurrentContext();
690 SuspendContext(pContext);
692 if (alIsBuffer(buffer) && (buffer != 0))
694 switch(eParam)
696 default:
697 alSetError(AL_INVALID_ENUM);
698 break;
701 else
703 alSetError(AL_INVALID_NAME);
706 ProcessContext(pContext);
710 ALAPI void ALAPIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
712 ALCcontext *pContext;
714 (void)lValue1;
715 (void)lValue2;
716 (void)lValue3;
718 pContext = alcGetCurrentContext();
719 SuspendContext(pContext);
721 if (alIsBuffer(buffer) && (buffer != 0))
723 switch(eParam)
725 default:
726 alSetError(AL_INVALID_ENUM);
727 break;
730 else
732 alSetError(AL_INVALID_NAME);
735 ProcessContext(pContext);
739 ALAPI void ALAPIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues)
741 ALCcontext *pContext;
743 (void)plValues;
745 pContext = alcGetCurrentContext();
746 SuspendContext(pContext);
748 if (alIsBuffer(buffer) && (buffer != 0))
750 switch(eParam)
752 default:
753 alSetError(AL_INVALID_ENUM);
754 break;
757 else
759 alSetError(AL_INVALID_NAME);
762 ProcessContext(pContext);
766 ALAPI ALvoid ALAPIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue)
768 ALCcontext *pContext;
770 pContext = alcGetCurrentContext();
771 SuspendContext(pContext);
773 if (pflValue)
775 if (alIsBuffer(buffer) && (buffer != 0))
777 switch(eParam)
779 default:
780 alSetError(AL_INVALID_ENUM);
781 break;
784 else
786 alSetError(AL_INVALID_NAME);
789 else
791 alSetError(AL_INVALID_VALUE);
794 ProcessContext(pContext);
798 ALAPI void ALAPIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3)
800 ALCcontext *pContext;
802 pContext = alcGetCurrentContext();
803 SuspendContext(pContext);
805 if ((pflValue1) && (pflValue2) && (pflValue3))
807 if (alIsBuffer(buffer) && (buffer != 0))
809 switch(eParam)
811 default:
812 alSetError(AL_INVALID_ENUM);
813 break;
816 else
818 alSetError(AL_INVALID_NAME);
821 else
823 alSetError(AL_INVALID_VALUE);
826 ProcessContext(pContext);
830 ALAPI void ALAPIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues)
832 ALCcontext *pContext;
834 pContext = alcGetCurrentContext();
835 SuspendContext(pContext);
837 if (pflValues)
839 if (alIsBuffer(buffer) && (buffer != 0))
841 switch(eParam)
843 default:
844 alSetError(AL_INVALID_ENUM);
845 break;
848 else
850 alSetError(AL_INVALID_NAME);
853 else
855 alSetError(AL_INVALID_VALUE);
858 ProcessContext(pContext);
862 ALAPI ALvoid ALAPIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue)
864 ALCcontext *pContext;
865 ALbuffer *pBuffer;
867 pContext = alcGetCurrentContext();
868 SuspendContext(pContext);
870 if (plValue)
872 if (alIsBuffer(buffer) && (buffer != 0))
874 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
876 switch (eParam)
878 case AL_FREQUENCY:
879 *plValue = pBuffer->frequency;
880 break;
882 case AL_BITS:
883 *plValue = aluBytesFromFormat(pBuffer->format) * 8;
884 break;
886 case AL_CHANNELS:
887 *plValue = aluChannelsFromFormat(pBuffer->format);
888 break;
890 case AL_SIZE:
891 *plValue = pBuffer->size;
892 break;
894 default:
895 alSetError(AL_INVALID_ENUM);
896 break;
899 else
901 alSetError(AL_INVALID_NAME);
904 else
906 alSetError(AL_INVALID_VALUE);
909 ProcessContext(pContext);
913 ALAPI void ALAPIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3)
915 ALCcontext *pContext;
917 pContext = alcGetCurrentContext();
918 SuspendContext(pContext);
920 if ((plValue1) && (plValue2) && (plValue3))
922 if (alIsBuffer(buffer) && (buffer != 0))
924 switch(eParam)
926 default:
927 alSetError(AL_INVALID_ENUM);
928 break;
931 else
933 alSetError(AL_INVALID_NAME);
936 else
938 alSetError(AL_INVALID_VALUE);
941 ProcessContext(pContext);
945 ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues)
947 ALCcontext *pContext;
949 pContext = alcGetCurrentContext();
950 SuspendContext(pContext);
952 if (plValues)
954 if (alIsBuffer(buffer) && (buffer != 0))
956 switch (eParam)
958 case AL_FREQUENCY:
959 case AL_BITS:
960 case AL_CHANNELS:
961 case AL_SIZE:
962 alGetBufferi(buffer, eParam, plValues);
963 break;
965 default:
966 alSetError(AL_INVALID_ENUM);
967 break;
970 else
972 alSetError(AL_INVALID_NAME);
975 else
977 alSetError(AL_INVALID_VALUE);
980 ProcessContext(pContext);
984 * LoadData
986 * Loads the specified data into the buffer, using the specified formats.
987 * Currently, the new format must be 16-bit, and must have the same channel
988 * configuration as the original format. This does NOT handle compressed
989 * formats (eg. IMA4).
991 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
993 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
994 ALuint OrigBytes = aluBytesFromFormat(OrigFormat);
995 ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
996 ALsizei i;
998 assert(aluBytesFromFormat(NewFormat) == 2);
999 assert(NewChannels == OrigChannels);
1001 if ((size%(OrigBytes*OrigChannels)) != 0)
1003 alSetError(AL_INVALID_VALUE);
1004 return;
1007 switch(OrigBytes)
1009 case 1:
1010 size /= sizeof(ALubyte);
1012 // 8bit Samples are converted to 16 bit here
1013 // Allocate 8 extra samples
1014 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
1015 if (ALBuf->data)
1017 for (i = 0;i < size;i++)
1018 ALBuf->data[i] = (ALshort)((data[i]-128) << 8);
1019 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
1021 ALBuf->format = NewFormat;
1022 ALBuf->eOriginalFormat = OrigFormat;
1023 ALBuf->size = size*1*sizeof(ALshort);
1024 ALBuf->frequency = freq;
1026 else
1027 alSetError(AL_OUT_OF_MEMORY);
1028 break;
1030 case 2:
1031 size /= sizeof(ALshort);
1033 // Allocate 8 extra samples
1034 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
1035 if (ALBuf->data)
1037 memcpy(ALBuf->data, data, size*1*sizeof(ALshort));
1038 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
1040 ALBuf->format = NewFormat;
1041 ALBuf->eOriginalFormat = OrigFormat;
1042 ALBuf->size = size*1*sizeof(ALshort);
1043 ALBuf->frequency = freq;
1045 else
1046 alSetError(AL_OUT_OF_MEMORY);
1047 break;
1049 case 4:
1050 size /= sizeof(ALfloat);
1052 // Allocate 8 extra samples
1053 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
1054 if (ALBuf->data)
1056 ALint smp;
1057 for (i = 0;i < size;i++)
1059 smp = (((ALfloat*)data)[i] * 32767.5f - 0.5f);
1060 smp = min(smp, 32767);
1061 smp = max(smp, -32768);
1062 ALBuf->data[i] = (ALshort)smp;
1064 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
1066 ALBuf->format = NewFormat;
1067 ALBuf->eOriginalFormat = OrigFormat;
1068 ALBuf->size = size*1*sizeof(ALshort);
1069 ALBuf->frequency = freq;
1071 else
1072 alSetError(AL_OUT_OF_MEMORY);
1073 break;
1075 default:
1076 assert(0);
1082 * ReleaseALBuffers()
1084 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
1086 ALvoid ReleaseALBuffers(ALvoid)
1088 ALbuffer *ALBuffer;
1089 ALbuffer *ALBufferTemp;
1091 #ifdef _DEBUG
1092 if(g_uiBufferCount > 0)
1093 AL_PRINT("exit(): deleting %d Buffer(s)\n", g_uiBufferCount);
1094 #endif
1096 ALBuffer = g_pBuffers;
1097 while(ALBuffer)
1099 // Release sample data
1100 free(ALBuffer->data);
1102 // Release Buffer structure
1103 ALBufferTemp = ALBuffer;
1104 ALBuffer = ALBuffer->next;
1105 memset(ALBufferTemp, 0, sizeof(ALbuffer));
1106 free(ALBufferTemp);
1108 g_pBuffers = NULL;
1109 g_uiBufferCount = 0;