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
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
);
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
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
)
86 Context
= alcGetCurrentContext();
87 SuspendContext(Context
);
89 // Check that we are actually generation some Buffers
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
;
97 list
= &(*list
)->next
;
99 // Create all the new Buffers
102 *list
= calloc(1, sizeof(ALbuffer
));
105 alDeleteBuffers(i
, puiBuffers
);
106 alSetError(AL_OUT_OF_MEMORY
);
110 puiBuffers
[i
] = (ALuint
)ALTHUNK_ADDENTRY(*list
);
111 (*list
)->state
= UNUSED
;
115 list
= &(*list
)->next
;
120 // Pointer does not point to enough memory to write Buffer names
121 alSetError(AL_INVALID_VALUE
);
125 ProcessContext(Context
);
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
)
140 ALboolean bFailed
= AL_FALSE
;
142 Context
= alcGetCurrentContext();
143 SuspendContext(Context
);
145 // Check we are actually Deleting some Buffers
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
]));
158 if (ALBuf
->refcount
!= 0)
160 // Buffer still in use, cannot be deleted
161 alSetError(AL_INVALID_OPERATION
);
169 alSetError(AL_INVALID_NAME
);
174 // If all the Buffers were valid (and have Reference Counts of 0), then we can delete them
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
;
188 *list
= (*list
)->next
;
190 // Release the memory used to store audio data
193 // Release buffer structure
194 ALTHUNK_REMOVEENTRY(puiBuffers
[i
]);
195 memset(ALBuf
, 0, sizeof(ALbuffer
));
203 alSetError(AL_INVALID_VALUE
);
205 ProcessContext(Context
);
212 * alIsBuffer(ALuint uiBuffer)
214 * Checks if ulBuffer is a valid Buffer Name
216 ALAPI ALboolean ALAPIENTRY
alIsBuffer(ALuint uiBuffer
)
219 ALboolean result
=AL_FALSE
;
223 Context
= alcGetCurrentContext();
224 SuspendContext(Context
);
228 TgtALBuf
= (ALbuffer
*)ALTHUNK_LOOKUPENTRY(uiBuffer
);
230 // Check through list of generated buffers for uiBuffer
234 if (ALBuf
== TgtALBuf
)
249 ProcessContext(Context
);
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
)
266 Context
= alcGetCurrentContext();
267 SuspendContext(Context
);
269 if (alIsBuffer(buffer
) && (buffer
!= 0))
271 ALBuf
=((ALbuffer
*)ALTHUNK_LOOKUPENTRY(buffer
));
272 if ((ALBuf
->refcount
==0)&&(data
))
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
);
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
);
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 :
297 assert(aluBytesFromFormat(NewFormat
) == 2);
299 if((size
%(OrigBytes
*2)) != 0)
301 alSetError(AL_INVALID_VALUE
);
308 // Samples are converted to 16 bit here
309 temp
= realloc(ALBuf
->data
, (padding
*NewChannels
+ size
) * sizeof(ALshort
));
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
;
324 alSetError(AL_OUT_OF_MEMORY
);
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
);
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
);
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
);
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
);
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
);
369 // Allocate extra padding samples
370 temp
= realloc(ALBuf
->data
, (padding
*OrigChans
+ size
)*sizeof(ALshort
));
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
;
385 alSetError(AL_OUT_OF_MEMORY
);
389 alSetError(AL_INVALID_ENUM
);
395 // Buffer is in use, or data is a NULL pointer
396 alSetError(AL_INVALID_VALUE
);
401 // Invalid Buffer Name
402 alSetError(AL_INVALID_NAME
);
405 ProcessContext(Context
);
409 ALAPI
void ALAPIENTRY
alBufferf(ALuint buffer
, ALenum eParam
, ALfloat flValue
)
411 ALCcontext
*pContext
;
415 pContext
= alcGetCurrentContext();
416 SuspendContext(pContext
);
418 if (alIsBuffer(buffer
) && (buffer
!= 0))
423 alSetError(AL_INVALID_ENUM
);
429 alSetError(AL_INVALID_NAME
);
432 ProcessContext(pContext
);
436 ALAPI
void ALAPIENTRY
alBuffer3f(ALuint buffer
, ALenum eParam
, ALfloat flValue1
, ALfloat flValue2
, ALfloat flValue3
)
438 ALCcontext
*pContext
;
444 pContext
= alcGetCurrentContext();
445 SuspendContext(pContext
);
447 if (alIsBuffer(buffer
) && (buffer
!= 0))
452 alSetError(AL_INVALID_ENUM
);
458 alSetError(AL_INVALID_NAME
);
461 ProcessContext(pContext
);
465 ALAPI
void ALAPIENTRY
alBufferfv(ALuint buffer
, ALenum eParam
, const ALfloat
* flValues
)
467 ALCcontext
*pContext
;
471 pContext
= alcGetCurrentContext();
472 SuspendContext(pContext
);
474 if (alIsBuffer(buffer
) && (buffer
!= 0))
479 alSetError(AL_INVALID_ENUM
);
485 alSetError(AL_INVALID_NAME
);
488 ProcessContext(pContext
);
492 ALAPI
void ALAPIENTRY
alBufferi(ALuint buffer
, ALenum eParam
, ALint lValue
)
494 ALCcontext
*pContext
;
498 pContext
= alcGetCurrentContext();
499 SuspendContext(pContext
);
501 if (alIsBuffer(buffer
) && (buffer
!= 0))
506 alSetError(AL_INVALID_ENUM
);
512 alSetError(AL_INVALID_NAME
);
515 ProcessContext(pContext
);
519 ALAPI
void ALAPIENTRY
alBuffer3i( ALuint buffer
, ALenum eParam
, ALint lValue1
, ALint lValue2
, ALint lValue3
)
521 ALCcontext
*pContext
;
527 pContext
= alcGetCurrentContext();
528 SuspendContext(pContext
);
530 if (alIsBuffer(buffer
) && (buffer
!= 0))
535 alSetError(AL_INVALID_ENUM
);
541 alSetError(AL_INVALID_NAME
);
544 ProcessContext(pContext
);
548 ALAPI
void ALAPIENTRY
alBufferiv(ALuint buffer
, ALenum eParam
, const ALint
* plValues
)
550 ALCcontext
*pContext
;
554 pContext
= alcGetCurrentContext();
555 SuspendContext(pContext
);
557 if (alIsBuffer(buffer
) && (buffer
!= 0))
562 alSetError(AL_INVALID_ENUM
);
568 alSetError(AL_INVALID_NAME
);
571 ProcessContext(pContext
);
575 ALAPI ALvoid ALAPIENTRY
alGetBufferf(ALuint buffer
, ALenum eParam
, ALfloat
*pflValue
)
577 ALCcontext
*pContext
;
579 pContext
= alcGetCurrentContext();
580 SuspendContext(pContext
);
584 if (alIsBuffer(buffer
) && (buffer
!= 0))
589 alSetError(AL_INVALID_ENUM
);
595 alSetError(AL_INVALID_NAME
);
600 alSetError(AL_INVALID_VALUE
);
603 ProcessContext(pContext
);
607 ALAPI
void ALAPIENTRY
alGetBuffer3f(ALuint buffer
, ALenum eParam
, ALfloat
* pflValue1
, ALfloat
* pflValue2
, ALfloat
* pflValue3
)
609 ALCcontext
*pContext
;
611 pContext
= alcGetCurrentContext();
612 SuspendContext(pContext
);
614 if ((pflValue1
) && (pflValue2
) && (pflValue3
))
616 if (alIsBuffer(buffer
) && (buffer
!= 0))
621 alSetError(AL_INVALID_ENUM
);
627 alSetError(AL_INVALID_NAME
);
632 alSetError(AL_INVALID_VALUE
);
635 ProcessContext(pContext
);
639 ALAPI
void ALAPIENTRY
alGetBufferfv(ALuint buffer
, ALenum eParam
, ALfloat
* pflValues
)
641 ALCcontext
*pContext
;
643 pContext
= alcGetCurrentContext();
644 SuspendContext(pContext
);
648 if (alIsBuffer(buffer
) && (buffer
!= 0))
653 alSetError(AL_INVALID_ENUM
);
659 alSetError(AL_INVALID_NAME
);
664 alSetError(AL_INVALID_VALUE
);
667 ProcessContext(pContext
);
671 ALAPI ALvoid ALAPIENTRY
alGetBufferi(ALuint buffer
, ALenum eParam
, ALint
*plValue
)
673 ALCcontext
*pContext
;
676 pContext
= alcGetCurrentContext();
677 SuspendContext(pContext
);
681 if (alIsBuffer(buffer
) && (buffer
!= 0))
683 pBuffer
= ((ALbuffer
*)ALTHUNK_LOOKUPENTRY(buffer
));
688 *plValue
= pBuffer
->frequency
;
692 *plValue
= aluBytesFromFormat(pBuffer
->format
) * 8;
696 *plValue
= aluChannelsFromFormat(pBuffer
->format
);
700 *plValue
= pBuffer
->size
;
704 alSetError(AL_INVALID_ENUM
);
710 alSetError(AL_INVALID_NAME
);
715 alSetError(AL_INVALID_VALUE
);
718 ProcessContext(pContext
);
722 ALAPI
void ALAPIENTRY
alGetBuffer3i(ALuint buffer
, ALenum eParam
, ALint
* plValue1
, ALint
* plValue2
, ALint
* plValue3
)
724 ALCcontext
*pContext
;
726 pContext
= alcGetCurrentContext();
727 SuspendContext(pContext
);
729 if ((plValue1
) && (plValue2
) && (plValue3
))
731 if (alIsBuffer(buffer
) && (buffer
!= 0))
736 alSetError(AL_INVALID_ENUM
);
742 alSetError(AL_INVALID_NAME
);
747 alSetError(AL_INVALID_VALUE
);
750 ProcessContext(pContext
);
754 ALAPI
void ALAPIENTRY
alGetBufferiv(ALuint buffer
, ALenum eParam
, ALint
* plValues
)
756 ALCcontext
*pContext
;
758 pContext
= alcGetCurrentContext();
759 SuspendContext(pContext
);
763 if (alIsBuffer(buffer
) && (buffer
!= 0))
771 alGetBufferi(buffer
, eParam
, plValues
);
775 alSetError(AL_INVALID_ENUM
);
781 alSetError(AL_INVALID_NAME
);
786 alSetError(AL_INVALID_VALUE
);
789 ProcessContext(pContext
);
795 * Loads the specified data into the buffer, using the specified formats.
796 * Currently, the new format must be 16-bit, and must have the same channel
797 * configuration as the original format. This does NOT handle compressed
798 * formats (eg. IMA4).
800 static void LoadData(ALbuffer
*ALBuf
, const ALubyte
*data
, ALsizei size
, ALuint freq
, ALenum OrigFormat
, ALenum NewFormat
)
802 ALuint NewChannels
= aluChannelsFromFormat(NewFormat
);
803 ALuint OrigBytes
= aluBytesFromFormat(OrigFormat
);
804 ALuint OrigChannels
= aluChannelsFromFormat(OrigFormat
);
808 assert(aluBytesFromFormat(NewFormat
) == 2);
809 assert(NewChannels
== OrigChannels
);
811 if ((size
%(OrigBytes
*OrigChannels
)) != 0)
813 alSetError(AL_INVALID_VALUE
);
817 // Samples are converted to 16 bit here
819 temp
= realloc(ALBuf
->data
, (padding
*NewChannels
+ size
) * sizeof(ALshort
));
823 ConvertData(ALBuf
->data
, data
, OrigBytes
, size
);
825 memset(&(ALBuf
->data
[size
]), 0, padding
*NewChannels
*sizeof(ALshort
));
827 ALBuf
->format
= NewFormat
;
828 ALBuf
->eOriginalFormat
= OrigFormat
;
829 ALBuf
->size
= size
*sizeof(ALshort
);
830 ALBuf
->frequency
= freq
;
831 ALBuf
->padding
= padding
;
834 alSetError(AL_OUT_OF_MEMORY
);
837 static void ConvertData(ALshort
*dst
, const ALvoid
*src
, ALint origBytes
, ALsizei len
)
843 for(i
= 0;i
< len
;i
++)
844 dst
[i
] = ((ALshort
)((ALubyte
*)src
)[i
] - 128) << 8;
848 memcpy(dst
, src
, len
*sizeof(ALshort
));
852 for(i
= 0;i
< len
;i
++)
855 smp
= (((ALfloat
*)src
)[i
] * 32767.5f
- 0.5f
);
856 smp
= min(smp
, 32767);
857 smp
= max(smp
, -32768);
858 dst
[i
] = (ALshort
)smp
;
867 static void ConvertDataRear(ALshort
*dst
, const ALvoid
*src
, ALint origBytes
, ALsizei len
)
873 for(i
= 0;i
< len
;i
+=4)
877 dst
[i
+2] = ((ALshort
)((ALubyte
*)src
)[i
/2+0] - 128) << 8;
878 dst
[i
+3] = ((ALshort
)((ALubyte
*)src
)[i
/2+1] - 128) << 8;
883 for(i
= 0;i
< len
;i
+=4)
887 dst
[i
+2] = ((ALshort
*)src
)[i
/2+0];
888 dst
[i
+3] = ((ALshort
*)src
)[i
/2+1];
893 for(i
= 0;i
< len
;i
+=4)
898 smp
= (((ALfloat
*)src
)[i
/2+0] * 32767.5f
- 0.5);
899 smp
= min(smp
, 32767);
900 smp
= max(smp
, -32768);
901 dst
[i
+2] = (ALshort
)smp
;
902 smp
= (((ALfloat
*)src
)[i
/2+1] * 32767.5f
- 0.5);
903 smp
= min(smp
, 32767);
904 smp
= max(smp
, -32768);
905 dst
[i
+3] = (ALshort
)smp
;
914 static void ConvertDataIMA4(ALshort
*dst
, const ALvoid
*src
, ALint origChans
, ALsizei len
)
916 const ALuint
*IMAData
;
917 ALint Sample
[2],Index
[2];
921 assert(origChans
<= 2);
924 for(i
= 0;i
< len
/origChans
;i
++)
926 for(c
= 0;c
< origChans
;c
++)
928 Sample
[c
] = ((ALshort
*)IMAData
)[0];
929 Index
[c
] = ((ALshort
*)IMAData
)[1];
931 Index
[c
] = ((Index
[c
]<0) ? 0 : Index
[c
]);
932 Index
[c
] = ((Index
[c
]>88) ? 88 : Index
[c
]);
934 dst
[i
*65*origChans
+ c
] = (ALshort
)Sample
[c
];
939 for(j
= 1;j
< 65;j
+= 8)
941 for(c
= 0;c
< origChans
;c
++)
942 IMACode
[c
] = *(IMAData
++);
946 for(c
= 0;c
< origChans
;c
++)
948 Sample
[c
] += ((g_IMAStep_size
[Index
[c
]]*g_IMACodeword_4
[IMACode
[c
]&15])/8);
949 Index
[c
] += g_IMAIndex_adjust_4
[IMACode
[c
]&15];
951 if(Sample
[c
] < -32768) Sample
[c
] = -32768;
952 else if(Sample
[c
] > 32767) Sample
[c
] = 32767;
954 if(Index
[c
]<0) Index
[c
] = 0;
955 else if(Index
[c
]>88) Index
[c
] = 88;
957 dst
[(i
*65+j
+k
)*origChans
+ c
] = (ALshort
)Sample
[c
];
968 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
970 ALvoid
ReleaseALBuffers(ALvoid
)
973 ALbuffer
*ALBufferTemp
;
976 if(g_uiBufferCount
> 0)
977 AL_PRINT("exit(): deleting %d Buffer(s)\n", g_uiBufferCount
);
980 ALBuffer
= g_pBuffers
;
983 // Release sample data
984 free(ALBuffer
->data
);
986 // Release Buffer structure
987 ALBufferTemp
= ALBuffer
;
988 ALBuffer
= ALBuffer
->next
;
989 memset(ALBufferTemp
, 0, sizeof(ALbuffer
));