Be more flexible with channel count when loading IMA4 data
[openal-soft.git] / OpenAL32 / alBuffer.c
bloba8258d04a8a3413f8a5ba683b69d5569a720b156
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 #define _CRT_SECURE_NO_DEPRECATE // get rid of sprintf security warnings on VS2005
23 #include "config.h"
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <assert.h>
28 #include "alMain.h"
29 #include "AL/al.h"
30 #include "AL/alc.h"
31 #include "alError.h"
32 #include "alBuffer.h"
33 #include "alThunk.h"
36 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat);
37 static void ConvertData(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len);
38 static void ConvertDataRear(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len);
39 static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, ALsizei len);
42 * AL Buffer Functions
44 * AL Buffers are shared amoung Contexts, so we store the list of generated Buffers
45 * as a global variable in this module. (A valid context is not required to make
46 * AL Buffer function calls
51 * Global Variables
54 static ALbuffer *g_pBuffers = NULL; // Linked List of Buffers
55 static ALuint g_uiBufferCount = 0; // Buffer Count
57 static const long g_IMAStep_size[89]={ // IMA ADPCM Stepsize table
58 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
59 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
60 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
61 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
62 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493,10442,11487,12635,13899,
63 15289,16818,18500,20350,22358,24633,27086,29794,32767
66 static const long g_IMACodeword_4[16]={ // IMA4 ADPCM Codeword decode table
67 1, 3, 5, 7, 9, 11, 13, 15,
68 -1,-3,-5,-7,-9,-11,-13,-15,
71 static const long g_IMAIndex_adjust_4[16]={ // IMA4 ADPCM Step index adjust decode table
72 -1,-1,-1,-1, 2, 4, 6, 8,
73 -1,-1,-1,-1, 2, 4, 6, 8
77 * alGenBuffers(ALsizei n, ALuint *puiBuffers)
79 * Generates n AL Buffers, and stores the Buffers Names in the array pointed to by puiBuffers
81 ALAPI ALvoid ALAPIENTRY alGenBuffers(ALsizei n,ALuint *puiBuffers)
83 ALCcontext *Context;
84 ALsizei i=0;
86 Context = alcGetCurrentContext();
87 SuspendContext(Context);
89 // Check that we are actually generation some Buffers
90 if (n > 0)
92 // Check the pointer is valid (and points to enough memory to store Buffer Names)
93 if (!IsBadWritePtr((void*)puiBuffers, n * sizeof(ALuint)))
95 ALbuffer **list = &g_pBuffers;
96 while(*list)
97 list = &(*list)->next;
99 // Create all the new Buffers
100 while(i < n)
102 *list = calloc(1, sizeof(ALbuffer));
103 if(!(*list))
105 alDeleteBuffers(i, puiBuffers);
106 alSetError(AL_OUT_OF_MEMORY);
107 break;
110 puiBuffers[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
111 (*list)->state = UNUSED;
112 g_uiBufferCount++;
113 i++;
115 list = &(*list)->next;
118 else
120 // Pointer does not point to enough memory to write Buffer names
121 alSetError(AL_INVALID_VALUE);
125 ProcessContext(Context);
127 return;
131 * alDeleteBuffers(ALsizei n, ALuint *puiBuffers)
133 * Deletes the n AL Buffers pointed to by puiBuffers
135 ALAPI ALvoid ALAPIENTRY alDeleteBuffers(ALsizei n, const ALuint *puiBuffers)
137 ALCcontext *Context;
138 ALbuffer *ALBuf;
139 ALsizei i;
140 ALboolean bFailed = AL_FALSE;
142 Context = alcGetCurrentContext();
143 SuspendContext(Context);
145 // Check we are actually Deleting some Buffers
146 if (n >= 0)
148 // Check that all the buffers are valid and can actually be deleted
149 for (i = 0; i < n; i++)
151 // Check for valid Buffer ID (can be NULL buffer)
152 if (alIsBuffer(puiBuffers[i]))
154 // If not the NULL buffer, check that the reference count is 0
155 ALBuf = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
156 if (ALBuf)
158 if (ALBuf->refcount != 0)
160 // Buffer still in use, cannot be deleted
161 alSetError(AL_INVALID_OPERATION);
162 bFailed = AL_TRUE;
166 else
168 // Invalid Buffer
169 alSetError(AL_INVALID_NAME);
170 bFailed = AL_TRUE;
174 // If all the Buffers were valid (and have Reference Counts of 0), then we can delete them
175 if (!bFailed)
177 for (i = 0; i < n; i++)
179 if (puiBuffers[i] && alIsBuffer(puiBuffers[i]))
181 ALbuffer **list = &g_pBuffers;
183 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
184 while(*list && *list != ALBuf)
185 list = &(*list)->next;
187 if(*list)
188 *list = (*list)->next;
190 // Release the memory used to store audio data
191 free(ALBuf->data);
193 // Release buffer structure
194 ALTHUNK_REMOVEENTRY(puiBuffers[i]);
195 memset(ALBuf, 0, sizeof(ALbuffer));
196 g_uiBufferCount--;
197 free(ALBuf);
202 else
203 alSetError(AL_INVALID_VALUE);
205 ProcessContext(Context);
207 return;
212 * alIsBuffer(ALuint uiBuffer)
214 * Checks if ulBuffer is a valid Buffer Name
216 ALAPI ALboolean ALAPIENTRY alIsBuffer(ALuint uiBuffer)
218 ALCcontext *Context;
219 ALboolean result=AL_FALSE;
220 ALbuffer *ALBuf;
221 ALbuffer *TgtALBuf;
223 Context = alcGetCurrentContext();
224 SuspendContext(Context);
226 if (uiBuffer)
228 TgtALBuf = (ALbuffer *)ALTHUNK_LOOKUPENTRY(uiBuffer);
230 // Check through list of generated buffers for uiBuffer
231 ALBuf = g_pBuffers;
232 while (ALBuf)
234 if (ALBuf == TgtALBuf)
236 result = AL_TRUE;
237 break;
240 ALBuf = ALBuf->next;
243 else
245 result = AL_TRUE;
249 ProcessContext(Context);
251 return result;
255 * alBufferData(ALuint buffer,ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
257 * Fill buffer with audio data
259 ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq)
261 ALCcontext *Context;
262 ALsizei padding = 2;
263 ALbuffer *ALBuf;
264 ALvoid *temp;
266 Context = alcGetCurrentContext();
267 SuspendContext(Context);
269 if (alIsBuffer(buffer) && (buffer != 0))
271 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
272 if ((ALBuf->refcount==0)&&(data))
274 switch(format)
276 case AL_FORMAT_MONO8:
277 case AL_FORMAT_MONO16:
278 case AL_FORMAT_MONO_FLOAT32:
279 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO16);
280 break;
282 case AL_FORMAT_STEREO8:
283 case AL_FORMAT_STEREO16:
284 case AL_FORMAT_STEREO_FLOAT32:
285 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO16);
286 break;
288 case AL_FORMAT_REAR8:
289 case AL_FORMAT_REAR16:
290 case AL_FORMAT_REAR32: {
291 ALuint NewFormat = AL_FORMAT_QUAD16;
292 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
293 ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
294 ((format==AL_FORMAT_REAR16) ? 2 :
295 4));
297 assert(aluBytesFromFormat(NewFormat) == 2);
299 if((size%(OrigBytes*2)) != 0)
301 alSetError(AL_INVALID_VALUE);
302 break;
305 size /= OrigBytes;
306 size *= 2;
308 // Samples are converted to 16 bit here
309 temp = realloc(ALBuf->data, (padding*NewChannels + size) * sizeof(ALshort));
310 if(temp)
312 ALBuf->data = temp;
313 ConvertDataRear(ALBuf->data, data, OrigBytes, size);
315 memset(&(ALBuf->data[size]), 0, padding*NewChannels*sizeof(ALshort));
317 ALBuf->format = NewFormat;
318 ALBuf->eOriginalFormat = format;
319 ALBuf->size = size*sizeof(ALshort);
320 ALBuf->frequency = freq;
321 ALBuf->padding = padding;
323 else
324 alSetError(AL_OUT_OF_MEMORY);
325 } break;
327 case AL_FORMAT_QUAD8_LOKI:
328 case AL_FORMAT_QUAD16_LOKI:
329 case AL_FORMAT_QUAD8:
330 case AL_FORMAT_QUAD16:
331 case AL_FORMAT_QUAD32:
332 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD16);
333 break;
335 case AL_FORMAT_51CHN8:
336 case AL_FORMAT_51CHN16:
337 case AL_FORMAT_51CHN32:
338 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN16);
339 break;
341 case AL_FORMAT_61CHN8:
342 case AL_FORMAT_61CHN16:
343 case AL_FORMAT_61CHN32:
344 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN16);
345 break;
347 case AL_FORMAT_71CHN8:
348 case AL_FORMAT_71CHN16:
349 case AL_FORMAT_71CHN32:
350 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN16);
351 break;
353 case AL_FORMAT_MONO_IMA4:
354 case AL_FORMAT_STEREO_IMA4: {
355 int OrigChans = ((format==AL_FORMAT_MONO_IMA4) ? 1 : 2);
357 // Here is where things vary:
358 // nVidia and Apple use 64+1 samples per channel per block => block_size=36*chans bytes
359 // Most PC sound software uses 2040+1 samples per channel per block -> block_size=1024*chans bytes
360 if((size%(36*OrigChans)) != 0)
362 alSetError(AL_INVALID_VALUE);
363 break;
366 size /= 36;
367 size *= 65;
369 // Allocate extra padding samples
370 temp = realloc(ALBuf->data, (padding*OrigChans + size)*sizeof(ALshort));
371 if(temp)
373 ALBuf->data = temp;
374 ConvertDataIMA4(ALBuf->data, data, OrigChans, size/65);
376 memset(&(ALBuf->data[size]), 0, padding*sizeof(ALshort)*OrigChans);
378 ALBuf->format = ((OrigChans==1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16);
379 ALBuf->eOriginalFormat = format;
380 ALBuf->size = size*sizeof(ALshort);
381 ALBuf->frequency = freq;
382 ALBuf->padding = padding;
384 else
385 alSetError(AL_OUT_OF_MEMORY);
386 } break;
388 default:
389 alSetError(AL_INVALID_ENUM);
390 break;
393 else
395 // Buffer is in use, or data is a NULL pointer
396 alSetError(AL_INVALID_VALUE);
399 else
401 // Invalid Buffer Name
402 alSetError(AL_INVALID_NAME);
405 ProcessContext(Context);
409 ALAPI void ALAPIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
411 ALCcontext *pContext;
413 (void)flValue;
415 pContext = alcGetCurrentContext();
416 SuspendContext(pContext);
418 if (alIsBuffer(buffer) && (buffer != 0))
420 switch(eParam)
422 default:
423 alSetError(AL_INVALID_ENUM);
424 break;
427 else
429 alSetError(AL_INVALID_NAME);
432 ProcessContext(pContext);
436 ALAPI void ALAPIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
438 ALCcontext *pContext;
440 (void)flValue1;
441 (void)flValue2;
442 (void)flValue3;
444 pContext = alcGetCurrentContext();
445 SuspendContext(pContext);
447 if (alIsBuffer(buffer) && (buffer != 0))
449 switch(eParam)
451 default:
452 alSetError(AL_INVALID_ENUM);
453 break;
456 else
458 alSetError(AL_INVALID_NAME);
461 ProcessContext(pContext);
465 ALAPI void ALAPIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues)
467 ALCcontext *pContext;
469 (void)flValues;
471 pContext = alcGetCurrentContext();
472 SuspendContext(pContext);
474 if (alIsBuffer(buffer) && (buffer != 0))
476 switch(eParam)
478 default:
479 alSetError(AL_INVALID_ENUM);
480 break;
483 else
485 alSetError(AL_INVALID_NAME);
488 ProcessContext(pContext);
492 ALAPI void ALAPIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
494 ALCcontext *pContext;
496 (void)lValue;
498 pContext = alcGetCurrentContext();
499 SuspendContext(pContext);
501 if (alIsBuffer(buffer) && (buffer != 0))
503 switch(eParam)
505 default:
506 alSetError(AL_INVALID_ENUM);
507 break;
510 else
512 alSetError(AL_INVALID_NAME);
515 ProcessContext(pContext);
519 ALAPI void ALAPIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
521 ALCcontext *pContext;
523 (void)lValue1;
524 (void)lValue2;
525 (void)lValue3;
527 pContext = alcGetCurrentContext();
528 SuspendContext(pContext);
530 if (alIsBuffer(buffer) && (buffer != 0))
532 switch(eParam)
534 default:
535 alSetError(AL_INVALID_ENUM);
536 break;
539 else
541 alSetError(AL_INVALID_NAME);
544 ProcessContext(pContext);
548 ALAPI void ALAPIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues)
550 ALCcontext *pContext;
552 (void)plValues;
554 pContext = alcGetCurrentContext();
555 SuspendContext(pContext);
557 if (alIsBuffer(buffer) && (buffer != 0))
559 switch(eParam)
561 default:
562 alSetError(AL_INVALID_ENUM);
563 break;
566 else
568 alSetError(AL_INVALID_NAME);
571 ProcessContext(pContext);
575 ALAPI ALvoid ALAPIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue)
577 ALCcontext *pContext;
579 pContext = alcGetCurrentContext();
580 SuspendContext(pContext);
582 if (pflValue)
584 if (alIsBuffer(buffer) && (buffer != 0))
586 switch(eParam)
588 default:
589 alSetError(AL_INVALID_ENUM);
590 break;
593 else
595 alSetError(AL_INVALID_NAME);
598 else
600 alSetError(AL_INVALID_VALUE);
603 ProcessContext(pContext);
607 ALAPI void ALAPIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3)
609 ALCcontext *pContext;
611 pContext = alcGetCurrentContext();
612 SuspendContext(pContext);
614 if ((pflValue1) && (pflValue2) && (pflValue3))
616 if (alIsBuffer(buffer) && (buffer != 0))
618 switch(eParam)
620 default:
621 alSetError(AL_INVALID_ENUM);
622 break;
625 else
627 alSetError(AL_INVALID_NAME);
630 else
632 alSetError(AL_INVALID_VALUE);
635 ProcessContext(pContext);
639 ALAPI void ALAPIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues)
641 ALCcontext *pContext;
643 pContext = alcGetCurrentContext();
644 SuspendContext(pContext);
646 if (pflValues)
648 if (alIsBuffer(buffer) && (buffer != 0))
650 switch(eParam)
652 default:
653 alSetError(AL_INVALID_ENUM);
654 break;
657 else
659 alSetError(AL_INVALID_NAME);
662 else
664 alSetError(AL_INVALID_VALUE);
667 ProcessContext(pContext);
671 ALAPI ALvoid ALAPIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue)
673 ALCcontext *pContext;
674 ALbuffer *pBuffer;
676 pContext = alcGetCurrentContext();
677 SuspendContext(pContext);
679 if (plValue)
681 if (alIsBuffer(buffer) && (buffer != 0))
683 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
685 switch (eParam)
687 case AL_FREQUENCY:
688 *plValue = pBuffer->frequency;
689 break;
691 case AL_BITS:
692 *plValue = aluBytesFromFormat(pBuffer->format) * 8;
693 break;
695 case AL_CHANNELS:
696 *plValue = aluChannelsFromFormat(pBuffer->format);
697 break;
699 case AL_SIZE:
700 *plValue = pBuffer->size;
701 break;
703 default:
704 alSetError(AL_INVALID_ENUM);
705 break;
708 else
710 alSetError(AL_INVALID_NAME);
713 else
715 alSetError(AL_INVALID_VALUE);
718 ProcessContext(pContext);
722 ALAPI void ALAPIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3)
724 ALCcontext *pContext;
726 pContext = alcGetCurrentContext();
727 SuspendContext(pContext);
729 if ((plValue1) && (plValue2) && (plValue3))
731 if (alIsBuffer(buffer) && (buffer != 0))
733 switch(eParam)
735 default:
736 alSetError(AL_INVALID_ENUM);
737 break;
740 else
742 alSetError(AL_INVALID_NAME);
745 else
747 alSetError(AL_INVALID_VALUE);
750 ProcessContext(pContext);
754 ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues)
756 ALCcontext *pContext;
758 pContext = alcGetCurrentContext();
759 SuspendContext(pContext);
761 if (plValues)
763 if (alIsBuffer(buffer) && (buffer != 0))
765 switch (eParam)
767 case AL_FREQUENCY:
768 case AL_BITS:
769 case AL_CHANNELS:
770 case AL_SIZE:
771 alGetBufferi(buffer, eParam, plValues);
772 break;
774 default:
775 alSetError(AL_INVALID_ENUM);
776 break;
779 else
781 alSetError(AL_INVALID_NAME);
784 else
786 alSetError(AL_INVALID_VALUE);
789 ProcessContext(pContext);
793 * LoadData
795 * Loads the specified data into the buffer, using the specified formats.
796 * Currently, the new format must be 16-bit, and must have the same channel
797 * configuration as the original format. This does NOT handle compressed
798 * formats (eg. IMA4).
800 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
802 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
803 ALuint OrigBytes = aluBytesFromFormat(OrigFormat);
804 ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
805 ALsizei padding = 2;
806 ALvoid *temp;
808 assert(aluBytesFromFormat(NewFormat) == 2);
809 assert(NewChannels == OrigChannels);
811 if ((size%(OrigBytes*OrigChannels)) != 0)
813 alSetError(AL_INVALID_VALUE);
814 return;
817 // Samples are converted to 16 bit here
818 size /= OrigBytes;
819 temp = realloc(ALBuf->data, (padding*NewChannels + size) * sizeof(ALshort));
820 if(temp)
822 ALBuf->data = temp;
823 ConvertData(ALBuf->data, data, OrigBytes, size);
825 memset(&(ALBuf->data[size]), 0, padding*NewChannels*sizeof(ALshort));
827 ALBuf->format = NewFormat;
828 ALBuf->eOriginalFormat = OrigFormat;
829 ALBuf->size = size*sizeof(ALshort);
830 ALBuf->frequency = freq;
831 ALBuf->padding = padding;
833 else
834 alSetError(AL_OUT_OF_MEMORY);
837 static void ConvertData(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len)
839 ALsizei i;
840 switch(origBytes)
842 case 1:
843 for(i = 0;i < len;i++)
844 dst[i] = ((ALshort)((ALubyte*)src)[i] - 128) << 8;
845 break;
847 case 2:
848 memcpy(dst, src, len*sizeof(ALshort));
849 break;
851 case 4:
852 for(i = 0;i < len;i++)
854 ALint smp;
855 smp = (((ALfloat*)src)[i] * 32767.5f - 0.5f);
856 smp = min(smp, 32767);
857 smp = max(smp, -32768);
858 dst[i] = (ALshort)smp;
860 break;
862 default:
863 assert(0);
867 static void ConvertDataRear(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len)
869 ALsizei i;
870 switch(origBytes)
872 case 1:
873 for(i = 0;i < len;i+=4)
875 dst[i+0] = 0;
876 dst[i+1] = 0;
877 dst[i+2] = ((ALshort)((ALubyte*)src)[i/2+0] - 128) << 8;
878 dst[i+3] = ((ALshort)((ALubyte*)src)[i/2+1] - 128) << 8;
880 break;
882 case 2:
883 for(i = 0;i < len;i+=4)
885 dst[i+0] = 0;
886 dst[i+1] = 0;
887 dst[i+2] = ((ALshort*)src)[i/2+0];
888 dst[i+3] = ((ALshort*)src)[i/2+1];
890 break;
892 case 4:
893 for(i = 0;i < len;i+=4)
895 ALint smp;
896 dst[i+0] = 0;
897 dst[i+1] = 0;
898 smp = (((ALfloat*)src)[i/2+0] * 32767.5f - 0.5);
899 smp = min(smp, 32767);
900 smp = max(smp, -32768);
901 dst[i+2] = (ALshort)smp;
902 smp = (((ALfloat*)src)[i/2+1] * 32767.5f - 0.5);
903 smp = min(smp, 32767);
904 smp = max(smp, -32768);
905 dst[i+3] = (ALshort)smp;
907 break;
909 default:
910 assert(0);
914 static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, ALsizei len)
916 const ALuint *IMAData;
917 ALint Sample[2],Index[2];
918 ALuint IMACode[2];
919 ALsizei i,j,k,c;
921 assert(origChans <= 2);
923 IMAData = src;
924 for(i = 0;i < len/origChans;i++)
926 for(c = 0;c < origChans;c++)
928 Sample[c] = ((ALshort*)IMAData)[0];
929 Index[c] = ((ALshort*)IMAData)[1];
931 Index[c] = ((Index[c]<0) ? 0 : Index[c]);
932 Index[c] = ((Index[c]>88) ? 88 : Index[c]);
934 dst[i*65*origChans + c] = (ALshort)Sample[c];
936 IMAData++;
939 for(j = 1;j < 65;j += 8)
941 for(c = 0;c < origChans;c++)
942 IMACode[c] = *(IMAData++);
944 for(k = 0;k < 8;k++)
946 for(c = 0;c < origChans;c++)
948 Sample[c] += ((g_IMAStep_size[Index[c]]*g_IMACodeword_4[IMACode[c]&15])/8);
949 Index[c] += g_IMAIndex_adjust_4[IMACode[c]&15];
951 if(Sample[c] < -32768) Sample[c] = -32768;
952 else if(Sample[c] > 32767) Sample[c] = 32767;
954 if(Index[c]<0) Index[c] = 0;
955 else if(Index[c]>88) Index[c] = 88;
957 dst[(i*65+j+k)*origChans + c] = (ALshort)Sample[c];
958 IMACode[c] >>= 4;
966 * ReleaseALBuffers()
968 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
970 ALvoid ReleaseALBuffers(ALvoid)
972 ALbuffer *ALBuffer;
973 ALbuffer *ALBufferTemp;
975 #ifdef _DEBUG
976 if(g_uiBufferCount > 0)
977 AL_PRINT("exit(): deleting %d Buffer(s)\n", g_uiBufferCount);
978 #endif
980 ALBuffer = g_pBuffers;
981 while(ALBuffer)
983 // Release sample data
984 free(ALBuffer->data);
986 // Release Buffer structure
987 ALBufferTemp = ALBuffer;
988 ALBuffer = ALBuffer->next;
989 memset(ALBufferTemp, 0, sizeof(ALbuffer));
990 free(ALBufferTemp);
992 g_pBuffers = NULL;
993 g_uiBufferCount = 0;