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
34 #include "alAuxEffectSlot.h"
37 enum Resampler DefaultResampler
= LinearResampler
;
38 const ALsizei ResamplerPadding
[ResamplerMax
] = {
43 const ALsizei ResamplerPrePadding
[ResamplerMax
] = {
50 static ALvoid
InitSourceParams(ALsource
*Source
);
51 static ALint64
GetSourceOffset(const ALsource
*Source
);
52 static ALdouble
GetSourceSecOffset(const ALsource
*Source
);
53 static ALvoid
GetSourceOffsets(const ALsource
*Source
, ALenum name
, ALdouble
*offsets
, ALdouble updateLen
);
54 static ALint
GetSampleOffset(ALsource
*Source
);
56 typedef enum SrcFloatProp
{
59 sfvMinGain
= AL_MIN_GAIN
,
60 sfvMaxGain
= AL_MAX_GAIN
,
61 sfvMaxDistance
= AL_MAX_DISTANCE
,
62 sfvRolloffFactor
= AL_ROLLOFF_FACTOR
,
63 sfvDopplerFactor
= AL_DOPPLER_FACTOR
,
64 sfvConeOuterGain
= AL_CONE_OUTER_GAIN
,
65 sfvSecOffset
= AL_SEC_OFFSET
,
66 sfvSampleOffset
= AL_SAMPLE_OFFSET
,
67 sfvByteOffset
= AL_BYTE_OFFSET
,
68 sfvConeInnerAngle
= AL_CONE_INNER_ANGLE
,
69 sfvConeOuterAngle
= AL_CONE_OUTER_ANGLE
,
70 sfvRefDistance
= AL_REFERENCE_DISTANCE
,
72 sfvPosition
= AL_POSITION
,
73 sfvVelocity
= AL_VELOCITY
,
74 sfvDirection
= AL_DIRECTION
,
76 sfvSourceRelative
= AL_SOURCE_RELATIVE
,
77 sfvLooping
= AL_LOOPING
,
78 sfvBuffer
= AL_BUFFER
,
79 sfvSourceState
= AL_SOURCE_STATE
,
80 sfvBuffersQueued
= AL_BUFFERS_QUEUED
,
81 sfvBuffersProcessed
= AL_BUFFERS_PROCESSED
,
82 sfvSourceType
= AL_SOURCE_TYPE
,
85 sfvConeOuterGainHF
= AL_CONE_OUTER_GAINHF
,
86 sfvAirAbsorptionFactor
= AL_AIR_ABSORPTION_FACTOR
,
87 sfvRoomRolloffFactor
= AL_ROOM_ROLLOFF_FACTOR
,
88 sfvDirectFilterGainHFAuto
= AL_DIRECT_FILTER_GAINHF_AUTO
,
89 sfvAuxSendFilterGainAuto
= AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
,
90 sfvAuxSendFilterGainHFAuto
= AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
,
92 /* AL_SOFT_direct_channels */
93 sfvDirectChannelsSOFT
= AL_DIRECT_CHANNELS_SOFT
,
95 /* AL_EXT_source_distance_model */
96 sfvDistanceModel
= AL_DISTANCE_MODEL
,
98 /* AL_SOFT_buffer_sub_data / AL_SOFT_buffer_samples */
99 sfvSampleRWOffsetsSOFT
= AL_SAMPLE_RW_OFFSETS_SOFT
,
100 sfvByteRWOffsetsSOFT
= AL_BYTE_RW_OFFSETS_SOFT
,
102 /* AL_SOFT_source_latency */
103 sfvSecOffsetLatencySOFT
= AL_SEC_OFFSET_LATENCY_SOFT
,
106 typedef enum SrcIntProp
{
107 sivMaxDistance
= AL_MAX_DISTANCE
,
108 sivRolloffFactor
= AL_ROLLOFF_FACTOR
,
109 sivRefDistance
= AL_REFERENCE_DISTANCE
,
110 sivSourceRelative
= AL_SOURCE_RELATIVE
,
111 sivConeInnerAngle
= AL_CONE_INNER_ANGLE
,
112 sivConeOuterAngle
= AL_CONE_OUTER_ANGLE
,
113 sivLooping
= AL_LOOPING
,
114 sivBuffer
= AL_BUFFER
,
115 sivSourceState
= AL_SOURCE_STATE
,
116 sivBuffersQueued
= AL_BUFFERS_QUEUED
,
117 sivBuffersProcessed
= AL_BUFFERS_PROCESSED
,
118 sivSourceType
= AL_SOURCE_TYPE
,
119 sivSecOffset
= AL_SEC_OFFSET
,
120 sivSampleOffset
= AL_SAMPLE_OFFSET
,
121 sivByteOffset
= AL_BYTE_OFFSET
,
122 sivDopplerFactor
= AL_DOPPLER_FACTOR
,
123 sivPosition
= AL_POSITION
,
124 sivVelocity
= AL_VELOCITY
,
125 sivDirection
= AL_DIRECTION
,
128 sivDirectFilterGainHFAuto
= AL_DIRECT_FILTER_GAINHF_AUTO
,
129 sivAuxSendFilterGainAutio
= AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
,
130 sivAuxSendFilterGainHFAuto
= AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
,
131 sivDirectFilter
= AL_DIRECT_FILTER
,
132 sivAuxSendFilter
= AL_AUXILIARY_SEND_FILTER
,
134 /* AL_SOFT_direct_channels */
135 sivDirectChannelsSOFT
= AL_DIRECT_CHANNELS_SOFT
,
137 /* AL_EXT_source_distance_model */
138 sivDistanceModel
= AL_DISTANCE_MODEL
,
140 /* AL_SOFT_buffer_sub_data / AL_SOFT_buffer_samples */
141 sivSampleRWOffsetsSOFT
= AL_SAMPLE_RW_OFFSETS_SOFT
,
142 sivByteRWOffsetsSOFT
= AL_BYTE_RW_OFFSETS_SOFT
,
144 /* AL_SOFT_source_latency */
145 sivSampleOffsetLatencySOFT
= AL_SAMPLE_OFFSET_LATENCY_SOFT
,
148 static ALenum
SetSourcefv(ALsource
*Source
, ALCcontext
*Context
, SrcFloatProp prop
, const ALfloat
*values
);
149 static ALenum
SetSourceiv(ALsource
*Source
, ALCcontext
*Context
, SrcIntProp prop
, const ALint
*values
);
150 static ALenum
SetSourcei64v(ALsource
*Source
, ALCcontext
*Context
, SrcIntProp prop
, const ALint64SOFT
*values
);
152 static ALenum
GetSourcedv(const ALsource
*Source
, ALCcontext
*Context
, SrcFloatProp prop
, ALdouble
*values
);
153 static ALenum
GetSourceiv(const ALsource
*Source
, ALCcontext
*Context
, SrcIntProp prop
, ALint
*values
);
154 static ALenum
GetSourcei64v(const ALsource
*Source
, ALCcontext
*Context
, SrcIntProp prop
, ALint64
*values
);
157 #define RETERR(x) do { \
158 alSetError(Context, (x)); \
162 #define CHECKVAL(x) do { \
164 RETERR(AL_INVALID_VALUE); \
167 static ALenum
SetSourcefv(ALsource
*Source
, ALCcontext
*Context
, SrcFloatProp prop
, const ALfloat
*values
)
174 CHECKVAL(*values
>= 0.0f
);
176 Source
->Pitch
= *values
;
177 Source
->NeedsUpdate
= AL_TRUE
;
180 case AL_CONE_INNER_ANGLE
:
181 CHECKVAL(*values
>= 0.0f
&& *values
<= 360.0f
);
183 Source
->InnerAngle
= *values
;
184 Source
->NeedsUpdate
= AL_TRUE
;
187 case AL_CONE_OUTER_ANGLE
:
188 CHECKVAL(*values
>= 0.0f
&& *values
<= 360.0f
);
190 Source
->OuterAngle
= *values
;
191 Source
->NeedsUpdate
= AL_TRUE
;
195 CHECKVAL(*values
>= 0.0f
);
197 Source
->Gain
= *values
;
198 Source
->NeedsUpdate
= AL_TRUE
;
201 case AL_MAX_DISTANCE
:
202 CHECKVAL(*values
>= 0.0f
);
204 Source
->MaxDistance
= *values
;
205 Source
->NeedsUpdate
= AL_TRUE
;
208 case AL_ROLLOFF_FACTOR
:
209 CHECKVAL(*values
>= 0.0f
);
211 Source
->RollOffFactor
= *values
;
212 Source
->NeedsUpdate
= AL_TRUE
;
215 case AL_REFERENCE_DISTANCE
:
216 CHECKVAL(*values
>= 0.0f
);
218 Source
->RefDistance
= *values
;
219 Source
->NeedsUpdate
= AL_TRUE
;
223 CHECKVAL(*values
>= 0.0f
&& *values
<= 1.0f
);
225 Source
->MinGain
= *values
;
226 Source
->NeedsUpdate
= AL_TRUE
;
230 CHECKVAL(*values
>= 0.0f
&& *values
<= 1.0f
);
232 Source
->MaxGain
= *values
;
233 Source
->NeedsUpdate
= AL_TRUE
;
236 case AL_CONE_OUTER_GAIN
:
237 CHECKVAL(*values
>= 0.0f
&& *values
<= 1.0f
);
239 Source
->OuterGain
= *values
;
240 Source
->NeedsUpdate
= AL_TRUE
;
243 case AL_CONE_OUTER_GAINHF
:
244 CHECKVAL(*values
>= 0.0f
&& *values
<= 1.0f
);
246 Source
->OuterGainHF
= *values
;
247 Source
->NeedsUpdate
= AL_TRUE
;
250 case AL_AIR_ABSORPTION_FACTOR
:
251 CHECKVAL(*values
>= 0.0f
&& *values
<= 10.0f
);
253 Source
->AirAbsorptionFactor
= *values
;
254 Source
->NeedsUpdate
= AL_TRUE
;
257 case AL_ROOM_ROLLOFF_FACTOR
:
258 CHECKVAL(*values
>= 0.0f
&& *values
<= 10.0f
);
260 Source
->RoomRolloffFactor
= *values
;
261 Source
->NeedsUpdate
= AL_TRUE
;
264 case AL_DOPPLER_FACTOR
:
265 CHECKVAL(*values
>= 0.0f
&& *values
<= 1.0f
);
267 Source
->DopplerFactor
= *values
;
268 Source
->NeedsUpdate
= AL_TRUE
;
272 case AL_SAMPLE_OFFSET
:
274 CHECKVAL(*values
>= 0.0f
);
276 LockContext(Context
);
277 Source
->OffsetType
= prop
;
278 Source
->Offset
= *values
;
280 if((Source
->state
== AL_PLAYING
|| Source
->state
== AL_PAUSED
) &&
281 !Context
->DeferUpdates
)
283 if(ApplyOffset(Source
) == AL_FALSE
)
285 UnlockContext(Context
);
286 RETERR(AL_INVALID_VALUE
);
289 UnlockContext(Context
);
293 case AL_SEC_OFFSET_LATENCY_SOFT
:
295 RETERR(AL_INVALID_OPERATION
);
299 CHECKVAL(isfinite(values
[0]) && isfinite(values
[1]) && isfinite(values
[2]));
301 LockContext(Context
);
302 Source
->Position
[0] = values
[0];
303 Source
->Position
[1] = values
[1];
304 Source
->Position
[2] = values
[2];
305 UnlockContext(Context
);
306 Source
->NeedsUpdate
= AL_TRUE
;
310 CHECKVAL(isfinite(values
[0]) && isfinite(values
[1]) && isfinite(values
[2]));
312 LockContext(Context
);
313 Source
->Velocity
[0] = values
[0];
314 Source
->Velocity
[1] = values
[1];
315 Source
->Velocity
[2] = values
[2];
316 UnlockContext(Context
);
317 Source
->NeedsUpdate
= AL_TRUE
;
321 CHECKVAL(isfinite(values
[0]) && isfinite(values
[1]) && isfinite(values
[2]));
323 LockContext(Context
);
324 Source
->Orientation
[0] = values
[0];
325 Source
->Orientation
[1] = values
[1];
326 Source
->Orientation
[2] = values
[2];
327 UnlockContext(Context
);
328 Source
->NeedsUpdate
= AL_TRUE
;
332 case sfvSampleRWOffsetsSOFT
:
333 case sfvByteRWOffsetsSOFT
:
334 RETERR(AL_INVALID_OPERATION
);
337 case sfvSourceRelative
:
341 case sfvDistanceModel
:
342 case sfvDirectFilterGainHFAuto
:
343 case sfvAuxSendFilterGainAuto
:
344 case sfvAuxSendFilterGainHFAuto
:
345 case sfvDirectChannelsSOFT
:
346 ival
= (ALint
)values
[0];
347 return SetSourceiv(Source
, Context
, prop
, &ival
);
350 case sfvBuffersQueued
:
351 case sfvBuffersProcessed
:
352 ival
= (ALint
)((ALuint
)values
[0]);
353 return SetSourceiv(Source
, Context
, prop
, &ival
);
356 ERR("Unexpected property: 0x%04x\n", prop
);
357 RETERR(AL_INVALID_ENUM
);
360 static ALenum
SetSourceiv(ALsource
*Source
, ALCcontext
*Context
, SrcIntProp prop
, const ALint
*values
)
362 ALCdevice
*device
= Context
->Device
;
363 ALbuffer
*buffer
= NULL
;
364 ALfilter
*filter
= NULL
;
365 ALeffectslot
*slot
= NULL
;
366 ALbufferlistitem
*oldlist
;
371 case AL_SOURCE_RELATIVE
:
372 CHECKVAL(*values
== AL_FALSE
|| *values
== AL_TRUE
);
374 Source
->HeadRelative
= (ALboolean
)*values
;
375 Source
->NeedsUpdate
= AL_TRUE
;
379 CHECKVAL(*values
== AL_FALSE
|| *values
== AL_TRUE
);
381 Source
->Looping
= (ALboolean
)*values
;
385 CHECKVAL(*values
== 0 || (buffer
=LookupBuffer(device
, *values
)) != NULL
);
387 LockContext(Context
);
388 if(!(Source
->state
== AL_STOPPED
|| Source
->state
== AL_INITIAL
))
390 UnlockContext(Context
);
391 RETERR(AL_INVALID_OPERATION
);
394 Source
->BuffersInQueue
= 0;
395 Source
->BuffersPlayed
= 0;
399 ALbufferlistitem
*BufferListItem
;
401 /* Source is now Static */
402 Source
->SourceType
= AL_STATIC
;
404 /* Add the selected buffer to a one-item queue */
405 BufferListItem
= malloc(sizeof(ALbufferlistitem
));
406 BufferListItem
->buffer
= buffer
;
407 BufferListItem
->next
= NULL
;
408 BufferListItem
->prev
= NULL
;
409 IncrementRef(&buffer
->ref
);
411 oldlist
= ExchangePtr((XchgPtr
*)&Source
->queue
, BufferListItem
);
412 Source
->BuffersInQueue
= 1;
414 ReadLock(&buffer
->lock
);
415 Source
->NumChannels
= ChannelsFromFmt(buffer
->FmtChannels
);
416 Source
->SampleSize
= BytesFromFmt(buffer
->FmtType
);
417 ReadUnlock(&buffer
->lock
);
418 if(buffer
->FmtChannels
== FmtMono
)
419 Source
->Update
= CalcSourceParams
;
421 Source
->Update
= CalcNonAttnSourceParams
;
422 Source
->NeedsUpdate
= AL_TRUE
;
426 /* Source is now Undetermined */
427 Source
->SourceType
= AL_UNDETERMINED
;
428 oldlist
= ExchangePtr((XchgPtr
*)&Source
->queue
, NULL
);
431 /* Delete all elements in the previous queue */
432 while(oldlist
!= NULL
)
434 ALbufferlistitem
*temp
= oldlist
;
435 oldlist
= temp
->next
;
438 DecrementRef(&temp
->buffer
->ref
);
441 UnlockContext(Context
);
446 case sivBuffersQueued
:
447 case sivBuffersProcessed
:
449 RETERR(AL_INVALID_OPERATION
);
452 case AL_SAMPLE_OFFSET
:
454 CHECKVAL(*values
>= 0);
456 LockContext(Context
);
457 Source
->OffsetType
= prop
;
458 Source
->Offset
= *values
;
460 if((Source
->state
== AL_PLAYING
|| Source
->state
== AL_PAUSED
) &&
461 !Context
->DeferUpdates
)
463 if(ApplyOffset(Source
) == AL_FALSE
)
465 UnlockContext(Context
);
466 RETERR(AL_INVALID_VALUE
);
469 UnlockContext(Context
);
473 case sivSampleRWOffsetsSOFT
:
474 case sivByteRWOffsetsSOFT
:
475 case sivSampleOffsetLatencySOFT
:
477 RETERR(AL_INVALID_OPERATION
);
480 case AL_DIRECT_FILTER
:
481 CHECKVAL(*values
== 0 || (filter
=LookupFilter(device
, *values
)) != NULL
);
483 LockContext(Context
);
486 Source
->DirectGain
= 1.0f
;
487 Source
->DirectGainHF
= 1.0f
;
491 Source
->DirectGain
= filter
->Gain
;
492 Source
->DirectGainHF
= filter
->GainHF
;
494 UnlockContext(Context
);
495 Source
->NeedsUpdate
= AL_TRUE
;
498 case AL_DIRECT_FILTER_GAINHF_AUTO
:
499 CHECKVAL(*values
== AL_FALSE
|| *values
== AL_TRUE
);
501 Source
->DryGainHFAuto
= *values
;
502 Source
->NeedsUpdate
= AL_TRUE
;
505 case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
:
506 CHECKVAL(*values
== AL_FALSE
|| *values
== AL_TRUE
);
508 Source
->WetGainAuto
= *values
;
509 Source
->NeedsUpdate
= AL_TRUE
;
512 case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
:
513 CHECKVAL(*values
== AL_FALSE
|| *values
== AL_TRUE
);
515 Source
->WetGainHFAuto
= *values
;
516 Source
->NeedsUpdate
= AL_TRUE
;
519 case AL_DIRECT_CHANNELS_SOFT
:
520 CHECKVAL(*values
== AL_FALSE
|| *values
== AL_TRUE
);
522 Source
->DirectChannels
= *values
;
523 Source
->NeedsUpdate
= AL_TRUE
;
526 case AL_DISTANCE_MODEL
:
527 CHECKVAL(*values
== AL_NONE
||
528 *values
== AL_INVERSE_DISTANCE
||
529 *values
== AL_INVERSE_DISTANCE_CLAMPED
||
530 *values
== AL_LINEAR_DISTANCE
||
531 *values
== AL_LINEAR_DISTANCE_CLAMPED
||
532 *values
== AL_EXPONENT_DISTANCE
||
533 *values
== AL_EXPONENT_DISTANCE_CLAMPED
);
535 Source
->DistanceModel
= *values
;
536 if(Context
->SourceDistanceModel
)
537 Source
->NeedsUpdate
= AL_TRUE
;
541 case AL_AUXILIARY_SEND_FILTER
:
542 LockContext(Context
);
543 if(!((ALuint
)values
[1] < device
->NumAuxSends
&&
544 (values
[0] == 0 || (slot
=LookupEffectSlot(Context
, values
[0])) != NULL
) &&
545 (values
[2] == 0 || (filter
=LookupFilter(device
, values
[2])) != NULL
)))
547 UnlockContext(Context
);
548 RETERR(AL_INVALID_VALUE
);
551 /* Add refcount on the new slot, and release the previous slot */
552 if(slot
) IncrementRef(&slot
->ref
);
553 slot
= ExchangePtr((XchgPtr
*)&Source
->Send
[values
[1]].Slot
, slot
);
554 if(slot
) DecrementRef(&slot
->ref
);
559 Source
->Send
[values
[1]].Gain
= 1.0f
;
560 Source
->Send
[values
[1]].GainHF
= 1.0f
;
564 Source
->Send
[values
[1]].Gain
= filter
->Gain
;
565 Source
->Send
[values
[1]].GainHF
= filter
->GainHF
;
567 Source
->NeedsUpdate
= AL_TRUE
;
568 UnlockContext(Context
);
572 case AL_MAX_DISTANCE
:
573 case AL_ROLLOFF_FACTOR
:
574 case AL_CONE_INNER_ANGLE
:
575 case AL_CONE_OUTER_ANGLE
:
576 case AL_REFERENCE_DISTANCE
:
577 case sivDopplerFactor
:
578 fvals
[0] = (ALfloat
)*values
;
579 return SetSourcefv(Source
, Context
, (int)prop
, fvals
);
584 fvals
[0] = (ALfloat
)values
[0];
585 fvals
[1] = (ALfloat
)values
[1];
586 fvals
[2] = (ALfloat
)values
[2];
587 return SetSourcefv(Source
, Context
, (int)prop
, fvals
);
590 ERR("Unexpected property: 0x%04x\n", prop
);
591 RETERR(AL_INVALID_ENUM
);
594 static ALenum
SetSourcei64v(ALsource
*Source
, ALCcontext
*Context
, SrcIntProp prop
, const ALint64SOFT
*values
)
601 case sivSampleRWOffsetsSOFT
:
602 case sivByteRWOffsetsSOFT
:
603 case sivSampleOffsetLatencySOFT
:
605 RETERR(AL_INVALID_OPERATION
);
609 case AL_SOURCE_RELATIVE
:
611 case AL_SOURCE_STATE
:
613 case AL_SAMPLE_OFFSET
:
615 case sivBuffersQueued
:
616 case sivBuffersProcessed
:
617 case AL_DIRECT_FILTER_GAINHF_AUTO
:
618 case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
:
619 case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
:
620 case AL_DIRECT_CHANNELS_SOFT
:
621 case AL_DISTANCE_MODEL
:
622 CHECKVAL(*values
<= INT_MAX
&& *values
>= INT_MIN
);
624 ivals
[0] = (ALint
)*values
;
625 return SetSourceiv(Source
, Context
, (int)prop
, ivals
);
629 case AL_DIRECT_FILTER
:
630 CHECKVAL(*values
<= UINT_MAX
&& *values
>= 0);
632 ivals
[0] = (ALuint
)*values
;
633 return SetSourceiv(Source
, Context
, (int)prop
, ivals
);
636 case AL_AUXILIARY_SEND_FILTER
:
637 CHECKVAL(values
[0] <= UINT_MAX
&& values
[0] >= 0 &&
638 values
[1] <= UINT_MAX
&& values
[1] >= 0 &&
639 values
[2] <= UINT_MAX
&& values
[2] >= 0);
641 ivals
[0] = (ALuint
)values
[0];
642 ivals
[1] = (ALuint
)values
[1];
643 ivals
[2] = (ALuint
)values
[2];
644 return SetSourceiv(Source
, Context
, (int)prop
, ivals
);
647 case AL_MAX_DISTANCE
:
648 case AL_ROLLOFF_FACTOR
:
649 case AL_CONE_INNER_ANGLE
:
650 case AL_CONE_OUTER_ANGLE
:
651 case AL_REFERENCE_DISTANCE
:
653 case sivDopplerFactor
:
654 fvals
[0] = (ALfloat
)*values
;
655 return SetSourcefv(Source
, Context
, (int)prop
, fvals
);
661 fvals
[0] = (ALfloat
)values
[0];
662 fvals
[1] = (ALfloat
)values
[1];
663 fvals
[2] = (ALfloat
)values
[2];
664 return SetSourcefv(Source
, Context
, (int)prop
, fvals
);
667 ERR("Unexpected property: 0x%04x\n", prop
);
668 RETERR(AL_INVALID_ENUM
);
674 static ALenum
GetSourcedv(const ALsource
*Source
, ALCcontext
*Context
, SrcFloatProp prop
, ALdouble
*values
)
684 *values
= Source
->Gain
;
688 *values
= Source
->Pitch
;
691 case AL_MAX_DISTANCE
:
692 *values
= Source
->MaxDistance
;
695 case AL_ROLLOFF_FACTOR
:
696 *values
= Source
->RollOffFactor
;
699 case AL_REFERENCE_DISTANCE
:
700 *values
= Source
->RefDistance
;
703 case AL_CONE_INNER_ANGLE
:
704 *values
= Source
->InnerAngle
;
707 case AL_CONE_OUTER_ANGLE
:
708 *values
= Source
->OuterAngle
;
712 *values
= Source
->MinGain
;
716 *values
= Source
->MaxGain
;
719 case AL_CONE_OUTER_GAIN
:
720 *values
= Source
->OuterGain
;
724 case AL_SAMPLE_OFFSET
:
726 LockContext(Context
);
727 updateLen
= (ALdouble
)Context
->Device
->UpdateSize
/
728 Context
->Device
->Frequency
;
729 GetSourceOffsets(Source
, prop
, offsets
, updateLen
);
730 UnlockContext(Context
);
731 *values
= offsets
[0];
734 case AL_CONE_OUTER_GAINHF
:
735 *values
= Source
->OuterGainHF
;
738 case AL_AIR_ABSORPTION_FACTOR
:
739 *values
= Source
->AirAbsorptionFactor
;
742 case AL_ROOM_ROLLOFF_FACTOR
:
743 *values
= Source
->RoomRolloffFactor
;
746 case AL_DOPPLER_FACTOR
:
747 *values
= Source
->DopplerFactor
;
750 case AL_SAMPLE_RW_OFFSETS_SOFT
:
751 case AL_BYTE_RW_OFFSETS_SOFT
:
752 LockContext(Context
);
753 updateLen
= (ALdouble
)Context
->Device
->UpdateSize
/
754 Context
->Device
->Frequency
;
755 GetSourceOffsets(Source
, prop
, values
, updateLen
);
756 UnlockContext(Context
);
759 case AL_SEC_OFFSET_LATENCY_SOFT
:
760 LockContext(Context
);
761 values
[0] = GetSourceSecOffset(Source
);
762 values
[1] = (ALdouble
)ALCdevice_GetLatency(Context
->Device
) /
764 UnlockContext(Context
);
768 LockContext(Context
);
769 values
[0] = Source
->Position
[0];
770 values
[1] = Source
->Position
[1];
771 values
[2] = Source
->Position
[2];
772 UnlockContext(Context
);
776 LockContext(Context
);
777 values
[0] = Source
->Velocity
[0];
778 values
[1] = Source
->Velocity
[1];
779 values
[2] = Source
->Velocity
[2];
780 UnlockContext(Context
);
784 LockContext(Context
);
785 values
[0] = Source
->Orientation
[0];
786 values
[1] = Source
->Orientation
[1];
787 values
[2] = Source
->Orientation
[2];
788 UnlockContext(Context
);
791 case AL_SOURCE_RELATIVE
:
794 case AL_SOURCE_STATE
:
795 case AL_BUFFERS_QUEUED
:
796 case AL_BUFFERS_PROCESSED
:
798 case AL_DIRECT_FILTER_GAINHF_AUTO
:
799 case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
:
800 case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
:
801 case AL_DIRECT_CHANNELS_SOFT
:
802 case AL_DISTANCE_MODEL
:
803 if((err
=GetSourceiv(Source
, Context
, (int)prop
, ivals
)) == AL_NO_ERROR
)
804 *values
= (ALdouble
)ivals
[0];
808 ERR("Unexpected property: 0x%04x\n", prop
);
809 RETERR(AL_INVALID_ENUM
);
812 static ALenum
GetSourceiv(const ALsource
*Source
, ALCcontext
*Context
, SrcIntProp prop
, ALint
*values
)
814 ALbufferlistitem
*BufferList
;
820 case AL_SOURCE_RELATIVE
:
821 *values
= Source
->HeadRelative
;
825 *values
= Source
->Looping
;
829 LockContext(Context
);
830 BufferList
= Source
->queue
;
831 if(Source
->SourceType
!= AL_STATIC
)
833 ALuint i
= Source
->BuffersPlayed
;
836 BufferList
= BufferList
->next
;
840 *values
= ((BufferList
&& BufferList
->buffer
) ?
841 BufferList
->buffer
->id
: 0);
842 UnlockContext(Context
);
845 case AL_SOURCE_STATE
:
846 *values
= Source
->state
;
849 case AL_BUFFERS_QUEUED
:
850 *values
= Source
->BuffersInQueue
;
853 case AL_BUFFERS_PROCESSED
:
854 LockContext(Context
);
855 if(Source
->Looping
|| Source
->SourceType
!= AL_STREAMING
)
857 /* Buffers on a looping source are in a perpetual state of
858 * PENDING, so don't report any as PROCESSED */
862 *values
= Source
->BuffersPlayed
;
863 UnlockContext(Context
);
867 *values
= Source
->SourceType
;
870 case AL_DIRECT_FILTER_GAINHF_AUTO
:
871 *values
= Source
->DryGainHFAuto
;
874 case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
:
875 *values
= Source
->WetGainAuto
;
878 case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
:
879 *values
= Source
->WetGainHFAuto
;
882 case AL_DIRECT_CHANNELS_SOFT
:
883 *values
= Source
->DirectChannels
;
886 case AL_DISTANCE_MODEL
:
887 *values
= Source
->DistanceModel
;
890 case AL_MAX_DISTANCE
:
891 case AL_ROLLOFF_FACTOR
:
892 case AL_REFERENCE_DISTANCE
:
893 case AL_CONE_INNER_ANGLE
:
894 case AL_CONE_OUTER_ANGLE
:
896 case AL_SAMPLE_OFFSET
:
898 case AL_DOPPLER_FACTOR
:
899 if((err
=GetSourcedv(Source
, Context
, (int)prop
, dvals
)) == AL_NO_ERROR
)
900 *values
= (ALint
)dvals
[0];
903 case AL_SAMPLE_RW_OFFSETS_SOFT
:
904 case AL_BYTE_RW_OFFSETS_SOFT
:
905 if((err
=GetSourcedv(Source
, Context
, (int)prop
, dvals
)) == AL_NO_ERROR
)
907 values
[0] = (ALint
)dvals
[0];
908 values
[1] = (ALint
)dvals
[1];
915 if((err
=GetSourcedv(Source
, Context
, (int)prop
, dvals
)) == AL_NO_ERROR
)
917 values
[0] = (ALint
)dvals
[0];
918 values
[1] = (ALint
)dvals
[1];
919 values
[2] = (ALint
)dvals
[2];
923 case sivSampleOffsetLatencySOFT
:
927 case sivDirectFilter
:
928 case sivAuxSendFilter
:
933 ERR("Unexpected property: 0x%04x\n", prop
);
934 RETERR(AL_INVALID_ENUM
);
937 static ALenum
GetSourcei64v(const ALsource
*Source
, ALCcontext
*Context
, SrcIntProp prop
, ALint64
*values
)
945 case AL_SAMPLE_OFFSET_LATENCY_SOFT
:
946 LockContext(Context
);
947 values
[0] = GetSourceOffset(Source
);
948 values
[1] = ALCdevice_GetLatency(Context
->Device
);
949 UnlockContext(Context
);
952 case AL_MAX_DISTANCE
:
953 case AL_ROLLOFF_FACTOR
:
954 case AL_REFERENCE_DISTANCE
:
955 case AL_CONE_INNER_ANGLE
:
956 case AL_CONE_OUTER_ANGLE
:
958 case AL_SAMPLE_OFFSET
:
960 case AL_DOPPLER_FACTOR
:
961 if((err
=GetSourcedv(Source
, Context
, (int)prop
, dvals
)) == AL_NO_ERROR
)
962 *values
= (ALint64
)dvals
[0];
965 case AL_SAMPLE_RW_OFFSETS_SOFT
:
966 case AL_BYTE_RW_OFFSETS_SOFT
:
967 if((err
=GetSourcedv(Source
, Context
, (int)prop
, dvals
)) == AL_NO_ERROR
)
969 values
[0] = (ALint64
)dvals
[0];
970 values
[1] = (ALint64
)dvals
[1];
977 if((err
=GetSourcedv(Source
, Context
, (int)prop
, dvals
)) == AL_NO_ERROR
)
979 values
[0] = (ALint64
)dvals
[0];
980 values
[1] = (ALint64
)dvals
[1];
981 values
[2] = (ALint64
)dvals
[2];
985 case AL_SOURCE_RELATIVE
:
988 case AL_SOURCE_STATE
:
989 case AL_BUFFERS_QUEUED
:
990 case AL_BUFFERS_PROCESSED
:
992 case AL_DIRECT_FILTER_GAINHF_AUTO
:
993 case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
:
994 case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
:
995 case AL_DIRECT_CHANNELS_SOFT
:
996 case AL_DISTANCE_MODEL
:
997 if((err
=GetSourceiv(Source
, Context
, (int)prop
, ivals
)) == AL_NO_ERROR
)
1002 case sivDirectFilter
:
1003 case sivAuxSendFilter
:
1007 ERR("Unexpected property: 0x%04x\n", prop
);
1008 RETERR(AL_INVALID_ENUM
);
1014 AL_API ALvoid AL_APIENTRY
alGenSources(ALsizei n
, ALuint
*sources
)
1016 ALCcontext
*Context
;
1019 Context
= GetContextRef();
1020 if(!Context
) return;
1026 CHECK_VALUE(Context
, n
>= 0);
1027 for(cur
= 0;cur
< n
;cur
++)
1029 ALsource
*source
= al_calloc(16, sizeof(ALsource
));
1031 al_throwerr(Context
, AL_OUT_OF_MEMORY
);
1032 InitSourceParams(source
);
1034 err
= NewThunkEntry(&source
->id
);
1035 if(err
== AL_NO_ERROR
)
1036 err
= InsertUIntMapEntry(&Context
->SourceMap
, source
->id
, source
);
1037 if(err
!= AL_NO_ERROR
)
1039 FreeThunkEntry(source
->id
);
1040 memset(source
, 0, sizeof(ALsource
));
1043 al_throwerr(Context
, err
);
1046 sources
[cur
] = source
->id
;
1052 alDeleteSources(cur
, sources
);
1056 ALCcontext_DecRef(Context
);
1060 AL_API ALvoid AL_APIENTRY
alDeleteSources(ALsizei n
, const ALuint
*sources
)
1062 ALCcontext
*Context
;
1064 Context
= GetContextRef();
1065 if(!Context
) return;
1069 ALbufferlistitem
*BufferList
;
1073 CHECK_VALUE(Context
, n
>= 0);
1075 /* Check that all Sources are valid */
1076 for(i
= 0;i
< n
;i
++)
1078 if(LookupSource(Context
, sources
[i
]) == NULL
)
1079 al_throwerr(Context
, AL_INVALID_NAME
);
1082 for(i
= 0;i
< n
;i
++)
1084 ALsource
**srclist
, **srclistend
;
1086 if((Source
=RemoveSource(Context
, sources
[i
])) == NULL
)
1088 FreeThunkEntry(Source
->id
);
1090 LockContext(Context
);
1091 srclist
= Context
->ActiveSources
;
1092 srclistend
= srclist
+ Context
->ActiveSourceCount
;
1093 while(srclist
!= srclistend
)
1095 if(*srclist
== Source
)
1097 Context
->ActiveSourceCount
--;
1098 *srclist
= *(--srclistend
);
1103 UnlockContext(Context
);
1105 while(Source
->queue
!= NULL
)
1107 BufferList
= Source
->queue
;
1108 Source
->queue
= BufferList
->next
;
1110 if(BufferList
->buffer
!= NULL
)
1111 DecrementRef(&BufferList
->buffer
->ref
);
1115 for(j
= 0;j
< MAX_SENDS
;++j
)
1117 if(Source
->Send
[j
].Slot
)
1118 DecrementRef(&Source
->Send
[j
].Slot
->ref
);
1119 Source
->Send
[j
].Slot
= NULL
;
1122 memset(Source
, 0, sizeof(*Source
));
1128 ALCcontext_DecRef(Context
);
1132 AL_API ALboolean AL_APIENTRY
alIsSource(ALuint source
)
1134 ALCcontext
*Context
;
1137 Context
= GetContextRef();
1138 if(!Context
) return AL_FALSE
;
1140 result
= (LookupSource(Context
, source
) ? AL_TRUE
: AL_FALSE
);
1142 ALCcontext_DecRef(Context
);
1148 AL_API ALvoid AL_APIENTRY
alSourcef(ALuint source
, ALenum param
, ALfloat value
)
1150 ALCcontext
*Context
;
1153 Context
= GetContextRef();
1154 if(!Context
) return;
1156 if((Source
=LookupSource(Context
, source
)) == NULL
)
1157 alSetError(Context
, AL_INVALID_NAME
);
1161 case AL_CONE_INNER_ANGLE
:
1162 case AL_CONE_OUTER_ANGLE
:
1164 case AL_MAX_DISTANCE
:
1165 case AL_ROLLOFF_FACTOR
:
1166 case AL_REFERENCE_DISTANCE
:
1169 case AL_CONE_OUTER_GAIN
:
1170 case AL_CONE_OUTER_GAINHF
:
1171 case AL_AIR_ABSORPTION_FACTOR
:
1172 case AL_ROOM_ROLLOFF_FACTOR
:
1173 case AL_DOPPLER_FACTOR
:
1175 case AL_SAMPLE_OFFSET
:
1176 case AL_BYTE_OFFSET
:
1177 SetSourcefv(Source
, Context
, param
, &value
);
1181 alSetError(Context
, AL_INVALID_ENUM
);
1184 ALCcontext_DecRef(Context
);
1187 AL_API ALvoid AL_APIENTRY
alSource3f(ALuint source
, ALenum param
, ALfloat value1
, ALfloat value2
, ALfloat value3
)
1189 ALCcontext
*Context
;
1193 Context
= GetContextRef();
1194 if(!Context
) return;
1196 if((Source
=LookupSource(Context
, source
)) == NULL
)
1197 alSetError(Context
, AL_INVALID_NAME
);
1206 SetSourcefv(Source
, Context
, param
, fvals
);
1210 alSetError(Context
, AL_INVALID_ENUM
);
1213 ALCcontext_DecRef(Context
);
1216 AL_API ALvoid AL_APIENTRY
alSourcefv(ALuint source
, ALenum param
, const ALfloat
*values
)
1218 ALCcontext
*Context
;
1221 Context
= GetContextRef();
1222 if(!Context
) return;
1224 if((Source
=LookupSource(Context
, source
)) == NULL
)
1225 alSetError(Context
, AL_INVALID_NAME
);
1227 alSetError(Context
, AL_INVALID_VALUE
);
1231 case AL_CONE_INNER_ANGLE
:
1232 case AL_CONE_OUTER_ANGLE
:
1234 case AL_MAX_DISTANCE
:
1235 case AL_ROLLOFF_FACTOR
:
1236 case AL_REFERENCE_DISTANCE
:
1239 case AL_CONE_OUTER_GAIN
:
1240 case AL_CONE_OUTER_GAINHF
:
1242 case AL_SAMPLE_OFFSET
:
1243 case AL_BYTE_OFFSET
:
1244 case AL_AIR_ABSORPTION_FACTOR
:
1245 case AL_ROOM_ROLLOFF_FACTOR
:
1250 SetSourcefv(Source
, Context
, param
, values
);
1254 alSetError(Context
, AL_INVALID_ENUM
);
1257 ALCcontext_DecRef(Context
);
1261 AL_API ALvoid AL_APIENTRY
alSourcedSOFT(ALuint source
, ALenum param
, ALdouble value
)
1263 ALCcontext
*Context
;
1267 Context
= GetContextRef();
1268 if(!Context
) return;
1270 if((Source
=LookupSource(Context
, source
)) == NULL
)
1271 alSetError(Context
, AL_INVALID_NAME
);
1275 case AL_CONE_INNER_ANGLE
:
1276 case AL_CONE_OUTER_ANGLE
:
1278 case AL_MAX_DISTANCE
:
1279 case AL_ROLLOFF_FACTOR
:
1280 case AL_REFERENCE_DISTANCE
:
1283 case AL_CONE_OUTER_GAIN
:
1284 case AL_CONE_OUTER_GAINHF
:
1285 case AL_AIR_ABSORPTION_FACTOR
:
1286 case AL_ROOM_ROLLOFF_FACTOR
:
1287 case AL_DOPPLER_FACTOR
:
1289 case AL_SAMPLE_OFFSET
:
1290 case AL_BYTE_OFFSET
:
1291 fval
= (ALfloat
)value
;
1292 SetSourcefv(Source
, Context
, param
, &fval
);
1296 alSetError(Context
, AL_INVALID_ENUM
);
1299 ALCcontext_DecRef(Context
);
1302 AL_API ALvoid AL_APIENTRY
alSource3dSOFT(ALuint source
, ALenum param
, ALdouble value1
, ALdouble value2
, ALdouble value3
)
1304 ALCcontext
*Context
;
1308 Context
= GetContextRef();
1309 if(!Context
) return;
1311 if((Source
=LookupSource(Context
, source
)) == NULL
)
1312 alSetError(Context
, AL_INVALID_NAME
);
1318 fvals
[0] = (ALfloat
)value1
;
1319 fvals
[1] = (ALfloat
)value2
;
1320 fvals
[2] = (ALfloat
)value3
;
1321 SetSourcefv(Source
, Context
, param
, fvals
);
1325 alSetError(Context
, AL_INVALID_ENUM
);
1328 ALCcontext_DecRef(Context
);
1331 AL_API ALvoid AL_APIENTRY
alSourcedvSOFT(ALuint source
, ALenum param
, const ALdouble
*values
)
1333 ALCcontext
*Context
;
1337 Context
= GetContextRef();
1338 if(!Context
) return;
1340 if((Source
=LookupSource(Context
, source
)) == NULL
)
1341 alSetError(Context
, AL_INVALID_NAME
);
1343 alSetError(Context
, AL_INVALID_VALUE
);
1347 case AL_CONE_INNER_ANGLE
:
1348 case AL_CONE_OUTER_ANGLE
:
1350 case AL_MAX_DISTANCE
:
1351 case AL_ROLLOFF_FACTOR
:
1352 case AL_REFERENCE_DISTANCE
:
1355 case AL_CONE_OUTER_GAIN
:
1356 case AL_CONE_OUTER_GAINHF
:
1358 case AL_SAMPLE_OFFSET
:
1359 case AL_BYTE_OFFSET
:
1360 case AL_AIR_ABSORPTION_FACTOR
:
1361 case AL_ROOM_ROLLOFF_FACTOR
:
1362 fvals
[0] = (ALfloat
)values
[0];
1363 SetSourcefv(Source
, Context
, param
, fvals
);
1366 case AL_SEC_OFFSET_LATENCY_SOFT
:
1367 fvals
[0] = (ALfloat
)values
[0];
1368 fvals
[1] = (ALfloat
)values
[1];
1369 SetSourcefv(Source
, Context
, param
, fvals
);
1375 fvals
[0] = (ALfloat
)values
[0];
1376 fvals
[1] = (ALfloat
)values
[1];
1377 fvals
[2] = (ALfloat
)values
[2];
1378 SetSourcefv(Source
, Context
, param
, fvals
);
1382 alSetError(Context
, AL_INVALID_ENUM
);
1385 ALCcontext_DecRef(Context
);
1389 AL_API ALvoid AL_APIENTRY
alSourcei(ALuint source
, ALenum param
, ALint value
)
1391 ALCcontext
*Context
;
1394 Context
= GetContextRef();
1395 if(!Context
) return;
1397 if((Source
=LookupSource(Context
, source
)) == NULL
)
1398 alSetError(Context
, AL_INVALID_NAME
);
1401 case AL_MAX_DISTANCE
:
1402 case AL_ROLLOFF_FACTOR
:
1403 case AL_CONE_INNER_ANGLE
:
1404 case AL_CONE_OUTER_ANGLE
:
1405 case AL_REFERENCE_DISTANCE
:
1406 case AL_SOURCE_RELATIVE
:
1409 case AL_SOURCE_STATE
:
1411 case AL_SAMPLE_OFFSET
:
1412 case AL_BYTE_OFFSET
:
1413 case AL_DIRECT_FILTER
:
1414 case AL_DIRECT_FILTER_GAINHF_AUTO
:
1415 case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
:
1416 case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
:
1417 case AL_DIRECT_CHANNELS_SOFT
:
1418 case AL_DISTANCE_MODEL
:
1419 SetSourceiv(Source
, Context
, param
, &value
);
1423 alSetError(Context
, AL_INVALID_ENUM
);
1426 ALCcontext_DecRef(Context
);
1429 AL_API
void AL_APIENTRY
alSource3i(ALuint source
, ALenum param
, ALint value1
, ALint value2
, ALint value3
)
1431 ALCcontext
*Context
;
1435 Context
= GetContextRef();
1436 if(!Context
) return;
1438 if((Source
=LookupSource(Context
, source
)) == NULL
)
1439 alSetError(Context
, AL_INVALID_NAME
);
1445 case AL_AUXILIARY_SEND_FILTER
:
1449 SetSourceiv(Source
, Context
, param
, ivals
);
1453 alSetError(Context
, AL_INVALID_ENUM
);
1456 ALCcontext_DecRef(Context
);
1459 AL_API
void AL_APIENTRY
alSourceiv(ALuint source
, ALenum param
, const ALint
*values
)
1461 ALCcontext
*Context
;
1464 Context
= GetContextRef();
1465 if(!Context
) return;
1467 if((Source
=LookupSource(Context
, source
)) == NULL
)
1468 alSetError(Context
, AL_INVALID_NAME
);
1470 alSetError(Context
, AL_INVALID_VALUE
);
1473 case AL_SOURCE_RELATIVE
:
1474 case AL_CONE_INNER_ANGLE
:
1475 case AL_CONE_OUTER_ANGLE
:
1478 case AL_SOURCE_STATE
:
1480 case AL_SAMPLE_OFFSET
:
1481 case AL_BYTE_OFFSET
:
1482 case AL_MAX_DISTANCE
:
1483 case AL_ROLLOFF_FACTOR
:
1484 case AL_REFERENCE_DISTANCE
:
1485 case AL_DIRECT_FILTER
:
1486 case AL_DIRECT_FILTER_GAINHF_AUTO
:
1487 case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
:
1488 case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
:
1489 case AL_DISTANCE_MODEL
:
1490 case AL_DIRECT_CHANNELS_SOFT
:
1495 case AL_AUXILIARY_SEND_FILTER
:
1496 SetSourceiv(Source
, Context
, param
, values
);
1500 alSetError(Context
, AL_INVALID_ENUM
);
1503 ALCcontext_DecRef(Context
);
1507 AL_API ALvoid AL_APIENTRY
alSourcei64SOFT(ALuint source
, ALenum param
, ALint64SOFT value
)
1509 ALCcontext
*Context
;
1512 Context
= GetContextRef();
1513 if(!Context
) return;
1515 if((Source
=LookupSource(Context
, source
)) == NULL
)
1516 alSetError(Context
, AL_INVALID_NAME
);
1519 case AL_MAX_DISTANCE
:
1520 case AL_ROLLOFF_FACTOR
:
1521 case AL_CONE_INNER_ANGLE
:
1522 case AL_CONE_OUTER_ANGLE
:
1523 case AL_REFERENCE_DISTANCE
:
1524 case AL_SOURCE_RELATIVE
:
1526 case AL_SOURCE_STATE
:
1528 case AL_SAMPLE_OFFSET
:
1529 case AL_BYTE_OFFSET
:
1530 case AL_DIRECT_FILTER_GAINHF_AUTO
:
1531 case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
:
1532 case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
:
1533 case AL_DIRECT_CHANNELS_SOFT
:
1534 case AL_DISTANCE_MODEL
:
1536 case AL_DIRECT_FILTER
:
1537 SetSourcei64v(Source
, Context
, param
, &value
);
1541 alSetError(Context
, AL_INVALID_ENUM
);
1544 ALCcontext_DecRef(Context
);
1547 AL_API
void AL_APIENTRY
alSource3i64SOFT(ALuint source
, ALenum param
, ALint64SOFT value1
, ALint64SOFT value2
, ALint64SOFT value3
)
1549 ALCcontext
*Context
;
1551 ALint64SOFT i64vals
[3];
1553 Context
= GetContextRef();
1554 if(!Context
) return;
1556 if((Source
=LookupSource(Context
, source
)) == NULL
)
1557 alSetError(Context
, AL_INVALID_NAME
);
1563 case AL_AUXILIARY_SEND_FILTER
:
1564 i64vals
[0] = value1
;
1565 i64vals
[1] = value2
;
1566 i64vals
[2] = value3
;
1567 SetSourcei64v(Source
, Context
, param
, i64vals
);
1571 alSetError(Context
, AL_INVALID_ENUM
);
1574 ALCcontext_DecRef(Context
);
1577 AL_API
void AL_APIENTRY
alSourcei64vSOFT(ALuint source
, ALenum param
, const ALint64SOFT
*values
)
1579 ALCcontext
*Context
;
1582 Context
= GetContextRef();
1583 if(!Context
) return;
1585 if((Source
=LookupSource(Context
, source
)) == NULL
)
1586 alSetError(Context
, AL_INVALID_NAME
);
1588 alSetError(Context
, AL_INVALID_VALUE
);
1591 case AL_SOURCE_RELATIVE
:
1592 case AL_CONE_INNER_ANGLE
:
1593 case AL_CONE_OUTER_ANGLE
:
1595 case AL_SOURCE_STATE
:
1597 case AL_SAMPLE_OFFSET
:
1598 case AL_BYTE_OFFSET
:
1599 case AL_MAX_DISTANCE
:
1600 case AL_ROLLOFF_FACTOR
:
1601 case AL_REFERENCE_DISTANCE
:
1602 case AL_DIRECT_FILTER_GAINHF_AUTO
:
1603 case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
:
1604 case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
:
1605 case AL_DISTANCE_MODEL
:
1606 case AL_DIRECT_CHANNELS_SOFT
:
1608 case AL_DIRECT_FILTER
:
1610 case AL_SAMPLE_OFFSET_LATENCY_SOFT
:
1615 case AL_AUXILIARY_SEND_FILTER
:
1616 SetSourcei64v(Source
, Context
, param
, values
);
1620 alSetError(Context
, AL_INVALID_ENUM
);
1623 ALCcontext_DecRef(Context
);
1627 AL_API ALvoid AL_APIENTRY
alGetSourcef(ALuint source
, ALenum param
, ALfloat
*value
)
1629 ALCcontext
*Context
;
1633 Context
= GetContextRef();
1634 if(!Context
) return;
1636 if((Source
=LookupSource(Context
, source
)) == NULL
)
1637 alSetError(Context
, AL_INVALID_NAME
);
1639 alSetError(Context
, AL_INVALID_VALUE
);
1646 case AL_MAX_DISTANCE
:
1647 case AL_ROLLOFF_FACTOR
:
1648 case AL_CONE_OUTER_GAIN
:
1649 case AL_CONE_OUTER_GAINHF
:
1651 case AL_SAMPLE_OFFSET
:
1652 case AL_BYTE_OFFSET
:
1653 case AL_CONE_INNER_ANGLE
:
1654 case AL_CONE_OUTER_ANGLE
:
1655 case AL_REFERENCE_DISTANCE
:
1656 case AL_AIR_ABSORPTION_FACTOR
:
1657 case AL_ROOM_ROLLOFF_FACTOR
:
1658 case AL_DOPPLER_FACTOR
:
1659 if(GetSourcedv(Source
, Context
, param
, &dval
) == AL_NO_ERROR
)
1660 *value
= (ALfloat
)dval
;
1664 alSetError(Context
, AL_INVALID_ENUM
);
1667 ALCcontext_DecRef(Context
);
1671 AL_API ALvoid AL_APIENTRY
alGetSource3f(ALuint source
, ALenum param
, ALfloat
*value1
, ALfloat
*value2
, ALfloat
*value3
)
1673 ALCcontext
*Context
;
1677 Context
= GetContextRef();
1678 if(!Context
) return;
1680 if((Source
=LookupSource(Context
, source
)) == NULL
)
1681 alSetError(Context
, AL_INVALID_NAME
);
1682 else if(!(value1
&& value2
&& value3
))
1683 alSetError(Context
, AL_INVALID_VALUE
);
1689 if(GetSourcedv(Source
, Context
, param
, dvals
) == AL_NO_ERROR
)
1691 *value1
= (ALfloat
)dvals
[0];
1692 *value2
= (ALfloat
)dvals
[1];
1693 *value3
= (ALfloat
)dvals
[2];
1698 alSetError(Context
, AL_INVALID_ENUM
);
1701 ALCcontext_DecRef(Context
);
1705 AL_API ALvoid AL_APIENTRY
alGetSourcefv(ALuint source
, ALenum param
, ALfloat
*values
)
1707 ALCcontext
*Context
;
1717 case AL_MAX_DISTANCE
:
1718 case AL_ROLLOFF_FACTOR
:
1719 case AL_DOPPLER_FACTOR
:
1720 case AL_CONE_OUTER_GAIN
:
1722 case AL_SAMPLE_OFFSET
:
1723 case AL_BYTE_OFFSET
:
1724 case AL_CONE_INNER_ANGLE
:
1725 case AL_CONE_OUTER_ANGLE
:
1726 case AL_REFERENCE_DISTANCE
:
1727 case AL_CONE_OUTER_GAINHF
:
1728 case AL_AIR_ABSORPTION_FACTOR
:
1729 case AL_ROOM_ROLLOFF_FACTOR
:
1730 alGetSourcef(source
, param
, values
);
1736 alGetSource3f(source
, param
, values
+0, values
+1, values
+2);
1740 Context
= GetContextRef();
1741 if(!Context
) return;
1743 if((Source
=LookupSource(Context
, source
)) == NULL
)
1744 alSetError(Context
, AL_INVALID_NAME
);
1746 alSetError(Context
, AL_INVALID_VALUE
);
1749 case AL_SAMPLE_RW_OFFSETS_SOFT
:
1750 case AL_BYTE_RW_OFFSETS_SOFT
:
1751 if(GetSourcedv(Source
, Context
, param
, dvals
) == AL_NO_ERROR
)
1753 values
[0] = (ALfloat
)dvals
[0];
1754 values
[1] = (ALfloat
)dvals
[1];
1759 alSetError(Context
, AL_INVALID_ENUM
);
1762 ALCcontext_DecRef(Context
);
1766 AL_API
void AL_APIENTRY
alGetSourcedSOFT(ALuint source
, ALenum param
, ALdouble
*value
)
1768 ALCcontext
*Context
;
1771 Context
= GetContextRef();
1772 if(!Context
) return;
1774 if((Source
=LookupSource(Context
, source
)) == NULL
)
1775 alSetError(Context
, AL_INVALID_NAME
);
1777 alSetError(Context
, AL_INVALID_VALUE
);
1784 case AL_MAX_DISTANCE
:
1785 case AL_ROLLOFF_FACTOR
:
1786 case AL_CONE_OUTER_GAIN
:
1787 case AL_CONE_OUTER_GAINHF
:
1789 case AL_SAMPLE_OFFSET
:
1790 case AL_BYTE_OFFSET
:
1791 case AL_CONE_INNER_ANGLE
:
1792 case AL_CONE_OUTER_ANGLE
:
1793 case AL_REFERENCE_DISTANCE
:
1794 case AL_AIR_ABSORPTION_FACTOR
:
1795 case AL_ROOM_ROLLOFF_FACTOR
:
1796 case AL_DOPPLER_FACTOR
:
1797 GetSourcedv(Source
, Context
, param
, value
);
1801 alSetError(Context
, AL_INVALID_ENUM
);
1804 ALCcontext_DecRef(Context
);
1807 AL_API
void AL_APIENTRY
alGetSource3dSOFT(ALuint source
, ALenum param
, ALdouble
*value1
, ALdouble
*value2
, ALdouble
*value3
)
1809 ALCcontext
*Context
;
1813 Context
= GetContextRef();
1814 if(!Context
) return;
1816 if((Source
=LookupSource(Context
, source
)) == NULL
)
1817 alSetError(Context
, AL_INVALID_NAME
);
1818 else if(!(value1
&& value2
&& value3
))
1819 alSetError(Context
, AL_INVALID_VALUE
);
1825 if(GetSourcedv(Source
, Context
, param
, dvals
) == AL_NO_ERROR
)
1834 alSetError(Context
, AL_INVALID_ENUM
);
1837 ALCcontext_DecRef(Context
);
1840 AL_API
void AL_APIENTRY
alGetSourcedvSOFT(ALuint source
, ALenum param
, ALdouble
*values
)
1842 ALCcontext
*Context
;
1845 Context
= GetContextRef();
1846 if(!Context
) return;
1848 if((Source
=LookupSource(Context
, source
)) == NULL
)
1849 alSetError(Context
, AL_INVALID_NAME
);
1851 alSetError(Context
, AL_INVALID_VALUE
);
1858 case AL_MAX_DISTANCE
:
1859 case AL_ROLLOFF_FACTOR
:
1860 case AL_DOPPLER_FACTOR
:
1861 case AL_CONE_OUTER_GAIN
:
1863 case AL_SAMPLE_OFFSET
:
1864 case AL_BYTE_OFFSET
:
1865 case AL_CONE_INNER_ANGLE
:
1866 case AL_CONE_OUTER_ANGLE
:
1867 case AL_REFERENCE_DISTANCE
:
1868 case AL_CONE_OUTER_GAINHF
:
1869 case AL_AIR_ABSORPTION_FACTOR
:
1870 case AL_ROOM_ROLLOFF_FACTOR
:
1872 case AL_SAMPLE_RW_OFFSETS_SOFT
:
1873 case AL_BYTE_RW_OFFSETS_SOFT
:
1874 case AL_SEC_OFFSET_LATENCY_SOFT
:
1879 GetSourcedv(Source
, Context
, param
, values
);
1883 alSetError(Context
, AL_INVALID_ENUM
);
1886 ALCcontext_DecRef(Context
);
1890 AL_API ALvoid AL_APIENTRY
alGetSourcei(ALuint source
, ALenum param
, ALint
*value
)
1892 ALCcontext
*Context
;
1895 Context
= GetContextRef();
1896 if(!Context
) return;
1898 if((Source
=LookupSource(Context
, source
)) == NULL
)
1899 alSetError(Context
, AL_INVALID_NAME
);
1901 alSetError(Context
, AL_INVALID_VALUE
);
1904 case AL_MAX_DISTANCE
:
1905 case AL_ROLLOFF_FACTOR
:
1906 case AL_REFERENCE_DISTANCE
:
1907 case AL_SOURCE_RELATIVE
:
1908 case AL_CONE_INNER_ANGLE
:
1909 case AL_CONE_OUTER_ANGLE
:
1912 case AL_SOURCE_STATE
:
1913 case AL_BUFFERS_QUEUED
:
1914 case AL_BUFFERS_PROCESSED
:
1915 case AL_SOURCE_TYPE
:
1917 case AL_SAMPLE_OFFSET
:
1918 case AL_BYTE_OFFSET
:
1919 case AL_DIRECT_FILTER_GAINHF_AUTO
:
1920 case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
:
1921 case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
:
1922 case AL_DOPPLER_FACTOR
:
1923 case AL_DIRECT_CHANNELS_SOFT
:
1924 case AL_DISTANCE_MODEL
:
1925 GetSourceiv(Source
, Context
, param
, value
);
1929 alSetError(Context
, AL_INVALID_ENUM
);
1932 ALCcontext_DecRef(Context
);
1936 AL_API
void AL_APIENTRY
alGetSource3i(ALuint source
, ALenum param
, ALint
*value1
, ALint
*value2
, ALint
*value3
)
1938 ALCcontext
*Context
;
1942 Context
= GetContextRef();
1943 if(!Context
) return;
1945 if((Source
=LookupSource(Context
, source
)) == NULL
)
1946 alSetError(Context
, AL_INVALID_NAME
);
1947 else if(!(value1
&& value2
&& value3
))
1948 alSetError(Context
, AL_INVALID_VALUE
);
1954 if(GetSourceiv(Source
, Context
, param
, ivals
) == AL_NO_ERROR
)
1963 alSetError(Context
, AL_INVALID_ENUM
);
1966 ALCcontext_DecRef(Context
);
1970 AL_API
void AL_APIENTRY
alGetSourceiv(ALuint source
, ALenum param
, ALint
*values
)
1972 ALCcontext
*Context
;
1975 Context
= GetContextRef();
1976 if(!Context
) return;
1978 if((Source
=LookupSource(Context
, source
)) == NULL
)
1979 alSetError(Context
, AL_INVALID_NAME
);
1981 alSetError(Context
, AL_INVALID_VALUE
);
1984 case AL_SOURCE_RELATIVE
:
1985 case AL_CONE_INNER_ANGLE
:
1986 case AL_CONE_OUTER_ANGLE
:
1989 case AL_SOURCE_STATE
:
1990 case AL_BUFFERS_QUEUED
:
1991 case AL_BUFFERS_PROCESSED
:
1993 case AL_SAMPLE_OFFSET
:
1994 case AL_BYTE_OFFSET
:
1995 case AL_MAX_DISTANCE
:
1996 case AL_ROLLOFF_FACTOR
:
1997 case AL_DOPPLER_FACTOR
:
1998 case AL_REFERENCE_DISTANCE
:
1999 case AL_SOURCE_TYPE
:
2000 case AL_DIRECT_FILTER
:
2001 case AL_DIRECT_FILTER_GAINHF_AUTO
:
2002 case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
:
2003 case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
:
2004 case AL_DISTANCE_MODEL
:
2005 case AL_DIRECT_CHANNELS_SOFT
:
2007 case AL_SAMPLE_RW_OFFSETS_SOFT
:
2008 case AL_BYTE_RW_OFFSETS_SOFT
:
2013 GetSourceiv(Source
, Context
, param
, values
);
2017 alSetError(Context
, AL_INVALID_ENUM
);
2020 ALCcontext_DecRef(Context
);
2024 AL_API
void AL_APIENTRY
alGetSourcei64SOFT(ALuint source
, ALenum param
, ALint64SOFT
*value
)
2026 ALCcontext
*Context
;
2029 Context
= GetContextRef();
2030 if(!Context
) return;
2032 if((Source
=LookupSource(Context
, source
)) == NULL
)
2033 alSetError(Context
, AL_INVALID_NAME
);
2035 alSetError(Context
, AL_INVALID_VALUE
);
2038 case AL_MAX_DISTANCE
:
2039 case AL_ROLLOFF_FACTOR
:
2040 case AL_REFERENCE_DISTANCE
:
2041 case AL_SOURCE_RELATIVE
:
2042 case AL_CONE_INNER_ANGLE
:
2043 case AL_CONE_OUTER_ANGLE
:
2046 case AL_SOURCE_STATE
:
2047 case AL_BUFFERS_QUEUED
:
2048 case AL_BUFFERS_PROCESSED
:
2049 case AL_SOURCE_TYPE
:
2051 case AL_SAMPLE_OFFSET
:
2052 case AL_BYTE_OFFSET
:
2053 case AL_DIRECT_FILTER_GAINHF_AUTO
:
2054 case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
:
2055 case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
:
2056 case AL_DOPPLER_FACTOR
:
2057 case AL_DIRECT_CHANNELS_SOFT
:
2058 case AL_DISTANCE_MODEL
:
2059 GetSourcei64v(Source
, Context
, param
, value
);
2063 alSetError(Context
, AL_INVALID_ENUM
);
2066 ALCcontext_DecRef(Context
);
2069 AL_API
void AL_APIENTRY
alGetSource3i64SOFT(ALuint source
, ALenum param
, ALint64SOFT
*value1
, ALint64SOFT
*value2
, ALint64SOFT
*value3
)
2071 ALCcontext
*Context
;
2075 Context
= GetContextRef();
2076 if(!Context
) return;
2078 if((Source
=LookupSource(Context
, source
)) == NULL
)
2079 alSetError(Context
, AL_INVALID_NAME
);
2080 else if(!(value1
&& value2
&& value3
))
2081 alSetError(Context
, AL_INVALID_VALUE
);
2087 if(GetSourcei64v(Source
, Context
, param
, i64vals
) == AL_NO_ERROR
)
2089 *value1
= i64vals
[0];
2090 *value2
= i64vals
[1];
2091 *value3
= i64vals
[2];
2096 alSetError(Context
, AL_INVALID_ENUM
);
2099 ALCcontext_DecRef(Context
);
2102 AL_API
void AL_APIENTRY
alGetSourcei64vSOFT(ALuint source
, ALenum param
, ALint64SOFT
*values
)
2104 ALCcontext
*Context
;
2107 Context
= GetContextRef();
2108 if(!Context
) return;
2110 if((Source
=LookupSource(Context
, source
)) == NULL
)
2111 alSetError(Context
, AL_INVALID_NAME
);
2113 alSetError(Context
, AL_INVALID_VALUE
);
2116 case AL_MAX_DISTANCE
:
2117 case AL_ROLLOFF_FACTOR
:
2118 case AL_REFERENCE_DISTANCE
:
2119 case AL_SOURCE_RELATIVE
:
2120 case AL_CONE_INNER_ANGLE
:
2121 case AL_CONE_OUTER_ANGLE
:
2124 case AL_SOURCE_STATE
:
2125 case AL_BUFFERS_QUEUED
:
2126 case AL_BUFFERS_PROCESSED
:
2127 case AL_SOURCE_TYPE
:
2129 case AL_SAMPLE_OFFSET
:
2130 case AL_BYTE_OFFSET
:
2131 case AL_DIRECT_FILTER_GAINHF_AUTO
:
2132 case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
:
2133 case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
:
2134 case AL_DOPPLER_FACTOR
:
2135 case AL_DIRECT_CHANNELS_SOFT
:
2136 case AL_DISTANCE_MODEL
:
2138 case AL_SAMPLE_RW_OFFSETS_SOFT
:
2139 case AL_BYTE_RW_OFFSETS_SOFT
:
2140 case AL_SAMPLE_OFFSET_LATENCY_SOFT
:
2145 GetSourcei64v(Source
, Context
, param
, values
);
2149 alSetError(Context
, AL_INVALID_ENUM
);
2152 ALCcontext_DecRef(Context
);
2156 AL_API ALvoid AL_APIENTRY
alSourcePlay(ALuint source
)
2158 alSourcePlayv(1, &source
);
2160 AL_API ALvoid AL_APIENTRY
alSourcePlayv(ALsizei n
, const ALuint
*sources
)
2162 ALCcontext
*Context
;
2166 Context
= GetContextRef();
2167 if(!Context
) return;
2171 CHECK_VALUE(Context
, n
>= 0);
2172 for(i
= 0;i
< n
;i
++)
2174 if(!LookupSource(Context
, sources
[i
]))
2175 al_throwerr(Context
, AL_INVALID_NAME
);
2178 LockContext(Context
);
2179 while(Context
->MaxActiveSources
-Context
->ActiveSourceCount
< n
)
2184 newcount
= Context
->MaxActiveSources
<< 1;
2186 temp
= realloc(Context
->ActiveSources
,
2187 sizeof(*Context
->ActiveSources
) * newcount
);
2190 UnlockContext(Context
);
2191 al_throwerr(Context
, AL_OUT_OF_MEMORY
);
2194 Context
->ActiveSources
= temp
;
2195 Context
->MaxActiveSources
= newcount
;
2198 for(i
= 0;i
< n
;i
++)
2200 Source
= LookupSource(Context
, sources
[i
]);
2201 if(Context
->DeferUpdates
) Source
->new_state
= AL_PLAYING
;
2202 else SetSourceState(Source
, Context
, AL_PLAYING
);
2204 UnlockContext(Context
);
2208 ALCcontext_DecRef(Context
);
2211 AL_API ALvoid AL_APIENTRY
alSourcePause(ALuint source
)
2213 alSourcePausev(1, &source
);
2215 AL_API ALvoid AL_APIENTRY
alSourcePausev(ALsizei n
, const ALuint
*sources
)
2217 ALCcontext
*Context
;
2221 Context
= GetContextRef();
2222 if(!Context
) return;
2226 CHECK_VALUE(Context
, n
>= 0);
2227 for(i
= 0;i
< n
;i
++)
2229 if(!LookupSource(Context
, sources
[i
]))
2230 al_throwerr(Context
, AL_INVALID_NAME
);
2233 LockContext(Context
);
2234 for(i
= 0;i
< n
;i
++)
2236 Source
= LookupSource(Context
, sources
[i
]);
2237 if(Context
->DeferUpdates
) Source
->new_state
= AL_PAUSED
;
2238 else SetSourceState(Source
, Context
, AL_PAUSED
);
2240 UnlockContext(Context
);
2244 ALCcontext_DecRef(Context
);
2247 AL_API ALvoid AL_APIENTRY
alSourceStop(ALuint source
)
2249 alSourceStopv(1, &source
);
2251 AL_API ALvoid AL_APIENTRY
alSourceStopv(ALsizei n
, const ALuint
*sources
)
2253 ALCcontext
*Context
;
2257 Context
= GetContextRef();
2258 if(!Context
) return;
2262 CHECK_VALUE(Context
, n
>= 0);
2263 for(i
= 0;i
< n
;i
++)
2265 if(!LookupSource(Context
, sources
[i
]))
2266 al_throwerr(Context
, AL_INVALID_NAME
);
2269 LockContext(Context
);
2270 for(i
= 0;i
< n
;i
++)
2272 Source
= LookupSource(Context
, sources
[i
]);
2273 Source
->new_state
= AL_NONE
;
2274 SetSourceState(Source
, Context
, AL_STOPPED
);
2276 UnlockContext(Context
);
2280 ALCcontext_DecRef(Context
);
2283 AL_API ALvoid AL_APIENTRY
alSourceRewind(ALuint source
)
2285 alSourceRewindv(1, &source
);
2287 AL_API ALvoid AL_APIENTRY
alSourceRewindv(ALsizei n
, const ALuint
*sources
)
2289 ALCcontext
*Context
;
2293 Context
= GetContextRef();
2294 if(!Context
) return;
2298 CHECK_VALUE(Context
, n
>= 0);
2299 for(i
= 0;i
< n
;i
++)
2301 if(!LookupSource(Context
, sources
[i
]))
2302 al_throwerr(Context
, AL_INVALID_NAME
);
2305 LockContext(Context
);
2306 for(i
= 0;i
< n
;i
++)
2308 Source
= LookupSource(Context
, sources
[i
]);
2309 Source
->new_state
= AL_NONE
;
2310 SetSourceState(Source
, Context
, AL_INITIAL
);
2312 UnlockContext(Context
);
2316 ALCcontext_DecRef(Context
);
2320 AL_API ALvoid AL_APIENTRY
alSourceQueueBuffers(ALuint source
, ALsizei nb
, const ALuint
*buffers
)
2322 ALCcontext
*Context
;
2325 ALbufferlistitem
*BufferListStart
= NULL
;
2326 ALbufferlistitem
*BufferList
;
2327 ALbuffer
*BufferFmt
;
2332 Context
= GetContextRef();
2333 if(!Context
) return;
2337 ALCdevice
*device
= Context
->Device
;
2339 CHECK_VALUE(Context
, nb
>= 0);
2341 if((Source
=LookupSource(Context
, source
)) == NULL
)
2342 al_throwerr(Context
, AL_INVALID_NAME
);
2344 LockContext(Context
);
2345 if(Source
->SourceType
== AL_STATIC
)
2347 UnlockContext(Context
);
2348 /* Can't queue on a Static Source */
2349 al_throwerr(Context
, AL_INVALID_OPERATION
);
2354 /* Check for a valid Buffer, for its frequency and format */
2355 BufferList
= Source
->queue
;
2358 if(BufferList
->buffer
)
2360 BufferFmt
= BufferList
->buffer
;
2363 BufferList
= BufferList
->next
;
2366 for(i
= 0;i
< nb
;i
++)
2368 ALbuffer
*buffer
= NULL
;
2369 if(buffers
[i
] && (buffer
=LookupBuffer(device
, buffers
[i
])) == NULL
)
2371 UnlockContext(Context
);
2372 al_throwerr(Context
, AL_INVALID_NAME
);
2375 if(!BufferListStart
)
2377 BufferListStart
= malloc(sizeof(ALbufferlistitem
));
2378 BufferListStart
->buffer
= buffer
;
2379 BufferListStart
->next
= NULL
;
2380 BufferListStart
->prev
= NULL
;
2381 BufferList
= BufferListStart
;
2385 BufferList
->next
= malloc(sizeof(ALbufferlistitem
));
2386 BufferList
->next
->buffer
= buffer
;
2387 BufferList
->next
->next
= NULL
;
2388 BufferList
->next
->prev
= BufferList
;
2389 BufferList
= BufferList
->next
;
2391 if(!buffer
) continue;
2392 IncrementRef(&buffer
->ref
);
2394 ReadLock(&buffer
->lock
);
2395 if(BufferFmt
== NULL
)
2399 Source
->NumChannels
= ChannelsFromFmt(buffer
->FmtChannels
);
2400 Source
->SampleSize
= BytesFromFmt(buffer
->FmtType
);
2401 if(buffer
->FmtChannels
== FmtMono
)
2402 Source
->Update
= CalcSourceParams
;
2404 Source
->Update
= CalcNonAttnSourceParams
;
2406 Source
->NeedsUpdate
= AL_TRUE
;
2408 else if(BufferFmt
->Frequency
!= buffer
->Frequency
||
2409 BufferFmt
->OriginalChannels
!= buffer
->OriginalChannels
||
2410 BufferFmt
->OriginalType
!= buffer
->OriginalType
)
2412 ReadUnlock(&buffer
->lock
);
2413 UnlockContext(Context
);
2414 al_throwerr(Context
, AL_INVALID_OPERATION
);
2416 ReadUnlock(&buffer
->lock
);
2419 /* Source is now streaming */
2420 Source
->SourceType
= AL_STREAMING
;
2422 if(Source
->queue
== NULL
)
2423 Source
->queue
= BufferListStart
;
2426 /* Append to the end of the queue */
2427 BufferList
= Source
->queue
;
2428 while(BufferList
->next
!= NULL
)
2429 BufferList
= BufferList
->next
;
2431 BufferListStart
->prev
= BufferList
;
2432 BufferList
->next
= BufferListStart
;
2435 Source
->BuffersInQueue
+= nb
;
2437 UnlockContext(Context
);
2441 while(BufferListStart
)
2443 BufferList
= BufferListStart
;
2444 BufferListStart
= BufferList
->next
;
2446 if(BufferList
->buffer
)
2447 DecrementRef(&BufferList
->buffer
->ref
);
2453 ALCcontext_DecRef(Context
);
2456 AL_API ALvoid AL_APIENTRY
alSourceUnqueueBuffers(ALuint source
, ALsizei nb
, ALuint
*buffers
)
2458 ALCcontext
*Context
;
2461 ALbufferlistitem
*BufferList
;
2466 Context
= GetContextRef();
2467 if(!Context
) return;
2471 CHECK_VALUE(Context
, nb
>= 0);
2473 if((Source
=LookupSource(Context
, source
)) == NULL
)
2474 al_throwerr(Context
, AL_INVALID_NAME
);
2476 LockContext(Context
);
2477 if(Source
->Looping
|| Source
->SourceType
!= AL_STREAMING
||
2478 (ALuint
)nb
> Source
->BuffersPlayed
)
2480 UnlockContext(Context
);
2481 /* Trying to unqueue pending buffers, or a buffer that wasn't queued. */
2482 al_throwerr(Context
, AL_INVALID_VALUE
);
2485 for(i
= 0;i
< nb
;i
++)
2487 BufferList
= Source
->queue
;
2488 Source
->queue
= BufferList
->next
;
2489 Source
->BuffersInQueue
--;
2490 Source
->BuffersPlayed
--;
2492 if(BufferList
->buffer
)
2494 buffers
[i
] = BufferList
->buffer
->id
;
2495 DecrementRef(&BufferList
->buffer
->ref
);
2503 Source
->queue
->prev
= NULL
;
2504 UnlockContext(Context
);
2508 ALCcontext_DecRef(Context
);
2512 static ALvoid
InitSourceParams(ALsource
*Source
)
2516 Source
->InnerAngle
= 360.0f
;
2517 Source
->OuterAngle
= 360.0f
;
2518 Source
->Pitch
= 1.0f
;
2519 Source
->Position
[0] = 0.0f
;
2520 Source
->Position
[1] = 0.0f
;
2521 Source
->Position
[2] = 0.0f
;
2522 Source
->Orientation
[0] = 0.0f
;
2523 Source
->Orientation
[1] = 0.0f
;
2524 Source
->Orientation
[2] = 0.0f
;
2525 Source
->Velocity
[0] = 0.0f
;
2526 Source
->Velocity
[1] = 0.0f
;
2527 Source
->Velocity
[2] = 0.0f
;
2528 Source
->RefDistance
= 1.0f
;
2529 Source
->MaxDistance
= FLT_MAX
;
2530 Source
->RollOffFactor
= 1.0f
;
2531 Source
->Looping
= AL_FALSE
;
2532 Source
->Gain
= 1.0f
;
2533 Source
->MinGain
= 0.0f
;
2534 Source
->MaxGain
= 1.0f
;
2535 Source
->OuterGain
= 0.0f
;
2536 Source
->OuterGainHF
= 1.0f
;
2538 Source
->DryGainHFAuto
= AL_TRUE
;
2539 Source
->WetGainAuto
= AL_TRUE
;
2540 Source
->WetGainHFAuto
= AL_TRUE
;
2541 Source
->AirAbsorptionFactor
= 0.0f
;
2542 Source
->RoomRolloffFactor
= 0.0f
;
2543 Source
->DopplerFactor
= 1.0f
;
2544 Source
->DirectChannels
= AL_FALSE
;
2546 Source
->DistanceModel
= DefaultDistanceModel
;
2548 Source
->Resampler
= DefaultResampler
;
2550 Source
->state
= AL_INITIAL
;
2551 Source
->new_state
= AL_NONE
;
2552 Source
->SourceType
= AL_UNDETERMINED
;
2553 Source
->Offset
= -1.0;
2555 Source
->DirectGain
= 1.0f
;
2556 Source
->DirectGainHF
= 1.0f
;
2557 for(i
= 0;i
< MAX_SENDS
;i
++)
2559 Source
->Send
[i
].Gain
= 1.0f
;
2560 Source
->Send
[i
].GainHF
= 1.0f
;
2563 Source
->NeedsUpdate
= AL_TRUE
;
2565 Source
->Hrtf
.Moving
= AL_FALSE
;
2566 Source
->Hrtf
.Counter
= 0;
2572 * Sets the source's new play state given its current state.
2574 ALvoid
SetSourceState(ALsource
*Source
, ALCcontext
*Context
, ALenum state
)
2576 if(state
== AL_PLAYING
)
2578 ALbufferlistitem
*BufferList
;
2581 /* Check that there is a queue containing at least one valid, non zero
2583 BufferList
= Source
->queue
;
2586 if(BufferList
->buffer
!= NULL
&& BufferList
->buffer
->SampleLen
)
2588 BufferList
= BufferList
->next
;
2591 if(Source
->state
!= AL_PLAYING
)
2593 for(j
= 0;j
< MaxChannels
;j
++)
2595 for(k
= 0;k
< SRC_HISTORY_LENGTH
;k
++)
2596 Source
->Hrtf
.History
[j
][k
] = 0.0f
;
2597 for(k
= 0;k
< HRIR_LENGTH
;k
++)
2599 Source
->Hrtf
.Values
[j
][k
][0] = 0.0f
;
2600 Source
->Hrtf
.Values
[j
][k
][1] = 0.0f
;
2605 if(Source
->state
!= AL_PAUSED
)
2607 Source
->state
= AL_PLAYING
;
2608 Source
->position
= 0;
2609 Source
->position_fraction
= 0;
2610 Source
->BuffersPlayed
= 0;
2613 Source
->state
= AL_PLAYING
;
2615 // Check if an Offset has been set
2616 if(Source
->Offset
>= 0.0)
2617 ApplyOffset(Source
);
2619 /* If there's nothing to play, or device is disconnected, go right to
2621 if(!BufferList
|| !Context
->Device
->Connected
)
2623 SetSourceState(Source
, Context
, AL_STOPPED
);
2627 for(j
= 0;j
< Context
->ActiveSourceCount
;j
++)
2629 if(Context
->ActiveSources
[j
] == Source
)
2632 if(j
== Context
->ActiveSourceCount
)
2633 Context
->ActiveSources
[Context
->ActiveSourceCount
++] = Source
;
2635 else if(state
== AL_PAUSED
)
2637 if(Source
->state
== AL_PLAYING
)
2639 Source
->state
= AL_PAUSED
;
2640 Source
->Hrtf
.Moving
= AL_FALSE
;
2641 Source
->Hrtf
.Counter
= 0;
2644 else if(state
== AL_STOPPED
)
2646 if(Source
->state
!= AL_INITIAL
)
2648 Source
->state
= AL_STOPPED
;
2649 Source
->BuffersPlayed
= Source
->BuffersInQueue
;
2650 Source
->Hrtf
.Moving
= AL_FALSE
;
2651 Source
->Hrtf
.Counter
= 0;
2653 Source
->Offset
= -1.0;
2655 else if(state
== AL_INITIAL
)
2657 if(Source
->state
!= AL_INITIAL
)
2659 Source
->state
= AL_INITIAL
;
2660 Source
->position
= 0;
2661 Source
->position_fraction
= 0;
2662 Source
->BuffersPlayed
= 0;
2663 Source
->Hrtf
.Moving
= AL_FALSE
;
2664 Source
->Hrtf
.Counter
= 0;
2666 Source
->Offset
= -1.0;
2672 * Gets the current read offset for the given Source, in 32.32 fixed-point
2673 * samples. The offset is relative to the start of the queue (not the start of
2674 * the current buffer).
2676 static ALint64
GetSourceOffset(const ALsource
*Source
)
2678 const ALbufferlistitem
*BufferList
;
2682 if(Source
->state
!= AL_PLAYING
&& Source
->state
!= AL_PAUSED
)
2685 /* NOTE: This is the offset into the *current* buffer, so add the length of
2686 * any played buffers */
2687 readPos
= (ALuint64
)Source
->position
<< 32;
2688 readPos
|= (ALuint64
)Source
->position_fraction
<< (32-FRACTIONBITS
);
2689 BufferList
= Source
->queue
;
2690 for(i
= 0;i
< Source
->BuffersPlayed
&& BufferList
;i
++)
2692 if(BufferList
->buffer
)
2693 readPos
+= (ALuint64
)BufferList
->buffer
->SampleLen
<< 32;
2694 BufferList
= BufferList
->next
;
2697 return (ALint64
)minu64(readPos
, MAKEU64(0x7fffffff,0xffffffff));
2700 /* GetSourceSecOffset
2702 * Gets the current read offset for the given Source, in seconds. The offset is
2703 * relative to the start of the queue (not the start of the current buffer).
2705 static ALdouble
GetSourceSecOffset(const ALsource
*Source
)
2707 const ALbufferlistitem
*BufferList
;
2708 const ALbuffer
*Buffer
= NULL
;
2712 BufferList
= Source
->queue
;
2715 if(BufferList
->buffer
)
2717 Buffer
= BufferList
->buffer
;
2720 BufferList
= BufferList
->next
;
2723 if((Source
->state
!= AL_PLAYING
&& Source
->state
!= AL_PAUSED
) || !Buffer
)
2726 /* NOTE: This is the offset into the *current* buffer, so add the length of
2727 * any played buffers */
2728 readPos
= (ALuint64
)Source
->position
<< FRACTIONBITS
;
2729 readPos
|= (ALuint64
)Source
->position_fraction
;
2730 BufferList
= Source
->queue
;
2731 for(i
= 0;i
< Source
->BuffersPlayed
&& BufferList
;i
++)
2733 if(BufferList
->buffer
)
2734 readPos
+= (ALuint64
)BufferList
->buffer
->SampleLen
<< FRACTIONBITS
;
2735 BufferList
= BufferList
->next
;
2738 return (ALdouble
)readPos
/ (ALdouble
)FRACTIONONE
/ (ALdouble
)Buffer
->Frequency
;
2743 * Gets the current read and write offsets for the given Source, in the
2744 * appropriate format (Bytes, Samples or Seconds). The offsets are relative to
2745 * the start of the queue (not the start of the current buffer).
2747 static ALvoid
GetSourceOffsets(const ALsource
*Source
, ALenum name
, ALdouble
*offset
, ALdouble updateLen
)
2749 const ALbufferlistitem
*BufferList
;
2750 const ALbuffer
*Buffer
= NULL
;
2751 ALuint readPos
, writePos
;
2752 ALuint totalBufferLen
;
2755 // Find the first valid Buffer in the Queue
2756 BufferList
= Source
->queue
;
2759 if(BufferList
->buffer
)
2761 Buffer
= BufferList
->buffer
;
2764 BufferList
= BufferList
->next
;
2767 if((Source
->state
!= AL_PLAYING
&& Source
->state
!= AL_PAUSED
) || !Buffer
)
2774 if(updateLen
> 0.0 && updateLen
< 0.015)
2777 /* NOTE: This is the offset into the *current* buffer, so add the length of
2778 * any played buffers */
2779 readPos
= Source
->position
;
2781 BufferList
= Source
->queue
;
2782 for(i
= 0;BufferList
;i
++)
2784 if(BufferList
->buffer
)
2786 if(i
< Source
->BuffersPlayed
)
2787 readPos
+= BufferList
->buffer
->SampleLen
;
2788 totalBufferLen
+= BufferList
->buffer
->SampleLen
;
2790 BufferList
= BufferList
->next
;
2792 if(Source
->state
== AL_PLAYING
)
2793 writePos
= readPos
+ (ALuint
)(updateLen
*Buffer
->Frequency
);
2799 readPos
%= totalBufferLen
;
2800 writePos
%= totalBufferLen
;
2804 /* Wrap positions back to 0 */
2805 if(readPos
>= totalBufferLen
)
2807 if(writePos
>= totalBufferLen
)
2814 offset
[0] = (ALdouble
)readPos
/ Buffer
->Frequency
;
2815 offset
[1] = (ALdouble
)writePos
/ Buffer
->Frequency
;
2818 case AL_SAMPLE_OFFSET
:
2819 case AL_SAMPLE_RW_OFFSETS_SOFT
:
2820 offset
[0] = (ALdouble
)readPos
;
2821 offset
[1] = (ALdouble
)writePos
;
2824 case AL_BYTE_OFFSET
:
2825 case AL_BYTE_RW_OFFSETS_SOFT
:
2826 if(Buffer
->OriginalType
== UserFmtIMA4
)
2828 ALuint BlockSize
= 36 * ChannelsFromFmt(Buffer
->FmtChannels
);
2829 ALuint FrameBlockSize
= 65;
2831 /* Round down to nearest ADPCM block */
2832 offset
[0] = (ALdouble
)(readPos
/ FrameBlockSize
* BlockSize
);
2833 if(Source
->state
!= AL_PLAYING
)
2834 offset
[1] = offset
[0];
2837 /* Round up to nearest ADPCM block */
2838 offset
[1] = (ALdouble
)((writePos
+FrameBlockSize
-1) /
2839 FrameBlockSize
* BlockSize
);
2844 ALuint FrameSize
= FrameSizeFromUserFmt(Buffer
->OriginalChannels
, Buffer
->OriginalType
);
2845 offset
[0] = (ALdouble
)(readPos
* FrameSize
);
2846 offset
[1] = (ALdouble
)(writePos
* FrameSize
);
2855 * Apply the stored playback offset to the Source. This function will update
2856 * the number of buffers "played" given the stored offset.
2858 ALboolean
ApplyOffset(ALsource
*Source
)
2860 const ALbufferlistitem
*BufferList
;
2861 const ALbuffer
*Buffer
;
2862 ALint bufferLen
, totalBufferLen
;
2863 ALint buffersPlayed
;
2866 /* Get sample frame offset */
2867 offset
= GetSampleOffset(Source
);
2874 BufferList
= Source
->queue
;
2877 Buffer
= BufferList
->buffer
;
2878 bufferLen
= Buffer
? Buffer
->SampleLen
: 0;
2880 if(bufferLen
<= offset
-totalBufferLen
)
2882 /* Offset is past this buffer so increment to the next buffer */
2885 else if(totalBufferLen
<= offset
)
2887 /* Offset is in this buffer */
2888 Source
->BuffersPlayed
= buffersPlayed
;
2890 Source
->position
= offset
- totalBufferLen
;
2891 Source
->position_fraction
= 0;
2895 totalBufferLen
+= bufferLen
;
2897 BufferList
= BufferList
->next
;
2900 /* Offset is out of range of the queue */
2907 * Returns the sample offset into the Source's queue (from the Sample, Byte or
2908 * Second offset supplied by the application). This takes into account the fact
2909 * that the buffer format may have been modifed since.
2911 static ALint
GetSampleOffset(ALsource
*Source
)
2913 const ALbuffer
*Buffer
= NULL
;
2914 const ALbufferlistitem
*BufferList
;
2917 /* Find the first valid Buffer in the Queue */
2918 BufferList
= Source
->queue
;
2921 if(BufferList
->buffer
)
2923 Buffer
= BufferList
->buffer
;
2926 BufferList
= BufferList
->next
;
2931 Source
->Offset
= -1.0;
2935 switch(Source
->OffsetType
)
2937 case AL_BYTE_OFFSET
:
2938 /* Determine the ByteOffset (and ensure it is block aligned) */
2939 Offset
= (ALint
)Source
->Offset
;
2940 if(Buffer
->OriginalType
== UserFmtIMA4
)
2942 Offset
/= 36 * ChannelsFromUserFmt(Buffer
->OriginalChannels
);
2946 Offset
/= FrameSizeFromUserFmt(Buffer
->OriginalChannels
, Buffer
->OriginalType
);
2949 case AL_SAMPLE_OFFSET
:
2950 Offset
= (ALint
)Source
->Offset
;
2954 Offset
= (ALint
)(Source
->Offset
* Buffer
->Frequency
);
2957 Source
->Offset
= -1.0;
2965 * Destroys all sources in the source map.
2967 ALvoid
ReleaseALSources(ALCcontext
*Context
)
2971 for(pos
= 0;pos
< Context
->SourceMap
.size
;pos
++)
2973 ALsource
*temp
= Context
->SourceMap
.array
[pos
].value
;
2974 Context
->SourceMap
.array
[pos
].value
= NULL
;
2976 while(temp
->queue
!= NULL
)
2978 ALbufferlistitem
*BufferList
= temp
->queue
;
2979 temp
->queue
= BufferList
->next
;
2981 if(BufferList
->buffer
!= NULL
)
2982 DecrementRef(&BufferList
->buffer
->ref
);
2986 for(j
= 0;j
< MAX_SENDS
;++j
)
2988 if(temp
->Send
[j
].Slot
)
2989 DecrementRef(&temp
->Send
[j
].Slot
->ref
);
2990 temp
->Send
[j
].Slot
= NULL
;
2993 FreeThunkEntry(temp
->id
);
2994 memset(temp
, 0, sizeof(*temp
));