Remove unnecessary returns
[openal-soft/openal-hmr.git] / OpenAL32 / alBuffer.c
blob5b541c7bc95562067699b2366e8bdba54f067e0e
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);
128 * alDeleteBuffers(ALsizei n, ALuint *puiBuffers)
130 * Deletes the n AL Buffers pointed to by puiBuffers
132 ALAPI ALvoid ALAPIENTRY alDeleteBuffers(ALsizei n, const ALuint *puiBuffers)
134 ALCcontext *Context;
135 ALbuffer *ALBuf;
136 ALsizei i;
137 ALboolean bFailed = AL_FALSE;
139 Context = GetContextSuspended();
140 if(!Context) return;
142 // Check we are actually Deleting some Buffers
143 if (n >= 0)
145 ALCdevice *device = Context->Device;
147 // Check that all the buffers are valid and can actually be deleted
148 for (i = 0; i < n; i++)
150 // Check for valid Buffer ID (can be NULL buffer)
151 if (alIsBuffer(puiBuffers[i]))
153 // If not the NULL buffer, check that the reference count is 0
154 ALBuf = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
155 if (ALBuf)
157 if (ALBuf->refcount != 0)
159 // Buffer still in use, cannot be deleted
160 alSetError(AL_INVALID_OPERATION);
161 bFailed = AL_TRUE;
165 else
167 // Invalid Buffer
168 alSetError(AL_INVALID_NAME);
169 bFailed = AL_TRUE;
173 // If all the Buffers were valid (and have Reference Counts of 0), then we can delete them
174 if (!bFailed)
176 for (i = 0; i < n; i++)
178 if (puiBuffers[i] && alIsBuffer(puiBuffers[i]))
180 ALbuffer **list = &device->Buffers;
182 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
183 while(*list && *list != ALBuf)
184 list = &(*list)->next;
186 if(*list)
187 *list = (*list)->next;
189 // Release the memory used to store audio data
190 free(ALBuf->data);
192 // Release buffer structure
193 ALTHUNK_REMOVEENTRY(puiBuffers[i]);
194 memset(ALBuf, 0, sizeof(ALbuffer));
195 device->BufferCount--;
196 free(ALBuf);
201 else
202 alSetError(AL_INVALID_VALUE);
204 ProcessContext(Context);
208 * alIsBuffer(ALuint uiBuffer)
210 * Checks if ulBuffer is a valid Buffer Name
212 ALAPI ALboolean ALAPIENTRY alIsBuffer(ALuint uiBuffer)
214 ALCcontext *Context;
215 ALboolean result=AL_FALSE;
216 ALbuffer *ALBuf;
217 ALbuffer *TgtALBuf;
219 Context = GetContextSuspended();
220 if(!Context) return AL_FALSE;
222 if (uiBuffer)
224 ALCdevice *device = Context->Device;
226 TgtALBuf = (ALbuffer *)ALTHUNK_LOOKUPENTRY(uiBuffer);
228 // Check through list of generated buffers for uiBuffer
229 ALBuf = device->Buffers;
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 ALbuffer *ALBuf;
261 ALvoid *temp;
263 Context = GetContextSuspended();
264 if(!Context) return;
266 if (alIsBuffer(buffer) && (buffer != 0))
268 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
270 if(Context->SampleSource)
272 ALuint offset;
274 if(Context->SampleSource->state == MAPPED)
276 alSetError(AL_INVALID_OPERATION);
277 ProcessContext(Context);
278 return;
281 offset = (ALuint)data;
282 data = Context->SampleSource->data + offset;
285 if ((ALBuf->refcount==0)&&(data))
287 switch(format)
289 case AL_FORMAT_MONO8:
290 case AL_FORMAT_MONO16:
291 case AL_FORMAT_MONO_FLOAT32:
292 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO16);
293 break;
295 case AL_FORMAT_STEREO8:
296 case AL_FORMAT_STEREO16:
297 case AL_FORMAT_STEREO_FLOAT32:
298 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO16);
299 break;
301 case AL_FORMAT_REAR8:
302 case AL_FORMAT_REAR16:
303 case AL_FORMAT_REAR32: {
304 ALuint NewFormat = AL_FORMAT_QUAD16;
305 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
306 ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
307 ((format==AL_FORMAT_REAR16) ? 2 :
308 4));
310 assert(aluBytesFromFormat(NewFormat) == 2);
312 if((size%(OrigBytes*2)) != 0)
314 alSetError(AL_INVALID_VALUE);
315 break;
318 size /= OrigBytes;
319 size *= 2;
321 // Samples are converted to 16 bit here
322 temp = realloc(ALBuf->data, (BUFFER_PADDING*NewChannels + size) * sizeof(ALshort));
323 if(temp)
325 ALBuf->data = temp;
326 ConvertDataRear(ALBuf->data, data, OrigBytes, size);
328 memset(&(ALBuf->data[size]), 0, BUFFER_PADDING*NewChannels*sizeof(ALshort));
330 ALBuf->format = NewFormat;
331 ALBuf->eOriginalFormat = format;
332 ALBuf->size = size*sizeof(ALshort);
333 ALBuf->frequency = freq;
335 else
336 alSetError(AL_OUT_OF_MEMORY);
337 } break;
339 case AL_FORMAT_QUAD8_LOKI:
340 case AL_FORMAT_QUAD16_LOKI:
341 case AL_FORMAT_QUAD8:
342 case AL_FORMAT_QUAD16:
343 case AL_FORMAT_QUAD32:
344 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD16);
345 break;
347 case AL_FORMAT_51CHN8:
348 case AL_FORMAT_51CHN16:
349 case AL_FORMAT_51CHN32:
350 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN16);
351 break;
353 case AL_FORMAT_61CHN8:
354 case AL_FORMAT_61CHN16:
355 case AL_FORMAT_61CHN32:
356 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN16);
357 break;
359 case AL_FORMAT_71CHN8:
360 case AL_FORMAT_71CHN16:
361 case AL_FORMAT_71CHN32:
362 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN16);
363 break;
365 case AL_FORMAT_MONO_IMA4:
366 case AL_FORMAT_STEREO_IMA4: {
367 int OrigChans = ((format==AL_FORMAT_MONO_IMA4) ? 1 : 2);
369 // Here is where things vary:
370 // nVidia and Apple use 64+1 samples per channel per block => block_size=36*chans bytes
371 // Most PC sound software uses 2040+1 samples per channel per block -> block_size=1024*chans bytes
372 if((size%(36*OrigChans)) != 0)
374 alSetError(AL_INVALID_VALUE);
375 break;
378 size /= 36;
379 size *= 65;
381 // Allocate extra padding samples
382 temp = realloc(ALBuf->data, (BUFFER_PADDING*OrigChans + size)*sizeof(ALshort));
383 if(temp)
385 ALBuf->data = temp;
386 ConvertDataIMA4(ALBuf->data, data, OrigChans, size/65);
388 memset(&(ALBuf->data[size]), 0, BUFFER_PADDING*sizeof(ALshort)*OrigChans);
390 ALBuf->format = ((OrigChans==1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16);
391 ALBuf->eOriginalFormat = format;
392 ALBuf->size = size*sizeof(ALshort);
393 ALBuf->frequency = freq;
395 else
396 alSetError(AL_OUT_OF_MEMORY);
397 } break;
399 default:
400 alSetError(AL_INVALID_ENUM);
401 break;
404 else
406 // Buffer is in use, or data is a NULL pointer
407 alSetError(AL_INVALID_VALUE);
410 else
412 // Invalid Buffer Name
413 alSetError(AL_INVALID_NAME);
416 ProcessContext(Context);
420 * alBufferSubDataEXT(ALuint buffer,ALenum format,ALvoid *data,ALsizei offset,ALsizei length)
422 * Fill buffer with audio data
424 ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length)
426 ALCcontext *Context;
427 ALbuffer *ALBuf;
429 Context = GetContextSuspended();
430 if(!Context) return;
432 if(alIsBuffer(buffer) && buffer != 0)
434 ALBuf = (ALbuffer*)ALTHUNK_LOOKUPENTRY(buffer);
436 if(Context->SampleSource)
438 ALuint offset;
440 if(Context->SampleSource->state == MAPPED)
442 alSetError(AL_INVALID_OPERATION);
443 ProcessContext(Context);
444 return;
447 offset = (ALuint)data;
448 data = Context->SampleSource->data + offset;
451 if(ALBuf->data == NULL)
453 // buffer does not have any data
454 alSetError(AL_INVALID_NAME);
456 else if(length < 0 || offset < 0 || (length > 0 && data == NULL))
458 // data is NULL or offset/length is negative
459 alSetError(AL_INVALID_VALUE);
461 else
463 switch(format)
465 case AL_FORMAT_REAR8:
466 case AL_FORMAT_REAR16:
467 case AL_FORMAT_REAR32: {
468 ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
469 ((format==AL_FORMAT_REAR16) ? 2 :
470 4));
472 if(ALBuf->eOriginalFormat != AL_FORMAT_REAR8 &&
473 ALBuf->eOriginalFormat != AL_FORMAT_REAR16 &&
474 ALBuf->eOriginalFormat != AL_FORMAT_REAR32)
476 alSetError(AL_INVALID_ENUM);
477 break;
480 if(ALBuf->size/4/sizeof(ALshort) < (ALuint)offset+length)
482 alSetError(AL_INVALID_VALUE);
483 break;
486 ConvertDataRear(&ALBuf->data[offset*4], data, OrigBytes, length*2);
487 } break;
489 case AL_FORMAT_MONO_IMA4:
490 case AL_FORMAT_STEREO_IMA4: {
491 int Channels = aluChannelsFromFormat(ALBuf->format);
493 if(ALBuf->eOriginalFormat != format)
495 alSetError(AL_INVALID_ENUM);
496 break;
499 if((offset%65) != 0 || (length%65) != 0 ||
500 ALBuf->size/Channels/sizeof(ALshort) < (ALuint)offset+length)
502 alSetError(AL_INVALID_VALUE);
503 break;
506 ConvertDataIMA4(&ALBuf->data[offset*Channels], data, Channels, length/65*Channels);
507 } break;
509 default: {
510 ALuint Channels = aluChannelsFromFormat(format);
511 ALuint Bytes = aluBytesFromFormat(format);
513 if(Channels != aluChannelsFromFormat(ALBuf->format))
515 alSetError(AL_INVALID_ENUM);
516 break;
519 if(ALBuf->size/Channels/sizeof(ALshort) < (ALuint)offset+length)
521 alSetError(AL_INVALID_VALUE);
522 break;
525 ConvertData(&ALBuf->data[offset*Channels], data, Bytes, length*Channels);
526 } break;
530 else
532 // Invalid Buffer Name
533 alSetError(AL_INVALID_NAME);
536 ProcessContext(Context);
540 ALAPI void ALAPIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
542 ALCcontext *pContext;
544 (void)flValue;
546 pContext = GetContextSuspended();
547 if(!pContext) return;
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 alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
569 ALCcontext *pContext;
571 (void)flValue1;
572 (void)flValue2;
573 (void)flValue3;
575 pContext = GetContextSuspended();
576 if(!pContext) return;
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 alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues)
598 ALCcontext *pContext;
600 (void)flValues;
602 pContext = GetContextSuspended();
603 if(!pContext) return;
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 alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
625 ALCcontext *pContext;
627 (void)lValue;
629 pContext = GetContextSuspended();
630 if(!pContext) return;
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 alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
652 ALCcontext *pContext;
654 (void)lValue1;
655 (void)lValue2;
656 (void)lValue3;
658 pContext = GetContextSuspended();
659 if(!pContext) return;
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 void ALAPIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues)
681 ALCcontext *pContext;
683 (void)plValues;
685 pContext = GetContextSuspended();
686 if(!pContext) return;
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 ProcessContext(pContext);
706 ALAPI ALvoid ALAPIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue)
708 ALCcontext *pContext;
710 pContext = GetContextSuspended();
711 if(!pContext) return;
713 if (pflValue)
715 if (alIsBuffer(buffer) && (buffer != 0))
717 switch(eParam)
719 default:
720 alSetError(AL_INVALID_ENUM);
721 break;
724 else
726 alSetError(AL_INVALID_NAME);
729 else
731 alSetError(AL_INVALID_VALUE);
734 ProcessContext(pContext);
738 ALAPI void ALAPIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3)
740 ALCcontext *pContext;
742 pContext = GetContextSuspended();
743 if(!pContext) return;
745 if ((pflValue1) && (pflValue2) && (pflValue3))
747 if (alIsBuffer(buffer) && (buffer != 0))
749 switch(eParam)
751 default:
752 alSetError(AL_INVALID_ENUM);
753 break;
756 else
758 alSetError(AL_INVALID_NAME);
761 else
763 alSetError(AL_INVALID_VALUE);
766 ProcessContext(pContext);
770 ALAPI void ALAPIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues)
772 ALCcontext *pContext;
774 pContext = GetContextSuspended();
775 if(!pContext) return;
777 if (pflValues)
779 if (alIsBuffer(buffer) && (buffer != 0))
781 switch(eParam)
783 default:
784 alSetError(AL_INVALID_ENUM);
785 break;
788 else
790 alSetError(AL_INVALID_NAME);
793 else
795 alSetError(AL_INVALID_VALUE);
798 ProcessContext(pContext);
802 ALAPI ALvoid ALAPIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue)
804 ALCcontext *pContext;
805 ALbuffer *pBuffer;
807 pContext = GetContextSuspended();
808 if(!pContext) return;
810 if (plValue)
812 if (alIsBuffer(buffer) && (buffer != 0))
814 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
816 switch (eParam)
818 case AL_FREQUENCY:
819 *plValue = pBuffer->frequency;
820 break;
822 case AL_BITS:
823 *plValue = aluBytesFromFormat(pBuffer->format) * 8;
824 break;
826 case AL_CHANNELS:
827 *plValue = aluChannelsFromFormat(pBuffer->format);
828 break;
830 case AL_SIZE:
831 *plValue = pBuffer->size;
832 break;
834 default:
835 alSetError(AL_INVALID_ENUM);
836 break;
839 else
841 alSetError(AL_INVALID_NAME);
844 else
846 alSetError(AL_INVALID_VALUE);
849 ProcessContext(pContext);
853 ALAPI void ALAPIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3)
855 ALCcontext *pContext;
857 pContext = GetContextSuspended();
858 if(!pContext) return;
860 if ((plValue1) && (plValue2) && (plValue3))
862 if (alIsBuffer(buffer) && (buffer != 0))
864 switch(eParam)
866 default:
867 alSetError(AL_INVALID_ENUM);
868 break;
871 else
873 alSetError(AL_INVALID_NAME);
876 else
878 alSetError(AL_INVALID_VALUE);
881 ProcessContext(pContext);
885 ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues)
887 ALCcontext *pContext;
889 pContext = GetContextSuspended();
890 if(!pContext) return;
892 if (plValues)
894 if (alIsBuffer(buffer) && (buffer != 0))
896 switch (eParam)
898 case AL_FREQUENCY:
899 case AL_BITS:
900 case AL_CHANNELS:
901 case AL_SIZE:
902 alGetBufferi(buffer, eParam, plValues);
903 break;
905 default:
906 alSetError(AL_INVALID_ENUM);
907 break;
910 else
912 alSetError(AL_INVALID_NAME);
915 else
917 alSetError(AL_INVALID_VALUE);
920 ProcessContext(pContext);
924 * LoadData
926 * Loads the specified data into the buffer, using the specified formats.
927 * Currently, the new format must be 16-bit, and must have the same channel
928 * configuration as the original format. This does NOT handle compressed
929 * formats (eg. IMA4).
931 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
933 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
934 ALuint OrigBytes = aluBytesFromFormat(OrigFormat);
935 ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
936 ALvoid *temp;
938 assert(aluBytesFromFormat(NewFormat) == 2);
939 assert(NewChannels == OrigChannels);
941 if ((size%(OrigBytes*OrigChannels)) != 0)
943 alSetError(AL_INVALID_VALUE);
944 return;
947 // Samples are converted to 16 bit here
948 size /= OrigBytes;
949 temp = realloc(ALBuf->data, (BUFFER_PADDING*NewChannels + size) * sizeof(ALshort));
950 if(temp)
952 ALBuf->data = temp;
953 ConvertData(ALBuf->data, data, OrigBytes, size);
955 memset(&(ALBuf->data[size]), 0, BUFFER_PADDING*NewChannels*sizeof(ALshort));
957 ALBuf->format = NewFormat;
958 ALBuf->eOriginalFormat = OrigFormat;
959 ALBuf->size = size*sizeof(ALshort);
960 ALBuf->frequency = freq;
962 else
963 alSetError(AL_OUT_OF_MEMORY);
966 static void ConvertData(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len)
968 ALsizei i;
969 switch(origBytes)
971 case 1:
972 for(i = 0;i < len;i++)
973 dst[i] = ((ALshort)((ALubyte*)src)[i] - 128) << 8;
974 break;
976 case 2:
977 memcpy(dst, src, len*sizeof(ALshort));
978 break;
980 case 4:
981 for(i = 0;i < len;i++)
983 ALint smp;
984 smp = (((ALfloat*)src)[i] * 32767.5f - 0.5f);
985 smp = min(smp, 32767);
986 smp = max(smp, -32768);
987 dst[i] = (ALshort)smp;
989 break;
991 default:
992 assert(0);
996 static void ConvertDataRear(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len)
998 ALsizei i;
999 switch(origBytes)
1001 case 1:
1002 for(i = 0;i < len;i+=4)
1004 dst[i+0] = 0;
1005 dst[i+1] = 0;
1006 dst[i+2] = ((ALshort)((ALubyte*)src)[i/2+0] - 128) << 8;
1007 dst[i+3] = ((ALshort)((ALubyte*)src)[i/2+1] - 128) << 8;
1009 break;
1011 case 2:
1012 for(i = 0;i < len;i+=4)
1014 dst[i+0] = 0;
1015 dst[i+1] = 0;
1016 dst[i+2] = ((ALshort*)src)[i/2+0];
1017 dst[i+3] = ((ALshort*)src)[i/2+1];
1019 break;
1021 case 4:
1022 for(i = 0;i < len;i+=4)
1024 ALint smp;
1025 dst[i+0] = 0;
1026 dst[i+1] = 0;
1027 smp = (((ALfloat*)src)[i/2+0] * 32767.5f - 0.5);
1028 smp = min(smp, 32767);
1029 smp = max(smp, -32768);
1030 dst[i+2] = (ALshort)smp;
1031 smp = (((ALfloat*)src)[i/2+1] * 32767.5f - 0.5);
1032 smp = min(smp, 32767);
1033 smp = max(smp, -32768);
1034 dst[i+3] = (ALshort)smp;
1036 break;
1038 default:
1039 assert(0);
1043 static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, ALsizei len)
1045 const ALuint *IMAData;
1046 ALint Sample[2],Index[2];
1047 ALuint IMACode[2];
1048 ALsizei i,j,k,c;
1050 assert(origChans <= 2);
1052 IMAData = src;
1053 for(i = 0;i < len/origChans;i++)
1055 for(c = 0;c < origChans;c++)
1057 Sample[c] = ((ALshort*)IMAData)[0];
1058 Index[c] = ((ALshort*)IMAData)[1];
1060 Index[c] = ((Index[c]<0) ? 0 : Index[c]);
1061 Index[c] = ((Index[c]>88) ? 88 : Index[c]);
1063 dst[i*65*origChans + c] = (ALshort)Sample[c];
1065 IMAData++;
1068 for(j = 1;j < 65;j += 8)
1070 for(c = 0;c < origChans;c++)
1071 IMACode[c] = *(IMAData++);
1073 for(k = 0;k < 8;k++)
1075 for(c = 0;c < origChans;c++)
1077 Sample[c] += ((g_IMAStep_size[Index[c]]*g_IMACodeword_4[IMACode[c]&15])/8);
1078 Index[c] += g_IMAIndex_adjust_4[IMACode[c]&15];
1080 if(Sample[c] < -32768) Sample[c] = -32768;
1081 else if(Sample[c] > 32767) Sample[c] = 32767;
1083 if(Index[c]<0) Index[c] = 0;
1084 else if(Index[c]>88) Index[c] = 88;
1086 dst[(i*65+j+k)*origChans + c] = (ALshort)Sample[c];
1087 IMACode[c] >>= 4;
1095 * ReleaseALBuffers()
1097 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
1099 ALvoid ReleaseALBuffers(ALCdevice *device)
1101 ALbuffer *ALBuffer;
1102 ALbuffer *ALBufferTemp;
1104 ALBuffer = device->Buffers;
1105 while(ALBuffer)
1107 // Release sample data
1108 free(ALBuffer->data);
1110 // Release Buffer structure
1111 ALBufferTemp = ALBuffer;
1112 ALBuffer = ALBuffer->next;
1113 memset(ALBufferTemp, 0, sizeof(ALbuffer));
1114 free(ALBufferTemp);
1116 device->Buffers = NULL;
1117 device->BufferCount = 0;