Mercurial > fife-parpg
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 } |