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
119 alSetError(Context
, AL_INVALID_VALUE
);
122 ALCdevice
*device
= Context
->Device
;
125 // Check the pointer is valid (and points to enough memory to store Buffer Names)
126 if(IsBadWritePtr((void*)buffers
, n
* sizeof(ALuint
)))
127 alSetError(Context
, AL_INVALID_VALUE
);
130 // Create all the new Buffers
133 ALbuffer
*buffer
= calloc(1, sizeof(ALbuffer
));
136 alSetError(Context
, AL_OUT_OF_MEMORY
);
137 alDeleteBuffers(i
, buffers
);
141 buffer
->buffer
= (ALuint
)ALTHUNK_ADDENTRY(buffer
);
142 err
= InsertUIntMapEntry(&device
->BufferMap
, buffer
->buffer
,
144 if(err
!= AL_NO_ERROR
)
146 ALTHUNK_REMOVEENTRY(buffer
->buffer
);
147 memset(buffer
, 0, sizeof(ALbuffer
));
150 alSetError(Context
, err
);
151 alDeleteBuffers(i
, buffers
);
154 buffers
[i
++] = buffer
->buffer
;
159 ProcessContext(Context
);
163 * alDeleteBuffers(ALsizei n, ALuint *puiBuffers)
165 * Deletes the n AL Buffers pointed to by puiBuffers
167 AL_API ALvoid AL_APIENTRY
alDeleteBuffers(ALsizei n
, const ALuint
*puiBuffers
)
173 Context
= GetContextSuspended();
176 // Check we are actually Deleting some Buffers
178 alSetError(Context
, AL_INVALID_VALUE
);
181 ALCdevice
*device
= Context
->Device
;
182 ALboolean bFailed
= AL_FALSE
;
184 // Check that all the buffers are valid and can actually be deleted
190 // Check for valid Buffer ID (can be NULL buffer)
191 if((ALBuf
=LookupBuffer(device
->BufferMap
, puiBuffers
[i
])) != NULL
)
193 if(ALBuf
->refcount
!= 0)
195 // Buffer still in use, cannot be deleted
196 alSetError(Context
, AL_INVALID_OPERATION
);
204 alSetError(Context
, AL_INVALID_NAME
);
210 // If all the Buffers were valid (and have Reference Counts of 0), then we can delete them
215 if((ALBuf
=LookupBuffer(device
->BufferMap
, puiBuffers
[i
])) != NULL
)
217 // Release the memory used to store audio data
220 // Release buffer structure
221 RemoveUIntMapKey(&device
->BufferMap
, ALBuf
->buffer
);
222 ALTHUNK_REMOVEENTRY(ALBuf
->buffer
);
224 memset(ALBuf
, 0, sizeof(ALbuffer
));
231 ProcessContext(Context
);
235 * alIsBuffer(ALuint uiBuffer)
237 * Checks if ulBuffer is a valid Buffer Name
239 AL_API ALboolean AL_APIENTRY
alIsBuffer(ALuint buffer
)
244 Context
= GetContextSuspended();
245 if(!Context
) return AL_FALSE
;
247 result
= ((!buffer
|| LookupBuffer(Context
->Device
->BufferMap
, buffer
)) ?
250 ProcessContext(Context
);
256 * alBufferData(ALuint buffer,ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
258 * Fill buffer with audio data
260 AL_API ALvoid AL_APIENTRY
alBufferData(ALuint buffer
,ALenum format
,const ALvoid
*data
,ALsizei size
,ALsizei freq
)
268 Context
= GetContextSuspended();
271 device
= Context
->Device
;
272 if((ALBuf
=LookupBuffer(device
->BufferMap
, buffer
)) == NULL
)
273 alSetError(Context
, AL_INVALID_NAME
); /* Invalid Buffer Name */
276 if(Context
->SampleSource
)
280 if(Context
->SampleSource
->state
== MAPPED
)
282 alSetError(Context
, AL_INVALID_OPERATION
);
283 ProcessContext(Context
);
287 offset
= (const ALubyte
*)data
- (ALubyte
*)NULL
;
288 data
= Context
->SampleSource
->data
+ offset
;
291 if(size
< 0 || freq
< 0)
292 alSetError(Context
, AL_INVALID_VALUE
);
293 else if(ALBuf
->refcount
!= 0)
294 alSetError(Context
, AL_INVALID_VALUE
);
299 case AL_FORMAT_MONO8
:
300 case AL_FORMAT_MONO16
:
301 case AL_FORMAT_MONO_FLOAT32
:
302 case AL_FORMAT_MONO_DOUBLE_EXT
:
303 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_MONO_FLOAT32
);
304 if(err
!= AL_NO_ERROR
)
305 alSetError(Context
, err
);
308 case AL_FORMAT_STEREO8
:
309 case AL_FORMAT_STEREO16
:
310 case AL_FORMAT_STEREO_FLOAT32
:
311 case AL_FORMAT_STEREO_DOUBLE_EXT
:
312 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_STEREO_FLOAT32
);
313 if(err
!= AL_NO_ERROR
)
314 alSetError(Context
, err
);
317 case AL_FORMAT_REAR8
:
318 case AL_FORMAT_REAR16
:
319 case AL_FORMAT_REAR32
: {
320 ALenum NewFormat
= AL_FORMAT_QUAD32
;
321 ALuint NewChannels
= aluChannelsFromFormat(NewFormat
);
322 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
323 ALuint OrigBytes
= ((format
==AL_FORMAT_REAR8
) ? 1 :
324 ((format
==AL_FORMAT_REAR16
) ? 2 :
326 ALuint64 newsize
, allocsize
;
328 if((size
%(OrigBytes
*2)) != 0)
330 alSetError(Context
, AL_INVALID_VALUE
);
334 newsize
= size
/ OrigBytes
;
337 allocsize
= (BUFFER_PADDING
*NewChannels
+ newsize
)*NewBytes
;
338 if(allocsize
> INT_MAX
)
340 alSetError(Context
, AL_OUT_OF_MEMORY
);
343 temp
= realloc(ALBuf
->data
, allocsize
);
347 ConvertDataRear(ALBuf
->data
, data
, OrigBytes
, newsize
);
349 ALBuf
->format
= NewFormat
;
350 ALBuf
->eOriginalFormat
= format
;
351 ALBuf
->size
= newsize
*NewBytes
;
352 ALBuf
->frequency
= freq
;
354 ALBuf
->LoopStart
= 0;
355 ALBuf
->LoopEnd
= newsize
/ NewChannels
;
357 ALBuf
->OriginalSize
= size
;
358 ALBuf
->OriginalAlign
= OrigBytes
* 2;
361 alSetError(Context
, AL_OUT_OF_MEMORY
);
364 case AL_FORMAT_QUAD8_LOKI
:
365 case AL_FORMAT_QUAD16_LOKI
:
366 case AL_FORMAT_QUAD8
:
367 case AL_FORMAT_QUAD16
:
368 case AL_FORMAT_QUAD32
:
369 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_QUAD32
);
370 if(err
!= AL_NO_ERROR
)
371 alSetError(Context
, err
);
374 case AL_FORMAT_51CHN8
:
375 case AL_FORMAT_51CHN16
:
376 case AL_FORMAT_51CHN32
:
377 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_51CHN32
);
378 if(err
!= AL_NO_ERROR
)
379 alSetError(Context
, err
);
382 case AL_FORMAT_61CHN8
:
383 case AL_FORMAT_61CHN16
:
384 case AL_FORMAT_61CHN32
:
385 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_61CHN32
);
386 if(err
!= AL_NO_ERROR
)
387 alSetError(Context
, err
);
390 case AL_FORMAT_71CHN8
:
391 case AL_FORMAT_71CHN16
:
392 case AL_FORMAT_71CHN32
:
393 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_71CHN32
);
394 if(err
!= AL_NO_ERROR
)
395 alSetError(Context
, err
);
398 case AL_FORMAT_MONO_IMA4
:
399 case AL_FORMAT_STEREO_IMA4
: {
400 int Channels
= ((format
==AL_FORMAT_MONO_IMA4
) ? 1 : 2);
401 ALenum NewFormat
= ((Channels
==1) ? AL_FORMAT_MONO_FLOAT32
:
402 AL_FORMAT_STEREO_FLOAT32
);
403 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
404 ALuint64 newsize
, allocsize
;
406 // Here is where things vary:
407 // nVidia and Apple use 64+1 samples per channel per block => block_size=36*chans bytes
408 // Most PC sound software uses 2040+1 samples per channel per block -> block_size=1024*chans bytes
409 if((size
%(36*Channels
)) != 0)
411 alSetError(Context
, AL_INVALID_VALUE
);
418 allocsize
= (BUFFER_PADDING
*Channels
+ newsize
)*NewBytes
;
419 if(allocsize
> INT_MAX
)
421 alSetError(Context
, AL_OUT_OF_MEMORY
);
424 temp
= realloc(ALBuf
->data
, allocsize
);
428 ConvertDataIMA4(ALBuf
->data
, data
, Channels
, newsize
/(65*Channels
));
430 ALBuf
->format
= NewFormat
;
431 ALBuf
->eOriginalFormat
= format
;
432 ALBuf
->size
= newsize
*NewBytes
;
433 ALBuf
->frequency
= freq
;
435 ALBuf
->LoopStart
= 0;
436 ALBuf
->LoopEnd
= newsize
/ Channels
;
438 ALBuf
->OriginalSize
= size
;
439 ALBuf
->OriginalAlign
= 36 * Channels
;
442 alSetError(Context
, AL_OUT_OF_MEMORY
);
445 case AL_FORMAT_MONO_MULAW
:
446 case AL_FORMAT_STEREO_MULAW
:
447 case AL_FORMAT_QUAD_MULAW
:
448 case AL_FORMAT_51CHN_MULAW
:
449 case AL_FORMAT_61CHN_MULAW
:
450 case AL_FORMAT_71CHN_MULAW
: {
451 int Channels
= ((format
==AL_FORMAT_MONO_MULAW
) ? 1 :
452 ((format
==AL_FORMAT_STEREO_MULAW
) ? 2 :
453 ((format
==AL_FORMAT_QUAD_MULAW
) ? 4 :
454 ((format
==AL_FORMAT_51CHN_MULAW
) ? 6 :
455 ((format
==AL_FORMAT_61CHN_MULAW
) ? 7 : 8)))));
456 ALenum NewFormat
= ((Channels
==1) ? AL_FORMAT_MONO_FLOAT32
:
457 ((Channels
==2) ? AL_FORMAT_STEREO_FLOAT32
:
458 ((Channels
==4) ? AL_FORMAT_QUAD32
:
459 ((Channels
==6) ? AL_FORMAT_51CHN32
:
460 ((Channels
==7) ? AL_FORMAT_61CHN32
:
461 AL_FORMAT_71CHN32
)))));
462 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
465 if((size
%(1*Channels
)) != 0)
467 alSetError(Context
, AL_INVALID_VALUE
);
471 allocsize
= (BUFFER_PADDING
*Channels
+ size
)*NewBytes
;
472 if(allocsize
> INT_MAX
)
474 alSetError(Context
, AL_OUT_OF_MEMORY
);
477 temp
= realloc(ALBuf
->data
, allocsize
);
481 ConvertDataMULaw(ALBuf
->data
, data
, size
);
483 ALBuf
->format
= NewFormat
;
484 ALBuf
->eOriginalFormat
= format
;
485 ALBuf
->size
= size
*NewBytes
;
486 ALBuf
->frequency
= freq
;
488 ALBuf
->LoopStart
= 0;
489 ALBuf
->LoopEnd
= size
/ Channels
;
491 ALBuf
->OriginalSize
= size
;
492 ALBuf
->OriginalAlign
= 1 * Channels
;
495 alSetError(Context
, AL_OUT_OF_MEMORY
);
498 case AL_FORMAT_REAR_MULAW
: {
499 ALenum NewFormat
= AL_FORMAT_QUAD32
;
500 ALuint NewChannels
= aluChannelsFromFormat(NewFormat
);
501 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
502 ALuint64 newsize
, allocsize
;
504 if((size
%(1*2)) != 0)
506 alSetError(Context
, AL_INVALID_VALUE
);
512 allocsize
= (BUFFER_PADDING
*NewChannels
+ newsize
)*NewBytes
;
513 if(allocsize
> INT_MAX
)
515 alSetError(Context
, AL_OUT_OF_MEMORY
);
518 temp
= realloc(ALBuf
->data
, allocsize
);
522 ConvertDataMULawRear(ALBuf
->data
, data
, newsize
);
524 ALBuf
->format
= NewFormat
;
525 ALBuf
->eOriginalFormat
= format
;
526 ALBuf
->size
= newsize
*NewBytes
;
527 ALBuf
->frequency
= freq
;
529 ALBuf
->LoopStart
= 0;
530 ALBuf
->LoopEnd
= newsize
/ NewChannels
;
532 ALBuf
->OriginalSize
= size
;
533 ALBuf
->OriginalAlign
= 1 * 2;
536 alSetError(Context
, AL_OUT_OF_MEMORY
);
540 alSetError(Context
, AL_INVALID_ENUM
);
546 ProcessContext(Context
);
550 * alBufferSubDataEXT(ALuint buffer,ALenum format,ALvoid *data,ALsizei offset,ALsizei length)
552 * Fill buffer with audio data
554 AL_API ALvoid AL_APIENTRY
alBufferSubDataEXT(ALuint buffer
,ALenum format
,const ALvoid
*data
,ALsizei offset
,ALsizei length
)
560 Context
= GetContextSuspended();
563 device
= Context
->Device
;
564 if((ALBuf
=LookupBuffer(device
->BufferMap
, buffer
)) == NULL
)
565 alSetError(Context
, AL_INVALID_NAME
);
568 if(Context
->SampleSource
)
572 if(Context
->SampleSource
->state
== MAPPED
)
574 alSetError(Context
, AL_INVALID_OPERATION
);
575 ProcessContext(Context
);
579 offset
= (const ALubyte
*)data
- (ALubyte
*)NULL
;
580 data
= Context
->SampleSource
->data
+ offset
;
583 if(length
< 0 || offset
< 0 || (length
> 0 && data
== NULL
))
584 alSetError(Context
, AL_INVALID_VALUE
);
585 else if(ALBuf
->eOriginalFormat
!= format
)
586 alSetError(Context
, AL_INVALID_ENUM
);
587 else if(offset
+length
< offset
||
588 offset
+length
> ALBuf
->OriginalSize
||
589 (offset
%ALBuf
->OriginalAlign
) != 0 ||
590 (length
%ALBuf
->OriginalAlign
) != 0)
591 alSetError(Context
, AL_INVALID_VALUE
);
596 case AL_FORMAT_MONO8
:
597 case AL_FORMAT_MONO16
:
598 case AL_FORMAT_MONO_FLOAT32
:
599 case AL_FORMAT_MONO_DOUBLE_EXT
:
600 case AL_FORMAT_STEREO8
:
601 case AL_FORMAT_STEREO16
:
602 case AL_FORMAT_STEREO_FLOAT32
:
603 case AL_FORMAT_STEREO_DOUBLE_EXT
:
604 case AL_FORMAT_QUAD8_LOKI
:
605 case AL_FORMAT_QUAD16_LOKI
:
606 case AL_FORMAT_QUAD8
:
607 case AL_FORMAT_QUAD16
:
608 case AL_FORMAT_QUAD32
:
609 case AL_FORMAT_51CHN8
:
610 case AL_FORMAT_51CHN16
:
611 case AL_FORMAT_51CHN32
:
612 case AL_FORMAT_61CHN8
:
613 case AL_FORMAT_61CHN16
:
614 case AL_FORMAT_61CHN32
:
615 case AL_FORMAT_71CHN8
:
616 case AL_FORMAT_71CHN16
:
617 case AL_FORMAT_71CHN32
: {
618 ALuint Bytes
= aluBytesFromFormat(format
);
623 ConvertData(&ALBuf
->data
[offset
], data
, Bytes
, length
);
626 case AL_FORMAT_REAR8
:
627 case AL_FORMAT_REAR16
:
628 case AL_FORMAT_REAR32
: {
629 ALuint Bytes
= ((format
==AL_FORMAT_REAR8
) ? 1 :
630 ((format
==AL_FORMAT_REAR16
) ? 2 :
638 ConvertDataRear(&ALBuf
->data
[offset
], data
, Bytes
, length
);
641 case AL_FORMAT_MONO_IMA4
:
642 case AL_FORMAT_STEREO_IMA4
: {
643 int Channels
= aluChannelsFromFormat(ALBuf
->format
);
645 // offset -> sample*channel offset, length -> block count
648 length
/= ALBuf
->OriginalAlign
;
650 ConvertDataIMA4(&ALBuf
->data
[offset
], data
, Channels
, length
);
653 case AL_FORMAT_MONO_MULAW
:
654 case AL_FORMAT_STEREO_MULAW
:
655 case AL_FORMAT_QUAD_MULAW
:
656 case AL_FORMAT_51CHN_MULAW
:
657 case AL_FORMAT_61CHN_MULAW
:
658 case AL_FORMAT_71CHN_MULAW
:
659 ConvertDataMULaw(&ALBuf
->data
[offset
], data
, length
);
662 case AL_FORMAT_REAR_MULAW
:
665 ConvertDataMULawRear(&ALBuf
->data
[offset
], data
, length
);
669 alSetError(Context
, AL_INVALID_ENUM
);
675 ProcessContext(Context
);
679 AL_API
void AL_APIENTRY
alBufferf(ALuint buffer
, ALenum eParam
, ALfloat flValue
)
681 ALCcontext
*pContext
;
686 pContext
= GetContextSuspended();
687 if(!pContext
) return;
689 device
= pContext
->Device
;
690 if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
691 alSetError(pContext
, AL_INVALID_NAME
);
697 alSetError(pContext
, AL_INVALID_ENUM
);
702 ProcessContext(pContext
);
706 AL_API
void AL_APIENTRY
alBuffer3f(ALuint buffer
, ALenum eParam
, ALfloat flValue1
, ALfloat flValue2
, ALfloat flValue3
)
708 ALCcontext
*pContext
;
715 pContext
= GetContextSuspended();
716 if(!pContext
) return;
718 device
= pContext
->Device
;
719 if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
720 alSetError(pContext
, AL_INVALID_NAME
);
726 alSetError(pContext
, AL_INVALID_ENUM
);
731 ProcessContext(pContext
);
735 AL_API
void AL_APIENTRY
alBufferfv(ALuint buffer
, ALenum eParam
, const ALfloat
* flValues
)
737 ALCcontext
*pContext
;
740 pContext
= GetContextSuspended();
741 if(!pContext
) return;
743 device
= pContext
->Device
;
745 alSetError(pContext
, AL_INVALID_VALUE
);
746 else if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
747 alSetError(pContext
, AL_INVALID_NAME
);
753 alSetError(pContext
, AL_INVALID_ENUM
);
758 ProcessContext(pContext
);
762 AL_API
void AL_APIENTRY
alBufferi(ALuint buffer
, ALenum eParam
, ALint lValue
)
764 ALCcontext
*pContext
;
769 pContext
= GetContextSuspended();
770 if(!pContext
) return;
772 device
= pContext
->Device
;
773 if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
774 alSetError(pContext
, AL_INVALID_NAME
);
780 alSetError(pContext
, AL_INVALID_ENUM
);
785 ProcessContext(pContext
);
789 AL_API
void AL_APIENTRY
alBuffer3i( ALuint buffer
, ALenum eParam
, ALint lValue1
, ALint lValue2
, ALint lValue3
)
791 ALCcontext
*pContext
;
798 pContext
= GetContextSuspended();
799 if(!pContext
) return;
801 device
= pContext
->Device
;
802 if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
803 alSetError(pContext
, AL_INVALID_NAME
);
809 alSetError(pContext
, AL_INVALID_ENUM
);
814 ProcessContext(pContext
);
818 AL_API
void AL_APIENTRY
alBufferiv(ALuint buffer
, ALenum eParam
, const ALint
* plValues
)
820 ALCcontext
*pContext
;
824 pContext
= GetContextSuspended();
825 if(!pContext
) return;
827 device
= pContext
->Device
;
829 alSetError(pContext
, AL_INVALID_VALUE
);
830 else if((ALBuf
=LookupBuffer(device
->BufferMap
, buffer
)) == NULL
)
831 alSetError(pContext
, AL_INVALID_NAME
);
837 if(ALBuf
->refcount
> 0)
838 alSetError(pContext
, AL_INVALID_OPERATION
);
839 else if(plValues
[0] < 0 || plValues
[1] < 0 ||
840 plValues
[0] >= plValues
[1] || ALBuf
->size
== 0)
841 alSetError(pContext
, AL_INVALID_VALUE
);
844 ALint maxlen
= ALBuf
->size
/ aluFrameSizeFromFormat(ALBuf
->format
);
845 if(plValues
[0] > maxlen
|| plValues
[1] > maxlen
)
846 alSetError(pContext
, AL_INVALID_VALUE
);
849 ALBuf
->LoopStart
= plValues
[0];
850 ALBuf
->LoopEnd
= plValues
[1];
856 alSetError(pContext
, AL_INVALID_ENUM
);
861 ProcessContext(pContext
);
865 AL_API ALvoid AL_APIENTRY
alGetBufferf(ALuint buffer
, ALenum eParam
, ALfloat
*pflValue
)
867 ALCcontext
*pContext
;
870 pContext
= GetContextSuspended();
871 if(!pContext
) return;
873 device
= pContext
->Device
;
875 alSetError(pContext
, AL_INVALID_VALUE
);
876 else if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
877 alSetError(pContext
, AL_INVALID_NAME
);
883 alSetError(pContext
, AL_INVALID_ENUM
);
888 ProcessContext(pContext
);
892 AL_API
void AL_APIENTRY
alGetBuffer3f(ALuint buffer
, ALenum eParam
, ALfloat
* pflValue1
, ALfloat
* pflValue2
, ALfloat
* pflValue3
)
894 ALCcontext
*pContext
;
897 pContext
= GetContextSuspended();
898 if(!pContext
) return;
900 device
= pContext
->Device
;
901 if(!pflValue1
|| !pflValue2
|| !pflValue3
)
902 alSetError(pContext
, AL_INVALID_VALUE
);
903 else if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
904 alSetError(pContext
, AL_INVALID_NAME
);
910 alSetError(pContext
, AL_INVALID_ENUM
);
915 ProcessContext(pContext
);
919 AL_API
void AL_APIENTRY
alGetBufferfv(ALuint buffer
, ALenum eParam
, ALfloat
* pflValues
)
921 ALCcontext
*pContext
;
924 pContext
= GetContextSuspended();
925 if(!pContext
) return;
927 device
= pContext
->Device
;
929 alSetError(pContext
, AL_INVALID_VALUE
);
930 else if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
931 alSetError(pContext
, AL_INVALID_NAME
);
937 alSetError(pContext
, AL_INVALID_ENUM
);
942 ProcessContext(pContext
);
946 AL_API ALvoid AL_APIENTRY
alGetBufferi(ALuint buffer
, ALenum eParam
, ALint
*plValue
)
948 ALCcontext
*pContext
;
952 pContext
= GetContextSuspended();
953 if(!pContext
) return;
955 device
= pContext
->Device
;
957 alSetError(pContext
, AL_INVALID_VALUE
);
958 else if((pBuffer
=LookupBuffer(device
->BufferMap
, buffer
)) == NULL
)
959 alSetError(pContext
, AL_INVALID_NAME
);
965 *plValue
= pBuffer
->frequency
;
969 *plValue
= aluBytesFromFormat(pBuffer
->format
) * 8;
973 *plValue
= aluChannelsFromFormat(pBuffer
->format
);
977 *plValue
= pBuffer
->size
;
981 alSetError(pContext
, AL_INVALID_ENUM
);
986 ProcessContext(pContext
);
990 AL_API
void AL_APIENTRY
alGetBuffer3i(ALuint buffer
, ALenum eParam
, ALint
* plValue1
, ALint
* plValue2
, ALint
* plValue3
)
992 ALCcontext
*pContext
;
995 pContext
= GetContextSuspended();
996 if(!pContext
) return;
998 device
= pContext
->Device
;
999 if(!plValue1
|| !plValue2
|| !plValue3
)
1000 alSetError(pContext
, AL_INVALID_VALUE
);
1001 else if(LookupBuffer(device
->BufferMap
, buffer
) == NULL
)
1002 alSetError(pContext
, AL_INVALID_NAME
);
1008 alSetError(pContext
, AL_INVALID_ENUM
);
1013 ProcessContext(pContext
);
1017 AL_API
void AL_APIENTRY
alGetBufferiv(ALuint buffer
, ALenum eParam
, ALint
* plValues
)
1019 ALCcontext
*pContext
;
1023 pContext
= GetContextSuspended();
1024 if(!pContext
) return;
1026 device
= pContext
->Device
;
1028 alSetError(pContext
, AL_INVALID_VALUE
);
1029 else if((ALBuf
=LookupBuffer(device
->BufferMap
, buffer
)) == NULL
)
1030 alSetError(pContext
, AL_INVALID_NAME
);
1039 alGetBufferi(buffer
, eParam
, plValues
);
1042 case AL_LOOP_POINTS
:
1043 plValues
[0] = ALBuf
->LoopStart
;
1044 plValues
[1] = ALBuf
->LoopEnd
;
1048 alSetError(pContext
, AL_INVALID_ENUM
);
1053 ProcessContext(pContext
);
1059 * Loads the specified data into the buffer, using the specified formats.
1060 * Currently, the new format must be 32-bit float, and must have the same
1061 * channel configuration as the original format. This does NOT handle
1062 * compressed formats (eg. IMA4).
1064 static ALenum
LoadData(ALbuffer
*ALBuf
, const ALvoid
*data
, ALsizei size
, ALuint freq
, ALenum OrigFormat
, ALenum NewFormat
)
1066 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
1067 ALuint NewChannels
= aluChannelsFromFormat(NewFormat
);
1068 ALuint OrigBytes
= aluBytesFromFormat(OrigFormat
);
1069 ALuint OrigChannels
= aluChannelsFromFormat(OrigFormat
);
1070 ALuint64 newsize
, allocsize
;
1073 assert(NewBytes
== 4);
1074 assert(NewChannels
== OrigChannels
);
1076 if((size
%(OrigBytes
*OrigChannels
)) != 0)
1077 return AL_INVALID_VALUE
;
1079 // Allocate extra padding samples
1080 newsize
= size
/ OrigBytes
;
1081 allocsize
= (BUFFER_PADDING
*NewChannels
+ newsize
)*NewBytes
;
1082 if(allocsize
> INT_MAX
)
1083 return AL_OUT_OF_MEMORY
;
1085 temp
= realloc(ALBuf
->data
, allocsize
);
1086 if(!temp
) return AL_OUT_OF_MEMORY
;
1089 // Samples are converted here
1090 ConvertData(ALBuf
->data
, data
, OrigBytes
, newsize
);
1092 ALBuf
->format
= NewFormat
;
1093 ALBuf
->eOriginalFormat
= OrigFormat
;
1094 ALBuf
->size
= newsize
*NewBytes
;
1095 ALBuf
->frequency
= freq
;
1097 ALBuf
->LoopStart
= 0;
1098 ALBuf
->LoopEnd
= newsize
/ NewChannels
;
1100 ALBuf
->OriginalSize
= size
;
1101 ALBuf
->OriginalAlign
= OrigBytes
* OrigChannels
;
1106 static void ConvertData(ALfloat
*dst
, const ALvoid
*src
, ALint origBytes
, ALsizei len
)
1115 for(i
= 0;i
< len
;i
++)
1117 smp
= ((ALubyte
*)src
)[i
];
1118 dst
[i
] = ((smp
< 0x80) ? ((smp
-128)/128.0f
) : ((smp
-128)/127.0f
));
1123 for(i
= 0;i
< len
;i
++)
1125 smp
= ((ALshort
*)src
)[i
];
1126 dst
[i
] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1131 for(i
= 0;i
< len
;i
++)
1132 dst
[i
] = ((ALfloat
*)src
)[i
];
1136 for(i
= 0;i
< len
;i
++)
1137 dst
[i
] = ((ALdouble
*)src
)[i
];
1145 static void ConvertDataRear(ALfloat
*dst
, const ALvoid
*src
, ALint origBytes
, ALsizei len
)
1154 for(i
= 0;i
< len
;i
+=4)
1158 smp
= ((ALubyte
*)src
)[i
/2+0];
1159 dst
[i
+2] = ((smp
< 0x80) ? ((smp
-128)/128.0f
) : ((smp
-128)/127.0f
));
1160 smp
= ((ALubyte
*)src
)[i
/2+1];
1161 dst
[i
+3] = ((smp
< 0x80) ? ((smp
-128)/128.0f
) : ((smp
-128)/127.0f
));
1166 for(i
= 0;i
< len
;i
+=4)
1170 smp
= ((ALshort
*)src
)[i
/2+0];
1171 dst
[i
+2] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1172 smp
= ((ALshort
*)src
)[i
/2+1];
1173 dst
[i
+3] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1178 for(i
= 0;i
< len
;i
+=4)
1182 dst
[i
+2] = ((ALfloat
*)src
)[i
/2+0];
1183 dst
[i
+3] = ((ALfloat
*)src
)[i
/2+1];
1192 static void ConvertDataIMA4(ALfloat
*dst
, const ALvoid
*src
, ALint chans
, ALsizei len
)
1194 const ALubyte
*IMAData
;
1195 ALint Sample
[2],Index
[2];
1203 for(i
= 0;i
< len
;i
++)
1205 for(c
= 0;c
< chans
;c
++)
1207 Sample
[c
] = *(IMAData
++);
1208 Sample
[c
] |= *(IMAData
++) << 8;
1209 Sample
[c
] = (Sample
[c
]^0x8000) - 32768;
1210 Index
[c
] = *(IMAData
++);
1211 Index
[c
] |= *(IMAData
++) << 8;
1212 Index
[c
] = (Index
[c
]^0x8000) - 32768;
1214 Index
[c
] = ((Index
[c
]<0) ? 0 : Index
[c
]);
1215 Index
[c
] = ((Index
[c
]>88) ? 88 : Index
[c
]);
1217 dst
[i
*65*chans
+ c
] = ((Sample
[c
] < 0) ? (Sample
[c
]/32768.0f
) : (Sample
[c
]/32767.0f
));
1220 for(j
= 1;j
< 65;j
+= 8)
1222 for(c
= 0;c
< chans
;c
++)
1224 IMACode
[c
] = *(IMAData
++);
1225 IMACode
[c
] |= *(IMAData
++) << 8;
1226 IMACode
[c
] |= *(IMAData
++) << 16;
1227 IMACode
[c
] |= *(IMAData
++) << 24;
1230 for(k
= 0;k
< 8;k
++)
1232 for(c
= 0;c
< chans
;c
++)
1234 Sample
[c
] += ((g_IMAStep_size
[Index
[c
]]*g_IMACodeword_4
[IMACode
[c
]&15])/8);
1235 Index
[c
] += g_IMAIndex_adjust_4
[IMACode
[c
]&15];
1237 if(Sample
[c
] < -32768) Sample
[c
] = -32768;
1238 else if(Sample
[c
] > 32767) Sample
[c
] = 32767;
1240 if(Index
[c
]<0) Index
[c
] = 0;
1241 else if(Index
[c
]>88) Index
[c
] = 88;
1243 dst
[(i
*65+j
+k
)*chans
+ c
] = ((Sample
[c
] < 0) ? (Sample
[c
]/32768.0f
) : (Sample
[c
]/32767.0f
));
1251 static void ConvertDataMULaw(ALfloat
*dst
, const ALvoid
*src
, ALsizei len
)
1257 for(i
= 0;i
< len
;i
++)
1259 smp
= muLawDecompressionTable
[((ALubyte
*)src
)[i
]];
1260 dst
[i
] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1264 static void ConvertDataMULawRear(ALfloat
*dst
, const ALvoid
*src
, ALsizei len
)
1270 for(i
= 0;i
< len
;i
+=4)
1274 smp
= muLawDecompressionTable
[((ALubyte
*)src
)[i
/2+0]];
1275 dst
[i
+2] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1276 smp
= muLawDecompressionTable
[((ALubyte
*)src
)[i
/2+1]];
1277 dst
[i
+3] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1282 * ReleaseALBuffers()
1284 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
1286 ALvoid
ReleaseALBuffers(ALCdevice
*device
)
1289 for(i
= 0;i
< device
->BufferMap
.size
;i
++)
1291 ALbuffer
*temp
= device
->BufferMap
.array
[i
].value
;
1292 device
->BufferMap
.array
[i
].value
= NULL
;
1294 // Release sample data
1297 // Release Buffer structure
1298 ALTHUNK_REMOVEENTRY(temp
->buffer
);
1299 memset(temp
, 0, sizeof(ALbuffer
));