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
31 #include "alDatabuffer.h"
35 static ALenum
LoadData(ALbuffer
*ALBuf
, const ALvoid
*data
, ALsizei size
, ALuint freq
, ALenum OrigFormat
, ALenum NewFormat
);
36 static void ConvertData(ALfloat
*dst
, const ALvoid
*src
, ALint origBytes
, ALsizei len
);
37 static void ConvertDataRear(ALfloat
*dst
, const ALvoid
*src
, ALint origBytes
, ALsizei len
);
38 static void ConvertDataIMA4(ALfloat
*dst
, const ALvoid
*src
, ALint origChans
, ALsizei len
);
39 static void ConvertDataMULaw(ALfloat
*dst
, const ALvoid
*src
, ALsizei len
);
40 static void ConvertDataMULawRear(ALfloat
*dst
, const ALvoid
*src
, ALsizei len
);
42 #define LookupBuffer(m, k) ((ALbuffer*)LookupUIntMapKey(&(m), (k)))
48 static const long g_IMAStep_size
[89]={ // IMA ADPCM Stepsize table
49 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
50 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
51 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
52 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
53 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493,10442,11487,12635,13899,
54 15289,16818,18500,20350,22358,24633,27086,29794,32767
57 static const long g_IMACodeword_4
[16]={ // IMA4 ADPCM Codeword decode table
58 1, 3, 5, 7, 9, 11, 13, 15,
59 -1,-3,-5,-7,-9,-11,-13,-15,
62 static const long g_IMAIndex_adjust_4
[16]={ // IMA4 ADPCM Step index adjust decode table
63 -1,-1,-1,-1, 2, 4, 6, 8,
64 -1,-1,-1,-1, 2, 4, 6, 8
67 static const ALshort muLawDecompressionTable
[256] = {
68 -32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956,
69 -23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764,
70 -15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412,
71 -11900,-11388,-10876,-10364, -9852, -9340, -8828, -8316,
72 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
73 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
74 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
75 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
76 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
77 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
78 -876, -844, -812, -780, -748, -716, -684, -652,
79 -620, -588, -556, -524, -492, -460, -428, -396,
80 -372, -356, -340, -324, -308, -292, -276, -260,
81 -244, -228, -212, -196, -180, -164, -148, -132,
82 -120, -112, -104, -96, -88, -80, -72, -64,
83 -56, -48, -40, -32, -24, -16, -8, 0,
84 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
85 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
86 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
87 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
88 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
89 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
90 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
91 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
92 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
93 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
94 876, 844, 812, 780, 748, 716, 684, 652,
95 620, 588, 556, 524, 492, 460, 428, 396,
96 372, 356, 340, 324, 308, 292, 276, 260,
97 244, 228, 212, 196, 180, 164, 148, 132,
98 120, 112, 104, 96, 88, 80, 72, 64,
99 56, 48, 40, 32, 24, 16, 8, 0
103 * alGenBuffers(ALsizei n, ALuint *puiBuffers)
105 * Generates n AL Buffers, and stores the Buffers Names in the array pointed to by puiBuffers
107 AL_API ALvoid AL_APIENTRY
alGenBuffers(ALsizei n
, ALuint
*buffers
)
112 Context
= GetContextSuspended();
115 // Check that we are actually generation some Buffers
118 ALCdevice
*device
= Context
->Device
;
121 // Check the pointer is valid (and points to enough memory to store Buffer Names)
122 if(!IsBadWritePtr((void*)buffers
, n
* sizeof(ALuint
)))
124 // Create all the new Buffers
127 ALbuffer
*buffer
= calloc(1, sizeof(ALbuffer
));
130 alSetError(Context
, AL_OUT_OF_MEMORY
);
131 alDeleteBuffers(i
, buffers
);
135 buffer
->buffer
= (ALuint
)ALTHUNK_ADDENTRY(buffer
);
136 err
= InsertUIntMapEntry(&device
->BufferMap
, buffer
->buffer
,
138 if(err
!= AL_NO_ERROR
)
140 ALTHUNK_REMOVEENTRY(buffer
->buffer
);
141 memset(buffer
, 0, sizeof(ALbuffer
));
144 alSetError(Context
, err
);
145 alDeleteBuffers(i
, buffers
);
148 buffers
[i
++] = buffer
->buffer
;
153 // Pointer does not point to enough memory to write Buffer names
154 alSetError(Context
, AL_INVALID_VALUE
);
158 ProcessContext(Context
);
162 * alDeleteBuffers(ALsizei n, ALuint *puiBuffers)
164 * Deletes the n AL Buffers pointed to by puiBuffers
166 AL_API ALvoid AL_APIENTRY
alDeleteBuffers(ALsizei n
, const ALuint
*puiBuffers
)
171 ALboolean bFailed
= AL_FALSE
;
173 Context
= GetContextSuspended();
176 // Check we are actually Deleting some Buffers
179 ALCdevice
*device
= Context
->Device
;
181 // Check that all the buffers are valid and can actually be deleted
182 for (i
= 0; i
< n
; i
++)
187 // Check for valid Buffer ID (can be NULL buffer)
188 if((ALBuf
=LookupBuffer(device
->BufferMap
, puiBuffers
[i
])) != NULL
)
190 if(ALBuf
->refcount
!= 0)
192 // Buffer still in use, cannot be deleted
193 alSetError(Context
, AL_INVALID_OPERATION
);
201 alSetError(Context
, AL_INVALID_NAME
);
207 // If all the Buffers were valid (and have Reference Counts of 0), then we can delete them
210 for (i
= 0; i
< n
; i
++)
212 if((ALBuf
=LookupBuffer(device
->BufferMap
, puiBuffers
[i
])) != NULL
)
214 // Release the memory used to store audio data
217 // Release buffer structure
218 RemoveUIntMapKey(&device
->BufferMap
, ALBuf
->buffer
);
219 ALTHUNK_REMOVEENTRY(ALBuf
->buffer
);
221 memset(ALBuf
, 0, sizeof(ALbuffer
));
228 alSetError(Context
, AL_INVALID_VALUE
);
230 ProcessContext(Context
);
234 * alIsBuffer(ALuint uiBuffer)
236 * Checks if ulBuffer is a valid Buffer Name
238 AL_API ALboolean AL_APIENTRY
alIsBuffer(ALuint buffer
)
243 Context
= GetContextSuspended();
244 if(!Context
) return AL_FALSE
;
246 result
= ((!buffer
|| LookupBuffer(Context
->Device
->BufferMap
, buffer
)) ?
249 ProcessContext(Context
);
255 * alBufferData(ALuint buffer,ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
257 * Fill buffer with audio data
259 AL_API ALvoid AL_APIENTRY
alBufferData(ALuint buffer
,ALenum format
,const ALvoid
*data
,ALsizei size
,ALsizei freq
)
267 Context
= GetContextSuspended();
270 device
= Context
->Device
;
271 if((ALBuf
=LookupBuffer(device
->BufferMap
, buffer
)) != NULL
)
273 if(Context
->SampleSource
)
277 if(Context
->SampleSource
->state
== MAPPED
)
279 alSetError(Context
, AL_INVALID_OPERATION
);
280 ProcessContext(Context
);
284 offset
= (const ALubyte
*)data
- (ALubyte
*)NULL
;
285 data
= Context
->SampleSource
->data
+ offset
;
288 if(ALBuf
->refcount
==0)
292 case AL_FORMAT_MONO8
:
293 case AL_FORMAT_MONO16
:
294 case AL_FORMAT_MONO_FLOAT32
:
295 case AL_FORMAT_MONO_DOUBLE_EXT
:
296 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_MONO_FLOAT32
);
297 if(err
!= AL_NO_ERROR
)
298 alSetError(Context
, err
);
301 case AL_FORMAT_STEREO8
:
302 case AL_FORMAT_STEREO16
:
303 case AL_FORMAT_STEREO_FLOAT32
:
304 case AL_FORMAT_STEREO_DOUBLE_EXT
:
305 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_STEREO_FLOAT32
);
306 if(err
!= AL_NO_ERROR
)
307 alSetError(Context
, err
);
310 case AL_FORMAT_REAR8
:
311 case AL_FORMAT_REAR16
:
312 case AL_FORMAT_REAR32
: {
313 ALenum NewFormat
= AL_FORMAT_QUAD32
;
314 ALuint NewChannels
= aluChannelsFromFormat(NewFormat
);
315 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
316 ALuint OrigBytes
= ((format
==AL_FORMAT_REAR8
) ? 1 :
317 ((format
==AL_FORMAT_REAR16
) ? 2 :
321 if((size
%(OrigBytes
*2)) != 0)
323 alSetError(Context
, AL_INVALID_VALUE
);
327 newsize
= size
/ OrigBytes
;
330 // Samples are converted here
331 temp
= realloc(ALBuf
->data
, (BUFFER_PADDING
*NewChannels
+ newsize
) * NewBytes
);
335 ConvertDataRear(ALBuf
->data
, data
, OrigBytes
, newsize
);
337 ALBuf
->format
= NewFormat
;
338 ALBuf
->eOriginalFormat
= format
;
339 ALBuf
->size
= newsize
*NewBytes
;
340 ALBuf
->frequency
= freq
;
342 ALBuf
->LoopStart
= 0;
343 ALBuf
->LoopEnd
= newsize
/ NewChannels
;
345 ALBuf
->OriginalSize
= size
;
346 ALBuf
->OriginalAlign
= OrigBytes
* 2;
349 alSetError(Context
, AL_OUT_OF_MEMORY
);
352 case AL_FORMAT_QUAD8_LOKI
:
353 case AL_FORMAT_QUAD16_LOKI
:
354 case AL_FORMAT_QUAD8
:
355 case AL_FORMAT_QUAD16
:
356 case AL_FORMAT_QUAD32
:
357 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_QUAD32
);
358 if(err
!= AL_NO_ERROR
)
359 alSetError(Context
, err
);
362 case AL_FORMAT_51CHN8
:
363 case AL_FORMAT_51CHN16
:
364 case AL_FORMAT_51CHN32
:
365 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_51CHN32
);
366 if(err
!= AL_NO_ERROR
)
367 alSetError(Context
, err
);
370 case AL_FORMAT_61CHN8
:
371 case AL_FORMAT_61CHN16
:
372 case AL_FORMAT_61CHN32
:
373 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_61CHN32
);
374 if(err
!= AL_NO_ERROR
)
375 alSetError(Context
, err
);
378 case AL_FORMAT_71CHN8
:
379 case AL_FORMAT_71CHN16
:
380 case AL_FORMAT_71CHN32
:
381 err
= LoadData(ALBuf
, data
, size
, freq
, format
, AL_FORMAT_71CHN32
);
382 if(err
!= AL_NO_ERROR
)
383 alSetError(Context
, err
);
386 case AL_FORMAT_MONO_IMA4
:
387 case AL_FORMAT_STEREO_IMA4
: {
388 int OrigChans
= ((format
==AL_FORMAT_MONO_IMA4
) ? 1 : 2);
389 ALenum NewFormat
= ((OrigChans
==1) ? AL_FORMAT_MONO_FLOAT32
:
390 AL_FORMAT_STEREO_FLOAT32
);
391 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
394 // Here is where things vary:
395 // nVidia and Apple use 64+1 samples per channel per block => block_size=36*chans bytes
396 // Most PC sound software uses 2040+1 samples per channel per block -> block_size=1024*chans bytes
397 if((size
%(36*OrigChans
)) != 0)
399 alSetError(Context
, AL_INVALID_VALUE
);
406 // Allocate extra padding samples
407 temp
= realloc(ALBuf
->data
, (BUFFER_PADDING
*OrigChans
+ newsize
)*NewBytes
);
411 ConvertDataIMA4(ALBuf
->data
, data
, OrigChans
, newsize
/65);
413 ALBuf
->format
= NewFormat
;
414 ALBuf
->eOriginalFormat
= format
;
415 ALBuf
->size
= newsize
*NewBytes
;
416 ALBuf
->frequency
= freq
;
418 ALBuf
->LoopStart
= 0;
419 ALBuf
->LoopEnd
= newsize
/ OrigChans
;
421 ALBuf
->OriginalSize
= size
;
422 ALBuf
->OriginalAlign
= 36 * OrigChans
;
425 alSetError(Context
, AL_OUT_OF_MEMORY
);
428 case AL_FORMAT_MONO_MULAW
:
429 case AL_FORMAT_STEREO_MULAW
:
430 case AL_FORMAT_QUAD_MULAW
:
431 case AL_FORMAT_51CHN_MULAW
:
432 case AL_FORMAT_61CHN_MULAW
:
433 case AL_FORMAT_71CHN_MULAW
: {
434 int Channels
= ((format
==AL_FORMAT_MONO_MULAW
) ? 1 :
435 ((format
==AL_FORMAT_STEREO_MULAW
) ? 2 :
436 ((format
==AL_FORMAT_QUAD_MULAW
) ? 4 :
437 ((format
==AL_FORMAT_51CHN_MULAW
) ? 6 :
438 ((format
==AL_FORMAT_61CHN_MULAW
) ? 7 : 8)))));
439 ALenum NewFormat
= ((Channels
==1) ? AL_FORMAT_MONO_FLOAT32
:
440 ((Channels
==2) ? AL_FORMAT_STEREO_FLOAT32
:
441 ((Channels
==4) ? AL_FORMAT_QUAD32
:
442 ((Channels
==6) ? AL_FORMAT_51CHN32
:
443 ((Channels
==7) ? AL_FORMAT_61CHN32
:
444 AL_FORMAT_71CHN32
)))));
445 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
447 if((size
%(1*Channels
)) != 0)
449 alSetError(Context
, AL_INVALID_VALUE
);
453 // Allocate extra padding samples
454 temp
= realloc(ALBuf
->data
, (BUFFER_PADDING
*Channels
+ size
)*NewBytes
);
458 ConvertDataMULaw(ALBuf
->data
, data
, size
);
460 ALBuf
->format
= NewFormat
;
461 ALBuf
->eOriginalFormat
= format
;
462 ALBuf
->size
= size
*NewBytes
;
463 ALBuf
->frequency
= freq
;
465 ALBuf
->LoopStart
= 0;
466 ALBuf
->LoopEnd
= size
/ Channels
;
468 ALBuf
->OriginalSize
= size
;
469 ALBuf
->OriginalAlign
= 1 * Channels
;
472 alSetError(Context
, AL_OUT_OF_MEMORY
);
475 case AL_FORMAT_REAR_MULAW
: {
477 ALenum NewFormat
= AL_FORMAT_QUAD32
;
478 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
479 ALuint NewChannels
= aluChannelsFromFormat(NewFormat
);
482 if((size
%(1*OrigChans
)) != 0)
484 alSetError(Context
, AL_INVALID_VALUE
);
490 // Allocate extra padding samples
491 temp
= realloc(ALBuf
->data
, (BUFFER_PADDING
*NewChannels
+ newsize
)*NewBytes
);
495 ConvertDataMULawRear(ALBuf
->data
, data
, newsize
);
497 ALBuf
->format
= NewFormat
;
498 ALBuf
->eOriginalFormat
= format
;
499 ALBuf
->size
= newsize
*NewBytes
;
500 ALBuf
->frequency
= freq
;
502 ALBuf
->LoopStart
= 0;
503 ALBuf
->LoopEnd
= newsize
/ NewChannels
;
505 ALBuf
->OriginalSize
= size
;
506 ALBuf
->OriginalAlign
= 1 * OrigChans
;
509 alSetError(Context
, AL_OUT_OF_MEMORY
);
513 alSetError(Context
, AL_INVALID_ENUM
);
519 // Buffer is in use, or data is a NULL pointer
520 alSetError(Context
, AL_INVALID_VALUE
);
525 // Invalid Buffer Name
526 alSetError(Context
, AL_INVALID_NAME
);
529 ProcessContext(Context
);
533 * alBufferSubDataEXT(ALuint buffer,ALenum format,ALvoid *data,ALsizei offset,ALsizei length)
535 * Fill buffer with audio data
537 AL_API ALvoid AL_APIENTRY
alBufferSubDataEXT(ALuint buffer
,ALenum format
,const ALvoid
*data
,ALsizei offset
,ALsizei length
)
543 Context
= GetContextSuspended();
546 device
= Context
->Device
;
547 if((ALBuf
=LookupBuffer(device
->BufferMap
, buffer
)) != NULL
)
549 if(Context
->SampleSource
)
553 if(Context
->SampleSource
->state
== MAPPED
)
555 alSetError(Context
, AL_INVALID_OPERATION
);
556 ProcessContext(Context
);
560 offset
= (const ALubyte
*)data
- (ALubyte
*)NULL
;
561 data
= Context
->SampleSource
->data
+ offset
;
564 if(length
< 0 || offset
< 0 || (length
> 0 && data
== NULL
))
566 // data is NULL or offset/length is negative
567 alSetError(Context
, AL_INVALID_VALUE
);
569 else if(ALBuf
->eOriginalFormat
!= format
)
570 alSetError(Context
, AL_INVALID_ENUM
);
571 else if(ALBuf
->OriginalAlign
== 0 ||
572 (offset
%ALBuf
->OriginalAlign
) != 0 ||
573 (length
%ALBuf
->OriginalAlign
) != 0 ||
574 offset
+length
> ALBuf
->OriginalSize
)
575 alSetError(Context
, AL_INVALID_VALUE
);
580 case AL_FORMAT_MONO8
:
581 case AL_FORMAT_MONO16
:
582 case AL_FORMAT_MONO_FLOAT32
:
583 case AL_FORMAT_MONO_DOUBLE_EXT
:
584 case AL_FORMAT_STEREO8
:
585 case AL_FORMAT_STEREO16
:
586 case AL_FORMAT_STEREO_FLOAT32
:
587 case AL_FORMAT_STEREO_DOUBLE_EXT
:
588 case AL_FORMAT_QUAD8_LOKI
:
589 case AL_FORMAT_QUAD16_LOKI
:
590 case AL_FORMAT_QUAD8
:
591 case AL_FORMAT_QUAD16
:
592 case AL_FORMAT_QUAD32
:
593 case AL_FORMAT_51CHN8
:
594 case AL_FORMAT_51CHN16
:
595 case AL_FORMAT_51CHN32
:
596 case AL_FORMAT_61CHN8
:
597 case AL_FORMAT_61CHN16
:
598 case AL_FORMAT_61CHN32
:
599 case AL_FORMAT_71CHN8
:
600 case AL_FORMAT_71CHN16
:
601 case AL_FORMAT_71CHN32
: {
602 ALuint Bytes
= aluBytesFromFormat(format
);
607 ConvertData(&ALBuf
->data
[offset
], data
, Bytes
, length
);
610 case AL_FORMAT_REAR8
:
611 case AL_FORMAT_REAR16
:
612 case AL_FORMAT_REAR32
: {
613 ALuint Bytes
= ((format
==AL_FORMAT_REAR8
) ? 1 :
614 ((format
==AL_FORMAT_REAR16
) ? 2 :
622 ConvertDataRear(&ALBuf
->data
[offset
], data
, Bytes
, length
);
625 case AL_FORMAT_MONO_IMA4
:
626 case AL_FORMAT_STEREO_IMA4
: {
627 int Channels
= aluChannelsFromFormat(ALBuf
->format
);
629 // offset -> sample*channel offset, length -> block count
634 ConvertDataIMA4(&ALBuf
->data
[offset
], data
, Channels
, length
);
637 case AL_FORMAT_MONO_MULAW
:
638 case AL_FORMAT_STEREO_MULAW
:
639 case AL_FORMAT_QUAD_MULAW
:
640 case AL_FORMAT_51CHN_MULAW
:
641 case AL_FORMAT_61CHN_MULAW
:
642 case AL_FORMAT_71CHN_MULAW
:
643 ConvertDataMULaw(&ALBuf
->data
[offset
], data
, length
);
646 case AL_FORMAT_REAR_MULAW
:
649 ConvertDataMULawRear(&ALBuf
->data
[offset
], data
, length
);
653 alSetError(Context
, AL_INVALID_ENUM
);
660 // Invalid Buffer Name
661 alSetError(Context
, AL_INVALID_NAME
);
664 ProcessContext(Context
);
668 AL_API
void AL_APIENTRY
alBufferf(ALuint buffer
, ALenum eParam
, ALfloat flValue
)
670 ALCcontext
*pContext
;
675 pContext
= GetContextSuspended();
676 if(!pContext
) return;
678 device
= pContext
->Device
;
679 if(LookupBuffer(device
->BufferMap
, buffer
) != NULL
)
684 alSetError(pContext
, AL_INVALID_ENUM
);
690 alSetError(pContext
, AL_INVALID_NAME
);
693 ProcessContext(pContext
);
697 AL_API
void AL_APIENTRY
alBuffer3f(ALuint buffer
, ALenum eParam
, ALfloat flValue1
, ALfloat flValue2
, ALfloat flValue3
)
699 ALCcontext
*pContext
;
706 pContext
= GetContextSuspended();
707 if(!pContext
) return;
709 device
= pContext
->Device
;
710 if(LookupBuffer(device
->BufferMap
, buffer
) != NULL
)
715 alSetError(pContext
, AL_INVALID_ENUM
);
721 alSetError(pContext
, AL_INVALID_NAME
);
724 ProcessContext(pContext
);
728 AL_API
void AL_APIENTRY
alBufferfv(ALuint buffer
, ALenum eParam
, const ALfloat
* flValues
)
730 ALCcontext
*pContext
;
735 pContext
= GetContextSuspended();
736 if(!pContext
) return;
738 device
= pContext
->Device
;
739 if(LookupBuffer(device
->BufferMap
, buffer
) != NULL
)
744 alSetError(pContext
, AL_INVALID_ENUM
);
750 alSetError(pContext
, AL_INVALID_NAME
);
753 ProcessContext(pContext
);
757 AL_API
void AL_APIENTRY
alBufferi(ALuint buffer
, ALenum eParam
, ALint lValue
)
759 ALCcontext
*pContext
;
764 pContext
= GetContextSuspended();
765 if(!pContext
) return;
767 device
= pContext
->Device
;
768 if(LookupBuffer(device
->BufferMap
, buffer
) != NULL
)
773 alSetError(pContext
, AL_INVALID_ENUM
);
779 alSetError(pContext
, AL_INVALID_NAME
);
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
)
804 alSetError(pContext
, AL_INVALID_ENUM
);
810 alSetError(pContext
, AL_INVALID_NAME
);
813 ProcessContext(pContext
);
817 AL_API
void AL_APIENTRY
alBufferiv(ALuint buffer
, ALenum eParam
, const ALint
* plValues
)
819 ALCcontext
*pContext
;
825 pContext
= GetContextSuspended();
826 if(!pContext
) return;
828 device
= pContext
->Device
;
829 if((ALBuf
=LookupBuffer(device
->BufferMap
, buffer
)) != NULL
)
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
/ aluBytesFromFormat(ALBuf
->format
) /
842 aluChannelsFromFormat(ALBuf
->format
);
843 if(plValues
[0] > maxlen
|| plValues
[1] > maxlen
)
844 alSetError(pContext
, AL_INVALID_VALUE
);
847 ALBuf
->LoopStart
= plValues
[0];
848 ALBuf
->LoopEnd
= plValues
[1];
854 alSetError(pContext
, AL_INVALID_ENUM
);
860 alSetError(pContext
, AL_INVALID_NAME
);
863 ProcessContext(pContext
);
867 AL_API ALvoid AL_APIENTRY
alGetBufferf(ALuint buffer
, ALenum eParam
, ALfloat
*pflValue
)
869 ALCcontext
*pContext
;
872 pContext
= GetContextSuspended();
873 if(!pContext
) return;
877 device
= pContext
->Device
;
878 if(LookupBuffer(device
->BufferMap
, buffer
) != NULL
)
883 alSetError(pContext
, AL_INVALID_ENUM
);
889 alSetError(pContext
, AL_INVALID_NAME
);
894 alSetError(pContext
, AL_INVALID_VALUE
);
897 ProcessContext(pContext
);
901 AL_API
void AL_APIENTRY
alGetBuffer3f(ALuint buffer
, ALenum eParam
, ALfloat
* pflValue1
, ALfloat
* pflValue2
, ALfloat
* pflValue3
)
903 ALCcontext
*pContext
;
906 pContext
= GetContextSuspended();
907 if(!pContext
) return;
909 if ((pflValue1
) && (pflValue2
) && (pflValue3
))
911 device
= pContext
->Device
;
912 if(LookupBuffer(device
->BufferMap
, buffer
) != NULL
)
917 alSetError(pContext
, AL_INVALID_ENUM
);
923 alSetError(pContext
, AL_INVALID_NAME
);
928 alSetError(pContext
, AL_INVALID_VALUE
);
931 ProcessContext(pContext
);
935 AL_API
void AL_APIENTRY
alGetBufferfv(ALuint buffer
, ALenum eParam
, ALfloat
* pflValues
)
937 ALCcontext
*pContext
;
940 pContext
= GetContextSuspended();
941 if(!pContext
) return;
945 device
= pContext
->Device
;
946 if(LookupBuffer(device
->BufferMap
, buffer
) != NULL
)
951 alSetError(pContext
, AL_INVALID_ENUM
);
957 alSetError(pContext
, AL_INVALID_NAME
);
962 alSetError(pContext
, AL_INVALID_VALUE
);
965 ProcessContext(pContext
);
969 AL_API ALvoid AL_APIENTRY
alGetBufferi(ALuint buffer
, ALenum eParam
, ALint
*plValue
)
971 ALCcontext
*pContext
;
975 pContext
= GetContextSuspended();
976 if(!pContext
) return;
980 device
= pContext
->Device
;
981 if((pBuffer
=LookupBuffer(device
->BufferMap
, buffer
)) != NULL
)
986 *plValue
= pBuffer
->frequency
;
990 *plValue
= aluBytesFromFormat(pBuffer
->format
) * 8;
994 *plValue
= aluChannelsFromFormat(pBuffer
->format
);
998 *plValue
= pBuffer
->size
;
1002 alSetError(pContext
, AL_INVALID_ENUM
);
1008 alSetError(pContext
, AL_INVALID_NAME
);
1013 alSetError(pContext
, AL_INVALID_VALUE
);
1016 ProcessContext(pContext
);
1020 AL_API
void AL_APIENTRY
alGetBuffer3i(ALuint buffer
, ALenum eParam
, ALint
* plValue1
, ALint
* plValue2
, ALint
* plValue3
)
1022 ALCcontext
*pContext
;
1025 pContext
= GetContextSuspended();
1026 if(!pContext
) return;
1028 if ((plValue1
) && (plValue2
) && (plValue3
))
1030 device
= pContext
->Device
;
1031 if(LookupBuffer(device
->BufferMap
, buffer
) != NULL
)
1036 alSetError(pContext
, AL_INVALID_ENUM
);
1042 alSetError(pContext
, AL_INVALID_NAME
);
1047 alSetError(pContext
, AL_INVALID_VALUE
);
1050 ProcessContext(pContext
);
1054 AL_API
void AL_APIENTRY
alGetBufferiv(ALuint buffer
, ALenum eParam
, ALint
* plValues
)
1056 ALCcontext
*pContext
;
1060 pContext
= GetContextSuspended();
1061 if(!pContext
) return;
1065 device
= pContext
->Device
;
1066 if((ALBuf
=LookupBuffer(device
->BufferMap
, buffer
)) != NULL
)
1074 alGetBufferi(buffer
, eParam
, plValues
);
1077 case AL_LOOP_POINTS
:
1078 plValues
[0] = ALBuf
->LoopStart
;
1079 plValues
[1] = ALBuf
->LoopEnd
;
1083 alSetError(pContext
, AL_INVALID_ENUM
);
1089 alSetError(pContext
, AL_INVALID_NAME
);
1094 alSetError(pContext
, AL_INVALID_VALUE
);
1097 ProcessContext(pContext
);
1103 * Loads the specified data into the buffer, using the specified formats.
1104 * Currently, the new format must be 32-bit float, and must have the same
1105 * channel configuration as the original format. This does NOT handle
1106 * compressed formats (eg. IMA4).
1108 static ALenum
LoadData(ALbuffer
*ALBuf
, const ALvoid
*data
, ALsizei size
, ALuint freq
, ALenum OrigFormat
, ALenum NewFormat
)
1110 ALuint NewBytes
= aluBytesFromFormat(NewFormat
);
1111 ALuint NewChannels
= aluChannelsFromFormat(NewFormat
);
1112 ALuint OrigBytes
= aluBytesFromFormat(OrigFormat
);
1113 ALuint OrigChannels
= aluChannelsFromFormat(OrigFormat
);
1117 assert(NewBytes
== 4);
1118 assert(NewChannels
== OrigChannels
);
1120 if ((size
%(OrigBytes
*OrigChannels
)) != 0)
1121 return AL_INVALID_VALUE
;
1123 // Samples are converted here
1124 newsize
= size
/ OrigBytes
;
1125 temp
= realloc(ALBuf
->data
, (BUFFER_PADDING
*NewChannels
+ newsize
) * NewBytes
);
1126 if(!temp
) return AL_OUT_OF_MEMORY
;
1129 ConvertData(ALBuf
->data
, data
, OrigBytes
, newsize
);
1131 ALBuf
->format
= NewFormat
;
1132 ALBuf
->eOriginalFormat
= OrigFormat
;
1133 ALBuf
->size
= newsize
*NewBytes
;
1134 ALBuf
->frequency
= freq
;
1136 ALBuf
->LoopStart
= 0;
1137 ALBuf
->LoopEnd
= newsize
/ NewChannels
;
1139 ALBuf
->OriginalSize
= size
;
1140 ALBuf
->OriginalAlign
= OrigBytes
* OrigChannels
;
1145 static void ConvertData(ALfloat
*dst
, const ALvoid
*src
, ALint origBytes
, ALsizei len
)
1154 for(i
= 0;i
< len
;i
++)
1156 smp
= ((ALubyte
*)src
)[i
];
1157 dst
[i
] = ((smp
< 0x80) ? ((smp
-128)/128.0f
) : ((smp
-128)/127.0f
));
1162 for(i
= 0;i
< len
;i
++)
1164 smp
= ((ALshort
*)src
)[i
];
1165 dst
[i
] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1170 for(i
= 0;i
< len
;i
++)
1171 dst
[i
] = ((ALfloat
*)src
)[i
];
1175 for(i
= 0;i
< len
;i
++)
1176 dst
[i
] = ((ALdouble
*)src
)[i
];
1184 static void ConvertDataRear(ALfloat
*dst
, const ALvoid
*src
, ALint origBytes
, ALsizei len
)
1193 for(i
= 0;i
< len
;i
+=4)
1197 smp
= ((ALubyte
*)src
)[i
/2+0];
1198 dst
[i
+2] = ((smp
< 0x80) ? ((smp
-128)/128.0f
) : ((smp
-128)/127.0f
));
1199 smp
= ((ALubyte
*)src
)[i
/2+1];
1200 dst
[i
+3] = ((smp
< 0x80) ? ((smp
-128)/128.0f
) : ((smp
-128)/127.0f
));
1205 for(i
= 0;i
< len
;i
+=4)
1209 smp
= ((ALshort
*)src
)[i
/2+0];
1210 dst
[i
+2] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1211 smp
= ((ALshort
*)src
)[i
/2+1];
1212 dst
[i
+3] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1217 for(i
= 0;i
< len
;i
+=4)
1221 dst
[i
+2] = ((ALfloat
*)src
)[i
/2+0];
1222 dst
[i
+3] = ((ALfloat
*)src
)[i
/2+1];
1231 static void ConvertDataIMA4(ALfloat
*dst
, const ALvoid
*src
, ALint origChans
, ALsizei len
)
1233 const ALubyte
*IMAData
;
1234 ALint Sample
[2],Index
[2];
1242 for(i
= 0;i
< len
/origChans
;i
++)
1244 for(c
= 0;c
< origChans
;c
++)
1246 Sample
[c
] = IMAData
[0];
1247 Sample
[c
] |= IMAData
[1] << 8;
1248 Sample
[c
] = (Sample
[c
]^0x8000) - 32768;
1249 Index
[c
] = IMAData
[2];
1250 Index
[c
] |= IMAData
[3] << 8;
1251 Index
[c
] = (Index
[c
]^0x8000) - 32768;
1253 Index
[c
] = ((Index
[c
]<0) ? 0 : Index
[c
]);
1254 Index
[c
] = ((Index
[c
]>88) ? 88 : Index
[c
]);
1256 dst
[i
*65*origChans
+ c
] = ((Sample
[c
] < 0) ? (Sample
[c
]/32768.0f
) : (Sample
[c
]/32767.0f
));
1261 for(j
= 1;j
< 65;j
+= 8)
1263 for(c
= 0;c
< origChans
;c
++)
1265 IMACode
[c
] = *(IMAData
++);
1266 IMACode
[c
] |= *(IMAData
++) << 8;
1267 IMACode
[c
] |= *(IMAData
++) << 16;
1268 IMACode
[c
] |= *(IMAData
++) << 24;
1271 for(k
= 0;k
< 8;k
++)
1273 for(c
= 0;c
< origChans
;c
++)
1275 Sample
[c
] += ((g_IMAStep_size
[Index
[c
]]*g_IMACodeword_4
[IMACode
[c
]&15])/8);
1276 Index
[c
] += g_IMAIndex_adjust_4
[IMACode
[c
]&15];
1278 if(Sample
[c
] < -32768) Sample
[c
] = -32768;
1279 else if(Sample
[c
] > 32767) Sample
[c
] = 32767;
1281 if(Index
[c
]<0) Index
[c
] = 0;
1282 else if(Index
[c
]>88) Index
[c
] = 88;
1284 dst
[(i
*65+j
+k
)*origChans
+ c
] = ((Sample
[c
] < 0) ? (Sample
[c
]/32768.0f
) : (Sample
[c
]/32767.0f
));
1292 static void ConvertDataMULaw(ALfloat
*dst
, const ALvoid
*src
, ALsizei len
)
1298 for(i
= 0;i
< len
;i
++)
1300 smp
= muLawDecompressionTable
[((ALubyte
*)src
)[i
]];
1301 dst
[i
] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1305 static void ConvertDataMULawRear(ALfloat
*dst
, const ALvoid
*src
, ALsizei len
)
1311 for(i
= 0;i
< len
;i
+=4)
1315 smp
= muLawDecompressionTable
[((ALubyte
*)src
)[i
/2+0]];
1316 dst
[i
+2] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1317 smp
= muLawDecompressionTable
[((ALubyte
*)src
)[i
/2+1]];
1318 dst
[i
+3] = ((smp
< 0) ? (smp
/32768.0f
) : (smp
/32767.0f
));
1323 * ReleaseALBuffers()
1325 * INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
1327 ALvoid
ReleaseALBuffers(ALCdevice
*device
)
1330 for(i
= 0;i
< device
->BufferMap
.size
;i
++)
1332 ALbuffer
*temp
= device
->BufferMap
.array
[i
].value
;
1333 device
->BufferMap
.array
[i
].value
= NULL
;
1335 // Release sample data
1338 // Release Buffer structure
1339 ALTHUNK_REMOVEENTRY(temp
->buffer
);
1340 memset(temp
, 0, sizeof(ALbuffer
));