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.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
36 #include "sample_cvt.h"
39 extern inline void LockBuffersRead(ALCdevice
*device
);
40 extern inline void UnlockBuffersRead(ALCdevice
*device
);
41 extern inline void LockBuffersWrite(ALCdevice
*device
);
42 extern inline void UnlockBuffersWrite(ALCdevice
*device
);
43 extern inline struct ALbuffer
*LookupBuffer(ALCdevice
*device
, ALuint id
);
44 extern inline struct ALbuffer
*RemoveBuffer(ALCdevice
*device
, ALuint id
);
45 extern inline ALsizei
FrameSizeFromUserFmt(enum UserFmtChannels chans
, enum UserFmtType type
);
46 extern inline ALsizei
FrameSizeFromFmt(enum FmtChannels chans
, enum FmtType type
);
48 static ALboolean
IsValidType(ALenum type
);
49 static ALboolean
IsValidChannels(ALenum channels
);
50 static ALboolean
DecomposeUserFormat(ALenum format
, enum UserFmtChannels
*chans
, enum UserFmtType
*type
);
51 static ALboolean
DecomposeFormat(ALenum format
, enum FmtChannels
*chans
, enum FmtType
*type
);
52 static ALboolean
SanitizeAlignment(enum UserFmtType type
, ALsizei
*align
);
55 AL_API ALvoid AL_APIENTRY
alGenBuffers(ALsizei n
, ALuint
*buffers
)
60 context
= GetContextRef();
64 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
66 for(cur
= 0;cur
< n
;cur
++)
68 ALbuffer
*buffer
= NewBuffer(context
);
71 alDeleteBuffers(cur
, buffers
);
75 buffers
[cur
] = buffer
->id
;
79 ALCcontext_DecRef(context
);
82 AL_API ALvoid AL_APIENTRY
alDeleteBuffers(ALsizei n
, const ALuint
*buffers
)
89 context
= GetContextRef();
92 device
= context
->Device
;
94 LockBuffersWrite(device
);
96 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
103 /* Check for valid Buffer ID */
104 if((ALBuf
=LookupBuffer(device
, buffers
[i
])) == NULL
)
105 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
106 if(ReadRef(&ALBuf
->ref
) != 0)
107 SET_ERROR_AND_GOTO(context
, AL_INVALID_OPERATION
, done
);
112 if((ALBuf
=LookupBuffer(device
, buffers
[i
])) != NULL
)
113 DeleteBuffer(device
, ALBuf
);
117 UnlockBuffersWrite(device
);
118 ALCcontext_DecRef(context
);
121 AL_API ALboolean AL_APIENTRY
alIsBuffer(ALuint buffer
)
126 context
= GetContextRef();
127 if(!context
) return AL_FALSE
;
129 LockBuffersRead(context
->Device
);
130 ret
= ((!buffer
|| LookupBuffer(context
->Device
, buffer
)) ?
132 UnlockBuffersRead(context
->Device
);
134 ALCcontext_DecRef(context
);
140 AL_API ALvoid AL_APIENTRY
alBufferData(ALuint buffer
, ALenum format
, const ALvoid
*data
, ALsizei size
, ALsizei freq
)
142 enum UserFmtChannels srcchannels
= UserFmtMono
;
143 enum UserFmtType srctype
= UserFmtByte
;
147 ALenum newformat
= AL_NONE
;
152 context
= GetContextRef();
155 device
= context
->Device
;
156 LockBuffersRead(device
);
157 if((albuf
=LookupBuffer(device
, buffer
)) == NULL
)
158 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
159 if(!(size
>= 0 && freq
> 0))
160 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
161 if(DecomposeUserFormat(format
, &srcchannels
, &srctype
) == AL_FALSE
)
162 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
164 align
= ATOMIC_LOAD_SEQ(&albuf
->UnpackAlign
);
165 if(SanitizeAlignment(srctype
, &align
) == AL_FALSE
)
166 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
174 framesize
= FrameSizeFromUserFmt(srcchannels
, srctype
) * align
;
175 if((size
%framesize
) != 0)
176 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
178 err
= LoadData(albuf
, freq
, format
, size
/framesize
*align
,
179 srcchannels
, srctype
, data
, align
, AL_TRUE
);
180 if(err
!= AL_NO_ERROR
)
181 SET_ERROR_AND_GOTO(context
, err
, done
);
187 framesize
= FrameSizeFromUserFmt(srcchannels
, srctype
) * align
;
188 if((size
%framesize
) != 0)
189 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
193 case UserFmtMono
: newformat
= AL_FORMAT_MONO_FLOAT32
; break;
194 case UserFmtStereo
: newformat
= AL_FORMAT_STEREO_FLOAT32
; break;
195 case UserFmtRear
: newformat
= AL_FORMAT_REAR32
; break;
196 case UserFmtQuad
: newformat
= AL_FORMAT_QUAD32
; break;
197 case UserFmtX51
: newformat
= AL_FORMAT_51CHN32
; break;
198 case UserFmtX61
: newformat
= AL_FORMAT_61CHN32
; break;
199 case UserFmtX71
: newformat
= AL_FORMAT_71CHN32
; break;
200 case UserFmtBFormat2D
: newformat
= AL_FORMAT_BFORMAT2D_FLOAT32
; break;
201 case UserFmtBFormat3D
: newformat
= AL_FORMAT_BFORMAT3D_FLOAT32
; break;
203 err
= LoadData(albuf
, freq
, newformat
, size
/framesize
*align
,
204 srcchannels
, srctype
, data
, align
, AL_TRUE
);
205 if(err
!= AL_NO_ERROR
)
206 SET_ERROR_AND_GOTO(context
, err
, done
);
211 framesize
= FrameSizeFromUserFmt(srcchannels
, srctype
) * align
;
212 if((size
%framesize
) != 0)
213 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
217 case UserFmtMono
: newformat
= AL_FORMAT_MONO16
; break;
218 case UserFmtStereo
: newformat
= AL_FORMAT_STEREO16
; break;
219 case UserFmtRear
: newformat
= AL_FORMAT_REAR16
; break;
220 case UserFmtQuad
: newformat
= AL_FORMAT_QUAD16
; break;
221 case UserFmtX51
: newformat
= AL_FORMAT_51CHN16
; break;
222 case UserFmtX61
: newformat
= AL_FORMAT_61CHN16
; break;
223 case UserFmtX71
: newformat
= AL_FORMAT_71CHN16
; break;
224 case UserFmtBFormat2D
: newformat
= AL_FORMAT_BFORMAT2D_16
; break;
225 case UserFmtBFormat3D
: newformat
= AL_FORMAT_BFORMAT3D_16
; break;
227 err
= LoadData(albuf
, freq
, newformat
, size
/framesize
*align
,
228 srcchannels
, srctype
, data
, align
, AL_TRUE
);
229 if(err
!= AL_NO_ERROR
)
230 SET_ERROR_AND_GOTO(context
, err
, done
);
234 framesize
= (align
-1)/2 + 4;
235 framesize
*= ChannelsFromUserFmt(srcchannels
);
236 if((size
%framesize
) != 0)
237 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
241 case UserFmtMono
: newformat
= AL_FORMAT_MONO16
; break;
242 case UserFmtStereo
: newformat
= AL_FORMAT_STEREO16
; break;
243 case UserFmtRear
: newformat
= AL_FORMAT_REAR16
; break;
244 case UserFmtQuad
: newformat
= AL_FORMAT_QUAD16
; break;
245 case UserFmtX51
: newformat
= AL_FORMAT_51CHN16
; break;
246 case UserFmtX61
: newformat
= AL_FORMAT_61CHN16
; break;
247 case UserFmtX71
: newformat
= AL_FORMAT_71CHN16
; break;
248 case UserFmtBFormat2D
: newformat
= AL_FORMAT_BFORMAT2D_16
; break;
249 case UserFmtBFormat3D
: newformat
= AL_FORMAT_BFORMAT3D_16
; break;
251 err
= LoadData(albuf
, freq
, newformat
, size
/framesize
*align
,
252 srcchannels
, srctype
, data
, align
, AL_TRUE
);
253 if(err
!= AL_NO_ERROR
)
254 SET_ERROR_AND_GOTO(context
, err
, done
);
258 framesize
= (align
-2)/2 + 7;
259 framesize
*= ChannelsFromUserFmt(srcchannels
);
260 if((size
%framesize
) != 0)
261 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
265 case UserFmtMono
: newformat
= AL_FORMAT_MONO16
; break;
266 case UserFmtStereo
: newformat
= AL_FORMAT_STEREO16
; break;
267 case UserFmtRear
: newformat
= AL_FORMAT_REAR16
; break;
268 case UserFmtQuad
: newformat
= AL_FORMAT_QUAD16
; break;
269 case UserFmtX51
: newformat
= AL_FORMAT_51CHN16
; break;
270 case UserFmtX61
: newformat
= AL_FORMAT_61CHN16
; break;
271 case UserFmtX71
: newformat
= AL_FORMAT_71CHN16
; break;
272 case UserFmtBFormat2D
: newformat
= AL_FORMAT_BFORMAT2D_16
; break;
273 case UserFmtBFormat3D
: newformat
= AL_FORMAT_BFORMAT3D_16
; break;
275 err
= LoadData(albuf
, freq
, newformat
, size
/framesize
*align
,
276 srcchannels
, srctype
, data
, align
, AL_TRUE
);
277 if(err
!= AL_NO_ERROR
)
278 SET_ERROR_AND_GOTO(context
, err
, done
);
283 UnlockBuffersRead(device
);
284 ALCcontext_DecRef(context
);
287 AL_API ALvoid AL_APIENTRY
alBufferSubDataSOFT(ALuint buffer
, ALenum format
, const ALvoid
*data
, ALsizei offset
, ALsizei length
)
289 enum UserFmtChannels srcchannels
= UserFmtMono
;
290 enum UserFmtType srctype
= UserFmtByte
;
299 context
= GetContextRef();
302 device
= context
->Device
;
303 LockBuffersRead(device
);
304 if((albuf
=LookupBuffer(device
, buffer
)) == NULL
)
305 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
306 if(!(length
>= 0 && offset
>= 0))
307 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
308 if(DecomposeUserFormat(format
, &srcchannels
, &srctype
) == AL_FALSE
)
309 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
311 WriteLock(&albuf
->lock
);
312 align
= ATOMIC_LOAD_SEQ(&albuf
->UnpackAlign
);
313 if(SanitizeAlignment(srctype
, &align
) == AL_FALSE
)
315 WriteUnlock(&albuf
->lock
);
316 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
318 if(srcchannels
!= albuf
->OriginalChannels
|| srctype
!= albuf
->OriginalType
)
320 WriteUnlock(&albuf
->lock
);
321 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
323 if(align
!= albuf
->OriginalAlign
)
325 WriteUnlock(&albuf
->lock
);
326 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
329 if(albuf
->OriginalType
== UserFmtIMA4
)
331 byte_align
= (albuf
->OriginalAlign
-1)/2 + 4;
332 byte_align
*= ChannelsFromUserFmt(albuf
->OriginalChannels
);
334 else if(albuf
->OriginalType
== UserFmtMSADPCM
)
336 byte_align
= (albuf
->OriginalAlign
-2)/2 + 7;
337 byte_align
*= ChannelsFromUserFmt(albuf
->OriginalChannels
);
341 byte_align
= albuf
->OriginalAlign
;
342 byte_align
*= FrameSizeFromUserFmt(albuf
->OriginalChannels
,
343 albuf
->OriginalType
);
346 if(offset
> albuf
->OriginalSize
|| length
> albuf
->OriginalSize
-offset
||
347 (offset
%byte_align
) != 0 || (length
%byte_align
) != 0)
349 WriteUnlock(&albuf
->lock
);
350 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
353 channels
= ChannelsFromFmt(albuf
->FmtChannels
);
354 bytes
= BytesFromFmt(albuf
->FmtType
);
355 /* offset -> byte offset, length -> sample count */
356 offset
= offset
/byte_align
* channels
*bytes
;
357 length
= length
/byte_align
* albuf
->OriginalAlign
;
359 ConvertData((char*)albuf
->data
+offset
, (enum UserFmtType
)albuf
->FmtType
,
360 data
, srctype
, channels
, length
, align
);
361 WriteUnlock(&albuf
->lock
);
364 UnlockBuffersRead(device
);
365 ALCcontext_DecRef(context
);
369 AL_API
void AL_APIENTRY
alBufferSamplesSOFT(ALuint buffer
,
370 ALuint samplerate
, ALenum internalformat
, ALsizei samples
,
371 ALenum channels
, ALenum type
, const ALvoid
*data
)
379 context
= GetContextRef();
382 device
= context
->Device
;
383 LockBuffersRead(device
);
384 if((albuf
=LookupBuffer(device
, buffer
)) == NULL
)
385 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
386 if(!(samples
>= 0 && samplerate
!= 0))
387 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
388 if(IsValidType(type
) == AL_FALSE
|| IsValidChannels(channels
) == AL_FALSE
)
389 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
391 align
= ATOMIC_LOAD_SEQ(&albuf
->UnpackAlign
);
392 if(SanitizeAlignment(type
, &align
) == AL_FALSE
)
393 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
394 if((samples
%align
) != 0)
395 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
397 err
= LoadData(albuf
, samplerate
, internalformat
, samples
,
398 channels
, type
, data
, align
, AL_FALSE
);
399 if(err
!= AL_NO_ERROR
)
400 SET_ERROR_AND_GOTO(context
, err
, done
);
403 UnlockBuffersRead(device
);
404 ALCcontext_DecRef(context
);
407 AL_API
void AL_APIENTRY
alBufferSubSamplesSOFT(ALuint buffer
,
408 ALsizei offset
, ALsizei samples
,
409 ALenum channels
, ALenum type
, const ALvoid
*data
)
416 context
= GetContextRef();
419 device
= context
->Device
;
420 LockBuffersRead(device
);
421 if((albuf
=LookupBuffer(device
, buffer
)) == NULL
)
422 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
423 if(!(samples
>= 0 && offset
>= 0))
424 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
425 if(IsValidType(type
) == AL_FALSE
)
426 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
428 WriteLock(&albuf
->lock
);
429 align
= ATOMIC_LOAD_SEQ(&albuf
->UnpackAlign
);
430 if(SanitizeAlignment(type
, &align
) == AL_FALSE
)
432 WriteUnlock(&albuf
->lock
);
433 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
435 if(channels
!= (ALenum
)albuf
->FmtChannels
)
437 WriteUnlock(&albuf
->lock
);
438 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
440 if(offset
> albuf
->SampleLen
|| samples
> albuf
->SampleLen
-offset
)
442 WriteUnlock(&albuf
->lock
);
443 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
445 if((samples
%align
) != 0)
447 WriteUnlock(&albuf
->lock
);
448 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
451 /* offset -> byte offset */
452 offset
*= FrameSizeFromFmt(albuf
->FmtChannels
, albuf
->FmtType
);
453 ConvertData((char*)albuf
->data
+offset
, (enum UserFmtType
)albuf
->FmtType
,
454 data
, type
, ChannelsFromFmt(albuf
->FmtChannels
), samples
, align
);
455 WriteUnlock(&albuf
->lock
);
458 UnlockBuffersRead(device
);
459 ALCcontext_DecRef(context
);
462 AL_API
void AL_APIENTRY
alGetBufferSamplesSOFT(ALuint buffer
,
463 ALsizei offset
, ALsizei samples
,
464 ALenum channels
, ALenum type
, ALvoid
*data
)
471 context
= GetContextRef();
474 device
= context
->Device
;
475 LockBuffersRead(device
);
476 if((albuf
=LookupBuffer(device
, buffer
)) == NULL
)
477 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
478 if(!(samples
>= 0 && offset
>= 0))
479 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
480 if(IsValidType(type
) == AL_FALSE
)
481 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
483 ReadLock(&albuf
->lock
);
484 align
= ATOMIC_LOAD_SEQ(&albuf
->PackAlign
);
485 if(SanitizeAlignment(type
, &align
) == AL_FALSE
)
487 ReadUnlock(&albuf
->lock
);
488 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
490 if(channels
!= (ALenum
)albuf
->FmtChannels
)
492 ReadUnlock(&albuf
->lock
);
493 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
495 if(offset
> albuf
->SampleLen
|| samples
> albuf
->SampleLen
-offset
)
497 ReadUnlock(&albuf
->lock
);
498 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
500 if((samples
%align
) != 0)
502 ReadUnlock(&albuf
->lock
);
503 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
506 /* offset -> byte offset */
507 offset
*= FrameSizeFromFmt(albuf
->FmtChannels
, albuf
->FmtType
);
508 ConvertData(data
, type
, (char*)albuf
->data
+offset
, (enum UserFmtType
)albuf
->FmtType
,
509 ChannelsFromFmt(albuf
->FmtChannels
), samples
, align
);
510 ReadUnlock(&albuf
->lock
);
513 UnlockBuffersRead(device
);
514 ALCcontext_DecRef(context
);
517 AL_API ALboolean AL_APIENTRY
alIsBufferFormatSupportedSOFT(ALenum format
)
519 enum FmtChannels dstchannels
;
520 enum FmtType dsttype
;
524 context
= GetContextRef();
525 if(!context
) return AL_FALSE
;
527 ret
= DecomposeFormat(format
, &dstchannels
, &dsttype
);
529 ALCcontext_DecRef(context
);
535 AL_API
void AL_APIENTRY
alBufferf(ALuint buffer
, ALenum param
, ALfloat
UNUSED(value
))
540 context
= GetContextRef();
543 device
= context
->Device
;
544 LockBuffersRead(device
);
545 if(LookupBuffer(device
, buffer
) == NULL
)
546 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
551 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
555 UnlockBuffersRead(device
);
556 ALCcontext_DecRef(context
);
560 AL_API
void AL_APIENTRY
alBuffer3f(ALuint buffer
, ALenum param
, ALfloat
UNUSED(value1
), ALfloat
UNUSED(value2
), ALfloat
UNUSED(value3
))
565 context
= GetContextRef();
568 device
= context
->Device
;
569 LockBuffersRead(device
);
570 if(LookupBuffer(device
, buffer
) == NULL
)
571 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
576 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
580 UnlockBuffersRead(device
);
581 ALCcontext_DecRef(context
);
585 AL_API
void AL_APIENTRY
alBufferfv(ALuint buffer
, ALenum param
, const ALfloat
*values
)
590 context
= GetContextRef();
593 device
= context
->Device
;
594 LockBuffersRead(device
);
595 if(LookupBuffer(device
, buffer
) == NULL
)
596 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
599 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
603 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
607 UnlockBuffersRead(device
);
608 ALCcontext_DecRef(context
);
612 AL_API
void AL_APIENTRY
alBufferi(ALuint buffer
, ALenum param
, ALint value
)
618 context
= GetContextRef();
621 device
= context
->Device
;
622 LockBuffersRead(device
);
623 if((albuf
=LookupBuffer(device
, buffer
)) == NULL
)
624 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
628 case AL_UNPACK_BLOCK_ALIGNMENT_SOFT
:
630 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
631 ATOMIC_STORE_SEQ(&albuf
->UnpackAlign
, value
);
634 case AL_PACK_BLOCK_ALIGNMENT_SOFT
:
636 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
637 ATOMIC_STORE_SEQ(&albuf
->PackAlign
, value
);
641 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
645 UnlockBuffersRead(device
);
646 ALCcontext_DecRef(context
);
650 AL_API
void AL_APIENTRY
alBuffer3i(ALuint buffer
, ALenum param
, ALint
UNUSED(value1
), ALint
UNUSED(value2
), ALint
UNUSED(value3
))
655 context
= GetContextRef();
658 device
= context
->Device
;
659 if(LookupBuffer(device
, buffer
) == NULL
)
660 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
665 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
669 ALCcontext_DecRef(context
);
673 AL_API
void AL_APIENTRY
alBufferiv(ALuint buffer
, ALenum param
, const ALint
*values
)
683 case AL_UNPACK_BLOCK_ALIGNMENT_SOFT
:
684 case AL_PACK_BLOCK_ALIGNMENT_SOFT
:
685 alBufferi(buffer
, param
, values
[0]);
690 context
= GetContextRef();
693 device
= context
->Device
;
694 LockBuffersRead(device
);
695 if((albuf
=LookupBuffer(device
, buffer
)) == NULL
)
696 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
699 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
702 case AL_LOOP_POINTS_SOFT
:
703 WriteLock(&albuf
->lock
);
704 if(ReadRef(&albuf
->ref
) != 0)
706 WriteUnlock(&albuf
->lock
);
707 SET_ERROR_AND_GOTO(context
, AL_INVALID_OPERATION
, done
);
709 if(values
[0] >= values
[1] || values
[0] < 0 ||
710 values
[1] > albuf
->SampleLen
)
712 WriteUnlock(&albuf
->lock
);
713 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
716 albuf
->LoopStart
= values
[0];
717 albuf
->LoopEnd
= values
[1];
718 WriteUnlock(&albuf
->lock
);
722 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
726 UnlockBuffersRead(device
);
727 ALCcontext_DecRef(context
);
731 AL_API ALvoid AL_APIENTRY
alGetBufferf(ALuint buffer
, ALenum param
, ALfloat
*value
)
737 context
= GetContextRef();
740 device
= context
->Device
;
741 LockBuffersRead(device
);
742 if((albuf
=LookupBuffer(device
, buffer
)) == NULL
)
743 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
746 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
749 case AL_SEC_LENGTH_SOFT
:
750 ReadLock(&albuf
->lock
);
751 if(albuf
->SampleLen
!= 0)
752 *value
= albuf
->SampleLen
/ (ALfloat
)albuf
->Frequency
;
755 ReadUnlock(&albuf
->lock
);
759 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
763 UnlockBuffersRead(device
);
764 ALCcontext_DecRef(context
);
768 AL_API
void AL_APIENTRY
alGetBuffer3f(ALuint buffer
, ALenum param
, ALfloat
*value1
, ALfloat
*value2
, ALfloat
*value3
)
773 context
= GetContextRef();
776 device
= context
->Device
;
777 LockBuffersRead(device
);
778 if(LookupBuffer(device
, buffer
) == NULL
)
779 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
781 if(!(value1
&& value2
&& value3
))
782 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
786 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
790 UnlockBuffersRead(device
);
791 ALCcontext_DecRef(context
);
795 AL_API
void AL_APIENTRY
alGetBufferfv(ALuint buffer
, ALenum param
, ALfloat
*values
)
802 case AL_SEC_LENGTH_SOFT
:
803 alGetBufferf(buffer
, param
, values
);
807 context
= GetContextRef();
810 device
= context
->Device
;
811 LockBuffersRead(device
);
812 if(LookupBuffer(device
, buffer
) == NULL
)
813 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
816 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
820 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
824 UnlockBuffersRead(device
);
825 ALCcontext_DecRef(context
);
829 AL_API ALvoid AL_APIENTRY
alGetBufferi(ALuint buffer
, ALenum param
, ALint
*value
)
835 context
= GetContextRef();
838 device
= context
->Device
;
839 LockBuffersRead(device
);
840 if((albuf
=LookupBuffer(device
, buffer
)) == NULL
)
841 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
844 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
848 *value
= albuf
->Frequency
;
852 *value
= BytesFromFmt(albuf
->FmtType
) * 8;
856 *value
= ChannelsFromFmt(albuf
->FmtChannels
);
860 ReadLock(&albuf
->lock
);
861 *value
= albuf
->SampleLen
* FrameSizeFromFmt(albuf
->FmtChannels
,
863 ReadUnlock(&albuf
->lock
);
866 case AL_INTERNAL_FORMAT_SOFT
:
867 *value
= albuf
->Format
;
870 case AL_BYTE_LENGTH_SOFT
:
871 *value
= albuf
->OriginalSize
;
874 case AL_SAMPLE_LENGTH_SOFT
:
875 *value
= albuf
->SampleLen
;
878 case AL_UNPACK_BLOCK_ALIGNMENT_SOFT
:
879 *value
= ATOMIC_LOAD_SEQ(&albuf
->UnpackAlign
);
882 case AL_PACK_BLOCK_ALIGNMENT_SOFT
:
883 *value
= ATOMIC_LOAD_SEQ(&albuf
->PackAlign
);
887 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
891 UnlockBuffersRead(device
);
892 ALCcontext_DecRef(context
);
896 AL_API
void AL_APIENTRY
alGetBuffer3i(ALuint buffer
, ALenum param
, ALint
*value1
, ALint
*value2
, ALint
*value3
)
901 context
= GetContextRef();
904 device
= context
->Device
;
905 LockBuffersRead(device
);
906 if(LookupBuffer(device
, buffer
) == NULL
)
907 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
909 if(!(value1
&& value2
&& value3
))
910 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
914 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
918 UnlockBuffersRead(device
);
919 ALCcontext_DecRef(context
);
923 AL_API
void AL_APIENTRY
alGetBufferiv(ALuint buffer
, ALenum param
, ALint
*values
)
935 case AL_INTERNAL_FORMAT_SOFT
:
936 case AL_BYTE_LENGTH_SOFT
:
937 case AL_SAMPLE_LENGTH_SOFT
:
938 case AL_UNPACK_BLOCK_ALIGNMENT_SOFT
:
939 case AL_PACK_BLOCK_ALIGNMENT_SOFT
:
940 alGetBufferi(buffer
, param
, values
);
944 context
= GetContextRef();
947 device
= context
->Device
;
948 LockBuffersRead(device
);
949 if((albuf
=LookupBuffer(device
, buffer
)) == NULL
)
950 SET_ERROR_AND_GOTO(context
, AL_INVALID_NAME
, done
);
953 SET_ERROR_AND_GOTO(context
, AL_INVALID_VALUE
, done
);
956 case AL_LOOP_POINTS_SOFT
:
957 ReadLock(&albuf
->lock
);
958 values
[0] = albuf
->LoopStart
;
959 values
[1] = albuf
->LoopEnd
;
960 ReadUnlock(&albuf
->lock
);
964 SET_ERROR_AND_GOTO(context
, AL_INVALID_ENUM
, done
);
968 UnlockBuffersRead(device
);
969 ALCcontext_DecRef(context
);
976 * Loads the specified data into the buffer, using the specified formats.
977 * Currently, the new format must have the same channel configuration as the
980 ALenum
LoadData(ALbuffer
*ALBuf
, ALuint freq
, ALenum NewFormat
, ALsizei frames
, enum UserFmtChannels SrcChannels
, enum UserFmtType SrcType
, const ALvoid
*data
, ALsizei align
, ALboolean storesrc
)
982 enum FmtChannels DstChannels
= FmtMono
;
983 enum FmtType DstType
= FmtByte
;
984 ALuint NewChannels
, NewBytes
;
987 if(DecomposeFormat(NewFormat
, &DstChannels
, &DstType
) == AL_FALSE
)
988 return AL_INVALID_ENUM
;
989 if((long)SrcChannels
!= (long)DstChannels
)
990 return AL_INVALID_ENUM
;
992 NewChannels
= ChannelsFromFmt(DstChannels
);
993 NewBytes
= BytesFromFmt(DstType
);
997 newsize
*= NewChannels
;
998 if(newsize
> INT_MAX
)
999 return AL_OUT_OF_MEMORY
;
1001 WriteLock(&ALBuf
->lock
);
1002 if(ReadRef(&ALBuf
->ref
) != 0)
1004 WriteUnlock(&ALBuf
->lock
);
1005 return AL_INVALID_OPERATION
;
1008 /* Round up to the next 16-byte multiple. This could reallocate only when
1009 * increasing or the new size is less than half the current, but then the
1010 * buffer's AL_SIZE would not be very reliable for accounting buffer memory
1011 * usage, and reporting the real size could cause problems for apps that
1012 * use AL_SIZE to try to get the buffer's play length.
1014 newsize
= (newsize
+15) & ~0xf;
1015 if(newsize
!= ALBuf
->BytesAlloc
)
1017 void *temp
= al_calloc(16, (size_t)newsize
);
1018 if(!temp
&& newsize
)
1020 WriteUnlock(&ALBuf
->lock
);
1021 return AL_OUT_OF_MEMORY
;
1023 al_free(ALBuf
->data
);
1025 ALBuf
->BytesAlloc
= (ALuint
)newsize
;
1029 ConvertData(ALBuf
->data
, (enum UserFmtType
)DstType
, data
, SrcType
, NewChannels
, frames
, align
);
1033 ALBuf
->OriginalChannels
= SrcChannels
;
1034 ALBuf
->OriginalType
= SrcType
;
1035 if(SrcType
== UserFmtIMA4
)
1037 ALsizei byte_align
= ((align
-1)/2 + 4) * ChannelsFromUserFmt(SrcChannels
);
1038 ALBuf
->OriginalSize
= frames
/ align
* byte_align
;
1039 ALBuf
->OriginalAlign
= align
;
1041 else if(SrcType
== UserFmtMSADPCM
)
1043 ALsizei byte_align
= ((align
-2)/2 + 7) * ChannelsFromUserFmt(SrcChannels
);
1044 ALBuf
->OriginalSize
= frames
/ align
* byte_align
;
1045 ALBuf
->OriginalAlign
= align
;
1049 ALBuf
->OriginalSize
= frames
* FrameSizeFromUserFmt(SrcChannels
, SrcType
);
1050 ALBuf
->OriginalAlign
= 1;
1055 ALBuf
->OriginalChannels
= (enum UserFmtChannels
)DstChannels
;
1056 ALBuf
->OriginalType
= (enum UserFmtType
)DstType
;
1057 ALBuf
->OriginalSize
= frames
* NewBytes
* NewChannels
;
1058 ALBuf
->OriginalAlign
= 1;
1061 ALBuf
->Frequency
= freq
;
1062 ALBuf
->FmtChannels
= DstChannels
;
1063 ALBuf
->FmtType
= DstType
;
1064 ALBuf
->Format
= NewFormat
;
1066 ALBuf
->SampleLen
= frames
;
1067 ALBuf
->LoopStart
= 0;
1068 ALBuf
->LoopEnd
= ALBuf
->SampleLen
;
1070 WriteUnlock(&ALBuf
->lock
);
1075 ALsizei
BytesFromUserFmt(enum UserFmtType type
)
1079 case UserFmtByte
: return sizeof(ALbyte
);
1080 case UserFmtUByte
: return sizeof(ALubyte
);
1081 case UserFmtShort
: return sizeof(ALshort
);
1082 case UserFmtUShort
: return sizeof(ALushort
);
1083 case UserFmtInt
: return sizeof(ALint
);
1084 case UserFmtUInt
: return sizeof(ALuint
);
1085 case UserFmtFloat
: return sizeof(ALfloat
);
1086 case UserFmtDouble
: return sizeof(ALdouble
);
1087 case UserFmtMulaw
: return sizeof(ALubyte
);
1088 case UserFmtAlaw
: return sizeof(ALubyte
);
1089 case UserFmtIMA4
: break; /* not handled here */
1090 case UserFmtMSADPCM
: break; /* not handled here */
1094 ALsizei
ChannelsFromUserFmt(enum UserFmtChannels chans
)
1098 case UserFmtMono
: return 1;
1099 case UserFmtStereo
: return 2;
1100 case UserFmtRear
: return 2;
1101 case UserFmtQuad
: return 4;
1102 case UserFmtX51
: return 6;
1103 case UserFmtX61
: return 7;
1104 case UserFmtX71
: return 8;
1105 case UserFmtBFormat2D
: return 3;
1106 case UserFmtBFormat3D
: return 4;
1110 static ALboolean
DecomposeUserFormat(ALenum format
, enum UserFmtChannels
*chans
,
1111 enum UserFmtType
*type
)
1113 static const struct {
1115 enum UserFmtChannels channels
;
1116 enum UserFmtType type
;
1118 { AL_FORMAT_MONO8
, UserFmtMono
, UserFmtUByte
},
1119 { AL_FORMAT_MONO16
, UserFmtMono
, UserFmtShort
},
1120 { AL_FORMAT_MONO_FLOAT32
, UserFmtMono
, UserFmtFloat
},
1121 { AL_FORMAT_MONO_DOUBLE_EXT
, UserFmtMono
, UserFmtDouble
},
1122 { AL_FORMAT_MONO_IMA4
, UserFmtMono
, UserFmtIMA4
},
1123 { AL_FORMAT_MONO_MSADPCM_SOFT
, UserFmtMono
, UserFmtMSADPCM
},
1124 { AL_FORMAT_MONO_MULAW
, UserFmtMono
, UserFmtMulaw
},
1125 { AL_FORMAT_MONO_ALAW_EXT
, UserFmtMono
, UserFmtAlaw
},
1127 { AL_FORMAT_STEREO8
, UserFmtStereo
, UserFmtUByte
},
1128 { AL_FORMAT_STEREO16
, UserFmtStereo
, UserFmtShort
},
1129 { AL_FORMAT_STEREO_FLOAT32
, UserFmtStereo
, UserFmtFloat
},
1130 { AL_FORMAT_STEREO_DOUBLE_EXT
, UserFmtStereo
, UserFmtDouble
},
1131 { AL_FORMAT_STEREO_IMA4
, UserFmtStereo
, UserFmtIMA4
},
1132 { AL_FORMAT_STEREO_MSADPCM_SOFT
, UserFmtStereo
, UserFmtMSADPCM
},
1133 { AL_FORMAT_STEREO_MULAW
, UserFmtStereo
, UserFmtMulaw
},
1134 { AL_FORMAT_STEREO_ALAW_EXT
, UserFmtStereo
, UserFmtAlaw
},
1136 { AL_FORMAT_REAR8
, UserFmtRear
, UserFmtUByte
},
1137 { AL_FORMAT_REAR16
, UserFmtRear
, UserFmtShort
},
1138 { AL_FORMAT_REAR32
, UserFmtRear
, UserFmtFloat
},
1139 { AL_FORMAT_REAR_MULAW
, UserFmtRear
, UserFmtMulaw
},
1141 { AL_FORMAT_QUAD8_LOKI
, UserFmtQuad
, UserFmtUByte
},
1142 { AL_FORMAT_QUAD16_LOKI
, UserFmtQuad
, UserFmtShort
},
1144 { AL_FORMAT_QUAD8
, UserFmtQuad
, UserFmtUByte
},
1145 { AL_FORMAT_QUAD16
, UserFmtQuad
, UserFmtShort
},
1146 { AL_FORMAT_QUAD32
, UserFmtQuad
, UserFmtFloat
},
1147 { AL_FORMAT_QUAD_MULAW
, UserFmtQuad
, UserFmtMulaw
},
1149 { AL_FORMAT_51CHN8
, UserFmtX51
, UserFmtUByte
},
1150 { AL_FORMAT_51CHN16
, UserFmtX51
, UserFmtShort
},
1151 { AL_FORMAT_51CHN32
, UserFmtX51
, UserFmtFloat
},
1152 { AL_FORMAT_51CHN_MULAW
, UserFmtX51
, UserFmtMulaw
},
1154 { AL_FORMAT_61CHN8
, UserFmtX61
, UserFmtUByte
},
1155 { AL_FORMAT_61CHN16
, UserFmtX61
, UserFmtShort
},
1156 { AL_FORMAT_61CHN32
, UserFmtX61
, UserFmtFloat
},
1157 { AL_FORMAT_61CHN_MULAW
, UserFmtX61
, UserFmtMulaw
},
1159 { AL_FORMAT_71CHN8
, UserFmtX71
, UserFmtUByte
},
1160 { AL_FORMAT_71CHN16
, UserFmtX71
, UserFmtShort
},
1161 { AL_FORMAT_71CHN32
, UserFmtX71
, UserFmtFloat
},
1162 { AL_FORMAT_71CHN_MULAW
, UserFmtX71
, UserFmtMulaw
},
1164 { AL_FORMAT_BFORMAT2D_8
, UserFmtBFormat2D
, UserFmtUByte
},
1165 { AL_FORMAT_BFORMAT2D_16
, UserFmtBFormat2D
, UserFmtShort
},
1166 { AL_FORMAT_BFORMAT2D_FLOAT32
, UserFmtBFormat2D
, UserFmtFloat
},
1167 { AL_FORMAT_BFORMAT2D_MULAW
, UserFmtBFormat2D
, UserFmtMulaw
},
1169 { AL_FORMAT_BFORMAT3D_8
, UserFmtBFormat3D
, UserFmtUByte
},
1170 { AL_FORMAT_BFORMAT3D_16
, UserFmtBFormat3D
, UserFmtShort
},
1171 { AL_FORMAT_BFORMAT3D_FLOAT32
, UserFmtBFormat3D
, UserFmtFloat
},
1172 { AL_FORMAT_BFORMAT3D_MULAW
, UserFmtBFormat3D
, UserFmtMulaw
},
1176 for(i
= 0;i
< COUNTOF(list
);i
++)
1178 if(list
[i
].format
== format
)
1180 *chans
= list
[i
].channels
;
1181 *type
= list
[i
].type
;
1189 ALsizei
BytesFromFmt(enum FmtType type
)
1193 case FmtByte
: return sizeof(ALbyte
);
1194 case FmtShort
: return sizeof(ALshort
);
1195 case FmtFloat
: return sizeof(ALfloat
);
1199 ALsizei
ChannelsFromFmt(enum FmtChannels chans
)
1203 case FmtMono
: return 1;
1204 case FmtStereo
: return 2;
1205 case FmtRear
: return 2;
1206 case FmtQuad
: return 4;
1207 case FmtX51
: return 6;
1208 case FmtX61
: return 7;
1209 case FmtX71
: return 8;
1210 case FmtBFormat2D
: return 3;
1211 case FmtBFormat3D
: return 4;
1215 static ALboolean
DecomposeFormat(ALenum format
, enum FmtChannels
*chans
, enum FmtType
*type
)
1217 static const struct {
1219 enum FmtChannels channels
;
1222 { AL_MONO8_SOFT
, FmtMono
, FmtByte
},
1223 { AL_MONO16_SOFT
, FmtMono
, FmtShort
},
1224 { AL_MONO32F_SOFT
, FmtMono
, FmtFloat
},
1226 { AL_STEREO8_SOFT
, FmtStereo
, FmtByte
},
1227 { AL_STEREO16_SOFT
, FmtStereo
, FmtShort
},
1228 { AL_STEREO32F_SOFT
, FmtStereo
, FmtFloat
},
1230 { AL_REAR8_SOFT
, FmtRear
, FmtByte
},
1231 { AL_REAR16_SOFT
, FmtRear
, FmtShort
},
1232 { AL_REAR32F_SOFT
, FmtRear
, FmtFloat
},
1234 { AL_FORMAT_QUAD8_LOKI
, FmtQuad
, FmtByte
},
1235 { AL_FORMAT_QUAD16_LOKI
, FmtQuad
, FmtShort
},
1237 { AL_QUAD8_SOFT
, FmtQuad
, FmtByte
},
1238 { AL_QUAD16_SOFT
, FmtQuad
, FmtShort
},
1239 { AL_QUAD32F_SOFT
, FmtQuad
, FmtFloat
},
1241 { AL_5POINT1_8_SOFT
, FmtX51
, FmtByte
},
1242 { AL_5POINT1_16_SOFT
, FmtX51
, FmtShort
},
1243 { AL_5POINT1_32F_SOFT
, FmtX51
, FmtFloat
},
1245 { AL_6POINT1_8_SOFT
, FmtX61
, FmtByte
},
1246 { AL_6POINT1_16_SOFT
, FmtX61
, FmtShort
},
1247 { AL_6POINT1_32F_SOFT
, FmtX61
, FmtFloat
},
1249 { AL_7POINT1_8_SOFT
, FmtX71
, FmtByte
},
1250 { AL_7POINT1_16_SOFT
, FmtX71
, FmtShort
},
1251 { AL_7POINT1_32F_SOFT
, FmtX71
, FmtFloat
},
1253 { AL_BFORMAT2D_8_SOFT
, FmtBFormat2D
, FmtByte
},
1254 { AL_BFORMAT2D_16_SOFT
, FmtBFormat2D
, FmtShort
},
1255 { AL_BFORMAT2D_32F_SOFT
, FmtBFormat2D
, FmtFloat
},
1257 { AL_BFORMAT3D_8_SOFT
, FmtBFormat3D
, FmtByte
},
1258 { AL_BFORMAT3D_16_SOFT
, FmtBFormat3D
, FmtShort
},
1259 { AL_BFORMAT3D_32F_SOFT
, FmtBFormat3D
, FmtFloat
},
1263 for(i
= 0;i
< COUNTOF(list
);i
++)
1265 if(list
[i
].format
== format
)
1267 *chans
= list
[i
].channels
;
1268 *type
= list
[i
].type
;
1276 static ALboolean
SanitizeAlignment(enum UserFmtType type
, ALsizei
*align
)
1283 if(type
== UserFmtIMA4
)
1285 /* Here is where things vary:
1286 * nVidia and Apple use 64+1 sample frames per block -> block_size=36 bytes per channel
1287 * Most PC sound software uses 2040+1 sample frames per block -> block_size=1024 bytes per channel
1291 else if(type
== UserFmtMSADPCM
)
1298 if(type
== UserFmtIMA4
)
1300 /* IMA4 block alignment must be a multiple of 8, plus 1. */
1301 return ((*align
)&7) == 1;
1303 if(type
== UserFmtMSADPCM
)
1305 /* MSADPCM block alignment must be a multiple of 2. */
1306 /* FIXME: Too strict? Might only require align*channels to be a
1308 return ((*align
)&1) == 0;
1315 static ALboolean
IsValidType(ALenum type
)
1320 case AL_UNSIGNED_BYTE_SOFT
:
1322 case AL_UNSIGNED_SHORT_SOFT
:
1324 case AL_UNSIGNED_INT_SOFT
:
1326 case AL_DOUBLE_SOFT
:
1333 static ALboolean
IsValidChannels(ALenum channels
)
1338 case AL_STEREO_SOFT
:
1341 case AL_5POINT1_SOFT
:
1342 case AL_6POINT1_SOFT
:
1343 case AL_7POINT1_SOFT
:
1344 case AL_BFORMAT2D_SOFT
:
1345 case AL_BFORMAT3D_SOFT
:
1352 ALbuffer
*NewBuffer(ALCcontext
*context
)
1354 ALCdevice
*device
= context
->Device
;
1358 buffer
= al_calloc(16, sizeof(ALbuffer
));
1360 SET_ERROR_AND_RETURN_VALUE(context
, AL_OUT_OF_MEMORY
, NULL
);
1361 RWLockInit(&buffer
->lock
);
1363 err
= NewThunkEntry(&buffer
->id
);
1364 if(err
== AL_NO_ERROR
)
1365 err
= InsertUIntMapEntry(&device
->BufferMap
, buffer
->id
, buffer
);
1366 if(err
!= AL_NO_ERROR
)
1368 FreeThunkEntry(buffer
->id
);
1369 memset(buffer
, 0, sizeof(ALbuffer
));
1372 SET_ERROR_AND_RETURN_VALUE(context
, err
, NULL
);
1378 void DeleteBuffer(ALCdevice
*device
, ALbuffer
*buffer
)
1380 RemoveBuffer(device
, buffer
->id
);
1381 FreeThunkEntry(buffer
->id
);
1383 al_free(buffer
->data
);
1385 memset(buffer
, 0, sizeof(*buffer
));
1391 * ReleaseALBuffers()
1393 * INTERNAL: Called to destroy any buffers that still exist on the device
1395 ALvoid
ReleaseALBuffers(ALCdevice
*device
)
1398 for(i
= 0;i
< device
->BufferMap
.size
;i
++)
1400 ALbuffer
*temp
= device
->BufferMap
.values
[i
];
1401 device
->BufferMap
.values
[i
] = NULL
;
1403 al_free(temp
->data
);
1405 FreeThunkEntry(temp
->id
);
1406 memset(temp
, 0, sizeof(ALbuffer
));