Implement AL_SOFT_buffer_sub_data using the current AL_EXT_buffer_sub_data spec
[openal-soft.git] / OpenAL32 / alBuffer.c
blob6ea11cdd7dbd8578ccd2704291c20384c495d410
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)
119 alSetError(Context, AL_INVALID_VALUE);
120 else
122 ALCdevice *device = Context->Device;
123 ALenum err;
125 // Check the pointer is valid (and points to enough memory to store Buffer Names)
126 if(IsBadWritePtr((void*)buffers, n * sizeof(ALuint)))
127 alSetError(Context, AL_INVALID_VALUE);
128 else
130 // Create all the new Buffers
131 while(i < n)
133 ALbuffer *buffer = calloc(1, sizeof(ALbuffer));
134 if(!buffer)
136 alSetError(Context, AL_OUT_OF_MEMORY);
137 alDeleteBuffers(i, buffers);
138 break;
141 buffer->buffer = (ALuint)ALTHUNK_ADDENTRY(buffer);
142 err = InsertUIntMapEntry(&device->BufferMap, buffer->buffer,
143 buffer);
144 if(err != AL_NO_ERROR)
146 ALTHUNK_REMOVEENTRY(buffer->buffer);
147 memset(buffer, 0, sizeof(ALbuffer));
148 free(buffer);
150 alSetError(Context, err);
151 alDeleteBuffers(i, buffers);
152 break;
154 buffers[i++] = buffer->buffer;
159 ProcessContext(Context);
163 * alDeleteBuffers(ALsizei n, ALuint *puiBuffers)
165 * Deletes the n AL Buffers pointed to by puiBuffers
167 AL_API ALvoid AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *puiBuffers)
169 ALCcontext *Context;
170 ALbuffer *ALBuf;
171 ALsizei i;
173 Context = GetContextSuspended();
174 if(!Context) return;
176 // Check we are actually Deleting some Buffers
177 if(n < 0)
178 alSetError(Context, AL_INVALID_VALUE);
179 else
181 ALCdevice *device = Context->Device;
182 ALboolean bFailed = AL_FALSE;
184 // Check that all the buffers are valid and can actually be deleted
185 for(i = 0;i < n;i++)
187 if(!puiBuffers[i])
188 continue;
190 // Check for valid Buffer ID (can be NULL buffer)
191 if((ALBuf=LookupBuffer(device->BufferMap, puiBuffers[i])) != NULL)
193 if(ALBuf->refcount != 0)
195 // Buffer still in use, cannot be deleted
196 alSetError(Context, AL_INVALID_OPERATION);
197 bFailed = AL_TRUE;
198 break;
201 else
203 // Invalid Buffer
204 alSetError(Context, AL_INVALID_NAME);
205 bFailed = AL_TRUE;
206 break;
210 // If all the Buffers were valid (and have Reference Counts of 0), then we can delete them
211 if(!bFailed)
213 for(i = 0;i < n;i++)
215 if((ALBuf=LookupBuffer(device->BufferMap, puiBuffers[i])) != NULL)
217 // Release the memory used to store audio data
218 free(ALBuf->data);
220 // Release buffer structure
221 RemoveUIntMapKey(&device->BufferMap, ALBuf->buffer);
222 ALTHUNK_REMOVEENTRY(ALBuf->buffer);
224 memset(ALBuf, 0, sizeof(ALbuffer));
225 free(ALBuf);
231 ProcessContext(Context);
235 * alIsBuffer(ALuint uiBuffer)
237 * Checks if ulBuffer is a valid Buffer Name
239 AL_API ALboolean AL_APIENTRY alIsBuffer(ALuint buffer)
241 ALCcontext *Context;
242 ALboolean result;
244 Context = GetContextSuspended();
245 if(!Context) return AL_FALSE;
247 result = ((!buffer || LookupBuffer(Context->Device->BufferMap, buffer)) ?
248 AL_TRUE : AL_FALSE);
250 ProcessContext(Context);
252 return result;
256 * alBufferData(ALuint buffer,ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
258 * Fill buffer with audio data
260 AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq)
262 ALCcontext *Context;
263 ALCdevice *device;
264 ALbuffer *ALBuf;
265 ALvoid *temp;
266 ALenum err;
268 Context = GetContextSuspended();
269 if(!Context) return;
271 device = Context->Device;
272 if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL)
273 alSetError(Context, AL_INVALID_NAME); /* Invalid Buffer Name */
274 else
276 if(Context->SampleSource)
278 ALintptrEXT offset;
280 if(Context->SampleSource->state == MAPPED)
282 alSetError(Context, AL_INVALID_OPERATION);
283 ProcessContext(Context);
284 return;
287 offset = (const ALubyte*)data - (ALubyte*)NULL;
288 data = Context->SampleSource->data + offset;
291 if(size < 0 || freq < 0)
292 alSetError(Context, AL_INVALID_VALUE);
293 else if(ALBuf->refcount != 0)
294 alSetError(Context, AL_INVALID_VALUE);
295 else
297 switch(format)
299 case AL_FORMAT_MONO8:
300 case AL_FORMAT_MONO16:
301 case AL_FORMAT_MONO_FLOAT32:
302 case AL_FORMAT_MONO_DOUBLE_EXT:
303 err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO_FLOAT32);
304 if(err != AL_NO_ERROR)
305 alSetError(Context, err);
306 break;
308 case AL_FORMAT_STEREO8:
309 case AL_FORMAT_STEREO16:
310 case AL_FORMAT_STEREO_FLOAT32:
311 case AL_FORMAT_STEREO_DOUBLE_EXT:
312 err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO_FLOAT32);
313 if(err != AL_NO_ERROR)
314 alSetError(Context, err);
315 break;
317 case AL_FORMAT_REAR8:
318 case AL_FORMAT_REAR16:
319 case AL_FORMAT_REAR32: {
320 ALenum NewFormat = AL_FORMAT_QUAD32;
321 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
322 ALuint NewBytes = aluBytesFromFormat(NewFormat);
323 ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
324 ((format==AL_FORMAT_REAR16) ? 2 :
325 4));
326 ALuint64 newsize, allocsize;
328 if((size%(OrigBytes*2)) != 0)
330 alSetError(Context, AL_INVALID_VALUE);
331 break;
334 newsize = size / OrigBytes;
335 newsize *= 2;
337 allocsize = (BUFFER_PADDING*NewChannels + newsize)*NewBytes;
338 if(allocsize > INT_MAX)
340 alSetError(Context, AL_OUT_OF_MEMORY);
341 break;
343 temp = realloc(ALBuf->data, allocsize);
344 if(temp)
346 ALBuf->data = temp;
347 ConvertDataRear(ALBuf->data, data, OrigBytes, newsize);
349 ALBuf->format = NewFormat;
350 ALBuf->eOriginalFormat = format;
351 ALBuf->size = newsize*NewBytes;
352 ALBuf->frequency = freq;
354 ALBuf->LoopStart = 0;
355 ALBuf->LoopEnd = newsize / NewChannels;
357 ALBuf->OriginalSize = size;
358 ALBuf->OriginalAlign = OrigBytes * 2;
360 else
361 alSetError(Context, AL_OUT_OF_MEMORY);
362 } break;
364 case AL_FORMAT_QUAD8_LOKI:
365 case AL_FORMAT_QUAD16_LOKI:
366 case AL_FORMAT_QUAD8:
367 case AL_FORMAT_QUAD16:
368 case AL_FORMAT_QUAD32:
369 err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD32);
370 if(err != AL_NO_ERROR)
371 alSetError(Context, err);
372 break;
374 case AL_FORMAT_51CHN8:
375 case AL_FORMAT_51CHN16:
376 case AL_FORMAT_51CHN32:
377 err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN32);
378 if(err != AL_NO_ERROR)
379 alSetError(Context, err);
380 break;
382 case AL_FORMAT_61CHN8:
383 case AL_FORMAT_61CHN16:
384 case AL_FORMAT_61CHN32:
385 err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN32);
386 if(err != AL_NO_ERROR)
387 alSetError(Context, err);
388 break;
390 case AL_FORMAT_71CHN8:
391 case AL_FORMAT_71CHN16:
392 case AL_FORMAT_71CHN32:
393 err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN32);
394 if(err != AL_NO_ERROR)
395 alSetError(Context, err);
396 break;
398 case AL_FORMAT_MONO_IMA4:
399 case AL_FORMAT_STEREO_IMA4: {
400 int Channels = ((format==AL_FORMAT_MONO_IMA4) ? 1 : 2);
401 ALenum NewFormat = ((Channels==1) ? AL_FORMAT_MONO_FLOAT32 :
402 AL_FORMAT_STEREO_FLOAT32);
403 ALuint NewBytes = aluBytesFromFormat(NewFormat);
404 ALuint64 newsize, allocsize;
406 // Here is where things vary:
407 // nVidia and Apple use 64+1 samples per channel per block => block_size=36*chans bytes
408 // Most PC sound software uses 2040+1 samples per channel per block -> block_size=1024*chans bytes
409 if((size%(36*Channels)) != 0)
411 alSetError(Context, AL_INVALID_VALUE);
412 break;
415 newsize = size / 36;
416 newsize *= 65;
418 allocsize = (BUFFER_PADDING*Channels + newsize)*NewBytes;
419 if(allocsize > INT_MAX)
421 alSetError(Context, AL_OUT_OF_MEMORY);
422 break;
424 temp = realloc(ALBuf->data, allocsize);
425 if(temp)
427 ALBuf->data = temp;
428 ConvertDataIMA4(ALBuf->data, data, Channels, newsize/(65*Channels));
430 ALBuf->format = NewFormat;
431 ALBuf->eOriginalFormat = format;
432 ALBuf->size = newsize*NewBytes;
433 ALBuf->frequency = freq;
435 ALBuf->LoopStart = 0;
436 ALBuf->LoopEnd = newsize / Channels;
438 ALBuf->OriginalSize = size;
439 ALBuf->OriginalAlign = 36 * Channels;
441 else
442 alSetError(Context, AL_OUT_OF_MEMORY);
443 } break;
445 case AL_FORMAT_MONO_MULAW:
446 case AL_FORMAT_STEREO_MULAW:
447 case AL_FORMAT_QUAD_MULAW:
448 case AL_FORMAT_51CHN_MULAW:
449 case AL_FORMAT_61CHN_MULAW:
450 case AL_FORMAT_71CHN_MULAW: {
451 int Channels = ((format==AL_FORMAT_MONO_MULAW) ? 1 :
452 ((format==AL_FORMAT_STEREO_MULAW) ? 2 :
453 ((format==AL_FORMAT_QUAD_MULAW) ? 4 :
454 ((format==AL_FORMAT_51CHN_MULAW) ? 6 :
455 ((format==AL_FORMAT_61CHN_MULAW) ? 7 : 8)))));
456 ALenum NewFormat = ((Channels==1) ? AL_FORMAT_MONO_FLOAT32 :
457 ((Channels==2) ? AL_FORMAT_STEREO_FLOAT32 :
458 ((Channels==4) ? AL_FORMAT_QUAD32 :
459 ((Channels==6) ? AL_FORMAT_51CHN32 :
460 ((Channels==7) ? AL_FORMAT_61CHN32 :
461 AL_FORMAT_71CHN32)))));
462 ALuint NewBytes = aluBytesFromFormat(NewFormat);
463 ALuint64 allocsize;
465 if((size%(1*Channels)) != 0)
467 alSetError(Context, AL_INVALID_VALUE);
468 break;
471 allocsize = (BUFFER_PADDING*Channels + size)*NewBytes;
472 if(allocsize > INT_MAX)
474 alSetError(Context, AL_OUT_OF_MEMORY);
475 break;
477 temp = realloc(ALBuf->data, allocsize);
478 if(temp)
480 ALBuf->data = temp;
481 ConvertDataMULaw(ALBuf->data, data, size);
483 ALBuf->format = NewFormat;
484 ALBuf->eOriginalFormat = format;
485 ALBuf->size = size*NewBytes;
486 ALBuf->frequency = freq;
488 ALBuf->LoopStart = 0;
489 ALBuf->LoopEnd = size / Channels;
491 ALBuf->OriginalSize = size;
492 ALBuf->OriginalAlign = 1 * Channels;
494 else
495 alSetError(Context, AL_OUT_OF_MEMORY);
496 } break;
498 case AL_FORMAT_REAR_MULAW: {
499 ALenum NewFormat = AL_FORMAT_QUAD32;
500 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
501 ALuint NewBytes = aluBytesFromFormat(NewFormat);
502 ALuint64 newsize, allocsize;
504 if((size%(1*2)) != 0)
506 alSetError(Context, AL_INVALID_VALUE);
507 break;
510 newsize = size * 2;
512 allocsize = (BUFFER_PADDING*NewChannels + newsize)*NewBytes;
513 if(allocsize > INT_MAX)
515 alSetError(Context, AL_OUT_OF_MEMORY);
516 break;
518 temp = realloc(ALBuf->data, allocsize);
519 if(temp)
521 ALBuf->data = temp;
522 ConvertDataMULawRear(ALBuf->data, data, newsize);
524 ALBuf->format = NewFormat;
525 ALBuf->eOriginalFormat = format;
526 ALBuf->size = newsize*NewBytes;
527 ALBuf->frequency = freq;
529 ALBuf->LoopStart = 0;
530 ALBuf->LoopEnd = newsize / NewChannels;
532 ALBuf->OriginalSize = size;
533 ALBuf->OriginalAlign = 1 * 2;
535 else
536 alSetError(Context, AL_OUT_OF_MEMORY);
537 } break;
539 default:
540 alSetError(Context, AL_INVALID_ENUM);
541 break;
546 ProcessContext(Context);
550 * alBufferSubDataSOFT(ALuint buffer,ALenum format,ALvoid *data,ALsizei offset,ALsizei length)
552 * Fill buffer with audio data
554 AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length)
556 ALCcontext *Context;
557 ALCdevice *device;
558 ALbuffer *ALBuf;
560 Context = GetContextSuspended();
561 if(!Context) return;
563 device = Context->Device;
564 if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL)
565 alSetError(Context, AL_INVALID_NAME);
566 else
568 if(Context->SampleSource)
570 ALintptrEXT offset;
572 if(Context->SampleSource->state == MAPPED)
574 alSetError(Context, AL_INVALID_OPERATION);
575 ProcessContext(Context);
576 return;
579 offset = (const ALubyte*)data - (ALubyte*)NULL;
580 data = Context->SampleSource->data + offset;
583 if(length < 0 || offset < 0 || (length > 0 && data == NULL))
584 alSetError(Context, AL_INVALID_VALUE);
585 else if(ALBuf->eOriginalFormat != format)
586 alSetError(Context, AL_INVALID_ENUM);
587 else if(offset > ALBuf->OriginalSize ||
588 length > ALBuf->OriginalSize-offset ||
589 (offset%ALBuf->OriginalAlign) != 0 ||
590 (length%ALBuf->OriginalAlign) != 0)
591 alSetError(Context, AL_INVALID_VALUE);
592 else
594 switch(format)
596 case AL_FORMAT_MONO8:
597 case AL_FORMAT_MONO16:
598 case AL_FORMAT_MONO_FLOAT32:
599 case AL_FORMAT_MONO_DOUBLE_EXT:
600 case AL_FORMAT_STEREO8:
601 case AL_FORMAT_STEREO16:
602 case AL_FORMAT_STEREO_FLOAT32:
603 case AL_FORMAT_STEREO_DOUBLE_EXT:
604 case AL_FORMAT_QUAD8_LOKI:
605 case AL_FORMAT_QUAD16_LOKI:
606 case AL_FORMAT_QUAD8:
607 case AL_FORMAT_QUAD16:
608 case AL_FORMAT_QUAD32:
609 case AL_FORMAT_51CHN8:
610 case AL_FORMAT_51CHN16:
611 case AL_FORMAT_51CHN32:
612 case AL_FORMAT_61CHN8:
613 case AL_FORMAT_61CHN16:
614 case AL_FORMAT_61CHN32:
615 case AL_FORMAT_71CHN8:
616 case AL_FORMAT_71CHN16:
617 case AL_FORMAT_71CHN32: {
618 ALuint Bytes = aluBytesFromFormat(format);
620 offset /= Bytes;
621 length /= Bytes;
623 ConvertData(&ALBuf->data[offset], data, Bytes, length);
624 } break;
626 case AL_FORMAT_REAR8:
627 case AL_FORMAT_REAR16:
628 case AL_FORMAT_REAR32: {
629 ALuint Bytes = ((format==AL_FORMAT_REAR8) ? 1 :
630 ((format==AL_FORMAT_REAR16) ? 2 :
631 4));
633 offset /= Bytes;
634 offset *= 2;
635 length /= Bytes;
636 length *= 2;
638 ConvertDataRear(&ALBuf->data[offset], data, Bytes, length);
639 } break;
641 case AL_FORMAT_MONO_IMA4:
642 case AL_FORMAT_STEREO_IMA4: {
643 int Channels = aluChannelsFromFormat(ALBuf->format);
645 // offset -> sample*channel offset, length -> block count
646 offset /= 36;
647 offset *= 65;
648 length /= ALBuf->OriginalAlign;
650 ConvertDataIMA4(&ALBuf->data[offset], data, Channels, length);
651 } break;
653 case AL_FORMAT_MONO_MULAW:
654 case AL_FORMAT_STEREO_MULAW:
655 case AL_FORMAT_QUAD_MULAW:
656 case AL_FORMAT_51CHN_MULAW:
657 case AL_FORMAT_61CHN_MULAW:
658 case AL_FORMAT_71CHN_MULAW:
659 ConvertDataMULaw(&ALBuf->data[offset], data, length);
660 break;
662 case AL_FORMAT_REAR_MULAW:
663 offset *= 2;
664 length *= 2;
665 ConvertDataMULawRear(&ALBuf->data[offset], data, length);
666 break;
668 default:
669 alSetError(Context, AL_INVALID_ENUM);
670 break;
675 ProcessContext(Context);
678 AL_API ALvoid AL_APIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length)
680 alBufferSubDataSOFT(buffer, format, data, offset, length);
684 AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
686 ALCcontext *pContext;
687 ALCdevice *device;
689 (void)flValue;
691 pContext = GetContextSuspended();
692 if(!pContext) return;
694 device = pContext->Device;
695 if(LookupBuffer(device->BufferMap, buffer) == NULL)
696 alSetError(pContext, AL_INVALID_NAME);
697 else
699 switch(eParam)
701 default:
702 alSetError(pContext, AL_INVALID_ENUM);
703 break;
707 ProcessContext(pContext);
711 AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
713 ALCcontext *pContext;
714 ALCdevice *device;
716 (void)flValue1;
717 (void)flValue2;
718 (void)flValue3;
720 pContext = GetContextSuspended();
721 if(!pContext) return;
723 device = pContext->Device;
724 if(LookupBuffer(device->BufferMap, buffer) == NULL)
725 alSetError(pContext, AL_INVALID_NAME);
726 else
728 switch(eParam)
730 default:
731 alSetError(pContext, AL_INVALID_ENUM);
732 break;
736 ProcessContext(pContext);
740 AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues)
742 ALCcontext *pContext;
743 ALCdevice *device;
745 pContext = GetContextSuspended();
746 if(!pContext) return;
748 device = pContext->Device;
749 if(!flValues)
750 alSetError(pContext, AL_INVALID_VALUE);
751 else if(LookupBuffer(device->BufferMap, buffer) == NULL)
752 alSetError(pContext, AL_INVALID_NAME);
753 else
755 switch(eParam)
757 default:
758 alSetError(pContext, AL_INVALID_ENUM);
759 break;
763 ProcessContext(pContext);
767 AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
769 ALCcontext *pContext;
770 ALCdevice *device;
772 (void)lValue;
774 pContext = GetContextSuspended();
775 if(!pContext) return;
777 device = pContext->Device;
778 if(LookupBuffer(device->BufferMap, buffer) == NULL)
779 alSetError(pContext, AL_INVALID_NAME);
780 else
782 switch(eParam)
784 default:
785 alSetError(pContext, AL_INVALID_ENUM);
786 break;
790 ProcessContext(pContext);
794 AL_API void AL_APIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
796 ALCcontext *pContext;
797 ALCdevice *device;
799 (void)lValue1;
800 (void)lValue2;
801 (void)lValue3;
803 pContext = GetContextSuspended();
804 if(!pContext) return;
806 device = pContext->Device;
807 if(LookupBuffer(device->BufferMap, buffer) == NULL)
808 alSetError(pContext, AL_INVALID_NAME);
809 else
811 switch(eParam)
813 default:
814 alSetError(pContext, AL_INVALID_ENUM);
815 break;
819 ProcessContext(pContext);
823 AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues)
825 ALCcontext *pContext;
826 ALCdevice *device;
827 ALbuffer *ALBuf;
829 pContext = GetContextSuspended();
830 if(!pContext) return;
832 device = pContext->Device;
833 if(!plValues)
834 alSetError(pContext, AL_INVALID_VALUE);
835 else if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL)
836 alSetError(pContext, AL_INVALID_NAME);
837 else
839 switch(eParam)
841 case AL_LOOP_POINTS:
842 if(ALBuf->refcount > 0)
843 alSetError(pContext, AL_INVALID_OPERATION);
844 else if(plValues[0] < 0 || plValues[1] < 0 ||
845 plValues[0] >= plValues[1] || ALBuf->size == 0)
846 alSetError(pContext, AL_INVALID_VALUE);
847 else
849 ALint maxlen = ALBuf->size / aluFrameSizeFromFormat(ALBuf->format);
850 if(plValues[0] > maxlen || plValues[1] > maxlen)
851 alSetError(pContext, AL_INVALID_VALUE);
852 else
854 ALBuf->LoopStart = plValues[0];
855 ALBuf->LoopEnd = plValues[1];
858 break;
860 default:
861 alSetError(pContext, AL_INVALID_ENUM);
862 break;
866 ProcessContext(pContext);
870 AL_API ALvoid AL_APIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue)
872 ALCcontext *pContext;
873 ALCdevice *device;
875 pContext = GetContextSuspended();
876 if(!pContext) return;
878 device = pContext->Device;
879 if(!pflValue)
880 alSetError(pContext, AL_INVALID_VALUE);
881 else if(LookupBuffer(device->BufferMap, buffer) == NULL)
882 alSetError(pContext, AL_INVALID_NAME);
883 else
885 switch(eParam)
887 default:
888 alSetError(pContext, AL_INVALID_ENUM);
889 break;
893 ProcessContext(pContext);
897 AL_API void AL_APIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3)
899 ALCcontext *pContext;
900 ALCdevice *device;
902 pContext = GetContextSuspended();
903 if(!pContext) return;
905 device = pContext->Device;
906 if(!pflValue1 || !pflValue2 || !pflValue3)
907 alSetError(pContext, AL_INVALID_VALUE);
908 else if(LookupBuffer(device->BufferMap, buffer) == NULL)
909 alSetError(pContext, AL_INVALID_NAME);
910 else
912 switch(eParam)
914 default:
915 alSetError(pContext, AL_INVALID_ENUM);
916 break;
920 ProcessContext(pContext);
924 AL_API void AL_APIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues)
926 ALCcontext *pContext;
927 ALCdevice *device;
929 pContext = GetContextSuspended();
930 if(!pContext) return;
932 device = pContext->Device;
933 if(!pflValues)
934 alSetError(pContext, AL_INVALID_VALUE);
935 else if(LookupBuffer(device->BufferMap, buffer) == NULL)
936 alSetError(pContext, AL_INVALID_NAME);
937 else
939 switch(eParam)
941 default:
942 alSetError(pContext, AL_INVALID_ENUM);
943 break;
947 ProcessContext(pContext);
951 AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue)
953 ALCcontext *pContext;
954 ALbuffer *pBuffer;
955 ALCdevice *device;
957 pContext = GetContextSuspended();
958 if(!pContext) return;
960 device = pContext->Device;
961 if(!plValue)
962 alSetError(pContext, AL_INVALID_VALUE);
963 else if((pBuffer=LookupBuffer(device->BufferMap, buffer)) == NULL)
964 alSetError(pContext, AL_INVALID_NAME);
965 else
967 switch(eParam)
969 case AL_FREQUENCY:
970 *plValue = pBuffer->frequency;
971 break;
973 case AL_BITS:
974 *plValue = aluBytesFromFormat(pBuffer->format) * 8;
975 break;
977 case AL_CHANNELS:
978 *plValue = aluChannelsFromFormat(pBuffer->format);
979 break;
981 case AL_SIZE:
982 *plValue = pBuffer->size;
983 break;
985 default:
986 alSetError(pContext, AL_INVALID_ENUM);
987 break;
991 ProcessContext(pContext);
995 AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3)
997 ALCcontext *pContext;
998 ALCdevice *device;
1000 pContext = GetContextSuspended();
1001 if(!pContext) return;
1003 device = pContext->Device;
1004 if(!plValue1 || !plValue2 || !plValue3)
1005 alSetError(pContext, AL_INVALID_VALUE);
1006 else if(LookupBuffer(device->BufferMap, buffer) == NULL)
1007 alSetError(pContext, AL_INVALID_NAME);
1008 else
1010 switch(eParam)
1012 default:
1013 alSetError(pContext, AL_INVALID_ENUM);
1014 break;
1018 ProcessContext(pContext);
1022 AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues)
1024 ALCcontext *pContext;
1025 ALCdevice *device;
1026 ALbuffer *ALBuf;
1028 pContext = GetContextSuspended();
1029 if(!pContext) return;
1031 device = pContext->Device;
1032 if(!plValues)
1033 alSetError(pContext, AL_INVALID_VALUE);
1034 else if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL)
1035 alSetError(pContext, AL_INVALID_NAME);
1036 else
1038 switch(eParam)
1040 case AL_FREQUENCY:
1041 case AL_BITS:
1042 case AL_CHANNELS:
1043 case AL_SIZE:
1044 alGetBufferi(buffer, eParam, plValues);
1045 break;
1047 case AL_LOOP_POINTS:
1048 plValues[0] = ALBuf->LoopStart;
1049 plValues[1] = ALBuf->LoopEnd;
1050 break;
1052 default:
1053 alSetError(pContext, AL_INVALID_ENUM);
1054 break;
1058 ProcessContext(pContext);
1062 * LoadData
1064 * Loads the specified data into the buffer, using the specified formats.
1065 * Currently, the new format must be 32-bit float, and must have the same
1066 * channel configuration as the original format. This does NOT handle
1067 * compressed formats (eg. IMA4).
1069 static ALenum LoadData(ALbuffer *ALBuf, const ALvoid *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
1071 ALuint NewBytes = aluBytesFromFormat(NewFormat);
1072 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
1073 ALuint OrigBytes = aluBytesFromFormat(OrigFormat);
1074 ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
1075 ALuint64 newsize, allocsize;
1076 ALvoid *temp;
1078 assert(NewBytes == 4);
1079 assert(NewChannels == OrigChannels);
1081 if((size%(OrigBytes*OrigChannels)) != 0)
1082 return AL_INVALID_VALUE;
1084 // Allocate extra padding samples
1085 newsize = size / OrigBytes;
1086 allocsize = (BUFFER_PADDING*NewChannels + newsize)*NewBytes;
1087 if(allocsize > INT_MAX)
1088 return AL_OUT_OF_MEMORY;
1090 temp = realloc(ALBuf->data, allocsize);
1091 if(!temp) return AL_OUT_OF_MEMORY;
1092 ALBuf->data = temp;
1094 // Samples are converted here
1095 ConvertData(ALBuf->data, data, OrigBytes, newsize);
1097 ALBuf->format = NewFormat;
1098 ALBuf->eOriginalFormat = OrigFormat;
1099 ALBuf->size = newsize*NewBytes;
1100 ALBuf->frequency = freq;
1102 ALBuf->LoopStart = 0;
1103 ALBuf->LoopEnd = newsize / NewChannels;
1105 ALBuf->OriginalSize = size;
1106 ALBuf->OriginalAlign = OrigBytes * OrigChannels;
1108 return AL_NO_ERROR;
1111 static void ConvertData(ALfloat *dst, const ALvoid *src, ALint origBytes, ALsizei len)
1113 ALsizei i;
1114 ALint smp;
1115 if(src == NULL)
1116 return;
1117 switch(origBytes)
1119 case 1:
1120 for(i = 0;i < len;i++)
1122 smp = ((ALubyte*)src)[i];
1123 dst[i] = ((smp < 0x80) ? ((smp-128)/128.0f) : ((smp-128)/127.0f));
1125 break;
1127 case 2:
1128 for(i = 0;i < len;i++)
1130 smp = ((ALshort*)src)[i];
1131 dst[i] = ((smp < 0) ? (smp/32768.0f) : (smp/32767.0f));
1133 break;
1135 case 4:
1136 for(i = 0;i < len;i++)
1137 dst[i] = ((ALfloat*)src)[i];
1138 break;
1140 case 8:
1141 for(i = 0;i < len;i++)
1142 dst[i] = ((ALdouble*)src)[i];
1143 break;
1145 default:
1146 assert(0);
1150 static void ConvertDataRear(ALfloat *dst, const ALvoid *src, ALint origBytes, ALsizei len)
1152 ALsizei i;
1153 ALint smp;
1154 if(src == NULL)
1155 return;
1156 switch(origBytes)
1158 case 1:
1159 for(i = 0;i < len;i+=4)
1161 dst[i+0] = 0;
1162 dst[i+1] = 0;
1163 smp = ((ALubyte*)src)[i/2+0];
1164 dst[i+2] = ((smp < 0x80) ? ((smp-128)/128.0f) : ((smp-128)/127.0f));
1165 smp = ((ALubyte*)src)[i/2+1];
1166 dst[i+3] = ((smp < 0x80) ? ((smp-128)/128.0f) : ((smp-128)/127.0f));
1168 break;
1170 case 2:
1171 for(i = 0;i < len;i+=4)
1173 dst[i+0] = 0;
1174 dst[i+1] = 0;
1175 smp = ((ALshort*)src)[i/2+0];
1176 dst[i+2] = ((smp < 0) ? (smp/32768.0f) : (smp/32767.0f));
1177 smp = ((ALshort*)src)[i/2+1];
1178 dst[i+3] = ((smp < 0) ? (smp/32768.0f) : (smp/32767.0f));
1180 break;
1182 case 4:
1183 for(i = 0;i < len;i+=4)
1185 dst[i+0] = 0;
1186 dst[i+1] = 0;
1187 dst[i+2] = ((ALfloat*)src)[i/2+0];
1188 dst[i+3] = ((ALfloat*)src)[i/2+1];
1190 break;
1192 default:
1193 assert(0);
1197 static void ConvertDataIMA4(ALfloat *dst, const ALvoid *src, ALint chans, ALsizei len)
1199 const ALubyte *IMAData;
1200 ALint Sample[2],Index[2];
1201 ALuint IMACode[2];
1202 ALsizei i,j,k,c;
1204 if(src == NULL)
1205 return;
1207 IMAData = src;
1208 for(i = 0;i < len;i++)
1210 for(c = 0;c < chans;c++)
1212 Sample[c] = *(IMAData++);
1213 Sample[c] |= *(IMAData++) << 8;
1214 Sample[c] = (Sample[c]^0x8000) - 32768;
1215 Index[c] = *(IMAData++);
1216 Index[c] |= *(IMAData++) << 8;
1217 Index[c] = (Index[c]^0x8000) - 32768;
1219 Index[c] = ((Index[c]<0) ? 0 : Index[c]);
1220 Index[c] = ((Index[c]>88) ? 88 : Index[c]);
1222 dst[i*65*chans + c] = ((Sample[c] < 0) ? (Sample[c]/32768.0f) : (Sample[c]/32767.0f));
1225 for(j = 1;j < 65;j += 8)
1227 for(c = 0;c < chans;c++)
1229 IMACode[c] = *(IMAData++);
1230 IMACode[c] |= *(IMAData++) << 8;
1231 IMACode[c] |= *(IMAData++) << 16;
1232 IMACode[c] |= *(IMAData++) << 24;
1235 for(k = 0;k < 8;k++)
1237 for(c = 0;c < chans;c++)
1239 Sample[c] += ((g_IMAStep_size[Index[c]]*g_IMACodeword_4[IMACode[c]&15])/8);
1240 Index[c] += g_IMAIndex_adjust_4[IMACode[c]&15];
1242 if(Sample[c] < -32768) Sample[c] = -32768;
1243 else if(Sample[c] > 32767) Sample[c] = 32767;
1245 if(Index[c]<0) Index[c] = 0;
1246 else if(Index[c]>88) Index[c] = 88;
1248 dst[(i*65+j+k)*chans + c] = ((Sample[c] < 0) ? (Sample[c]/32768.0f) : (Sample[c]/32767.0f));
1249 IMACode[c] >>= 4;
1256 static void ConvertDataMULaw(ALfloat *dst, const ALvoid *src, ALsizei len)
1258 ALsizei i;
1259 ALint smp;
1260 if(src == NULL)
1261 return;
1262 for(i = 0;i < len;i++)
1264 smp = muLawDecompressionTable[((ALubyte*)src)[i]];
1265 dst[i] = ((smp < 0) ? (smp/32768.0f) : (smp/32767.0f));
1269 static void ConvertDataMULawRear(ALfloat *dst, const ALvoid *src, ALsizei len)
1271 ALsizei i;
1272 ALint smp;
1273 if(src == NULL)
1274 return;
1275 for(i = 0;i < len;i+=4)
1277 dst[i+0] = 0;
1278 dst[i+1] = 0;
1279 smp = muLawDecompressionTable[((ALubyte*)src)[i/2+0]];
1280 dst[i+2] = ((smp < 0) ? (smp/32768.0f) : (smp/32767.0f));
1281 smp = muLawDecompressionTable[((ALubyte*)src)[i/2+1]];
1282 dst[i+3] = ((smp < 0) ? (smp/32768.0f) : (smp/32767.0f));
1287 * ReleaseALBuffers()
1289 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
1291 ALvoid ReleaseALBuffers(ALCdevice *device)
1293 ALsizei i;
1294 for(i = 0;i < device->BufferMap.size;i++)
1296 ALbuffer *temp = device->BufferMap.array[i].value;
1297 device->BufferMap.array[i].value = NULL;
1299 // Release sample data
1300 free(temp->data);
1302 // Release Buffer structure
1303 ALTHUNK_REMOVEENTRY(temp->buffer);
1304 memset(temp, 0, sizeof(ALbuffer));
1305 free(temp);