comparison ext/openal-soft/OpenAL32/alBuffer.c @ 89:fa33cda75471

* Reverting back to 2543 as requested by sleek
author mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222
date Sat, 19 Jul 2008 11:38:52 +0000
parents 4a0efb7baf70
children
comparison
equal deleted inserted replaced
88:1c2842ebe393 89:fa33cda75471
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.
8 *
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.
13 *
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
19 */
20
21 #define _CRT_SECURE_NO_DEPRECATE // get rid of sprintf security warnings on VS2005
22
23 #include "config.h"
24
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"
34
35
36 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat);
37
38 /*
39 * AL Buffer Functions
40 *
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
44 *
45 */
46
47 /*
48 * Global Variables
49 */
50
51 static ALbuffer *g_pBuffers = NULL; // Linked List of Buffers
52 static ALuint g_uiBufferCount = 0; // Buffer Count
53
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
61 };
62
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,
66 };
67
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
71 };
72
73 /*
74 * alGenBuffers(ALsizei n, ALuint *puiBuffers)
75 *
76 * Generates n AL Buffers, and stores the Buffers Names in the array pointed to by puiBuffers
77 */
78 ALAPI ALvoid ALAPIENTRY alGenBuffers(ALsizei n,ALuint *puiBuffers)
79 {
80 ALCcontext *Context;
81 ALsizei i=0;
82
83 Context = alcGetCurrentContext();
84 SuspendContext(Context);
85
86 // Check that we are actually generation some Buffers
87 if (n > 0)
88 {
89 // Check the pointer is valid (and points to enough memory to store Buffer Names)
90 if (!IsBadWritePtr((void*)puiBuffers, n * sizeof(ALuint)))
91 {
92 ALbuffer **list = &g_pBuffers;
93 while(*list)
94 list = &(*list)->next;
95
96 // Create all the new Buffers
97 while(i < n)
98 {
99 *list = calloc(1, sizeof(ALbuffer));
100 if(!(*list))
101 {
102 alDeleteBuffers(i, puiBuffers);
103 alSetError(AL_OUT_OF_MEMORY);
104 break;
105 }
106
107 puiBuffers[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
108 (*list)->state = UNUSED;
109 g_uiBufferCount++;
110 i++;
111
112 list = &(*list)->next;
113 }
114 }
115 else
116 {
117 // Pointer does not point to enough memory to write Buffer names
118 alSetError(AL_INVALID_VALUE);
119 }
120 }
121
122 ProcessContext(Context);
123
124 return;
125 }
126
127 /*
128 * alDeleteBuffers(ALsizei n, ALuint *puiBuffers)
129 *
130 * Deletes the n AL Buffers pointed to by puiBuffers
131 */
132 ALAPI ALvoid ALAPIENTRY alDeleteBuffers(ALsizei n, const ALuint *puiBuffers)
133 {
134 ALCcontext *Context;
135 ALbuffer *ALBuf;
136 ALsizei i;
137 ALboolean bFailed = AL_FALSE;
138
139 Context = alcGetCurrentContext();
140 SuspendContext(Context);
141
142 // Check we are actually Deleting some Buffers
143 if (n >= 0)
144 {
145 if ((ALuint)n <= g_uiBufferCount)
146 {
147 // Check that all the buffers are valid and can actually be deleted
148 for (i = 0; i < n; i++)
149 {
150 // Check for valid Buffer ID (can be NULL buffer)
151 if (alIsBuffer(puiBuffers[i]))
152 {
153 // If not the NULL buffer, check that the reference count is 0
154 ALBuf = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
155 if (ALBuf)
156 {
157 if (ALBuf->refcount != 0)
158 {
159 // Buffer still in use, cannot be deleted
160 alSetError(AL_INVALID_OPERATION);
161 bFailed = AL_TRUE;
162 }
163 }
164 }
165 else
166 {
167 // Invalid Buffer
168 alSetError(AL_INVALID_NAME);
169 bFailed = AL_TRUE;
170 }
171 }
172
173 // If all the Buffers were valid (and have Reference Counts of 0), then we can delete them
174 if (!bFailed)
175 {
176 for (i = 0; i < n; i++)
177 {
178 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
179 if (ALBuf)
180 {
181 ALbuffer **list = &g_pBuffers;
182 while(*list && *list != ALBuf)
183 list = &(*list)->next;
184
185 if(*list)
186 *list = (*list)->next;
187
188 // Release the memory used to store audio data
189 free(ALBuf->data);
190
191 // Release buffer structure
192 ALTHUNK_REMOVEENTRY(puiBuffers[i]);
193 memset(ALBuf, 0, sizeof(ALbuffer));
194 g_uiBufferCount--;
195 free(ALBuf);
196 }
197 }
198 }
199 }
200 else
201 alSetError(AL_INVALID_NAME);
202 }
203 else
204 alSetError(AL_INVALID_VALUE);
205
206 ProcessContext(Context);
207
208 return;
209
210 }
211
212 /*
213 * alIsBuffer(ALuint uiBuffer)
214 *
215 * Checks if ulBuffer is a valid Buffer Name
216 */
217 ALAPI ALboolean ALAPIENTRY alIsBuffer(ALuint uiBuffer)
218 {
219 ALCcontext *Context;
220 ALboolean result=AL_FALSE;
221 ALbuffer *ALBuf;
222 ALbuffer *TgtALBuf;
223
224 Context = alcGetCurrentContext();
225 SuspendContext(Context);
226
227 if (uiBuffer)
228 {
229 TgtALBuf = (ALbuffer *)ALTHUNK_LOOKUPENTRY(uiBuffer);
230
231 // Check through list of generated buffers for uiBuffer
232 ALBuf = g_pBuffers;
233 while (ALBuf)
234 {
235 if (ALBuf == TgtALBuf)
236 {
237 result = AL_TRUE;
238 break;
239 }
240
241 ALBuf = ALBuf->next;
242 }
243 }
244 else
245 {
246 result = AL_TRUE;
247 }
248
249
250 ProcessContext(Context);
251
252 return result;
253 }
254
255 /*
256 * alBufferData(ALuint buffer,ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
257 *
258 * Fill buffer with audio data
259 */
260 ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq)
261 {
262 ALuint *IMAData,IMACode;
263 ALCcontext *Context;
264 ALint Sample,Index;
265 ALint LeftSample,LeftIndex;
266 ALint RightSample,RightIndex;
267 ALuint LeftIMACode,RightIMACode;
268 ALbuffer *ALBuf;
269 ALsizei i,j,k;
270
271 Context = alcGetCurrentContext();
272 SuspendContext(Context);
273
274 if (alIsBuffer(buffer) && (buffer != 0))
275 {
276 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
277 if ((ALBuf->refcount==0)&&(data))
278 {
279 switch(format)
280 {
281 case AL_FORMAT_MONO8:
282 case AL_FORMAT_MONO16:
283 case AL_FORMAT_MONO_FLOAT32:
284 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO16);
285 break;
286
287 case AL_FORMAT_STEREO8:
288 case AL_FORMAT_STEREO16:
289 case AL_FORMAT_STEREO_FLOAT32:
290 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO16);
291 break;
292
293 case AL_FORMAT_REAR8:
294 case AL_FORMAT_REAR16:
295 case AL_FORMAT_REAR32: {
296 ALuint NewFormat = AL_FORMAT_QUAD16;
297 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
298 ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
299 ((format==AL_FORMAT_REAR16) ? 2 :
300 4));
301 ALsizei i;
302
303 assert(aluBytesFromFormat(NewFormat) == 2);
304
305 if ((size%(OrigBytes*2)) != 0)
306 {
307 alSetError(AL_INVALID_VALUE);
308 break;
309 }
310
311 switch(OrigBytes)
312 {
313 case 1:
314 size /= sizeof(ALubyte);
315 size *= 2;
316
317 // 8bit Samples are converted to 16 bit here
318 // Allocate 8 extra samples
319 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
320 if (ALBuf->data)
321 {
322 for (i = 0;i < size;i+=4)
323 {
324 ALBuf->data[i+0] = 0;
325 ALBuf->data[i+1] = 0;
326 ALBuf->data[i+2] = (ALshort)((((ALubyte*)data)[i/2+0]-128) << 8);
327 ALBuf->data[i+3] = (ALshort)((((ALubyte*)data)[i/2+1]-128) << 8);
328 }
329 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
330
331 ALBuf->format = NewFormat;
332 ALBuf->eOriginalFormat = format;
333 ALBuf->size = size*1*sizeof(ALshort);
334 ALBuf->frequency = freq;
335 }
336 else
337 alSetError(AL_OUT_OF_MEMORY);
338 break;
339
340 case 2:
341 size /= sizeof(ALshort);
342 size *= 2;
343
344 // Allocate 8 extra samples
345 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
346 if (ALBuf->data)
347 {
348 for (i = 0;i < size;i+=4)
349 {
350 ALBuf->data[i+0] = 0;
351 ALBuf->data[i+1] = 0;
352 ALBuf->data[i+2] = ((ALshort*)data)[i/2+0];
353 ALBuf->data[i+3] = ((ALshort*)data)[i/2+1];
354 }
355 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
356
357 ALBuf->format = NewFormat;
358 ALBuf->eOriginalFormat = format;
359 ALBuf->size = size*1*sizeof(ALshort);
360 ALBuf->frequency = freq;
361 }
362 else
363 alSetError(AL_OUT_OF_MEMORY);
364 break;
365
366 case 4:
367 size /= sizeof(ALfloat);
368 size *= 2;
369
370 // Allocate 8 extra samples
371 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
372 if (ALBuf->data)
373 {
374 ALint smp;
375 for (i = 0;i < size;i+=4)
376 {
377 ALBuf->data[i+0] = 0;
378 ALBuf->data[i+1] = 0;
379 smp = (((ALfloat*)data)[i/2+0] * 32767.5f - 0.5);
380 smp = min(smp, 32767);
381 smp = max(smp, -32768);
382 ALBuf->data[i+2] = (ALshort)smp;
383 smp = (((ALfloat*)data)[i/2+1] * 32767.5f - 0.5);
384 smp = min(smp, 32767);
385 smp = max(smp, -32768);
386 ALBuf->data[i+3] = (ALshort)smp;
387 }
388 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
389
390 ALBuf->format = NewFormat;
391 ALBuf->eOriginalFormat = format;
392 ALBuf->size = size*1*sizeof(ALshort);
393 ALBuf->frequency = freq;
394 }
395 else
396 alSetError(AL_OUT_OF_MEMORY);
397 break;
398
399 default:
400 assert(0);
401 }
402 } break;
403
404 case AL_FORMAT_QUAD8_LOKI:
405 case AL_FORMAT_QUAD16_LOKI:
406 case AL_FORMAT_QUAD8:
407 case AL_FORMAT_QUAD16:
408 case AL_FORMAT_QUAD32:
409 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD16);
410 break;
411
412 case AL_FORMAT_51CHN8:
413 case AL_FORMAT_51CHN16:
414 case AL_FORMAT_51CHN32:
415 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN16);
416 break;
417
418 case AL_FORMAT_61CHN8:
419 case AL_FORMAT_61CHN16:
420 case AL_FORMAT_61CHN32:
421 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN16);
422 break;
423
424 case AL_FORMAT_71CHN8:
425 case AL_FORMAT_71CHN16:
426 case AL_FORMAT_71CHN32:
427 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN16);
428 break;
429
430 case AL_FORMAT_MONO_IMA4:
431 // Here is where things vary:
432 // nVidia and Apple use 64+1 samples per block => block_size=36 bytes
433 // Most PC sound software uses 2040+1 samples per block -> block_size=1024 bytes
434 if ((size%36) == 0)
435 {
436 // Allocate 8 extra samples (16 bytes)
437 ALBuf->data=realloc(ALBuf->data,16+(size/36)*(65*sizeof(ALshort)));
438 if (ALBuf->data)
439 {
440 ALBuf->format = AL_FORMAT_MONO16;
441 ALBuf->eOriginalFormat = AL_FORMAT_MONO_IMA4;
442 IMAData=(ALuint *)data;
443 for (i=0;i<size/36;i++)
444 {
445 Sample=((ALshort *)IMAData)[0];
446 Index=((ALshort *)IMAData)[1];
447
448 Index=Index<0?0:Index;
449 Index=Index>88?88:Index;
450
451 ALBuf->data[i*65]=(short)Sample;
452
453 IMAData++;
454
455 for (j=1;j<65;j+=8)
456 {
457 IMACode=*IMAData;
458 for (k=0;k<8;k+=2)
459 {
460 Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8);
461 Index+=g_IMAIndex_adjust_4[IMACode&15];
462 if (Sample<-32768) Sample=-32768;
463 else if (Sample>32767) Sample=32767;
464 if (Index<0) Index=0;
465 else if (Index>88) Index=88;
466 ALBuf->data[i*65+j+k]=(short)Sample;
467 IMACode>>=4;
468
469 Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8);
470 Index+=g_IMAIndex_adjust_4[IMACode&15];
471 if (Sample<-32768) Sample=-32768;
472 else if (Sample>32767) Sample=32767;
473 if (Index<0) Index=0;
474 else if (Index>88) Index=88;
475 ALBuf->data[i*65+j+k+1]=(short)Sample;
476 IMACode>>=4;
477 }
478 IMAData++;
479 }
480 }
481 memset(&(ALBuf->data[(size/36*65)]), 0, 16);
482 ALBuf->size=size/36*65*sizeof(ALshort);
483 ALBuf->frequency=freq;
484 }
485 else
486 alSetError(AL_OUT_OF_MEMORY);
487 }
488 else
489 alSetError(AL_INVALID_VALUE);
490 break;
491
492 case AL_FORMAT_STEREO_IMA4:
493 // Here is where things vary:
494 // nVidia and Apple use 64+1 samples per channel per block => block_size=72 bytes
495 // Most PC sound software uses 2040+1 samples per channel per block -> block_size=2048 bytes
496 if ((size%72) == 0)
497 {
498 // Allocate 8 extra samples (32 bytes)
499 ALBuf->data=realloc(ALBuf->data,32+(size/72)*(2*65*sizeof(ALshort)));
500 if (ALBuf->data)
501 {
502 ALBuf->format = AL_FORMAT_STEREO16;
503 ALBuf->eOriginalFormat = AL_FORMAT_STEREO_IMA4;
504 IMAData=(ALuint *)data;
505 for (i=0;i<size/72;i++)
506 {
507 LeftSample=((ALshort *)IMAData)[0];
508 LeftIndex=((ALshort *)IMAData)[1];
509
510 LeftIndex=LeftIndex<0?0:LeftIndex;
511 LeftIndex=LeftIndex>88?88:LeftIndex;
512
513 ALBuf->data[i*2*65]=(short)LeftSample;
514
515 IMAData++;
516
517 RightSample=((ALshort *)IMAData)[0];
518 RightIndex=((ALshort *)IMAData)[1];
519
520 RightIndex=RightIndex<0?0:RightIndex;
521 RightIndex=RightIndex>88?88:RightIndex;
522
523 ALBuf->data[i*2*65+1]=(short)RightSample;
524
525 IMAData++;
526
527 for (j=2;j<130;j+=16)
528 {
529 LeftIMACode=IMAData[0];
530 RightIMACode=IMAData[1];
531 for (k=0;k<16;k+=4)
532 {
533 LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
534 LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15];
535 if (LeftSample<-32768) LeftSample=-32768;
536 else if (LeftSample>32767) LeftSample=32767;
537 if (LeftIndex<0) LeftIndex=0;
538 else if (LeftIndex>88) LeftIndex=88;
539 ALBuf->data[i*2*65+j+k]=(short)LeftSample;
540 LeftIMACode>>=4;
541
542 RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
543 RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
544 if (RightSample<-32768) RightSample=-32768;
545 else if (RightSample>32767) RightSample=32767;
546 if (RightIndex<0) RightIndex=0;
547 else if (RightIndex>88) RightIndex=88;
548 ALBuf->data[i*2*65+j+k+1]=(short)RightSample;
549 RightIMACode>>=4;
550
551 LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
552 LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15];
553 if (LeftSample<-32768) LeftSample=-32768;
554 else if (LeftSample>32767) LeftSample=32767;
555 if (LeftIndex<0) LeftIndex=0;
556 else if (LeftIndex>88) LeftIndex=88;
557 ALBuf->data[i*2*65+j+k+2]=(short)LeftSample;
558 LeftIMACode>>=4;
559
560 RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
561 RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
562 if (RightSample<-32768) RightSample=-32768;
563 else if (RightSample>32767) RightSample=32767;
564 if (RightIndex<0) RightIndex=0;
565 else if (RightIndex>88) RightIndex=88;
566 ALBuf->data[i*2*65+j+k+3]=(short)RightSample;
567 RightIMACode>>=4;
568 }
569 IMAData+=2;
570 }
571 }
572 memset(&(ALBuf->data[(size/72*2*65)]), 0, 32);
573 ALBuf->size=size/72*2*65*sizeof(ALshort);
574 ALBuf->frequency=freq;
575 }
576 else
577 alSetError(AL_OUT_OF_MEMORY);
578 }
579 else
580 alSetError(AL_INVALID_VALUE);
581 break;
582
583 default:
584 alSetError(AL_INVALID_ENUM);
585 break;
586 }
587 }
588 else
589 {
590 // Buffer is in use, or data is a NULL pointer
591 alSetError(AL_INVALID_VALUE);
592 }
593 }
594 else
595 {
596 // Invalid Buffer Name
597 alSetError(AL_INVALID_NAME);
598 }
599
600 ProcessContext(Context);
601 }
602
603
604 ALAPI void ALAPIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
605 {
606 ALCcontext *pContext;
607
608 (void)flValue;
609
610 pContext = alcGetCurrentContext();
611 SuspendContext(pContext);
612
613 if (alIsBuffer(buffer) && (buffer != 0))
614 {
615 switch(eParam)
616 {
617 default:
618 alSetError(AL_INVALID_ENUM);
619 break;
620 }
621 }
622 else
623 {
624 alSetError(AL_INVALID_NAME);
625 }
626
627 ProcessContext(pContext);
628 }
629
630
631 ALAPI void ALAPIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
632 {
633 ALCcontext *pContext;
634
635 (void)flValue1;
636 (void)flValue2;
637 (void)flValue3;
638
639 pContext = alcGetCurrentContext();
640 SuspendContext(pContext);
641
642 if (alIsBuffer(buffer) && (buffer != 0))
643 {
644 switch(eParam)
645 {
646 default:
647 alSetError(AL_INVALID_ENUM);
648 break;
649 }
650 }
651 else
652 {
653 alSetError(AL_INVALID_NAME);
654 }
655
656 ProcessContext(pContext);
657 }
658
659
660 ALAPI void ALAPIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues)
661 {
662 ALCcontext *pContext;
663
664 (void)flValues;
665
666 pContext = alcGetCurrentContext();
667 SuspendContext(pContext);
668
669 if (alIsBuffer(buffer) && (buffer != 0))
670 {
671 switch(eParam)
672 {
673 default:
674 alSetError(AL_INVALID_ENUM);
675 break;
676 }
677 }
678 else
679 {
680 alSetError(AL_INVALID_NAME);
681 }
682
683 ProcessContext(pContext);
684 }
685
686
687 ALAPI void ALAPIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
688 {
689 ALCcontext *pContext;
690
691 (void)lValue;
692
693 pContext = alcGetCurrentContext();
694 SuspendContext(pContext);
695
696 if (alIsBuffer(buffer) && (buffer != 0))
697 {
698 switch(eParam)
699 {
700 default:
701 alSetError(AL_INVALID_ENUM);
702 break;
703 }
704 }
705 else
706 {
707 alSetError(AL_INVALID_NAME);
708 }
709
710 ProcessContext(pContext);
711 }
712
713
714 ALAPI void ALAPIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
715 {
716 ALCcontext *pContext;
717
718 (void)lValue1;
719 (void)lValue2;
720 (void)lValue3;
721
722 pContext = alcGetCurrentContext();
723 SuspendContext(pContext);
724
725 if (alIsBuffer(buffer) && (buffer != 0))
726 {
727 switch(eParam)
728 {
729 default:
730 alSetError(AL_INVALID_ENUM);
731 break;
732 }
733 }
734 else
735 {
736 alSetError(AL_INVALID_NAME);
737 }
738
739 ProcessContext(pContext);
740 }
741
742
743 ALAPI void ALAPIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues)
744 {
745 ALCcontext *pContext;
746
747 (void)plValues;
748
749 pContext = alcGetCurrentContext();
750 SuspendContext(pContext);
751
752 if (alIsBuffer(buffer) && (buffer != 0))
753 {
754 switch(eParam)
755 {
756 default:
757 alSetError(AL_INVALID_ENUM);
758 break;
759 }
760 }
761 else
762 {
763 alSetError(AL_INVALID_NAME);
764 }
765
766 ProcessContext(pContext);
767 }
768
769
770 ALAPI ALvoid ALAPIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue)
771 {
772 ALCcontext *pContext;
773
774 pContext = alcGetCurrentContext();
775 SuspendContext(pContext);
776
777 if (pflValue)
778 {
779 if (alIsBuffer(buffer) && (buffer != 0))
780 {
781 switch(eParam)
782 {
783 default:
784 alSetError(AL_INVALID_ENUM);
785 break;
786 }
787 }
788 else
789 {
790 alSetError(AL_INVALID_NAME);
791 }
792 }
793 else
794 {
795 alSetError(AL_INVALID_VALUE);
796 }
797
798 ProcessContext(pContext);
799 }
800
801
802 ALAPI void ALAPIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3)
803 {
804 ALCcontext *pContext;
805
806 pContext = alcGetCurrentContext();
807 SuspendContext(pContext);
808
809 if ((pflValue1) && (pflValue2) && (pflValue3))
810 {
811 if (alIsBuffer(buffer) && (buffer != 0))
812 {
813 switch(eParam)
814 {
815 default:
816 alSetError(AL_INVALID_ENUM);
817 break;
818 }
819 }
820 else
821 {
822 alSetError(AL_INVALID_NAME);
823 }
824 }
825 else
826 {
827 alSetError(AL_INVALID_VALUE);
828 }
829
830 ProcessContext(pContext);
831 }
832
833
834 ALAPI void ALAPIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues)
835 {
836 ALCcontext *pContext;
837
838 pContext = alcGetCurrentContext();
839 SuspendContext(pContext);
840
841 if (pflValues)
842 {
843 if (alIsBuffer(buffer) && (buffer != 0))
844 {
845 switch(eParam)
846 {
847 default:
848 alSetError(AL_INVALID_ENUM);
849 break;
850 }
851 }
852 else
853 {
854 alSetError(AL_INVALID_NAME);
855 }
856 }
857 else
858 {
859 alSetError(AL_INVALID_VALUE);
860 }
861
862 ProcessContext(pContext);
863 }
864
865
866 ALAPI ALvoid ALAPIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue)
867 {
868 ALCcontext *pContext;
869 ALbuffer *pBuffer;
870
871 pContext = alcGetCurrentContext();
872 SuspendContext(pContext);
873
874 if (plValue)
875 {
876 if (alIsBuffer(buffer) && (buffer != 0))
877 {
878 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
879
880 switch (eParam)
881 {
882 case AL_FREQUENCY:
883 *plValue = pBuffer->frequency;
884 break;
885
886 case AL_BITS:
887 *plValue = aluBytesFromFormat(pBuffer->format) * 8;
888 break;
889
890 case AL_CHANNELS:
891 *plValue = aluChannelsFromFormat(pBuffer->format);
892 break;
893
894 case AL_SIZE:
895 *plValue = pBuffer->size;
896 break;
897
898 default:
899 alSetError(AL_INVALID_ENUM);
900 break;
901 }
902 }
903 else
904 {
905 alSetError(AL_INVALID_NAME);
906 }
907 }
908 else
909 {
910 alSetError(AL_INVALID_VALUE);
911 }
912
913 ProcessContext(pContext);
914 }
915
916
917 ALAPI void ALAPIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3)
918 {
919 ALCcontext *pContext;
920
921 pContext = alcGetCurrentContext();
922 SuspendContext(pContext);
923
924 if ((plValue1) && (plValue2) && (plValue3))
925 {
926 if (alIsBuffer(buffer) && (buffer != 0))
927 {
928 switch(eParam)
929 {
930 default:
931 alSetError(AL_INVALID_ENUM);
932 break;
933 }
934 }
935 else
936 {
937 alSetError(AL_INVALID_NAME);
938 }
939 }
940 else
941 {
942 alSetError(AL_INVALID_VALUE);
943 }
944
945 ProcessContext(pContext);
946 }
947
948
949 ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues)
950 {
951 ALCcontext *pContext;
952
953 pContext = alcGetCurrentContext();
954 SuspendContext(pContext);
955
956 if (plValues)
957 {
958 if (alIsBuffer(buffer) && (buffer != 0))
959 {
960 switch (eParam)
961 {
962 case AL_FREQUENCY:
963 case AL_BITS:
964 case AL_CHANNELS:
965 case AL_SIZE:
966 alGetBufferi(buffer, eParam, plValues);
967 break;
968
969 default:
970 alSetError(AL_INVALID_ENUM);
971 break;
972 }
973 }
974 else
975 {
976 alSetError(AL_INVALID_NAME);
977 }
978 }
979 else
980 {
981 alSetError(AL_INVALID_VALUE);
982 }
983
984 ProcessContext(pContext);
985 }
986
987 /*
988 * LoadData
989 *
990 * Loads the specified data into the buffer, using the specified formats.
991 * Currently, the new format must be 16-bit, and must have the same channel
992 * configuration as the original format. This does NOT handle compressed
993 * formats (eg. IMA4).
994 */
995 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
996 {
997 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
998 ALuint OrigBytes = aluBytesFromFormat(OrigFormat);
999 ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
1000 ALsizei i;
1001
1002 assert(aluBytesFromFormat(NewFormat) == 2);
1003 assert(NewChannels == OrigChannels);
1004
1005 if ((size%(OrigBytes*OrigChannels)) != 0)
1006 {
1007 alSetError(AL_INVALID_VALUE);
1008 return;
1009 }
1010
1011 switch(OrigBytes)
1012 {
1013 case 1:
1014 size /= sizeof(ALubyte);
1015
1016 // 8bit Samples are converted to 16 bit here
1017 // Allocate 8 extra samples
1018 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
1019 if (ALBuf->data)
1020 {
1021 for (i = 0;i < size;i++)
1022 ALBuf->data[i] = (ALshort)((data[i]-128) << 8);
1023 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
1024
1025 ALBuf->format = NewFormat;
1026 ALBuf->eOriginalFormat = OrigFormat;
1027 ALBuf->size = size*1*sizeof(ALshort);
1028 ALBuf->frequency = freq;
1029 }
1030 else
1031 alSetError(AL_OUT_OF_MEMORY);
1032 break;
1033
1034 case 2:
1035 size /= sizeof(ALshort);
1036
1037 // Allocate 8 extra samples
1038 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
1039 if (ALBuf->data)
1040 {
1041 memcpy(ALBuf->data, data, size*1*sizeof(ALshort));
1042 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
1043
1044 ALBuf->format = NewFormat;
1045 ALBuf->eOriginalFormat = OrigFormat;
1046 ALBuf->size = size*1*sizeof(ALshort);
1047 ALBuf->frequency = freq;
1048 }
1049 else
1050 alSetError(AL_OUT_OF_MEMORY);
1051 break;
1052
1053 case 4:
1054 size /= sizeof(ALfloat);
1055
1056 // Allocate 8 extra samples
1057 ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort)));
1058 if (ALBuf->data)
1059 {
1060 ALint smp;
1061 for (i = 0;i < size;i++)
1062 {
1063 smp = (((ALfloat*)data)[i] * 32767.5f - 0.5f);
1064 smp = min(smp, 32767);
1065 smp = max(smp, -32768);
1066 ALBuf->data[i] = (ALshort)smp;
1067 }
1068 memset(&(ALBuf->data[size]), 0, 16*NewChannels);
1069
1070 ALBuf->format = NewFormat;
1071 ALBuf->eOriginalFormat = OrigFormat;
1072 ALBuf->size = size*1*sizeof(ALshort);
1073 ALBuf->frequency = freq;
1074 }
1075 else
1076 alSetError(AL_OUT_OF_MEMORY);
1077 break;
1078
1079 default:
1080 assert(0);
1081 }
1082 }
1083
1084
1085 /*
1086 * ReleaseALBuffers()
1087 *
1088 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
1089 */
1090 ALvoid ReleaseALBuffers(ALvoid)
1091 {
1092 ALbuffer *ALBuffer;
1093 ALbuffer *ALBufferTemp;
1094
1095 #ifdef _DEBUG
1096 if(g_uiBufferCount > 0)
1097 AL_PRINT("exit() %d Buffer(s) NOT deleted\n", g_uiBufferCount);
1098 #endif
1099
1100 ALBuffer = g_pBuffers;
1101 while(ALBuffer)
1102 {
1103 // Release sample data
1104 free(ALBuffer->data);
1105
1106 // Release Buffer structure
1107 ALBufferTemp = ALBuffer;
1108 ALBuffer = ALBuffer->next;
1109 memset(ALBufferTemp, 0, sizeof(ALbuffer));
1110 free(ALBufferTemp);
1111 }
1112 g_pBuffers = NULL;
1113 g_uiBufferCount = 0;
1114 }