More padding fixes
[openal-soft.git] / OpenAL32 / alBuffer.c
blob54fce5f86ffe2ed966876255c0d4bdbe4e19f8b9
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 ALsizei padding = 2;
265 ALbuffer *ALBuf;
266 ALsizei i,j,k;
267 ALvoid *temp;
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 size /= OrigBytes;
310 size *= 2;
312 // Samples are converted to 16 bit here
313 temp = realloc(ALBuf->data, (padding*NewChannels + size) * sizeof(ALshort));
314 if(temp)
316 ALBuf->data = temp;
317 switch(OrigBytes)
319 case 1:
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 break;
329 case 2:
330 for(i = 0;i < size;i+=4)
332 ALBuf->data[i+0] = 0;
333 ALBuf->data[i+1] = 0;
334 ALBuf->data[i+2] = ((ALshort*)data)[i/2+0];
335 ALBuf->data[i+3] = ((ALshort*)data)[i/2+1];
337 break;
339 case 4:
340 for(i = 0;i < size;i+=4)
342 ALint smp;
343 ALBuf->data[i+0] = 0;
344 ALBuf->data[i+1] = 0;
345 smp = (((ALfloat*)data)[i/2+0] * 32767.5f - 0.5);
346 smp = min(smp, 32767);
347 smp = max(smp, -32768);
348 ALBuf->data[i+2] = (ALshort)smp;
349 smp = (((ALfloat*)data)[i/2+1] * 32767.5f - 0.5);
350 smp = min(smp, 32767);
351 smp = max(smp, -32768);
352 ALBuf->data[i+3] = (ALshort)smp;
354 break;
356 default:
357 assert(0);
359 memset(&(ALBuf->data[size]), 0, padding*NewChannels*sizeof(ALshort));
361 ALBuf->format = NewFormat;
362 ALBuf->eOriginalFormat = format;
363 ALBuf->size = size*sizeof(ALshort);
364 ALBuf->frequency = freq;
365 ALBuf->padding = padding;
367 else
368 alSetError(AL_OUT_OF_MEMORY);
369 } break;
371 case AL_FORMAT_QUAD8_LOKI:
372 case AL_FORMAT_QUAD16_LOKI:
373 case AL_FORMAT_QUAD8:
374 case AL_FORMAT_QUAD16:
375 case AL_FORMAT_QUAD32:
376 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD16);
377 break;
379 case AL_FORMAT_51CHN8:
380 case AL_FORMAT_51CHN16:
381 case AL_FORMAT_51CHN32:
382 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN16);
383 break;
385 case AL_FORMAT_61CHN8:
386 case AL_FORMAT_61CHN16:
387 case AL_FORMAT_61CHN32:
388 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN16);
389 break;
391 case AL_FORMAT_71CHN8:
392 case AL_FORMAT_71CHN16:
393 case AL_FORMAT_71CHN32:
394 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN16);
395 break;
397 case AL_FORMAT_MONO_IMA4:
398 // Here is where things vary:
399 // nVidia and Apple use 64+1 samples per block => block_size=36 bytes
400 // Most PC sound software uses 2040+1 samples per block -> block_size=1024 bytes
401 if ((size%36) == 0)
403 // Allocate extra padding samples
404 temp=realloc(ALBuf->data,padding*2+(size/36)*(65*sizeof(ALshort)));
405 if (temp)
407 ALBuf->data = temp;
408 ALBuf->format = AL_FORMAT_MONO16;
409 ALBuf->eOriginalFormat = AL_FORMAT_MONO_IMA4;
410 IMAData=(ALuint *)data;
411 for (i=0;i<size/36;i++)
413 Sample=((ALshort *)IMAData)[0];
414 Index=((ALshort *)IMAData)[1];
416 Index=Index<0?0:Index;
417 Index=Index>88?88:Index;
419 ALBuf->data[i*65]=(short)Sample;
421 IMAData++;
423 for (j=1;j<65;j+=8)
425 IMACode=*IMAData;
426 for (k=0;k<8;k+=2)
428 Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8);
429 Index+=g_IMAIndex_adjust_4[IMACode&15];
430 if (Sample<-32768) Sample=-32768;
431 else if (Sample>32767) Sample=32767;
432 if (Index<0) Index=0;
433 else if (Index>88) Index=88;
434 ALBuf->data[i*65+j+k]=(short)Sample;
435 IMACode>>=4;
437 Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8);
438 Index+=g_IMAIndex_adjust_4[IMACode&15];
439 if (Sample<-32768) Sample=-32768;
440 else if (Sample>32767) Sample=32767;
441 if (Index<0) Index=0;
442 else if (Index>88) Index=88;
443 ALBuf->data[i*65+j+k+1]=(short)Sample;
444 IMACode>>=4;
446 IMAData++;
449 memset(&(ALBuf->data[(size/36*65)]), 0, padding*2);
450 ALBuf->size=size/36*65*sizeof(ALshort);
451 ALBuf->frequency=freq;
452 ALBuf->padding=padding;
454 else
455 alSetError(AL_OUT_OF_MEMORY);
457 else
458 alSetError(AL_INVALID_VALUE);
459 break;
461 case AL_FORMAT_STEREO_IMA4:
462 // Here is where things vary:
463 // nVidia and Apple use 64+1 samples per channel per block => block_size=72 bytes
464 // Most PC sound software uses 2040+1 samples per channel per block -> block_size=2048 bytes
465 if ((size%72) == 0)
467 // Allocate extra padding samples
468 temp=realloc(ALBuf->data,padding*2*2+(size/72)*(2*65*sizeof(ALshort)));
469 if (temp)
471 ALBuf->data = temp;
472 ALBuf->format = AL_FORMAT_STEREO16;
473 ALBuf->eOriginalFormat = AL_FORMAT_STEREO_IMA4;
474 IMAData=(ALuint *)data;
475 for (i=0;i<size/72;i++)
477 LeftSample=((ALshort *)IMAData)[0];
478 LeftIndex=((ALshort *)IMAData)[1];
480 LeftIndex=LeftIndex<0?0:LeftIndex;
481 LeftIndex=LeftIndex>88?88:LeftIndex;
483 ALBuf->data[i*2*65]=(short)LeftSample;
485 IMAData++;
487 RightSample=((ALshort *)IMAData)[0];
488 RightIndex=((ALshort *)IMAData)[1];
490 RightIndex=RightIndex<0?0:RightIndex;
491 RightIndex=RightIndex>88?88:RightIndex;
493 ALBuf->data[i*2*65+1]=(short)RightSample;
495 IMAData++;
497 for (j=2;j<130;j+=16)
499 LeftIMACode=IMAData[0];
500 RightIMACode=IMAData[1];
501 for (k=0;k<16;k+=4)
503 LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
504 LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15];
505 if (LeftSample<-32768) LeftSample=-32768;
506 else if (LeftSample>32767) LeftSample=32767;
507 if (LeftIndex<0) LeftIndex=0;
508 else if (LeftIndex>88) LeftIndex=88;
509 ALBuf->data[i*2*65+j+k]=(short)LeftSample;
510 LeftIMACode>>=4;
512 RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
513 RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
514 if (RightSample<-32768) RightSample=-32768;
515 else if (RightSample>32767) RightSample=32767;
516 if (RightIndex<0) RightIndex=0;
517 else if (RightIndex>88) RightIndex=88;
518 ALBuf->data[i*2*65+j+k+1]=(short)RightSample;
519 RightIMACode>>=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+2]=(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+3]=(short)RightSample;
537 RightIMACode>>=4;
539 IMAData+=2;
542 memset(&(ALBuf->data[(size/72*2*65)]), 0, padding*2*2);
543 ALBuf->size=size/72*2*65*sizeof(ALshort);
544 ALBuf->frequency=freq;
545 ALBuf->padding=padding;
547 else
548 alSetError(AL_OUT_OF_MEMORY);
550 else
551 alSetError(AL_INVALID_VALUE);
552 break;
554 default:
555 alSetError(AL_INVALID_ENUM);
556 break;
559 else
561 // Buffer is in use, or data is a NULL pointer
562 alSetError(AL_INVALID_VALUE);
565 else
567 // Invalid Buffer Name
568 alSetError(AL_INVALID_NAME);
571 ProcessContext(Context);
575 ALAPI void ALAPIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
577 ALCcontext *pContext;
579 (void)flValue;
581 pContext = alcGetCurrentContext();
582 SuspendContext(pContext);
584 if (alIsBuffer(buffer) && (buffer != 0))
586 switch(eParam)
588 default:
589 alSetError(AL_INVALID_ENUM);
590 break;
593 else
595 alSetError(AL_INVALID_NAME);
598 ProcessContext(pContext);
602 ALAPI void ALAPIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
604 ALCcontext *pContext;
606 (void)flValue1;
607 (void)flValue2;
608 (void)flValue3;
610 pContext = alcGetCurrentContext();
611 SuspendContext(pContext);
613 if (alIsBuffer(buffer) && (buffer != 0))
615 switch(eParam)
617 default:
618 alSetError(AL_INVALID_ENUM);
619 break;
622 else
624 alSetError(AL_INVALID_NAME);
627 ProcessContext(pContext);
631 ALAPI void ALAPIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues)
633 ALCcontext *pContext;
635 (void)flValues;
637 pContext = alcGetCurrentContext();
638 SuspendContext(pContext);
640 if (alIsBuffer(buffer) && (buffer != 0))
642 switch(eParam)
644 default:
645 alSetError(AL_INVALID_ENUM);
646 break;
649 else
651 alSetError(AL_INVALID_NAME);
654 ProcessContext(pContext);
658 ALAPI void ALAPIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
660 ALCcontext *pContext;
662 (void)lValue;
664 pContext = alcGetCurrentContext();
665 SuspendContext(pContext);
667 if (alIsBuffer(buffer) && (buffer != 0))
669 switch(eParam)
671 default:
672 alSetError(AL_INVALID_ENUM);
673 break;
676 else
678 alSetError(AL_INVALID_NAME);
681 ProcessContext(pContext);
685 ALAPI void ALAPIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
687 ALCcontext *pContext;
689 (void)lValue1;
690 (void)lValue2;
691 (void)lValue3;
693 pContext = alcGetCurrentContext();
694 SuspendContext(pContext);
696 if (alIsBuffer(buffer) && (buffer != 0))
698 switch(eParam)
700 default:
701 alSetError(AL_INVALID_ENUM);
702 break;
705 else
707 alSetError(AL_INVALID_NAME);
710 ProcessContext(pContext);
714 ALAPI void ALAPIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues)
716 ALCcontext *pContext;
718 (void)plValues;
720 pContext = alcGetCurrentContext();
721 SuspendContext(pContext);
723 if (alIsBuffer(buffer) && (buffer != 0))
725 switch(eParam)
727 default:
728 alSetError(AL_INVALID_ENUM);
729 break;
732 else
734 alSetError(AL_INVALID_NAME);
737 ProcessContext(pContext);
741 ALAPI ALvoid ALAPIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue)
743 ALCcontext *pContext;
745 pContext = alcGetCurrentContext();
746 SuspendContext(pContext);
748 if (pflValue)
750 if (alIsBuffer(buffer) && (buffer != 0))
752 switch(eParam)
754 default:
755 alSetError(AL_INVALID_ENUM);
756 break;
759 else
761 alSetError(AL_INVALID_NAME);
764 else
766 alSetError(AL_INVALID_VALUE);
769 ProcessContext(pContext);
773 ALAPI void ALAPIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3)
775 ALCcontext *pContext;
777 pContext = alcGetCurrentContext();
778 SuspendContext(pContext);
780 if ((pflValue1) && (pflValue2) && (pflValue3))
782 if (alIsBuffer(buffer) && (buffer != 0))
784 switch(eParam)
786 default:
787 alSetError(AL_INVALID_ENUM);
788 break;
791 else
793 alSetError(AL_INVALID_NAME);
796 else
798 alSetError(AL_INVALID_VALUE);
801 ProcessContext(pContext);
805 ALAPI void ALAPIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues)
807 ALCcontext *pContext;
809 pContext = alcGetCurrentContext();
810 SuspendContext(pContext);
812 if (pflValues)
814 if (alIsBuffer(buffer) && (buffer != 0))
816 switch(eParam)
818 default:
819 alSetError(AL_INVALID_ENUM);
820 break;
823 else
825 alSetError(AL_INVALID_NAME);
828 else
830 alSetError(AL_INVALID_VALUE);
833 ProcessContext(pContext);
837 ALAPI ALvoid ALAPIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue)
839 ALCcontext *pContext;
840 ALbuffer *pBuffer;
842 pContext = alcGetCurrentContext();
843 SuspendContext(pContext);
845 if (plValue)
847 if (alIsBuffer(buffer) && (buffer != 0))
849 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
851 switch (eParam)
853 case AL_FREQUENCY:
854 *plValue = pBuffer->frequency;
855 break;
857 case AL_BITS:
858 *plValue = aluBytesFromFormat(pBuffer->format) * 8;
859 break;
861 case AL_CHANNELS:
862 *plValue = aluChannelsFromFormat(pBuffer->format);
863 break;
865 case AL_SIZE:
866 *plValue = pBuffer->size;
867 break;
869 default:
870 alSetError(AL_INVALID_ENUM);
871 break;
874 else
876 alSetError(AL_INVALID_NAME);
879 else
881 alSetError(AL_INVALID_VALUE);
884 ProcessContext(pContext);
888 ALAPI void ALAPIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3)
890 ALCcontext *pContext;
892 pContext = alcGetCurrentContext();
893 SuspendContext(pContext);
895 if ((plValue1) && (plValue2) && (plValue3))
897 if (alIsBuffer(buffer) && (buffer != 0))
899 switch(eParam)
901 default:
902 alSetError(AL_INVALID_ENUM);
903 break;
906 else
908 alSetError(AL_INVALID_NAME);
911 else
913 alSetError(AL_INVALID_VALUE);
916 ProcessContext(pContext);
920 ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues)
922 ALCcontext *pContext;
924 pContext = alcGetCurrentContext();
925 SuspendContext(pContext);
927 if (plValues)
929 if (alIsBuffer(buffer) && (buffer != 0))
931 switch (eParam)
933 case AL_FREQUENCY:
934 case AL_BITS:
935 case AL_CHANNELS:
936 case AL_SIZE:
937 alGetBufferi(buffer, eParam, plValues);
938 break;
940 default:
941 alSetError(AL_INVALID_ENUM);
942 break;
945 else
947 alSetError(AL_INVALID_NAME);
950 else
952 alSetError(AL_INVALID_VALUE);
955 ProcessContext(pContext);
959 * LoadData
961 * Loads the specified data into the buffer, using the specified formats.
962 * Currently, the new format must be 16-bit, and must have the same channel
963 * configuration as the original format. This does NOT handle compressed
964 * formats (eg. IMA4).
966 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
968 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
969 ALuint OrigBytes = aluBytesFromFormat(OrigFormat);
970 ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
971 ALsizei padding = 2;
972 ALvoid *temp;
973 ALsizei i;
975 assert(aluBytesFromFormat(NewFormat) == 2);
976 assert(NewChannels == OrigChannels);
978 if ((size%(OrigBytes*OrigChannels)) != 0)
980 alSetError(AL_INVALID_VALUE);
981 return;
984 // Samples are converted to 16 bit here
985 size /= OrigBytes;
986 temp = realloc(ALBuf->data, (padding*NewChannels + size) * sizeof(ALshort));
987 if(temp)
989 ALBuf->data = temp;
991 switch(OrigBytes)
993 case 1:
994 for(i = 0;i < size;i++)
995 ALBuf->data[i] = (ALshort)((data[i]-128) << 8);
996 break;
998 case 2:
999 memcpy(ALBuf->data, data, size*sizeof(ALshort));
1000 break;
1002 case 4:
1003 for(i = 0;i < size;i++)
1005 ALint smp;
1006 smp = (((ALfloat*)data)[i] * 32767.5f - 0.5f);
1007 smp = min(smp, 32767);
1008 smp = max(smp, -32768);
1009 ALBuf->data[i] = (ALshort)smp;
1011 break;
1013 default:
1014 assert(0);
1017 memset(&(ALBuf->data[size]), 0, padding*NewChannels*sizeof(ALshort));
1019 ALBuf->format = NewFormat;
1020 ALBuf->eOriginalFormat = OrigFormat;
1021 ALBuf->size = size*sizeof(ALshort);
1022 ALBuf->frequency = freq;
1023 ALBuf->padding = padding;
1025 else
1026 alSetError(AL_OUT_OF_MEMORY);
1031 * ReleaseALBuffers()
1033 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
1035 ALvoid ReleaseALBuffers(ALvoid)
1037 ALbuffer *ALBuffer;
1038 ALbuffer *ALBufferTemp;
1040 #ifdef _DEBUG
1041 if(g_uiBufferCount > 0)
1042 AL_PRINT("exit(): deleting %d Buffer(s)\n", g_uiBufferCount);
1043 #endif
1045 ALBuffer = g_pBuffers;
1046 while(ALBuffer)
1048 // Release sample data
1049 free(ALBuffer->data);
1051 // Release Buffer structure
1052 ALBufferTemp = ALBuffer;
1053 ALBuffer = ALBuffer->next;
1054 memset(ALBufferTemp, 0, sizeof(ALbuffer));
1055 free(ALBufferTemp);
1057 g_pBuffers = NULL;
1058 g_uiBufferCount = 0;