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(ALfloat
*dst
, const ALvoid
*src
, ALint origBytes
, ALsizei len
);
39 static void ConvertDataRear(ALfloat
*dst
, const ALvoid
*src
, ALint origBytes
, ALsizei len
);
40 static void ConvertDataIMA4(ALfloat
*dst
, const ALvoid
*src
, ALint origChans
, ALsizei len
);
41 static void ConvertDataMULaw(ALfloat
*dst
, const ALvoid
*src
, ALsizei len
);
42 static void ConvertDataMULawRear(ALfloat
*dst
, const ALvoid
*src
, ALsizei len
);
44 #define LookupBuffer(m, k) ((ALbuffer*)LookupUIntMapKey(&(m), (k)))
50 static const long g_IMAStep_size
[89]={ // IMA ADPCM Stepsize table
51 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
52 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
53 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
54 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
55 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493,10442,11487,12635,13899,
56 15289,16818,18500,20350,22358,24633,27086,29794,32767
59 static const long g_IMACodeword_4
[16]={ // IMA4 ADPCM Codeword decode table
60 1, 3, 5, 7, 9, 11, 13, 15,
61 -1,-3,-5,-7,-9,-11,-13,-15,
64 static const long g_IMAIndex_adjust_4
[16]={ // IMA4 ADPCM Step index adjust decode table
65 -1,-1,-1,-1, 2, 4, 6, 8,
66 -1,-1,-1,-1, 2, 4, 6, 8
69 static const ALshort muLawDecompressionTable
[256] = {
70 -32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956,
71 -23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764,
72 -15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412,
73 -11900,-11388,-10876,-10364, -9852, -9340, -8828, -8316,
74 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
75 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
76 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
77 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
78 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
79 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
80 -876, -844, -812, -780, -748, -716, -684, -652,
81 -620, -588, -556, -524, -492, -460, -428, -396,
82 -372, -356, -340, -324, -308, -292, -276, -260,
83 -244, -228, -212, -196, -180, -164, -148, -132,
84 -120, -112, -104, -96, -88, -80, -72, -64,
85 -56, -48, -40, -32, -24, -16, -8, 0,
86 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
87 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
88 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
89 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
90 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
91 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
92 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
93 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
94 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
95 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
96 876, 844, 812, 780, 748, 716, 684, 652,
97 620, 588, 556, 524, 492, 460, 428, 396,
98 372, 356, 340, 324, 308, 292, 276, 260,
99 244, 228, 212, 196, 180, 164, 148, 132,
100 120, 112, 104, 96, 88, 80, 72, 64,
101 56, 48, 40, 32, 24, 16, 8, 0
105 * alGenBuffers(ALsizei n, ALuint *puiBuffers)
107 * Generates n AL Buffers, and stores the Buffers Names in the array pointed to by puiBuffers
109 AL_API ALvoid AL_APIENTRY
alGenBuffers(ALsizei n
, ALuint
*buffers
)
114 Context
= GetContextSuspended();
117 // Check that we are actually generation some Buffers
120 ALCdevice
*device
= Context
->Device
;
123 // Check the pointer is valid (and points to enough memory to store Buffer Names)
124 if(IsBadWritePtr((void*)buffers
, n
* sizeof(ALuint
)))
125 alSetError(Context
, AL_INVALID_VALUE
);
128 // Create all the new Buffers
131 ALbuffer
*buffer
= calloc(1, sizeof(ALbuffer
));
134 alSetError(Context
, AL_OUT_OF_MEMORY
);
135 alDeleteBuffers(i
, buffers
);
139 buffer
->buffer
= (ALuint
)ALTHUNK_ADDENTRY(buffer
);
140 err
= InsertUIntMapEntry(&device
->BufferMap
, buffer
->buffer
,
142 if(err
!= AL_NO_ERROR
)
144 ALTHUNK_REMOVEENTRY(buffer
->buffer
);
145 memset(buffer
, 0, sizeof(ALbuffer
));
148 alSetError(Context
, err
);
149 alDeleteBuffers(i
, buffers
);
152 buffers
[i
++] = buffer
->buffer
;
157 ProcessContext(Context
);
161 * alDeleteBuffers(ALsizei n, ALuint *puiBuffers)
163 * Deletes the n AL Buffers pointed to by puiBuffers
165 AL_API ALvoid AL_APIENTRY
alDeleteBuffers(ALsizei n
, const ALuint
*puiBuffers
)
171 Context
= GetContextSuspended();
174 // Check we are actually Deleting some Buffers
176 alSetError(Context
, AL_INVALID_VALUE
);
179 ALCdevice
*device
= Context
->Device
;
180 ALboolean bFailed
= AL_FALSE
;
182 // Check that all the buffers are valid and can actually be deleted
183 for (i
= 0; i
< n
; i
++)
188 // Check for valid Buffer ID (can be NULL buffer)
189 if((ALBuf
=LookupBuffer(device
->BufferMap
, puiBuffers
[i
])) != NULL
)
191 if(ALBuf
->refcount
!= 0)
193 // Buffer still in use, cannot be deleted
194 alSetError(Context
, AL_INVALID_OPERATION
);
202 alSetError(Context
, AL_INVALID_NAME
);
208 // If all the Buffers were valid (and have Reference Counts of 0), then we can delete them
211 for (i
= 0; i
< n
; i
++)
213 if((ALBuf
=LookupBuffer(device
->BufferMap
, puiBuffers
[i
])) != NULL
)
215 // Release the memory used to store audio data
218 // Release buffer structure
219 RemoveUIntMapKey(&device
->BufferMap
, ALBuf
->buffer
);
220 ALTHUNK_REMOVEENTRY(ALBuf
->buffer
);
222 memset(ALBuf
, 0, sizeof(ALbuffer
));
229 ProcessContext(Context
);
233 * alIsBuffer(ALuint uiBuffer)
235 * Checks if ulBuffer is a valid Buffer Name
237 AL_API ALboolean AL_APIENTRY
alIsBuffer(ALuint buffer
)
242 Context
= GetContextSuspended();
243 if(!Context
) return AL_FALSE
;
245 result
= ((!buffer
|| LookupBuffer(Context
->Device
->BufferMap
, buffer
)) ?
248 ProcessContext(Context
);
254 * alBufferData(ALuint buffer,ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
256 * Fill buffer with audio data
258 AL_API ALvoid AL_APIENTRY
alBufferData(ALuint buffer
,ALenum format
,const ALvoid
*data
,ALsizei size
,ALsizei freq
)
266 Context
= GetContextSuspended();
269 device
= Context
->Device
;
270 if((ALBuf
=LookupBuffer(device
->BufferMap
, buffer
)) == NULL
)
271 alSetError(Context
, AL_INVALID_NAME
); /* Invalid Buffer Name */
274 if(Context
->SampleSource
)
278 if(Context
->SampleSource
->state
== MAPPED
)
280 alSetError(Context
, AL_INVALID_OPERATION
);
281 ProcessContext(Context
);
285 offset
= (const ALubyte
*)data
- (ALubyte
*)NULL
;
286 data
= Context
->SampleSource
->data
+ offset
;
290 alSetError(Context
, AL_INVALID_VALUE
);
291 else if(ALBuf
->refcount
!= 0)
292 alSetError(Context
, AL_INVALID_VALUE
);
297 case AL_FORMAT_MONO8
:
298 case AL_FORMAT_MONO16
:
299 case AL_FORMAT_MONO_FLOAT32
:
300 case AL_FORMAT_MONO_DOUBLE_EXT
:
301 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_MONO_FLOAT32
);
302 if(err
!= AL_NO_ERROR
)
303 alSetError(Context
, err
);
306 case AL_FORMAT_STEREO8
:
307 case AL_FORMAT_STEREO16
:
308 case AL_FORMAT_STEREO_FLOAT32
:
309 case AL_FORMAT_STEREO_DOUBLE_EXT
:
310 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_STEREO_FLOAT32
);
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 ALenum NewFormat
= AL_FORMAT_QUAD32
;
319 ALuint NewChannels
= aluChannelsFromFormat(NewFormat
);
320 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
321 ALuint OrigBytes
= ((format
==AL_FORMAT_REAR8
) ? 1 :
322 ((format
==AL_FORMAT_REAR16
) ? 2 :
324 ALuint64 newsize
, allocsize
;
326 if((size
%(OrigBytes
*2)) != 0)
328 alSetError(Context
, AL_INVALID_VALUE
);
332 newsize
= size
/ OrigBytes
;
335 allocsize
= (BUFFER_PADDING
*NewChannels
+ newsize
)*NewBytes
;
336 if(allocsize
> INT_MAX
)
338 alSetError(Context
, AL_OUT_OF_MEMORY
);
341 temp
= realloc(ALBuf
->data
, allocsize
);
345 ConvertDataRear(ALBuf
->data
, data
, OrigBytes
, newsize
);
347 ALBuf
->format
= NewFormat
;
348 ALBuf
->eOriginalFormat
= format
;
349 ALBuf
->size
= newsize
*NewBytes
;
350 ALBuf
->frequency
= freq
;
352 ALBuf
->LoopStart
= 0;
353 ALBuf
->LoopEnd
= newsize
/ NewChannels
;
355 ALBuf
->OriginalSize
= size
;
356 ALBuf
->OriginalAlign
= OrigBytes
* 2;
359 alSetError(Context
, AL_OUT_OF_MEMORY
);
362 case AL_FORMAT_QUAD8_LOKI
:
363 case AL_FORMAT_QUAD16_LOKI
:
364 case AL_FORMAT_QUAD8
:
365 case AL_FORMAT_QUAD16
:
366 case AL_FORMAT_QUAD32
:
367 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_QUAD32
);
368 if(err
!= AL_NO_ERROR
)
369 alSetError(Context
, err
);
372 case AL_FORMAT_51CHN8
:
373 case AL_FORMAT_51CHN16
:
374 case AL_FORMAT_51CHN32
:
375 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_51CHN32
);
376 if(err
!= AL_NO_ERROR
)
377 alSetError(Context
, err
);
380 case AL_FORMAT_61CHN8
:
381 case AL_FORMAT_61CHN16
:
382 case AL_FORMAT_61CHN32
:
383 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_61CHN32
);
384 if(err
!= AL_NO_ERROR
)
385 alSetError(Context
, err
);
388 case AL_FORMAT_71CHN8
:
389 case AL_FORMAT_71CHN16
:
390 case AL_FORMAT_71CHN32
:
391 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_71CHN32
);
392 if(err
!= AL_NO_ERROR
)
393 alSetError(Context
, err
);
396 case AL_FORMAT_MONO_IMA4
:
397 case AL_FORMAT_STEREO_IMA4
: {
398 int Channels
= ((format
==AL_FORMAT_MONO_IMA4
) ? 1 : 2);
399 ALenum NewFormat
= ((Channels
==1) ? AL_FORMAT_MONO_FLOAT32
:
400 AL_FORMAT_STEREO_FLOAT32
);
401 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
402 ALuint64 newsize
, allocsize
;
404 // Here is where things vary:
405 // nVidia and Apple use 64+1 samples per channel per block => block_size=36*chans bytes
406 // Most PC sound software uses 2040+1 samples per channel per block -> block_size=1024*chans bytes
407 if((size
%(36*Channels
)) != 0)
409 alSetError(Context
, AL_INVALID_VALUE
);
416 allocsize
= (BUFFER_PADDING
*Channels
+ newsize
)*NewBytes
;
417 if(allocsize
> INT_MAX
)
419 alSetError(Context
, AL_OUT_OF_MEMORY
);
422 temp
= realloc(ALBuf
->data
, allocsize
);
426 ConvertDataIMA4(ALBuf
->data
, data
, Channels
, newsize
/(65*Channels
));
428 ALBuf
->format
= NewFormat
;
429 ALBuf
->eOriginalFormat
= format
;
430 ALBuf
->size
= newsize
*NewBytes
;
431 ALBuf
->frequency
= freq
;
433 ALBuf
->LoopStart
= 0;
434 ALBuf
->LoopEnd
= newsize
/ Channels
;
436 ALBuf
->OriginalSize
= size
;
437 ALBuf
->OriginalAlign
= 36 * Channels
;
440 alSetError(Context
, AL_OUT_OF_MEMORY
);
443 case AL_FORMAT_MONO_MULAW
:
444 case AL_FORMAT_STEREO_MULAW
:
445 case AL_FORMAT_QUAD_MULAW
:
446 case AL_FORMAT_51CHN_MULAW
:
447 case AL_FORMAT_61CHN_MULAW
:
448 case AL_FORMAT_71CHN_MULAW
: {
449 int Channels
= ((format
==AL_FORMAT_MONO_MULAW
) ? 1 :
450 ((format
==AL_FORMAT_STEREO_MULAW
) ? 2 :
451 ((format
==AL_FORMAT_QUAD_MULAW
) ? 4 :
452 ((format
==AL_FORMAT_51CHN_MULAW
) ? 6 :
453 ((format
==AL_FORMAT_61CHN_MULAW
) ? 7 : 8)))));
454 ALenum NewFormat
= ((Channels
==1) ? AL_FORMAT_MONO_FLOAT32
:
455 ((Channels
==2) ? AL_FORMAT_STEREO_FLOAT32
:
456 ((Channels
==4) ? AL_FORMAT_QUAD32
:
457 ((Channels
==6) ? AL_FORMAT_51CHN32
:
458 ((Channels
==7) ? AL_FORMAT_61CHN32
:
459 AL_FORMAT_71CHN32
)))));
460 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
463 if((size
%(1*Channels
)) != 0)
465 alSetError(Context
, AL_INVALID_VALUE
);
469 allocsize
= (BUFFER_PADDING
*Channels
+ size
)*NewBytes
;
470 if(allocsize
> INT_MAX
)
472 alSetError(Context
, AL_OUT_OF_MEMORY
);
475 temp
= realloc(ALBuf
->data
, allocsize
);
479 ConvertDataMULaw(ALBuf
->data
, data
, size
);
481 ALBuf
->format
= NewFormat
;
482 ALBuf
->eOriginalFormat
= format
;
483 ALBuf
->size
= size
*NewBytes
;
484 ALBuf
->frequency
= freq
;
486 ALBuf
->LoopStart
= 0;
487 ALBuf
->LoopEnd
= size
/ Channels
;
489 ALBuf
->OriginalSize
= size
;
490 ALBuf
->OriginalAlign
= 1 * Channels
;
493 alSetError(Context
, AL_OUT_OF_MEMORY
);
496 case AL_FORMAT_REAR_MULAW
: {
497 ALenum NewFormat
= AL_FORMAT_QUAD32
;
498 ALuint NewChannels
= aluChannelsFromFormat(NewFormat
);
499 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
500 ALuint64 newsize
, allocsize
;
502 if((size
%(1*2)) != 0)
504 alSetError(Context
, AL_INVALID_VALUE
);
510 allocsize
= (BUFFER_PADDING
*NewChannels
+ newsize
)*NewBytes
;
511 if(allocsize
> INT_MAX
)
513 alSetError(Context
, AL_OUT_OF_MEMORY
);
516 temp
= realloc(ALBuf
->data
, allocsize
);
520 ConvertDataMULawRear(ALBuf
->data
, data
, newsize
);
522 ALBuf
->format
= NewFormat
;
523 ALBuf
->eOriginalFormat
= format
;
524 ALBuf
->size
= newsize
*NewBytes
;
525 ALBuf
->frequency
= freq
;
527 ALBuf
->LoopStart
= 0;
528 ALBuf
->LoopEnd
= newsize
/ NewChannels
;
530 ALBuf
->OriginalSize
= size
;
531 ALBuf
->OriginalAlign
= 1 * 2;
534 alSetError(Context
, AL_OUT_OF_MEMORY
);
538 alSetError(Context
, AL_INVALID_ENUM
);
544 ProcessContext(Context
);
548 * alBufferSubDataEXT(ALuint buffer,ALenum format,ALvoid *data,ALsizei offset,ALsizei length)
550 * Fill buffer with audio data
552 AL_API ALvoid AL_APIENTRY
alBufferSubDataEXT(ALuint buffer
,ALenum format
,const ALvoid
*data
,ALsizei offset
,ALsizei length
)
558 Context
= GetContextSuspended();
561 device
= Context
->Device
;
562 if((ALBuf
=LookupBuffer(device
->BufferMap
, buffer
)) == NULL
)
563 alSetError(Context
, AL_INVALID_NAME
);
566 if(Context
->SampleSource
)
570 if(Context
->SampleSource
->state
== MAPPED
)
572 alSetError(Context
, AL_INVALID_OPERATION
);
573 ProcessContext(Context
);
577 offset
= (const ALubyte
*)data
- (ALubyte
*)NULL
;
578 data
= Context
->SampleSource
->data
+ offset
;
581 if(length
< 0 || offset
< 0 || (length
> 0 && data
== NULL
))
582 alSetError(Context
, AL_INVALID_VALUE
);
583 else if(ALBuf
->eOriginalFormat
!= format
)
584 alSetError(Context
, AL_INVALID_ENUM
);
585 else if(offset
+length
< offset
||
586 offset
+length
> ALBuf
->OriginalSize
||
587 (offset
%ALBuf
->OriginalAlign
) != 0 ||
588 (length
%ALBuf
->OriginalAlign
) != 0)
589 alSetError(Context
, AL_INVALID_VALUE
);
594 case AL_FORMAT_MONO8
:
595 case AL_FORMAT_MONO16
:
596 case AL_FORMAT_MONO_FLOAT32
:
597 case AL_FORMAT_MONO_DOUBLE_EXT
:
598 case AL_FORMAT_STEREO8
:
599 case AL_FORMAT_STEREO16
:
600 case AL_FORMAT_STEREO_FLOAT32
:
601 case AL_FORMAT_STEREO_DOUBLE_EXT
:
602 case AL_FORMAT_QUAD8_LOKI
:
603 case AL_FORMAT_QUAD16_LOKI
:
604 case AL_FORMAT_QUAD8
:
605 case AL_FORMAT_QUAD16
:
606 case AL_FORMAT_QUAD32
:
607 case AL_FORMAT_51CHN8
:
608 case AL_FORMAT_51CHN16
:
609 case AL_FORMAT_51CHN32
:
610 case AL_FORMAT_61CHN8
:
611 case AL_FORMAT_61CHN16
:
612 case AL_FORMAT_61CHN32
:
613 case AL_FORMAT_71CHN8
:
614 case AL_FORMAT_71CHN16
:
615 case AL_FORMAT_71CHN32
: {
616 ALuint Bytes
= aluBytesFromFormat(format
);
621 ConvertData(&ALBuf
->data
[offset
], data
, Bytes
, length
);
624 case AL_FORMAT_REAR8
:
625 case AL_FORMAT_REAR16
:
626 case AL_FORMAT_REAR32
: {
627 ALuint Bytes
= ((format
==AL_FORMAT_REAR8
) ? 1 :
628 ((format
==AL_FORMAT_REAR16
) ? 2 :
636 ConvertDataRear(&ALBuf
->data
[offset
], data
, Bytes
, length
);
639 case AL_FORMAT_MONO_IMA4
:
640 case AL_FORMAT_STEREO_IMA4
: {
641 int Channels
= aluChannelsFromFormat(ALBuf
->format
);
643 // offset -> sample*channel offset, length -> block count
646 length
/= ALBuf
->OriginalAlign
;
648 ConvertDataIMA4(&ALBuf
->data
[offset
], data
, Channels
, length
);
651 case AL_FORMAT_MONO_MULAW
:
652 case AL_FORMAT_STEREO_MULAW
:
653 case AL_FORMAT_QUAD_MULAW
:
654 case AL_FORMAT_51CHN_MULAW
:
655 case AL_FORMAT_61CHN_MULAW
:
656 case AL_FORMAT_71CHN_MULAW
:
657 ConvertDataMULaw(&ALBuf
->data
[offset
], data
, length
);
660 case AL_FORMAT_REAR_MULAW
:
663 ConvertDataMULawRear(&ALBuf
->data
[offset
], data
, length
);
667 alSetError(Context
, AL_INVALID_ENUM
);
673 ProcessContext(Context
);
677 AL_API
void AL_APIENTRY
alBufferf(ALuint buffer
, ALenum eParam
, ALfloat flValue
)
679 ALCcontext
*pContext
;
684 pContext
= GetContextSuspended();
685 if(!pContext
) return;
687 device
= pContext
->Device
;
688 if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
689 alSetError(pContext
, AL_INVALID_NAME
);
694 alSetError(pContext
, AL_INVALID_ENUM
);
699 ProcessContext(pContext
);
703 AL_API
void AL_APIENTRY
alBuffer3f(ALuint buffer
, ALenum eParam
, ALfloat flValue1
, ALfloat flValue2
, ALfloat flValue3
)
705 ALCcontext
*pContext
;
712 pContext
= GetContextSuspended();
713 if(!pContext
) return;
715 device
= pContext
->Device
;
716 if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
717 alSetError(pContext
, AL_INVALID_NAME
);
723 alSetError(pContext
, AL_INVALID_ENUM
);
728 ProcessContext(pContext
);
732 AL_API
void AL_APIENTRY
alBufferfv(ALuint buffer
, ALenum eParam
, const ALfloat
* flValues
)
734 ALCcontext
*pContext
;
737 pContext
= GetContextSuspended();
738 if(!pContext
) return;
740 device
= pContext
->Device
;
742 alSetError(pContext
, AL_INVALID_VALUE
);
743 else if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
744 alSetError(pContext
, AL_INVALID_NAME
);
750 alSetError(pContext
, AL_INVALID_ENUM
);
755 ProcessContext(pContext
);
759 AL_API
void AL_APIENTRY
alBufferi(ALuint buffer
, ALenum eParam
, ALint lValue
)
761 ALCcontext
*pContext
;
766 pContext
= GetContextSuspended();
767 if(!pContext
) return;
769 device
= pContext
->Device
;
770 if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
771 alSetError(pContext
, AL_INVALID_NAME
);
777 alSetError(pContext
, AL_INVALID_ENUM
);
782 ProcessContext(pContext
);
786 AL_API
void AL_APIENTRY
alBuffer3i( ALuint buffer
, ALenum eParam
, ALint lValue1
, ALint lValue2
, ALint lValue3
)
788 ALCcontext
*pContext
;
795 pContext
= GetContextSuspended();
796 if(!pContext
) return;
798 device
= pContext
->Device
;
799 if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
800 alSetError(pContext
, AL_INVALID_NAME
);
806 alSetError(pContext
, AL_INVALID_ENUM
);
811 ProcessContext(pContext
);
815 AL_API
void AL_APIENTRY
alBufferiv(ALuint buffer
, ALenum eParam
, const ALint
* plValues
)
817 ALCcontext
*pContext
;
821 pContext
= GetContextSuspended();
822 if(!pContext
) return;
824 device
= pContext
->Device
;
826 alSetError(pContext
, AL_INVALID_VALUE
);
827 else if((ALBuf
=LookupBuffer(device
->BufferMap
, buffer
)) == NULL
)
828 alSetError(pContext
, AL_INVALID_NAME
);
834 if(ALBuf
->refcount
> 0)
835 alSetError(pContext
, AL_INVALID_OPERATION
);
836 else if(plValues
[0] < 0 || plValues
[1] < 0 ||
837 plValues
[0] >= plValues
[1] || ALBuf
->size
== 0)
838 alSetError(pContext
, AL_INVALID_VALUE
);
841 ALint maxlen
= ALBuf
->size
/ aluFrameSizeFromFormat(ALBuf
->format
);
842 if(plValues
[0] > maxlen
|| plValues
[1] > maxlen
)
843 alSetError(pContext
, AL_INVALID_VALUE
);
846 ALBuf
->LoopStart
= plValues
[0];
847 ALBuf
->LoopEnd
= plValues
[1];
853 alSetError(pContext
, AL_INVALID_ENUM
);
858 ProcessContext(pContext
);
862 AL_API ALvoid AL_APIENTRY
alGetBufferf(ALuint buffer
, ALenum eParam
, ALfloat
*pflValue
)
864 ALCcontext
*pContext
;
867 pContext
= GetContextSuspended();
868 if(!pContext
) return;
870 device
= pContext
->Device
;
872 alSetError(pContext
, AL_INVALID_VALUE
);
873 else if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
874 alSetError(pContext
, AL_INVALID_NAME
);
880 alSetError(pContext
, AL_INVALID_ENUM
);
885 ProcessContext(pContext
);
889 AL_API
void AL_APIENTRY
alGetBuffer3f(ALuint buffer
, ALenum eParam
, ALfloat
* pflValue1
, ALfloat
* pflValue2
, ALfloat
* pflValue3
)
891 ALCcontext
*pContext
;
894 pContext
= GetContextSuspended();
895 if(!pContext
) return;
897 device
= pContext
->Device
;
898 if(!pflValue1
|| !pflValue2
|| !pflValue3
)
899 alSetError(pContext
, AL_INVALID_VALUE
);
900 else if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
901 alSetError(pContext
, AL_INVALID_NAME
);
907 alSetError(pContext
, AL_INVALID_ENUM
);
912 ProcessContext(pContext
);
916 AL_API
void AL_APIENTRY
alGetBufferfv(ALuint buffer
, ALenum eParam
, ALfloat
* pflValues
)
918 ALCcontext
*pContext
;
921 pContext
= GetContextSuspended();
922 if(!pContext
) return;
924 device
= pContext
->Device
;
926 alSetError(pContext
, AL_INVALID_VALUE
);
927 else if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
928 alSetError(pContext
, AL_INVALID_NAME
);
934 alSetError(pContext
, AL_INVALID_ENUM
);
939 ProcessContext(pContext
);
943 AL_API ALvoid AL_APIENTRY
alGetBufferi(ALuint buffer
, ALenum eParam
, ALint
*plValue
)
945 ALCcontext
*pContext
;
949 pContext
= GetContextSuspended();
950 if(!pContext
) return;
952 device
= pContext
->Device
;
954 alSetError(pContext
, AL_INVALID_VALUE
);
955 else if((pBuffer
=LookupBuffer(device
->BufferMap
, buffer
)) == NULL
)
956 alSetError(pContext
, AL_INVALID_NAME
);
962 *plValue
= pBuffer
->frequency
;
966 *plValue
= aluBytesFromFormat(pBuffer
->format
) * 8;
970 *plValue
= aluChannelsFromFormat(pBuffer
->format
);
974 *plValue
= pBuffer
->size
;
978 alSetError(pContext
, AL_INVALID_ENUM
);
983 ProcessContext(pContext
);
987 AL_API
void AL_APIENTRY
alGetBuffer3i(ALuint buffer
, ALenum eParam
, ALint
* plValue1
, ALint
* plValue2
, ALint
* plValue3
)
989 ALCcontext
*pContext
;
992 pContext
= GetContextSuspended();
993 if(!pContext
) return;
995 device
= pContext
->Device
;
996 if(!plValue1
|| !plValue2
|| !plValue3
)
997 alSetError(pContext
, AL_INVALID_VALUE
);
998 else if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
999 alSetError(pContext
, AL_INVALID_NAME
);
1005 alSetError(pContext
, AL_INVALID_ENUM
);
1010 ProcessContext(pContext
);
1014 AL_API
void AL_APIENTRY
alGetBufferiv(ALuint buffer
, ALenum eParam
, ALint
* plValues
)
1016 ALCcontext
*pContext
;
1020 pContext
= GetContextSuspended();
1021 if(!pContext
) return;
1023 device
= pContext
->Device
;
1025 alSetError(pContext
, AL_INVALID_VALUE
);
1026 else if((ALBuf
=LookupBuffer(device
->BufferMap
, buffer
)) == NULL
)
1027 alSetError(pContext
, AL_INVALID_NAME
);
1036 alGetBufferi(buffer
, eParam
, plValues
);
1039 case AL_LOOP_POINTS
:
1040 plValues
[0] = ALBuf
->LoopStart
;
1041 plValues
[1] = ALBuf
->LoopEnd
;
1045 alSetError(pContext
, AL_INVALID_ENUM
);
1050 ProcessContext(pContext
);
1056 * Loads the specified data into the buffer, using the specified formats.
1057 * Currently, the new format must be 32-bit float, and must have the same
1058 * channel configuration as the original format. This does NOT handle
1059 * compressed formats (eg. IMA4).
1061 static ALenum
LoadData(ALbuffer
*ALBuf
, const ALvoid
*data
, ALsizei size
, ALuint freq
, ALenum OrigFormat
, ALenum NewFormat
)
1063 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
1064 ALuint NewChannels
= aluChannelsFromFormat(NewFormat
);
1065 ALuint OrigBytes
= aluBytesFromFormat(OrigFormat
);
1066 ALuint OrigChannels
= aluChannelsFromFormat(OrigFormat
);
1067 ALuint64 newsize
, allocsize
;
1070 assert(NewBytes
== 4);
1071 assert(NewChannels
== OrigChannels
);
1073 if ((size
%(OrigBytes
*OrigChannels
)) != 0)
1074 return AL_INVALID_VALUE
;
1076 // Allocate extra padding samples
1077 newsize
= size
/ OrigBytes
;
1078 allocsize
= (BUFFER_PADDING
*NewChannels
+ newsize
)*NewBytes
;
1079 if(allocsize
> INT_MAX
)
1080 return AL_OUT_OF_MEMORY
;
1082 temp
= realloc(ALBuf
->data
, allocsize
);
1083 if(!temp
) return AL_OUT_OF_MEMORY
;
1086 // Samples are converted here
1087 ConvertData(ALBuf
->data
, data
, OrigBytes
, newsize
);
1089 ALBuf
->format
= NewFormat
;
1090 ALBuf
->eOriginalFormat
= OrigFormat
;
1091 ALBuf
->size
= newsize
*NewBytes
;
1092 ALBuf
->frequency
= freq
;
1094 ALBuf
->LoopStart
= 0;
1095 ALBuf
->LoopEnd
= newsize
/ NewChannels
;
1097 ALBuf
->OriginalSize
= size
;
1098 ALBuf
->OriginalAlign
= OrigBytes
* OrigChannels
;
1103 static void ConvertData(ALfloat
*dst
, const ALvoid
*src
, ALint origBytes
, ALsizei len
)
1112 for(i
= 0;i
< len
;i
++)
1114 smp
= ((ALubyte
*)src
)[i
];
1115 dst
[i
] = ((smp
< 0x80) ? ((smp
-128)/128.0f
) : ((smp
-128)/127.0f
));
1120 for(i
= 0;i
< len
;i
++)
1122 smp
= ((ALshort
*)src
)[i
];
1123 dst
[i
] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1128 for(i
= 0;i
< len
;i
++)
1129 dst
[i
] = ((ALfloat
*)src
)[i
];
1133 for(i
= 0;i
< len
;i
++)
1134 dst
[i
] = ((ALdouble
*)src
)[i
];
1142 static void ConvertDataRear(ALfloat
*dst
, const ALvoid
*src
, ALint origBytes
, ALsizei len
)
1151 for(i
= 0;i
< len
;i
+=4)
1155 smp
= ((ALubyte
*)src
)[i
/2+0];
1156 dst
[i
+2] = ((smp
< 0x80) ? ((smp
-128)/128.0f
) : ((smp
-128)/127.0f
));
1157 smp
= ((ALubyte
*)src
)[i
/2+1];
1158 dst
[i
+3] = ((smp
< 0x80) ? ((smp
-128)/128.0f
) : ((smp
-128)/127.0f
));
1163 for(i
= 0;i
< len
;i
+=4)
1167 smp
= ((ALshort
*)src
)[i
/2+0];
1168 dst
[i
+2] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1169 smp
= ((ALshort
*)src
)[i
/2+1];
1170 dst
[i
+3] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1175 for(i
= 0;i
< len
;i
+=4)
1179 dst
[i
+2] = ((ALfloat
*)src
)[i
/2+0];
1180 dst
[i
+3] = ((ALfloat
*)src
)[i
/2+1];
1189 static void ConvertDataIMA4(ALfloat
*dst
, const ALvoid
*src
, ALint chans
, ALsizei len
)
1191 const ALubyte
*IMAData
;
1192 ALint Sample
[2],Index
[2];
1200 for(i
= 0;i
< len
;i
++)
1202 for(c
= 0;c
< chans
;c
++)
1204 Sample
[c
] = *(IMAData
++);
1205 Sample
[c
] |= *(IMAData
++) << 8;
1206 Sample
[c
] = (Sample
[c
]^0x8000) - 32768;
1207 Index
[c
] = *(IMAData
++);
1208 Index
[c
] |= *(IMAData
++) << 8;
1209 Index
[c
] = (Index
[c
]^0x8000) - 32768;
1211 Index
[c
] = ((Index
[c
]<0) ? 0 : Index
[c
]);
1212 Index
[c
] = ((Index
[c
]>88) ? 88 : Index
[c
]);
1214 dst
[i
*65*chans
+ c
] = ((Sample
[c
] < 0) ? (Sample
[c
]/32768.0f
) : (Sample
[c
]/32767.0f
));
1217 for(j
= 1;j
< 65;j
+= 8)
1219 for(c
= 0;c
< chans
;c
++)
1221 IMACode
[c
] = *(IMAData
++);
1222 IMACode
[c
] |= *(IMAData
++) << 8;
1223 IMACode
[c
] |= *(IMAData
++) << 16;
1224 IMACode
[c
] |= *(IMAData
++) << 24;
1227 for(k
= 0;k
< 8;k
++)
1229 for(c
= 0;c
< chans
;c
++)
1231 Sample
[c
] += ((g_IMAStep_size
[Index
[c
]]*g_IMACodeword_4
[IMACode
[c
]&15])/8);
1232 Index
[c
] += g_IMAIndex_adjust_4
[IMACode
[c
]&15];
1234 if(Sample
[c
] < -32768) Sample
[c
] = -32768;
1235 else if(Sample
[c
] > 32767) Sample
[c
] = 32767;
1237 if(Index
[c
]<0) Index
[c
] = 0;
1238 else if(Index
[c
]>88) Index
[c
] = 88;
1240 dst
[(i
*65+j
+k
)*chans
+ c
] = ((Sample
[c
] < 0) ? (Sample
[c
]/32768.0f
) : (Sample
[c
]/32767.0f
));
1248 static void ConvertDataMULaw(ALfloat
*dst
, const ALvoid
*src
, ALsizei len
)
1254 for(i
= 0;i
< len
;i
++)
1256 smp
= muLawDecompressionTable
[((ALubyte
*)src
)[i
]];
1257 dst
[i
] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1261 static void ConvertDataMULawRear(ALfloat
*dst
, const ALvoid
*src
, ALsizei len
)
1267 for(i
= 0;i
< len
;i
+=4)
1271 smp
= muLawDecompressionTable
[((ALubyte
*)src
)[i
/2+0]];
1272 dst
[i
+2] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1273 smp
= muLawDecompressionTable
[((ALubyte
*)src
)[i
/2+1]];
1274 dst
[i
+3] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1279 * ReleaseALBuffers()
1281 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
1283 ALvoid
ReleaseALBuffers(ALCdevice
*device
)
1286 for(i
= 0;i
< device
->BufferMap
.size
;i
++)
1288 ALbuffer
*temp
= device
->BufferMap
.array
[i
].value
;
1289 device
->BufferMap
.array
[i
].value
= NULL
;
1291 // Release sample data
1294 // Release Buffer structure
1295 ALTHUNK_REMOVEENTRY(temp
->buffer
);
1296 memset(temp
, 0, sizeof(ALbuffer
));