Seperate mixing loops depending on source channel configuration
[openal-soft.git] / OpenAL32 / alBuffer.c
blob959d309829a7558f873322af727ead7cbce83c4f
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 * alBufferSubDataEXT(ALuint buffer,ALenum format,ALvoid *data,ALsizei offset,ALsizei length)
411 * Fill buffer with audio data
413 ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length)
415 ALCcontext *Context;
416 ALbuffer *ALBuf;
418 Context = alcGetCurrentContext();
419 SuspendContext(Context);
421 if(alIsBuffer(buffer) && buffer != 0)
423 ALBuf = (ALbuffer*)ALTHUNK_LOOKUPENTRY(buffer);
424 if(ALBuf->data == NULL)
426 // buffer does not have any data
427 alSetError(AL_INVALID_NAME);
429 else if(length < 0 || offset < 0 || (length > 0 && data == NULL))
431 // data is NULL or offset/length is negative
432 alSetError(AL_INVALID_VALUE);
434 else
436 switch(format)
438 case AL_FORMAT_REAR8:
439 case AL_FORMAT_REAR16:
440 case AL_FORMAT_REAR32: {
441 ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
442 ((format==AL_FORMAT_REAR16) ? 2 :
443 4));
445 if(ALBuf->eOriginalFormat != AL_FORMAT_REAR8 &&
446 ALBuf->eOriginalFormat != AL_FORMAT_REAR16 &&
447 ALBuf->eOriginalFormat != AL_FORMAT_REAR32)
449 alSetError(AL_INVALID_ENUM);
450 break;
453 if(ALBuf->size/4/sizeof(ALshort) < (ALuint)offset+length)
455 alSetError(AL_INVALID_VALUE);
456 break;
459 ConvertDataRear(&ALBuf->data[offset*4], data, OrigBytes, length*2);
460 } break;
462 case AL_FORMAT_MONO_IMA4:
463 case AL_FORMAT_STEREO_IMA4: {
464 int Channels = aluChannelsFromFormat(ALBuf->format);
466 if(ALBuf->eOriginalFormat != format)
468 alSetError(AL_INVALID_ENUM);
469 break;
472 if((offset%65) != 0 || (length%65) != 0 ||
473 ALBuf->size/Channels/sizeof(ALshort) < (ALuint)offset+length)
475 alSetError(AL_INVALID_VALUE);
476 break;
479 ConvertDataIMA4(&ALBuf->data[offset*Channels], data, Channels, length/65*Channels);
480 } break;
482 default: {
483 ALuint Channels = aluChannelsFromFormat(format);
484 ALuint Bytes = aluBytesFromFormat(format);
486 if(Channels != aluChannelsFromFormat(ALBuf->format))
488 alSetError(AL_INVALID_ENUM);
489 break;
492 if(ALBuf->size/Channels/sizeof(ALshort) < (ALuint)offset+length)
494 alSetError(AL_INVALID_VALUE);
495 break;
498 ConvertData(&ALBuf->data[offset*Channels], data, Bytes, length*Channels);
499 } break;
503 else
505 // Invalid Buffer Name
506 alSetError(AL_INVALID_NAME);
509 ProcessContext(Context);
513 ALAPI void ALAPIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
515 ALCcontext *pContext;
517 (void)flValue;
519 pContext = alcGetCurrentContext();
520 SuspendContext(pContext);
522 if (alIsBuffer(buffer) && (buffer != 0))
524 switch(eParam)
526 default:
527 alSetError(AL_INVALID_ENUM);
528 break;
531 else
533 alSetError(AL_INVALID_NAME);
536 ProcessContext(pContext);
540 ALAPI void ALAPIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
542 ALCcontext *pContext;
544 (void)flValue1;
545 (void)flValue2;
546 (void)flValue3;
548 pContext = alcGetCurrentContext();
549 SuspendContext(pContext);
551 if (alIsBuffer(buffer) && (buffer != 0))
553 switch(eParam)
555 default:
556 alSetError(AL_INVALID_ENUM);
557 break;
560 else
562 alSetError(AL_INVALID_NAME);
565 ProcessContext(pContext);
569 ALAPI void ALAPIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues)
571 ALCcontext *pContext;
573 (void)flValues;
575 pContext = alcGetCurrentContext();
576 SuspendContext(pContext);
578 if (alIsBuffer(buffer) && (buffer != 0))
580 switch(eParam)
582 default:
583 alSetError(AL_INVALID_ENUM);
584 break;
587 else
589 alSetError(AL_INVALID_NAME);
592 ProcessContext(pContext);
596 ALAPI void ALAPIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
598 ALCcontext *pContext;
600 (void)lValue;
602 pContext = alcGetCurrentContext();
603 SuspendContext(pContext);
605 if (alIsBuffer(buffer) && (buffer != 0))
607 switch(eParam)
609 default:
610 alSetError(AL_INVALID_ENUM);
611 break;
614 else
616 alSetError(AL_INVALID_NAME);
619 ProcessContext(pContext);
623 ALAPI void ALAPIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
625 ALCcontext *pContext;
627 (void)lValue1;
628 (void)lValue2;
629 (void)lValue3;
631 pContext = alcGetCurrentContext();
632 SuspendContext(pContext);
634 if (alIsBuffer(buffer) && (buffer != 0))
636 switch(eParam)
638 default:
639 alSetError(AL_INVALID_ENUM);
640 break;
643 else
645 alSetError(AL_INVALID_NAME);
648 ProcessContext(pContext);
652 ALAPI void ALAPIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues)
654 ALCcontext *pContext;
656 (void)plValues;
658 pContext = alcGetCurrentContext();
659 SuspendContext(pContext);
661 if (alIsBuffer(buffer) && (buffer != 0))
663 switch(eParam)
665 default:
666 alSetError(AL_INVALID_ENUM);
667 break;
670 else
672 alSetError(AL_INVALID_NAME);
675 ProcessContext(pContext);
679 ALAPI ALvoid ALAPIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue)
681 ALCcontext *pContext;
683 pContext = alcGetCurrentContext();
684 SuspendContext(pContext);
686 if (pflValue)
688 if (alIsBuffer(buffer) && (buffer != 0))
690 switch(eParam)
692 default:
693 alSetError(AL_INVALID_ENUM);
694 break;
697 else
699 alSetError(AL_INVALID_NAME);
702 else
704 alSetError(AL_INVALID_VALUE);
707 ProcessContext(pContext);
711 ALAPI void ALAPIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3)
713 ALCcontext *pContext;
715 pContext = alcGetCurrentContext();
716 SuspendContext(pContext);
718 if ((pflValue1) && (pflValue2) && (pflValue3))
720 if (alIsBuffer(buffer) && (buffer != 0))
722 switch(eParam)
724 default:
725 alSetError(AL_INVALID_ENUM);
726 break;
729 else
731 alSetError(AL_INVALID_NAME);
734 else
736 alSetError(AL_INVALID_VALUE);
739 ProcessContext(pContext);
743 ALAPI void ALAPIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues)
745 ALCcontext *pContext;
747 pContext = alcGetCurrentContext();
748 SuspendContext(pContext);
750 if (pflValues)
752 if (alIsBuffer(buffer) && (buffer != 0))
754 switch(eParam)
756 default:
757 alSetError(AL_INVALID_ENUM);
758 break;
761 else
763 alSetError(AL_INVALID_NAME);
766 else
768 alSetError(AL_INVALID_VALUE);
771 ProcessContext(pContext);
775 ALAPI ALvoid ALAPIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue)
777 ALCcontext *pContext;
778 ALbuffer *pBuffer;
780 pContext = alcGetCurrentContext();
781 SuspendContext(pContext);
783 if (plValue)
785 if (alIsBuffer(buffer) && (buffer != 0))
787 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
789 switch (eParam)
791 case AL_FREQUENCY:
792 *plValue = pBuffer->frequency;
793 break;
795 case AL_BITS:
796 *plValue = aluBytesFromFormat(pBuffer->format) * 8;
797 break;
799 case AL_CHANNELS:
800 *plValue = aluChannelsFromFormat(pBuffer->format);
801 break;
803 case AL_SIZE:
804 *plValue = pBuffer->size;
805 break;
807 default:
808 alSetError(AL_INVALID_ENUM);
809 break;
812 else
814 alSetError(AL_INVALID_NAME);
817 else
819 alSetError(AL_INVALID_VALUE);
822 ProcessContext(pContext);
826 ALAPI void ALAPIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3)
828 ALCcontext *pContext;
830 pContext = alcGetCurrentContext();
831 SuspendContext(pContext);
833 if ((plValue1) && (plValue2) && (plValue3))
835 if (alIsBuffer(buffer) && (buffer != 0))
837 switch(eParam)
839 default:
840 alSetError(AL_INVALID_ENUM);
841 break;
844 else
846 alSetError(AL_INVALID_NAME);
849 else
851 alSetError(AL_INVALID_VALUE);
854 ProcessContext(pContext);
858 ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues)
860 ALCcontext *pContext;
862 pContext = alcGetCurrentContext();
863 SuspendContext(pContext);
865 if (plValues)
867 if (alIsBuffer(buffer) && (buffer != 0))
869 switch (eParam)
871 case AL_FREQUENCY:
872 case AL_BITS:
873 case AL_CHANNELS:
874 case AL_SIZE:
875 alGetBufferi(buffer, eParam, plValues);
876 break;
878 default:
879 alSetError(AL_INVALID_ENUM);
880 break;
883 else
885 alSetError(AL_INVALID_NAME);
888 else
890 alSetError(AL_INVALID_VALUE);
893 ProcessContext(pContext);
897 * LoadData
899 * Loads the specified data into the buffer, using the specified formats.
900 * Currently, the new format must be 16-bit, and must have the same channel
901 * configuration as the original format. This does NOT handle compressed
902 * formats (eg. IMA4).
904 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
906 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
907 ALuint OrigBytes = aluBytesFromFormat(OrigFormat);
908 ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
909 ALsizei padding = 2;
910 ALvoid *temp;
912 assert(aluBytesFromFormat(NewFormat) == 2);
913 assert(NewChannels == OrigChannels);
915 if ((size%(OrigBytes*OrigChannels)) != 0)
917 alSetError(AL_INVALID_VALUE);
918 return;
921 // Samples are converted to 16 bit here
922 size /= OrigBytes;
923 temp = realloc(ALBuf->data, (padding*NewChannels + size) * sizeof(ALshort));
924 if(temp)
926 ALBuf->data = temp;
927 ConvertData(ALBuf->data, data, OrigBytes, size);
929 memset(&(ALBuf->data[size]), 0, padding*NewChannels*sizeof(ALshort));
931 ALBuf->format = NewFormat;
932 ALBuf->eOriginalFormat = OrigFormat;
933 ALBuf->size = size*sizeof(ALshort);
934 ALBuf->frequency = freq;
935 ALBuf->padding = padding;
937 else
938 alSetError(AL_OUT_OF_MEMORY);
941 static void ConvertData(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len)
943 ALsizei i;
944 switch(origBytes)
946 case 1:
947 for(i = 0;i < len;i++)
948 dst[i] = ((ALshort)((ALubyte*)src)[i] - 128) << 8;
949 break;
951 case 2:
952 memcpy(dst, src, len*sizeof(ALshort));
953 break;
955 case 4:
956 for(i = 0;i < len;i++)
958 ALint smp;
959 smp = (((ALfloat*)src)[i] * 32767.5f - 0.5f);
960 smp = min(smp, 32767);
961 smp = max(smp, -32768);
962 dst[i] = (ALshort)smp;
964 break;
966 default:
967 assert(0);
971 static void ConvertDataRear(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len)
973 ALsizei i;
974 switch(origBytes)
976 case 1:
977 for(i = 0;i < len;i+=4)
979 dst[i+0] = 0;
980 dst[i+1] = 0;
981 dst[i+2] = ((ALshort)((ALubyte*)src)[i/2+0] - 128) << 8;
982 dst[i+3] = ((ALshort)((ALubyte*)src)[i/2+1] - 128) << 8;
984 break;
986 case 2:
987 for(i = 0;i < len;i+=4)
989 dst[i+0] = 0;
990 dst[i+1] = 0;
991 dst[i+2] = ((ALshort*)src)[i/2+0];
992 dst[i+3] = ((ALshort*)src)[i/2+1];
994 break;
996 case 4:
997 for(i = 0;i < len;i+=4)
999 ALint smp;
1000 dst[i+0] = 0;
1001 dst[i+1] = 0;
1002 smp = (((ALfloat*)src)[i/2+0] * 32767.5f - 0.5);
1003 smp = min(smp, 32767);
1004 smp = max(smp, -32768);
1005 dst[i+2] = (ALshort)smp;
1006 smp = (((ALfloat*)src)[i/2+1] * 32767.5f - 0.5);
1007 smp = min(smp, 32767);
1008 smp = max(smp, -32768);
1009 dst[i+3] = (ALshort)smp;
1011 break;
1013 default:
1014 assert(0);
1018 static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, ALsizei len)
1020 const ALuint *IMAData;
1021 ALint Sample[2],Index[2];
1022 ALuint IMACode[2];
1023 ALsizei i,j,k,c;
1025 assert(origChans <= 2);
1027 IMAData = src;
1028 for(i = 0;i < len/origChans;i++)
1030 for(c = 0;c < origChans;c++)
1032 Sample[c] = ((ALshort*)IMAData)[0];
1033 Index[c] = ((ALshort*)IMAData)[1];
1035 Index[c] = ((Index[c]<0) ? 0 : Index[c]);
1036 Index[c] = ((Index[c]>88) ? 88 : Index[c]);
1038 dst[i*65*origChans + c] = (ALshort)Sample[c];
1040 IMAData++;
1043 for(j = 1;j < 65;j += 8)
1045 for(c = 0;c < origChans;c++)
1046 IMACode[c] = *(IMAData++);
1048 for(k = 0;k < 8;k++)
1050 for(c = 0;c < origChans;c++)
1052 Sample[c] += ((g_IMAStep_size[Index[c]]*g_IMACodeword_4[IMACode[c]&15])/8);
1053 Index[c] += g_IMAIndex_adjust_4[IMACode[c]&15];
1055 if(Sample[c] < -32768) Sample[c] = -32768;
1056 else if(Sample[c] > 32767) Sample[c] = 32767;
1058 if(Index[c]<0) Index[c] = 0;
1059 else if(Index[c]>88) Index[c] = 88;
1061 dst[(i*65+j+k)*origChans + c] = (ALshort)Sample[c];
1062 IMACode[c] >>= 4;
1070 * ReleaseALBuffers()
1072 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
1074 ALvoid ReleaseALBuffers(ALvoid)
1076 ALbuffer *ALBuffer;
1077 ALbuffer *ALBufferTemp;
1079 #ifdef _DEBUG
1080 if(g_uiBufferCount > 0)
1081 AL_PRINT("exit(): deleting %d Buffer(s)\n", g_uiBufferCount);
1082 #endif
1084 ALBuffer = g_pBuffers;
1085 while(ALBuffer)
1087 // Release sample data
1088 free(ALBuffer->data);
1090 // Release Buffer structure
1091 ALBufferTemp = ALBuffer;
1092 ALBuffer = ALBuffer->next;
1093 memset(ALBufferTemp, 0, sizeof(ALbuffer));
1094 free(ALBufferTemp);
1096 g_pBuffers = NULL;
1097 g_uiBufferCount = 0;