ALCAPIENTRY is deprecated in favor of ALC_APIENTRY
[openal-soft.git] / OpenAL32 / alBuffer.c
blob66d6cee4bcf8543bc831ebb47195c230618c2b24
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 "alDatabuffer.h"
32 #include "alThunk.h"
35 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat);
36 static void ConvertData(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len);
37 static void ConvertDataRear(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len);
38 static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, ALsizei len);
41 * AL Buffer Functions
43 * AL Buffers are shared amoung Contexts, so we store the list of generated Buffers
44 * as a global variable in this module. (A valid context is not required to make
45 * AL Buffer function calls
50 * Global Variables
53 static const long g_IMAStep_size[89]={ // IMA ADPCM Stepsize table
54 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
55 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
56 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
57 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
58 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493,10442,11487,12635,13899,
59 15289,16818,18500,20350,22358,24633,27086,29794,32767
62 static const long g_IMACodeword_4[16]={ // IMA4 ADPCM Codeword decode table
63 1, 3, 5, 7, 9, 11, 13, 15,
64 -1,-3,-5,-7,-9,-11,-13,-15,
67 static const long g_IMAIndex_adjust_4[16]={ // IMA4 ADPCM Step index adjust decode table
68 -1,-1,-1,-1, 2, 4, 6, 8,
69 -1,-1,-1,-1, 2, 4, 6, 8
73 * alGenBuffers(ALsizei n, ALuint *puiBuffers)
75 * Generates n AL Buffers, and stores the Buffers Names in the array pointed to by puiBuffers
77 ALAPI ALvoid ALAPIENTRY alGenBuffers(ALsizei n,ALuint *puiBuffers)
79 ALCcontext *Context;
80 ALsizei i=0;
82 Context = GetContextSuspended();
83 if(!Context) return;
85 // Check that we are actually generation some Buffers
86 if (n > 0)
88 ALCdevice *device = Context->Device;
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 = &device->Buffers;
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)->buffer = puiBuffers[i];
111 device->BufferCount++;
112 i++;
114 list = &(*list)->next;
117 else
119 // Pointer does not point to enough memory to write Buffer names
120 alSetError(AL_INVALID_VALUE);
124 ProcessContext(Context);
126 return;
130 * alDeleteBuffers(ALsizei n, ALuint *puiBuffers)
132 * Deletes the n AL Buffers pointed to by puiBuffers
134 ALAPI ALvoid ALAPIENTRY alDeleteBuffers(ALsizei n, const ALuint *puiBuffers)
136 ALCcontext *Context;
137 ALbuffer *ALBuf;
138 ALsizei i;
139 ALboolean bFailed = AL_FALSE;
141 Context = GetContextSuspended();
142 if(!Context) return;
144 // Check we are actually Deleting some Buffers
145 if (n >= 0)
147 ALCdevice *device = Context->Device;
149 // Check that all the buffers are valid and can actually be deleted
150 for (i = 0; i < n; i++)
152 // Check for valid Buffer ID (can be NULL buffer)
153 if (alIsBuffer(puiBuffers[i]))
155 // If not the NULL buffer, check that the reference count is 0
156 ALBuf = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
157 if (ALBuf)
159 if (ALBuf->refcount != 0)
161 // Buffer still in use, cannot be deleted
162 alSetError(AL_INVALID_OPERATION);
163 bFailed = AL_TRUE;
167 else
169 // Invalid Buffer
170 alSetError(AL_INVALID_NAME);
171 bFailed = AL_TRUE;
175 // If all the Buffers were valid (and have Reference Counts of 0), then we can delete them
176 if (!bFailed)
178 for (i = 0; i < n; i++)
180 if (puiBuffers[i] && alIsBuffer(puiBuffers[i]))
182 ALbuffer **list = &device->Buffers;
184 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
185 while(*list && *list != ALBuf)
186 list = &(*list)->next;
188 if(*list)
189 *list = (*list)->next;
191 // Release the memory used to store audio data
192 free(ALBuf->data);
194 // Release buffer structure
195 ALTHUNK_REMOVEENTRY(puiBuffers[i]);
196 memset(ALBuf, 0, sizeof(ALbuffer));
197 device->BufferCount--;
198 free(ALBuf);
203 else
204 alSetError(AL_INVALID_VALUE);
206 ProcessContext(Context);
208 return;
213 * alIsBuffer(ALuint uiBuffer)
215 * Checks if ulBuffer is a valid Buffer Name
217 ALAPI ALboolean ALAPIENTRY alIsBuffer(ALuint uiBuffer)
219 ALCcontext *Context;
220 ALboolean result=AL_FALSE;
221 ALbuffer *ALBuf;
222 ALbuffer *TgtALBuf;
224 Context = GetContextSuspended();
225 if(!Context) return AL_FALSE;
227 if (uiBuffer)
229 ALCdevice *device = Context->Device;
231 TgtALBuf = (ALbuffer *)ALTHUNK_LOOKUPENTRY(uiBuffer);
233 // Check through list of generated buffers for uiBuffer
234 ALBuf = device->Buffers;
235 while (ALBuf)
237 if (ALBuf == TgtALBuf)
239 result = AL_TRUE;
240 break;
243 ALBuf = ALBuf->next;
246 else
248 result = AL_TRUE;
252 ProcessContext(Context);
254 return result;
258 * alBufferData(ALuint buffer,ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
260 * Fill buffer with audio data
262 ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq)
264 ALCcontext *Context;
265 ALbuffer *ALBuf;
266 ALvoid *temp;
268 Context = GetContextSuspended();
269 if(!Context) return;
271 if (alIsBuffer(buffer) && (buffer != 0))
273 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
275 if(Context->SampleSource)
277 ALuint offset;
279 if(Context->SampleSource->state == MAPPED)
281 alSetError(AL_INVALID_OPERATION);
282 ProcessContext(Context);
283 return;
286 offset = (ALuint)data;
287 data = Context->SampleSource->data + offset;
290 if ((ALBuf->refcount==0)&&(data))
292 switch(format)
294 case AL_FORMAT_MONO8:
295 case AL_FORMAT_MONO16:
296 case AL_FORMAT_MONO_FLOAT32:
297 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO16);
298 break;
300 case AL_FORMAT_STEREO8:
301 case AL_FORMAT_STEREO16:
302 case AL_FORMAT_STEREO_FLOAT32:
303 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO16);
304 break;
306 case AL_FORMAT_REAR8:
307 case AL_FORMAT_REAR16:
308 case AL_FORMAT_REAR32: {
309 ALuint NewFormat = AL_FORMAT_QUAD16;
310 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
311 ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
312 ((format==AL_FORMAT_REAR16) ? 2 :
313 4));
315 assert(aluBytesFromFormat(NewFormat) == 2);
317 if((size%(OrigBytes*2)) != 0)
319 alSetError(AL_INVALID_VALUE);
320 break;
323 size /= OrigBytes;
324 size *= 2;
326 // Samples are converted to 16 bit here
327 temp = realloc(ALBuf->data, (BUFFER_PADDING*NewChannels + size) * sizeof(ALshort));
328 if(temp)
330 ALBuf->data = temp;
331 ConvertDataRear(ALBuf->data, data, OrigBytes, size);
333 memset(&(ALBuf->data[size]), 0, BUFFER_PADDING*NewChannels*sizeof(ALshort));
335 ALBuf->format = NewFormat;
336 ALBuf->eOriginalFormat = format;
337 ALBuf->size = size*sizeof(ALshort);
338 ALBuf->frequency = freq;
340 else
341 alSetError(AL_OUT_OF_MEMORY);
342 } break;
344 case AL_FORMAT_QUAD8_LOKI:
345 case AL_FORMAT_QUAD16_LOKI:
346 case AL_FORMAT_QUAD8:
347 case AL_FORMAT_QUAD16:
348 case AL_FORMAT_QUAD32:
349 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD16);
350 break;
352 case AL_FORMAT_51CHN8:
353 case AL_FORMAT_51CHN16:
354 case AL_FORMAT_51CHN32:
355 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN16);
356 break;
358 case AL_FORMAT_61CHN8:
359 case AL_FORMAT_61CHN16:
360 case AL_FORMAT_61CHN32:
361 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN16);
362 break;
364 case AL_FORMAT_71CHN8:
365 case AL_FORMAT_71CHN16:
366 case AL_FORMAT_71CHN32:
367 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN16);
368 break;
370 case AL_FORMAT_MONO_IMA4:
371 case AL_FORMAT_STEREO_IMA4: {
372 int OrigChans = ((format==AL_FORMAT_MONO_IMA4) ? 1 : 2);
374 // Here is where things vary:
375 // nVidia and Apple use 64+1 samples per channel per block => block_size=36*chans bytes
376 // Most PC sound software uses 2040+1 samples per channel per block -> block_size=1024*chans bytes
377 if((size%(36*OrigChans)) != 0)
379 alSetError(AL_INVALID_VALUE);
380 break;
383 size /= 36;
384 size *= 65;
386 // Allocate extra padding samples
387 temp = realloc(ALBuf->data, (BUFFER_PADDING*OrigChans + size)*sizeof(ALshort));
388 if(temp)
390 ALBuf->data = temp;
391 ConvertDataIMA4(ALBuf->data, data, OrigChans, size/65);
393 memset(&(ALBuf->data[size]), 0, BUFFER_PADDING*sizeof(ALshort)*OrigChans);
395 ALBuf->format = ((OrigChans==1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16);
396 ALBuf->eOriginalFormat = format;
397 ALBuf->size = size*sizeof(ALshort);
398 ALBuf->frequency = freq;
400 else
401 alSetError(AL_OUT_OF_MEMORY);
402 } break;
404 default:
405 alSetError(AL_INVALID_ENUM);
406 break;
409 else
411 // Buffer is in use, or data is a NULL pointer
412 alSetError(AL_INVALID_VALUE);
415 else
417 // Invalid Buffer Name
418 alSetError(AL_INVALID_NAME);
421 ProcessContext(Context);
425 * alBufferSubDataEXT(ALuint buffer,ALenum format,ALvoid *data,ALsizei offset,ALsizei length)
427 * Fill buffer with audio data
429 ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length)
431 ALCcontext *Context;
432 ALbuffer *ALBuf;
434 Context = GetContextSuspended();
435 if(!Context) return;
437 if(alIsBuffer(buffer) && buffer != 0)
439 ALBuf = (ALbuffer*)ALTHUNK_LOOKUPENTRY(buffer);
441 if(Context->SampleSource)
443 ALuint offset;
445 if(Context->SampleSource->state == MAPPED)
447 alSetError(AL_INVALID_OPERATION);
448 ProcessContext(Context);
449 return;
452 offset = (ALuint)data;
453 data = Context->SampleSource->data + offset;
456 if(ALBuf->data == NULL)
458 // buffer does not have any data
459 alSetError(AL_INVALID_NAME);
461 else if(length < 0 || offset < 0 || (length > 0 && data == NULL))
463 // data is NULL or offset/length is negative
464 alSetError(AL_INVALID_VALUE);
466 else
468 switch(format)
470 case AL_FORMAT_REAR8:
471 case AL_FORMAT_REAR16:
472 case AL_FORMAT_REAR32: {
473 ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
474 ((format==AL_FORMAT_REAR16) ? 2 :
475 4));
477 if(ALBuf->eOriginalFormat != AL_FORMAT_REAR8 &&
478 ALBuf->eOriginalFormat != AL_FORMAT_REAR16 &&
479 ALBuf->eOriginalFormat != AL_FORMAT_REAR32)
481 alSetError(AL_INVALID_ENUM);
482 break;
485 if(ALBuf->size/4/sizeof(ALshort) < (ALuint)offset+length)
487 alSetError(AL_INVALID_VALUE);
488 break;
491 ConvertDataRear(&ALBuf->data[offset*4], data, OrigBytes, length*2);
492 } break;
494 case AL_FORMAT_MONO_IMA4:
495 case AL_FORMAT_STEREO_IMA4: {
496 int Channels = aluChannelsFromFormat(ALBuf->format);
498 if(ALBuf->eOriginalFormat != format)
500 alSetError(AL_INVALID_ENUM);
501 break;
504 if((offset%65) != 0 || (length%65) != 0 ||
505 ALBuf->size/Channels/sizeof(ALshort) < (ALuint)offset+length)
507 alSetError(AL_INVALID_VALUE);
508 break;
511 ConvertDataIMA4(&ALBuf->data[offset*Channels], data, Channels, length/65*Channels);
512 } break;
514 default: {
515 ALuint Channels = aluChannelsFromFormat(format);
516 ALuint Bytes = aluBytesFromFormat(format);
518 if(Channels != aluChannelsFromFormat(ALBuf->format))
520 alSetError(AL_INVALID_ENUM);
521 break;
524 if(ALBuf->size/Channels/sizeof(ALshort) < (ALuint)offset+length)
526 alSetError(AL_INVALID_VALUE);
527 break;
530 ConvertData(&ALBuf->data[offset*Channels], data, Bytes, length*Channels);
531 } break;
535 else
537 // Invalid Buffer Name
538 alSetError(AL_INVALID_NAME);
541 ProcessContext(Context);
545 ALAPI void ALAPIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
547 ALCcontext *pContext;
549 (void)flValue;
551 pContext = GetContextSuspended();
552 if(!pContext) return;
554 if (alIsBuffer(buffer) && (buffer != 0))
556 switch(eParam)
558 default:
559 alSetError(AL_INVALID_ENUM);
560 break;
563 else
565 alSetError(AL_INVALID_NAME);
568 ProcessContext(pContext);
572 ALAPI void ALAPIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
574 ALCcontext *pContext;
576 (void)flValue1;
577 (void)flValue2;
578 (void)flValue3;
580 pContext = GetContextSuspended();
581 if(!pContext) return;
583 if (alIsBuffer(buffer) && (buffer != 0))
585 switch(eParam)
587 default:
588 alSetError(AL_INVALID_ENUM);
589 break;
592 else
594 alSetError(AL_INVALID_NAME);
597 ProcessContext(pContext);
601 ALAPI void ALAPIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues)
603 ALCcontext *pContext;
605 (void)flValues;
607 pContext = GetContextSuspended();
608 if(!pContext) return;
610 if (alIsBuffer(buffer) && (buffer != 0))
612 switch(eParam)
614 default:
615 alSetError(AL_INVALID_ENUM);
616 break;
619 else
621 alSetError(AL_INVALID_NAME);
624 ProcessContext(pContext);
628 ALAPI void ALAPIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
630 ALCcontext *pContext;
632 (void)lValue;
634 pContext = GetContextSuspended();
635 if(!pContext) return;
637 if (alIsBuffer(buffer) && (buffer != 0))
639 switch(eParam)
641 default:
642 alSetError(AL_INVALID_ENUM);
643 break;
646 else
648 alSetError(AL_INVALID_NAME);
651 ProcessContext(pContext);
655 ALAPI void ALAPIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
657 ALCcontext *pContext;
659 (void)lValue1;
660 (void)lValue2;
661 (void)lValue3;
663 pContext = GetContextSuspended();
664 if(!pContext) return;
666 if (alIsBuffer(buffer) && (buffer != 0))
668 switch(eParam)
670 default:
671 alSetError(AL_INVALID_ENUM);
672 break;
675 else
677 alSetError(AL_INVALID_NAME);
680 ProcessContext(pContext);
684 ALAPI void ALAPIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues)
686 ALCcontext *pContext;
688 (void)plValues;
690 pContext = GetContextSuspended();
691 if(!pContext) return;
693 if (alIsBuffer(buffer) && (buffer != 0))
695 switch(eParam)
697 default:
698 alSetError(AL_INVALID_ENUM);
699 break;
702 else
704 alSetError(AL_INVALID_NAME);
707 ProcessContext(pContext);
711 ALAPI ALvoid ALAPIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue)
713 ALCcontext *pContext;
715 pContext = GetContextSuspended();
716 if(!pContext) return;
718 if (pflValue)
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 alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3)
745 ALCcontext *pContext;
747 pContext = GetContextSuspended();
748 if(!pContext) return;
750 if ((pflValue1) && (pflValue2) && (pflValue3))
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 void ALAPIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues)
777 ALCcontext *pContext;
779 pContext = GetContextSuspended();
780 if(!pContext) return;
782 if (pflValues)
784 if (alIsBuffer(buffer) && (buffer != 0))
786 switch(eParam)
788 default:
789 alSetError(AL_INVALID_ENUM);
790 break;
793 else
795 alSetError(AL_INVALID_NAME);
798 else
800 alSetError(AL_INVALID_VALUE);
803 ProcessContext(pContext);
807 ALAPI ALvoid ALAPIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue)
809 ALCcontext *pContext;
810 ALbuffer *pBuffer;
812 pContext = GetContextSuspended();
813 if(!pContext) return;
815 if (plValue)
817 if (alIsBuffer(buffer) && (buffer != 0))
819 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
821 switch (eParam)
823 case AL_FREQUENCY:
824 *plValue = pBuffer->frequency;
825 break;
827 case AL_BITS:
828 *plValue = aluBytesFromFormat(pBuffer->format) * 8;
829 break;
831 case AL_CHANNELS:
832 *plValue = aluChannelsFromFormat(pBuffer->format);
833 break;
835 case AL_SIZE:
836 *plValue = pBuffer->size;
837 break;
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 alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3)
860 ALCcontext *pContext;
862 pContext = GetContextSuspended();
863 if(!pContext) return;
865 if ((plValue1) && (plValue2) && (plValue3))
867 if (alIsBuffer(buffer) && (buffer != 0))
869 switch(eParam)
871 default:
872 alSetError(AL_INVALID_ENUM);
873 break;
876 else
878 alSetError(AL_INVALID_NAME);
881 else
883 alSetError(AL_INVALID_VALUE);
886 ProcessContext(pContext);
890 ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues)
892 ALCcontext *pContext;
894 pContext = GetContextSuspended();
895 if(!pContext) return;
897 if (plValues)
899 if (alIsBuffer(buffer) && (buffer != 0))
901 switch (eParam)
903 case AL_FREQUENCY:
904 case AL_BITS:
905 case AL_CHANNELS:
906 case AL_SIZE:
907 alGetBufferi(buffer, eParam, plValues);
908 break;
910 default:
911 alSetError(AL_INVALID_ENUM);
912 break;
915 else
917 alSetError(AL_INVALID_NAME);
920 else
922 alSetError(AL_INVALID_VALUE);
925 ProcessContext(pContext);
929 * LoadData
931 * Loads the specified data into the buffer, using the specified formats.
932 * Currently, the new format must be 16-bit, and must have the same channel
933 * configuration as the original format. This does NOT handle compressed
934 * formats (eg. IMA4).
936 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
938 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
939 ALuint OrigBytes = aluBytesFromFormat(OrigFormat);
940 ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
941 ALvoid *temp;
943 assert(aluBytesFromFormat(NewFormat) == 2);
944 assert(NewChannels == OrigChannels);
946 if ((size%(OrigBytes*OrigChannels)) != 0)
948 alSetError(AL_INVALID_VALUE);
949 return;
952 // Samples are converted to 16 bit here
953 size /= OrigBytes;
954 temp = realloc(ALBuf->data, (BUFFER_PADDING*NewChannels + size) * sizeof(ALshort));
955 if(temp)
957 ALBuf->data = temp;
958 ConvertData(ALBuf->data, data, OrigBytes, size);
960 memset(&(ALBuf->data[size]), 0, BUFFER_PADDING*NewChannels*sizeof(ALshort));
962 ALBuf->format = NewFormat;
963 ALBuf->eOriginalFormat = OrigFormat;
964 ALBuf->size = size*sizeof(ALshort);
965 ALBuf->frequency = freq;
967 else
968 alSetError(AL_OUT_OF_MEMORY);
971 static void ConvertData(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++)
978 dst[i] = ((ALshort)((ALubyte*)src)[i] - 128) << 8;
979 break;
981 case 2:
982 memcpy(dst, src, len*sizeof(ALshort));
983 break;
985 case 4:
986 for(i = 0;i < len;i++)
988 ALint smp;
989 smp = (((ALfloat*)src)[i] * 32767.5f - 0.5f);
990 smp = min(smp, 32767);
991 smp = max(smp, -32768);
992 dst[i] = (ALshort)smp;
994 break;
996 default:
997 assert(0);
1001 static void ConvertDataRear(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len)
1003 ALsizei i;
1004 switch(origBytes)
1006 case 1:
1007 for(i = 0;i < len;i+=4)
1009 dst[i+0] = 0;
1010 dst[i+1] = 0;
1011 dst[i+2] = ((ALshort)((ALubyte*)src)[i/2+0] - 128) << 8;
1012 dst[i+3] = ((ALshort)((ALubyte*)src)[i/2+1] - 128) << 8;
1014 break;
1016 case 2:
1017 for(i = 0;i < len;i+=4)
1019 dst[i+0] = 0;
1020 dst[i+1] = 0;
1021 dst[i+2] = ((ALshort*)src)[i/2+0];
1022 dst[i+3] = ((ALshort*)src)[i/2+1];
1024 break;
1026 case 4:
1027 for(i = 0;i < len;i+=4)
1029 ALint smp;
1030 dst[i+0] = 0;
1031 dst[i+1] = 0;
1032 smp = (((ALfloat*)src)[i/2+0] * 32767.5f - 0.5);
1033 smp = min(smp, 32767);
1034 smp = max(smp, -32768);
1035 dst[i+2] = (ALshort)smp;
1036 smp = (((ALfloat*)src)[i/2+1] * 32767.5f - 0.5);
1037 smp = min(smp, 32767);
1038 smp = max(smp, -32768);
1039 dst[i+3] = (ALshort)smp;
1041 break;
1043 default:
1044 assert(0);
1048 static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, ALsizei len)
1050 const ALuint *IMAData;
1051 ALint Sample[2],Index[2];
1052 ALuint IMACode[2];
1053 ALsizei i,j,k,c;
1055 assert(origChans <= 2);
1057 IMAData = src;
1058 for(i = 0;i < len/origChans;i++)
1060 for(c = 0;c < origChans;c++)
1062 Sample[c] = ((ALshort*)IMAData)[0];
1063 Index[c] = ((ALshort*)IMAData)[1];
1065 Index[c] = ((Index[c]<0) ? 0 : Index[c]);
1066 Index[c] = ((Index[c]>88) ? 88 : Index[c]);
1068 dst[i*65*origChans + c] = (ALshort)Sample[c];
1070 IMAData++;
1073 for(j = 1;j < 65;j += 8)
1075 for(c = 0;c < origChans;c++)
1076 IMACode[c] = *(IMAData++);
1078 for(k = 0;k < 8;k++)
1080 for(c = 0;c < origChans;c++)
1082 Sample[c] += ((g_IMAStep_size[Index[c]]*g_IMACodeword_4[IMACode[c]&15])/8);
1083 Index[c] += g_IMAIndex_adjust_4[IMACode[c]&15];
1085 if(Sample[c] < -32768) Sample[c] = -32768;
1086 else if(Sample[c] > 32767) Sample[c] = 32767;
1088 if(Index[c]<0) Index[c] = 0;
1089 else if(Index[c]>88) Index[c] = 88;
1091 dst[(i*65+j+k)*origChans + c] = (ALshort)Sample[c];
1092 IMACode[c] >>= 4;
1100 * ReleaseALBuffers()
1102 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
1104 ALvoid ReleaseALBuffers(ALCdevice *device)
1106 ALbuffer *ALBuffer;
1107 ALbuffer *ALBufferTemp;
1109 ALBuffer = device->Buffers;
1110 while(ALBuffer)
1112 // Release sample data
1113 free(ALBuffer->data);
1115 // Release Buffer structure
1116 ALBufferTemp = ALBuffer;
1117 ALBuffer = ALBuffer->next;
1118 memset(ALBufferTemp, 0, sizeof(ALbuffer));
1119 free(ALBufferTemp);
1121 device->Buffers = NULL;
1122 device->BufferCount = 0;