Make sure _CRT_SECURE_NO_WARNINGS is always defined for MSVC
[openal-soft.git] / OpenAL32 / alBuffer.c
blob0dfe05badcb88da25faa8bdbcd8526257f46e901
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 "alMain.h"
27 #include "AL/al.h"
28 #include "AL/alc.h"
29 #include "alError.h"
30 #include "alBuffer.h"
31 #include "alThunk.h"
34 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat);
35 static void ConvertData(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len);
36 static void ConvertDataRear(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len);
37 static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, ALsizei len);
40 * AL Buffer Functions
42 * AL Buffers are shared amoung Contexts, so we store the list of generated Buffers
43 * as a global variable in this module. (A valid context is not required to make
44 * AL Buffer function calls
49 * Global Variables
52 static ALbuffer *g_pBuffers = NULL; // Linked List of Buffers
53 static ALuint g_uiBufferCount = 0; // Buffer Count
55 static const long g_IMAStep_size[89]={ // IMA ADPCM Stepsize table
56 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
57 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
58 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
59 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
60 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493,10442,11487,12635,13899,
61 15289,16818,18500,20350,22358,24633,27086,29794,32767
64 static const long g_IMACodeword_4[16]={ // IMA4 ADPCM Codeword decode table
65 1, 3, 5, 7, 9, 11, 13, 15,
66 -1,-3,-5,-7,-9,-11,-13,-15,
69 static const long g_IMAIndex_adjust_4[16]={ // IMA4 ADPCM Step index adjust decode table
70 -1,-1,-1,-1, 2, 4, 6, 8,
71 -1,-1,-1,-1, 2, 4, 6, 8
75 * alGenBuffers(ALsizei n, ALuint *puiBuffers)
77 * Generates n AL Buffers, and stores the Buffers Names in the array pointed to by puiBuffers
79 ALAPI ALvoid ALAPIENTRY alGenBuffers(ALsizei n,ALuint *puiBuffers)
81 ALCcontext *Context;
82 ALsizei i=0;
84 Context = alcGetCurrentContext();
85 SuspendContext(Context);
87 // Check that we are actually generation some Buffers
88 if (n > 0)
90 // Check the pointer is valid (and points to enough memory to store Buffer Names)
91 if (!IsBadWritePtr((void*)puiBuffers, n * sizeof(ALuint)))
93 ALbuffer **list = &g_pBuffers;
94 while(*list)
95 list = &(*list)->next;
97 // Create all the new Buffers
98 while(i < n)
100 *list = calloc(1, sizeof(ALbuffer));
101 if(!(*list))
103 alDeleteBuffers(i, puiBuffers);
104 alSetError(AL_OUT_OF_MEMORY);
105 break;
108 puiBuffers[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
109 (*list)->state = UNUSED;
110 g_uiBufferCount++;
111 i++;
113 list = &(*list)->next;
116 else
118 // Pointer does not point to enough memory to write Buffer names
119 alSetError(AL_INVALID_VALUE);
123 ProcessContext(Context);
125 return;
129 * alDeleteBuffers(ALsizei n, ALuint *puiBuffers)
131 * Deletes the n AL Buffers pointed to by puiBuffers
133 ALAPI ALvoid ALAPIENTRY alDeleteBuffers(ALsizei n, const ALuint *puiBuffers)
135 ALCcontext *Context;
136 ALbuffer *ALBuf;
137 ALsizei i;
138 ALboolean bFailed = AL_FALSE;
140 Context = alcGetCurrentContext();
141 SuspendContext(Context);
143 // Check we are actually Deleting some Buffers
144 if (n >= 0)
146 // Check that all the buffers are valid and can actually be deleted
147 for (i = 0; i < n; i++)
149 // Check for valid Buffer ID (can be NULL buffer)
150 if (alIsBuffer(puiBuffers[i]))
152 // If not the NULL buffer, check that the reference count is 0
153 ALBuf = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
154 if (ALBuf)
156 if (ALBuf->refcount != 0)
158 // Buffer still in use, cannot be deleted
159 alSetError(AL_INVALID_OPERATION);
160 bFailed = AL_TRUE;
164 else
166 // Invalid Buffer
167 alSetError(AL_INVALID_NAME);
168 bFailed = AL_TRUE;
172 // If all the Buffers were valid (and have Reference Counts of 0), then we can delete them
173 if (!bFailed)
175 for (i = 0; i < n; i++)
177 if (puiBuffers[i] && alIsBuffer(puiBuffers[i]))
179 ALbuffer **list = &g_pBuffers;
181 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
182 while(*list && *list != ALBuf)
183 list = &(*list)->next;
185 if(*list)
186 *list = (*list)->next;
188 // Release the memory used to store audio data
189 free(ALBuf->data);
191 // Release buffer structure
192 ALTHUNK_REMOVEENTRY(puiBuffers[i]);
193 memset(ALBuf, 0, sizeof(ALbuffer));
194 g_uiBufferCount--;
195 free(ALBuf);
200 else
201 alSetError(AL_INVALID_VALUE);
203 ProcessContext(Context);
205 return;
210 * alIsBuffer(ALuint uiBuffer)
212 * Checks if ulBuffer is a valid Buffer Name
214 ALAPI ALboolean ALAPIENTRY alIsBuffer(ALuint uiBuffer)
216 ALCcontext *Context;
217 ALboolean result=AL_FALSE;
218 ALbuffer *ALBuf;
219 ALbuffer *TgtALBuf;
221 Context = alcGetCurrentContext();
222 SuspendContext(Context);
224 if (uiBuffer)
226 TgtALBuf = (ALbuffer *)ALTHUNK_LOOKUPENTRY(uiBuffer);
228 // Check through list of generated buffers for uiBuffer
229 ALBuf = g_pBuffers;
230 while (ALBuf)
232 if (ALBuf == TgtALBuf)
234 result = AL_TRUE;
235 break;
238 ALBuf = ALBuf->next;
241 else
243 result = AL_TRUE;
247 ProcessContext(Context);
249 return result;
253 * alBufferData(ALuint buffer,ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
255 * Fill buffer with audio data
257 ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq)
259 ALCcontext *Context;
260 ALsizei padding = 2;
261 ALbuffer *ALBuf;
262 ALvoid *temp;
264 Context = alcGetCurrentContext();
265 SuspendContext(Context);
267 if (alIsBuffer(buffer) && (buffer != 0))
269 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
270 if ((ALBuf->refcount==0)&&(data))
272 switch(format)
274 case AL_FORMAT_MONO8:
275 case AL_FORMAT_MONO16:
276 case AL_FORMAT_MONO_FLOAT32:
277 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO16);
278 break;
280 case AL_FORMAT_STEREO8:
281 case AL_FORMAT_STEREO16:
282 case AL_FORMAT_STEREO_FLOAT32:
283 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO16);
284 break;
286 case AL_FORMAT_REAR8:
287 case AL_FORMAT_REAR16:
288 case AL_FORMAT_REAR32: {
289 ALuint NewFormat = AL_FORMAT_QUAD16;
290 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
291 ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
292 ((format==AL_FORMAT_REAR16) ? 2 :
293 4));
295 assert(aluBytesFromFormat(NewFormat) == 2);
297 if((size%(OrigBytes*2)) != 0)
299 alSetError(AL_INVALID_VALUE);
300 break;
303 size /= OrigBytes;
304 size *= 2;
306 // Samples are converted to 16 bit here
307 temp = realloc(ALBuf->data, (padding*NewChannels + size) * sizeof(ALshort));
308 if(temp)
310 ALBuf->data = temp;
311 ConvertDataRear(ALBuf->data, data, OrigBytes, size);
313 memset(&(ALBuf->data[size]), 0, padding*NewChannels*sizeof(ALshort));
315 ALBuf->format = NewFormat;
316 ALBuf->eOriginalFormat = format;
317 ALBuf->size = size*sizeof(ALshort);
318 ALBuf->frequency = freq;
319 ALBuf->padding = padding;
321 else
322 alSetError(AL_OUT_OF_MEMORY);
323 } break;
325 case AL_FORMAT_QUAD8_LOKI:
326 case AL_FORMAT_QUAD16_LOKI:
327 case AL_FORMAT_QUAD8:
328 case AL_FORMAT_QUAD16:
329 case AL_FORMAT_QUAD32:
330 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD16);
331 break;
333 case AL_FORMAT_51CHN8:
334 case AL_FORMAT_51CHN16:
335 case AL_FORMAT_51CHN32:
336 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN16);
337 break;
339 case AL_FORMAT_61CHN8:
340 case AL_FORMAT_61CHN16:
341 case AL_FORMAT_61CHN32:
342 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN16);
343 break;
345 case AL_FORMAT_71CHN8:
346 case AL_FORMAT_71CHN16:
347 case AL_FORMAT_71CHN32:
348 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN16);
349 break;
351 case AL_FORMAT_MONO_IMA4:
352 case AL_FORMAT_STEREO_IMA4: {
353 int OrigChans = ((format==AL_FORMAT_MONO_IMA4) ? 1 : 2);
355 // Here is where things vary:
356 // nVidia and Apple use 64+1 samples per channel per block => block_size=36*chans bytes
357 // Most PC sound software uses 2040+1 samples per channel per block -> block_size=1024*chans bytes
358 if((size%(36*OrigChans)) != 0)
360 alSetError(AL_INVALID_VALUE);
361 break;
364 size /= 36;
365 size *= 65;
367 // Allocate extra padding samples
368 temp = realloc(ALBuf->data, (padding*OrigChans + size)*sizeof(ALshort));
369 if(temp)
371 ALBuf->data = temp;
372 ConvertDataIMA4(ALBuf->data, data, OrigChans, size/65);
374 memset(&(ALBuf->data[size]), 0, padding*sizeof(ALshort)*OrigChans);
376 ALBuf->format = ((OrigChans==1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16);
377 ALBuf->eOriginalFormat = format;
378 ALBuf->size = size*sizeof(ALshort);
379 ALBuf->frequency = freq;
380 ALBuf->padding = padding;
382 else
383 alSetError(AL_OUT_OF_MEMORY);
384 } break;
386 default:
387 alSetError(AL_INVALID_ENUM);
388 break;
391 else
393 // Buffer is in use, or data is a NULL pointer
394 alSetError(AL_INVALID_VALUE);
397 else
399 // Invalid Buffer Name
400 alSetError(AL_INVALID_NAME);
403 ProcessContext(Context);
407 * alBufferSubDataEXT(ALuint buffer,ALenum format,ALvoid *data,ALsizei offset,ALsizei length)
409 * Fill buffer with audio data
411 ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length)
413 ALCcontext *Context;
414 ALbuffer *ALBuf;
416 Context = alcGetCurrentContext();
417 SuspendContext(Context);
419 if(alIsBuffer(buffer) && buffer != 0)
421 ALBuf = (ALbuffer*)ALTHUNK_LOOKUPENTRY(buffer);
422 if(ALBuf->data == NULL)
424 // buffer does not have any data
425 alSetError(AL_INVALID_NAME);
427 else if(length < 0 || offset < 0 || (length > 0 && data == NULL))
429 // data is NULL or offset/length is negative
430 alSetError(AL_INVALID_VALUE);
432 else
434 switch(format)
436 case AL_FORMAT_REAR8:
437 case AL_FORMAT_REAR16:
438 case AL_FORMAT_REAR32: {
439 ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
440 ((format==AL_FORMAT_REAR16) ? 2 :
441 4));
443 if(ALBuf->eOriginalFormat != AL_FORMAT_REAR8 &&
444 ALBuf->eOriginalFormat != AL_FORMAT_REAR16 &&
445 ALBuf->eOriginalFormat != AL_FORMAT_REAR32)
447 alSetError(AL_INVALID_ENUM);
448 break;
451 if(ALBuf->size/4/sizeof(ALshort) < (ALuint)offset+length)
453 alSetError(AL_INVALID_VALUE);
454 break;
457 ConvertDataRear(&ALBuf->data[offset*4], data, OrigBytes, length*2);
458 } break;
460 case AL_FORMAT_MONO_IMA4:
461 case AL_FORMAT_STEREO_IMA4: {
462 int Channels = aluChannelsFromFormat(ALBuf->format);
464 if(ALBuf->eOriginalFormat != format)
466 alSetError(AL_INVALID_ENUM);
467 break;
470 if((offset%65) != 0 || (length%65) != 0 ||
471 ALBuf->size/Channels/sizeof(ALshort) < (ALuint)offset+length)
473 alSetError(AL_INVALID_VALUE);
474 break;
477 ConvertDataIMA4(&ALBuf->data[offset*Channels], data, Channels, length/65*Channels);
478 } break;
480 default: {
481 ALuint Channels = aluChannelsFromFormat(format);
482 ALuint Bytes = aluBytesFromFormat(format);
484 if(Channels != aluChannelsFromFormat(ALBuf->format))
486 alSetError(AL_INVALID_ENUM);
487 break;
490 if(ALBuf->size/Channels/sizeof(ALshort) < (ALuint)offset+length)
492 alSetError(AL_INVALID_VALUE);
493 break;
496 ConvertData(&ALBuf->data[offset*Channels], data, Bytes, length*Channels);
497 } break;
501 else
503 // Invalid Buffer Name
504 alSetError(AL_INVALID_NAME);
507 ProcessContext(Context);
511 ALAPI void ALAPIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
513 ALCcontext *pContext;
515 (void)flValue;
517 pContext = alcGetCurrentContext();
518 SuspendContext(pContext);
520 if (alIsBuffer(buffer) && (buffer != 0))
522 switch(eParam)
524 default:
525 alSetError(AL_INVALID_ENUM);
526 break;
529 else
531 alSetError(AL_INVALID_NAME);
534 ProcessContext(pContext);
538 ALAPI void ALAPIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
540 ALCcontext *pContext;
542 (void)flValue1;
543 (void)flValue2;
544 (void)flValue3;
546 pContext = alcGetCurrentContext();
547 SuspendContext(pContext);
549 if (alIsBuffer(buffer) && (buffer != 0))
551 switch(eParam)
553 default:
554 alSetError(AL_INVALID_ENUM);
555 break;
558 else
560 alSetError(AL_INVALID_NAME);
563 ProcessContext(pContext);
567 ALAPI void ALAPIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues)
569 ALCcontext *pContext;
571 (void)flValues;
573 pContext = alcGetCurrentContext();
574 SuspendContext(pContext);
576 if (alIsBuffer(buffer) && (buffer != 0))
578 switch(eParam)
580 default:
581 alSetError(AL_INVALID_ENUM);
582 break;
585 else
587 alSetError(AL_INVALID_NAME);
590 ProcessContext(pContext);
594 ALAPI void ALAPIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
596 ALCcontext *pContext;
598 (void)lValue;
600 pContext = alcGetCurrentContext();
601 SuspendContext(pContext);
603 if (alIsBuffer(buffer) && (buffer != 0))
605 switch(eParam)
607 default:
608 alSetError(AL_INVALID_ENUM);
609 break;
612 else
614 alSetError(AL_INVALID_NAME);
617 ProcessContext(pContext);
621 ALAPI void ALAPIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
623 ALCcontext *pContext;
625 (void)lValue1;
626 (void)lValue2;
627 (void)lValue3;
629 pContext = alcGetCurrentContext();
630 SuspendContext(pContext);
632 if (alIsBuffer(buffer) && (buffer != 0))
634 switch(eParam)
636 default:
637 alSetError(AL_INVALID_ENUM);
638 break;
641 else
643 alSetError(AL_INVALID_NAME);
646 ProcessContext(pContext);
650 ALAPI void ALAPIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues)
652 ALCcontext *pContext;
654 (void)plValues;
656 pContext = alcGetCurrentContext();
657 SuspendContext(pContext);
659 if (alIsBuffer(buffer) && (buffer != 0))
661 switch(eParam)
663 default:
664 alSetError(AL_INVALID_ENUM);
665 break;
668 else
670 alSetError(AL_INVALID_NAME);
673 ProcessContext(pContext);
677 ALAPI ALvoid ALAPIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue)
679 ALCcontext *pContext;
681 pContext = alcGetCurrentContext();
682 SuspendContext(pContext);
684 if (pflValue)
686 if (alIsBuffer(buffer) && (buffer != 0))
688 switch(eParam)
690 default:
691 alSetError(AL_INVALID_ENUM);
692 break;
695 else
697 alSetError(AL_INVALID_NAME);
700 else
702 alSetError(AL_INVALID_VALUE);
705 ProcessContext(pContext);
709 ALAPI void ALAPIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3)
711 ALCcontext *pContext;
713 pContext = alcGetCurrentContext();
714 SuspendContext(pContext);
716 if ((pflValue1) && (pflValue2) && (pflValue3))
718 if (alIsBuffer(buffer) && (buffer != 0))
720 switch(eParam)
722 default:
723 alSetError(AL_INVALID_ENUM);
724 break;
727 else
729 alSetError(AL_INVALID_NAME);
732 else
734 alSetError(AL_INVALID_VALUE);
737 ProcessContext(pContext);
741 ALAPI void ALAPIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues)
743 ALCcontext *pContext;
745 pContext = alcGetCurrentContext();
746 SuspendContext(pContext);
748 if (pflValues)
750 if (alIsBuffer(buffer) && (buffer != 0))
752 switch(eParam)
754 default:
755 alSetError(AL_INVALID_ENUM);
756 break;
759 else
761 alSetError(AL_INVALID_NAME);
764 else
766 alSetError(AL_INVALID_VALUE);
769 ProcessContext(pContext);
773 ALAPI ALvoid ALAPIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue)
775 ALCcontext *pContext;
776 ALbuffer *pBuffer;
778 pContext = alcGetCurrentContext();
779 SuspendContext(pContext);
781 if (plValue)
783 if (alIsBuffer(buffer) && (buffer != 0))
785 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
787 switch (eParam)
789 case AL_FREQUENCY:
790 *plValue = pBuffer->frequency;
791 break;
793 case AL_BITS:
794 *plValue = aluBytesFromFormat(pBuffer->format) * 8;
795 break;
797 case AL_CHANNELS:
798 *plValue = aluChannelsFromFormat(pBuffer->format);
799 break;
801 case AL_SIZE:
802 *plValue = pBuffer->size;
803 break;
805 default:
806 alSetError(AL_INVALID_ENUM);
807 break;
810 else
812 alSetError(AL_INVALID_NAME);
815 else
817 alSetError(AL_INVALID_VALUE);
820 ProcessContext(pContext);
824 ALAPI void ALAPIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3)
826 ALCcontext *pContext;
828 pContext = alcGetCurrentContext();
829 SuspendContext(pContext);
831 if ((plValue1) && (plValue2) && (plValue3))
833 if (alIsBuffer(buffer) && (buffer != 0))
835 switch(eParam)
837 default:
838 alSetError(AL_INVALID_ENUM);
839 break;
842 else
844 alSetError(AL_INVALID_NAME);
847 else
849 alSetError(AL_INVALID_VALUE);
852 ProcessContext(pContext);
856 ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues)
858 ALCcontext *pContext;
860 pContext = alcGetCurrentContext();
861 SuspendContext(pContext);
863 if (plValues)
865 if (alIsBuffer(buffer) && (buffer != 0))
867 switch (eParam)
869 case AL_FREQUENCY:
870 case AL_BITS:
871 case AL_CHANNELS:
872 case AL_SIZE:
873 alGetBufferi(buffer, eParam, plValues);
874 break;
876 default:
877 alSetError(AL_INVALID_ENUM);
878 break;
881 else
883 alSetError(AL_INVALID_NAME);
886 else
888 alSetError(AL_INVALID_VALUE);
891 ProcessContext(pContext);
895 * LoadData
897 * Loads the specified data into the buffer, using the specified formats.
898 * Currently, the new format must be 16-bit, and must have the same channel
899 * configuration as the original format. This does NOT handle compressed
900 * formats (eg. IMA4).
902 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
904 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
905 ALuint OrigBytes = aluBytesFromFormat(OrigFormat);
906 ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
907 ALsizei padding = 2;
908 ALvoid *temp;
910 assert(aluBytesFromFormat(NewFormat) == 2);
911 assert(NewChannels == OrigChannels);
913 if ((size%(OrigBytes*OrigChannels)) != 0)
915 alSetError(AL_INVALID_VALUE);
916 return;
919 // Samples are converted to 16 bit here
920 size /= OrigBytes;
921 temp = realloc(ALBuf->data, (padding*NewChannels + size) * sizeof(ALshort));
922 if(temp)
924 ALBuf->data = temp;
925 ConvertData(ALBuf->data, data, OrigBytes, size);
927 memset(&(ALBuf->data[size]), 0, padding*NewChannels*sizeof(ALshort));
929 ALBuf->format = NewFormat;
930 ALBuf->eOriginalFormat = OrigFormat;
931 ALBuf->size = size*sizeof(ALshort);
932 ALBuf->frequency = freq;
933 ALBuf->padding = padding;
935 else
936 alSetError(AL_OUT_OF_MEMORY);
939 static void ConvertData(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len)
941 ALsizei i;
942 switch(origBytes)
944 case 1:
945 for(i = 0;i < len;i++)
946 dst[i] = ((ALshort)((ALubyte*)src)[i] - 128) << 8;
947 break;
949 case 2:
950 memcpy(dst, src, len*sizeof(ALshort));
951 break;
953 case 4:
954 for(i = 0;i < len;i++)
956 ALint smp;
957 smp = (((ALfloat*)src)[i] * 32767.5f - 0.5f);
958 smp = min(smp, 32767);
959 smp = max(smp, -32768);
960 dst[i] = (ALshort)smp;
962 break;
964 default:
965 assert(0);
969 static void ConvertDataRear(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len)
971 ALsizei i;
972 switch(origBytes)
974 case 1:
975 for(i = 0;i < len;i+=4)
977 dst[i+0] = 0;
978 dst[i+1] = 0;
979 dst[i+2] = ((ALshort)((ALubyte*)src)[i/2+0] - 128) << 8;
980 dst[i+3] = ((ALshort)((ALubyte*)src)[i/2+1] - 128) << 8;
982 break;
984 case 2:
985 for(i = 0;i < len;i+=4)
987 dst[i+0] = 0;
988 dst[i+1] = 0;
989 dst[i+2] = ((ALshort*)src)[i/2+0];
990 dst[i+3] = ((ALshort*)src)[i/2+1];
992 break;
994 case 4:
995 for(i = 0;i < len;i+=4)
997 ALint smp;
998 dst[i+0] = 0;
999 dst[i+1] = 0;
1000 smp = (((ALfloat*)src)[i/2+0] * 32767.5f - 0.5);
1001 smp = min(smp, 32767);
1002 smp = max(smp, -32768);
1003 dst[i+2] = (ALshort)smp;
1004 smp = (((ALfloat*)src)[i/2+1] * 32767.5f - 0.5);
1005 smp = min(smp, 32767);
1006 smp = max(smp, -32768);
1007 dst[i+3] = (ALshort)smp;
1009 break;
1011 default:
1012 assert(0);
1016 static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, ALsizei len)
1018 const ALuint *IMAData;
1019 ALint Sample[2],Index[2];
1020 ALuint IMACode[2];
1021 ALsizei i,j,k,c;
1023 assert(origChans <= 2);
1025 IMAData = src;
1026 for(i = 0;i < len/origChans;i++)
1028 for(c = 0;c < origChans;c++)
1030 Sample[c] = ((ALshort*)IMAData)[0];
1031 Index[c] = ((ALshort*)IMAData)[1];
1033 Index[c] = ((Index[c]<0) ? 0 : Index[c]);
1034 Index[c] = ((Index[c]>88) ? 88 : Index[c]);
1036 dst[i*65*origChans + c] = (ALshort)Sample[c];
1038 IMAData++;
1041 for(j = 1;j < 65;j += 8)
1043 for(c = 0;c < origChans;c++)
1044 IMACode[c] = *(IMAData++);
1046 for(k = 0;k < 8;k++)
1048 for(c = 0;c < origChans;c++)
1050 Sample[c] += ((g_IMAStep_size[Index[c]]*g_IMACodeword_4[IMACode[c]&15])/8);
1051 Index[c] += g_IMAIndex_adjust_4[IMACode[c]&15];
1053 if(Sample[c] < -32768) Sample[c] = -32768;
1054 else if(Sample[c] > 32767) Sample[c] = 32767;
1056 if(Index[c]<0) Index[c] = 0;
1057 else if(Index[c]>88) Index[c] = 88;
1059 dst[(i*65+j+k)*origChans + c] = (ALshort)Sample[c];
1060 IMACode[c] >>= 4;
1068 * ReleaseALBuffers()
1070 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
1072 ALvoid ReleaseALBuffers(ALvoid)
1074 ALbuffer *ALBuffer;
1075 ALbuffer *ALBufferTemp;
1077 #ifdef _DEBUG
1078 if(g_uiBufferCount > 0)
1079 AL_PRINT("exit(): deleting %d Buffer(s)\n", g_uiBufferCount);
1080 #endif
1082 ALBuffer = g_pBuffers;
1083 while(ALBuffer)
1085 // Release sample data
1086 free(ALBuffer->data);
1088 // Release Buffer structure
1089 ALBufferTemp = ALBuffer;
1090 ALBuffer = ALBuffer->next;
1091 memset(ALBufferTemp, 0, sizeof(ALbuffer));
1092 free(ALBufferTemp);
1094 g_pBuffers = NULL;
1095 g_uiBufferCount = 0;