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
)))
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
,
140 if(err
!= AL_NO_ERROR
)
142 ALTHUNK_REMOVEENTRY(buffer
->buffer
);
143 memset(buffer
, 0, sizeof(ALbuffer
));
146 alSetError(Context
, err
);
147 alDeleteBuffers(i
, buffers
);
150 buffers
[i
++] = buffer
->buffer
;
155 // Pointer does not point to enough memory to write Buffer names
156 alSetError(Context
, AL_INVALID_VALUE
);
160 ProcessContext(Context
);
164 * alDeleteBuffers(ALsizei n, ALuint *puiBuffers)
166 * Deletes the n AL Buffers pointed to by puiBuffers
168 AL_API ALvoid AL_APIENTRY
alDeleteBuffers(ALsizei n
, const ALuint
*puiBuffers
)
173 ALboolean bFailed
= AL_FALSE
;
175 Context
= GetContextSuspended();
178 // Check we are actually Deleting some Buffers
181 ALCdevice
*device
= Context
->Device
;
183 // Check that all the buffers are valid and can actually be deleted
184 for (i
= 0; i
< n
; i
++)
189 // Check for valid Buffer ID (can be NULL buffer)
190 if((ALBuf
=LookupBuffer(device
->BufferMap
, puiBuffers
[i
])) != NULL
)
192 if(ALBuf
->refcount
!= 0)
194 // Buffer still in use, cannot be deleted
195 alSetError(Context
, AL_INVALID_OPERATION
);
203 alSetError(Context
, AL_INVALID_NAME
);
209 // If all the Buffers were valid (and have Reference Counts of 0), then we can delete them
212 for (i
= 0; i
< n
; i
++)
214 if((ALBuf
=LookupBuffer(device
->BufferMap
, puiBuffers
[i
])) != NULL
)
216 // Release the memory used to store audio data
219 // Release buffer structure
220 RemoveUIntMapKey(&device
->BufferMap
, ALBuf
->buffer
);
221 ALTHUNK_REMOVEENTRY(ALBuf
->buffer
);
223 memset(ALBuf
, 0, sizeof(ALbuffer
));
230 alSetError(Context
, AL_INVALID_VALUE
);
232 ProcessContext(Context
);
236 * alIsBuffer(ALuint uiBuffer)
238 * Checks if ulBuffer is a valid Buffer Name
240 AL_API ALboolean AL_APIENTRY
alIsBuffer(ALuint buffer
)
245 Context
= GetContextSuspended();
246 if(!Context
) return AL_FALSE
;
248 result
= ((!buffer
|| LookupBuffer(Context
->Device
->BufferMap
, buffer
)) ?
251 ProcessContext(Context
);
257 * alBufferData(ALuint buffer,ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
259 * Fill buffer with audio data
261 AL_API ALvoid AL_APIENTRY
alBufferData(ALuint buffer
,ALenum format
,const ALvoid
*data
,ALsizei size
,ALsizei freq
)
269 Context
= GetContextSuspended();
272 device
= Context
->Device
;
273 if((ALBuf
=LookupBuffer(device
->BufferMap
, buffer
)) == NULL
)
274 alSetError(Context
, AL_INVALID_NAME
); /* Invalid Buffer Name */
277 if(Context
->SampleSource
)
281 if(Context
->SampleSource
->state
== MAPPED
)
283 alSetError(Context
, AL_INVALID_OPERATION
);
284 ProcessContext(Context
);
288 offset
= (const ALubyte
*)data
- (ALubyte
*)NULL
;
289 data
= Context
->SampleSource
->data
+ offset
;
293 alSetError(Context
, AL_INVALID_VALUE
);
294 else if(ALBuf
->refcount
!= 0)
295 alSetError(Context
, AL_INVALID_VALUE
);
300 case AL_FORMAT_MONO8
:
301 case AL_FORMAT_MONO16
:
302 case AL_FORMAT_MONO_FLOAT32
:
303 case AL_FORMAT_MONO_DOUBLE_EXT
:
304 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_MONO_FLOAT32
);
305 if(err
!= AL_NO_ERROR
)
306 alSetError(Context
, err
);
309 case AL_FORMAT_STEREO8
:
310 case AL_FORMAT_STEREO16
:
311 case AL_FORMAT_STEREO_FLOAT32
:
312 case AL_FORMAT_STEREO_DOUBLE_EXT
:
313 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_STEREO_FLOAT32
);
314 if(err
!= AL_NO_ERROR
)
315 alSetError(Context
, err
);
318 case AL_FORMAT_REAR8
:
319 case AL_FORMAT_REAR16
:
320 case AL_FORMAT_REAR32
: {
321 ALenum NewFormat
= AL_FORMAT_QUAD32
;
322 ALuint NewChannels
= aluChannelsFromFormat(NewFormat
);
323 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
324 ALuint OrigBytes
= ((format
==AL_FORMAT_REAR8
) ? 1 :
325 ((format
==AL_FORMAT_REAR16
) ? 2 :
327 ALuint64 newsize
, allocsize
;
329 if((size
%(OrigBytes
*2)) != 0)
331 alSetError(Context
, AL_INVALID_VALUE
);
335 newsize
= size
/ OrigBytes
;
338 allocsize
= (BUFFER_PADDING
*NewChannels
+ newsize
)*NewBytes
;
339 if(allocsize
> INT_MAX
)
341 alSetError(Context
, AL_OUT_OF_MEMORY
);
344 temp
= realloc(ALBuf
->data
, allocsize
);
348 ConvertDataRear(ALBuf
->data
, data
, OrigBytes
, newsize
);
350 ALBuf
->format
= NewFormat
;
351 ALBuf
->eOriginalFormat
= format
;
352 ALBuf
->size
= newsize
*NewBytes
;
353 ALBuf
->frequency
= freq
;
355 ALBuf
->LoopStart
= 0;
356 ALBuf
->LoopEnd
= newsize
/ NewChannels
;
358 ALBuf
->OriginalSize
= size
;
359 ALBuf
->OriginalAlign
= OrigBytes
* 2;
362 alSetError(Context
, AL_OUT_OF_MEMORY
);
365 case AL_FORMAT_QUAD8_LOKI
:
366 case AL_FORMAT_QUAD16_LOKI
:
367 case AL_FORMAT_QUAD8
:
368 case AL_FORMAT_QUAD16
:
369 case AL_FORMAT_QUAD32
:
370 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_QUAD32
);
371 if(err
!= AL_NO_ERROR
)
372 alSetError(Context
, err
);
375 case AL_FORMAT_51CHN8
:
376 case AL_FORMAT_51CHN16
:
377 case AL_FORMAT_51CHN32
:
378 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_51CHN32
);
379 if(err
!= AL_NO_ERROR
)
380 alSetError(Context
, err
);
383 case AL_FORMAT_61CHN8
:
384 case AL_FORMAT_61CHN16
:
385 case AL_FORMAT_61CHN32
:
386 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_61CHN32
);
387 if(err
!= AL_NO_ERROR
)
388 alSetError(Context
, err
);
391 case AL_FORMAT_71CHN8
:
392 case AL_FORMAT_71CHN16
:
393 case AL_FORMAT_71CHN32
:
394 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_71CHN32
);
395 if(err
!= AL_NO_ERROR
)
396 alSetError(Context
, err
);
399 case AL_FORMAT_MONO_IMA4
:
400 case AL_FORMAT_STEREO_IMA4
: {
401 int Channels
= ((format
==AL_FORMAT_MONO_IMA4
) ? 1 : 2);
402 ALenum NewFormat
= ((Channels
==1) ? AL_FORMAT_MONO_FLOAT32
:
403 AL_FORMAT_STEREO_FLOAT32
);
404 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
405 ALuint64 newsize
, allocsize
;
407 // Here is where things vary:
408 // nVidia and Apple use 64+1 samples per channel per block => block_size=36*chans bytes
409 // Most PC sound software uses 2040+1 samples per channel per block -> block_size=1024*chans bytes
410 if((size
%(36*Channels
)) != 0)
412 alSetError(Context
, AL_INVALID_VALUE
);
419 allocsize
= (BUFFER_PADDING
*Channels
+ newsize
)*NewBytes
;
420 if(allocsize
> INT_MAX
)
422 alSetError(Context
, AL_OUT_OF_MEMORY
);
425 temp
= realloc(ALBuf
->data
, allocsize
);
429 ConvertDataIMA4(ALBuf
->data
, data
, Channels
, newsize
/65);
431 ALBuf
->format
= NewFormat
;
432 ALBuf
->eOriginalFormat
= format
;
433 ALBuf
->size
= newsize
*NewBytes
;
434 ALBuf
->frequency
= freq
;
436 ALBuf
->LoopStart
= 0;
437 ALBuf
->LoopEnd
= newsize
/ Channels
;
439 ALBuf
->OriginalSize
= size
;
440 ALBuf
->OriginalAlign
= 36 * Channels
;
443 alSetError(Context
, AL_OUT_OF_MEMORY
);
446 case AL_FORMAT_MONO_MULAW
:
447 case AL_FORMAT_STEREO_MULAW
:
448 case AL_FORMAT_QUAD_MULAW
:
449 case AL_FORMAT_51CHN_MULAW
:
450 case AL_FORMAT_61CHN_MULAW
:
451 case AL_FORMAT_71CHN_MULAW
: {
452 int Channels
= ((format
==AL_FORMAT_MONO_MULAW
) ? 1 :
453 ((format
==AL_FORMAT_STEREO_MULAW
) ? 2 :
454 ((format
==AL_FORMAT_QUAD_MULAW
) ? 4 :
455 ((format
==AL_FORMAT_51CHN_MULAW
) ? 6 :
456 ((format
==AL_FORMAT_61CHN_MULAW
) ? 7 : 8)))));
457 ALenum NewFormat
= ((Channels
==1) ? AL_FORMAT_MONO_FLOAT32
:
458 ((Channels
==2) ? AL_FORMAT_STEREO_FLOAT32
:
459 ((Channels
==4) ? AL_FORMAT_QUAD32
:
460 ((Channels
==6) ? AL_FORMAT_51CHN32
:
461 ((Channels
==7) ? AL_FORMAT_61CHN32
:
462 AL_FORMAT_71CHN32
)))));
463 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
466 if((size
%(1*Channels
)) != 0)
468 alSetError(Context
, AL_INVALID_VALUE
);
472 allocsize
= (BUFFER_PADDING
*Channels
+ size
)*NewBytes
;
473 if(allocsize
> INT_MAX
)
475 alSetError(Context
, AL_OUT_OF_MEMORY
);
478 temp
= realloc(ALBuf
->data
, allocsize
);
482 ConvertDataMULaw(ALBuf
->data
, data
, size
);
484 ALBuf
->format
= NewFormat
;
485 ALBuf
->eOriginalFormat
= format
;
486 ALBuf
->size
= size
*NewBytes
;
487 ALBuf
->frequency
= freq
;
489 ALBuf
->LoopStart
= 0;
490 ALBuf
->LoopEnd
= size
/ Channels
;
492 ALBuf
->OriginalSize
= size
;
493 ALBuf
->OriginalAlign
= 1 * Channels
;
496 alSetError(Context
, AL_OUT_OF_MEMORY
);
499 case AL_FORMAT_REAR_MULAW
: {
500 ALenum NewFormat
= AL_FORMAT_QUAD32
;
501 ALuint NewChannels
= aluChannelsFromFormat(NewFormat
);
502 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
503 ALuint64 newsize
, allocsize
;
505 if((size
%(1*2)) != 0)
507 alSetError(Context
, AL_INVALID_VALUE
);
513 allocsize
= (BUFFER_PADDING
*NewChannels
+ newsize
)*NewBytes
;
514 if(allocsize
> INT_MAX
)
516 alSetError(Context
, AL_OUT_OF_MEMORY
);
519 temp
= realloc(ALBuf
->data
, allocsize
);
523 ConvertDataMULawRear(ALBuf
->data
, data
, newsize
);
525 ALBuf
->format
= NewFormat
;
526 ALBuf
->eOriginalFormat
= format
;
527 ALBuf
->size
= newsize
*NewBytes
;
528 ALBuf
->frequency
= freq
;
530 ALBuf
->LoopStart
= 0;
531 ALBuf
->LoopEnd
= newsize
/ NewChannels
;
533 ALBuf
->OriginalSize
= size
;
534 ALBuf
->OriginalAlign
= 1 * 2;
537 alSetError(Context
, AL_OUT_OF_MEMORY
);
541 alSetError(Context
, AL_INVALID_ENUM
);
547 ProcessContext(Context
);
551 * alBufferSubDataEXT(ALuint buffer,ALenum format,ALvoid *data,ALsizei offset,ALsizei length)
553 * Fill buffer with audio data
555 AL_API ALvoid AL_APIENTRY
alBufferSubDataEXT(ALuint buffer
,ALenum format
,const ALvoid
*data
,ALsizei offset
,ALsizei length
)
561 Context
= GetContextSuspended();
564 device
= Context
->Device
;
565 if((ALBuf
=LookupBuffer(device
->BufferMap
, buffer
)) != NULL
)
567 if(Context
->SampleSource
)
571 if(Context
->SampleSource
->state
== MAPPED
)
573 alSetError(Context
, AL_INVALID_OPERATION
);
574 ProcessContext(Context
);
578 offset
= (const ALubyte
*)data
- (ALubyte
*)NULL
;
579 data
= Context
->SampleSource
->data
+ offset
;
582 if(length
< 0 || offset
< 0 || (length
> 0 && data
== NULL
))
584 // data is NULL or offset/length is negative
585 alSetError(Context
, AL_INVALID_VALUE
);
587 else if(ALBuf
->eOriginalFormat
!= format
)
588 alSetError(Context
, AL_INVALID_ENUM
);
589 else if(ALBuf
->OriginalAlign
== 0 ||
590 (offset
%ALBuf
->OriginalAlign
) != 0 ||
591 (length
%ALBuf
->OriginalAlign
) != 0 ||
592 offset
+length
> ALBuf
->OriginalSize
)
593 alSetError(Context
, AL_INVALID_VALUE
);
598 case AL_FORMAT_MONO8
:
599 case AL_FORMAT_MONO16
:
600 case AL_FORMAT_MONO_FLOAT32
:
601 case AL_FORMAT_MONO_DOUBLE_EXT
:
602 case AL_FORMAT_STEREO8
:
603 case AL_FORMAT_STEREO16
:
604 case AL_FORMAT_STEREO_FLOAT32
:
605 case AL_FORMAT_STEREO_DOUBLE_EXT
:
606 case AL_FORMAT_QUAD8_LOKI
:
607 case AL_FORMAT_QUAD16_LOKI
:
608 case AL_FORMAT_QUAD8
:
609 case AL_FORMAT_QUAD16
:
610 case AL_FORMAT_QUAD32
:
611 case AL_FORMAT_51CHN8
:
612 case AL_FORMAT_51CHN16
:
613 case AL_FORMAT_51CHN32
:
614 case AL_FORMAT_61CHN8
:
615 case AL_FORMAT_61CHN16
:
616 case AL_FORMAT_61CHN32
:
617 case AL_FORMAT_71CHN8
:
618 case AL_FORMAT_71CHN16
:
619 case AL_FORMAT_71CHN32
: {
620 ALuint Bytes
= aluBytesFromFormat(format
);
625 ConvertData(&ALBuf
->data
[offset
], data
, Bytes
, length
);
628 case AL_FORMAT_REAR8
:
629 case AL_FORMAT_REAR16
:
630 case AL_FORMAT_REAR32
: {
631 ALuint Bytes
= ((format
==AL_FORMAT_REAR8
) ? 1 :
632 ((format
==AL_FORMAT_REAR16
) ? 2 :
640 ConvertDataRear(&ALBuf
->data
[offset
], data
, Bytes
, length
);
643 case AL_FORMAT_MONO_IMA4
:
644 case AL_FORMAT_STEREO_IMA4
: {
645 int Channels
= aluChannelsFromFormat(ALBuf
->format
);
647 // offset -> sample*channel offset, length -> block count
652 ConvertDataIMA4(&ALBuf
->data
[offset
], data
, Channels
, length
);
655 case AL_FORMAT_MONO_MULAW
:
656 case AL_FORMAT_STEREO_MULAW
:
657 case AL_FORMAT_QUAD_MULAW
:
658 case AL_FORMAT_51CHN_MULAW
:
659 case AL_FORMAT_61CHN_MULAW
:
660 case AL_FORMAT_71CHN_MULAW
:
661 ConvertDataMULaw(&ALBuf
->data
[offset
], data
, length
);
664 case AL_FORMAT_REAR_MULAW
:
667 ConvertDataMULawRear(&ALBuf
->data
[offset
], data
, length
);
671 alSetError(Context
, AL_INVALID_ENUM
);
678 // Invalid Buffer Name
679 alSetError(Context
, AL_INVALID_NAME
);
682 ProcessContext(Context
);
686 AL_API
void AL_APIENTRY
alBufferf(ALuint buffer
, ALenum eParam
, ALfloat flValue
)
688 ALCcontext
*pContext
;
693 pContext
= GetContextSuspended();
694 if(!pContext
) return;
696 device
= pContext
->Device
;
697 if(LookupBuffer(device
->BufferMap
, buffer
) != NULL
)
702 alSetError(pContext
, AL_INVALID_ENUM
);
708 alSetError(pContext
, AL_INVALID_NAME
);
711 ProcessContext(pContext
);
715 AL_API
void AL_APIENTRY
alBuffer3f(ALuint buffer
, ALenum eParam
, ALfloat flValue1
, ALfloat flValue2
, ALfloat flValue3
)
717 ALCcontext
*pContext
;
724 pContext
= GetContextSuspended();
725 if(!pContext
) return;
727 device
= pContext
->Device
;
728 if(LookupBuffer(device
->BufferMap
, buffer
) != NULL
)
733 alSetError(pContext
, AL_INVALID_ENUM
);
739 alSetError(pContext
, AL_INVALID_NAME
);
742 ProcessContext(pContext
);
746 AL_API
void AL_APIENTRY
alBufferfv(ALuint buffer
, ALenum eParam
, const ALfloat
* flValues
)
748 ALCcontext
*pContext
;
753 pContext
= GetContextSuspended();
754 if(!pContext
) return;
756 device
= pContext
->Device
;
757 if(LookupBuffer(device
->BufferMap
, buffer
) != NULL
)
762 alSetError(pContext
, AL_INVALID_ENUM
);
768 alSetError(pContext
, AL_INVALID_NAME
);
771 ProcessContext(pContext
);
775 AL_API
void AL_APIENTRY
alBufferi(ALuint buffer
, ALenum eParam
, ALint lValue
)
777 ALCcontext
*pContext
;
782 pContext
= GetContextSuspended();
783 if(!pContext
) return;
785 device
= pContext
->Device
;
786 if(LookupBuffer(device
->BufferMap
, buffer
) != NULL
)
791 alSetError(pContext
, AL_INVALID_ENUM
);
797 alSetError(pContext
, AL_INVALID_NAME
);
800 ProcessContext(pContext
);
804 AL_API
void AL_APIENTRY
alBuffer3i( ALuint buffer
, ALenum eParam
, ALint lValue1
, ALint lValue2
, ALint lValue3
)
806 ALCcontext
*pContext
;
813 pContext
= GetContextSuspended();
814 if(!pContext
) return;
816 device
= pContext
->Device
;
817 if(LookupBuffer(device
->BufferMap
, buffer
) != NULL
)
822 alSetError(pContext
, AL_INVALID_ENUM
);
828 alSetError(pContext
, AL_INVALID_NAME
);
831 ProcessContext(pContext
);
835 AL_API
void AL_APIENTRY
alBufferiv(ALuint buffer
, ALenum eParam
, const ALint
* plValues
)
837 ALCcontext
*pContext
;
843 pContext
= GetContextSuspended();
844 if(!pContext
) return;
846 device
= pContext
->Device
;
847 if((ALBuf
=LookupBuffer(device
->BufferMap
, buffer
)) != NULL
)
852 if(ALBuf
->refcount
> 0)
853 alSetError(pContext
, AL_INVALID_OPERATION
);
854 else if(plValues
[0] < 0 || plValues
[1] < 0 ||
855 plValues
[0] >= plValues
[1] || ALBuf
->size
== 0)
856 alSetError(pContext
, AL_INVALID_VALUE
);
859 ALint maxlen
= ALBuf
->size
/ aluBytesFromFormat(ALBuf
->format
) /
860 aluChannelsFromFormat(ALBuf
->format
);
861 if(plValues
[0] > maxlen
|| plValues
[1] > maxlen
)
862 alSetError(pContext
, AL_INVALID_VALUE
);
865 ALBuf
->LoopStart
= plValues
[0];
866 ALBuf
->LoopEnd
= plValues
[1];
872 alSetError(pContext
, AL_INVALID_ENUM
);
878 alSetError(pContext
, AL_INVALID_NAME
);
881 ProcessContext(pContext
);
885 AL_API ALvoid AL_APIENTRY
alGetBufferf(ALuint buffer
, ALenum eParam
, ALfloat
*pflValue
)
887 ALCcontext
*pContext
;
890 pContext
= GetContextSuspended();
891 if(!pContext
) return;
895 device
= pContext
->Device
;
896 if(LookupBuffer(device
->BufferMap
, buffer
) != NULL
)
901 alSetError(pContext
, AL_INVALID_ENUM
);
907 alSetError(pContext
, AL_INVALID_NAME
);
912 alSetError(pContext
, AL_INVALID_VALUE
);
915 ProcessContext(pContext
);
919 AL_API
void AL_APIENTRY
alGetBuffer3f(ALuint buffer
, ALenum eParam
, ALfloat
* pflValue1
, ALfloat
* pflValue2
, ALfloat
* pflValue3
)
921 ALCcontext
*pContext
;
924 pContext
= GetContextSuspended();
925 if(!pContext
) return;
927 if ((pflValue1
) && (pflValue2
) && (pflValue3
))
929 device
= pContext
->Device
;
930 if(LookupBuffer(device
->BufferMap
, buffer
) != NULL
)
935 alSetError(pContext
, AL_INVALID_ENUM
);
941 alSetError(pContext
, AL_INVALID_NAME
);
946 alSetError(pContext
, AL_INVALID_VALUE
);
949 ProcessContext(pContext
);
953 AL_API
void AL_APIENTRY
alGetBufferfv(ALuint buffer
, ALenum eParam
, ALfloat
* pflValues
)
955 ALCcontext
*pContext
;
958 pContext
= GetContextSuspended();
959 if(!pContext
) return;
963 device
= pContext
->Device
;
964 if(LookupBuffer(device
->BufferMap
, buffer
) != NULL
)
969 alSetError(pContext
, AL_INVALID_ENUM
);
975 alSetError(pContext
, AL_INVALID_NAME
);
980 alSetError(pContext
, AL_INVALID_VALUE
);
983 ProcessContext(pContext
);
987 AL_API ALvoid AL_APIENTRY
alGetBufferi(ALuint buffer
, ALenum eParam
, ALint
*plValue
)
989 ALCcontext
*pContext
;
993 pContext
= GetContextSuspended();
994 if(!pContext
) return;
998 device
= pContext
->Device
;
999 if((pBuffer
=LookupBuffer(device
->BufferMap
, buffer
)) != NULL
)
1004 *plValue
= pBuffer
->frequency
;
1008 *plValue
= aluBytesFromFormat(pBuffer
->format
) * 8;
1012 *plValue
= aluChannelsFromFormat(pBuffer
->format
);
1016 *plValue
= pBuffer
->size
;
1020 alSetError(pContext
, AL_INVALID_ENUM
);
1026 alSetError(pContext
, AL_INVALID_NAME
);
1031 alSetError(pContext
, AL_INVALID_VALUE
);
1034 ProcessContext(pContext
);
1038 AL_API
void AL_APIENTRY
alGetBuffer3i(ALuint buffer
, ALenum eParam
, ALint
* plValue1
, ALint
* plValue2
, ALint
* plValue3
)
1040 ALCcontext
*pContext
;
1043 pContext
= GetContextSuspended();
1044 if(!pContext
) return;
1046 if ((plValue1
) && (plValue2
) && (plValue3
))
1048 device
= pContext
->Device
;
1049 if(LookupBuffer(device
->BufferMap
, buffer
) != NULL
)
1054 alSetError(pContext
, AL_INVALID_ENUM
);
1060 alSetError(pContext
, AL_INVALID_NAME
);
1065 alSetError(pContext
, AL_INVALID_VALUE
);
1068 ProcessContext(pContext
);
1072 AL_API
void AL_APIENTRY
alGetBufferiv(ALuint buffer
, ALenum eParam
, ALint
* plValues
)
1074 ALCcontext
*pContext
;
1078 pContext
= GetContextSuspended();
1079 if(!pContext
) return;
1083 device
= pContext
->Device
;
1084 if((ALBuf
=LookupBuffer(device
->BufferMap
, buffer
)) != NULL
)
1092 alGetBufferi(buffer
, eParam
, plValues
);
1095 case AL_LOOP_POINTS
:
1096 plValues
[0] = ALBuf
->LoopStart
;
1097 plValues
[1] = ALBuf
->LoopEnd
;
1101 alSetError(pContext
, AL_INVALID_ENUM
);
1107 alSetError(pContext
, AL_INVALID_NAME
);
1112 alSetError(pContext
, AL_INVALID_VALUE
);
1115 ProcessContext(pContext
);
1121 * Loads the specified data into the buffer, using the specified formats.
1122 * Currently, the new format must be 32-bit float, and must have the same
1123 * channel configuration as the original format. This does NOT handle
1124 * compressed formats (eg. IMA4).
1126 static ALenum
LoadData(ALbuffer
*ALBuf
, const ALvoid
*data
, ALsizei size
, ALuint freq
, ALenum OrigFormat
, ALenum NewFormat
)
1128 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
1129 ALuint NewChannels
= aluChannelsFromFormat(NewFormat
);
1130 ALuint OrigBytes
= aluBytesFromFormat(OrigFormat
);
1131 ALuint OrigChannels
= aluChannelsFromFormat(OrigFormat
);
1132 ALuint64 newsize
, allocsize
;
1135 assert(NewBytes
== 4);
1136 assert(NewChannels
== OrigChannels
);
1138 if ((size
%(OrigBytes
*OrigChannels
)) != 0)
1139 return AL_INVALID_VALUE
;
1141 // Allocate extra padding samples
1142 newsize
= size
/ OrigBytes
;
1143 allocsize
= (BUFFER_PADDING
*NewChannels
+ newsize
)*NewBytes
;
1144 if(allocsize
> INT_MAX
)
1145 return AL_OUT_OF_MEMORY
;
1147 temp
= realloc(ALBuf
->data
, allocsize
);
1148 if(!temp
) return AL_OUT_OF_MEMORY
;
1151 // Samples are converted here
1152 ConvertData(ALBuf
->data
, data
, OrigBytes
, newsize
);
1154 ALBuf
->format
= NewFormat
;
1155 ALBuf
->eOriginalFormat
= OrigFormat
;
1156 ALBuf
->size
= newsize
*NewBytes
;
1157 ALBuf
->frequency
= freq
;
1159 ALBuf
->LoopStart
= 0;
1160 ALBuf
->LoopEnd
= newsize
/ NewChannels
;
1162 ALBuf
->OriginalSize
= size
;
1163 ALBuf
->OriginalAlign
= OrigBytes
* OrigChannels
;
1168 static void ConvertData(ALfloat
*dst
, const ALvoid
*src
, ALint origBytes
, ALsizei len
)
1177 for(i
= 0;i
< len
;i
++)
1179 smp
= ((ALubyte
*)src
)[i
];
1180 dst
[i
] = ((smp
< 0x80) ? ((smp
-128)/128.0f
) : ((smp
-128)/127.0f
));
1185 for(i
= 0;i
< len
;i
++)
1187 smp
= ((ALshort
*)src
)[i
];
1188 dst
[i
] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1193 for(i
= 0;i
< len
;i
++)
1194 dst
[i
] = ((ALfloat
*)src
)[i
];
1198 for(i
= 0;i
< len
;i
++)
1199 dst
[i
] = ((ALdouble
*)src
)[i
];
1207 static void ConvertDataRear(ALfloat
*dst
, const ALvoid
*src
, ALint origBytes
, ALsizei len
)
1216 for(i
= 0;i
< len
;i
+=4)
1220 smp
= ((ALubyte
*)src
)[i
/2+0];
1221 dst
[i
+2] = ((smp
< 0x80) ? ((smp
-128)/128.0f
) : ((smp
-128)/127.0f
));
1222 smp
= ((ALubyte
*)src
)[i
/2+1];
1223 dst
[i
+3] = ((smp
< 0x80) ? ((smp
-128)/128.0f
) : ((smp
-128)/127.0f
));
1228 for(i
= 0;i
< len
;i
+=4)
1232 smp
= ((ALshort
*)src
)[i
/2+0];
1233 dst
[i
+2] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1234 smp
= ((ALshort
*)src
)[i
/2+1];
1235 dst
[i
+3] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1240 for(i
= 0;i
< len
;i
+=4)
1244 dst
[i
+2] = ((ALfloat
*)src
)[i
/2+0];
1245 dst
[i
+3] = ((ALfloat
*)src
)[i
/2+1];
1254 static void ConvertDataIMA4(ALfloat
*dst
, const ALvoid
*src
, ALint origChans
, ALsizei len
)
1256 const ALubyte
*IMAData
;
1257 ALint Sample
[2],Index
[2];
1265 for(i
= 0;i
< len
/origChans
;i
++)
1267 for(c
= 0;c
< origChans
;c
++)
1269 Sample
[c
] = IMAData
[0];
1270 Sample
[c
] |= IMAData
[1] << 8;
1271 Sample
[c
] = (Sample
[c
]^0x8000) - 32768;
1272 Index
[c
] = IMAData
[2];
1273 Index
[c
] |= IMAData
[3] << 8;
1274 Index
[c
] = (Index
[c
]^0x8000) - 32768;
1276 Index
[c
] = ((Index
[c
]<0) ? 0 : Index
[c
]);
1277 Index
[c
] = ((Index
[c
]>88) ? 88 : Index
[c
]);
1279 dst
[i
*65*origChans
+ c
] = ((Sample
[c
] < 0) ? (Sample
[c
]/32768.0f
) : (Sample
[c
]/32767.0f
));
1284 for(j
= 1;j
< 65;j
+= 8)
1286 for(c
= 0;c
< origChans
;c
++)
1288 IMACode
[c
] = *(IMAData
++);
1289 IMACode
[c
] |= *(IMAData
++) << 8;
1290 IMACode
[c
] |= *(IMAData
++) << 16;
1291 IMACode
[c
] |= *(IMAData
++) << 24;
1294 for(k
= 0;k
< 8;k
++)
1296 for(c
= 0;c
< origChans
;c
++)
1298 Sample
[c
] += ((g_IMAStep_size
[Index
[c
]]*g_IMACodeword_4
[IMACode
[c
]&15])/8);
1299 Index
[c
] += g_IMAIndex_adjust_4
[IMACode
[c
]&15];
1301 if(Sample
[c
] < -32768) Sample
[c
] = -32768;
1302 else if(Sample
[c
] > 32767) Sample
[c
] = 32767;
1304 if(Index
[c
]<0) Index
[c
] = 0;
1305 else if(Index
[c
]>88) Index
[c
] = 88;
1307 dst
[(i
*65+j
+k
)*origChans
+ c
] = ((Sample
[c
] < 0) ? (Sample
[c
]/32768.0f
) : (Sample
[c
]/32767.0f
));
1315 static void ConvertDataMULaw(ALfloat
*dst
, const ALvoid
*src
, ALsizei len
)
1321 for(i
= 0;i
< len
;i
++)
1323 smp
= muLawDecompressionTable
[((ALubyte
*)src
)[i
]];
1324 dst
[i
] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1328 static void ConvertDataMULawRear(ALfloat
*dst
, const ALvoid
*src
, ALsizei len
)
1334 for(i
= 0;i
< len
;i
+=4)
1338 smp
= muLawDecompressionTable
[((ALubyte
*)src
)[i
/2+0]];
1339 dst
[i
+2] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1340 smp
= muLawDecompressionTable
[((ALubyte
*)src
)[i
/2+1]];
1341 dst
[i
+3] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1346 * ReleaseALBuffers()
1348 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
1350 ALvoid
ReleaseALBuffers(ALCdevice
*device
)
1353 for(i
= 0;i
< device
->BufferMap
.size
;i
++)
1355 ALbuffer
*temp
= device
->BufferMap
.array
[i
].value
;
1356 device
->BufferMap
.array
[i
].value
= NULL
;
1358 // Release sample data
1361 // Release Buffer structure
1362 ALTHUNK_REMOVEENTRY(temp
->buffer
);
1363 memset(temp
, 0, sizeof(ALbuffer
));