Restructure buffer data conversion code a bit
[openal-soft.git] / OpenAL32 / alBuffer.c
blob0b02b5deb757feb398d02ed3e657850d7b79413c
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 padding;
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 padding = freq / LOWPASSFREQCUTOFF;
310 if(padding < 1) padding = 1;
312 switch(OrigBytes)
314 case 1:
315 size /= sizeof(ALubyte);
316 size *= 2;
318 // 8bit Samples are converted to 16 bit here
319 temp = realloc(ALBuf->data, (padding*NewChannels + size) * (1*sizeof(ALshort)));
320 if (temp)
322 ALBuf->data = temp;
323 for (i = 0;i < size;i+=4)
325 ALBuf->data[i+0] = 0;
326 ALBuf->data[i+1] = 0;
327 ALBuf->data[i+2] = (ALshort)((((ALubyte*)data)[i/2+0]-128) << 8);
328 ALBuf->data[i+3] = (ALshort)((((ALubyte*)data)[i/2+1]-128) << 8);
330 memset(&(ALBuf->data[size]), 0, padding*NewChannels*2);
332 ALBuf->format = NewFormat;
333 ALBuf->eOriginalFormat = format;
334 ALBuf->size = size*1*sizeof(ALshort);
335 ALBuf->frequency = freq;
336 ALBuf->padding = padding;
338 else
339 alSetError(AL_OUT_OF_MEMORY);
340 break;
342 case 2:
343 size /= sizeof(ALshort);
344 size *= 2;
346 temp = realloc(ALBuf->data, (padding*NewChannels + size) * (1*sizeof(ALshort)));
347 if (temp)
349 ALBuf->data = temp;
350 for (i = 0;i < size;i+=4)
352 ALBuf->data[i+0] = 0;
353 ALBuf->data[i+1] = 0;
354 ALBuf->data[i+2] = ((ALshort*)data)[i/2+0];
355 ALBuf->data[i+3] = ((ALshort*)data)[i/2+1];
357 memset(&(ALBuf->data[size]), 0, padding*NewChannels*2);
359 ALBuf->format = NewFormat;
360 ALBuf->eOriginalFormat = format;
361 ALBuf->size = size*1*sizeof(ALshort);
362 ALBuf->frequency = freq;
363 ALBuf->padding = padding;
365 else
366 alSetError(AL_OUT_OF_MEMORY);
367 break;
369 case 4:
370 size /= sizeof(ALfloat);
371 size *= 2;
373 temp = realloc(ALBuf->data, (padding*NewChannels + size) * (1*sizeof(ALshort)));
374 if (temp)
376 ALint smp;
377 ALBuf->data = temp;
378 for (i = 0;i < size;i+=4)
380 ALBuf->data[i+0] = 0;
381 ALBuf->data[i+1] = 0;
382 smp = (((ALfloat*)data)[i/2+0] * 32767.5f - 0.5);
383 smp = min(smp, 32767);
384 smp = max(smp, -32768);
385 ALBuf->data[i+2] = (ALshort)smp;
386 smp = (((ALfloat*)data)[i/2+1] * 32767.5f - 0.5);
387 smp = min(smp, 32767);
388 smp = max(smp, -32768);
389 ALBuf->data[i+3] = (ALshort)smp;
391 memset(&(ALBuf->data[size]), 0, padding*NewChannels*2);
393 ALBuf->format = NewFormat;
394 ALBuf->eOriginalFormat = format;
395 ALBuf->size = size*1*sizeof(ALshort);
396 ALBuf->frequency = freq;
397 ALBuf->padding = padding;
399 else
400 alSetError(AL_OUT_OF_MEMORY);
401 break;
403 default:
404 assert(0);
406 } break;
408 case AL_FORMAT_QUAD8_LOKI:
409 case AL_FORMAT_QUAD16_LOKI:
410 case AL_FORMAT_QUAD8:
411 case AL_FORMAT_QUAD16:
412 case AL_FORMAT_QUAD32:
413 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD16);
414 break;
416 case AL_FORMAT_51CHN8:
417 case AL_FORMAT_51CHN16:
418 case AL_FORMAT_51CHN32:
419 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN16);
420 break;
422 case AL_FORMAT_61CHN8:
423 case AL_FORMAT_61CHN16:
424 case AL_FORMAT_61CHN32:
425 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN16);
426 break;
428 case AL_FORMAT_71CHN8:
429 case AL_FORMAT_71CHN16:
430 case AL_FORMAT_71CHN32:
431 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN16);
432 break;
434 case AL_FORMAT_MONO_IMA4:
435 padding = freq / LOWPASSFREQCUTOFF;
436 if(padding < 1) padding = 1;
438 // Here is where things vary:
439 // nVidia and Apple use 64+1 samples per block => block_size=36 bytes
440 // Most PC sound software uses 2040+1 samples per block -> block_size=1024 bytes
441 if ((size%36) == 0)
443 // Allocate extra padding samples
444 temp=realloc(ALBuf->data,padding*2+(size/36)*(65*sizeof(ALshort)));
445 if (temp)
447 ALBuf->data = temp;
448 ALBuf->format = AL_FORMAT_MONO16;
449 ALBuf->eOriginalFormat = AL_FORMAT_MONO_IMA4;
450 IMAData=(ALuint *)data;
451 for (i=0;i<size/36;i++)
453 Sample=((ALshort *)IMAData)[0];
454 Index=((ALshort *)IMAData)[1];
456 Index=Index<0?0:Index;
457 Index=Index>88?88:Index;
459 ALBuf->data[i*65]=(short)Sample;
461 IMAData++;
463 for (j=1;j<65;j+=8)
465 IMACode=*IMAData;
466 for (k=0;k<8;k+=2)
468 Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8);
469 Index+=g_IMAIndex_adjust_4[IMACode&15];
470 if (Sample<-32768) Sample=-32768;
471 else if (Sample>32767) Sample=32767;
472 if (Index<0) Index=0;
473 else if (Index>88) Index=88;
474 ALBuf->data[i*65+j+k]=(short)Sample;
475 IMACode>>=4;
477 Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8);
478 Index+=g_IMAIndex_adjust_4[IMACode&15];
479 if (Sample<-32768) Sample=-32768;
480 else if (Sample>32767) Sample=32767;
481 if (Index<0) Index=0;
482 else if (Index>88) Index=88;
483 ALBuf->data[i*65+j+k+1]=(short)Sample;
484 IMACode>>=4;
486 IMAData++;
489 memset(&(ALBuf->data[(size/36*65)]), 0, padding*2);
490 ALBuf->size=size/36*65*sizeof(ALshort);
491 ALBuf->frequency=freq;
492 ALBuf->padding=padding;
494 else
495 alSetError(AL_OUT_OF_MEMORY);
497 else
498 alSetError(AL_INVALID_VALUE);
499 break;
501 case AL_FORMAT_STEREO_IMA4:
502 padding = freq / LOWPASSFREQCUTOFF;
503 if(padding < 1) padding = 1;
505 // Here is where things vary:
506 // nVidia and Apple use 64+1 samples per channel per block => block_size=72 bytes
507 // Most PC sound software uses 2040+1 samples per channel per block -> block_size=2048 bytes
508 if ((size%72) == 0)
510 // Allocate extra padding samples
511 temp=realloc(ALBuf->data,padding*2*2+(size/72)*(2*65*sizeof(ALshort)));
512 if (temp)
514 ALBuf->data = temp;
515 ALBuf->format = AL_FORMAT_STEREO16;
516 ALBuf->eOriginalFormat = AL_FORMAT_STEREO_IMA4;
517 IMAData=(ALuint *)data;
518 for (i=0;i<size/72;i++)
520 LeftSample=((ALshort *)IMAData)[0];
521 LeftIndex=((ALshort *)IMAData)[1];
523 LeftIndex=LeftIndex<0?0:LeftIndex;
524 LeftIndex=LeftIndex>88?88:LeftIndex;
526 ALBuf->data[i*2*65]=(short)LeftSample;
528 IMAData++;
530 RightSample=((ALshort *)IMAData)[0];
531 RightIndex=((ALshort *)IMAData)[1];
533 RightIndex=RightIndex<0?0:RightIndex;
534 RightIndex=RightIndex>88?88:RightIndex;
536 ALBuf->data[i*2*65+1]=(short)RightSample;
538 IMAData++;
540 for (j=2;j<130;j+=16)
542 LeftIMACode=IMAData[0];
543 RightIMACode=IMAData[1];
544 for (k=0;k<16;k+=4)
546 LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
547 LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15];
548 if (LeftSample<-32768) LeftSample=-32768;
549 else if (LeftSample>32767) LeftSample=32767;
550 if (LeftIndex<0) LeftIndex=0;
551 else if (LeftIndex>88) LeftIndex=88;
552 ALBuf->data[i*2*65+j+k]=(short)LeftSample;
553 LeftIMACode>>=4;
555 RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
556 RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
557 if (RightSample<-32768) RightSample=-32768;
558 else if (RightSample>32767) RightSample=32767;
559 if (RightIndex<0) RightIndex=0;
560 else if (RightIndex>88) RightIndex=88;
561 ALBuf->data[i*2*65+j+k+1]=(short)RightSample;
562 RightIMACode>>=4;
564 LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
565 LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15];
566 if (LeftSample<-32768) LeftSample=-32768;
567 else if (LeftSample>32767) LeftSample=32767;
568 if (LeftIndex<0) LeftIndex=0;
569 else if (LeftIndex>88) LeftIndex=88;
570 ALBuf->data[i*2*65+j+k+2]=(short)LeftSample;
571 LeftIMACode>>=4;
573 RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
574 RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
575 if (RightSample<-32768) RightSample=-32768;
576 else if (RightSample>32767) RightSample=32767;
577 if (RightIndex<0) RightIndex=0;
578 else if (RightIndex>88) RightIndex=88;
579 ALBuf->data[i*2*65+j+k+3]=(short)RightSample;
580 RightIMACode>>=4;
582 IMAData+=2;
585 memset(&(ALBuf->data[(size/72*2*65)]), 0, padding*2*2);
586 ALBuf->size=size/72*2*65*sizeof(ALshort);
587 ALBuf->frequency=freq;
588 ALBuf->padding=padding;
590 else
591 alSetError(AL_OUT_OF_MEMORY);
593 else
594 alSetError(AL_INVALID_VALUE);
595 break;
597 default:
598 alSetError(AL_INVALID_ENUM);
599 break;
602 else
604 // Buffer is in use, or data is a NULL pointer
605 alSetError(AL_INVALID_VALUE);
608 else
610 // Invalid Buffer Name
611 alSetError(AL_INVALID_NAME);
614 ProcessContext(Context);
618 ALAPI void ALAPIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
620 ALCcontext *pContext;
622 (void)flValue;
624 pContext = alcGetCurrentContext();
625 SuspendContext(pContext);
627 if (alIsBuffer(buffer) && (buffer != 0))
629 switch(eParam)
631 default:
632 alSetError(AL_INVALID_ENUM);
633 break;
636 else
638 alSetError(AL_INVALID_NAME);
641 ProcessContext(pContext);
645 ALAPI void ALAPIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
647 ALCcontext *pContext;
649 (void)flValue1;
650 (void)flValue2;
651 (void)flValue3;
653 pContext = alcGetCurrentContext();
654 SuspendContext(pContext);
656 if (alIsBuffer(buffer) && (buffer != 0))
658 switch(eParam)
660 default:
661 alSetError(AL_INVALID_ENUM);
662 break;
665 else
667 alSetError(AL_INVALID_NAME);
670 ProcessContext(pContext);
674 ALAPI void ALAPIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues)
676 ALCcontext *pContext;
678 (void)flValues;
680 pContext = alcGetCurrentContext();
681 SuspendContext(pContext);
683 if (alIsBuffer(buffer) && (buffer != 0))
685 switch(eParam)
687 default:
688 alSetError(AL_INVALID_ENUM);
689 break;
692 else
694 alSetError(AL_INVALID_NAME);
697 ProcessContext(pContext);
701 ALAPI void ALAPIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
703 ALCcontext *pContext;
705 (void)lValue;
707 pContext = alcGetCurrentContext();
708 SuspendContext(pContext);
710 if (alIsBuffer(buffer) && (buffer != 0))
712 switch(eParam)
714 default:
715 alSetError(AL_INVALID_ENUM);
716 break;
719 else
721 alSetError(AL_INVALID_NAME);
724 ProcessContext(pContext);
728 ALAPI void ALAPIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
730 ALCcontext *pContext;
732 (void)lValue1;
733 (void)lValue2;
734 (void)lValue3;
736 pContext = alcGetCurrentContext();
737 SuspendContext(pContext);
739 if (alIsBuffer(buffer) && (buffer != 0))
741 switch(eParam)
743 default:
744 alSetError(AL_INVALID_ENUM);
745 break;
748 else
750 alSetError(AL_INVALID_NAME);
753 ProcessContext(pContext);
757 ALAPI void ALAPIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues)
759 ALCcontext *pContext;
761 (void)plValues;
763 pContext = alcGetCurrentContext();
764 SuspendContext(pContext);
766 if (alIsBuffer(buffer) && (buffer != 0))
768 switch(eParam)
770 default:
771 alSetError(AL_INVALID_ENUM);
772 break;
775 else
777 alSetError(AL_INVALID_NAME);
780 ProcessContext(pContext);
784 ALAPI ALvoid ALAPIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue)
786 ALCcontext *pContext;
788 pContext = alcGetCurrentContext();
789 SuspendContext(pContext);
791 if (pflValue)
793 if (alIsBuffer(buffer) && (buffer != 0))
795 switch(eParam)
797 default:
798 alSetError(AL_INVALID_ENUM);
799 break;
802 else
804 alSetError(AL_INVALID_NAME);
807 else
809 alSetError(AL_INVALID_VALUE);
812 ProcessContext(pContext);
816 ALAPI void ALAPIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3)
818 ALCcontext *pContext;
820 pContext = alcGetCurrentContext();
821 SuspendContext(pContext);
823 if ((pflValue1) && (pflValue2) && (pflValue3))
825 if (alIsBuffer(buffer) && (buffer != 0))
827 switch(eParam)
829 default:
830 alSetError(AL_INVALID_ENUM);
831 break;
834 else
836 alSetError(AL_INVALID_NAME);
839 else
841 alSetError(AL_INVALID_VALUE);
844 ProcessContext(pContext);
848 ALAPI void ALAPIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues)
850 ALCcontext *pContext;
852 pContext = alcGetCurrentContext();
853 SuspendContext(pContext);
855 if (pflValues)
857 if (alIsBuffer(buffer) && (buffer != 0))
859 switch(eParam)
861 default:
862 alSetError(AL_INVALID_ENUM);
863 break;
866 else
868 alSetError(AL_INVALID_NAME);
871 else
873 alSetError(AL_INVALID_VALUE);
876 ProcessContext(pContext);
880 ALAPI ALvoid ALAPIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue)
882 ALCcontext *pContext;
883 ALbuffer *pBuffer;
885 pContext = alcGetCurrentContext();
886 SuspendContext(pContext);
888 if (plValue)
890 if (alIsBuffer(buffer) && (buffer != 0))
892 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
894 switch (eParam)
896 case AL_FREQUENCY:
897 *plValue = pBuffer->frequency;
898 break;
900 case AL_BITS:
901 *plValue = aluBytesFromFormat(pBuffer->format) * 8;
902 break;
904 case AL_CHANNELS:
905 *plValue = aluChannelsFromFormat(pBuffer->format);
906 break;
908 case AL_SIZE:
909 *plValue = pBuffer->size;
910 break;
912 default:
913 alSetError(AL_INVALID_ENUM);
914 break;
917 else
919 alSetError(AL_INVALID_NAME);
922 else
924 alSetError(AL_INVALID_VALUE);
927 ProcessContext(pContext);
931 ALAPI void ALAPIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3)
933 ALCcontext *pContext;
935 pContext = alcGetCurrentContext();
936 SuspendContext(pContext);
938 if ((plValue1) && (plValue2) && (plValue3))
940 if (alIsBuffer(buffer) && (buffer != 0))
942 switch(eParam)
944 default:
945 alSetError(AL_INVALID_ENUM);
946 break;
949 else
951 alSetError(AL_INVALID_NAME);
954 else
956 alSetError(AL_INVALID_VALUE);
959 ProcessContext(pContext);
963 ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues)
965 ALCcontext *pContext;
967 pContext = alcGetCurrentContext();
968 SuspendContext(pContext);
970 if (plValues)
972 if (alIsBuffer(buffer) && (buffer != 0))
974 switch (eParam)
976 case AL_FREQUENCY:
977 case AL_BITS:
978 case AL_CHANNELS:
979 case AL_SIZE:
980 alGetBufferi(buffer, eParam, plValues);
981 break;
983 default:
984 alSetError(AL_INVALID_ENUM);
985 break;
988 else
990 alSetError(AL_INVALID_NAME);
993 else
995 alSetError(AL_INVALID_VALUE);
998 ProcessContext(pContext);
1002 * LoadData
1004 * Loads the specified data into the buffer, using the specified formats.
1005 * Currently, the new format must be 16-bit, and must have the same channel
1006 * configuration as the original format. This does NOT handle compressed
1007 * formats (eg. IMA4).
1009 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
1011 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
1012 ALuint OrigBytes = aluBytesFromFormat(OrigFormat);
1013 ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
1014 ALsizei padding = freq / LOWPASSFREQCUTOFF;
1015 ALvoid *temp;
1016 ALsizei i;
1018 assert(aluBytesFromFormat(NewFormat) == 2);
1019 assert(NewChannels == OrigChannels);
1021 if ((size%(OrigBytes*OrigChannels)) != 0)
1023 alSetError(AL_INVALID_VALUE);
1024 return;
1027 /* Ensure at least one padding byte for the bilinear filter */
1028 if(padding < 1)
1029 padding = 1;
1031 // Samples are converted to 16 bit here
1032 size /= OrigBytes;
1033 temp = realloc(ALBuf->data, (padding*NewChannels + size) * sizeof(ALshort));
1034 if(temp)
1036 ALBuf->data = temp;
1038 switch(OrigBytes)
1040 case 1:
1041 for(i = 0;i < size;i++)
1042 ALBuf->data[i] = (ALshort)((data[i]-128) << 8);
1043 break;
1045 case 2:
1046 memcpy(ALBuf->data, data, size*sizeof(ALshort));
1047 break;
1049 case 4:
1050 for(i = 0;i < size;i++)
1052 ALint smp;
1053 smp = (((ALfloat*)data)[i] * 32767.5f - 0.5f);
1054 smp = min(smp, 32767);
1055 smp = max(smp, -32768);
1056 ALBuf->data[i] = (ALshort)smp;
1058 break;
1060 default:
1061 assert(0);
1064 memset(&(ALBuf->data[size]), 0, padding*NewChannels*sizeof(ALshort));
1066 ALBuf->format = NewFormat;
1067 ALBuf->eOriginalFormat = OrigFormat;
1068 ALBuf->size = size*sizeof(ALshort);
1069 ALBuf->frequency = freq;
1070 ALBuf->padding = padding;
1072 else
1073 alSetError(AL_OUT_OF_MEMORY);
1078 * ReleaseALBuffers()
1080 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
1082 ALvoid ReleaseALBuffers(ALvoid)
1084 ALbuffer *ALBuffer;
1085 ALbuffer *ALBufferTemp;
1087 #ifdef _DEBUG
1088 if(g_uiBufferCount > 0)
1089 AL_PRINT("exit(): deleting %d Buffer(s)\n", g_uiBufferCount);
1090 #endif
1092 ALBuffer = g_pBuffers;
1093 while(ALBuffer)
1095 // Release sample data
1096 free(ALBuffer->data);
1098 // Release Buffer structure
1099 ALBufferTemp = ALBuffer;
1100 ALBuffer = ALBuffer->next;
1101 memset(ALBufferTemp, 0, sizeof(ALbuffer));
1102 free(ALBufferTemp);
1104 g_pBuffers = NULL;
1105 g_uiBufferCount = 0;