Reorder and rename parameters for the format decomposition functions
[openal-soft.git] / OpenAL32 / alBuffer.c
blob35e30c4f6168f5c545e35e099813c5c065a9ab6a
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(ALvoid *dst, enum FmtType dstType, const ALvoid *src, enum SrcFmtType srcType, ALsizei len);
39 static void ConvertDataIMA4(ALvoid *dst, const ALvoid *src, ALint origChans, ALsizei len);
41 #define LookupBuffer(m, k) ((ALbuffer*)LookupUIntMapKey(&(m), (k)))
45 * Global Variables
48 static const long g_IMAStep_size[89]={ // IMA ADPCM Stepsize table
49 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
50 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
51 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
52 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
53 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493,10442,11487,12635,13899,
54 15289,16818,18500,20350,22358,24633,27086,29794,32767
57 static const long g_IMACodeword_4[16]={ // IMA4 ADPCM Codeword decode table
58 1, 3, 5, 7, 9, 11, 13, 15,
59 -1,-3,-5,-7,-9,-11,-13,-15,
62 static const long g_IMAIndex_adjust_4[16]={ // IMA4 ADPCM Step index adjust decode table
63 -1,-1,-1,-1, 2, 4, 6, 8,
64 -1,-1,-1,-1, 2, 4, 6, 8
67 static const ALshort muLawDecompressionTable[256] = {
68 -32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956,
69 -23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764,
70 -15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412,
71 -11900,-11388,-10876,-10364, -9852, -9340, -8828, -8316,
72 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
73 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
74 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
75 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
76 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
77 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
78 -876, -844, -812, -780, -748, -716, -684, -652,
79 -620, -588, -556, -524, -492, -460, -428, -396,
80 -372, -356, -340, -324, -308, -292, -276, -260,
81 -244, -228, -212, -196, -180, -164, -148, -132,
82 -120, -112, -104, -96, -88, -80, -72, -64,
83 -56, -48, -40, -32, -24, -16, -8, 0,
84 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
85 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
86 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
87 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
88 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
89 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
90 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
91 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
92 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
93 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
94 876, 844, 812, 780, 748, 716, 684, 652,
95 620, 588, 556, 524, 492, 460, 428, 396,
96 372, 356, 340, 324, 308, 292, 276, 260,
97 244, 228, 212, 196, 180, 164, 148, 132,
98 120, 112, 104, 96, 88, 80, 72, 64,
99 56, 48, 40, 32, 24, 16, 8, 0
103 * alGenBuffers(ALsizei n, ALuint *buffers)
105 * Generates n AL Buffers, and stores the Buffers Names in the array pointed to by buffers
107 AL_API ALvoid AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers)
109 ALCcontext *Context;
110 ALsizei i=0;
112 Context = GetContextSuspended();
113 if(!Context) return;
115 // Check that we are actually generating some Buffers
116 if(n < 0 || IsBadWritePtr((void*)buffers, n * sizeof(ALuint)))
117 alSetError(Context, AL_INVALID_VALUE);
118 else
120 ALCdevice *device = Context->Device;
121 ALenum err;
123 // Create all the new Buffers
124 while(i < n)
126 ALbuffer *buffer = calloc(1, sizeof(ALbuffer));
127 if(!buffer)
129 alSetError(Context, AL_OUT_OF_MEMORY);
130 alDeleteBuffers(i, buffers);
131 break;
134 buffer->buffer = (ALuint)ALTHUNK_ADDENTRY(buffer);
135 err = InsertUIntMapEntry(&device->BufferMap, buffer->buffer, buffer);
136 if(err != AL_NO_ERROR)
138 ALTHUNK_REMOVEENTRY(buffer->buffer);
139 memset(buffer, 0, sizeof(ALbuffer));
140 free(buffer);
142 alSetError(Context, err);
143 alDeleteBuffers(i, buffers);
144 break;
146 buffers[i++] = buffer->buffer;
150 ProcessContext(Context);
154 * alDeleteBuffers(ALsizei n, ALuint *buffers)
156 * Deletes the n AL Buffers pointed to by buffers
158 AL_API ALvoid AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers)
160 ALCcontext *Context;
161 ALCdevice *device;
162 ALboolean Failed;
163 ALbuffer *ALBuf;
164 ALsizei i;
166 Context = GetContextSuspended();
167 if(!Context) return;
169 Failed = AL_TRUE;
170 device = Context->Device;
171 /* Check we are actually Deleting some Buffers */
172 if(n < 0)
173 alSetError(Context, AL_INVALID_VALUE);
174 else
176 Failed = AL_FALSE;
178 /* Check that all the buffers are valid and can actually be deleted */
179 for(i = 0;i < n;i++)
181 if(!buffers[i])
182 continue;
184 /* Check for valid Buffer ID */
185 if((ALBuf=LookupBuffer(device->BufferMap, buffers[i])) == NULL)
187 alSetError(Context, AL_INVALID_NAME);
188 Failed = AL_TRUE;
189 break;
191 else if(ALBuf->refcount != 0)
193 /* Buffer still in use, cannot be deleted */
194 alSetError(Context, AL_INVALID_OPERATION);
195 Failed = AL_TRUE;
196 break;
201 /* If all the Buffers were valid (and have Reference Counts of 0), then we can delete them */
202 if(!Failed)
204 for(i = 0;i < n;i++)
206 if((ALBuf=LookupBuffer(device->BufferMap, buffers[i])) == NULL)
207 continue;
209 /* Release the memory used to store audio data */
210 free(ALBuf->data);
212 /* Release buffer structure */
213 RemoveUIntMapKey(&device->BufferMap, ALBuf->buffer);
214 ALTHUNK_REMOVEENTRY(ALBuf->buffer);
216 memset(ALBuf, 0, sizeof(ALbuffer));
217 free(ALBuf);
221 ProcessContext(Context);
225 * alIsBuffer(ALuint buffer)
227 * Checks if buffer is a valid Buffer Name
229 AL_API ALboolean AL_APIENTRY alIsBuffer(ALuint buffer)
231 ALCcontext *Context;
232 ALboolean result;
234 Context = GetContextSuspended();
235 if(!Context) return AL_FALSE;
237 result = ((!buffer || LookupBuffer(Context->Device->BufferMap, buffer)) ?
238 AL_TRUE : AL_FALSE);
240 ProcessContext(Context);
242 return result;
246 * alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq)
248 * Fill buffer with audio data
250 AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq)
252 ALCcontext *Context;
253 ALCdevice *device;
254 ALbuffer *ALBuf;
255 ALvoid *temp;
256 ALenum err;
258 Context = GetContextSuspended();
259 if(!Context) return;
261 if(Context->SampleSource)
263 ALintptrEXT offset;
265 if(Context->SampleSource->state == MAPPED)
267 alSetError(Context, AL_INVALID_OPERATION);
268 ProcessContext(Context);
269 return;
272 offset = (const ALubyte*)data - (ALubyte*)NULL;
273 data = Context->SampleSource->data + offset;
276 device = Context->Device;
277 if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL)
278 alSetError(Context, AL_INVALID_NAME);
279 else if(size < 0 || freq < 0)
280 alSetError(Context, AL_INVALID_VALUE);
281 else if(ALBuf->refcount != 0)
282 alSetError(Context, AL_INVALID_VALUE);
283 else switch(format)
285 case AL_FORMAT_MONO8:
286 case AL_FORMAT_MONO16:
287 case AL_FORMAT_MONO_FLOAT32:
288 case AL_FORMAT_STEREO8:
289 case AL_FORMAT_STEREO16:
290 case AL_FORMAT_STEREO_FLOAT32:
291 case AL_FORMAT_QUAD8_LOKI:
292 case AL_FORMAT_QUAD16_LOKI:
293 case AL_FORMAT_QUAD8:
294 case AL_FORMAT_QUAD16:
295 case AL_FORMAT_QUAD32:
296 case AL_FORMAT_REAR8:
297 case AL_FORMAT_REAR16:
298 case AL_FORMAT_REAR32:
299 case AL_FORMAT_51CHN8:
300 case AL_FORMAT_51CHN16:
301 case AL_FORMAT_51CHN32:
302 case AL_FORMAT_61CHN8:
303 case AL_FORMAT_61CHN16:
304 case AL_FORMAT_61CHN32:
305 case AL_FORMAT_71CHN8:
306 case AL_FORMAT_71CHN16:
307 case AL_FORMAT_71CHN32:
308 err = LoadData(ALBuf, data, size, freq, format, format);
309 if(err != AL_NO_ERROR)
310 alSetError(Context, err);
311 break;
313 case AL_FORMAT_MONO_DOUBLE_EXT:
314 err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO_FLOAT32);
315 if(err != AL_NO_ERROR)
316 alSetError(Context, err);
317 break;
318 case AL_FORMAT_STEREO_DOUBLE_EXT:
319 err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO_FLOAT32);
320 if(err != AL_NO_ERROR)
321 alSetError(Context, err);
322 break;
324 case AL_FORMAT_MONO_MULAW:
325 case AL_FORMAT_STEREO_MULAW:
326 case AL_FORMAT_QUAD_MULAW:
327 case AL_FORMAT_51CHN_MULAW:
328 case AL_FORMAT_61CHN_MULAW:
329 case AL_FORMAT_71CHN_MULAW: {
330 ALuint Channels = ((format==AL_FORMAT_MONO_MULAW) ? 1 :
331 ((format==AL_FORMAT_STEREO_MULAW) ? 2 :
332 ((format==AL_FORMAT_QUAD_MULAW) ? 4 :
333 ((format==AL_FORMAT_51CHN_MULAW) ? 6 :
334 ((format==AL_FORMAT_61CHN_MULAW) ? 7 : 8)))));
335 ALenum NewFormat = ((Channels==1) ? AL_FORMAT_MONO16 :
336 ((Channels==2) ? AL_FORMAT_STEREO16 :
337 ((Channels==4) ? AL_FORMAT_QUAD16 :
338 ((Channels==6) ? AL_FORMAT_51CHN16 :
339 ((Channels==7) ? AL_FORMAT_61CHN16 :
340 AL_FORMAT_71CHN16)))));
341 err = LoadData(ALBuf, data, size, freq, format, NewFormat);
342 if(err != AL_NO_ERROR)
343 alSetError(Context, err);
344 } break;
346 case AL_FORMAT_REAR_MULAW:
347 err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_REAR16);
348 if(err != AL_NO_ERROR)
349 alSetError(Context, err);
350 break;
352 case AL_FORMAT_MONO_IMA4:
353 case AL_FORMAT_STEREO_IMA4: {
354 ALuint Channels = ((format==AL_FORMAT_MONO_IMA4) ? 1 : 2);
355 ALenum NewFormat = ((Channels==1) ? AL_FORMAT_MONO16 :
356 AL_FORMAT_STEREO16);
357 ALuint NewBytes = aluBytesFromFormat(NewFormat);
358 ALuint64 newsize;
360 /* Here is where things vary:
361 * nVidia and Apple use 64+1 sample frames per block => block_size=36*chans bytes
362 * Most PC sound software uses 2040+1 sample frames per block -> block_size=1024*chans bytes
364 if((size%(36*Channels)) != 0)
366 alSetError(Context, AL_INVALID_VALUE);
367 break;
370 newsize = size / 36;
371 newsize *= 65;
372 newsize *= NewBytes;
374 if(newsize > INT_MAX)
376 alSetError(Context, AL_OUT_OF_MEMORY);
377 break;
379 temp = realloc(ALBuf->data, newsize);
380 if(temp)
382 ALBuf->data = temp;
383 ALBuf->size = newsize;
385 ConvertDataIMA4(ALBuf->data, data, Channels, newsize/(65*Channels*NewBytes));
387 ALBuf->Frequency = freq;
388 DecomposeFormat(NewFormat, &ALBuf->FmtChannels, &ALBuf->FmtType);
390 ALBuf->LoopStart = 0;
391 ALBuf->LoopEnd = newsize / Channels / NewBytes;
393 ALBuf->OriginalFormat = format;
394 ALBuf->OriginalSize = size;
395 ALBuf->OriginalAlign = 36 * Channels;
397 else
398 alSetError(Context, AL_OUT_OF_MEMORY);
399 } break;
401 default:
402 alSetError(Context, AL_INVALID_ENUM);
403 break;
406 ProcessContext(Context);
410 * alBufferSubDataSOFT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length)
412 * Update buffer's audio data
414 AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length)
416 ALCcontext *Context;
417 ALCdevice *device;
418 ALbuffer *ALBuf;
420 Context = GetContextSuspended();
421 if(!Context) return;
423 if(Context->SampleSource)
425 ALintptrEXT offset;
427 if(Context->SampleSource->state == MAPPED)
429 alSetError(Context, AL_INVALID_OPERATION);
430 ProcessContext(Context);
431 return;
434 offset = (const ALubyte*)data - (ALubyte*)NULL;
435 data = Context->SampleSource->data + offset;
438 device = Context->Device;
439 if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL)
440 alSetError(Context, AL_INVALID_NAME);
441 else if(length < 0 || offset < 0 || (length > 0 && data == NULL))
442 alSetError(Context, AL_INVALID_VALUE);
443 else if(ALBuf->OriginalFormat != format)
444 alSetError(Context, AL_INVALID_ENUM);
445 else if(offset > ALBuf->OriginalSize ||
446 length > ALBuf->OriginalSize-offset ||
447 (offset%ALBuf->OriginalAlign) != 0 ||
448 (length%ALBuf->OriginalAlign) != 0)
449 alSetError(Context, AL_INVALID_VALUE);
450 else switch(format)
452 case AL_FORMAT_MONO8:
453 case AL_FORMAT_MONO16:
454 case AL_FORMAT_MONO_FLOAT32:
455 case AL_FORMAT_MONO_DOUBLE_EXT:
456 case AL_FORMAT_MONO_MULAW:
457 case AL_FORMAT_STEREO8:
458 case AL_FORMAT_STEREO16:
459 case AL_FORMAT_STEREO_FLOAT32:
460 case AL_FORMAT_STEREO_DOUBLE_EXT:
461 case AL_FORMAT_STEREO_MULAW:
462 case AL_FORMAT_QUAD8_LOKI:
463 case AL_FORMAT_QUAD16_LOKI:
464 case AL_FORMAT_QUAD8:
465 case AL_FORMAT_QUAD16:
466 case AL_FORMAT_QUAD32:
467 case AL_FORMAT_QUAD_MULAW:
468 case AL_FORMAT_REAR8:
469 case AL_FORMAT_REAR16:
470 case AL_FORMAT_REAR32:
471 case AL_FORMAT_REAR_MULAW:
472 case AL_FORMAT_51CHN8:
473 case AL_FORMAT_51CHN16:
474 case AL_FORMAT_51CHN32:
475 case AL_FORMAT_51CHN_MULAW:
476 case AL_FORMAT_61CHN8:
477 case AL_FORMAT_61CHN16:
478 case AL_FORMAT_61CHN32:
479 case AL_FORMAT_61CHN_MULAW:
480 case AL_FORMAT_71CHN8:
481 case AL_FORMAT_71CHN16:
482 case AL_FORMAT_71CHN32:
483 case AL_FORMAT_71CHN_MULAW: {
484 ALuint OldBytes = aluBytesFromFormat(format);
485 ALuint Bytes = BytesFromFmt(ALBuf->FmtType);
486 enum SrcFmtChannels SrcChannels;
487 enum SrcFmtType SrcType;
489 offset /= OldBytes;
490 offset *= Bytes;
491 length /= OldBytes;
493 DecomposeInputFormat(format, &SrcChannels, &SrcType);
494 ConvertData(&((ALubyte*)ALBuf->data)[offset], ALBuf->FmtType,
495 data, SrcType, length);
496 } break;
498 case AL_FORMAT_MONO_IMA4:
499 case AL_FORMAT_STEREO_IMA4: {
500 ALuint Channels = ChannelsFromFmt(ALBuf->FmtChannels);
501 ALuint Bytes = BytesFromFmt(ALBuf->FmtType);
503 /* offset -> byte offset, length -> block count */
504 offset /= 36;
505 offset *= 65;
506 offset *= Bytes;
507 length /= ALBuf->OriginalAlign;
509 ConvertDataIMA4(&((ALubyte*)ALBuf->data)[offset], data, Channels, length);
510 } break;
512 default:
513 alSetError(Context, AL_INVALID_ENUM);
514 break;
517 ProcessContext(Context);
520 AL_API ALvoid AL_APIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length)
522 alBufferSubDataSOFT(buffer, format, data, offset, length);
526 AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
528 ALCcontext *pContext;
529 ALCdevice *device;
531 (void)flValue;
533 pContext = GetContextSuspended();
534 if(!pContext) return;
536 device = pContext->Device;
537 if(LookupBuffer(device->BufferMap, buffer) == NULL)
538 alSetError(pContext, AL_INVALID_NAME);
539 else
541 switch(eParam)
543 default:
544 alSetError(pContext, AL_INVALID_ENUM);
545 break;
549 ProcessContext(pContext);
553 AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
555 ALCcontext *pContext;
556 ALCdevice *device;
558 (void)flValue1;
559 (void)flValue2;
560 (void)flValue3;
562 pContext = GetContextSuspended();
563 if(!pContext) return;
565 device = pContext->Device;
566 if(LookupBuffer(device->BufferMap, buffer) == NULL)
567 alSetError(pContext, AL_INVALID_NAME);
568 else
570 switch(eParam)
572 default:
573 alSetError(pContext, AL_INVALID_ENUM);
574 break;
578 ProcessContext(pContext);
582 AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues)
584 ALCcontext *pContext;
585 ALCdevice *device;
587 pContext = GetContextSuspended();
588 if(!pContext) return;
590 device = pContext->Device;
591 if(!flValues)
592 alSetError(pContext, AL_INVALID_VALUE);
593 else if(LookupBuffer(device->BufferMap, buffer) == NULL)
594 alSetError(pContext, AL_INVALID_NAME);
595 else
597 switch(eParam)
599 default:
600 alSetError(pContext, AL_INVALID_ENUM);
601 break;
605 ProcessContext(pContext);
609 AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
611 ALCcontext *pContext;
612 ALCdevice *device;
614 (void)lValue;
616 pContext = GetContextSuspended();
617 if(!pContext) return;
619 device = pContext->Device;
620 if(LookupBuffer(device->BufferMap, buffer) == NULL)
621 alSetError(pContext, AL_INVALID_NAME);
622 else
624 switch(eParam)
626 default:
627 alSetError(pContext, AL_INVALID_ENUM);
628 break;
632 ProcessContext(pContext);
636 AL_API void AL_APIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
638 ALCcontext *pContext;
639 ALCdevice *device;
641 (void)lValue1;
642 (void)lValue2;
643 (void)lValue3;
645 pContext = GetContextSuspended();
646 if(!pContext) return;
648 device = pContext->Device;
649 if(LookupBuffer(device->BufferMap, buffer) == NULL)
650 alSetError(pContext, AL_INVALID_NAME);
651 else
653 switch(eParam)
655 default:
656 alSetError(pContext, AL_INVALID_ENUM);
657 break;
661 ProcessContext(pContext);
665 AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues)
667 ALCcontext *pContext;
668 ALCdevice *device;
669 ALbuffer *ALBuf;
671 pContext = GetContextSuspended();
672 if(!pContext) return;
674 device = pContext->Device;
675 if(!plValues)
676 alSetError(pContext, AL_INVALID_VALUE);
677 else if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL)
678 alSetError(pContext, AL_INVALID_NAME);
679 else
681 switch(eParam)
683 case AL_LOOP_POINTS:
684 if(ALBuf->refcount > 0)
685 alSetError(pContext, AL_INVALID_OPERATION);
686 else if(plValues[0] < 0 || plValues[1] < 0 ||
687 plValues[0] >= plValues[1] || ALBuf->size == 0)
688 alSetError(pContext, AL_INVALID_VALUE);
689 else
691 ALint maxlen = ALBuf->size /
692 FrameSizeFromFmt(ALBuf->FmtType, ALBuf->FmtChannels);
693 if(plValues[0] > maxlen || plValues[1] > maxlen)
694 alSetError(pContext, AL_INVALID_VALUE);
695 else
697 ALBuf->LoopStart = plValues[0];
698 ALBuf->LoopEnd = plValues[1];
701 break;
703 default:
704 alSetError(pContext, AL_INVALID_ENUM);
705 break;
709 ProcessContext(pContext);
713 AL_API ALvoid AL_APIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue)
715 ALCcontext *pContext;
716 ALCdevice *device;
718 pContext = GetContextSuspended();
719 if(!pContext) return;
721 device = pContext->Device;
722 if(!pflValue)
723 alSetError(pContext, AL_INVALID_VALUE);
724 else 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 alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3)
742 ALCcontext *pContext;
743 ALCdevice *device;
745 pContext = GetContextSuspended();
746 if(!pContext) return;
748 device = pContext->Device;
749 if(!pflValue1 || !pflValue2 || !pflValue3)
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 alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues)
769 ALCcontext *pContext;
770 ALCdevice *device;
772 pContext = GetContextSuspended();
773 if(!pContext) return;
775 device = pContext->Device;
776 if(!pflValues)
777 alSetError(pContext, AL_INVALID_VALUE);
778 else 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 ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue)
796 ALCcontext *pContext;
797 ALbuffer *pBuffer;
798 ALCdevice *device;
800 pContext = GetContextSuspended();
801 if(!pContext) return;
803 device = pContext->Device;
804 if(!plValue)
805 alSetError(pContext, AL_INVALID_VALUE);
806 else if((pBuffer=LookupBuffer(device->BufferMap, buffer)) == NULL)
807 alSetError(pContext, AL_INVALID_NAME);
808 else
810 switch(eParam)
812 case AL_FREQUENCY:
813 *plValue = pBuffer->Frequency;
814 break;
816 case AL_BITS:
817 *plValue = BytesFromFmt(pBuffer->FmtType) * 8;
818 break;
820 case AL_CHANNELS:
821 *plValue = ChannelsFromFmt(pBuffer->FmtChannels);
822 break;
824 case AL_SIZE:
825 *plValue = pBuffer->size;
826 break;
828 default:
829 alSetError(pContext, AL_INVALID_ENUM);
830 break;
834 ProcessContext(pContext);
838 AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3)
840 ALCcontext *pContext;
841 ALCdevice *device;
843 pContext = GetContextSuspended();
844 if(!pContext) return;
846 device = pContext->Device;
847 if(!plValue1 || !plValue2 || !plValue3)
848 alSetError(pContext, AL_INVALID_VALUE);
849 else if(LookupBuffer(device->BufferMap, buffer) == NULL)
850 alSetError(pContext, AL_INVALID_NAME);
851 else
853 switch(eParam)
855 default:
856 alSetError(pContext, AL_INVALID_ENUM);
857 break;
861 ProcessContext(pContext);
865 AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues)
867 ALCcontext *pContext;
868 ALCdevice *device;
869 ALbuffer *ALBuf;
871 pContext = GetContextSuspended();
872 if(!pContext) return;
874 device = pContext->Device;
875 if(!plValues)
876 alSetError(pContext, AL_INVALID_VALUE);
877 else if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL)
878 alSetError(pContext, AL_INVALID_NAME);
879 else
881 switch(eParam)
883 case AL_FREQUENCY:
884 case AL_BITS:
885 case AL_CHANNELS:
886 case AL_SIZE:
887 alGetBufferi(buffer, eParam, plValues);
888 break;
890 case AL_LOOP_POINTS:
891 plValues[0] = ALBuf->LoopStart;
892 plValues[1] = ALBuf->LoopEnd;
893 break;
895 default:
896 alSetError(pContext, AL_INVALID_ENUM);
897 break;
901 ProcessContext(pContext);
905 static void ConvertDataIMA4(ALvoid *dst, const ALvoid *src, ALint chans, ALsizei len)
907 const ALubyte *IMAData;
908 ALint Sample[2],Index[2];
909 ALuint IMACode[2];
910 ALsizei i,j,k,c;
912 if(src == NULL)
913 return;
915 IMAData = src;
916 for(i = 0;i < len;i++)
918 for(c = 0;c < chans;c++)
920 Sample[c] = *(IMAData++);
921 Sample[c] |= *(IMAData++) << 8;
922 Sample[c] = (Sample[c]^0x8000) - 32768;
923 Index[c] = *(IMAData++);
924 Index[c] |= *(IMAData++) << 8;
925 Index[c] = (Index[c]^0x8000) - 32768;
927 Index[c] = ((Index[c]<0) ? 0 : Index[c]);
928 Index[c] = ((Index[c]>88) ? 88 : Index[c]);
930 ((ALshort*)dst)[i*65*chans + c] = Sample[c];
933 for(j = 1;j < 65;j += 8)
935 for(c = 0;c < chans;c++)
937 IMACode[c] = *(IMAData++);
938 IMACode[c] |= *(IMAData++) << 8;
939 IMACode[c] |= *(IMAData++) << 16;
940 IMACode[c] |= *(IMAData++) << 24;
943 for(k = 0;k < 8;k++)
945 for(c = 0;c < chans;c++)
947 Sample[c] += ((g_IMAStep_size[Index[c]]*g_IMACodeword_4[IMACode[c]&15])/8);
948 Index[c] += g_IMAIndex_adjust_4[IMACode[c]&15];
950 if(Sample[c] < -32768) Sample[c] = -32768;
951 else if(Sample[c] > 32767) Sample[c] = 32767;
953 if(Index[c]<0) Index[c] = 0;
954 else if(Index[c]>88) Index[c] = 88;
956 ((ALshort*)dst)[(i*65+j+k)*chans + c] = Sample[c];
957 IMACode[c] >>= 4;
965 typedef ALubyte ALmulaw;
967 static __inline ALbyte Conv_ALbyte_ALbyte(ALbyte val)
968 { return val; }
969 static __inline ALbyte Conv_ALbyte_ALubyte(ALubyte val)
970 { return val^0x80; }
971 static __inline ALbyte Conv_ALbyte_ALshort(ALshort val)
972 { return val>>8; }
973 static __inline ALbyte Conv_ALbyte_ALushort(ALushort val)
974 { return (val>>8)-128; }
975 static __inline ALbyte Conv_ALbyte_ALfloat(ALfloat val)
977 if(val >= 1.0f) return 127;
978 if(val <= -1.0f) return -128;
979 return (ALint)(val * 127.0f);
981 static __inline ALbyte Conv_ALbyte_ALdouble(ALdouble val)
983 if(val >= 1.0) return 127;
984 if(val <= -1.0) return -128;
985 return (ALint)(val * 127.0);
987 static __inline ALbyte Conv_ALbyte_ALmulaw(ALmulaw val)
988 { return muLawDecompressionTable[val]>>8; }
990 static __inline ALubyte Conv_ALubyte_ALbyte(ALbyte val)
991 { return val^0x80; }
992 static __inline ALubyte Conv_ALubyte_ALubyte(ALubyte val)
993 { return val; }
994 static __inline ALubyte Conv_ALubyte_ALshort(ALshort val)
995 { return (val>>8)+128; }
996 static __inline ALubyte Conv_ALubyte_ALushort(ALushort val)
997 { return val>>8; }
998 static __inline ALubyte Conv_ALubyte_ALfloat(ALfloat val)
1000 if(val >= 1.0f) return 255;
1001 if(val <= -1.0f) return 0;
1002 return (ALint)(val * 127.0f) + 128;
1004 static __inline ALubyte Conv_ALubyte_ALdouble(ALdouble val)
1006 if(val >= 1.0) return 255;
1007 if(val <= -1.0) return 0;
1008 return (ALint)(val * 127.0) + 128;
1010 static __inline ALubyte Conv_ALubyte_ALmulaw(ALmulaw val)
1011 { return (muLawDecompressionTable[val]>>8)+128; }
1013 static __inline ALshort Conv_ALshort_ALbyte(ALbyte val)
1014 { return val<<8; }
1015 static __inline ALshort Conv_ALshort_ALubyte(ALubyte val)
1016 { return (val-128)<<8; }
1017 static __inline ALshort Conv_ALshort_ALshort(ALshort val)
1018 { return val; }
1019 static __inline ALshort Conv_ALshort_ALushort(ALushort val)
1020 { return val^0x8000; }
1021 static __inline ALshort Conv_ALshort_ALfloat(ALfloat val)
1023 if(val >= 1.0f) return 32767;
1024 if(val <= -1.0f) return -32768;
1025 return (ALint)(val * 32767.0f);
1027 static __inline ALshort Conv_ALshort_ALdouble(ALdouble val)
1029 if(val >= 1.0) return 32767;
1030 if(val <= -1.0) return -32768;
1031 return (ALint)(val * 32767.0);
1033 static __inline ALshort Conv_ALshort_ALmulaw(ALmulaw val)
1034 { return muLawDecompressionTable[val]; }
1036 static __inline ALushort Conv_ALushort_ALbyte(ALbyte val)
1037 { return (val+128)<<8; }
1038 static __inline ALushort Conv_ALushort_ALubyte(ALubyte val)
1039 { return val<<8; }
1040 static __inline ALushort Conv_ALushort_ALshort(ALshort val)
1041 { return val^0x8000; }
1042 static __inline ALushort Conv_ALushort_ALushort(ALushort val)
1043 { return val; }
1044 static __inline ALushort Conv_ALushort_ALfloat(ALfloat val)
1046 if(val >= 1.0f) return 65535;
1047 if(val <= -1.0f) return 0;
1048 return (ALint)(val * 32767.0f) + 32768;
1050 static __inline ALushort Conv_ALushort_ALdouble(ALdouble val)
1052 if(val >= 1.0) return 65535;
1053 if(val <= -1.0) return 0;
1054 return (ALint)(val * 32767.0) + 32768;
1056 static __inline ALushort Conv_ALushort_ALmulaw(ALmulaw val)
1057 { return muLawDecompressionTable[val]^0x8000; }
1059 static __inline ALfloat Conv_ALfloat_ALbyte(ALbyte val)
1060 { return val * (1.0f/127.0f); }
1061 static __inline ALfloat Conv_ALfloat_ALubyte(ALubyte val)
1062 { return (val-128) * (1.0f/127.0f); }
1063 static __inline ALfloat Conv_ALfloat_ALshort(ALshort val)
1064 { return val * (1.0f/32767.0f); }
1065 static __inline ALfloat Conv_ALfloat_ALushort(ALushort val)
1066 { return (val-32768) * (1.0f/32767.0f); }
1067 static __inline ALfloat Conv_ALfloat_ALfloat(ALfloat val)
1068 { return val; }
1069 static __inline ALfloat Conv_ALfloat_ALdouble(ALdouble val)
1070 { return val; }
1071 static __inline ALfloat Conv_ALfloat_ALmulaw(ALmulaw val)
1072 { return muLawDecompressionTable[val] * (1.0f/32767.0f); }
1074 static __inline ALdouble Conv_ALdouble_ALbyte(ALbyte val)
1075 { return val * (1.0/127.0); }
1076 static __inline ALdouble Conv_ALdouble_ALubyte(ALubyte val)
1077 { return (val-128) * (1.0/127.0); }
1078 static __inline ALdouble Conv_ALdouble_ALshort(ALshort val)
1079 { return val * (1.0/32767.0); }
1080 static __inline ALdouble Conv_ALdouble_ALushort(ALushort val)
1081 { return (val-32768) * (1.0/32767.0); }
1082 static __inline ALdouble Conv_ALdouble_ALfloat(ALfloat val)
1083 { return val; }
1084 static __inline ALdouble Conv_ALdouble_ALdouble(ALdouble val)
1085 { return val; }
1086 static __inline ALdouble Conv_ALdouble_ALmulaw(ALmulaw val)
1087 { return muLawDecompressionTable[val] * (1.0/32767.0); }
1090 #define DECL_TEMPLATE(T1, T2) \
1091 static void Convert_##T1##_##T2(T1 *dst, const T2 *src, ALuint len) \
1093 ALuint i; \
1094 for(i = 0;i < len;i++) \
1095 *(dst++) = Conv_##T1##_##T2(*(src++)); \
1098 DECL_TEMPLATE(ALbyte, ALbyte)
1099 DECL_TEMPLATE(ALbyte, ALubyte)
1100 DECL_TEMPLATE(ALbyte, ALshort)
1101 DECL_TEMPLATE(ALbyte, ALushort)
1102 DECL_TEMPLATE(ALbyte, ALfloat)
1103 DECL_TEMPLATE(ALbyte, ALdouble)
1104 DECL_TEMPLATE(ALbyte, ALmulaw)
1106 DECL_TEMPLATE(ALubyte, ALbyte)
1107 DECL_TEMPLATE(ALubyte, ALubyte)
1108 DECL_TEMPLATE(ALubyte, ALshort)
1109 DECL_TEMPLATE(ALubyte, ALushort)
1110 DECL_TEMPLATE(ALubyte, ALfloat)
1111 DECL_TEMPLATE(ALubyte, ALdouble)
1112 DECL_TEMPLATE(ALubyte, ALmulaw)
1114 DECL_TEMPLATE(ALshort, ALbyte)
1115 DECL_TEMPLATE(ALshort, ALubyte)
1116 DECL_TEMPLATE(ALshort, ALshort)
1117 DECL_TEMPLATE(ALshort, ALushort)
1118 DECL_TEMPLATE(ALshort, ALfloat)
1119 DECL_TEMPLATE(ALshort, ALdouble)
1120 DECL_TEMPLATE(ALshort, ALmulaw)
1122 DECL_TEMPLATE(ALushort, ALbyte)
1123 DECL_TEMPLATE(ALushort, ALubyte)
1124 DECL_TEMPLATE(ALushort, ALshort)
1125 DECL_TEMPLATE(ALushort, ALushort)
1126 DECL_TEMPLATE(ALushort, ALfloat)
1127 DECL_TEMPLATE(ALushort, ALdouble)
1128 DECL_TEMPLATE(ALushort, ALmulaw)
1130 DECL_TEMPLATE(ALfloat, ALbyte)
1131 DECL_TEMPLATE(ALfloat, ALubyte)
1132 DECL_TEMPLATE(ALfloat, ALshort)
1133 DECL_TEMPLATE(ALfloat, ALushort)
1134 DECL_TEMPLATE(ALfloat, ALfloat)
1135 DECL_TEMPLATE(ALfloat, ALdouble)
1136 DECL_TEMPLATE(ALfloat, ALmulaw)
1138 DECL_TEMPLATE(ALdouble, ALbyte)
1139 DECL_TEMPLATE(ALdouble, ALubyte)
1140 DECL_TEMPLATE(ALdouble, ALshort)
1141 DECL_TEMPLATE(ALdouble, ALushort)
1142 DECL_TEMPLATE(ALdouble, ALfloat)
1143 DECL_TEMPLATE(ALdouble, ALdouble)
1144 DECL_TEMPLATE(ALdouble, ALmulaw)
1146 #undef DECL_TEMPLATE
1148 #define DECL_TEMPLATE(T) \
1149 static void Convert_##T(T *dst, const ALvoid *src, enum SrcFmtType srcType, \
1150 ALsizei len) \
1152 switch(srcType) \
1154 case SrcFmtByte: \
1155 Convert_##T##_ALbyte(dst, src, len); \
1156 break; \
1157 case SrcFmtUByte: \
1158 Convert_##T##_ALubyte(dst, src, len); \
1159 break; \
1160 case SrcFmtShort: \
1161 Convert_##T##_ALshort(dst, src, len); \
1162 break; \
1163 case SrcFmtUShort: \
1164 Convert_##T##_ALushort(dst, src, len); \
1165 break; \
1166 case SrcFmtFloat: \
1167 Convert_##T##_ALfloat(dst, src, len); \
1168 break; \
1169 case SrcFmtDouble: \
1170 Convert_##T##_ALdouble(dst, src, len); \
1171 break; \
1172 case SrcFmtMulaw: \
1173 Convert_##T##_ALmulaw(dst, src, len); \
1174 break; \
1178 DECL_TEMPLATE(ALbyte)
1179 DECL_TEMPLATE(ALubyte)
1180 DECL_TEMPLATE(ALshort)
1181 DECL_TEMPLATE(ALushort)
1182 DECL_TEMPLATE(ALfloat)
1183 DECL_TEMPLATE(ALdouble)
1185 #undef DECL_TEMPLATE
1189 * LoadData
1191 * Loads the specified data into the buffer, using the specified formats.
1192 * Currently, the new format must have the same channel configuration as the
1193 * original format. This does NOT handle compressed formats (eg. IMA4).
1195 static ALenum LoadData(ALbuffer *ALBuf, const ALvoid *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
1197 ALuint NewBytes = aluBytesFromFormat(NewFormat);
1198 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
1199 ALuint OrigBytes = aluBytesFromFormat(OrigFormat);
1200 ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
1201 enum SrcFmtChannels SrcChannels;
1202 enum FmtChannels DstChannels;
1203 enum SrcFmtType SrcType;
1204 enum FmtType DstType;
1205 ALuint64 newsize;
1206 ALvoid *temp;
1208 assert(NewChannels == OrigChannels);
1210 DecomposeInputFormat(OrigFormat, &SrcChannels, &SrcType);
1211 DecomposeFormat(NewFormat, &DstChannels, &DstType);
1213 if((size%(OrigBytes*OrigChannels)) != 0)
1214 return AL_INVALID_VALUE;
1216 newsize = size / OrigBytes;
1217 newsize *= NewBytes;
1218 if(newsize > INT_MAX)
1219 return AL_OUT_OF_MEMORY;
1221 temp = realloc(ALBuf->data, newsize);
1222 if(!temp) return AL_OUT_OF_MEMORY;
1223 ALBuf->data = temp;
1224 ALBuf->size = newsize;
1226 if(data != NULL)
1228 // Samples are converted here
1229 ConvertData(ALBuf->data, DstType, data, SrcType, newsize/NewBytes);
1232 ALBuf->Frequency = freq;
1233 ALBuf->FmtType = DstType;
1234 ALBuf->FmtChannels = DstChannels;
1236 ALBuf->LoopStart = 0;
1237 ALBuf->LoopEnd = newsize / NewChannels / NewBytes;
1239 ALBuf->OriginalFormat = OrigFormat;
1240 ALBuf->OriginalSize = size;
1241 ALBuf->OriginalAlign = OrigBytes * OrigChannels;
1243 return AL_NO_ERROR;
1246 static void ConvertData(ALvoid *dst, enum FmtType dstType, const ALvoid *src, enum SrcFmtType srcType, ALsizei len)
1248 switch(dstType)
1250 (void)Convert_ALbyte;
1251 case FmtUByte:
1252 Convert_ALubyte(dst, src, srcType, len);
1253 break;
1254 case FmtShort:
1255 Convert_ALshort(dst, src, srcType, len);
1256 break;
1257 (void)Convert_ALushort;
1258 case FmtFloat:
1259 Convert_ALfloat(dst, src, srcType, len);
1260 break;
1261 (void)Convert_ALdouble;
1266 ALuint BytesFromSrcFmt(enum SrcFmtType type)
1268 switch(type)
1270 case SrcFmtByte: return sizeof(ALbyte);
1271 case SrcFmtUByte: return sizeof(ALubyte);
1272 case SrcFmtShort: return sizeof(ALshort);
1273 case SrcFmtUShort: return sizeof(ALushort);
1274 case SrcFmtFloat: return sizeof(ALfloat);
1275 case SrcFmtDouble: return sizeof(ALdouble);
1276 case SrcFmtMulaw: return sizeof(ALubyte);
1278 return 0;
1280 ALuint ChannelsFromSrcFmt(enum SrcFmtChannels chans)
1282 switch(chans)
1284 case SrcFmtMono: return 1;
1285 case SrcFmtStereo: return 2;
1286 case SrcFmtRear: return 2;
1287 case SrcFmtQuad: return 4;
1288 case SrcFmtX51: return 6;
1289 case SrcFmtX61: return 7;
1290 case SrcFmtX71: return 8;
1292 return 0;
1294 void DecomposeInputFormat(ALenum format, enum SrcFmtChannels *chans,
1295 enum SrcFmtType *type)
1297 switch(format)
1299 case AL_FORMAT_MONO8:
1300 *chans = SrcFmtMono;
1301 *type = SrcFmtUByte;
1302 break;
1303 case AL_FORMAT_MONO16:
1304 *chans = SrcFmtMono;
1305 *type = SrcFmtShort;
1306 break;
1307 case AL_FORMAT_MONO_FLOAT32:
1308 *chans = SrcFmtMono;
1309 *type = SrcFmtFloat;
1310 break;
1311 case AL_FORMAT_MONO_DOUBLE_EXT:
1312 *chans = SrcFmtMono;
1313 *type = SrcFmtDouble;
1314 break;
1315 case AL_FORMAT_STEREO8:
1316 *chans = SrcFmtStereo;
1317 *type = SrcFmtUByte;
1318 break;
1319 case AL_FORMAT_STEREO16:
1320 *chans = SrcFmtStereo;
1321 *type = SrcFmtShort;
1322 break;
1323 case AL_FORMAT_STEREO_FLOAT32:
1324 *chans = SrcFmtStereo;
1325 *type = SrcFmtFloat;
1326 break;
1327 case AL_FORMAT_STEREO_DOUBLE_EXT:
1328 *chans = SrcFmtStereo;
1329 *type = SrcFmtDouble;
1330 break;
1331 case AL_FORMAT_QUAD8_LOKI:
1332 case AL_FORMAT_QUAD8:
1333 *chans = SrcFmtQuad;
1334 *type = SrcFmtUByte;
1335 break;
1336 case AL_FORMAT_QUAD16_LOKI:
1337 case AL_FORMAT_QUAD16:
1338 *chans = SrcFmtQuad;
1339 *type = SrcFmtShort;
1340 break;
1341 case AL_FORMAT_QUAD32:
1342 *chans = SrcFmtQuad;
1343 *type = SrcFmtFloat;
1344 break;
1345 case AL_FORMAT_REAR8:
1346 *chans = SrcFmtRear;
1347 *type = SrcFmtUByte;
1348 break;
1349 case AL_FORMAT_REAR16:
1350 *chans = SrcFmtRear;
1351 *type = SrcFmtShort;
1352 break;
1353 case AL_FORMAT_REAR32:
1354 *chans = SrcFmtRear;
1355 *type = SrcFmtFloat;
1356 break;
1357 case AL_FORMAT_51CHN8:
1358 *chans = SrcFmtX51;
1359 *type = SrcFmtUByte;
1360 break;
1361 case AL_FORMAT_51CHN16:
1362 *chans = SrcFmtX51;
1363 *type = SrcFmtShort;
1364 break;
1365 case AL_FORMAT_51CHN32:
1366 *chans = SrcFmtX51;
1367 *type = SrcFmtFloat;
1368 break;
1369 case AL_FORMAT_61CHN8:
1370 *chans = SrcFmtX61;
1371 *type = SrcFmtUByte;
1372 break;
1373 case AL_FORMAT_61CHN16:
1374 *chans = SrcFmtX61;
1375 *type = SrcFmtShort;
1376 break;
1377 case AL_FORMAT_61CHN32:
1378 *chans = SrcFmtX61;
1379 *type = SrcFmtFloat;
1380 break;
1381 case AL_FORMAT_71CHN8:
1382 *chans = SrcFmtX71;
1383 *type = SrcFmtUByte;
1384 break;
1385 case AL_FORMAT_71CHN16:
1386 *chans = SrcFmtX71;
1387 *type = SrcFmtShort;
1388 break;
1389 case AL_FORMAT_71CHN32:
1390 *chans = SrcFmtX71;
1391 *type = SrcFmtFloat;
1392 break;
1393 case AL_FORMAT_MONO_MULAW:
1394 *chans = SrcFmtMono;
1395 *type = SrcFmtMulaw;
1396 break;
1397 case AL_FORMAT_STEREO_MULAW:
1398 *chans = SrcFmtStereo;
1399 *type = SrcFmtMulaw;
1400 break;
1401 case AL_FORMAT_QUAD_MULAW:
1402 *chans = SrcFmtQuad;
1403 *type = SrcFmtMulaw;
1404 break;
1405 case AL_FORMAT_REAR_MULAW:
1406 *chans = SrcFmtRear;
1407 *type = SrcFmtMulaw;
1408 break;
1409 case AL_FORMAT_51CHN_MULAW:
1410 *chans = SrcFmtX51;
1411 *type = SrcFmtMulaw;
1412 break;
1413 case AL_FORMAT_61CHN_MULAW:
1414 *chans = SrcFmtX61;
1415 *type = SrcFmtMulaw;
1416 break;
1417 case AL_FORMAT_71CHN_MULAW:
1418 *chans = SrcFmtX71;
1419 *type = SrcFmtMulaw;
1420 break;
1422 default:
1423 AL_PRINT("Unhandled format specified: 0x%X\n", format);
1424 abort();
1428 ALuint BytesFromFmt(enum FmtType type)
1430 switch(type)
1432 case FmtUByte: return sizeof(ALubyte);
1433 case FmtShort: return sizeof(ALshort);
1434 case FmtFloat: return sizeof(ALfloat);
1436 return 0;
1438 ALuint ChannelsFromFmt(enum FmtChannels chans)
1440 switch(chans)
1442 case FmtMono: return 1;
1443 case FmtStereo: return 2;
1444 case FmtRear: return 2;
1445 case FmtQuad: return 4;
1446 case FmtX51: return 6;
1447 case FmtX61: return 7;
1448 case FmtX71: return 8;
1450 return 0;
1452 void DecomposeFormat(ALenum format, enum FmtChannels *chans, enum FmtType *type)
1454 switch(format)
1456 case AL_FORMAT_MONO8:
1457 *chans = FmtMono;
1458 *type = FmtUByte;
1459 break;
1460 case AL_FORMAT_MONO16:
1461 *chans = FmtMono;
1462 *type = FmtShort;
1463 break;
1464 case AL_FORMAT_MONO_FLOAT32:
1465 *chans = FmtMono;
1466 *type = FmtFloat;
1467 break;
1468 case AL_FORMAT_STEREO8:
1469 *chans = FmtStereo;
1470 *type = FmtUByte;
1471 break;
1472 case AL_FORMAT_STEREO16:
1473 *chans = FmtStereo;
1474 *type = FmtShort;
1475 break;
1476 case AL_FORMAT_STEREO_FLOAT32:
1477 *chans = FmtStereo;
1478 *type = FmtFloat;
1479 break;
1480 case AL_FORMAT_QUAD8_LOKI:
1481 case AL_FORMAT_QUAD8:
1482 *chans = FmtQuad;
1483 *type = FmtUByte;
1484 break;
1485 case AL_FORMAT_QUAD16_LOKI:
1486 case AL_FORMAT_QUAD16:
1487 *chans = FmtQuad;
1488 *type = FmtShort;
1489 break;
1490 case AL_FORMAT_QUAD32:
1491 *chans = FmtQuad;
1492 *type = FmtFloat;
1493 break;
1494 case AL_FORMAT_REAR8:
1495 *chans = FmtRear;
1496 *type = FmtUByte;
1497 break;
1498 case AL_FORMAT_REAR16:
1499 *chans = FmtRear;
1500 *type = FmtShort;
1501 break;
1502 case AL_FORMAT_REAR32:
1503 *chans = FmtRear;
1504 *type = FmtFloat;
1505 break;
1506 case AL_FORMAT_51CHN8:
1507 *chans = FmtX51;
1508 *type = FmtUByte;
1509 break;
1510 case AL_FORMAT_51CHN16:
1511 *chans = FmtX51;
1512 *type = FmtShort;
1513 break;
1514 case AL_FORMAT_51CHN32:
1515 *chans = FmtX51;
1516 *type = FmtFloat;
1517 break;
1518 case AL_FORMAT_61CHN8:
1519 *chans = FmtX61;
1520 *type = FmtUByte;
1521 break;
1522 case AL_FORMAT_61CHN16:
1523 *chans = FmtX61;
1524 *type = FmtShort;
1525 break;
1526 case AL_FORMAT_61CHN32:
1527 *chans = FmtX61;
1528 *type = FmtFloat;
1529 break;
1530 case AL_FORMAT_71CHN8:
1531 *chans = FmtX71;
1532 *type = FmtUByte;
1533 break;
1534 case AL_FORMAT_71CHN16:
1535 *chans = FmtX71;
1536 *type = FmtShort;
1537 break;
1538 case AL_FORMAT_71CHN32:
1539 *chans = FmtX71;
1540 *type = FmtFloat;
1541 break;
1543 default:
1544 AL_PRINT("Unhandled format specified: 0x%X\n", format);
1545 abort();
1551 * ReleaseALBuffers()
1553 * INTERNAL FN : Called by alcCloseDevice to destroy any buffers that still exist
1555 ALvoid ReleaseALBuffers(ALCdevice *device)
1557 ALsizei i;
1558 for(i = 0;i < device->BufferMap.size;i++)
1560 ALbuffer *temp = device->BufferMap.array[i].value;
1561 device->BufferMap.array[i].value = NULL;
1563 // Release sample data
1564 free(temp->data);
1566 // Release Buffer structure
1567 ALTHUNK_REMOVEENTRY(temp->buffer);
1568 memset(temp, 0, sizeof(ALbuffer));
1569 free(temp);