Be careful of integer overflows when allocating buffer storage
[openal-soft/android/lowlatency.git] / OpenAL32 / alBuffer.c
blobf1144c25ddec9ee444ea6fad8c68190899751c4d
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 #include "config.h"
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <assert.h>
26 #include <limits.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 "alDatabuffer.h"
34 #include "alThunk.h"
37 static ALenum LoadData(ALbuffer *ALBuf, const ALvoid *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat);
38 static void ConvertData(ALfloat *dst, const ALvoid *src, ALint origBytes, ALsizei len);
39 static void ConvertDataRear(ALfloat *dst, const ALvoid *src, ALint origBytes, ALsizei len);
40 static void ConvertDataIMA4(ALfloat *dst, const ALvoid *src, ALint origChans, ALsizei len);
41 static void ConvertDataMULaw(ALfloat *dst, const ALvoid *src, ALsizei len);
42 static void ConvertDataMULawRear(ALfloat *dst, const ALvoid *src, ALsizei len);
44 #define LookupBuffer(m, k) ((ALbuffer*)LookupUIntMapKey(&(m), (k)))
47 * Global Variables
50 static const long g_IMAStep_size[89]={ // IMA ADPCM Stepsize table
51 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
52 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
53 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
54 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
55 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493,10442,11487,12635,13899,
56 15289,16818,18500,20350,22358,24633,27086,29794,32767
59 static const long g_IMACodeword_4[16]={ // IMA4 ADPCM Codeword decode table
60 1, 3, 5, 7, 9, 11, 13, 15,
61 -1,-3,-5,-7,-9,-11,-13,-15,
64 static const long g_IMAIndex_adjust_4[16]={ // IMA4 ADPCM Step index adjust decode table
65 -1,-1,-1,-1, 2, 4, 6, 8,
66 -1,-1,-1,-1, 2, 4, 6, 8
69 static const ALshort muLawDecompressionTable[256] = {
70 -32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956,
71 -23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764,
72 -15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412,
73 -11900,-11388,-10876,-10364, -9852, -9340, -8828, -8316,
74 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
75 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
76 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
77 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
78 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
79 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
80 -876, -844, -812, -780, -748, -716, -684, -652,
81 -620, -588, -556, -524, -492, -460, -428, -396,
82 -372, -356, -340, -324, -308, -292, -276, -260,
83 -244, -228, -212, -196, -180, -164, -148, -132,
84 -120, -112, -104, -96, -88, -80, -72, -64,
85 -56, -48, -40, -32, -24, -16, -8, 0,
86 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
87 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
88 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
89 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
90 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
91 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
92 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
93 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
94 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
95 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
96 876, 844, 812, 780, 748, 716, 684, 652,
97 620, 588, 556, 524, 492, 460, 428, 396,
98 372, 356, 340, 324, 308, 292, 276, 260,
99 244, 228, 212, 196, 180, 164, 148, 132,
100 120, 112, 104, 96, 88, 80, 72, 64,
101 56, 48, 40, 32, 24, 16, 8, 0
105 * alGenBuffers(ALsizei n, ALuint *puiBuffers)
107 * Generates n AL Buffers, and stores the Buffers Names in the array pointed to by puiBuffers
109 AL_API ALvoid AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers)
111 ALCcontext *Context;
112 ALsizei i=0;
114 Context = GetContextSuspended();
115 if(!Context) return;
117 // Check that we are actually generation some Buffers
118 if(n > 0)
120 ALCdevice *device = Context->Device;
121 ALenum err;
123 // Check the pointer is valid (and points to enough memory to store Buffer Names)
124 if(!IsBadWritePtr((void*)buffers, n * sizeof(ALuint)))
126 // Create all the new Buffers
127 while(i < n)
129 ALbuffer *buffer = calloc(1, sizeof(ALbuffer));
130 if(!buffer)
132 alSetError(Context, AL_OUT_OF_MEMORY);
133 alDeleteBuffers(i, buffers);
134 break;
137 buffer->buffer = (ALuint)ALTHUNK_ADDENTRY(buffer);
138 err = InsertUIntMapEntry(&device->BufferMap, buffer->buffer,
139 buffer);
140 if(err != AL_NO_ERROR)
142 ALTHUNK_REMOVEENTRY(buffer->buffer);
143 memset(buffer, 0, sizeof(ALbuffer));
144 free(buffer);
146 alSetError(Context, err);
147 alDeleteBuffers(i, buffers);
148 break;
150 buffers[i++] = buffer->buffer;
153 else
155 // Pointer does not point to enough memory to write Buffer names
156 alSetError(Context, AL_INVALID_VALUE);
160 ProcessContext(Context);
164 * alDeleteBuffers(ALsizei n, ALuint *puiBuffers)
166 * Deletes the n AL Buffers pointed to by puiBuffers
168 AL_API ALvoid AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *puiBuffers)
170 ALCcontext *Context;
171 ALbuffer *ALBuf;
172 ALsizei i;
173 ALboolean bFailed = AL_FALSE;
175 Context = GetContextSuspended();
176 if(!Context) return;
178 // Check we are actually Deleting some Buffers
179 if (n >= 0)
181 ALCdevice *device = Context->Device;
183 // Check that all the buffers are valid and can actually be deleted
184 for (i = 0; i < n; i++)
186 if(!puiBuffers[i])
187 continue;
189 // Check for valid Buffer ID (can be NULL buffer)
190 if((ALBuf=LookupBuffer(device->BufferMap, puiBuffers[i])) != NULL)
192 if(ALBuf->refcount != 0)
194 // Buffer still in use, cannot be deleted
195 alSetError(Context, AL_INVALID_OPERATION);
196 bFailed = AL_TRUE;
197 break;
200 else
202 // Invalid Buffer
203 alSetError(Context, AL_INVALID_NAME);
204 bFailed = AL_TRUE;
205 break;
209 // If all the Buffers were valid (and have Reference Counts of 0), then we can delete them
210 if (!bFailed)
212 for (i = 0; i < n; i++)
214 if((ALBuf=LookupBuffer(device->BufferMap, puiBuffers[i])) != NULL)
216 // Release the memory used to store audio data
217 free(ALBuf->data);
219 // Release buffer structure
220 RemoveUIntMapKey(&device->BufferMap, ALBuf->buffer);
221 ALTHUNK_REMOVEENTRY(ALBuf->buffer);
223 memset(ALBuf, 0, sizeof(ALbuffer));
224 free(ALBuf);
229 else
230 alSetError(Context, AL_INVALID_VALUE);
232 ProcessContext(Context);
236 * alIsBuffer(ALuint uiBuffer)
238 * Checks if ulBuffer is a valid Buffer Name
240 AL_API ALboolean AL_APIENTRY alIsBuffer(ALuint buffer)
242 ALCcontext *Context;
243 ALboolean result;
245 Context = GetContextSuspended();
246 if(!Context) return AL_FALSE;
248 result = ((!buffer || LookupBuffer(Context->Device->BufferMap, buffer)) ?
249 AL_TRUE : AL_FALSE);
251 ProcessContext(Context);
253 return result;
257 * alBufferData(ALuint buffer,ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
259 * Fill buffer with audio data
261 AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq)
263 ALCcontext *Context;
264 ALCdevice *device;
265 ALbuffer *ALBuf;
266 ALvoid *temp;
267 ALenum err;
269 Context = GetContextSuspended();
270 if(!Context) return;
272 device = Context->Device;
273 if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL)
274 alSetError(Context, AL_INVALID_NAME); /* Invalid Buffer Name */
275 else
277 if(Context->SampleSource)
279 ALintptrEXT offset;
281 if(Context->SampleSource->state == MAPPED)
283 alSetError(Context, AL_INVALID_OPERATION);
284 ProcessContext(Context);
285 return;
288 offset = (const ALubyte*)data - (ALubyte*)NULL;
289 data = Context->SampleSource->data + offset;
292 if(size < 0)
293 alSetError(Context, AL_INVALID_VALUE);
294 else if(ALBuf->refcount != 0)
295 alSetError(Context, AL_INVALID_VALUE);
296 else
298 switch(format)
300 case AL_FORMAT_MONO8:
301 case AL_FORMAT_MONO16:
302 case AL_FORMAT_MONO_FLOAT32:
303 case AL_FORMAT_MONO_DOUBLE_EXT:
304 err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO_FLOAT32);
305 if(err != AL_NO_ERROR)
306 alSetError(Context, err);
307 break;
309 case AL_FORMAT_STEREO8:
310 case AL_FORMAT_STEREO16:
311 case AL_FORMAT_STEREO_FLOAT32:
312 case AL_FORMAT_STEREO_DOUBLE_EXT:
313 err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO_FLOAT32);
314 if(err != AL_NO_ERROR)
315 alSetError(Context, err);
316 break;
318 case AL_FORMAT_REAR8:
319 case AL_FORMAT_REAR16:
320 case AL_FORMAT_REAR32: {
321 ALenum NewFormat = AL_FORMAT_QUAD32;
322 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
323 ALuint NewBytes = aluBytesFromFormat(NewFormat);
324 ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
325 ((format==AL_FORMAT_REAR16) ? 2 :
326 4));
327 ALuint64 newsize, allocsize;
329 if((size%(OrigBytes*2)) != 0)
331 alSetError(Context, AL_INVALID_VALUE);
332 break;
335 newsize = size / OrigBytes;
336 newsize *= 2;
338 allocsize = (BUFFER_PADDING*NewChannels + newsize)*NewBytes;
339 if(allocsize > INT_MAX)
341 alSetError(Context, AL_OUT_OF_MEMORY);
342 break;
344 temp = realloc(ALBuf->data, allocsize);
345 if(temp)
347 ALBuf->data = temp;
348 ConvertDataRear(ALBuf->data, data, OrigBytes, newsize);
350 ALBuf->format = NewFormat;
351 ALBuf->eOriginalFormat = format;
352 ALBuf->size = newsize*NewBytes;
353 ALBuf->frequency = freq;
355 ALBuf->LoopStart = 0;
356 ALBuf->LoopEnd = newsize / NewChannels;
358 ALBuf->OriginalSize = size;
359 ALBuf->OriginalAlign = OrigBytes * 2;
361 else
362 alSetError(Context, AL_OUT_OF_MEMORY);
363 } break;
365 case AL_FORMAT_QUAD8_LOKI:
366 case AL_FORMAT_QUAD16_LOKI:
367 case AL_FORMAT_QUAD8:
368 case AL_FORMAT_QUAD16:
369 case AL_FORMAT_QUAD32:
370 err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD32);
371 if(err != AL_NO_ERROR)
372 alSetError(Context, err);
373 break;
375 case AL_FORMAT_51CHN8:
376 case AL_FORMAT_51CHN16:
377 case AL_FORMAT_51CHN32:
378 err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN32);
379 if(err != AL_NO_ERROR)
380 alSetError(Context, err);
381 break;
383 case AL_FORMAT_61CHN8:
384 case AL_FORMAT_61CHN16:
385 case AL_FORMAT_61CHN32:
386 err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN32);
387 if(err != AL_NO_ERROR)
388 alSetError(Context, err);
389 break;
391 case AL_FORMAT_71CHN8:
392 case AL_FORMAT_71CHN16:
393 case AL_FORMAT_71CHN32:
394 err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN32);
395 if(err != AL_NO_ERROR)
396 alSetError(Context, err);
397 break;
399 case AL_FORMAT_MONO_IMA4:
400 case AL_FORMAT_STEREO_IMA4: {
401 int Channels = ((format==AL_FORMAT_MONO_IMA4) ? 1 : 2);
402 ALenum NewFormat = ((Channels==1) ? AL_FORMAT_MONO_FLOAT32 :
403 AL_FORMAT_STEREO_FLOAT32);
404 ALuint NewBytes = aluBytesFromFormat(NewFormat);
405 ALuint64 newsize, allocsize;
407 // Here is where things vary:
408 // nVidia and Apple use 64+1 samples per channel per block => block_size=36*chans bytes
409 // Most PC sound software uses 2040+1 samples per channel per block -> block_size=1024*chans bytes
410 if((size%(36*Channels)) != 0)
412 alSetError(Context, AL_INVALID_VALUE);
413 break;
416 newsize = size / 36;
417 newsize *= 65;
419 allocsize = (BUFFER_PADDING*Channels + newsize)*NewBytes;
420 if(allocsize > INT_MAX)
422 alSetError(Context, AL_OUT_OF_MEMORY);
423 break;
425 temp = realloc(ALBuf->data, allocsize);
426 if(temp)
428 ALBuf->data = temp;
429 ConvertDataIMA4(ALBuf->data, data, Channels, newsize/65);
431 ALBuf->format = NewFormat;
432 ALBuf->eOriginalFormat = format;
433 ALBuf->size = newsize*NewBytes;
434 ALBuf->frequency = freq;
436 ALBuf->LoopStart = 0;
437 ALBuf->LoopEnd = newsize / Channels;
439 ALBuf->OriginalSize = size;
440 ALBuf->OriginalAlign = 36 * Channels;
442 else
443 alSetError(Context, AL_OUT_OF_MEMORY);
444 } break;
446 case AL_FORMAT_MONO_MULAW:
447 case AL_FORMAT_STEREO_MULAW:
448 case AL_FORMAT_QUAD_MULAW:
449 case AL_FORMAT_51CHN_MULAW:
450 case AL_FORMAT_61CHN_MULAW:
451 case AL_FORMAT_71CHN_MULAW: {
452 int Channels = ((format==AL_FORMAT_MONO_MULAW) ? 1 :
453 ((format==AL_FORMAT_STEREO_MULAW) ? 2 :
454 ((format==AL_FORMAT_QUAD_MULAW) ? 4 :
455 ((format==AL_FORMAT_51CHN_MULAW) ? 6 :
456 ((format==AL_FORMAT_61CHN_MULAW) ? 7 : 8)))));
457 ALenum NewFormat = ((Channels==1) ? AL_FORMAT_MONO_FLOAT32 :
458 ((Channels==2) ? AL_FORMAT_STEREO_FLOAT32 :
459 ((Channels==4) ? AL_FORMAT_QUAD32 :
460 ((Channels==6) ? AL_FORMAT_51CHN32 :
461 ((Channels==7) ? AL_FORMAT_61CHN32 :
462 AL_FORMAT_71CHN32)))));
463 ALuint NewBytes = aluBytesFromFormat(NewFormat);
464 ALuint64 allocsize;
466 if((size%(1*Channels)) != 0)
468 alSetError(Context, AL_INVALID_VALUE);
469 break;
472 allocsize = (BUFFER_PADDING*Channels + size)*NewBytes;
473 if(allocsize > INT_MAX)
475 alSetError(Context, AL_OUT_OF_MEMORY);
476 break;
478 temp = realloc(ALBuf->data, allocsize);
479 if(temp)
481 ALBuf->data = temp;
482 ConvertDataMULaw(ALBuf->data, data, size);
484 ALBuf->format = NewFormat;
485 ALBuf->eOriginalFormat = format;
486 ALBuf->size = size*NewBytes;
487 ALBuf->frequency = freq;
489 ALBuf->LoopStart = 0;
490 ALBuf->LoopEnd = size / Channels;
492 ALBuf->OriginalSize = size;
493 ALBuf->OriginalAlign = 1 * Channels;
495 else
496 alSetError(Context, AL_OUT_OF_MEMORY);
497 } break;
499 case AL_FORMAT_REAR_MULAW: {
500 ALenum NewFormat = AL_FORMAT_QUAD32;
501 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
502 ALuint NewBytes = aluBytesFromFormat(NewFormat);
503 ALuint64 newsize, allocsize;
505 if((size%(1*2)) != 0)
507 alSetError(Context, AL_INVALID_VALUE);
508 break;
511 newsize = size * 2;
513 allocsize = (BUFFER_PADDING*NewChannels + newsize)*NewBytes;
514 if(allocsize > INT_MAX)
516 alSetError(Context, AL_OUT_OF_MEMORY);
517 break;
519 temp = realloc(ALBuf->data, allocsize);
520 if(temp)
522 ALBuf->data = temp;
523 ConvertDataMULawRear(ALBuf->data, data, newsize);
525 ALBuf->format = NewFormat;
526 ALBuf->eOriginalFormat = format;
527 ALBuf->size = newsize*NewBytes;
528 ALBuf->frequency = freq;
530 ALBuf->LoopStart = 0;
531 ALBuf->LoopEnd = newsize / NewChannels;
533 ALBuf->OriginalSize = size;
534 ALBuf->OriginalAlign = 1 * 2;
536 else
537 alSetError(Context, AL_OUT_OF_MEMORY);
538 } break;
540 default:
541 alSetError(Context, AL_INVALID_ENUM);
542 break;
547 ProcessContext(Context);
551 * alBufferSubDataEXT(ALuint buffer,ALenum format,ALvoid *data,ALsizei offset,ALsizei length)
553 * Fill buffer with audio data
555 AL_API ALvoid AL_APIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length)
557 ALCcontext *Context;
558 ALCdevice *device;
559 ALbuffer *ALBuf;
561 Context = GetContextSuspended();
562 if(!Context) return;
564 device = Context->Device;
565 if((ALBuf=LookupBuffer(device->BufferMap, buffer)) != NULL)
567 if(Context->SampleSource)
569 ALintptrEXT offset;
571 if(Context->SampleSource->state == MAPPED)
573 alSetError(Context, AL_INVALID_OPERATION);
574 ProcessContext(Context);
575 return;
578 offset = (const ALubyte*)data - (ALubyte*)NULL;
579 data = Context->SampleSource->data + offset;
582 if(length < 0 || offset < 0 || (length > 0 && data == NULL))
584 // data is NULL or offset/length is negative
585 alSetError(Context, AL_INVALID_VALUE);
587 else if(ALBuf->eOriginalFormat != format)
588 alSetError(Context, AL_INVALID_ENUM);
589 else if(ALBuf->OriginalAlign == 0 ||
590 (offset%ALBuf->OriginalAlign) != 0 ||
591 (length%ALBuf->OriginalAlign) != 0 ||
592 offset+length > ALBuf->OriginalSize)
593 alSetError(Context, AL_INVALID_VALUE);
594 else
596 switch(format)
598 case AL_FORMAT_MONO8:
599 case AL_FORMAT_MONO16:
600 case AL_FORMAT_MONO_FLOAT32:
601 case AL_FORMAT_MONO_DOUBLE_EXT:
602 case AL_FORMAT_STEREO8:
603 case AL_FORMAT_STEREO16:
604 case AL_FORMAT_STEREO_FLOAT32:
605 case AL_FORMAT_STEREO_DOUBLE_EXT:
606 case AL_FORMAT_QUAD8_LOKI:
607 case AL_FORMAT_QUAD16_LOKI:
608 case AL_FORMAT_QUAD8:
609 case AL_FORMAT_QUAD16:
610 case AL_FORMAT_QUAD32:
611 case AL_FORMAT_51CHN8:
612 case AL_FORMAT_51CHN16:
613 case AL_FORMAT_51CHN32:
614 case AL_FORMAT_61CHN8:
615 case AL_FORMAT_61CHN16:
616 case AL_FORMAT_61CHN32:
617 case AL_FORMAT_71CHN8:
618 case AL_FORMAT_71CHN16:
619 case AL_FORMAT_71CHN32: {
620 ALuint Bytes = aluBytesFromFormat(format);
622 offset /= Bytes;
623 length /= Bytes;
625 ConvertData(&ALBuf->data[offset], data, Bytes, length);
626 } break;
628 case AL_FORMAT_REAR8:
629 case AL_FORMAT_REAR16:
630 case AL_FORMAT_REAR32: {
631 ALuint Bytes = ((format==AL_FORMAT_REAR8) ? 1 :
632 ((format==AL_FORMAT_REAR16) ? 2 :
633 4));
635 offset /= Bytes;
636 offset *= 2;
637 length /= Bytes;
638 length *= 2;
640 ConvertDataRear(&ALBuf->data[offset], data, Bytes, length);
641 } break;
643 case AL_FORMAT_MONO_IMA4:
644 case AL_FORMAT_STEREO_IMA4: {
645 int Channels = aluChannelsFromFormat(ALBuf->format);
647 // offset -> sample*channel offset, length -> block count
648 offset /= 36;
649 offset *= 65;
650 length /= 36;
652 ConvertDataIMA4(&ALBuf->data[offset], data, Channels, length);
653 } break;
655 case AL_FORMAT_MONO_MULAW:
656 case AL_FORMAT_STEREO_MULAW:
657 case AL_FORMAT_QUAD_MULAW:
658 case AL_FORMAT_51CHN_MULAW:
659 case AL_FORMAT_61CHN_MULAW:
660 case AL_FORMAT_71CHN_MULAW:
661 ConvertDataMULaw(&ALBuf->data[offset], data, length);
662 break;
664 case AL_FORMAT_REAR_MULAW:
665 offset *= 2;
666 length *= 2;
667 ConvertDataMULawRear(&ALBuf->data[offset], data, length);
668 break;
670 default:
671 alSetError(Context, AL_INVALID_ENUM);
672 break;
676 else
678 // Invalid Buffer Name
679 alSetError(Context, AL_INVALID_NAME);
682 ProcessContext(Context);
686 AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
688 ALCcontext *pContext;
689 ALCdevice *device;
691 (void)flValue;
693 pContext = GetContextSuspended();
694 if(!pContext) return;
696 device = pContext->Device;
697 if(LookupBuffer(device->BufferMap, buffer) != NULL)
699 switch(eParam)
701 default:
702 alSetError(pContext, AL_INVALID_ENUM);
703 break;
706 else
708 alSetError(pContext, AL_INVALID_NAME);
711 ProcessContext(pContext);
715 AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
717 ALCcontext *pContext;
718 ALCdevice *device;
720 (void)flValue1;
721 (void)flValue2;
722 (void)flValue3;
724 pContext = GetContextSuspended();
725 if(!pContext) return;
727 device = pContext->Device;
728 if(LookupBuffer(device->BufferMap, buffer) != NULL)
730 switch(eParam)
732 default:
733 alSetError(pContext, AL_INVALID_ENUM);
734 break;
737 else
739 alSetError(pContext, AL_INVALID_NAME);
742 ProcessContext(pContext);
746 AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues)
748 ALCcontext *pContext;
749 ALCdevice *device;
751 (void)flValues;
753 pContext = GetContextSuspended();
754 if(!pContext) return;
756 device = pContext->Device;
757 if(LookupBuffer(device->BufferMap, buffer) != NULL)
759 switch(eParam)
761 default:
762 alSetError(pContext, AL_INVALID_ENUM);
763 break;
766 else
768 alSetError(pContext, AL_INVALID_NAME);
771 ProcessContext(pContext);
775 AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
777 ALCcontext *pContext;
778 ALCdevice *device;
780 (void)lValue;
782 pContext = GetContextSuspended();
783 if(!pContext) return;
785 device = pContext->Device;
786 if(LookupBuffer(device->BufferMap, buffer) != NULL)
788 switch(eParam)
790 default:
791 alSetError(pContext, AL_INVALID_ENUM);
792 break;
795 else
797 alSetError(pContext, AL_INVALID_NAME);
800 ProcessContext(pContext);
804 AL_API void AL_APIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
806 ALCcontext *pContext;
807 ALCdevice *device;
809 (void)lValue1;
810 (void)lValue2;
811 (void)lValue3;
813 pContext = GetContextSuspended();
814 if(!pContext) return;
816 device = pContext->Device;
817 if(LookupBuffer(device->BufferMap, buffer) != NULL)
819 switch(eParam)
821 default:
822 alSetError(pContext, AL_INVALID_ENUM);
823 break;
826 else
828 alSetError(pContext, AL_INVALID_NAME);
831 ProcessContext(pContext);
835 AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues)
837 ALCcontext *pContext;
838 ALCdevice *device;
839 ALbuffer *ALBuf;
841 (void)plValues;
843 pContext = GetContextSuspended();
844 if(!pContext) return;
846 device = pContext->Device;
847 if((ALBuf=LookupBuffer(device->BufferMap, buffer)) != NULL)
849 switch(eParam)
851 case AL_LOOP_POINTS:
852 if(ALBuf->refcount > 0)
853 alSetError(pContext, AL_INVALID_OPERATION);
854 else if(plValues[0] < 0 || plValues[1] < 0 ||
855 plValues[0] >= plValues[1] || ALBuf->size == 0)
856 alSetError(pContext, AL_INVALID_VALUE);
857 else
859 ALint maxlen = ALBuf->size / aluBytesFromFormat(ALBuf->format) /
860 aluChannelsFromFormat(ALBuf->format);
861 if(plValues[0] > maxlen || plValues[1] > maxlen)
862 alSetError(pContext, AL_INVALID_VALUE);
863 else
865 ALBuf->LoopStart = plValues[0];
866 ALBuf->LoopEnd = plValues[1];
869 break;
871 default:
872 alSetError(pContext, AL_INVALID_ENUM);
873 break;
876 else
878 alSetError(pContext, AL_INVALID_NAME);
881 ProcessContext(pContext);
885 AL_API ALvoid AL_APIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue)
887 ALCcontext *pContext;
888 ALCdevice *device;
890 pContext = GetContextSuspended();
891 if(!pContext) return;
893 if (pflValue)
895 device = pContext->Device;
896 if(LookupBuffer(device->BufferMap, buffer) != NULL)
898 switch(eParam)
900 default:
901 alSetError(pContext, AL_INVALID_ENUM);
902 break;
905 else
907 alSetError(pContext, AL_INVALID_NAME);
910 else
912 alSetError(pContext, AL_INVALID_VALUE);
915 ProcessContext(pContext);
919 AL_API void AL_APIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3)
921 ALCcontext *pContext;
922 ALCdevice *device;
924 pContext = GetContextSuspended();
925 if(!pContext) return;
927 if ((pflValue1) && (pflValue2) && (pflValue3))
929 device = pContext->Device;
930 if(LookupBuffer(device->BufferMap, buffer) != NULL)
932 switch(eParam)
934 default:
935 alSetError(pContext, AL_INVALID_ENUM);
936 break;
939 else
941 alSetError(pContext, AL_INVALID_NAME);
944 else
946 alSetError(pContext, AL_INVALID_VALUE);
949 ProcessContext(pContext);
953 AL_API void AL_APIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues)
955 ALCcontext *pContext;
956 ALCdevice *device;
958 pContext = GetContextSuspended();
959 if(!pContext) return;
961 if (pflValues)
963 device = pContext->Device;
964 if(LookupBuffer(device->BufferMap, buffer) != NULL)
966 switch(eParam)
968 default:
969 alSetError(pContext, AL_INVALID_ENUM);
970 break;
973 else
975 alSetError(pContext, AL_INVALID_NAME);
978 else
980 alSetError(pContext, AL_INVALID_VALUE);
983 ProcessContext(pContext);
987 AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue)
989 ALCcontext *pContext;
990 ALbuffer *pBuffer;
991 ALCdevice *device;
993 pContext = GetContextSuspended();
994 if(!pContext) return;
996 if (plValue)
998 device = pContext->Device;
999 if((pBuffer=LookupBuffer(device->BufferMap, buffer)) != NULL)
1001 switch (eParam)
1003 case AL_FREQUENCY:
1004 *plValue = pBuffer->frequency;
1005 break;
1007 case AL_BITS:
1008 *plValue = aluBytesFromFormat(pBuffer->format) * 8;
1009 break;
1011 case AL_CHANNELS:
1012 *plValue = aluChannelsFromFormat(pBuffer->format);
1013 break;
1015 case AL_SIZE:
1016 *plValue = pBuffer->size;
1017 break;
1019 default:
1020 alSetError(pContext, AL_INVALID_ENUM);
1021 break;
1024 else
1026 alSetError(pContext, AL_INVALID_NAME);
1029 else
1031 alSetError(pContext, AL_INVALID_VALUE);
1034 ProcessContext(pContext);
1038 AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3)
1040 ALCcontext *pContext;
1041 ALCdevice *device;
1043 pContext = GetContextSuspended();
1044 if(!pContext) return;
1046 if ((plValue1) && (plValue2) && (plValue3))
1048 device = pContext->Device;
1049 if(LookupBuffer(device->BufferMap, buffer) != NULL)
1051 switch(eParam)
1053 default:
1054 alSetError(pContext, AL_INVALID_ENUM);
1055 break;
1058 else
1060 alSetError(pContext, AL_INVALID_NAME);
1063 else
1065 alSetError(pContext, AL_INVALID_VALUE);
1068 ProcessContext(pContext);
1072 AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues)
1074 ALCcontext *pContext;
1075 ALCdevice *device;
1076 ALbuffer *ALBuf;
1078 pContext = GetContextSuspended();
1079 if(!pContext) return;
1081 if (plValues)
1083 device = pContext->Device;
1084 if((ALBuf=LookupBuffer(device->BufferMap, buffer)) != NULL)
1086 switch (eParam)
1088 case AL_FREQUENCY:
1089 case AL_BITS:
1090 case AL_CHANNELS:
1091 case AL_SIZE:
1092 alGetBufferi(buffer, eParam, plValues);
1093 break;
1095 case AL_LOOP_POINTS:
1096 plValues[0] = ALBuf->LoopStart;
1097 plValues[1] = ALBuf->LoopEnd;
1098 break;
1100 default:
1101 alSetError(pContext, AL_INVALID_ENUM);
1102 break;
1105 else
1107 alSetError(pContext, AL_INVALID_NAME);
1110 else
1112 alSetError(pContext, AL_INVALID_VALUE);
1115 ProcessContext(pContext);
1119 * LoadData
1121 * Loads the specified data into the buffer, using the specified formats.
1122 * Currently, the new format must be 32-bit float, and must have the same
1123 * channel configuration as the original format. This does NOT handle
1124 * compressed formats (eg. IMA4).
1126 static ALenum LoadData(ALbuffer *ALBuf, const ALvoid *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
1128 ALuint NewBytes = aluBytesFromFormat(NewFormat);
1129 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
1130 ALuint OrigBytes = aluBytesFromFormat(OrigFormat);
1131 ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
1132 ALuint64 newsize, allocsize;
1133 ALvoid *temp;
1135 assert(NewBytes == 4);
1136 assert(NewChannels == OrigChannels);
1138 if ((size%(OrigBytes*OrigChannels)) != 0)
1139 return AL_INVALID_VALUE;
1141 // Allocate extra padding samples
1142 newsize = size / OrigBytes;
1143 allocsize = (BUFFER_PADDING*NewChannels + newsize)*NewBytes;
1144 if(allocsize > INT_MAX)
1145 return AL_OUT_OF_MEMORY;
1147 temp = realloc(ALBuf->data, allocsize);
1148 if(!temp) return AL_OUT_OF_MEMORY;
1149 ALBuf->data = temp;
1151 // Samples are converted here
1152 ConvertData(ALBuf->data, data, OrigBytes, newsize);
1154 ALBuf->format = NewFormat;
1155 ALBuf->eOriginalFormat = OrigFormat;
1156 ALBuf->size = newsize*NewBytes;
1157 ALBuf->frequency = freq;
1159 ALBuf->LoopStart = 0;
1160 ALBuf->LoopEnd = newsize / NewChannels;
1162 ALBuf->OriginalSize = size;
1163 ALBuf->OriginalAlign = OrigBytes * OrigChannels;
1165 return AL_NO_ERROR;
1168 static void ConvertData(ALfloat *dst, const ALvoid *src, ALint origBytes, ALsizei len)
1170 ALsizei i;
1171 ALint smp;
1172 if(src == NULL)
1173 return;
1174 switch(origBytes)
1176 case 1:
1177 for(i = 0;i < len;i++)
1179 smp = ((ALubyte*)src)[i];
1180 dst[i] = ((smp < 0x80) ? ((smp-128)/128.0f) : ((smp-128)/127.0f));
1182 break;
1184 case 2:
1185 for(i = 0;i < len;i++)
1187 smp = ((ALshort*)src)[i];
1188 dst[i] = ((smp < 0) ? (smp/32768.0f) : (smp/32767.0f));
1190 break;
1192 case 4:
1193 for(i = 0;i < len;i++)
1194 dst[i] = ((ALfloat*)src)[i];
1195 break;
1197 case 8:
1198 for(i = 0;i < len;i++)
1199 dst[i] = ((ALdouble*)src)[i];
1200 break;
1202 default:
1203 assert(0);
1207 static void ConvertDataRear(ALfloat *dst, const ALvoid *src, ALint origBytes, ALsizei len)
1209 ALsizei i;
1210 ALint smp;
1211 if(src == NULL)
1212 return;
1213 switch(origBytes)
1215 case 1:
1216 for(i = 0;i < len;i+=4)
1218 dst[i+0] = 0;
1219 dst[i+1] = 0;
1220 smp = ((ALubyte*)src)[i/2+0];
1221 dst[i+2] = ((smp < 0x80) ? ((smp-128)/128.0f) : ((smp-128)/127.0f));
1222 smp = ((ALubyte*)src)[i/2+1];
1223 dst[i+3] = ((smp < 0x80) ? ((smp-128)/128.0f) : ((smp-128)/127.0f));
1225 break;
1227 case 2:
1228 for(i = 0;i < len;i+=4)
1230 dst[i+0] = 0;
1231 dst[i+1] = 0;
1232 smp = ((ALshort*)src)[i/2+0];
1233 dst[i+2] = ((smp < 0) ? (smp/32768.0f) : (smp/32767.0f));
1234 smp = ((ALshort*)src)[i/2+1];
1235 dst[i+3] = ((smp < 0) ? (smp/32768.0f) : (smp/32767.0f));
1237 break;
1239 case 4:
1240 for(i = 0;i < len;i+=4)
1242 dst[i+0] = 0;
1243 dst[i+1] = 0;
1244 dst[i+2] = ((ALfloat*)src)[i/2+0];
1245 dst[i+3] = ((ALfloat*)src)[i/2+1];
1247 break;
1249 default:
1250 assert(0);
1254 static void ConvertDataIMA4(ALfloat *dst, const ALvoid *src, ALint origChans, ALsizei len)
1256 const ALubyte *IMAData;
1257 ALint Sample[2],Index[2];
1258 ALuint IMACode[2];
1259 ALsizei i,j,k,c;
1261 if(src == NULL)
1262 return;
1264 IMAData = src;
1265 for(i = 0;i < len/origChans;i++)
1267 for(c = 0;c < origChans;c++)
1269 Sample[c] = IMAData[0];
1270 Sample[c] |= IMAData[1] << 8;
1271 Sample[c] = (Sample[c]^0x8000) - 32768;
1272 Index[c] = IMAData[2];
1273 Index[c] |= IMAData[3] << 8;
1274 Index[c] = (Index[c]^0x8000) - 32768;
1276 Index[c] = ((Index[c]<0) ? 0 : Index[c]);
1277 Index[c] = ((Index[c]>88) ? 88 : Index[c]);
1279 dst[i*65*origChans + c] = ((Sample[c] < 0) ? (Sample[c]/32768.0f) : (Sample[c]/32767.0f));
1281 IMAData += 4;
1284 for(j = 1;j < 65;j += 8)
1286 for(c = 0;c < origChans;c++)
1288 IMACode[c] = *(IMAData++);
1289 IMACode[c] |= *(IMAData++) << 8;
1290 IMACode[c] |= *(IMAData++) << 16;
1291 IMACode[c] |= *(IMAData++) << 24;
1294 for(k = 0;k < 8;k++)
1296 for(c = 0;c < origChans;c++)
1298 Sample[c] += ((g_IMAStep_size[Index[c]]*g_IMACodeword_4[IMACode[c]&15])/8);
1299 Index[c] += g_IMAIndex_adjust_4[IMACode[c]&15];
1301 if(Sample[c] < -32768) Sample[c] = -32768;
1302 else if(Sample[c] > 32767) Sample[c] = 32767;
1304 if(Index[c]<0) Index[c] = 0;
1305 else if(Index[c]>88) Index[c] = 88;
1307 dst[(i*65+j+k)*origChans + c] = ((Sample[c] < 0) ? (Sample[c]/32768.0f) : (Sample[c]/32767.0f));
1308 IMACode[c] >>= 4;
1315 static void ConvertDataMULaw(ALfloat *dst, const ALvoid *src, ALsizei len)
1317 ALsizei i;
1318 ALint smp;
1319 if(src == NULL)
1320 return;
1321 for(i = 0;i < len;i++)
1323 smp = muLawDecompressionTable[((ALubyte*)src)[i]];
1324 dst[i] = ((smp < 0) ? (smp/32768.0f) : (smp/32767.0f));
1328 static void ConvertDataMULawRear(ALfloat *dst, const ALvoid *src, ALsizei len)
1330 ALsizei i;
1331 ALint smp;
1332 if(src == NULL)
1333 return;
1334 for(i = 0;i < len;i+=4)
1336 dst[i+0] = 0;
1337 dst[i+1] = 0;
1338 smp = muLawDecompressionTable[((ALubyte*)src)[i/2+0]];
1339 dst[i+2] = ((smp < 0) ? (smp/32768.0f) : (smp/32767.0f));
1340 smp = muLawDecompressionTable[((ALubyte*)src)[i/2+1]];
1341 dst[i+3] = ((smp < 0) ? (smp/32768.0f) : (smp/32767.0f));
1346 * ReleaseALBuffers()
1348 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
1350 ALvoid ReleaseALBuffers(ALCdevice *device)
1352 ALsizei i;
1353 for(i = 0;i < device->BufferMap.size;i++)
1355 ALbuffer *temp = device->BufferMap.array[i].value;
1356 device->BufferMap.array[i].value = NULL;
1358 // Release sample data
1359 free(temp->data);
1361 // Release Buffer structure
1362 ALTHUNK_REMOVEENTRY(temp->buffer);
1363 memset(temp, 0, sizeof(ALbuffer));
1364 free(temp);