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
33 #include "alDatabuffer.h"
37 static ALenum
LoadData(ALbuffer
*ALBuf
, const ALvoid
*data
, ALsizei size
, ALuint freq
, ALenum OrigFormat
, ALenum NewFormat
);
38 static void ConvertData(ALvoid
*dst
, const ALvoid
*src
, enum SrcFmtType srcType
, ALsizei len
);
39 static void ConvertDataRear(ALvoid
*dst
, const ALvoid
*src
, ALint origBytes
, ALsizei len
);
40 static void ConvertDataIMA4(ALvoid
*dst
, const ALvoid
*src
, ALint origChans
, ALsizei len
);
41 static void ConvertDataMULaw(ALvoid
*dst
, const ALvoid
*src
, ALsizei len
);
42 static void ConvertDataMULawRear(ALvoid
*dst
, const ALvoid
*src
, ALsizei len
);
44 #define LookupBuffer(m, k) ((ALbuffer*)LookupUIntMapKey(&(m), (k)))
51 static const long g_IMAStep_size
[89]={ // IMA ADPCM Stepsize table
52 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
53 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
54 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
55 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
56 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493,10442,11487,12635,13899,
57 15289,16818,18500,20350,22358,24633,27086,29794,32767
60 static const long g_IMACodeword_4
[16]={ // IMA4 ADPCM Codeword decode table
61 1, 3, 5, 7, 9, 11, 13, 15,
62 -1,-3,-5,-7,-9,-11,-13,-15,
65 static const long g_IMAIndex_adjust_4
[16]={ // IMA4 ADPCM Step index adjust decode table
66 -1,-1,-1,-1, 2, 4, 6, 8,
67 -1,-1,-1,-1, 2, 4, 6, 8
70 static const ALshort muLawDecompressionTable
[256] = {
71 -32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956,
72 -23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764,
73 -15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412,
74 -11900,-11388,-10876,-10364, -9852, -9340, -8828, -8316,
75 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
76 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
77 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
78 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
79 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
80 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
81 -876, -844, -812, -780, -748, -716, -684, -652,
82 -620, -588, -556, -524, -492, -460, -428, -396,
83 -372, -356, -340, -324, -308, -292, -276, -260,
84 -244, -228, -212, -196, -180, -164, -148, -132,
85 -120, -112, -104, -96, -88, -80, -72, -64,
86 -56, -48, -40, -32, -24, -16, -8, 0,
87 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
88 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
89 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
90 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
91 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
92 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
93 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
94 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
95 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
96 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
97 876, 844, 812, 780, 748, 716, 684, 652,
98 620, 588, 556, 524, 492, 460, 428, 396,
99 372, 356, 340, 324, 308, 292, 276, 260,
100 244, 228, 212, 196, 180, 164, 148, 132,
101 120, 112, 104, 96, 88, 80, 72, 64,
102 56, 48, 40, 32, 24, 16, 8, 0
106 * alGenBuffers(ALsizei n, ALuint *buffers)
108 * Generates n AL Buffers, and stores the Buffers Names in the array pointed to by buffers
110 AL_API ALvoid AL_APIENTRY
alGenBuffers(ALsizei n
, ALuint
*buffers
)
115 Context
= GetContextSuspended();
118 // Check that we are actually generating some Buffers
119 if(n
< 0 || IsBadWritePtr((void*)buffers
, n
* sizeof(ALuint
)))
120 alSetError(Context
, AL_INVALID_VALUE
);
123 ALCdevice
*device
= Context
->Device
;
126 // Create all the new Buffers
129 ALbuffer
*buffer
= calloc(1, sizeof(ALbuffer
));
132 alSetError(Context
, AL_OUT_OF_MEMORY
);
133 alDeleteBuffers(i
, buffers
);
137 buffer
->buffer
= (ALuint
)ALTHUNK_ADDENTRY(buffer
);
138 err
= InsertUIntMapEntry(&device
->BufferMap
, buffer
->buffer
, buffer
);
139 if(err
!= AL_NO_ERROR
)
141 ALTHUNK_REMOVEENTRY(buffer
->buffer
);
142 memset(buffer
, 0, sizeof(ALbuffer
));
145 alSetError(Context
, err
);
146 alDeleteBuffers(i
, buffers
);
149 buffers
[i
++] = buffer
->buffer
;
153 ProcessContext(Context
);
157 * alDeleteBuffers(ALsizei n, ALuint *buffers)
159 * Deletes the n AL Buffers pointed to by buffers
161 AL_API ALvoid AL_APIENTRY
alDeleteBuffers(ALsizei n
, const ALuint
*buffers
)
169 Context
= GetContextSuspended();
173 device
= Context
->Device
;
174 /* Check we are actually Deleting some Buffers */
176 alSetError(Context
, AL_INVALID_VALUE
);
181 /* Check that all the buffers are valid and can actually be deleted */
187 /* Check for valid Buffer ID */
188 if((ALBuf
=LookupBuffer(device
->BufferMap
, buffers
[i
])) == NULL
)
190 alSetError(Context
, AL_INVALID_NAME
);
194 else if(ALBuf
->refcount
!= 0)
196 /* Buffer still in use, cannot be deleted */
197 alSetError(Context
, AL_INVALID_OPERATION
);
204 /* If all the Buffers were valid (and have Reference Counts of 0), then we can delete them */
209 if((ALBuf
=LookupBuffer(device
->BufferMap
, buffers
[i
])) == NULL
)
212 /* Release the memory used to store audio data */
215 /* Release buffer structure */
216 RemoveUIntMapKey(&device
->BufferMap
, ALBuf
->buffer
);
217 ALTHUNK_REMOVEENTRY(ALBuf
->buffer
);
219 memset(ALBuf
, 0, sizeof(ALbuffer
));
224 ProcessContext(Context
);
228 * alIsBuffer(ALuint buffer)
230 * Checks if buffer is a valid Buffer Name
232 AL_API ALboolean AL_APIENTRY
alIsBuffer(ALuint buffer
)
237 Context
= GetContextSuspended();
238 if(!Context
) return AL_FALSE
;
240 result
= ((!buffer
|| LookupBuffer(Context
->Device
->BufferMap
, buffer
)) ?
243 ProcessContext(Context
);
249 * alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq)
251 * Fill buffer with audio data
253 AL_API ALvoid AL_APIENTRY
alBufferData(ALuint buffer
,ALenum format
,const ALvoid
*data
,ALsizei size
,ALsizei freq
)
261 Context
= GetContextSuspended();
264 if(Context
->SampleSource
)
268 if(Context
->SampleSource
->state
== MAPPED
)
270 alSetError(Context
, AL_INVALID_OPERATION
);
271 ProcessContext(Context
);
275 offset
= (const ALubyte
*)data
- (ALubyte
*)NULL
;
276 data
= Context
->SampleSource
->data
+ offset
;
279 device
= Context
->Device
;
280 if((ALBuf
=LookupBuffer(device
->BufferMap
, buffer
)) == NULL
)
281 alSetError(Context
, AL_INVALID_NAME
);
282 else if(size
< 0 || freq
< 0)
283 alSetError(Context
, AL_INVALID_VALUE
);
284 else if(ALBuf
->refcount
!= 0)
285 alSetError(Context
, AL_INVALID_VALUE
);
288 case AL_FORMAT_MONO8
:
289 case AL_FORMAT_MONO16
:
290 case AL_FORMAT_MONO_FLOAT32
:
291 case AL_FORMAT_MONO_DOUBLE_EXT
:
292 case AL_FORMAT_STEREO8
:
293 case AL_FORMAT_STEREO16
:
294 case AL_FORMAT_STEREO_FLOAT32
:
295 case AL_FORMAT_STEREO_DOUBLE_EXT
:
296 case AL_FORMAT_QUAD8_LOKI
:
297 case AL_FORMAT_QUAD16_LOKI
:
298 case AL_FORMAT_QUAD8
:
299 case AL_FORMAT_QUAD16
:
300 case AL_FORMAT_QUAD32
:
301 case AL_FORMAT_51CHN8
:
302 case AL_FORMAT_51CHN16
:
303 case AL_FORMAT_51CHN32
:
304 case AL_FORMAT_61CHN8
:
305 case AL_FORMAT_61CHN16
:
306 case AL_FORMAT_61CHN32
:
307 case AL_FORMAT_71CHN8
:
308 case AL_FORMAT_71CHN16
:
309 case AL_FORMAT_71CHN32
:
310 err
= LoadData(ALBuf
, data
, size
, freq
, format
, format
);
311 if(err
!= AL_NO_ERROR
)
312 alSetError(Context
, err
);
315 case AL_FORMAT_REAR8
:
316 case AL_FORMAT_REAR16
:
317 case AL_FORMAT_REAR32
: {
318 ALuint OrigBytes
= ((format
==AL_FORMAT_REAR8
) ? 1 :
319 ((format
==AL_FORMAT_REAR16
) ? 2 : 4));
320 ALenum NewFormat
= ((OrigBytes
==4) ? AL_FORMAT_QUAD32
:
321 ((OrigBytes
==2) ? AL_FORMAT_QUAD16
:
323 ALuint NewChannels
= aluChannelsFromFormat(NewFormat
);
324 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
327 if((size
%(OrigBytes
*2)) != 0)
329 alSetError(Context
, AL_INVALID_VALUE
);
333 newsize
= size
/ OrigBytes
;
337 if(newsize
> INT_MAX
)
339 alSetError(Context
, AL_OUT_OF_MEMORY
);
342 temp
= realloc(ALBuf
->data
, newsize
);
346 ConvertDataRear(ALBuf
->data
, data
, OrigBytes
, newsize
/NewBytes
);
348 ALBuf
->format
= NewFormat
;
349 ALBuf
->eOriginalFormat
= format
;
350 ALBuf
->size
= newsize
;
351 ALBuf
->frequency
= freq
;
353 ALBuf
->LoopStart
= 0;
354 ALBuf
->LoopEnd
= newsize
/ NewChannels
/ NewBytes
;
356 DecomposeFormat(NewFormat
, &ALBuf
->FmtType
, &ALBuf
->FmtChannels
);
358 ALBuf
->OriginalSize
= size
;
359 ALBuf
->OriginalAlign
= OrigBytes
* 2;
362 alSetError(Context
, AL_OUT_OF_MEMORY
);
365 case AL_FORMAT_MONO_IMA4
:
366 case AL_FORMAT_STEREO_IMA4
: {
367 ALuint Channels
= ((format
==AL_FORMAT_MONO_IMA4
) ? 1 : 2);
368 ALenum NewFormat
= ((Channels
==1) ? AL_FORMAT_MONO16
:
370 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
373 /* Here is where things vary:
374 * nVidia and Apple use 64+1 sample frames per block => block_size=36*chans bytes
375 * Most PC sound software uses 2040+1 sample frames per block -> block_size=1024*chans bytes
377 if((size
%(36*Channels
)) != 0)
379 alSetError(Context
, AL_INVALID_VALUE
);
387 if(newsize
> INT_MAX
)
389 alSetError(Context
, AL_OUT_OF_MEMORY
);
392 temp
= realloc(ALBuf
->data
, newsize
);
396 ConvertDataIMA4(ALBuf
->data
, data
, Channels
, newsize
/(65*Channels
*NewBytes
));
398 ALBuf
->format
= NewFormat
;
399 ALBuf
->eOriginalFormat
= format
;
400 ALBuf
->size
= newsize
;
401 ALBuf
->frequency
= freq
;
403 ALBuf
->LoopStart
= 0;
404 ALBuf
->LoopEnd
= newsize
/ Channels
/ NewBytes
;
406 DecomposeFormat(NewFormat
, &ALBuf
->FmtType
, &ALBuf
->FmtChannels
);
408 ALBuf
->OriginalSize
= size
;
409 ALBuf
->OriginalAlign
= 36 * Channels
;
412 alSetError(Context
, AL_OUT_OF_MEMORY
);
415 case AL_FORMAT_MONO_MULAW
:
416 case AL_FORMAT_STEREO_MULAW
:
417 case AL_FORMAT_QUAD_MULAW
:
418 case AL_FORMAT_51CHN_MULAW
:
419 case AL_FORMAT_61CHN_MULAW
:
420 case AL_FORMAT_71CHN_MULAW
: {
421 ALuint Channels
= ((format
==AL_FORMAT_MONO_MULAW
) ? 1 :
422 ((format
==AL_FORMAT_STEREO_MULAW
) ? 2 :
423 ((format
==AL_FORMAT_QUAD_MULAW
) ? 4 :
424 ((format
==AL_FORMAT_51CHN_MULAW
) ? 6 :
425 ((format
==AL_FORMAT_61CHN_MULAW
) ? 7 : 8)))));
426 ALenum NewFormat
= ((Channels
==1) ? AL_FORMAT_MONO16
:
427 ((Channels
==2) ? AL_FORMAT_STEREO16
:
428 ((Channels
==4) ? AL_FORMAT_QUAD16
:
429 ((Channels
==6) ? AL_FORMAT_51CHN16
:
430 ((Channels
==7) ? AL_FORMAT_61CHN16
:
431 AL_FORMAT_71CHN16
)))));
432 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
435 if((size
%(1*Channels
)) != 0)
437 alSetError(Context
, AL_INVALID_VALUE
);
441 newsize
= size
* NewBytes
;
442 if(newsize
> INT_MAX
)
444 alSetError(Context
, AL_OUT_OF_MEMORY
);
447 temp
= realloc(ALBuf
->data
, newsize
);
451 ConvertDataMULaw(ALBuf
->data
, data
, newsize
/NewBytes
);
453 ALBuf
->format
= NewFormat
;
454 ALBuf
->eOriginalFormat
= format
;
455 ALBuf
->size
= newsize
;
456 ALBuf
->frequency
= freq
;
458 ALBuf
->LoopStart
= 0;
459 ALBuf
->LoopEnd
= newsize
/ Channels
/ NewBytes
;
461 DecomposeFormat(NewFormat
, &ALBuf
->FmtType
, &ALBuf
->FmtChannels
);
463 ALBuf
->OriginalSize
= size
;
464 ALBuf
->OriginalAlign
= 1 * Channels
;
467 alSetError(Context
, AL_OUT_OF_MEMORY
);
470 case AL_FORMAT_REAR_MULAW
: {
471 ALenum NewFormat
= AL_FORMAT_QUAD16
;
472 ALuint NewChannels
= aluChannelsFromFormat(NewFormat
);
473 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
476 if((size
%(1*2)) != 0)
478 alSetError(Context
, AL_INVALID_VALUE
);
485 if(newsize
> INT_MAX
)
487 alSetError(Context
, AL_OUT_OF_MEMORY
);
490 temp
= realloc(ALBuf
->data
, newsize
);
494 ConvertDataMULawRear(ALBuf
->data
, data
, newsize
/NewBytes
);
496 ALBuf
->format
= NewFormat
;
497 ALBuf
->eOriginalFormat
= format
;
498 ALBuf
->size
= newsize
;
499 ALBuf
->frequency
= freq
;
501 ALBuf
->LoopStart
= 0;
502 ALBuf
->LoopEnd
= newsize
/ NewChannels
/ NewBytes
;
504 DecomposeFormat(NewFormat
, &ALBuf
->FmtType
, &ALBuf
->FmtChannels
);
506 ALBuf
->OriginalSize
= size
;
507 ALBuf
->OriginalAlign
= 1 * 2;
510 alSetError(Context
, AL_OUT_OF_MEMORY
);
514 alSetError(Context
, AL_INVALID_ENUM
);
518 ProcessContext(Context
);
522 * alBufferSubDataSOFT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length)
524 * Update buffer's audio data
526 AL_API ALvoid AL_APIENTRY
alBufferSubDataSOFT(ALuint buffer
,ALenum format
,const ALvoid
*data
,ALsizei offset
,ALsizei length
)
532 Context
= GetContextSuspended();
535 if(Context
->SampleSource
)
539 if(Context
->SampleSource
->state
== MAPPED
)
541 alSetError(Context
, AL_INVALID_OPERATION
);
542 ProcessContext(Context
);
546 offset
= (const ALubyte
*)data
- (ALubyte
*)NULL
;
547 data
= Context
->SampleSource
->data
+ offset
;
550 device
= Context
->Device
;
551 if((ALBuf
=LookupBuffer(device
->BufferMap
, buffer
)) == NULL
)
552 alSetError(Context
, AL_INVALID_NAME
);
553 else if(length
< 0 || offset
< 0 || (length
> 0 && data
== NULL
))
554 alSetError(Context
, AL_INVALID_VALUE
);
555 else if(ALBuf
->eOriginalFormat
!= format
)
556 alSetError(Context
, AL_INVALID_ENUM
);
557 else if(offset
> ALBuf
->OriginalSize
||
558 length
> ALBuf
->OriginalSize
-offset
||
559 (offset
%ALBuf
->OriginalAlign
) != 0 ||
560 (length
%ALBuf
->OriginalAlign
) != 0)
561 alSetError(Context
, AL_INVALID_VALUE
);
564 case AL_FORMAT_MONO8
:
565 case AL_FORMAT_MONO16
:
566 case AL_FORMAT_MONO_FLOAT32
:
567 case AL_FORMAT_MONO_DOUBLE_EXT
:
568 case AL_FORMAT_STEREO8
:
569 case AL_FORMAT_STEREO16
:
570 case AL_FORMAT_STEREO_FLOAT32
:
571 case AL_FORMAT_STEREO_DOUBLE_EXT
:
572 case AL_FORMAT_QUAD8_LOKI
:
573 case AL_FORMAT_QUAD16_LOKI
:
574 case AL_FORMAT_QUAD8
:
575 case AL_FORMAT_QUAD16
:
576 case AL_FORMAT_QUAD32
:
577 case AL_FORMAT_51CHN8
:
578 case AL_FORMAT_51CHN16
:
579 case AL_FORMAT_51CHN32
:
580 case AL_FORMAT_61CHN8
:
581 case AL_FORMAT_61CHN16
:
582 case AL_FORMAT_61CHN32
:
583 case AL_FORMAT_71CHN8
:
584 case AL_FORMAT_71CHN16
:
585 case AL_FORMAT_71CHN32
: {
586 ALuint OldBytes
= aluBytesFromFormat(format
);
587 ALuint Bytes
= aluBytesFromFormat(ALBuf
->format
);
588 enum SrcFmtChannels SrcChannels
;
589 enum SrcFmtType SrcType
;
595 DecomposeInputFormat(format
, &SrcType
, &SrcChannels
);
596 ConvertData(&((ALubyte
*)ALBuf
->data
)[offset
], data
, SrcType
, length
);
599 case AL_FORMAT_REAR8
:
600 case AL_FORMAT_REAR16
:
601 case AL_FORMAT_REAR32
: {
602 ALuint OldBytes
= ((format
==AL_FORMAT_REAR8
) ? 1 :
603 ((format
==AL_FORMAT_REAR16
) ? 2 : 4));
604 ALuint Bytes
= aluBytesFromFormat(ALBuf
->format
);
612 ConvertDataRear(&((ALubyte
*)ALBuf
->data
)[offset
], data
, Bytes
, length
);
615 case AL_FORMAT_MONO_IMA4
:
616 case AL_FORMAT_STEREO_IMA4
: {
617 ALuint Channels
= aluChannelsFromFormat(ALBuf
->format
);
618 ALuint Bytes
= aluBytesFromFormat(ALBuf
->format
);
620 /* offset -> byte offset, length -> block count */
624 length
/= ALBuf
->OriginalAlign
;
626 ConvertDataIMA4(&((ALubyte
*)ALBuf
->data
)[offset
], data
, Channels
, length
);
629 case AL_FORMAT_MONO_MULAW
:
630 case AL_FORMAT_STEREO_MULAW
:
631 case AL_FORMAT_QUAD_MULAW
:
632 case AL_FORMAT_51CHN_MULAW
:
633 case AL_FORMAT_61CHN_MULAW
:
634 case AL_FORMAT_71CHN_MULAW
: {
635 ALuint Bytes
= aluBytesFromFormat(ALBuf
->format
);
639 ConvertDataMULaw(&((ALubyte
*)ALBuf
->data
)[offset
], data
, length
);
642 case AL_FORMAT_REAR_MULAW
: {
643 ALuint Bytes
= aluBytesFromFormat(ALBuf
->format
);
649 ConvertDataMULawRear(&((ALubyte
*)ALBuf
->data
)[offset
], data
, length
);
653 alSetError(Context
, AL_INVALID_ENUM
);
657 ProcessContext(Context
);
660 AL_API ALvoid AL_APIENTRY
alBufferSubDataEXT(ALuint buffer
,ALenum format
,const ALvoid
*data
,ALsizei offset
,ALsizei length
)
662 alBufferSubDataSOFT(buffer
, format
, data
, offset
, length
);
666 AL_API
void AL_APIENTRY
alBufferf(ALuint buffer
, ALenum eParam
, ALfloat flValue
)
668 ALCcontext
*pContext
;
673 pContext
= GetContextSuspended();
674 if(!pContext
) return;
676 device
= pContext
->Device
;
677 if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
678 alSetError(pContext
, AL_INVALID_NAME
);
684 alSetError(pContext
, AL_INVALID_ENUM
);
689 ProcessContext(pContext
);
693 AL_API
void AL_APIENTRY
alBuffer3f(ALuint buffer
, ALenum eParam
, ALfloat flValue1
, ALfloat flValue2
, ALfloat flValue3
)
695 ALCcontext
*pContext
;
702 pContext
= GetContextSuspended();
703 if(!pContext
) return;
705 device
= pContext
->Device
;
706 if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
707 alSetError(pContext
, AL_INVALID_NAME
);
713 alSetError(pContext
, AL_INVALID_ENUM
);
718 ProcessContext(pContext
);
722 AL_API
void AL_APIENTRY
alBufferfv(ALuint buffer
, ALenum eParam
, const ALfloat
* flValues
)
724 ALCcontext
*pContext
;
727 pContext
= GetContextSuspended();
728 if(!pContext
) return;
730 device
= pContext
->Device
;
732 alSetError(pContext
, AL_INVALID_VALUE
);
733 else if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
734 alSetError(pContext
, AL_INVALID_NAME
);
740 alSetError(pContext
, AL_INVALID_ENUM
);
745 ProcessContext(pContext
);
749 AL_API
void AL_APIENTRY
alBufferi(ALuint buffer
, ALenum eParam
, ALint lValue
)
751 ALCcontext
*pContext
;
756 pContext
= GetContextSuspended();
757 if(!pContext
) return;
759 device
= pContext
->Device
;
760 if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
761 alSetError(pContext
, AL_INVALID_NAME
);
767 alSetError(pContext
, AL_INVALID_ENUM
);
772 ProcessContext(pContext
);
776 AL_API
void AL_APIENTRY
alBuffer3i( ALuint buffer
, ALenum eParam
, ALint lValue1
, ALint lValue2
, ALint lValue3
)
778 ALCcontext
*pContext
;
785 pContext
= GetContextSuspended();
786 if(!pContext
) return;
788 device
= pContext
->Device
;
789 if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
790 alSetError(pContext
, AL_INVALID_NAME
);
796 alSetError(pContext
, AL_INVALID_ENUM
);
801 ProcessContext(pContext
);
805 AL_API
void AL_APIENTRY
alBufferiv(ALuint buffer
, ALenum eParam
, const ALint
* plValues
)
807 ALCcontext
*pContext
;
811 pContext
= GetContextSuspended();
812 if(!pContext
) return;
814 device
= pContext
->Device
;
816 alSetError(pContext
, AL_INVALID_VALUE
);
817 else if((ALBuf
=LookupBuffer(device
->BufferMap
, buffer
)) == NULL
)
818 alSetError(pContext
, AL_INVALID_NAME
);
824 if(ALBuf
->refcount
> 0)
825 alSetError(pContext
, AL_INVALID_OPERATION
);
826 else if(plValues
[0] < 0 || plValues
[1] < 0 ||
827 plValues
[0] >= plValues
[1] || ALBuf
->size
== 0)
828 alSetError(pContext
, AL_INVALID_VALUE
);
831 ALint maxlen
= ALBuf
->size
/ aluFrameSizeFromFormat(ALBuf
->format
);
832 if(plValues
[0] > maxlen
|| plValues
[1] > maxlen
)
833 alSetError(pContext
, AL_INVALID_VALUE
);
836 ALBuf
->LoopStart
= plValues
[0];
837 ALBuf
->LoopEnd
= plValues
[1];
843 alSetError(pContext
, AL_INVALID_ENUM
);
848 ProcessContext(pContext
);
852 AL_API ALvoid AL_APIENTRY
alGetBufferf(ALuint buffer
, ALenum eParam
, ALfloat
*pflValue
)
854 ALCcontext
*pContext
;
857 pContext
= GetContextSuspended();
858 if(!pContext
) return;
860 device
= pContext
->Device
;
862 alSetError(pContext
, AL_INVALID_VALUE
);
863 else if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
864 alSetError(pContext
, AL_INVALID_NAME
);
870 alSetError(pContext
, AL_INVALID_ENUM
);
875 ProcessContext(pContext
);
879 AL_API
void AL_APIENTRY
alGetBuffer3f(ALuint buffer
, ALenum eParam
, ALfloat
* pflValue1
, ALfloat
* pflValue2
, ALfloat
* pflValue3
)
881 ALCcontext
*pContext
;
884 pContext
= GetContextSuspended();
885 if(!pContext
) return;
887 device
= pContext
->Device
;
888 if(!pflValue1
|| !pflValue2
|| !pflValue3
)
889 alSetError(pContext
, AL_INVALID_VALUE
);
890 else if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
891 alSetError(pContext
, AL_INVALID_NAME
);
897 alSetError(pContext
, AL_INVALID_ENUM
);
902 ProcessContext(pContext
);
906 AL_API
void AL_APIENTRY
alGetBufferfv(ALuint buffer
, ALenum eParam
, ALfloat
* pflValues
)
908 ALCcontext
*pContext
;
911 pContext
= GetContextSuspended();
912 if(!pContext
) return;
914 device
= pContext
->Device
;
916 alSetError(pContext
, AL_INVALID_VALUE
);
917 else if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
918 alSetError(pContext
, AL_INVALID_NAME
);
924 alSetError(pContext
, AL_INVALID_ENUM
);
929 ProcessContext(pContext
);
933 AL_API ALvoid AL_APIENTRY
alGetBufferi(ALuint buffer
, ALenum eParam
, ALint
*plValue
)
935 ALCcontext
*pContext
;
939 pContext
= GetContextSuspended();
940 if(!pContext
) return;
942 device
= pContext
->Device
;
944 alSetError(pContext
, AL_INVALID_VALUE
);
945 else if((pBuffer
=LookupBuffer(device
->BufferMap
, buffer
)) == NULL
)
946 alSetError(pContext
, AL_INVALID_NAME
);
952 *plValue
= pBuffer
->frequency
;
956 *plValue
= aluBytesFromFormat(pBuffer
->format
) * 8;
960 *plValue
= aluChannelsFromFormat(pBuffer
->format
);
964 *plValue
= pBuffer
->size
;
968 alSetError(pContext
, AL_INVALID_ENUM
);
973 ProcessContext(pContext
);
977 AL_API
void AL_APIENTRY
alGetBuffer3i(ALuint buffer
, ALenum eParam
, ALint
* plValue1
, ALint
* plValue2
, ALint
* plValue3
)
979 ALCcontext
*pContext
;
982 pContext
= GetContextSuspended();
983 if(!pContext
) return;
985 device
= pContext
->Device
;
986 if(!plValue1
|| !plValue2
|| !plValue3
)
987 alSetError(pContext
, AL_INVALID_VALUE
);
988 else if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
989 alSetError(pContext
, AL_INVALID_NAME
);
995 alSetError(pContext
, AL_INVALID_ENUM
);
1000 ProcessContext(pContext
);
1004 AL_API
void AL_APIENTRY
alGetBufferiv(ALuint buffer
, ALenum eParam
, ALint
* plValues
)
1006 ALCcontext
*pContext
;
1010 pContext
= GetContextSuspended();
1011 if(!pContext
) return;
1013 device
= pContext
->Device
;
1015 alSetError(pContext
, AL_INVALID_VALUE
);
1016 else if((ALBuf
=LookupBuffer(device
->BufferMap
, buffer
)) == NULL
)
1017 alSetError(pContext
, AL_INVALID_NAME
);
1026 alGetBufferi(buffer
, eParam
, plValues
);
1029 case AL_LOOP_POINTS
:
1030 plValues
[0] = ALBuf
->LoopStart
;
1031 plValues
[1] = ALBuf
->LoopEnd
;
1035 alSetError(pContext
, AL_INVALID_ENUM
);
1040 ProcessContext(pContext
);
1046 * Loads the specified data into the buffer, using the specified formats.
1047 * Currently, the new format must have the same channel configuration as the
1048 * original format, and must have the same sample format (except for double,
1049 * which converts to float). This does NOT handle compressed formats (eg. IMA4
1052 static ALenum
LoadData(ALbuffer
*ALBuf
, const ALvoid
*data
, ALsizei size
, ALuint freq
, ALenum OrigFormat
, ALenum NewFormat
)
1054 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
1055 ALuint NewChannels
= aluChannelsFromFormat(NewFormat
);
1056 ALuint OrigBytes
= aluBytesFromFormat(OrigFormat
);
1057 ALuint OrigChannels
= aluChannelsFromFormat(OrigFormat
);
1058 enum SrcFmtChannels SrcChannels
;
1059 enum FmtChannels DstChannels
;
1060 enum SrcFmtType SrcType
;
1061 enum FmtType DstType
;
1065 assert(NewChannels
== OrigChannels
);
1066 assert(NewBytes
== OrigBytes
);
1068 DecomposeInputFormat(OrigFormat
, &SrcType
, &SrcChannels
);
1069 DecomposeFormat(NewFormat
, &DstType
, &DstChannels
);
1071 if((size
%(OrigBytes
*OrigChannels
)) != 0)
1072 return AL_INVALID_VALUE
;
1074 newsize
= size
/ OrigBytes
;
1075 newsize
*= NewBytes
;
1076 if(newsize
> INT_MAX
)
1077 return AL_OUT_OF_MEMORY
;
1079 temp
= realloc(ALBuf
->data
, newsize
);
1080 if(!temp
) return AL_OUT_OF_MEMORY
;
1083 // Samples are converted here
1084 ConvertData(ALBuf
->data
, data
, SrcType
, newsize
/NewBytes
);
1086 ALBuf
->format
= NewFormat
;
1087 ALBuf
->eOriginalFormat
= OrigFormat
;
1088 ALBuf
->size
= newsize
;
1089 ALBuf
->frequency
= freq
;
1091 ALBuf
->LoopStart
= 0;
1092 ALBuf
->LoopEnd
= newsize
/ NewChannels
/ NewBytes
;
1094 ALBuf
->FmtType
= DstType
;
1095 ALBuf
->FmtChannels
= DstChannels
;
1097 ALBuf
->OriginalSize
= size
;
1098 ALBuf
->OriginalAlign
= OrigBytes
* OrigChannels
;
1103 static void ConvertData(ALvoid
*dst
, const ALvoid
*src
, enum SrcFmtType srcType
, ALsizei len
)
1110 case SrcFmtByte
: /* signed byte -> unsigned byte */
1111 for(i
= 0;i
< len
;i
++)
1112 ((ALubyte
*)dst
)[i
] = ((ALbyte
*)src
)[i
] ^ 0x80;
1116 for(i
= 0;i
< len
;i
++)
1117 ((ALubyte
*)dst
)[i
] = ((ALubyte
*)src
)[i
];
1121 for(i
= 0;i
< len
;i
++)
1122 ((ALshort
*)dst
)[i
] = ((ALshort
*)src
)[i
];
1125 case SrcFmtUShort
: /* unsigned short -> signed short */
1126 for(i
= 0;i
< len
;i
++)
1127 ((ALshort
*)dst
)[i
] = ((ALushort
*)src
)[i
] ^ 0x8000;
1131 for(i
= 0;i
< len
;i
++)
1132 ((ALfloat
*)dst
)[i
] = ((ALfloat
*)src
)[i
];
1136 for(i
= 0;i
< len
;i
++)
1137 ((ALdouble
*)dst
)[i
] = ((ALdouble
*)src
)[i
];
1142 static void ConvertDataRear(ALvoid
*dst
, const ALvoid
*src
, ALint origBytes
, ALsizei len
)
1150 for(i
= 0;i
< len
;i
+=4)
1152 ((ALubyte
*)dst
)[i
+0] = 0;
1153 ((ALubyte
*)dst
)[i
+1] = 0;
1154 ((ALubyte
*)dst
)[i
+2] = ((ALubyte
*)src
)[i
/2+0];
1155 ((ALubyte
*)dst
)[i
+3] = ((ALubyte
*)src
)[i
/2+1];
1160 for(i
= 0;i
< len
;i
+=4)
1162 ((ALshort
*)dst
)[i
+0] = 0;
1163 ((ALshort
*)dst
)[i
+1] = 0;
1164 ((ALshort
*)dst
)[i
+2] = ((ALshort
*)src
)[i
/2+0];
1165 ((ALshort
*)dst
)[i
+3] = ((ALshort
*)src
)[i
/2+1];
1170 for(i
= 0;i
< len
;i
+=4)
1172 ((ALfloat
*)dst
)[i
+0] = 0.f
;
1173 ((ALfloat
*)dst
)[i
+1] = 0.f
;
1174 ((ALfloat
*)dst
)[i
+2] = ((ALfloat
*)src
)[i
/2+0];
1175 ((ALfloat
*)dst
)[i
+3] = ((ALfloat
*)src
)[i
/2+1];
1184 static void ConvertDataIMA4(ALvoid
*dst
, const ALvoid
*src
, ALint chans
, ALsizei len
)
1186 const ALubyte
*IMAData
;
1187 ALint Sample
[2],Index
[2];
1195 for(i
= 0;i
< len
;i
++)
1197 for(c
= 0;c
< chans
;c
++)
1199 Sample
[c
] = *(IMAData
++);
1200 Sample
[c
] |= *(IMAData
++) << 8;
1201 Sample
[c
] = (Sample
[c
]^0x8000) - 32768;
1202 Index
[c
] = *(IMAData
++);
1203 Index
[c
] |= *(IMAData
++) << 8;
1204 Index
[c
] = (Index
[c
]^0x8000) - 32768;
1206 Index
[c
] = ((Index
[c
]<0) ? 0 : Index
[c
]);
1207 Index
[c
] = ((Index
[c
]>88) ? 88 : Index
[c
]);
1209 ((ALshort
*)dst
)[i
*65*chans
+ c
] = Sample
[c
];
1212 for(j
= 1;j
< 65;j
+= 8)
1214 for(c
= 0;c
< chans
;c
++)
1216 IMACode
[c
] = *(IMAData
++);
1217 IMACode
[c
] |= *(IMAData
++) << 8;
1218 IMACode
[c
] |= *(IMAData
++) << 16;
1219 IMACode
[c
] |= *(IMAData
++) << 24;
1222 for(k
= 0;k
< 8;k
++)
1224 for(c
= 0;c
< chans
;c
++)
1226 Sample
[c
] += ((g_IMAStep_size
[Index
[c
]]*g_IMACodeword_4
[IMACode
[c
]&15])/8);
1227 Index
[c
] += g_IMAIndex_adjust_4
[IMACode
[c
]&15];
1229 if(Sample
[c
] < -32768) Sample
[c
] = -32768;
1230 else if(Sample
[c
] > 32767) Sample
[c
] = 32767;
1232 if(Index
[c
]<0) Index
[c
] = 0;
1233 else if(Index
[c
]>88) Index
[c
] = 88;
1235 ((ALshort
*)dst
)[(i
*65+j
+k
)*chans
+ c
] = Sample
[c
];
1243 static void ConvertDataMULaw(ALvoid
*dst
, const ALvoid
*src
, ALsizei len
)
1248 for(i
= 0;i
< len
;i
++)
1249 ((ALshort
*)dst
)[i
] = muLawDecompressionTable
[((ALubyte
*)src
)[i
]];
1252 static void ConvertDataMULawRear(ALvoid
*dst
, const ALvoid
*src
, ALsizei len
)
1257 for(i
= 0;i
< len
;i
+=4)
1259 ((ALshort
*)dst
)[i
+0] = 0;
1260 ((ALshort
*)dst
)[i
+1] = 0;
1261 ((ALshort
*)dst
)[i
+2] = muLawDecompressionTable
[((ALubyte
*)src
)[i
/2+0]];
1262 ((ALshort
*)dst
)[i
+3] = muLawDecompressionTable
[((ALubyte
*)src
)[i
/2+1]];
1267 void DecomposeInputFormat(ALenum format
, enum SrcFmtType
*type
,
1268 enum SrcFmtChannels
*order
)
1272 case AL_FORMAT_MONO8
:
1273 *type
= SrcFmtUByte
;
1274 *order
= SrcFmtMono
;
1276 case AL_FORMAT_MONO16
:
1277 *type
= SrcFmtShort
;
1278 *order
= SrcFmtMono
;
1280 case AL_FORMAT_MONO_FLOAT32
:
1281 *type
= SrcFmtFloat
;
1282 *order
= SrcFmtMono
;
1284 case AL_FORMAT_MONO_DOUBLE_EXT
:
1285 *type
= SrcFmtDouble
;
1286 *order
= SrcFmtMono
;
1288 case AL_FORMAT_STEREO8
:
1289 *type
= SrcFmtUByte
;
1290 *order
= SrcFmtStereo
;
1292 case AL_FORMAT_STEREO16
:
1293 *type
= SrcFmtShort
;
1294 *order
= SrcFmtStereo
;
1296 case AL_FORMAT_STEREO_FLOAT32
:
1297 *type
= SrcFmtFloat
;
1298 *order
= SrcFmtStereo
;
1300 case AL_FORMAT_STEREO_DOUBLE_EXT
:
1301 *type
= SrcFmtDouble
;
1302 *order
= SrcFmtStereo
;
1304 case AL_FORMAT_QUAD8_LOKI
:
1305 case AL_FORMAT_QUAD8
:
1306 *type
= SrcFmtUByte
;
1307 *order
= SrcFmtQuad
;
1309 case AL_FORMAT_QUAD16_LOKI
:
1310 case AL_FORMAT_QUAD16
:
1311 *type
= SrcFmtShort
;
1312 *order
= SrcFmtQuad
;
1314 case AL_FORMAT_QUAD32
:
1315 *type
= SrcFmtFloat
;
1316 *order
= SrcFmtQuad
;
1318 case AL_FORMAT_51CHN8
:
1319 *type
= SrcFmtUByte
;
1322 case AL_FORMAT_51CHN16
:
1323 *type
= SrcFmtShort
;
1326 case AL_FORMAT_51CHN32
:
1327 *type
= SrcFmtFloat
;
1330 case AL_FORMAT_61CHN8
:
1331 *type
= SrcFmtUByte
;
1334 case AL_FORMAT_61CHN16
:
1335 *type
= SrcFmtShort
;
1338 case AL_FORMAT_61CHN32
:
1339 *type
= SrcFmtFloat
;
1342 case AL_FORMAT_71CHN8
:
1343 *type
= SrcFmtUByte
;
1346 case AL_FORMAT_71CHN16
:
1347 *type
= SrcFmtShort
;
1350 case AL_FORMAT_71CHN32
:
1351 *type
= SrcFmtFloat
;
1356 AL_PRINT("Unhandled format specified: 0x%X\n", format
);
1361 void DecomposeFormat(ALenum format
, enum FmtType
*type
, enum FmtChannels
*order
)
1365 case AL_FORMAT_MONO8
:
1369 case AL_FORMAT_MONO16
:
1373 case AL_FORMAT_MONO_FLOAT32
:
1377 case AL_FORMAT_MONO_DOUBLE_EXT
:
1381 case AL_FORMAT_STEREO8
:
1385 case AL_FORMAT_STEREO16
:
1389 case AL_FORMAT_STEREO_FLOAT32
:
1393 case AL_FORMAT_STEREO_DOUBLE_EXT
:
1397 case AL_FORMAT_QUAD8_LOKI
:
1398 case AL_FORMAT_QUAD8
:
1402 case AL_FORMAT_QUAD16_LOKI
:
1403 case AL_FORMAT_QUAD16
:
1407 case AL_FORMAT_QUAD32
:
1411 case AL_FORMAT_51CHN8
:
1413 *order
= Fmt51ChanWFX
;
1415 case AL_FORMAT_51CHN16
:
1417 *order
= Fmt51ChanWFX
;
1419 case AL_FORMAT_51CHN32
:
1421 *order
= Fmt51ChanWFX
;
1423 case AL_FORMAT_61CHN8
:
1425 *order
= Fmt61ChanWFX
;
1427 case AL_FORMAT_61CHN16
:
1429 *order
= Fmt61ChanWFX
;
1431 case AL_FORMAT_61CHN32
:
1433 *order
= Fmt61ChanWFX
;
1435 case AL_FORMAT_71CHN8
:
1437 *order
= Fmt71ChanWFX
;
1439 case AL_FORMAT_71CHN16
:
1441 *order
= Fmt71ChanWFX
;
1443 case AL_FORMAT_71CHN32
:
1445 *order
= Fmt71ChanWFX
;
1449 AL_PRINT("Unhandled format specified: 0x%X\n", format
);
1456 * ReleaseALBuffers()
1458 * INTERNAL FN : Called by alcCloseDevice to destroy any buffers that still exist
1460 ALvoid
ReleaseALBuffers(ALCdevice
*device
)
1463 for(i
= 0;i
< device
->BufferMap
.size
;i
++)
1465 ALbuffer
*temp
= device
->BufferMap
.array
[i
].value
;
1466 device
->BufferMap
.array
[i
].value
= NULL
;
1468 // Release sample data
1471 // Release Buffer structure
1472 ALTHUNK_REMOVEENTRY(temp
->buffer
);
1473 memset(temp
, 0, sizeof(ALbuffer
));