zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
alSource.c
Go to the documentation of this file.
1 
21 #include "config.h"
22 
23 #include <stdlib.h>
24 #include <math.h>
25 #include <float.h>
26 
27 #include "AL/al.h"
28 #include "AL/alc.h"
29 #include "alMain.h"
30 #include "alError.h"
31 #include "alSource.h"
32 #include "alBuffer.h"
33 #include "alThunk.h"
34 #include "alAuxEffectSlot.h"
35 
36 
39  0, /* Point */
40  1, /* Linear */
41  2, /* Cubic */
42 };
44  0, /* Point */
45  0, /* Linear */
46  1, /* Cubic */
47 };
48 
49 
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);
55 
56 typedef enum SrcFloatProp {
71 
75 
83 
84  /* ALC_EXT_EFX */
91 
92  /* AL_SOFT_direct_channels */
94 
95  /* AL_EXT_source_distance_model */
97 
98  /* AL_SOFT_buffer_sub_data / AL_SOFT_buffer_samples */
101 
102  /* AL_SOFT_source_latency */
104 } SrcFloatProp;
105 
106 typedef enum SrcIntProp {
126 
127  /* ALC_EXT_EFX */
133 
134  /* AL_SOFT_direct_channels */
136 
137  /* AL_EXT_source_distance_model */
139 
140  /* AL_SOFT_buffer_sub_data / AL_SOFT_buffer_samples */
143 
144  /* AL_SOFT_source_latency */
146 } SrcIntProp;
147 
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);
151 
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);
155 
157 {
158  if(prop != (ALenum)((SrcFloatProp)prop))
159  return 0;
160  switch((SrcFloatProp)prop)
161  {
162  case sfPitch:
163  case sfGain:
164  case sfMinGain:
165  case sfMaxGain:
166  case sfMaxDistance:
167  case sfRolloffFactor:
168  case sfDopplerFactor:
169  case sfConeOuterGain:
170  case sfSecOffset:
171  case sfSampleOffset:
172  case sfByteOffset:
173  case sfConeInnerAngle:
174  case sfConeOuterAngle:
175  case sfRefDistance:
176  case sfConeOuterGainHF:
178  case sfRoomRolloffFactor:
183  case sfDistanceModel:
184  case sfSourceRelative:
185  case sfLooping:
186  case sfBuffer:
187  case sfSourceState:
188  case sfBuffersQueued:
189  case sfBuffersProcessed:
190  case sfSourceType:
191  return 1;
192 
194  case sfByteRWOffsetsSOFT:
195  return 2;
196 
197  case sfPosition:
198  case sfVelocity:
199  case sfDirection:
200  return 3;
201 
203  break; /* Double only */
204  }
205  return 0;
206 }
208 {
209  if(prop != (ALenum)((SrcFloatProp)prop))
210  return 0;
211  switch((SrcFloatProp)prop)
212  {
213  case sfPitch:
214  case sfGain:
215  case sfMinGain:
216  case sfMaxGain:
217  case sfMaxDistance:
218  case sfRolloffFactor:
219  case sfDopplerFactor:
220  case sfConeOuterGain:
221  case sfSecOffset:
222  case sfSampleOffset:
223  case sfByteOffset:
224  case sfConeInnerAngle:
225  case sfConeOuterAngle:
226  case sfRefDistance:
227  case sfConeOuterGainHF:
229  case sfRoomRolloffFactor:
234  case sfDistanceModel:
235  case sfSourceRelative:
236  case sfLooping:
237  case sfBuffer:
238  case sfSourceState:
239  case sfBuffersQueued:
240  case sfBuffersProcessed:
241  case sfSourceType:
242  return 1;
243 
245  case sfByteRWOffsetsSOFT:
247  return 2;
248 
249  case sfPosition:
250  case sfVelocity:
251  case sfDirection:
252  return 3;
253  }
254  return 0;
255 }
256 
258 {
259  if(prop != (ALenum)((SrcIntProp)prop))
260  return 0;
261  switch((SrcIntProp)prop)
262  {
263  case siMaxDistance:
264  case siRolloffFactor:
265  case siRefDistance:
266  case siSourceRelative:
267  case siConeInnerAngle:
268  case siConeOuterAngle:
269  case siLooping:
270  case siBuffer:
271  case siSourceState:
272  case siBuffersQueued:
273  case siBuffersProcessed:
274  case siSourceType:
275  case siSecOffset:
276  case siSampleOffset:
277  case siByteOffset:
278  case siDopplerFactor:
282  case siDirectFilter:
284  case siDistanceModel:
285  return 1;
286 
288  case siByteRWOffsetsSOFT:
289  return 2;
290 
291  case siPosition:
292  case siVelocity:
293  case siDirection:
294  case siAuxSendFilter:
295  return 3;
296 
298  break; /* i64 only */
299  }
300  return 0;
301 }
303 {
304  if(prop != (ALenum)((SrcIntProp)prop))
305  return 0;
306  switch((SrcIntProp)prop)
307  {
308  case siMaxDistance:
309  case siRolloffFactor:
310  case siRefDistance:
311  case siSourceRelative:
312  case siConeInnerAngle:
313  case siConeOuterAngle:
314  case siLooping:
315  case siBuffer:
316  case siSourceState:
317  case siBuffersQueued:
318  case siBuffersProcessed:
319  case siSourceType:
320  case siSecOffset:
321  case siSampleOffset:
322  case siByteOffset:
323  case siDopplerFactor:
327  case siDirectFilter:
329  case siDistanceModel:
330  return 1;
331 
333  case siByteRWOffsetsSOFT:
335  return 2;
336 
337  case siPosition:
338  case siVelocity:
339  case siDirection:
340  case siAuxSendFilter:
341  return 3;
342  }
343  return 0;
344 }
345 
346 
347 #define RETERR(x) do { \
348  alSetError(Context, (x)); \
349  return (x); \
350 } while(0)
351 
352 #define CHECKVAL(x) do { \
353  if(!(x)) \
354  RETERR(AL_INVALID_VALUE); \
355 } while(0)
356 
357 static ALenum SetSourcefv(ALsource *Source, ALCcontext *Context, SrcFloatProp prop, const ALfloat *values)
358 {
359  ALint ival;
360 
361  switch(prop)
362  {
363  case AL_PITCH:
364  CHECKVAL(*values >= 0.0f);
365 
366  Source->Pitch = *values;
367  Source->NeedsUpdate = AL_TRUE;
368  return AL_NO_ERROR;
369 
370  case AL_CONE_INNER_ANGLE:
371  CHECKVAL(*values >= 0.0f && *values <= 360.0f);
372 
373  Source->InnerAngle = *values;
374  Source->NeedsUpdate = AL_TRUE;
375  return AL_NO_ERROR;
376 
377  case AL_CONE_OUTER_ANGLE:
378  CHECKVAL(*values >= 0.0f && *values <= 360.0f);
379 
380  Source->OuterAngle = *values;
381  Source->NeedsUpdate = AL_TRUE;
382  return AL_NO_ERROR;
383 
384  case AL_GAIN:
385  CHECKVAL(*values >= 0.0f);
386 
387  Source->Gain = *values;
388  Source->NeedsUpdate = AL_TRUE;
389  return AL_NO_ERROR;
390 
391  case AL_MAX_DISTANCE:
392  CHECKVAL(*values >= 0.0f);
393 
394  Source->MaxDistance = *values;
395  Source->NeedsUpdate = AL_TRUE;
396  return AL_NO_ERROR;
397 
398  case AL_ROLLOFF_FACTOR:
399  CHECKVAL(*values >= 0.0f);
400 
401  Source->RollOffFactor = *values;
402  Source->NeedsUpdate = AL_TRUE;
403  return AL_NO_ERROR;
404 
406  CHECKVAL(*values >= 0.0f);
407 
408  Source->RefDistance = *values;
409  Source->NeedsUpdate = AL_TRUE;
410  return AL_NO_ERROR;
411 
412  case AL_MIN_GAIN:
413  CHECKVAL(*values >= 0.0f && *values <= 1.0f);
414 
415  Source->MinGain = *values;
416  Source->NeedsUpdate = AL_TRUE;
417  return AL_NO_ERROR;
418 
419  case AL_MAX_GAIN:
420  CHECKVAL(*values >= 0.0f && *values <= 1.0f);
421 
422  Source->MaxGain = *values;
423  Source->NeedsUpdate = AL_TRUE;
424  return AL_NO_ERROR;
425 
426  case AL_CONE_OUTER_GAIN:
427  CHECKVAL(*values >= 0.0f && *values <= 1.0f);
428 
429  Source->OuterGain = *values;
430  Source->NeedsUpdate = AL_TRUE;
431  return AL_NO_ERROR;
432 
434  CHECKVAL(*values >= 0.0f && *values <= 1.0f);
435 
436  Source->OuterGainHF = *values;
437  Source->NeedsUpdate = AL_TRUE;
438  return AL_NO_ERROR;
439 
441  CHECKVAL(*values >= 0.0f && *values <= 10.0f);
442 
443  Source->AirAbsorptionFactor = *values;
444  Source->NeedsUpdate = AL_TRUE;
445  return AL_NO_ERROR;
446 
448  CHECKVAL(*values >= 0.0f && *values <= 10.0f);
449 
450  Source->RoomRolloffFactor = *values;
451  Source->NeedsUpdate = AL_TRUE;
452  return AL_NO_ERROR;
453 
454  case AL_DOPPLER_FACTOR:
455  CHECKVAL(*values >= 0.0f && *values <= 1.0f);
456 
457  Source->DopplerFactor = *values;
458  Source->NeedsUpdate = AL_TRUE;
459  return AL_NO_ERROR;
460 
461  case AL_SEC_OFFSET:
462  case AL_SAMPLE_OFFSET:
463  case AL_BYTE_OFFSET:
464  CHECKVAL(*values >= 0.0f);
465 
466  LockContext(Context);
467  Source->OffsetType = prop;
468  Source->Offset = *values;
469 
470  if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
471  !Context->DeferUpdates)
472  {
473  if(ApplyOffset(Source) == AL_FALSE)
474  {
475  UnlockContext(Context);
477  }
478  }
479  UnlockContext(Context);
480  return AL_NO_ERROR;
481 
482 
484  /* Query only */
486 
487 
488  case AL_POSITION:
489  CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2]));
490 
491  LockContext(Context);
492  Source->Position[0] = values[0];
493  Source->Position[1] = values[1];
494  Source->Position[2] = values[2];
495  UnlockContext(Context);
496  Source->NeedsUpdate = AL_TRUE;
497  return AL_NO_ERROR;
498 
499  case AL_VELOCITY:
500  CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2]));
501 
502  LockContext(Context);
503  Source->Velocity[0] = values[0];
504  Source->Velocity[1] = values[1];
505  Source->Velocity[2] = values[2];
506  UnlockContext(Context);
507  Source->NeedsUpdate = AL_TRUE;
508  return AL_NO_ERROR;
509 
510  case AL_DIRECTION:
511  CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2]));
512 
513  LockContext(Context);
514  Source->Orientation[0] = values[0];
515  Source->Orientation[1] = values[1];
516  Source->Orientation[2] = values[2];
517  UnlockContext(Context);
518  Source->NeedsUpdate = AL_TRUE;
519  return AL_NO_ERROR;
520 
521 
523  case sfByteRWOffsetsSOFT:
525 
526 
527  case sfSourceRelative:
528  case sfLooping:
529  case sfSourceState:
530  case sfSourceType:
531  case sfDistanceModel:
536  ival = (ALint)values[0];
537  return SetSourceiv(Source, Context, prop, &ival);
538 
539  case sfBuffer:
540  case sfBuffersQueued:
541  case sfBuffersProcessed:
542  ival = (ALint)((ALuint)values[0]);
543  return SetSourceiv(Source, Context, prop, &ival);
544  }
545 
546  ERR("Unexpected property: 0x%04x\n", prop);
548 }
549 
550 static ALenum SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint *values)
551 {
552  ALCdevice *device = Context->Device;
553  ALbuffer *buffer = NULL;
554  ALfilter *filter = NULL;
555  ALeffectslot *slot = NULL;
556  ALbufferlistitem *oldlist;
557  ALfloat fvals[3];
558 
559  switch(prop)
560  {
561  case AL_SOURCE_RELATIVE:
562  CHECKVAL(*values == AL_FALSE || *values == AL_TRUE);
563 
564  Source->HeadRelative = (ALboolean)*values;
565  Source->NeedsUpdate = AL_TRUE;
566  return AL_NO_ERROR;
567 
568  case AL_LOOPING:
569  CHECKVAL(*values == AL_FALSE || *values == AL_TRUE);
570 
571  Source->Looping = (ALboolean)*values;
572  return AL_NO_ERROR;
573 
574  case AL_BUFFER:
575  CHECKVAL(*values == 0 || (buffer=LookupBuffer(device, *values)) != NULL);
576 
577  LockContext(Context);
578  if(!(Source->state == AL_STOPPED || Source->state == AL_INITIAL))
579  {
580  UnlockContext(Context);
582  }
583 
584  Source->BuffersInQueue = 0;
585  Source->BuffersPlayed = 0;
586 
587  if(buffer != NULL)
588  {
589  ALbufferlistitem *BufferListItem;
590 
591  /* Source is now Static */
592  Source->SourceType = AL_STATIC;
593 
594  /* Add the selected buffer to a one-item queue */
595  BufferListItem = malloc(sizeof(ALbufferlistitem));
596  BufferListItem->buffer = buffer;
597  BufferListItem->next = NULL;
598  BufferListItem->prev = NULL;
599  IncrementRef(&buffer->ref);
600 
601  oldlist = ExchangePtr((XchgPtr*)&Source->queue, BufferListItem);
602  Source->BuffersInQueue = 1;
603 
604  ReadLock(&buffer->lock);
605  Source->NumChannels = ChannelsFromFmt(buffer->FmtChannels);
606  Source->SampleSize = BytesFromFmt(buffer->FmtType);
607  ReadUnlock(&buffer->lock);
608  if(buffer->FmtChannels == FmtMono)
609  Source->Update = CalcSourceParams;
610  else
612  Source->NeedsUpdate = AL_TRUE;
613  }
614  else
615  {
616  /* Source is now Undetermined */
617  Source->SourceType = AL_UNDETERMINED;
618  oldlist = ExchangePtr((XchgPtr*)&Source->queue, NULL);
619  }
620 
621  /* Delete all elements in the previous queue */
622  while(oldlist != NULL)
623  {
624  ALbufferlistitem *temp = oldlist;
625  oldlist = temp->next;
626 
627  if(temp->buffer)
628  DecrementRef(&temp->buffer->ref);
629  free(temp);
630  }
631  UnlockContext(Context);
632  return AL_NO_ERROR;
633 
634  case siSourceState:
635  case siSourceType:
636  case siBuffersQueued:
637  case siBuffersProcessed:
638  /* Query only */
640 
641  case AL_SEC_OFFSET:
642  case AL_SAMPLE_OFFSET:
643  case AL_BYTE_OFFSET:
644  CHECKVAL(*values >= 0);
645 
646  LockContext(Context);
647  Source->OffsetType = prop;
648  Source->Offset = *values;
649 
650  if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
651  !Context->DeferUpdates)
652  {
653  if(ApplyOffset(Source) == AL_FALSE)
654  {
655  UnlockContext(Context);
657  }
658  }
659  UnlockContext(Context);
660  return AL_NO_ERROR;
661 
662 
664  case siByteRWOffsetsSOFT:
665  /* Query only */
667 
668 
669  case AL_DIRECT_FILTER:
670  CHECKVAL(*values == 0 || (filter=LookupFilter(device, *values)) != NULL);
671 
672  LockContext(Context);
673  if(!filter)
674  {
675  Source->DirectGain = 1.0f;
676  Source->DirectGainHF = 1.0f;
677  }
678  else
679  {
680  Source->DirectGain = filter->Gain;
681  Source->DirectGainHF = filter->GainHF;
682  }
683  UnlockContext(Context);
684  Source->NeedsUpdate = AL_TRUE;
685  return AL_NO_ERROR;
686 
688  CHECKVAL(*values == AL_FALSE || *values == AL_TRUE);
689 
690  Source->DryGainHFAuto = *values;
691  Source->NeedsUpdate = AL_TRUE;
692  return AL_NO_ERROR;
693 
695  CHECKVAL(*values == AL_FALSE || *values == AL_TRUE);
696 
697  Source->WetGainAuto = *values;
698  Source->NeedsUpdate = AL_TRUE;
699  return AL_NO_ERROR;
700 
702  CHECKVAL(*values == AL_FALSE || *values == AL_TRUE);
703 
704  Source->WetGainHFAuto = *values;
705  Source->NeedsUpdate = AL_TRUE;
706  return AL_NO_ERROR;
707 
709  CHECKVAL(*values == AL_FALSE || *values == AL_TRUE);
710 
711  Source->DirectChannels = *values;
712  Source->NeedsUpdate = AL_TRUE;
713  return AL_NO_ERROR;
714 
715  case AL_DISTANCE_MODEL:
716  CHECKVAL(*values == AL_NONE ||
717  *values == AL_INVERSE_DISTANCE ||
718  *values == AL_INVERSE_DISTANCE_CLAMPED ||
719  *values == AL_LINEAR_DISTANCE ||
720  *values == AL_LINEAR_DISTANCE_CLAMPED ||
721  *values == AL_EXPONENT_DISTANCE ||
722  *values == AL_EXPONENT_DISTANCE_CLAMPED);
723 
724  Source->DistanceModel = *values;
725  if(Context->SourceDistanceModel)
726  Source->NeedsUpdate = AL_TRUE;
727  return AL_NO_ERROR;
728 
729 
731  LockContext(Context);
732  if(!((ALuint)values[1] < device->NumAuxSends &&
733  (values[0] == 0 || (slot=LookupEffectSlot(Context, values[0])) != NULL) &&
734  (values[2] == 0 || (filter=LookupFilter(device, values[2])) != NULL)))
735  {
736  UnlockContext(Context);
738  }
739 
740  /* Add refcount on the new slot, and release the previous slot */
741  if(slot) IncrementRef(&slot->ref);
742  slot = ExchangePtr((XchgPtr*)&Source->Send[values[1]].Slot, slot);
743  if(slot) DecrementRef(&slot->ref);
744 
745  if(!filter)
746  {
747  /* Disable filter */
748  Source->Send[values[1]].Gain = 1.0f;
749  Source->Send[values[1]].GainHF = 1.0f;
750  }
751  else
752  {
753  Source->Send[values[1]].Gain = filter->Gain;
754  Source->Send[values[1]].GainHF = filter->GainHF;
755  }
756  Source->NeedsUpdate = AL_TRUE;
757  UnlockContext(Context);
758  return AL_NO_ERROR;
759 
760 
761  case AL_MAX_DISTANCE:
762  case AL_ROLLOFF_FACTOR:
763  case AL_CONE_INNER_ANGLE:
764  case AL_CONE_OUTER_ANGLE:
766  case siDopplerFactor:
767  fvals[0] = (ALfloat)*values;
768  return SetSourcefv(Source, Context, (int)prop, fvals);
769 
770  case AL_POSITION:
771  case AL_VELOCITY:
772  case AL_DIRECTION:
773  fvals[0] = (ALfloat)values[0];
774  fvals[1] = (ALfloat)values[1];
775  fvals[2] = (ALfloat)values[2];
776  return SetSourcefv(Source, Context, (int)prop, fvals);
777 
779  /* i64 only */
780  break;
781  }
782 
783  ERR("Unexpected property: 0x%04x\n", prop);
785 }
786 
787 static ALenum SetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint64SOFT *values)
788 {
789  ALfloat fvals[3];
790  ALint ivals[3];
791 
792  switch(prop)
793  {
795  case siByteRWOffsetsSOFT:
797  /* Query only */
799 
800 
801  /* 1x int */
802  case AL_SOURCE_RELATIVE:
803  case AL_LOOPING:
804  case AL_SOURCE_STATE:
805  case AL_BYTE_OFFSET:
806  case AL_SAMPLE_OFFSET:
807  case siSourceType:
808  case siBuffersQueued:
809  case siBuffersProcessed:
814  case AL_DISTANCE_MODEL:
816 
817  ivals[0] = (ALint)*values;
818  return SetSourceiv(Source, Context, (int)prop, ivals);
819 
820  /* 1x uint */
821  case AL_BUFFER:
822  case AL_DIRECT_FILTER:
824 
825  ivals[0] = (ALuint)*values;
826  return SetSourceiv(Source, Context, (int)prop, ivals);
827 
828  /* 3x uint */
830  CHECKVAL(values[0] <= UINT_MAX && values[0] >= 0 &&
831  values[1] <= UINT_MAX && values[1] >= 0 &&
832  values[2] <= UINT_MAX && values[2] >= 0);
833 
834  ivals[0] = (ALuint)values[0];
835  ivals[1] = (ALuint)values[1];
836  ivals[2] = (ALuint)values[2];
837  return SetSourceiv(Source, Context, (int)prop, ivals);
838 
839  /* 1x float */
840  case AL_MAX_DISTANCE:
841  case AL_ROLLOFF_FACTOR:
842  case AL_CONE_INNER_ANGLE:
843  case AL_CONE_OUTER_ANGLE:
845  case AL_SEC_OFFSET:
846  case siDopplerFactor:
847  fvals[0] = (ALfloat)*values;
848  return SetSourcefv(Source, Context, (int)prop, fvals);
849 
850  /* 3x float */
851  case AL_POSITION:
852  case AL_VELOCITY:
853  case AL_DIRECTION:
854  fvals[0] = (ALfloat)values[0];
855  fvals[1] = (ALfloat)values[1];
856  fvals[2] = (ALfloat)values[2];
857  return SetSourcefv(Source, Context, (int)prop, fvals);
858  }
859 
860  ERR("Unexpected property: 0x%04x\n", prop);
862 }
863 
864 #undef CHECKVAL
865 
866 
867 static ALenum GetSourcedv(const ALsource *Source, ALCcontext *Context, SrcFloatProp prop, ALdouble *values)
868 {
869  ALdouble offsets[2];
870  ALdouble updateLen;
871  ALint ivals[3];
872  ALenum err;
873 
874  switch(prop)
875  {
876  case AL_GAIN:
877  *values = Source->Gain;
878  return AL_NO_ERROR;
879 
880  case AL_PITCH:
881  *values = Source->Pitch;
882  return AL_NO_ERROR;
883 
884  case AL_MAX_DISTANCE:
885  *values = Source->MaxDistance;
886  return AL_NO_ERROR;
887 
888  case AL_ROLLOFF_FACTOR:
889  *values = Source->RollOffFactor;
890  return AL_NO_ERROR;
891 
893  *values = Source->RefDistance;
894  return AL_NO_ERROR;
895 
896  case AL_CONE_INNER_ANGLE:
897  *values = Source->InnerAngle;
898  return AL_NO_ERROR;
899 
900  case AL_CONE_OUTER_ANGLE:
901  *values = Source->OuterAngle;
902  return AL_NO_ERROR;
903 
904  case AL_MIN_GAIN:
905  *values = Source->MinGain;
906  return AL_NO_ERROR;
907 
908  case AL_MAX_GAIN:
909  *values = Source->MaxGain;
910  return AL_NO_ERROR;
911 
912  case AL_CONE_OUTER_GAIN:
913  *values = Source->OuterGain;
914  return AL_NO_ERROR;
915 
916  case AL_SEC_OFFSET:
917  case AL_SAMPLE_OFFSET:
918  case AL_BYTE_OFFSET:
919  LockContext(Context);
920  updateLen = (ALdouble)Context->Device->UpdateSize /
921  Context->Device->Frequency;
922  GetSourceOffsets(Source, prop, offsets, updateLen);
923  UnlockContext(Context);
924  *values = offsets[0];
925  return AL_NO_ERROR;
926 
928  *values = Source->OuterGainHF;
929  return AL_NO_ERROR;
930 
932  *values = Source->AirAbsorptionFactor;
933  return AL_NO_ERROR;
934 
936  *values = Source->RoomRolloffFactor;
937  return AL_NO_ERROR;
938 
939  case AL_DOPPLER_FACTOR:
940  *values = Source->DopplerFactor;
941  return AL_NO_ERROR;
942 
945  LockContext(Context);
946  updateLen = (ALdouble)Context->Device->UpdateSize /
947  Context->Device->Frequency;
948  GetSourceOffsets(Source, prop, values, updateLen);
949  UnlockContext(Context);
950  return AL_NO_ERROR;
951 
953  LockContext(Context);
954  values[0] = GetSourceSecOffset(Source);
955  values[1] = (ALdouble)ALCdevice_GetLatency(Context->Device) /
956  1000000000.0;
957  UnlockContext(Context);
958  return AL_NO_ERROR;
959 
960  case AL_POSITION:
961  LockContext(Context);
962  values[0] = Source->Position[0];
963  values[1] = Source->Position[1];
964  values[2] = Source->Position[2];
965  UnlockContext(Context);
966  return AL_NO_ERROR;
967 
968  case AL_VELOCITY:
969  LockContext(Context);
970  values[0] = Source->Velocity[0];
971  values[1] = Source->Velocity[1];
972  values[2] = Source->Velocity[2];
973  UnlockContext(Context);
974  return AL_NO_ERROR;
975 
976  case AL_DIRECTION:
977  LockContext(Context);
978  values[0] = Source->Orientation[0];
979  values[1] = Source->Orientation[1];
980  values[2] = Source->Orientation[2];
981  UnlockContext(Context);
982  return AL_NO_ERROR;
983 
984  case AL_SOURCE_RELATIVE:
985  case AL_LOOPING:
986  case AL_BUFFER:
987  case AL_SOURCE_STATE:
988  case AL_BUFFERS_QUEUED:
990  case AL_SOURCE_TYPE:
995  case AL_DISTANCE_MODEL:
996  if((err=GetSourceiv(Source, Context, (int)prop, ivals)) == AL_NO_ERROR)
997  *values = (ALdouble)ivals[0];
998  return err;
999  }
1000 
1001  ERR("Unexpected property: 0x%04x\n", prop);
1003 }
1004 
1005 static ALenum GetSourceiv(const ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint *values)
1006 {
1007  ALbufferlistitem *BufferList;
1008  ALdouble dvals[3];
1009  ALenum err;
1010 
1011  switch(prop)
1012  {
1013  case AL_SOURCE_RELATIVE:
1014  *values = Source->HeadRelative;
1015  return AL_NO_ERROR;
1016 
1017  case AL_LOOPING:
1018  *values = Source->Looping;
1019  return AL_NO_ERROR;
1020 
1021  case AL_BUFFER:
1022  LockContext(Context);
1023  BufferList = Source->queue;
1024  if(Source->SourceType != AL_STATIC)
1025  {
1026  ALuint i = Source->BuffersPlayed;
1027  while(i > 0)
1028  {
1029  BufferList = BufferList->next;
1030  i--;
1031  }
1032  }
1033  *values = ((BufferList && BufferList->buffer) ?
1034  BufferList->buffer->id : 0);
1035  UnlockContext(Context);
1036  return AL_NO_ERROR;
1037 
1038  case AL_SOURCE_STATE:
1039  *values = Source->state;
1040  return AL_NO_ERROR;
1041 
1042  case AL_BUFFERS_QUEUED:
1043  *values = Source->BuffersInQueue;
1044  return AL_NO_ERROR;
1045 
1046  case AL_BUFFERS_PROCESSED:
1047  LockContext(Context);
1048  if(Source->Looping || Source->SourceType != AL_STREAMING)
1049  {
1050  /* Buffers on a looping source are in a perpetual state of
1051  * PENDING, so don't report any as PROCESSED */
1052  *values = 0;
1053  }
1054  else
1055  *values = Source->BuffersPlayed;
1056  UnlockContext(Context);
1057  return AL_NO_ERROR;
1058 
1059  case AL_SOURCE_TYPE:
1060  *values = Source->SourceType;
1061  return AL_NO_ERROR;
1062 
1064  *values = Source->DryGainHFAuto;
1065  return AL_NO_ERROR;
1066 
1068  *values = Source->WetGainAuto;
1069  return AL_NO_ERROR;
1070 
1072  *values = Source->WetGainHFAuto;
1073  return AL_NO_ERROR;
1074 
1076  *values = Source->DirectChannels;
1077  return AL_NO_ERROR;
1078 
1079  case AL_DISTANCE_MODEL:
1080  *values = Source->DistanceModel;
1081  return AL_NO_ERROR;
1082 
1083  case AL_MAX_DISTANCE:
1084  case AL_ROLLOFF_FACTOR:
1085  case AL_REFERENCE_DISTANCE:
1086  case AL_CONE_INNER_ANGLE:
1087  case AL_CONE_OUTER_ANGLE:
1088  case AL_SEC_OFFSET:
1089  case AL_SAMPLE_OFFSET:
1090  case AL_BYTE_OFFSET:
1091  case AL_DOPPLER_FACTOR:
1092  if((err=GetSourcedv(Source, Context, (int)prop, dvals)) == AL_NO_ERROR)
1093  *values = (ALint)dvals[0];
1094  return err;
1095 
1098  if((err=GetSourcedv(Source, Context, (int)prop, dvals)) == AL_NO_ERROR)
1099  {
1100  values[0] = (ALint)dvals[0];
1101  values[1] = (ALint)dvals[1];
1102  }
1103  return err;
1104 
1105  case AL_POSITION:
1106  case AL_VELOCITY:
1107  case AL_DIRECTION:
1108  if((err=GetSourcedv(Source, Context, (int)prop, dvals)) == AL_NO_ERROR)
1109  {
1110  values[0] = (ALint)dvals[0];
1111  values[1] = (ALint)dvals[1];
1112  values[2] = (ALint)dvals[2];
1113  }
1114  return err;
1115 
1117  /* i64 only */
1118  break;
1119 
1120  case siDirectFilter:
1121  case siAuxSendFilter:
1122  /* ??? */
1123  break;
1124  }
1125 
1126  ERR("Unexpected property: 0x%04x\n", prop);
1128 }
1129 
1130 static ALenum GetSourcei64v(const ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint64 *values)
1131 {
1132  ALdouble dvals[3];
1133  ALint ivals[3];
1134  ALenum err;
1135 
1136  switch(prop)
1137  {
1139  LockContext(Context);
1140  values[0] = GetSourceOffset(Source);
1141  values[1] = ALCdevice_GetLatency(Context->Device);
1142  UnlockContext(Context);
1143  return AL_NO_ERROR;
1144 
1145  case AL_MAX_DISTANCE:
1146  case AL_ROLLOFF_FACTOR:
1147  case AL_REFERENCE_DISTANCE:
1148  case AL_CONE_INNER_ANGLE:
1149  case AL_CONE_OUTER_ANGLE:
1150  case AL_SEC_OFFSET:
1151  case AL_SAMPLE_OFFSET:
1152  case AL_BYTE_OFFSET:
1153  case AL_DOPPLER_FACTOR:
1154  if((err=GetSourcedv(Source, Context, (int)prop, dvals)) == AL_NO_ERROR)
1155  *values = (ALint64)dvals[0];
1156  return err;
1157 
1160  if((err=GetSourcedv(Source, Context, (int)prop, dvals)) == AL_NO_ERROR)
1161  {
1162  values[0] = (ALint64)dvals[0];
1163  values[1] = (ALint64)dvals[1];
1164  }
1165  return err;
1166 
1167  case AL_POSITION:
1168  case AL_VELOCITY:
1169  case AL_DIRECTION:
1170  if((err=GetSourcedv(Source, Context, (int)prop, dvals)) == AL_NO_ERROR)
1171  {
1172  values[0] = (ALint64)dvals[0];
1173  values[1] = (ALint64)dvals[1];
1174  values[2] = (ALint64)dvals[2];
1175  }
1176  return err;
1177 
1178  case AL_SOURCE_RELATIVE:
1179  case AL_LOOPING:
1180  case AL_SOURCE_STATE:
1181  case AL_BUFFERS_QUEUED:
1182  case AL_BUFFERS_PROCESSED:
1183  case AL_SOURCE_TYPE:
1188  case AL_DISTANCE_MODEL:
1189  if((err=GetSourceiv(Source, Context, (int)prop, ivals)) == AL_NO_ERROR)
1190  *values = ivals[0];
1191  return err;
1192 
1193  case siBuffer:
1194  case siDirectFilter:
1195  if((err=GetSourceiv(Source, Context, (int)prop, ivals)) == AL_NO_ERROR)
1196  *values = ((ALuint*)ivals)[0];
1197  return err;
1198 
1199  case siAuxSendFilter:
1200  if((err=GetSourceiv(Source, Context, (int)prop, ivals)) == AL_NO_ERROR)
1201  {
1202  values[0] = ((ALuint*)ivals)[0];
1203  values[1] = ((ALuint*)ivals)[1];
1204  values[2] = ((ALuint*)ivals)[2];
1205  }
1206  return err;
1207  }
1208 
1209  ERR("Unexpected property: 0x%04x\n", prop);
1211 }
1212 
1213 #undef RETERR
1214 
1215 
1217 {
1218  ALCcontext *Context;
1219  ALsizei cur = 0;
1220 
1221  Context = GetContextRef();
1222  if(!Context) return;
1223 
1224  al_try
1225  {
1226  ALenum err;
1227 
1228  CHECK_VALUE(Context, n >= 0);
1229  for(cur = 0;cur < n;cur++)
1230  {
1231  ALsource *source = al_calloc(16, sizeof(ALsource));
1232  if(!source)
1233  al_throwerr(Context, AL_OUT_OF_MEMORY);
1234  InitSourceParams(source);
1235 
1236  err = NewThunkEntry(&source->id);
1237  if(err == AL_NO_ERROR)
1238  err = InsertUIntMapEntry(&Context->SourceMap, source->id, source);
1239  if(err != AL_NO_ERROR)
1240  {
1241  FreeThunkEntry(source->id);
1242  memset(source, 0, sizeof(ALsource));
1243  al_free(source);
1244 
1245  al_throwerr(Context, err);
1246  }
1247 
1248  sources[cur] = source->id;
1249  }
1250  }
1251  al_catchany()
1252  {
1253  if(cur > 0)
1254  alDeleteSources(cur, sources);
1255  }
1256  al_endtry;
1257 
1258  ALCcontext_DecRef(Context);
1259 }
1260 
1261 
1263 {
1264  ALCcontext *Context;
1265 
1266  Context = GetContextRef();
1267  if(!Context) return;
1268 
1269  al_try
1270  {
1271  ALbufferlistitem *BufferList;
1272  ALsource *Source;
1273  ALsizei i, j;
1274 
1275  CHECK_VALUE(Context, n >= 0);
1276 
1277  /* Check that all Sources are valid */
1278  for(i = 0;i < n;i++)
1279  {
1280  if(LookupSource(Context, sources[i]) == NULL)
1281  al_throwerr(Context, AL_INVALID_NAME);
1282  }
1283 
1284  for(i = 0;i < n;i++)
1285  {
1286  ALsource **srclist, **srclistend;
1287 
1288  if((Source=RemoveSource(Context, sources[i])) == NULL)
1289  continue;
1290  FreeThunkEntry(Source->id);
1291 
1292  LockContext(Context);
1293  srclist = Context->ActiveSources;
1294  srclistend = srclist + Context->ActiveSourceCount;
1295  while(srclist != srclistend)
1296  {
1297  if(*srclist == Source)
1298  {
1299  Context->ActiveSourceCount--;
1300  *srclist = *(--srclistend);
1301  break;
1302  }
1303  srclist++;
1304  }
1305  UnlockContext(Context);
1306 
1307  while(Source->queue != NULL)
1308  {
1309  BufferList = Source->queue;
1310  Source->queue = BufferList->next;
1311 
1312  if(BufferList->buffer != NULL)
1313  DecrementRef(&BufferList->buffer->ref);
1314  free(BufferList);
1315  }
1316 
1317  for(j = 0;j < MAX_SENDS;++j)
1318  {
1319  if(Source->Send[j].Slot)
1320  DecrementRef(&Source->Send[j].Slot->ref);
1321  Source->Send[j].Slot = NULL;
1322  }
1323 
1324  memset(Source, 0, sizeof(*Source));
1325  al_free(Source);
1326  }
1327  }
1328  al_endtry;
1329 
1330  ALCcontext_DecRef(Context);
1331 }
1332 
1333 
1335 {
1336  ALCcontext *Context;
1337  ALboolean result;
1338 
1339  Context = GetContextRef();
1340  if(!Context) return AL_FALSE;
1341 
1342  result = (LookupSource(Context, source) ? AL_TRUE : AL_FALSE);
1343 
1344  ALCcontext_DecRef(Context);
1345 
1346  return result;
1347 }
1348 
1349 
1351 {
1352  ALCcontext *Context;
1353  ALsource *Source;
1354 
1355  Context = GetContextRef();
1356  if(!Context) return;
1357 
1358  if((Source=LookupSource(Context, source)) == NULL)
1359  alSetError(Context, AL_INVALID_NAME);
1360  else if(!(FloatValsByProp(param) == 1))
1361  alSetError(Context, AL_INVALID_ENUM);
1362  else
1363  SetSourcefv(Source, Context, param, &value);
1364 
1365  ALCcontext_DecRef(Context);
1366 }
1367 
1369 {
1370  ALCcontext *Context;
1371  ALsource *Source;
1372 
1373  Context = GetContextRef();
1374  if(!Context) return;
1375 
1376  if((Source=LookupSource(Context, source)) == NULL)
1377  alSetError(Context, AL_INVALID_NAME);
1378  else if(!(FloatValsByProp(param) == 3))
1379  alSetError(Context, AL_INVALID_ENUM);
1380  else
1381  {
1382  ALfloat fvals[3] = { value1, value2, value3 };
1383  SetSourcefv(Source, Context, param, fvals);
1384  }
1385 
1386  ALCcontext_DecRef(Context);
1387 }
1388 
1390 {
1391  ALCcontext *Context;
1392  ALsource *Source;
1393 
1394  Context = GetContextRef();
1395  if(!Context) return;
1396 
1397  if((Source=LookupSource(Context, source)) == NULL)
1398  alSetError(Context, AL_INVALID_NAME);
1399  else if(!values)
1400  alSetError(Context, AL_INVALID_VALUE);
1401  else if(!(FloatValsByProp(param) > 0))
1402  alSetError(Context, AL_INVALID_ENUM);
1403  else
1404  SetSourcefv(Source, Context, param, values);
1405 
1406  ALCcontext_DecRef(Context);
1407 }
1408 
1409 
1411 {
1412  ALCcontext *Context;
1413  ALsource *Source;
1414 
1415  Context = GetContextRef();
1416  if(!Context) return;
1417 
1418  if((Source=LookupSource(Context, source)) == NULL)
1419  alSetError(Context, AL_INVALID_NAME);
1420  else if(!(DoubleValsByProp(param) == 1))
1421  alSetError(Context, AL_INVALID_ENUM);
1422  else
1423  {
1424  ALfloat fval = (ALfloat)value;
1425  SetSourcefv(Source, Context, param, &fval);
1426  }
1427 
1428  ALCcontext_DecRef(Context);
1429 }
1430 
1432 {
1433  ALCcontext *Context;
1434  ALsource *Source;
1435 
1436  Context = GetContextRef();
1437  if(!Context) return;
1438 
1439  if((Source=LookupSource(Context, source)) == NULL)
1440  alSetError(Context, AL_INVALID_NAME);
1441  else if(!(DoubleValsByProp(param) == 3))
1442  alSetError(Context, AL_INVALID_ENUM);
1443  else
1444  {
1445  ALfloat fvals[3] = { (ALfloat)value1, (ALfloat)value2, (ALfloat)value3 };
1446  SetSourcefv(Source, Context, param, fvals);
1447  }
1448 
1449  ALCcontext_DecRef(Context);
1450 }
1451 
1453 {
1454  ALCcontext *Context;
1455  ALsource *Source;
1456  ALint count;
1457 
1458  Context = GetContextRef();
1459  if(!Context) return;
1460 
1461  if((Source=LookupSource(Context, source)) == NULL)
1462  alSetError(Context, AL_INVALID_NAME);
1463  else if(!values)
1464  alSetError(Context, AL_INVALID_VALUE);
1465  else if(!((count=DoubleValsByProp(param)) > 0 && count <= 3))
1466  alSetError(Context, AL_INVALID_ENUM);
1467  else
1468  {
1469  ALfloat fvals[3];
1470  ALint i;
1471 
1472  for(i = 0;i < count;i++)
1473  fvals[i] = (ALfloat)values[i];
1474  SetSourcefv(Source, Context, param, fvals);
1475  }
1476 
1477  ALCcontext_DecRef(Context);
1478 }
1479 
1480 
1482 {
1483  ALCcontext *Context;
1484  ALsource *Source;
1485 
1486  Context = GetContextRef();
1487  if(!Context) return;
1488 
1489  if((Source=LookupSource(Context, source)) == NULL)
1490  alSetError(Context, AL_INVALID_NAME);
1491  else if(!(IntValsByProp(param) == 1))
1492  alSetError(Context, AL_INVALID_ENUM);
1493  else
1494  SetSourceiv(Source, Context, param, &value);
1495 
1496  ALCcontext_DecRef(Context);
1497 }
1498 
1499 AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, ALint value2, ALint value3)
1500 {
1501  ALCcontext *Context;
1502  ALsource *Source;
1503 
1504  Context = GetContextRef();
1505  if(!Context) return;
1506 
1507  if((Source=LookupSource(Context, source)) == NULL)
1508  alSetError(Context, AL_INVALID_NAME);
1509  else if(!(IntValsByProp(param) == 3))
1510  alSetError(Context, AL_INVALID_ENUM);
1511  else
1512  {
1513  ALint ivals[3] = { value1, value2, value3 };
1514  SetSourceiv(Source, Context, param, ivals);
1515  }
1516 
1517  ALCcontext_DecRef(Context);
1518 }
1519 
1521 {
1522  ALCcontext *Context;
1523  ALsource *Source;
1524 
1525  Context = GetContextRef();
1526  if(!Context) return;
1527 
1528  if((Source=LookupSource(Context, source)) == NULL)
1529  alSetError(Context, AL_INVALID_NAME);
1530  else if(!values)
1531  alSetError(Context, AL_INVALID_VALUE);
1532  else if(!(IntValsByProp(param) > 0))
1533  alSetError(Context, AL_INVALID_ENUM);
1534  else
1535  SetSourceiv(Source, Context, param, values);
1536 
1537  ALCcontext_DecRef(Context);
1538 }
1539 
1540 
1542 {
1543  ALCcontext *Context;
1544  ALsource *Source;
1545 
1546  Context = GetContextRef();
1547  if(!Context) return;
1548 
1549  if((Source=LookupSource(Context, source)) == NULL)
1550  alSetError(Context, AL_INVALID_NAME);
1551  else if(!(Int64ValsByProp(param) == 1))
1552  alSetError(Context, AL_INVALID_ENUM);
1553  else
1554  SetSourcei64v(Source, Context, param, &value);
1555 
1556  ALCcontext_DecRef(Context);
1557 }
1558 
1560 {
1561  ALCcontext *Context;
1562  ALsource *Source;
1563 
1564  Context = GetContextRef();
1565  if(!Context) return;
1566 
1567  if((Source=LookupSource(Context, source)) == NULL)
1568  alSetError(Context, AL_INVALID_NAME);
1569  else if(!(Int64ValsByProp(param) == 3))
1570  alSetError(Context, AL_INVALID_ENUM);
1571  else
1572  {
1573  ALint64SOFT i64vals[3] = { value1, value2, value3 };
1574  SetSourcei64v(Source, Context, param, i64vals);
1575  }
1576 
1577  ALCcontext_DecRef(Context);
1578 }
1579 
1581 {
1582  ALCcontext *Context;
1583  ALsource *Source;
1584 
1585  Context = GetContextRef();
1586  if(!Context) return;
1587 
1588  if((Source=LookupSource(Context, source)) == NULL)
1589  alSetError(Context, AL_INVALID_NAME);
1590  else if(!values)
1591  alSetError(Context, AL_INVALID_VALUE);
1592  else if(!(Int64ValsByProp(param) > 0))
1593  alSetError(Context, AL_INVALID_ENUM);
1594  else
1595  SetSourcei64v(Source, Context, param, values);
1596 
1597  ALCcontext_DecRef(Context);
1598 }
1599 
1600 
1602 {
1603  ALCcontext *Context;
1604  ALsource *Source;
1605 
1606  Context = GetContextRef();
1607  if(!Context) return;
1608 
1609  if((Source=LookupSource(Context, source)) == NULL)
1610  alSetError(Context, AL_INVALID_NAME);
1611  else if(!value)
1612  alSetError(Context, AL_INVALID_VALUE);
1613  else if(!(FloatValsByProp(param) == 1))
1614  alSetError(Context, AL_INVALID_ENUM);
1615  else
1616  {
1617  ALdouble dval;
1618  if(GetSourcedv(Source, Context, param, &dval) == AL_NO_ERROR)
1619  *value = (ALfloat)dval;
1620  }
1621 
1622  ALCcontext_DecRef(Context);
1623 }
1624 
1625 
1626 AL_API ALvoid AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3)
1627 {
1628  ALCcontext *Context;
1629  ALsource *Source;
1630 
1631  Context = GetContextRef();
1632  if(!Context) return;
1633 
1634  if((Source=LookupSource(Context, source)) == NULL)
1635  alSetError(Context, AL_INVALID_NAME);
1636  else if(!(value1 && value2 && value3))
1637  alSetError(Context, AL_INVALID_VALUE);
1638  else if(!(FloatValsByProp(param) == 3))
1639  alSetError(Context, AL_INVALID_ENUM);
1640  else
1641  {
1642  ALdouble dvals[3];
1643  if(GetSourcedv(Source, Context, param, dvals) == AL_NO_ERROR)
1644  {
1645  *value1 = (ALfloat)dvals[0];
1646  *value2 = (ALfloat)dvals[1];
1647  *value3 = (ALfloat)dvals[2];
1648  }
1649  }
1650 
1651  ALCcontext_DecRef(Context);
1652 }
1653 
1654 
1656 {
1657  ALCcontext *Context;
1658  ALsource *Source;
1659  ALint count;
1660 
1661  Context = GetContextRef();
1662  if(!Context) return;
1663 
1664  if((Source=LookupSource(Context, source)) == NULL)
1665  alSetError(Context, AL_INVALID_NAME);
1666  else if(!values)
1667  alSetError(Context, AL_INVALID_VALUE);
1668  else if(!((count=FloatValsByProp(param)) > 0 && count <= 3))
1669  alSetError(Context, AL_INVALID_ENUM);
1670  else
1671  {
1672  ALdouble dvals[3];
1673  if(GetSourcedv(Source, Context, param, dvals) == AL_NO_ERROR)
1674  {
1675  ALint i;
1676  for(i = 0;i < count;i++)
1677  values[i] = (ALfloat)dvals[i];
1678  }
1679  }
1680 
1681  ALCcontext_DecRef(Context);
1682 }
1683 
1684 
1686 {
1687  ALCcontext *Context;
1688  ALsource *Source;
1689 
1690  Context = GetContextRef();
1691  if(!Context) return;
1692 
1693  if((Source=LookupSource(Context, source)) == NULL)
1694  alSetError(Context, AL_INVALID_NAME);
1695  else if(!value)
1696  alSetError(Context, AL_INVALID_VALUE);
1697  else if(!(DoubleValsByProp(param) == 1))
1698  alSetError(Context, AL_INVALID_ENUM);
1699  else
1700  GetSourcedv(Source, Context, param, value);
1701 
1702  ALCcontext_DecRef(Context);
1703 }
1704 
1705 AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble *value1, ALdouble *value2, ALdouble *value3)
1706 {
1707  ALCcontext *Context;
1708  ALsource *Source;
1709 
1710  Context = GetContextRef();
1711  if(!Context) return;
1712 
1713  if((Source=LookupSource(Context, source)) == NULL)
1714  alSetError(Context, AL_INVALID_NAME);
1715  else if(!(value1 && value2 && value3))
1716  alSetError(Context, AL_INVALID_VALUE);
1717  else if(!(DoubleValsByProp(param) == 3))
1718  alSetError(Context, AL_INVALID_ENUM);
1719  else
1720  {
1721  ALdouble dvals[3];
1722  if(GetSourcedv(Source, Context, param, dvals) == AL_NO_ERROR)
1723  {
1724  *value1 = dvals[0];
1725  *value2 = dvals[1];
1726  *value3 = dvals[2];
1727  }
1728  }
1729 
1730  ALCcontext_DecRef(Context);
1731 }
1732 
1734 {
1735  ALCcontext *Context;
1736  ALsource *Source;
1737 
1738  Context = GetContextRef();
1739  if(!Context) return;
1740 
1741  if((Source=LookupSource(Context, source)) == NULL)
1742  alSetError(Context, AL_INVALID_NAME);
1743  else if(!values)
1744  alSetError(Context, AL_INVALID_VALUE);
1745  else if(!(DoubleValsByProp(param) > 0))
1746  alSetError(Context, AL_INVALID_ENUM);
1747  else
1748  GetSourcedv(Source, Context, param, values);
1749 
1750  ALCcontext_DecRef(Context);
1751 }
1752 
1753 
1755 {
1756  ALCcontext *Context;
1757  ALsource *Source;
1758 
1759  Context = GetContextRef();
1760  if(!Context) return;
1761 
1762  if((Source=LookupSource(Context, source)) == NULL)
1763  alSetError(Context, AL_INVALID_NAME);
1764  else if(!value)
1765  alSetError(Context, AL_INVALID_VALUE);
1766  else if(!(IntValsByProp(param) == 1))
1767  alSetError(Context, AL_INVALID_ENUM);
1768  else
1769  GetSourceiv(Source, Context, param, value);
1770 
1771  ALCcontext_DecRef(Context);
1772 }
1773 
1774 
1775 AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1, ALint *value2, ALint *value3)
1776 {
1777  ALCcontext *Context;
1778  ALsource *Source;
1779 
1780  Context = GetContextRef();
1781  if(!Context) return;
1782 
1783  if((Source=LookupSource(Context, source)) == NULL)
1784  alSetError(Context, AL_INVALID_NAME);
1785  else if(!(value1 && value2 && value3))
1786  alSetError(Context, AL_INVALID_VALUE);
1787  else if(!(IntValsByProp(param) == 3))
1788  alSetError(Context, AL_INVALID_ENUM);
1789  else
1790  {
1791  ALint ivals[3];
1792  if(GetSourceiv(Source, Context, param, ivals) == AL_NO_ERROR)
1793  {
1794  *value1 = ivals[0];
1795  *value2 = ivals[1];
1796  *value3 = ivals[2];
1797  }
1798  }
1799 
1800  ALCcontext_DecRef(Context);
1801 }
1802 
1803 
1805 {
1806  ALCcontext *Context;
1807  ALsource *Source;
1808 
1809  Context = GetContextRef();
1810  if(!Context) return;
1811 
1812  if((Source=LookupSource(Context, source)) == NULL)
1813  alSetError(Context, AL_INVALID_NAME);
1814  else if(!values)
1815  alSetError(Context, AL_INVALID_VALUE);
1816  else if(!(IntValsByProp(param) > 0))
1817  alSetError(Context, AL_INVALID_ENUM);
1818  else
1819  GetSourceiv(Source, Context, param, values);
1820 
1821  ALCcontext_DecRef(Context);
1822 }
1823 
1824 
1826 {
1827  ALCcontext *Context;
1828  ALsource *Source;
1829 
1830  Context = GetContextRef();
1831  if(!Context) return;
1832 
1833  if((Source=LookupSource(Context, source)) == NULL)
1834  alSetError(Context, AL_INVALID_NAME);
1835  else if(!value)
1836  alSetError(Context, AL_INVALID_VALUE);
1837  else if(!(Int64ValsByProp(param) == 1))
1838  alSetError(Context, AL_INVALID_ENUM);
1839  else
1840  GetSourcei64v(Source, Context, param, value);
1841 
1842  ALCcontext_DecRef(Context);
1843 }
1844 
1846 {
1847  ALCcontext *Context;
1848  ALsource *Source;
1849 
1850  Context = GetContextRef();
1851  if(!Context) return;
1852 
1853  if((Source=LookupSource(Context, source)) == NULL)
1854  alSetError(Context, AL_INVALID_NAME);
1855  else if(!(value1 && value2 && value3))
1856  alSetError(Context, AL_INVALID_VALUE);
1857  else if(!(Int64ValsByProp(param) == 3))
1858  alSetError(Context, AL_INVALID_ENUM);
1859  else
1860  {
1861  ALint64 i64vals[3];
1862  if(GetSourcei64v(Source, Context, param, i64vals) == AL_NO_ERROR)
1863  {
1864  *value1 = i64vals[0];
1865  *value2 = i64vals[1];
1866  *value3 = i64vals[2];
1867  }
1868  }
1869 
1870  ALCcontext_DecRef(Context);
1871 }
1872 
1874 {
1875  ALCcontext *Context;
1876  ALsource *Source;
1877 
1878  Context = GetContextRef();
1879  if(!Context) return;
1880 
1881  if((Source=LookupSource(Context, source)) == NULL)
1882  alSetError(Context, AL_INVALID_NAME);
1883  else if(!values)
1884  alSetError(Context, AL_INVALID_VALUE);
1885  else if(!(Int64ValsByProp(param) > 0))
1886  alSetError(Context, AL_INVALID_ENUM);
1887  else
1888  GetSourcei64v(Source, Context, param, values);
1889 
1890  ALCcontext_DecRef(Context);
1891 }
1892 
1893 
1895 {
1896  alSourcePlayv(1, &source);
1897 }
1899 {
1900  ALCcontext *Context;
1901  ALsource *Source;
1902  ALsizei i;
1903 
1904  Context = GetContextRef();
1905  if(!Context) return;
1906 
1907  al_try
1908  {
1909  CHECK_VALUE(Context, n >= 0);
1910  for(i = 0;i < n;i++)
1911  {
1912  if(!LookupSource(Context, sources[i]))
1913  al_throwerr(Context, AL_INVALID_NAME);
1914  }
1915 
1916  LockContext(Context);
1917  while(Context->MaxActiveSources-Context->ActiveSourceCount < n)
1918  {
1919  void *temp = NULL;
1920  ALsizei newcount;
1921 
1922  newcount = Context->MaxActiveSources << 1;
1923  if(newcount > 0)
1924  temp = realloc(Context->ActiveSources,
1925  sizeof(*Context->ActiveSources) * newcount);
1926  if(!temp)
1927  {
1928  UnlockContext(Context);
1929  al_throwerr(Context, AL_OUT_OF_MEMORY);
1930  }
1931 
1932  Context->ActiveSources = temp;
1933  Context->MaxActiveSources = newcount;
1934  }
1935 
1936  for(i = 0;i < n;i++)
1937  {
1938  Source = LookupSource(Context, sources[i]);
1939  if(Context->DeferUpdates) Source->new_state = AL_PLAYING;
1940  else SetSourceState(Source, Context, AL_PLAYING);
1941  }
1942  UnlockContext(Context);
1943  }
1944  al_endtry;
1945 
1946  ALCcontext_DecRef(Context);
1947 }
1948 
1950 {
1951  alSourcePausev(1, &source);
1952 }
1954 {
1955  ALCcontext *Context;
1956  ALsource *Source;
1957  ALsizei i;
1958 
1959  Context = GetContextRef();
1960  if(!Context) return;
1961 
1962  al_try
1963  {
1964  CHECK_VALUE(Context, n >= 0);
1965  for(i = 0;i < n;i++)
1966  {
1967  if(!LookupSource(Context, sources[i]))
1968  al_throwerr(Context, AL_INVALID_NAME);
1969  }
1970 
1971  LockContext(Context);
1972  for(i = 0;i < n;i++)
1973  {
1974  Source = LookupSource(Context, sources[i]);
1975  if(Context->DeferUpdates) Source->new_state = AL_PAUSED;
1976  else SetSourceState(Source, Context, AL_PAUSED);
1977  }
1978  UnlockContext(Context);
1979  }
1980  al_endtry;
1981 
1982  ALCcontext_DecRef(Context);
1983 }
1984 
1986 {
1987  alSourceStopv(1, &source);
1988 }
1990 {
1991  ALCcontext *Context;
1992  ALsource *Source;
1993  ALsizei i;
1994 
1995  Context = GetContextRef();
1996  if(!Context) return;
1997 
1998  al_try
1999  {
2000  CHECK_VALUE(Context, n >= 0);
2001  for(i = 0;i < n;i++)
2002  {
2003  if(!LookupSource(Context, sources[i]))
2004  al_throwerr(Context, AL_INVALID_NAME);
2005  }
2006 
2007  LockContext(Context);
2008  for(i = 0;i < n;i++)
2009  {
2010  Source = LookupSource(Context, sources[i]);
2011  Source->new_state = AL_NONE;
2012  SetSourceState(Source, Context, AL_STOPPED);
2013  }
2014  UnlockContext(Context);
2015  }
2016  al_endtry;
2017 
2018  ALCcontext_DecRef(Context);
2019 }
2020 
2022 {
2023  alSourceRewindv(1, &source);
2024 }
2026 {
2027  ALCcontext *Context;
2028  ALsource *Source;
2029  ALsizei i;
2030 
2031  Context = GetContextRef();
2032  if(!Context) return;
2033 
2034  al_try
2035  {
2036  CHECK_VALUE(Context, n >= 0);
2037  for(i = 0;i < n;i++)
2038  {
2039  if(!LookupSource(Context, sources[i]))
2040  al_throwerr(Context, AL_INVALID_NAME);
2041  }
2042 
2043  LockContext(Context);
2044  for(i = 0;i < n;i++)
2045  {
2046  Source = LookupSource(Context, sources[i]);
2047  Source->new_state = AL_NONE;
2048  SetSourceState(Source, Context, AL_INITIAL);
2049  }
2050  UnlockContext(Context);
2051  }
2052  al_endtry;
2053 
2054  ALCcontext_DecRef(Context);
2055 }
2056 
2057 
2059 {
2060  ALCcontext *Context;
2061  ALsource *Source;
2062  ALsizei i;
2063  ALbufferlistitem *BufferListStart = NULL;
2064  ALbufferlistitem *BufferList;
2065  ALbuffer *BufferFmt;
2066 
2067  if(nb == 0)
2068  return;
2069 
2070  Context = GetContextRef();
2071  if(!Context) return;
2072 
2073  al_try
2074  {
2075  ALCdevice *device = Context->Device;
2076 
2077  CHECK_VALUE(Context, nb >= 0);
2078 
2079  if((Source=LookupSource(Context, source)) == NULL)
2080  al_throwerr(Context, AL_INVALID_NAME);
2081 
2082  LockContext(Context);
2083  if(Source->SourceType == AL_STATIC)
2084  {
2085  UnlockContext(Context);
2086  /* Can't queue on a Static Source */
2088  }
2089 
2090  BufferFmt = NULL;
2091 
2092  /* Check for a valid Buffer, for its frequency and format */
2093  BufferList = Source->queue;
2094  while(BufferList)
2095  {
2096  if(BufferList->buffer)
2097  {
2098  BufferFmt = BufferList->buffer;
2099  break;
2100  }
2101  BufferList = BufferList->next;
2102  }
2103 
2104  for(i = 0;i < nb;i++)
2105  {
2106  ALbuffer *buffer = NULL;
2107  if(buffers[i] && (buffer=LookupBuffer(device, buffers[i])) == NULL)
2108  {
2109  UnlockContext(Context);
2110  al_throwerr(Context, AL_INVALID_NAME);
2111  }
2112 
2113  if(!BufferListStart)
2114  {
2115  BufferListStart = malloc(sizeof(ALbufferlistitem));
2116  BufferListStart->buffer = buffer;
2117  BufferListStart->next = NULL;
2118  BufferListStart->prev = NULL;
2119  BufferList = BufferListStart;
2120  }
2121  else
2122  {
2123  BufferList->next = malloc(sizeof(ALbufferlistitem));
2124  BufferList->next->buffer = buffer;
2125  BufferList->next->next = NULL;
2126  BufferList->next->prev = BufferList;
2127  BufferList = BufferList->next;
2128  }
2129  if(!buffer) continue;
2130  IncrementRef(&buffer->ref);
2131 
2132  ReadLock(&buffer->lock);
2133  if(BufferFmt == NULL)
2134  {
2135  BufferFmt = buffer;
2136 
2137  Source->NumChannels = ChannelsFromFmt(buffer->FmtChannels);
2138  Source->SampleSize = BytesFromFmt(buffer->FmtType);
2139  if(buffer->FmtChannels == FmtMono)
2140  Source->Update = CalcSourceParams;
2141  else
2142  Source->Update = CalcNonAttnSourceParams;
2143 
2144  Source->NeedsUpdate = AL_TRUE;
2145  }
2146  else if(BufferFmt->Frequency != buffer->Frequency ||
2147  BufferFmt->OriginalChannels != buffer->OriginalChannels ||
2148  BufferFmt->OriginalType != buffer->OriginalType)
2149  {
2150  ReadUnlock(&buffer->lock);
2151  UnlockContext(Context);
2153  }
2154  ReadUnlock(&buffer->lock);
2155  }
2156 
2157  /* Source is now streaming */
2158  Source->SourceType = AL_STREAMING;
2159 
2160  if(Source->queue == NULL)
2161  Source->queue = BufferListStart;
2162  else
2163  {
2164  /* Append to the end of the queue */
2165  BufferList = Source->queue;
2166  while(BufferList->next != NULL)
2167  BufferList = BufferList->next;
2168 
2169  BufferListStart->prev = BufferList;
2170  BufferList->next = BufferListStart;
2171  }
2172 
2173  Source->BuffersInQueue += nb;
2174 
2175  UnlockContext(Context);
2176  }
2177  al_catchany()
2178  {
2179  while(BufferListStart)
2180  {
2181  BufferList = BufferListStart;
2182  BufferListStart = BufferList->next;
2183 
2184  if(BufferList->buffer)
2185  DecrementRef(&BufferList->buffer->ref);
2186  free(BufferList);
2187  }
2188  }
2189  al_endtry;
2190 
2191  ALCcontext_DecRef(Context);
2192 }
2193 
2195 {
2196  ALCcontext *Context;
2197  ALsource *Source;
2198  ALsizei i;
2199  ALbufferlistitem *BufferList;
2200 
2201  if(nb == 0)
2202  return;
2203 
2204  Context = GetContextRef();
2205  if(!Context) return;
2206 
2207  al_try
2208  {
2209  CHECK_VALUE(Context, nb >= 0);
2210 
2211  if((Source=LookupSource(Context, source)) == NULL)
2212  al_throwerr(Context, AL_INVALID_NAME);
2213 
2214  LockContext(Context);
2215  if(Source->Looping || Source->SourceType != AL_STREAMING ||
2216  (ALuint)nb > Source->BuffersPlayed)
2217  {
2218  UnlockContext(Context);
2219  /* Trying to unqueue pending buffers, or a buffer that wasn't queued. */
2220  al_throwerr(Context, AL_INVALID_VALUE);
2221  }
2222 
2223  for(i = 0;i < nb;i++)
2224  {
2225  BufferList = Source->queue;
2226  Source->queue = BufferList->next;
2227  Source->BuffersInQueue--;
2228  Source->BuffersPlayed--;
2229 
2230  if(BufferList->buffer)
2231  {
2232  buffers[i] = BufferList->buffer->id;
2233  DecrementRef(&BufferList->buffer->ref);
2234  }
2235  else
2236  buffers[i] = 0;
2237 
2238  free(BufferList);
2239  }
2240  if(Source->queue)
2241  Source->queue->prev = NULL;
2242  UnlockContext(Context);
2243  }
2244  al_endtry;
2245 
2246  ALCcontext_DecRef(Context);
2247 }
2248 
2249 
2251 {
2252  ALuint i;
2253 
2254  Source->InnerAngle = 360.0f;
2255  Source->OuterAngle = 360.0f;
2256  Source->Pitch = 1.0f;
2257  Source->Position[0] = 0.0f;
2258  Source->Position[1] = 0.0f;
2259  Source->Position[2] = 0.0f;
2260  Source->Orientation[0] = 0.0f;
2261  Source->Orientation[1] = 0.0f;
2262  Source->Orientation[2] = 0.0f;
2263  Source->Velocity[0] = 0.0f;
2264  Source->Velocity[1] = 0.0f;
2265  Source->Velocity[2] = 0.0f;
2266  Source->RefDistance = 1.0f;
2267  Source->MaxDistance = FLT_MAX;
2268  Source->RollOffFactor = 1.0f;
2269  Source->Looping = AL_FALSE;
2270  Source->Gain = 1.0f;
2271  Source->MinGain = 0.0f;
2272  Source->MaxGain = 1.0f;
2273  Source->OuterGain = 0.0f;
2274  Source->OuterGainHF = 1.0f;
2275 
2276  Source->DryGainHFAuto = AL_TRUE;
2277  Source->WetGainAuto = AL_TRUE;
2278  Source->WetGainHFAuto = AL_TRUE;
2279  Source->AirAbsorptionFactor = 0.0f;
2280  Source->RoomRolloffFactor = 0.0f;
2281  Source->DopplerFactor = 1.0f;
2282  Source->DirectChannels = AL_FALSE;
2283 
2285 
2286  Source->Resampler = DefaultResampler;
2287 
2288  Source->state = AL_INITIAL;
2289  Source->new_state = AL_NONE;
2290  Source->SourceType = AL_UNDETERMINED;
2291  Source->Offset = -1.0;
2292 
2293  Source->DirectGain = 1.0f;
2294  Source->DirectGainHF = 1.0f;
2295  for(i = 0;i < MAX_SENDS;i++)
2296  {
2297  Source->Send[i].Gain = 1.0f;
2298  Source->Send[i].GainHF = 1.0f;
2299  }
2300 
2301  Source->NeedsUpdate = AL_TRUE;
2302 
2303  Source->Hrtf.Moving = AL_FALSE;
2304  Source->Hrtf.Counter = 0;
2305 }
2306 
2307 
2308 /* SetSourceState
2309  *
2310  * Sets the source's new play state given its current state.
2311  */
2313 {
2314  if(state == AL_PLAYING)
2315  {
2316  ALbufferlistitem *BufferList;
2317  ALsizei j, k;
2318 
2319  /* Check that there is a queue containing at least one valid, non zero
2320  * length Buffer. */
2321  BufferList = Source->queue;
2322  while(BufferList)
2323  {
2324  if(BufferList->buffer != NULL && BufferList->buffer->SampleLen)
2325  break;
2326  BufferList = BufferList->next;
2327  }
2328 
2329  if(Source->state != AL_PLAYING)
2330  {
2331  for(j = 0;j < MaxChannels;j++)
2332  {
2333  for(k = 0;k < SRC_HISTORY_LENGTH;k++)
2334  Source->Hrtf.History[j][k] = 0.0f;
2335  for(k = 0;k < HRIR_LENGTH;k++)
2336  {
2337  Source->Hrtf.Values[j][k][0] = 0.0f;
2338  Source->Hrtf.Values[j][k][1] = 0.0f;
2339  }
2340  }
2341  }
2342 
2343  if(Source->state != AL_PAUSED)
2344  {
2345  Source->state = AL_PLAYING;
2346  Source->position = 0;
2347  Source->position_fraction = 0;
2348  Source->BuffersPlayed = 0;
2349  }
2350  else
2351  Source->state = AL_PLAYING;
2352 
2353  // Check if an Offset has been set
2354  if(Source->Offset >= 0.0)
2355  ApplyOffset(Source);
2356 
2357  /* If there's nothing to play, or device is disconnected, go right to
2358  * stopped */
2359  if(!BufferList || !Context->Device->Connected)
2360  {
2361  SetSourceState(Source, Context, AL_STOPPED);
2362  return;
2363  }
2364 
2365  for(j = 0;j < Context->ActiveSourceCount;j++)
2366  {
2367  if(Context->ActiveSources[j] == Source)
2368  break;
2369  }
2370  if(j == Context->ActiveSourceCount)
2371  Context->ActiveSources[Context->ActiveSourceCount++] = Source;
2372  }
2373  else if(state == AL_PAUSED)
2374  {
2375  if(Source->state == AL_PLAYING)
2376  {
2377  Source->state = AL_PAUSED;
2378  Source->Hrtf.Moving = AL_FALSE;
2379  Source->Hrtf.Counter = 0;
2380  }
2381  }
2382  else if(state == AL_STOPPED)
2383  {
2384  if(Source->state != AL_INITIAL)
2385  {
2386  Source->state = AL_STOPPED;
2387  Source->BuffersPlayed = Source->BuffersInQueue;
2388  Source->Hrtf.Moving = AL_FALSE;
2389  Source->Hrtf.Counter = 0;
2390  }
2391  Source->Offset = -1.0;
2392  }
2393  else if(state == AL_INITIAL)
2394  {
2395  if(Source->state != AL_INITIAL)
2396  {
2397  Source->state = AL_INITIAL;
2398  Source->position = 0;
2399  Source->position_fraction = 0;
2400  Source->BuffersPlayed = 0;
2401  Source->Hrtf.Moving = AL_FALSE;
2402  Source->Hrtf.Counter = 0;
2403  }
2404  Source->Offset = -1.0;
2405  }
2406 }
2407 
2408 /* GetSourceOffset
2409  *
2410  * Gets the current read offset for the given Source, in 32.32 fixed-point
2411  * samples. The offset is relative to the start of the queue (not the start of
2412  * the current buffer).
2413  */
2414 static ALint64 GetSourceOffset(const ALsource *Source)
2415 {
2416  const ALbufferlistitem *BufferList;
2417  ALuint64 readPos;
2418  ALuint i;
2419 
2420  if(Source->state != AL_PLAYING && Source->state != AL_PAUSED)
2421  return 0;
2422 
2423  /* NOTE: This is the offset into the *current* buffer, so add the length of
2424  * any played buffers */
2425  readPos = (ALuint64)Source->position << 32;
2426  readPos |= (ALuint64)Source->position_fraction << (32-FRACTIONBITS);
2427  BufferList = Source->queue;
2428  for(i = 0;i < Source->BuffersPlayed && BufferList;i++)
2429  {
2430  if(BufferList->buffer)
2431  readPos += (ALuint64)BufferList->buffer->SampleLen << 32;
2432  BufferList = BufferList->next;
2433  }
2434 
2435  return (ALint64)minu64(readPos, MAKEU64(0x7fffffff,0xffffffff));
2436 }
2437 
2438 /* GetSourceSecOffset
2439  *
2440  * Gets the current read offset for the given Source, in seconds. The offset is
2441  * relative to the start of the queue (not the start of the current buffer).
2442  */
2443 static ALdouble GetSourceSecOffset(const ALsource *Source)
2444 {
2445  const ALbufferlistitem *BufferList;
2446  const ALbuffer *Buffer = NULL;
2447  ALuint64 readPos;
2448  ALuint i;
2449 
2450  BufferList = Source->queue;
2451  while(BufferList)
2452  {
2453  if(BufferList->buffer)
2454  {
2455  Buffer = BufferList->buffer;
2456  break;
2457  }
2458  BufferList = BufferList->next;
2459  }
2460 
2461  if((Source->state != AL_PLAYING && Source->state != AL_PAUSED) || !Buffer)
2462  return 0.0;
2463 
2464  /* NOTE: This is the offset into the *current* buffer, so add the length of
2465  * any played buffers */
2466  readPos = (ALuint64)Source->position << FRACTIONBITS;
2467  readPos |= (ALuint64)Source->position_fraction;
2468  BufferList = Source->queue;
2469  for(i = 0;i < Source->BuffersPlayed && BufferList;i++)
2470  {
2471  if(BufferList->buffer)
2472  readPos += (ALuint64)BufferList->buffer->SampleLen << FRACTIONBITS;
2473  BufferList = BufferList->next;
2474  }
2475 
2476  return (ALdouble)readPos / (ALdouble)FRACTIONONE / (ALdouble)Buffer->Frequency;
2477 }
2478 
2479 /* GetSourceOffsets
2480  *
2481  * Gets the current read and write offsets for the given Source, in the
2482  * appropriate format (Bytes, Samples or Seconds). The offsets are relative to
2483  * the start of the queue (not the start of the current buffer).
2484  */
2485 static ALvoid GetSourceOffsets(const ALsource *Source, ALenum name, ALdouble *offset, ALdouble updateLen)
2486 {
2487  const ALbufferlistitem *BufferList;
2488  const ALbuffer *Buffer = NULL;
2489  ALuint readPos, writePos;
2490  ALuint totalBufferLen;
2491  ALuint i;
2492 
2493  // Find the first valid Buffer in the Queue
2494  BufferList = Source->queue;
2495  while(BufferList)
2496  {
2497  if(BufferList->buffer)
2498  {
2499  Buffer = BufferList->buffer;
2500  break;
2501  }
2502  BufferList = BufferList->next;
2503  }
2504 
2505  if((Source->state != AL_PLAYING && Source->state != AL_PAUSED) || !Buffer)
2506  {
2507  offset[0] = 0.0;
2508  offset[1] = 0.0;
2509  return;
2510  }
2511 
2512  if(updateLen > 0.0 && updateLen < 0.015)
2513  updateLen = 0.015;
2514 
2515  /* NOTE: This is the offset into the *current* buffer, so add the length of
2516  * any played buffers */
2517  readPos = Source->position;
2518  totalBufferLen = 0;
2519  BufferList = Source->queue;
2520  for(i = 0;BufferList;i++)
2521  {
2522  if(BufferList->buffer)
2523  {
2524  if(i < Source->BuffersPlayed)
2525  readPos += BufferList->buffer->SampleLen;
2526  totalBufferLen += BufferList->buffer->SampleLen;
2527  }
2528  BufferList = BufferList->next;
2529  }
2530  if(Source->state == AL_PLAYING)
2531  writePos = readPos + (ALuint)(updateLen*Buffer->Frequency);
2532  else
2533  writePos = readPos;
2534 
2535  if(Source->Looping)
2536  {
2537  readPos %= totalBufferLen;
2538  writePos %= totalBufferLen;
2539  }
2540  else
2541  {
2542  /* Wrap positions back to 0 */
2543  if(readPos >= totalBufferLen)
2544  readPos = 0;
2545  if(writePos >= totalBufferLen)
2546  writePos = 0;
2547  }
2548 
2549  switch(name)
2550  {
2551  case AL_SEC_OFFSET:
2552  offset[0] = (ALdouble)readPos / Buffer->Frequency;
2553  offset[1] = (ALdouble)writePos / Buffer->Frequency;
2554  break;
2555 
2556  case AL_SAMPLE_OFFSET:
2558  offset[0] = (ALdouble)readPos;
2559  offset[1] = (ALdouble)writePos;
2560  break;
2561 
2562  case AL_BYTE_OFFSET:
2564  if(Buffer->OriginalType == UserFmtIMA4)
2565  {
2566  ALuint BlockSize = 36 * ChannelsFromFmt(Buffer->FmtChannels);
2567  ALuint FrameBlockSize = 65;
2568 
2569  /* Round down to nearest ADPCM block */
2570  offset[0] = (ALdouble)(readPos / FrameBlockSize * BlockSize);
2571  if(Source->state != AL_PLAYING)
2572  offset[1] = offset[0];
2573  else
2574  {
2575  /* Round up to nearest ADPCM block */
2576  offset[1] = (ALdouble)((writePos+FrameBlockSize-1) /
2577  FrameBlockSize * BlockSize);
2578  }
2579  }
2580  else
2581  {
2582  ALuint FrameSize = FrameSizeFromUserFmt(Buffer->OriginalChannels, Buffer->OriginalType);
2583  offset[0] = (ALdouble)(readPos * FrameSize);
2584  offset[1] = (ALdouble)(writePos * FrameSize);
2585  }
2586  break;
2587  }
2588 }
2589 
2590 
2591 /* ApplyOffset
2592  *
2593  * Apply the stored playback offset to the Source. This function will update
2594  * the number of buffers "played" given the stored offset.
2595  */
2597 {
2598  const ALbufferlistitem *BufferList;
2599  const ALbuffer *Buffer;
2600  ALint bufferLen, totalBufferLen;
2601  ALint buffersPlayed;
2602  ALint offset;
2603 
2604  /* Get sample frame offset */
2605  offset = GetSampleOffset(Source);
2606  if(offset == -1)
2607  return AL_FALSE;
2608 
2609  buffersPlayed = 0;
2610  totalBufferLen = 0;
2611 
2612  BufferList = Source->queue;
2613  while(BufferList)
2614  {
2615  Buffer = BufferList->buffer;
2616  bufferLen = Buffer ? Buffer->SampleLen : 0;
2617 
2618  if(bufferLen <= offset-totalBufferLen)
2619  {
2620  /* Offset is past this buffer so increment to the next buffer */
2621  buffersPlayed++;
2622  }
2623  else if(totalBufferLen <= offset)
2624  {
2625  /* Offset is in this buffer */
2626  Source->BuffersPlayed = buffersPlayed;
2627 
2628  Source->position = offset - totalBufferLen;
2629  Source->position_fraction = 0;
2630  return AL_TRUE;
2631  }
2632 
2633  totalBufferLen += bufferLen;
2634 
2635  BufferList = BufferList->next;
2636  }
2637 
2638  /* Offset is out of range of the queue */
2639  return AL_FALSE;
2640 }
2641 
2642 
2643 /* GetSampleOffset
2644  *
2645  * Returns the sample offset into the Source's queue (from the Sample, Byte or
2646  * Second offset supplied by the application). This takes into account the fact
2647  * that the buffer format may have been modifed since.
2648  */
2650 {
2651  const ALbuffer *Buffer = NULL;
2652  const ALbufferlistitem *BufferList;
2653  ALint Offset = -1;
2654 
2655  /* Find the first valid Buffer in the Queue */
2656  BufferList = Source->queue;
2657  while(BufferList)
2658  {
2659  if(BufferList->buffer)
2660  {
2661  Buffer = BufferList->buffer;
2662  break;
2663  }
2664  BufferList = BufferList->next;
2665  }
2666 
2667  if(!Buffer)
2668  {
2669  Source->Offset = -1.0;
2670  return -1;
2671  }
2672 
2673  switch(Source->OffsetType)
2674  {
2675  case AL_BYTE_OFFSET:
2676  /* Determine the ByteOffset (and ensure it is block aligned) */
2677  Offset = (ALint)Source->Offset;
2678  if(Buffer->OriginalType == UserFmtIMA4)
2679  {
2680  Offset /= 36 * ChannelsFromUserFmt(Buffer->OriginalChannels);
2681  Offset *= 65;
2682  }
2683  else
2684  Offset /= FrameSizeFromUserFmt(Buffer->OriginalChannels, Buffer->OriginalType);
2685  break;
2686 
2687  case AL_SAMPLE_OFFSET:
2688  Offset = (ALint)Source->Offset;
2689  break;
2690 
2691  case AL_SEC_OFFSET:
2692  Offset = (ALint)(Source->Offset * Buffer->Frequency);
2693  break;
2694  }
2695  Source->Offset = -1.0;
2696 
2697  return Offset;
2698 }
2699 
2700 
2701 /* ReleaseALSources
2702  *
2703  * Destroys all sources in the source map.
2704  */
2706 {
2707  ALsizei pos;
2708  ALuint j;
2709  for(pos = 0;pos < Context->SourceMap.size;pos++)
2710  {
2711  ALsource *temp = Context->SourceMap.array[pos].value;
2712  Context->SourceMap.array[pos].value = NULL;
2713 
2714  while(temp->queue != NULL)
2715  {
2716  ALbufferlistitem *BufferList = temp->queue;
2717  temp->queue = BufferList->next;
2718 
2719  if(BufferList->buffer != NULL)
2720  DecrementRef(&BufferList->buffer->ref);
2721  free(BufferList);
2722  }
2723 
2724  for(j = 0;j < MAX_SENDS;++j)
2725  {
2726  if(temp->Send[j].Slot)
2727  DecrementRef(&temp->Send[j].Slot->ref);
2728  temp->Send[j].Slot = NULL;
2729  }
2730 
2731  FreeThunkEntry(temp->id);
2732  memset(temp, 0, sizeof(*temp));
2733  al_free(temp);
2734  }
2735 }
AL_API void AL_APIENTRY alSourcePlay(ALuint source)
Definition: alSource.c:1894
ALdouble Offset
Definition: alSource.h:118
#define AL_CONE_OUTER_GAINHF
Definition: efx.h:27
#define AL_APIENTRY
Definition: al.h:21
struct ALeffectslot * Slot
Definition: alSource.h:150
#define LookupFilter(m, k)
Definition: alMain.h:669
#define RemoveSource(m, k)
Definition: alMain.h:712
volatile ALboolean WetGainHFAuto
Definition: alSource.h:105
AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, ALint value2, ALint value3)
Definition: alSource.c:1499
void FreeThunkEntry(ALuint index)
Definition: alThunk.c:83
ALsizei MaxActiveSources
Definition: alMain.h:698
ALCboolean Connected
Definition: alMain.h:564
void ALvoid
Definition: al.h:74
GLenum GLint param
Definition: gl2ext.h:1491
#define AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO
Definition: efx.h:30
#define AL_INVERSE_DISTANCE_CLAMPED
Definition: al.h:446
#define AL_NONE
Definition: al.h:80
#define AL_STOPPED
Definition: al.h:241
static ALvoid InitSourceParams(ALsource *Source)
Definition: alSource.c:2250
#define CHECK_VALUE(ctx, cond)
Definition: alMain.h:875
void *volatile XchgPtr
Definition: alMain.h:119
enum FmtType FmtType
Definition: alBuffer.h:78
#define AL_BYTE_RW_OFFSETS_SOFT
Definition: alext.h:169
volatile ALenum state
Definition: alSource.h:125
#define AL_TRUE
Definition: al.h:86
enum FmtChannels FmtChannels
Definition: alBuffer.h:77
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: gl2ext.h:961
volatile ALfloat DopplerFactor
Definition: alSource.h:110
#define NULL
Definition: ftobjs.h:61
struct ALsource ** ActiveSources
Definition: alMain.h:696
GLclampf f
Definition: glew.h:3390
struct UIntMap::@59 * array
ALuint position
Definition: alSource.h:133
int32_t k
Definition: e_log.c:102
#define SRC_HISTORY_LENGTH
Definition: alSource.h:15
volatile ALfloat Pitch
Definition: alSource.h:85
RWLock lock
Definition: alBuffer.h:90
#define ALCdevice_GetLatency(a)
Definition: alMain.h:648
GLsizei GLenum * sources
Definition: glew.h:3769
#define al_throwerr(ctx, err)
Definition: alMain.h:866
GLclampd n
Definition: glew.h:7287
#define AL_INVALID_VALUE
Definition: al.h:373
ALenum OffsetType
Definition: alSource.h:119
const ALsizei ResamplerPadding[ResamplerMax]
Definition: alSource.c:38
ALuint BytesFromFmt(enum FmtType type)
Definition: alBuffer.c:2109
ALuint NumAuxSends
Definition: alMain.h:586
#define CHECKVAL(x)
Definition: alSource.c:352
ALvoid(* Update)(struct ALsource *self, const ALCcontext *context)
Definition: alSource.h:174
int ALsizei
Definition: al.h:62
void ReadLock(RWLock *lock)
Definition: helpers.c:515
SDL_EventEntry * free
Definition: SDL_events.c:80
ALuint Frequency
Definition: alMain.h:569
#define AL_MAX_DISTANCE
Definition: al.h:309
#define al_try
Definition: alMain.h:838
GLuint GLsizei const GLuint const GLintptr * offsets
Definition: glew.h:4750
AL_API void AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value)
Definition: alSource.c:1754
int ALint
Definition: al.h:56
int32_t j
Definition: e_log.c:102
UIntMap SourceMap
Definition: alMain.h:681
#define memset
Definition: SDL_malloc.c:633
#define AL_FALSE
Definition: al.h:83
enum UserFmtChannels OriginalChannels
Definition: alBuffer.h:80
#define FRACTIONONE
Definition: alu.h:50
#define AL_SOURCE_STATE
Definition: al.h:235
static ALvoid GetSourceOffsets(const ALsource *Source, ALenum name, ALdouble *offsets, ALdouble updateLen)
Definition: alSource.c:2485
LPALGETSOURCEI64SOFT alGetSourcei64SOFT
Definition: allatency.c:57
ALsizei Frequency
Definition: alBuffer.h:73
EGLImageKHR EGLint * name
Definition: eglext.h:284
volatile ALfloat Position[3]
Definition: alSource.h:95
#define AL_BYTE_OFFSET
Definition: al.h:316
static ALint DoubleValsByProp(ALenum prop)
Definition: alSource.c:207
volatile ALenum NeedsUpdate
Definition: alSource.h:171
static ALint64 GetSourceOffset(const ALsource *Source)
Definition: alSource.c:2414
#define al_endtry
Definition: alMain.h:853
volatile ALfloat OuterGainHF
Definition: alSource.h:106
LPALGETSOURCEDVSOFT alGetSourcedvSOFT
Definition: allatency.c:53
LPALGETSOURCE3DSOFT alGetSource3dSOFT
Definition: allatency.c:52
SrcFloatProp
Definition: alSource.c:56
ALCcontext * GetContextRef(void)
Definition: ALc.c:1999
AL_API void AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3)
Definition: alSource.c:1626
ALsizei ActiveSourceCount
Definition: alMain.h:697
static ALenum GetSourcedv(const ALsource *Source, ALCcontext *Context, SrcFloatProp prop, ALdouble *values)
Definition: alSource.c:867
#define HRIR_LENGTH
Definition: alMain.h:776
float ALfloat
Definition: al.h:68
#define AL_PAUSED
Definition: al.h:240
#define AL_DIRECT_FILTER_GAINHF_AUTO
Definition: efx.h:28
AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *values)
Definition: alSource.c:1520
ALsizei SampleLen
Definition: alBuffer.h:75
AL_API void AL_APIENTRY alGenSources(ALsizei n, ALuint *sources)
Definition: alSource.c:1216
#define AL_EXPONENT_DISTANCE
Definition: al.h:449
#define AL_SEC_OFFSET_LATENCY_SOFT
Definition: alext.h:320
#define AL_POSITION
Definition: al.h:144
#define LookupBuffer(m, k)
Definition: alMain.h:667
volatile ALfloat MinGain
Definition: alSource.h:88
LPALSOURCE3DSOFT alSource3dSOFT
Definition: allatency.c:49
ALvoid * value
Definition: alMain.h:310
enum Resampler DefaultResampler
Definition: alSource.c:37
const GLuint * buffers
Definition: glew.h:1669
void * al_calloc(size_t alignment, size_t size)
Definition: helpers.c:161
LPALGETSOURCEDSOFT alGetSourcedSOFT
Definition: allatency.c:51
#define AL_DIRECT_CHANNELS_SOFT
Definition: alext.h:272
volatile ALfloat RoomRolloffFactor
Definition: alSource.h:109
EGLContext EGLenum EGLClientBuffer buffer
Definition: eglext.h:87
LPALSOURCE3I64SOFT alSource3i64SOFT
Definition: allatency.c:55
#define AL_AUXILIARY_SEND_FILTER_GAIN_AUTO
Definition: efx.h:29
#define AL_EXPONENT_DISTANCE_CLAMPED
Definition: al.h:450
AL_API void AL_APIENTRY alSourceStop(ALuint source)
Definition: alSource.c:1985
volatile ALfloat AirAbsorptionFactor
Definition: alSource.h:108
volatile ALfloat Velocity[3]
Definition: alSource.h:96
double ALdouble
Definition: al.h:71
static ALint IntValsByProp(ALenum prop)
Definition: alSource.c:257
enum Resampler Resampler
Definition: alSource.h:112
ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext)
Definition: ALu.c:470
ALfloat DirectGainHF
Definition: alSource.h:147
ALuint position_fraction
Definition: alSource.h:134
GLuint64EXT * result
Definition: glew.h:12708
volatile ALfloat RefDistance
Definition: alSource.h:92
ALfloat DirectGain
Definition: alSource.h:146
#define AL_PLAYING
Definition: al.h:239
#define AL_ROLLOFF_FACTOR
Definition: al.h:286
ALfloat GainHF
Definition: alSource.h:152
volatile ALboolean HeadRelative
Definition: alSource.h:98
volatile ALfloat OuterAngle
Definition: alSource.h:91
enum UserFmtType OriginalType
Definition: alBuffer.h:81
ALuint id
Definition: alSource.h:177
volatile ALfloat MaxDistance
Definition: alSource.h:93
#define RETERR(x)
Definition: alSource.c:347
#define al_catchany()
Definition: alMain.h:851
AL_API void AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *values)
Definition: alSource.c:1655
#define AL_INVALID_NAME
Definition: al.h:367
#define AL_DISTANCE_MODEL
Definition: al.h:441
#define AL_LOOPING
Definition: al.h:173
#define AL_INVERSE_DISTANCE
Definition: al.h:445
static ALenum SetSourcefv(ALsource *Source, ALCcontext *Context, SrcFloatProp prop, const ALfloat *values)
Definition: alSource.c:357
ALuint SampleSize
Definition: alSource.h:143
GLint GLsizei count
Definition: gl2ext.h:1011
#define AL_PITCH
Definition: al.h:128
AL_API void AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources)
Definition: alSource.c:1898
void ReadUnlock(RWLock *lock)
Definition: helpers.c:525
LPALSOURCEDSOFT alSourcedSOFT
Definition: allatency.c:48
ALfloat Gain
Definition: alFilter.h:57
static __inline ALuint FrameSizeFromUserFmt(enum UserFmtChannels chans, enum UserFmtType type)
Definition: alBuffer.h:38
static ALenum SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint *values)
Definition: alSource.c:550
#define MAX_SENDS
Definition: alSource.h:4
RefCount ref
Definition: alBuffer.h:88
AL_API void AL_APIENTRY alSourceRewind(ALuint source)
Definition: alSource.c:2021
const ALsizei ResamplerPrePadding[ResamplerMax]
Definition: alSource.c:43
ALsizei size
Definition: alMain.h:312
LPALSOURCEI64VSOFT alSourcei64vSOFT
Definition: allatency.c:56
volatile ALboolean DryGainHFAuto
Definition: alSource.h:103
int64_t ALint64SOFT
Definition: alext.h:321
void al_free(void *ptr)
Definition: helpers.c:168
ALfloat GainHF
Definition: alFilter.h:58
#define AL_AIR_ABSORPTION_FACTOR
Definition: efx.h:25
ALenum new_state
Definition: alSource.h:126
volatile ALboolean SourceDistanceModel
Definition: alMain.h:689
#define realloc
Definition: SDL_malloc.c:637
int ALenum
Definition: al.h:65
AL_API void AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3)
Definition: alSource.c:1368
#define AL_BUFFERS_PROCESSED
Definition: al.h:262
volatile ALenum DeferUpdates
Definition: alMain.h:694
ALenum NewThunkEntry(ALuint *index)
Definition: alThunk.c:47
ALvoid ReleaseALSources(ALCcontext *Context)
Definition: alSource.c:2705
#define LookupEffectSlot(m, k)
Definition: alMain.h:711
#define LookupSource(m, k)
Definition: alMain.h:710
AL_API void AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *value)
Definition: alSource.c:1601
unsigned int ALuint
Definition: al.h:59
static __inline ALuint64 minu64(ALuint64 a, ALuint64 b)
Definition: alu.h:82
#define AL_BUFFER
Definition: al.h:182
volatile ALfloat OuterGain
Definition: alSource.h:87
#define AL_API
Definition: al.h:14
#define AL_SAMPLE_RW_OFFSETS_SOFT
Definition: alext.h:170
AL_API void AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value)
Definition: alSource.c:1350
LPALGETSOURCE3I64SOFT alGetSource3i64SOFT
Definition: allatency.c:58
#define AL_STATIC
Definition: al.h:334
LPALSOURCEI64SOFT alSourcei64SOFT
Definition: allatency.c:54
ALuint NumChannels
Definition: alSource.h:142
#define AL_INITIAL
Definition: al.h:238
#define AL_SOURCE_RELATIVE
Definition: al.h:97
volatile ALfloat MaxGain
Definition: alSource.h:89
static ALint GetSampleOffset(ALsource *Source)
Definition: alSource.c:2649
#define AL_LINEAR_DISTANCE_CLAMPED
Definition: al.h:448
volatile ALboolean WetGainAuto
Definition: alSource.h:104
#define AL_CONE_OUTER_ANGLE
Definition: al.h:118
struct ALbuffer * buffer
Definition: alSource.h:26
#define AL_SAMPLE_OFFSET
Definition: al.h:314
#define malloc
Definition: SDL_malloc.c:635
static ALint Int64ValsByProp(ALenum prop)
Definition: alSource.c:302
static ALenum GetSourcei64v(const ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint64 *values)
Definition: alSource.c:1130
void ALCcontext_DecRef(ALCcontext *context)
Definition: ALc.c:1949
ALboolean Moving
Definition: alSource.h:32
volatile ALboolean Looping
Definition: alSource.h:99
EGLSurface EGLint void ** value
Definition: eglext.h:301
AL_API void AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources)
Definition: alSource.c:1953
#define AL_SAMPLE_OFFSET_LATENCY_SOFT
Definition: alext.h:319
#define MAKEU64(x, y)
Definition: alMain.h:48
GLintptr offset
Definition: glew.h:1668
volatile ALboolean DirectChannels
Definition: alSource.h:101
#define FRACTIONBITS
Definition: alu.h:49
LPALSOURCEDVSOFT alSourcedvSOFT
Definition: allatency.c:50
#define ERR(...)
Definition: alMain.h:816
static ALdouble GetSourceSecOffset(const ALsource *Source)
Definition: alSource.c:2443
#define AL_DIRECTION
Definition: al.h:154
ALuint UpdateSize
Definition: alMain.h:570
#define AL_MIN_GAIN
Definition: al.h:206
#define AL_REFERENCE_DISTANCE
Definition: al.h:274
Resampler
Definition: alMain.h:472
AL_API void AL_APIENTRY alSourceQueueBuffers(ALuint source, ALsizei nb, const ALuint *buffers)
Definition: alSource.c:2058
#define AL_STREAMING
Definition: al.h:335
#define AL_CONE_OUTER_GAIN
Definition: al.h:297
struct ALbufferlistitem * next
Definition: alSource.h:27
#define AL_MAX_GAIN
Definition: al.h:216
volatile ALfloat Gain
Definition: alSource.h:86
ALuint Counter
Definition: alSource.h:33
static ALenum GetSourceiv(const ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint *values)
Definition: alSource.c:1005
#define AL_OUT_OF_MEMORY
Definition: al.h:379
char ALboolean
Definition: al.h:38
LPALGETSOURCEI64VSOFT alGetSourcei64vSOFT
Definition: allatency.c:59
#define AL_UNDETERMINED
Definition: al.h:336
ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext)
Definition: ALu.c:193
#define AL_ROOM_ROLLOFF_FACTOR
Definition: efx.h:26
volatile ALfloat RollOffFactor
Definition: alSource.h:94
#define AL_DOPPLER_FACTOR
Definition: al.h:400
ALuint BuffersInQueue
Definition: alSource.h:138
ALuint id
Definition: alBuffer.h:93
AL_API void AL_APIENTRY alSourceUnqueueBuffers(ALuint source, ALsizei nb, ALuint *buffers)
Definition: alSource.c:2194
ALCdevice * Device
Definition: alMain.h:704
static __inline void LockContext(ALCcontext *context)
Definition: alMain.h:728
AL_API void AL_APIENTRY alSourceRewindv(ALsizei n, const ALuint *sources)
Definition: alSource.c:2025
struct ALbufferlistitem * prev
Definition: alSource.h:28
static ALint FloatValsByProp(ALenum prop)
Definition: alSource.c:156
#define AL_GAIN
Definition: al.h:196
int i
Definition: pngrutil.c:1377
AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1, ALint *value2, ALint *value3)
Definition: alSource.c:1775
ALvoid alSetError(ALCcontext *Context, ALenum errorCode)
Definition: alError.c:31
AL_API void AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat *values)
Definition: alSource.c:1389
volatile ALint SourceType
Definition: alSource.h:122
#define AL_SEC_OFFSET
Definition: al.h:312
struct ALsource::@61 Send[MAX_SENDS]
ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value)
Definition: helpers.c:565
AL_API void AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value)
Definition: alSource.c:1481
static __inline void UnlockContext(ALCcontext *context)
Definition: alMain.h:730
enum DistanceModel DistanceModel
Definition: alSource.h:100
#define AL_INVALID_ENUM
Definition: al.h:370
SrcIntProp
Definition: alSource.c:106
ALuint ChannelsFromUserFmt(enum UserFmtChannels chans)
Definition: alBuffer.c:2028
GLsizei GLsizei GLchar * source
Definition: gl2ext.h:994
ALuint BuffersPlayed
Definition: alSource.h:139
volatile ALfloat InnerAngle
Definition: alSource.h:90
ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state)
Definition: alSource.c:2312
AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values)
Definition: alSource.c:1804
AL_API ALboolean AL_APIENTRY alIsSource(ALuint source)
Definition: alSource.c:1334
#define AL_BUFFERS_QUEUED
Definition: al.h:250
AL_API void AL_APIENTRY alSourcePause(ALuint source)
Definition: alSource.c:1949
ALboolean ApplyOffset(ALsource *Source)
Definition: alSource.c:2596
#define AL_NO_ERROR
Definition: al.h:364
ALuint ChannelsFromFmt(enum FmtChannels chans)
Definition: alBuffer.c:2119
volatile ALfloat Orientation[3]
Definition: alSource.h:97
#define AL_CONE_INNER_ANGLE
Definition: al.h:108
#define AL_INVALID_OPERATION
Definition: al.h:376
#define AL_DIRECT_FILTER
Definition: efx.h:23
GLint GLsizei const GLuint64 * values
Definition: glew.h:3473
#define AL_AUXILIARY_SEND_FILTER
Definition: efx.h:24
#define AL_VELOCITY
Definition: al.h:163
#define AL_LINEAR_DISTANCE
Definition: al.h:447
ALbufferlistitem * queue
Definition: alSource.h:137
#define AL_SOURCE_TYPE
Definition: al.h:331
AL_API void AL_APIENTRY alSourceStopv(ALsizei n, const ALuint *sources)
Definition: alSource.c:1989
HrtfState Hrtf
Definition: alSource.h:156
AL_API void AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources)
Definition: alSource.c:1262
static ALenum SetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint64SOFT *values)
Definition: alSource.c:787