Calculate more store only once per loop
[openal-soft.git] / OpenAL32 / alBuffer.c
blob2ebf42b040a44fb5dca2f4432267565ea4ce9f04
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 (*list)->state = UNUSED;
112 device->BufferCount++;
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 = GetContextSuspended();
143 if(!Context) return;
145 // Check we are actually Deleting some Buffers
146 if (n >= 0)
148 ALCdevice *device = Context->Device;
150 // Check that all the buffers are valid and can actually be deleted
151 for (i = 0; i < n; i++)
153 // Check for valid Buffer ID (can be NULL buffer)
154 if (alIsBuffer(puiBuffers[i]))
156 // If not the NULL buffer, check that the reference count is 0
157 ALBuf = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
158 if (ALBuf)
160 if (ALBuf->refcount != 0)
162 // Buffer still in use, cannot be deleted
163 alSetError(AL_INVALID_OPERATION);
164 bFailed = AL_TRUE;
168 else
170 // Invalid Buffer
171 alSetError(AL_INVALID_NAME);
172 bFailed = AL_TRUE;
176 // If all the Buffers were valid (and have Reference Counts of 0), then we can delete them
177 if (!bFailed)
179 for (i = 0; i < n; i++)
181 if (puiBuffers[i] && alIsBuffer(puiBuffers[i]))
183 ALbuffer **list = &device->Buffers;
185 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
186 while(*list && *list != ALBuf)
187 list = &(*list)->next;
189 if(*list)
190 *list = (*list)->next;
192 // Release the memory used to store audio data
193 free(ALBuf->data);
195 // Release buffer structure
196 ALTHUNK_REMOVEENTRY(puiBuffers[i]);
197 memset(ALBuf, 0, sizeof(ALbuffer));
198 device->BufferCount--;
199 free(ALBuf);
204 else
205 alSetError(AL_INVALID_VALUE);
207 ProcessContext(Context);
209 return;
214 * alIsBuffer(ALuint uiBuffer)
216 * Checks if ulBuffer is a valid Buffer Name
218 ALAPI ALboolean ALAPIENTRY alIsBuffer(ALuint uiBuffer)
220 ALCcontext *Context;
221 ALboolean result=AL_FALSE;
222 ALbuffer *ALBuf;
223 ALbuffer *TgtALBuf;
225 Context = GetContextSuspended();
226 if(!Context) return AL_FALSE;
228 if (uiBuffer)
230 ALCdevice *device = Context->Device;
232 TgtALBuf = (ALbuffer *)ALTHUNK_LOOKUPENTRY(uiBuffer);
234 // Check through list of generated buffers for uiBuffer
235 ALBuf = device->Buffers;
236 while (ALBuf)
238 if (ALBuf == TgtALBuf)
240 result = AL_TRUE;
241 break;
244 ALBuf = ALBuf->next;
247 else
249 result = AL_TRUE;
253 ProcessContext(Context);
255 return result;
259 * alBufferData(ALuint buffer,ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
261 * Fill buffer with audio data
263 ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq)
265 ALCcontext *Context;
266 ALsizei padding = 2;
267 ALbuffer *ALBuf;
268 ALvoid *temp;
270 Context = GetContextSuspended();
271 if(!Context) return;
273 if (alIsBuffer(buffer) && (buffer != 0))
275 ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
277 if(Context->SampleSource)
279 ALuint offset;
281 if(Context->SampleSource->state == MAPPED)
283 alSetError(AL_INVALID_OPERATION);
284 ProcessContext(Context);
285 return;
288 offset = (ALuint)data;
289 data = Context->SampleSource->data + offset;
292 if ((ALBuf->refcount==0)&&(data))
294 switch(format)
296 case AL_FORMAT_MONO8:
297 case AL_FORMAT_MONO16:
298 case AL_FORMAT_MONO_FLOAT32:
299 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO16);
300 break;
302 case AL_FORMAT_STEREO8:
303 case AL_FORMAT_STEREO16:
304 case AL_FORMAT_STEREO_FLOAT32:
305 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO16);
306 break;
308 case AL_FORMAT_REAR8:
309 case AL_FORMAT_REAR16:
310 case AL_FORMAT_REAR32: {
311 ALuint NewFormat = AL_FORMAT_QUAD16;
312 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
313 ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
314 ((format==AL_FORMAT_REAR16) ? 2 :
315 4));
317 assert(aluBytesFromFormat(NewFormat) == 2);
319 if((size%(OrigBytes*2)) != 0)
321 alSetError(AL_INVALID_VALUE);
322 break;
325 size /= OrigBytes;
326 size *= 2;
328 // Samples are converted to 16 bit here
329 temp = realloc(ALBuf->data, (padding*NewChannels + size) * sizeof(ALshort));
330 if(temp)
332 ALBuf->data = temp;
333 ConvertDataRear(ALBuf->data, data, OrigBytes, size);
335 memset(&(ALBuf->data[size]), 0, padding*NewChannels*sizeof(ALshort));
337 ALBuf->format = NewFormat;
338 ALBuf->eOriginalFormat = format;
339 ALBuf->size = size*sizeof(ALshort);
340 ALBuf->frequency = freq;
341 ALBuf->padding = padding;
343 else
344 alSetError(AL_OUT_OF_MEMORY);
345 } break;
347 case AL_FORMAT_QUAD8_LOKI:
348 case AL_FORMAT_QUAD16_LOKI:
349 case AL_FORMAT_QUAD8:
350 case AL_FORMAT_QUAD16:
351 case AL_FORMAT_QUAD32:
352 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD16);
353 break;
355 case AL_FORMAT_51CHN8:
356 case AL_FORMAT_51CHN16:
357 case AL_FORMAT_51CHN32:
358 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN16);
359 break;
361 case AL_FORMAT_61CHN8:
362 case AL_FORMAT_61CHN16:
363 case AL_FORMAT_61CHN32:
364 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN16);
365 break;
367 case AL_FORMAT_71CHN8:
368 case AL_FORMAT_71CHN16:
369 case AL_FORMAT_71CHN32:
370 LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN16);
371 break;
373 case AL_FORMAT_MONO_IMA4:
374 case AL_FORMAT_STEREO_IMA4: {
375 int OrigChans = ((format==AL_FORMAT_MONO_IMA4) ? 1 : 2);
377 // Here is where things vary:
378 // nVidia and Apple use 64+1 samples per channel per block => block_size=36*chans bytes
379 // Most PC sound software uses 2040+1 samples per channel per block -> block_size=1024*chans bytes
380 if((size%(36*OrigChans)) != 0)
382 alSetError(AL_INVALID_VALUE);
383 break;
386 size /= 36;
387 size *= 65;
389 // Allocate extra padding samples
390 temp = realloc(ALBuf->data, (padding*OrigChans + size)*sizeof(ALshort));
391 if(temp)
393 ALBuf->data = temp;
394 ConvertDataIMA4(ALBuf->data, data, OrigChans, size/65);
396 memset(&(ALBuf->data[size]), 0, padding*sizeof(ALshort)*OrigChans);
398 ALBuf->format = ((OrigChans==1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16);
399 ALBuf->eOriginalFormat = format;
400 ALBuf->size = size*sizeof(ALshort);
401 ALBuf->frequency = freq;
402 ALBuf->padding = padding;
404 else
405 alSetError(AL_OUT_OF_MEMORY);
406 } break;
408 default:
409 alSetError(AL_INVALID_ENUM);
410 break;
413 else
415 // Buffer is in use, or data is a NULL pointer
416 alSetError(AL_INVALID_VALUE);
419 else
421 // Invalid Buffer Name
422 alSetError(AL_INVALID_NAME);
425 ProcessContext(Context);
429 * alBufferSubDataEXT(ALuint buffer,ALenum format,ALvoid *data,ALsizei offset,ALsizei length)
431 * Fill buffer with audio data
433 ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length)
435 ALCcontext *Context;
436 ALbuffer *ALBuf;
438 Context = GetContextSuspended();
439 if(!Context) return;
441 if(alIsBuffer(buffer) && buffer != 0)
443 ALBuf = (ALbuffer*)ALTHUNK_LOOKUPENTRY(buffer);
445 if(Context->SampleSource)
447 ALuint offset;
449 if(Context->SampleSource->state == MAPPED)
451 alSetError(AL_INVALID_OPERATION);
452 ProcessContext(Context);
453 return;
456 offset = (ALuint)data;
457 data = Context->SampleSource->data + offset;
460 if(ALBuf->data == NULL)
462 // buffer does not have any data
463 alSetError(AL_INVALID_NAME);
465 else if(length < 0 || offset < 0 || (length > 0 && data == NULL))
467 // data is NULL or offset/length is negative
468 alSetError(AL_INVALID_VALUE);
470 else
472 switch(format)
474 case AL_FORMAT_REAR8:
475 case AL_FORMAT_REAR16:
476 case AL_FORMAT_REAR32: {
477 ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
478 ((format==AL_FORMAT_REAR16) ? 2 :
479 4));
481 if(ALBuf->eOriginalFormat != AL_FORMAT_REAR8 &&
482 ALBuf->eOriginalFormat != AL_FORMAT_REAR16 &&
483 ALBuf->eOriginalFormat != AL_FORMAT_REAR32)
485 alSetError(AL_INVALID_ENUM);
486 break;
489 if(ALBuf->size/4/sizeof(ALshort) < (ALuint)offset+length)
491 alSetError(AL_INVALID_VALUE);
492 break;
495 ConvertDataRear(&ALBuf->data[offset*4], data, OrigBytes, length*2);
496 } break;
498 case AL_FORMAT_MONO_IMA4:
499 case AL_FORMAT_STEREO_IMA4: {
500 int Channels = aluChannelsFromFormat(ALBuf->format);
502 if(ALBuf->eOriginalFormat != format)
504 alSetError(AL_INVALID_ENUM);
505 break;
508 if((offset%65) != 0 || (length%65) != 0 ||
509 ALBuf->size/Channels/sizeof(ALshort) < (ALuint)offset+length)
511 alSetError(AL_INVALID_VALUE);
512 break;
515 ConvertDataIMA4(&ALBuf->data[offset*Channels], data, Channels, length/65*Channels);
516 } break;
518 default: {
519 ALuint Channels = aluChannelsFromFormat(format);
520 ALuint Bytes = aluBytesFromFormat(format);
522 if(Channels != aluChannelsFromFormat(ALBuf->format))
524 alSetError(AL_INVALID_ENUM);
525 break;
528 if(ALBuf->size/Channels/sizeof(ALshort) < (ALuint)offset+length)
530 alSetError(AL_INVALID_VALUE);
531 break;
534 ConvertData(&ALBuf->data[offset*Channels], data, Bytes, length*Channels);
535 } break;
539 else
541 // Invalid Buffer Name
542 alSetError(AL_INVALID_NAME);
545 ProcessContext(Context);
549 ALAPI void ALAPIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
551 ALCcontext *pContext;
553 (void)flValue;
555 pContext = GetContextSuspended();
556 if(!pContext) return;
558 if (alIsBuffer(buffer) && (buffer != 0))
560 switch(eParam)
562 default:
563 alSetError(AL_INVALID_ENUM);
564 break;
567 else
569 alSetError(AL_INVALID_NAME);
572 ProcessContext(pContext);
576 ALAPI void ALAPIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
578 ALCcontext *pContext;
580 (void)flValue1;
581 (void)flValue2;
582 (void)flValue3;
584 pContext = GetContextSuspended();
585 if(!pContext) return;
587 if (alIsBuffer(buffer) && (buffer != 0))
589 switch(eParam)
591 default:
592 alSetError(AL_INVALID_ENUM);
593 break;
596 else
598 alSetError(AL_INVALID_NAME);
601 ProcessContext(pContext);
605 ALAPI void ALAPIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* flValues)
607 ALCcontext *pContext;
609 (void)flValues;
611 pContext = GetContextSuspended();
612 if(!pContext) return;
614 if (alIsBuffer(buffer) && (buffer != 0))
616 switch(eParam)
618 default:
619 alSetError(AL_INVALID_ENUM);
620 break;
623 else
625 alSetError(AL_INVALID_NAME);
628 ProcessContext(pContext);
632 ALAPI void ALAPIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
634 ALCcontext *pContext;
636 (void)lValue;
638 pContext = GetContextSuspended();
639 if(!pContext) return;
641 if (alIsBuffer(buffer) && (buffer != 0))
643 switch(eParam)
645 default:
646 alSetError(AL_INVALID_ENUM);
647 break;
650 else
652 alSetError(AL_INVALID_NAME);
655 ProcessContext(pContext);
659 ALAPI void ALAPIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
661 ALCcontext *pContext;
663 (void)lValue1;
664 (void)lValue2;
665 (void)lValue3;
667 pContext = GetContextSuspended();
668 if(!pContext) return;
670 if (alIsBuffer(buffer) && (buffer != 0))
672 switch(eParam)
674 default:
675 alSetError(AL_INVALID_ENUM);
676 break;
679 else
681 alSetError(AL_INVALID_NAME);
684 ProcessContext(pContext);
688 ALAPI void ALAPIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plValues)
690 ALCcontext *pContext;
692 (void)plValues;
694 pContext = GetContextSuspended();
695 if(!pContext) return;
697 if (alIsBuffer(buffer) && (buffer != 0))
699 switch(eParam)
701 default:
702 alSetError(AL_INVALID_ENUM);
703 break;
706 else
708 alSetError(AL_INVALID_NAME);
711 ProcessContext(pContext);
715 ALAPI ALvoid ALAPIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflValue)
717 ALCcontext *pContext;
719 pContext = GetContextSuspended();
720 if(!pContext) return;
722 if (pflValue)
724 if (alIsBuffer(buffer) && (buffer != 0))
726 switch(eParam)
728 default:
729 alSetError(AL_INVALID_ENUM);
730 break;
733 else
735 alSetError(AL_INVALID_NAME);
738 else
740 alSetError(AL_INVALID_VALUE);
743 ProcessContext(pContext);
747 ALAPI void ALAPIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3)
749 ALCcontext *pContext;
751 pContext = GetContextSuspended();
752 if(!pContext) return;
754 if ((pflValue1) && (pflValue2) && (pflValue3))
756 if (alIsBuffer(buffer) && (buffer != 0))
758 switch(eParam)
760 default:
761 alSetError(AL_INVALID_ENUM);
762 break;
765 else
767 alSetError(AL_INVALID_NAME);
770 else
772 alSetError(AL_INVALID_VALUE);
775 ProcessContext(pContext);
779 ALAPI void ALAPIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflValues)
781 ALCcontext *pContext;
783 pContext = GetContextSuspended();
784 if(!pContext) return;
786 if (pflValues)
788 if (alIsBuffer(buffer) && (buffer != 0))
790 switch(eParam)
792 default:
793 alSetError(AL_INVALID_ENUM);
794 break;
797 else
799 alSetError(AL_INVALID_NAME);
802 else
804 alSetError(AL_INVALID_VALUE);
807 ProcessContext(pContext);
811 ALAPI ALvoid ALAPIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValue)
813 ALCcontext *pContext;
814 ALbuffer *pBuffer;
816 pContext = GetContextSuspended();
817 if(!pContext) return;
819 if (plValue)
821 if (alIsBuffer(buffer) && (buffer != 0))
823 pBuffer = ((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
825 switch (eParam)
827 case AL_FREQUENCY:
828 *plValue = pBuffer->frequency;
829 break;
831 case AL_BITS:
832 *plValue = aluBytesFromFormat(pBuffer->format) * 8;
833 break;
835 case AL_CHANNELS:
836 *plValue = aluChannelsFromFormat(pBuffer->format);
837 break;
839 case AL_SIZE:
840 *plValue = pBuffer->size;
841 break;
843 default:
844 alSetError(AL_INVALID_ENUM);
845 break;
848 else
850 alSetError(AL_INVALID_NAME);
853 else
855 alSetError(AL_INVALID_VALUE);
858 ProcessContext(pContext);
862 ALAPI void ALAPIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue1, ALint* plValue2, ALint* plValue3)
864 ALCcontext *pContext;
866 pContext = GetContextSuspended();
867 if(!pContext) return;
869 if ((plValue1) && (plValue2) && (plValue3))
871 if (alIsBuffer(buffer) && (buffer != 0))
873 switch(eParam)
875 default:
876 alSetError(AL_INVALID_ENUM);
877 break;
880 else
882 alSetError(AL_INVALID_NAME);
885 else
887 alSetError(AL_INVALID_VALUE);
890 ProcessContext(pContext);
894 ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValues)
896 ALCcontext *pContext;
898 pContext = GetContextSuspended();
899 if(!pContext) return;
901 if (plValues)
903 if (alIsBuffer(buffer) && (buffer != 0))
905 switch (eParam)
907 case AL_FREQUENCY:
908 case AL_BITS:
909 case AL_CHANNELS:
910 case AL_SIZE:
911 alGetBufferi(buffer, eParam, plValues);
912 break;
914 default:
915 alSetError(AL_INVALID_ENUM);
916 break;
919 else
921 alSetError(AL_INVALID_NAME);
924 else
926 alSetError(AL_INVALID_VALUE);
929 ProcessContext(pContext);
933 * LoadData
935 * Loads the specified data into the buffer, using the specified formats.
936 * Currently, the new format must be 16-bit, and must have the same channel
937 * configuration as the original format. This does NOT handle compressed
938 * formats (eg. IMA4).
940 static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
942 ALuint NewChannels = aluChannelsFromFormat(NewFormat);
943 ALuint OrigBytes = aluBytesFromFormat(OrigFormat);
944 ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
945 ALsizei padding = 2;
946 ALvoid *temp;
948 assert(aluBytesFromFormat(NewFormat) == 2);
949 assert(NewChannels == OrigChannels);
951 if ((size%(OrigBytes*OrigChannels)) != 0)
953 alSetError(AL_INVALID_VALUE);
954 return;
957 // Samples are converted to 16 bit here
958 size /= OrigBytes;
959 temp = realloc(ALBuf->data, (padding*NewChannels + size) * sizeof(ALshort));
960 if(temp)
962 ALBuf->data = temp;
963 ConvertData(ALBuf->data, data, OrigBytes, size);
965 memset(&(ALBuf->data[size]), 0, padding*NewChannels*sizeof(ALshort));
967 ALBuf->format = NewFormat;
968 ALBuf->eOriginalFormat = OrigFormat;
969 ALBuf->size = size*sizeof(ALshort);
970 ALBuf->frequency = freq;
971 ALBuf->padding = padding;
973 else
974 alSetError(AL_OUT_OF_MEMORY);
977 static void ConvertData(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len)
979 ALsizei i;
980 switch(origBytes)
982 case 1:
983 for(i = 0;i < len;i++)
984 dst[i] = ((ALshort)((ALubyte*)src)[i] - 128) << 8;
985 break;
987 case 2:
988 memcpy(dst, src, len*sizeof(ALshort));
989 break;
991 case 4:
992 for(i = 0;i < len;i++)
994 ALint smp;
995 smp = (((ALfloat*)src)[i] * 32767.5f - 0.5f);
996 smp = min(smp, 32767);
997 smp = max(smp, -32768);
998 dst[i] = (ALshort)smp;
1000 break;
1002 default:
1003 assert(0);
1007 static void ConvertDataRear(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len)
1009 ALsizei i;
1010 switch(origBytes)
1012 case 1:
1013 for(i = 0;i < len;i+=4)
1015 dst[i+0] = 0;
1016 dst[i+1] = 0;
1017 dst[i+2] = ((ALshort)((ALubyte*)src)[i/2+0] - 128) << 8;
1018 dst[i+3] = ((ALshort)((ALubyte*)src)[i/2+1] - 128) << 8;
1020 break;
1022 case 2:
1023 for(i = 0;i < len;i+=4)
1025 dst[i+0] = 0;
1026 dst[i+1] = 0;
1027 dst[i+2] = ((ALshort*)src)[i/2+0];
1028 dst[i+3] = ((ALshort*)src)[i/2+1];
1030 break;
1032 case 4:
1033 for(i = 0;i < len;i+=4)
1035 ALint smp;
1036 dst[i+0] = 0;
1037 dst[i+1] = 0;
1038 smp = (((ALfloat*)src)[i/2+0] * 32767.5f - 0.5);
1039 smp = min(smp, 32767);
1040 smp = max(smp, -32768);
1041 dst[i+2] = (ALshort)smp;
1042 smp = (((ALfloat*)src)[i/2+1] * 32767.5f - 0.5);
1043 smp = min(smp, 32767);
1044 smp = max(smp, -32768);
1045 dst[i+3] = (ALshort)smp;
1047 break;
1049 default:
1050 assert(0);
1054 static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, ALsizei len)
1056 const ALuint *IMAData;
1057 ALint Sample[2],Index[2];
1058 ALuint IMACode[2];
1059 ALsizei i,j,k,c;
1061 assert(origChans <= 2);
1063 IMAData = src;
1064 for(i = 0;i < len/origChans;i++)
1066 for(c = 0;c < origChans;c++)
1068 Sample[c] = ((ALshort*)IMAData)[0];
1069 Index[c] = ((ALshort*)IMAData)[1];
1071 Index[c] = ((Index[c]<0) ? 0 : Index[c]);
1072 Index[c] = ((Index[c]>88) ? 88 : Index[c]);
1074 dst[i*65*origChans + c] = (ALshort)Sample[c];
1076 IMAData++;
1079 for(j = 1;j < 65;j += 8)
1081 for(c = 0;c < origChans;c++)
1082 IMACode[c] = *(IMAData++);
1084 for(k = 0;k < 8;k++)
1086 for(c = 0;c < origChans;c++)
1088 Sample[c] += ((g_IMAStep_size[Index[c]]*g_IMACodeword_4[IMACode[c]&15])/8);
1089 Index[c] += g_IMAIndex_adjust_4[IMACode[c]&15];
1091 if(Sample[c] < -32768) Sample[c] = -32768;
1092 else if(Sample[c] > 32767) Sample[c] = 32767;
1094 if(Index[c]<0) Index[c] = 0;
1095 else if(Index[c]>88) Index[c] = 88;
1097 dst[(i*65+j+k)*origChans + c] = (ALshort)Sample[c];
1098 IMACode[c] >>= 4;
1106 * ReleaseALBuffers()
1108 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
1110 ALvoid ReleaseALBuffers(ALCdevice *device)
1112 ALbuffer *ALBuffer;
1113 ALbuffer *ALBufferTemp;
1115 ALBuffer = device->Buffers;
1116 while(ALBuffer)
1118 // Release sample data
1119 free(ALBuffer->data);
1121 // Release Buffer structure
1122 ALBufferTemp = ALBuffer;
1123 ALBuffer = ALBuffer->next;
1124 memset(ALBufferTemp, 0, sizeof(ALbuffer));
1125 free(ALBufferTemp);
1127 device->Buffers = NULL;
1128 device->BufferCount = 0;