49
49
static ALvoid InitSourceParams(ALsource *Source);
50
50
static ALvoid GetSourceOffset(ALsource *Source, ALenum eName, ALdouble *Offsets, ALdouble updateLen);
51
static ALboolean ApplyOffset(ALsource *Source);
52
static ALint GetByteOffset(ALsource *Source);
51
static ALint GetSampleOffset(ALsource *Source);
54
#define LookupSource(m, k) ((ALsource*)LookupUIntMapKey(&(m), (k)))
55
#define LookupBuffer(m, k) ((ALbuffer*)LookupUIntMapKey(&(m), (k)))
56
#define LookupFilter(m, k) ((ALfilter*)LookupUIntMapKey(&(m), (k)))
57
#define LookupEffectSlot(m, k) ((ALeffectslot*)LookupUIntMapKey(&(m), (k)))
59
54
AL_API ALvoid AL_APIENTRY alGenSources(ALsizei n,ALuint *sources)
61
56
ALCcontext *Context;
64
Context = GetContextSuspended();
58
Context = GetContextRef();
65
59
if(!Context) return;
67
Device = Context->Device;
68
61
if(n < 0 || IsBadWritePtr((void*)sources, n * sizeof(ALuint)))
69
62
alSetError(Context, AL_INVALID_VALUE);
70
else if((ALuint)n > Device->MaxNoOfSources - Context->SourceMap.size)
71
alSetError(Context, AL_INVALID_VALUE);
85
76
alDeleteSources(i, sources);
79
InitSourceParams(source);
89
source->source = (ALuint)ALTHUNK_ADDENTRY(source);
90
err = InsertUIntMapEntry(&Context->SourceMap, source->source,
81
err = NewThunkEntry(&source->source);
82
if(err == AL_NO_ERROR)
83
err = InsertUIntMapEntry(&Context->SourceMap, source->source, source);
92
84
if(err != AL_NO_ERROR)
94
ALTHUNK_REMOVEENTRY(source->source);
86
FreeThunkEntry(source->source);
95
87
memset(source, 0, sizeof(ALsource));
115
106
ALsource *Source;
117
108
ALbufferlistitem *BufferList;
118
ALboolean SourcesValid = AL_FALSE;
120
Context = GetContextSuspended();
110
Context = GetContextRef();
121
111
if(!Context) return;
124
114
alSetError(Context, AL_INVALID_VALUE);
127
SourcesValid = AL_TRUE;
128
117
// Check that all Sources are valid (and can therefore be deleted)
129
118
for(i = 0;i < n;i++)
131
if(LookupSource(Context->SourceMap, sources[i]) == NULL)
120
if(LookupSource(Context, sources[i]) == NULL)
133
122
alSetError(Context, AL_INVALID_NAME);
134
SourcesValid = AL_FALSE;
142
128
// All Sources are valid, and can be deleted
143
129
for(i = 0;i < n;i++)
145
// Recheck that the Source is valid, because there could be duplicated Source names
146
if((Source=LookupSource(Context->SourceMap, sources[i])) == NULL)
131
ALsource **srclist, **srclistend;
133
// Remove Source from list of Sources
134
if((Source=RemoveSource(Context, sources[i])) == NULL)
149
for(j = 0;j < Context->ActiveSourceCount;j++)
137
FreeThunkEntry(Source->source);
139
LockContext(Context);
140
srclist = Context->ActiveSources;
141
srclistend = srclist + Context->ActiveSourceCount;
142
while(srclist != srclistend)
151
if(Context->ActiveSources[j] == Source)
144
if(*srclist == Source)
153
ALsizei end = --(Context->ActiveSourceCount);
154
Context->ActiveSources[j] = Context->ActiveSources[end];
146
Context->ActiveSourceCount--;
147
*srclist = *(--srclistend);
152
UnlockContext(Context);
159
154
// For each buffer in the source's queue...
160
155
while(Source->queue != NULL)
163
158
Source->queue = BufferList->next;
165
160
if(BufferList->buffer != NULL)
166
BufferList->buffer->refcount--;
161
DecrementRef(&BufferList->buffer->ref);
167
162
free(BufferList);
170
165
for(j = 0;j < MAX_SENDS;++j)
172
167
if(Source->Send[j].Slot)
173
Source->Send[j].Slot->refcount--;
168
DecrementRef(&Source->Send[j].Slot->ref);
174
169
Source->Send[j].Slot = NULL;
177
// Remove Source from list of Sources
178
RemoveUIntMapKey(&Context->SourceMap, Source->source);
179
ALTHUNK_REMOVEENTRY(Source->source);
181
172
memset(Source,0,sizeof(ALsource));
186
ProcessContext(Context);
177
ALCcontext_DecRef(Context);
389
383
alSetError(pContext, AL_INVALID_NAME);
392
ProcessContext(pContext);
386
ALCcontext_DecRef(pContext);
396
390
AL_API ALvoid AL_APIENTRY alSource3f(ALuint source, ALenum eParam, ALfloat flValue1,ALfloat flValue2,ALfloat flValue3)
398
ALCcontext *pContext;
392
ALCcontext *pContext;
401
pContext = GetContextSuspended();
395
pContext = GetContextRef();
402
396
if(!pContext) return;
404
if((Source=LookupSource(pContext->SourceMap, source)) != NULL)
398
if((Source=LookupSource(pContext, source)) != NULL)
408
402
case AL_POSITION:
409
Source->vPosition[0] = flValue1;
410
Source->vPosition[1] = flValue2;
411
Source->vPosition[2] = flValue3;
412
Source->NeedsUpdate = AL_TRUE;
403
if(isfinite(flValue1) && isfinite(flValue2) && isfinite(flValue3))
405
LockContext(pContext);
406
Source->vPosition[0] = flValue1;
407
Source->vPosition[1] = flValue2;
408
Source->vPosition[2] = flValue3;
409
UnlockContext(pContext);
410
Source->NeedsUpdate = AL_TRUE;
413
alSetError(pContext, AL_INVALID_VALUE);
415
416
case AL_VELOCITY:
416
Source->vVelocity[0] = flValue1;
417
Source->vVelocity[1] = flValue2;
418
Source->vVelocity[2] = flValue3;
419
Source->NeedsUpdate = AL_TRUE;
417
if(isfinite(flValue1) && isfinite(flValue2) && isfinite(flValue3))
419
LockContext(pContext);
420
Source->vVelocity[0] = flValue1;
421
Source->vVelocity[1] = flValue2;
422
Source->vVelocity[2] = flValue3;
423
UnlockContext(pContext);
424
Source->NeedsUpdate = AL_TRUE;
427
alSetError(pContext, AL_INVALID_VALUE);
422
430
case AL_DIRECTION:
423
Source->vOrientation[0] = flValue1;
424
Source->vOrientation[1] = flValue2;
425
Source->vOrientation[2] = flValue3;
426
Source->NeedsUpdate = AL_TRUE;
431
if(isfinite(flValue1) && isfinite(flValue2) && isfinite(flValue3))
433
LockContext(pContext);
434
Source->vOrientation[0] = flValue1;
435
Source->vOrientation[1] = flValue2;
436
Source->vOrientation[2] = flValue3;
437
UnlockContext(pContext);
438
Source->NeedsUpdate = AL_TRUE;
441
alSetError(pContext, AL_INVALID_VALUE);
435
450
alSetError(pContext, AL_INVALID_NAME);
437
ProcessContext(pContext);
452
ALCcontext_DecRef(pContext);
441
456
AL_API ALvoid AL_APIENTRY alSourcefv(ALuint source, ALenum eParam, const ALfloat *pflValues)
443
ALCcontext *pContext;
445
pContext = GetContextSuspended();
458
ALCcontext *pContext;
465
case AL_CONE_INNER_ANGLE:
466
case AL_CONE_OUTER_ANGLE:
468
case AL_MAX_DISTANCE:
469
case AL_ROLLOFF_FACTOR:
470
case AL_REFERENCE_DISTANCE:
473
case AL_CONE_OUTER_GAIN:
474
case AL_CONE_OUTER_GAINHF:
476
case AL_SAMPLE_OFFSET:
478
case AL_AIR_ABSORPTION_FACTOR:
479
case AL_ROOM_ROLLOFF_FACTOR:
480
alSourcef(source, eParam, pflValues[0]);
486
alSource3f(source, eParam, pflValues[0], pflValues[1], pflValues[2]);
491
pContext = GetContextRef();
446
492
if(!pContext) return;
450
if(LookupSource(pContext->SourceMap, source) != NULL)
496
if(LookupSource(pContext, source) != NULL)
455
case AL_CONE_INNER_ANGLE:
456
case AL_CONE_OUTER_ANGLE:
458
case AL_MAX_DISTANCE:
459
case AL_ROLLOFF_FACTOR:
460
case AL_REFERENCE_DISTANCE:
463
case AL_CONE_OUTER_GAIN:
464
case AL_CONE_OUTER_GAINHF:
466
case AL_SAMPLE_OFFSET:
468
case AL_AIR_ABSORPTION_FACTOR:
469
case AL_ROOM_ROLLOFF_FACTOR:
470
alSourcef(source, eParam, pflValues[0]);
476
alSource3f(source, eParam, pflValues[0], pflValues[1], pflValues[2]);
480
501
alSetError(pContext, AL_INVALID_ENUM);
488
509
alSetError(pContext, AL_INVALID_VALUE);
490
ProcessContext(pContext);
511
ALCcontext_DecRef(pContext);
494
515
AL_API ALvoid AL_APIENTRY alSourcei(ALuint source,ALenum eParam,ALint lValue)
496
ALCcontext *pContext;
498
ALbufferlistitem *BufferListItem;
500
pContext = GetContextSuspended();
517
ALCcontext *pContext;
519
ALbufferlistitem *BufferListItem;
523
case AL_MAX_DISTANCE:
524
case AL_ROLLOFF_FACTOR:
525
case AL_CONE_INNER_ANGLE:
526
case AL_CONE_OUTER_ANGLE:
527
case AL_REFERENCE_DISTANCE:
528
alSourcef(source, eParam, (ALfloat)lValue);
532
pContext = GetContextRef();
501
533
if(!pContext) return;
503
if((Source=LookupSource(pContext->SourceMap, source)) != NULL)
535
if((Source=LookupSource(pContext, source)) != NULL)
505
537
ALCdevice *device = pContext->Device;
509
case AL_MAX_DISTANCE:
510
case AL_ROLLOFF_FACTOR:
511
case AL_CONE_INNER_ANGLE:
512
case AL_CONE_OUTER_ANGLE:
513
case AL_REFERENCE_DISTANCE:
514
alSourcef(source, eParam, (ALfloat)lValue);
517
541
case AL_SOURCE_RELATIVE:
518
542
if(lValue == AL_FALSE || lValue == AL_TRUE)
559
LockContext(pContext);
535
560
if(Source->state == AL_STOPPED || Source->state == AL_INITIAL)
562
ALbufferlistitem *oldlist;
537
563
ALbuffer *buffer = NULL;
540
(buffer=LookupBuffer(device->BufferMap, lValue)) != NULL)
565
if(lValue == 0 || (buffer=LookupBuffer(device, lValue)) != NULL)
542
// Remove all elements in the queue
543
while(Source->queue != NULL)
545
BufferListItem = Source->queue;
546
Source->queue = BufferListItem->next;
548
if(BufferListItem->buffer)
549
BufferListItem->buffer->refcount--;
550
free(BufferListItem);
552
567
Source->BuffersInQueue = 0;
568
Source->BuffersPlayed = 0;
554
570
// Add the buffer to the queue (as long as it is NOT the NULL buffer)
555
571
if(buffer != NULL)
562
578
BufferListItem->buffer = buffer;
563
579
BufferListItem->next = NULL;
564
580
BufferListItem->prev = NULL;
581
// Increment reference counter for buffer
582
IncrementRef(&buffer->ref);
566
Source->queue = BufferListItem;
584
oldlist = ExchangePtr((XchgPtr*)&Source->queue, BufferListItem);
567
585
Source->BuffersInQueue = 1;
587
ReadLock(&buffer->lock);
588
Source->NumChannels = ChannelsFromFmt(buffer->FmtChannels);
589
Source->SampleSize = BytesFromFmt(buffer->FmtType);
590
ReadUnlock(&buffer->lock);
569
591
if(buffer->FmtChannels == FmtMono)
570
592
Source->Update = CalcSourceParams;
572
594
Source->Update = CalcNonAttnSourceParams;
574
// Increment reference counter for buffer
595
Source->NeedsUpdate = AL_TRUE;
579
599
// Source is now in UNDETERMINED mode
580
600
Source->lSourceType = AL_UNDETERMINED;
582
Source->BuffersPlayed = 0;
584
// Update AL_BUFFER parameter
585
Source->Buffer = buffer;
586
Source->NeedsUpdate = AL_TRUE;
601
oldlist = ExchangePtr((XchgPtr*)&Source->queue, NULL);
604
// Delete all previous elements in the queue
605
while(oldlist != NULL)
607
BufferListItem = oldlist;
608
oldlist = BufferListItem->next;
610
if(BufferListItem->buffer)
611
DecrementRef(&BufferListItem->buffer->ref);
612
free(BufferListItem);
589
616
alSetError(pContext, AL_INVALID_VALUE);
592
619
alSetError(pContext, AL_INVALID_OPERATION);
620
UnlockContext(pContext);
595
623
case AL_SOURCE_STATE:
623
654
case AL_DIRECT_FILTER: {
624
655
ALfilter *filter = NULL;
627
(filter=LookupFilter(pContext->Device->FilterMap, lValue)) != NULL)
657
if(lValue == 0 || (filter=LookupFilter(pContext->Device, lValue)) != NULL)
659
LockContext(pContext);
631
Source->DirectFilter.type = AL_FILTER_NULL;
632
Source->DirectFilter.filter = 0;
662
Source->DirectGain = 1.0f;
663
Source->DirectGainHF = 1.0f;
635
memcpy(&Source->DirectFilter, filter, sizeof(*filter));
667
Source->DirectGain = filter->Gain;
668
Source->DirectGainHF = filter->GainHF;
670
UnlockContext(pContext);
636
671
Source->NeedsUpdate = AL_TRUE;
703
748
ALCcontext *pContext;
704
749
ALsource *Source;
706
pContext = GetContextSuspended();
756
alSource3f(source, eParam, (ALfloat)lValue1, (ALfloat)lValue2, (ALfloat)lValue3);
760
pContext = GetContextRef();
707
761
if(!pContext) return;
709
if((Source=LookupSource(pContext->SourceMap, source)) != NULL)
763
if((Source=LookupSource(pContext, source)) != NULL)
711
765
ALCdevice *device = pContext->Device;
718
alSource3f(source, eParam, (ALfloat)lValue1, (ALfloat)lValue2, (ALfloat)lValue3);
721
769
case AL_AUXILIARY_SEND_FILTER: {
722
770
ALeffectslot *ALEffectSlot = NULL;
723
771
ALfilter *ALFilter = NULL;
773
LockContext(pContext);
725
774
if((ALuint)lValue2 < device->NumAuxSends &&
727
(ALEffectSlot=LookupEffectSlot(pContext->EffectSlotMap, lValue1)) != NULL) &&
729
(ALFilter=LookupFilter(device->FilterMap, lValue3)) != NULL))
775
(lValue1 == 0 || (ALEffectSlot=LookupEffectSlot(pContext, lValue1)) != NULL) &&
776
(lValue3 == 0 || (ALFilter=LookupFilter(device, lValue3)) != NULL))
731
778
/* Release refcount on the previous slot, and add one for
732
779
* the new slot */
733
if(Source->Send[lValue2].Slot)
734
Source->Send[lValue2].Slot->refcount--;
735
Source->Send[lValue2].Slot = ALEffectSlot;
736
if(Source->Send[lValue2].Slot)
737
Source->Send[lValue2].Slot->refcount++;
780
if(ALEffectSlot) IncrementRef(&ALEffectSlot->ref);
781
ALEffectSlot = ExchangePtr((XchgPtr*)&Source->Send[lValue2].Slot, ALEffectSlot);
782
if(ALEffectSlot) DecrementRef(&ALEffectSlot->ref);
741
786
/* Disable filter */
742
Source->Send[lValue2].WetFilter.type = 0;
743
Source->Send[lValue2].WetFilter.filter = 0;
787
Source->Send[lValue2].WetGain = 1.0f;
788
Source->Send[lValue2].WetGainHF = 1.0f;
746
memcpy(&Source->Send[lValue2].WetFilter, ALFilter, sizeof(*ALFilter));
792
Source->Send[lValue2].WetGain = ALFilter->Gain;
793
Source->Send[lValue2].WetGainHF = ALFilter->GainHF;
747
795
Source->NeedsUpdate = AL_TRUE;
750
798
alSetError(pContext, AL_INVALID_VALUE);
799
UnlockContext(pContext);
754
803
alSetError(pContext, AL_INVALID_ENUM);
759
808
alSetError(pContext, AL_INVALID_NAME);
761
ProcessContext(pContext);
810
ALCcontext_DecRef(pContext);
765
814
AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum eParam, const ALint* plValues)
767
ALCcontext *pContext;
769
pContext = GetContextSuspended();
816
ALCcontext *pContext;
822
case AL_SOURCE_RELATIVE:
823
case AL_CONE_INNER_ANGLE:
824
case AL_CONE_OUTER_ANGLE:
827
case AL_SOURCE_STATE:
829
case AL_SAMPLE_OFFSET:
831
case AL_MAX_DISTANCE:
832
case AL_ROLLOFF_FACTOR:
833
case AL_REFERENCE_DISTANCE:
834
case AL_DIRECT_FILTER:
835
case AL_DIRECT_FILTER_GAINHF_AUTO:
836
case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO:
837
case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO:
838
case AL_DISTANCE_MODEL:
839
case AL_DIRECT_CHANNELS_SOFT:
840
alSourcei(source, eParam, plValues[0]);
846
case AL_AUXILIARY_SEND_FILTER:
847
alSource3i(source, eParam, plValues[0], plValues[1], plValues[2]);
852
pContext = GetContextRef();
770
853
if(!pContext) return;
774
if(LookupSource(pContext->SourceMap, source) != NULL)
857
if(LookupSource(pContext, source) != NULL)
778
case AL_SOURCE_RELATIVE:
779
case AL_CONE_INNER_ANGLE:
780
case AL_CONE_OUTER_ANGLE:
783
case AL_SOURCE_STATE:
785
case AL_SAMPLE_OFFSET:
787
case AL_MAX_DISTANCE:
788
case AL_ROLLOFF_FACTOR:
789
case AL_REFERENCE_DISTANCE:
790
case AL_DIRECT_FILTER:
791
case AL_DIRECT_FILTER_GAINHF_AUTO:
792
case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO:
793
case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO:
794
case AL_DISTANCE_MODEL:
795
alSourcei(source, eParam, plValues[0]);
801
case AL_AUXILIARY_SEND_FILTER:
802
alSource3i(source, eParam, plValues[0], plValues[1], plValues[2]);
806
862
alSetError(pContext, AL_INVALID_ENUM);
910
968
alSetError(pContext, AL_INVALID_VALUE);
912
ProcessContext(pContext);
970
ALCcontext_DecRef(pContext);
916
974
AL_API ALvoid AL_APIENTRY alGetSource3f(ALuint source, ALenum eParam, ALfloat* pflValue1, ALfloat* pflValue2, ALfloat* pflValue3)
918
ALCcontext *pContext;
976
ALCcontext *pContext;
921
pContext = GetContextSuspended();
979
pContext = GetContextRef();
922
980
if(!pContext) return;
924
982
if(pflValue1 && pflValue2 && pflValue3)
926
if((Source=LookupSource(pContext->SourceMap, source)) != NULL)
984
if((Source=LookupSource(pContext, source)) != NULL)
930
988
case AL_POSITION:
989
LockContext(pContext);
931
990
*pflValue1 = Source->vPosition[0];
932
991
*pflValue2 = Source->vPosition[1];
933
992
*pflValue3 = Source->vPosition[2];
993
UnlockContext(pContext);
936
996
case AL_VELOCITY:
997
LockContext(pContext);
937
998
*pflValue1 = Source->vVelocity[0];
938
999
*pflValue2 = Source->vVelocity[1];
939
1000
*pflValue3 = Source->vVelocity[2];
1001
UnlockContext(pContext);
942
1004
case AL_DIRECTION:
1005
LockContext(pContext);
943
1006
*pflValue1 = Source->vOrientation[0];
944
1007
*pflValue2 = Source->vOrientation[1];
945
1008
*pflValue3 = Source->vOrientation[2];
1009
UnlockContext(pContext);
967
1031
ALdouble Offsets[2];
968
1032
ALdouble updateLen;
970
pContext = GetContextSuspended();
1040
case AL_MAX_DISTANCE:
1041
case AL_ROLLOFF_FACTOR:
1042
case AL_DOPPLER_FACTOR:
1043
case AL_CONE_OUTER_GAIN:
1045
case AL_SAMPLE_OFFSET:
1046
case AL_BYTE_OFFSET:
1047
case AL_CONE_INNER_ANGLE:
1048
case AL_CONE_OUTER_ANGLE:
1049
case AL_REFERENCE_DISTANCE:
1050
case AL_CONE_OUTER_GAINHF:
1051
case AL_AIR_ABSORPTION_FACTOR:
1052
case AL_ROOM_ROLLOFF_FACTOR:
1053
alGetSourcef(source, eParam, pflValues);
1059
alGetSource3f(source, eParam, pflValues+0, pflValues+1, pflValues+2);
1063
pContext = GetContextRef();
971
1064
if(!pContext) return;
975
if((Source=LookupSource(pContext->SourceMap, source)) != NULL)
1068
if((Source=LookupSource(pContext, source)) != NULL)
983
case AL_MAX_DISTANCE:
984
case AL_ROLLOFF_FACTOR:
985
case AL_DOPPLER_FACTOR:
986
case AL_CONE_OUTER_GAIN:
988
case AL_SAMPLE_OFFSET:
990
case AL_CONE_INNER_ANGLE:
991
case AL_CONE_OUTER_ANGLE:
992
case AL_REFERENCE_DISTANCE:
993
case AL_CONE_OUTER_GAINHF:
994
case AL_AIR_ABSORPTION_FACTOR:
995
case AL_ROOM_ROLLOFF_FACTOR:
996
alGetSourcef(source, eParam, pflValues);
1002
alGetSource3f(source, eParam, pflValues+0, pflValues+1, pflValues+2);
1005
1072
case AL_SAMPLE_RW_OFFSETS_SOFT:
1006
1073
case AL_BYTE_RW_OFFSETS_SOFT:
1074
LockContext(pContext);
1007
1075
updateLen = (ALdouble)pContext->Device->UpdateSize /
1008
1076
pContext->Device->Frequency;
1009
1077
GetSourceOffset(Source, eParam, Offsets, updateLen);
1010
pflValues[0] = Offsets[0];
1011
pflValues[1] = Offsets[1];
1078
UnlockContext(pContext);
1079
pflValues[0] = (ALfloat)Offsets[0];
1080
pflValues[1] = (ALfloat)Offsets[1];
1023
1092
alSetError(pContext, AL_INVALID_VALUE);
1025
ProcessContext(pContext);
1094
ALCcontext_DecRef(pContext);
1029
1098
AL_API ALvoid AL_APIENTRY alGetSourcei(ALuint source, ALenum eParam, ALint *plValue)
1100
ALbufferlistitem *BufferList;
1031
1101
ALCcontext *pContext;
1032
1102
ALsource *Source;
1033
1103
ALdouble Offsets[2];
1034
1104
ALdouble updateLen;
1036
pContext = GetContextSuspended();
1106
pContext = GetContextRef();
1037
1107
if(!pContext) return;
1041
if((Source=LookupSource(pContext->SourceMap, source)) != NULL)
1111
if((Source=LookupSource(pContext, source)) != NULL)
1150
1237
ALCcontext *pContext;
1151
1238
ALsource *Source;
1153
pContext = GetContextSuspended();
1240
pContext = GetContextRef();
1154
1241
if(!pContext) return;
1156
1243
if(plValue1 && plValue2 && plValue3)
1158
if((Source=LookupSource(pContext->SourceMap, source)) != NULL)
1245
if((Source=LookupSource(pContext, source)) != NULL)
1162
1249
case AL_POSITION:
1250
LockContext(pContext);
1163
1251
*plValue1 = (ALint)Source->vPosition[0];
1164
1252
*plValue2 = (ALint)Source->vPosition[1];
1165
1253
*plValue3 = (ALint)Source->vPosition[2];
1254
UnlockContext(pContext);
1168
1257
case AL_VELOCITY:
1258
LockContext(pContext);
1169
1259
*plValue1 = (ALint)Source->vVelocity[0];
1170
1260
*plValue2 = (ALint)Source->vVelocity[1];
1171
1261
*plValue3 = (ALint)Source->vVelocity[2];
1262
UnlockContext(pContext);
1174
1265
case AL_DIRECTION:
1266
LockContext(pContext);
1175
1267
*plValue1 = (ALint)Source->vOrientation[0];
1176
1268
*plValue2 = (ALint)Source->vOrientation[1];
1177
1269
*plValue3 = (ALint)Source->vOrientation[2];
1270
UnlockContext(pContext);
1199
1292
ALdouble Offsets[2];
1200
1293
ALdouble updateLen;
1202
pContext = GetContextSuspended();
1297
case AL_SOURCE_RELATIVE:
1298
case AL_CONE_INNER_ANGLE:
1299
case AL_CONE_OUTER_ANGLE:
1302
case AL_SOURCE_STATE:
1303
case AL_BUFFERS_QUEUED:
1304
case AL_BUFFERS_PROCESSED:
1306
case AL_SAMPLE_OFFSET:
1307
case AL_BYTE_OFFSET:
1308
case AL_MAX_DISTANCE:
1309
case AL_ROLLOFF_FACTOR:
1310
case AL_DOPPLER_FACTOR:
1311
case AL_REFERENCE_DISTANCE:
1312
case AL_SOURCE_TYPE:
1313
case AL_DIRECT_FILTER:
1314
case AL_DIRECT_FILTER_GAINHF_AUTO:
1315
case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO:
1316
case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO:
1317
case AL_DISTANCE_MODEL:
1318
case AL_DIRECT_CHANNELS_SOFT:
1319
alGetSourcei(source, eParam, plValues);
1325
alGetSource3i(source, eParam, plValues+0, plValues+1, plValues+2);
1329
pContext = GetContextRef();
1203
1330
if(!pContext) return;
1207
if((Source=LookupSource(pContext->SourceMap, source)) != NULL)
1334
if((Source=LookupSource(pContext, source)) != NULL)
1211
case AL_SOURCE_RELATIVE:
1212
case AL_CONE_INNER_ANGLE:
1213
case AL_CONE_OUTER_ANGLE:
1216
case AL_SOURCE_STATE:
1217
case AL_BUFFERS_QUEUED:
1218
case AL_BUFFERS_PROCESSED:
1220
case AL_SAMPLE_OFFSET:
1221
case AL_BYTE_OFFSET:
1222
case AL_MAX_DISTANCE:
1223
case AL_ROLLOFF_FACTOR:
1224
case AL_DOPPLER_FACTOR:
1225
case AL_REFERENCE_DISTANCE:
1226
case AL_SOURCE_TYPE:
1227
case AL_DIRECT_FILTER:
1228
case AL_DIRECT_FILTER_GAINHF_AUTO:
1229
case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO:
1230
case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO:
1231
case AL_DISTANCE_MODEL:
1232
alGetSourcei(source, eParam, plValues);
1238
alGetSource3i(source, eParam, plValues+0, plValues+1, plValues+2);
1241
1338
case AL_SAMPLE_RW_OFFSETS_SOFT:
1242
1339
case AL_BYTE_RW_OFFSETS_SOFT:
1340
LockContext(pContext);
1243
1341
updateLen = (ALdouble)pContext->Device->UpdateSize /
1244
1342
pContext->Device->Frequency;
1245
1343
GetSourceOffset(Source, eParam, Offsets, updateLen);
1344
UnlockContext(pContext);
1246
1345
plValues[0] = (ALint)Offsets[0];
1247
1346
plValues[1] = (ALint)Offsets[1];
1320
1420
for(i = 0;i < n;i++)
1322
Source = (ALsource*)ALTHUNK_LOOKUPENTRY(sources[i]);
1324
// Check that there is a queue containing at least one non-null, non zero length AL Buffer
1325
BufferList = Source->queue;
1328
if(BufferList->buffer != NULL && BufferList->buffer->size)
1330
BufferList = BufferList->next;
1335
Source->state = AL_STOPPED;
1336
Source->BuffersPlayed = Source->BuffersInQueue;
1337
Source->position = 0;
1338
Source->position_fraction = 0;
1339
Source->lOffset = 0;
1343
if(Source->state != AL_PAUSED)
1345
Source->state = AL_PLAYING;
1346
Source->position = 0;
1347
Source->position_fraction = 0;
1348
Source->BuffersPlayed = 0;
1350
Source->Buffer = Source->queue->buffer;
1353
Source->state = AL_PLAYING;
1355
// Check if an Offset has been set
1357
ApplyOffset(Source);
1359
// If device is disconnected, go right to stopped
1360
if(!Context->Device->Connected)
1362
Source->state = AL_STOPPED;
1363
Source->BuffersPlayed = Source->BuffersInQueue;
1364
Source->position = 0;
1365
Source->position_fraction = 0;
1369
for(j = 0;j < Context->ActiveSourceCount;j++)
1371
if(Context->ActiveSources[j] == Source)
1374
if(j == Context->ActiveSourceCount)
1375
Context->ActiveSources[Context->ActiveSourceCount++] = Source;
1422
Source = LookupSource(Context, sources[i]);
1423
if(Context->DeferUpdates) Source->new_state = AL_PLAYING;
1424
else SetSourceState(Source, Context, AL_PLAYING);
1426
UnlockContext(Context);
1380
ProcessContext(Context);
1429
ALCcontext_DecRef(Context);
1383
1432
AL_API ALvoid AL_APIENTRY alSourcePause(ALuint source)
1408
1457
// Check all the Sources are valid
1409
1458
for(i = 0;i < n;i++)
1411
if(!LookupSource(Context->SourceMap, sources[i]))
1460
if(!LookupSource(Context, sources[i]))
1413
1462
alSetError(Context, AL_INVALID_NAME);
1467
LockContext(Context);
1418
1468
for(i = 0;i < n;i++)
1420
Source = (ALsource*)ALTHUNK_LOOKUPENTRY(sources[i]);
1421
if(Source->state == AL_PLAYING)
1422
Source->state = AL_PAUSED;
1470
Source = LookupSource(Context, sources[i]);
1471
if(Context->DeferUpdates) Source->new_state = AL_PAUSED;
1472
else SetSourceState(Source, Context, AL_PAUSED);
1474
UnlockContext(Context);
1426
ProcessContext(Context);
1477
ALCcontext_DecRef(Context);
1429
1480
AL_API ALvoid AL_APIENTRY alSourceStop(ALuint source)
1454
1505
// Check all the Sources are valid
1455
1506
for(i = 0;i < n;i++)
1457
if(!LookupSource(Context->SourceMap, sources[i]))
1508
if(!LookupSource(Context, sources[i]))
1459
1510
alSetError(Context, AL_INVALID_NAME);
1515
LockContext(Context);
1464
1516
for(i = 0;i < n;i++)
1466
Source = (ALsource*)ALTHUNK_LOOKUPENTRY(sources[i]);
1467
if(Source->state != AL_INITIAL)
1469
Source->state = AL_STOPPED;
1470
Source->BuffersPlayed = Source->BuffersInQueue;
1472
Source->lOffset = 0;
1518
Source = LookupSource(Context, sources[i]);
1519
Source->new_state = AL_NONE;
1520
SetSourceState(Source, Context, AL_STOPPED);
1522
UnlockContext(Context);
1476
ProcessContext(Context);
1525
ALCcontext_DecRef(Context);
1479
1528
AL_API ALvoid AL_APIENTRY alSourceRewind(ALuint source)
1504
1553
// Check all the Sources are valid
1505
1554
for(i = 0;i < n;i++)
1507
if(!LookupSource(Context->SourceMap, sources[i]))
1556
if(!LookupSource(Context, sources[i]))
1509
1558
alSetError(Context, AL_INVALID_NAME);
1563
LockContext(Context);
1514
1564
for(i = 0;i < n;i++)
1516
Source = (ALsource*)ALTHUNK_LOOKUPENTRY(sources[i]);
1517
if(Source->state != AL_INITIAL)
1519
Source->state = AL_INITIAL;
1520
Source->position = 0;
1521
Source->position_fraction = 0;
1522
Source->BuffersPlayed = 0;
1524
Source->Buffer = Source->queue->buffer;
1526
Source->lOffset = 0;
1566
Source = LookupSource(Context, sources[i]);
1567
Source->new_state = AL_NONE;
1568
SetSourceState(Source, Context, AL_INITIAL);
1570
UnlockContext(Context);
1530
ProcessContext(Context);
1573
ALCcontext_DecRef(Context);
1536
1579
ALCcontext *Context;
1537
1580
ALCdevice *device;
1538
1581
ALsource *Source;
1541
ALbufferlistitem *BufferListStart;
1583
ALbufferlistitem *BufferListStart = NULL;
1542
1584
ALbufferlistitem *BufferList;
1543
1585
ALbuffer *BufferFmt;
1548
Context = GetContextSuspended();
1590
Context = GetContextRef();
1549
1591
if(!Context) return;
1553
1595
alSetError(Context, AL_INVALID_VALUE);
1557
1599
// Check that all buffers are valid or zero and that the source is valid
1559
1601
// Check that this is a valid source
1560
if((Source=LookupSource(Context->SourceMap, source)) == NULL)
1602
if((Source=LookupSource(Context, source)) == NULL)
1562
1604
alSetError(Context, AL_INVALID_NAME);
1608
LockContext(Context);
1566
1609
// Check that this is not a STATIC Source
1567
1610
if(Source->lSourceType == AL_STATIC)
1612
UnlockContext(Context);
1569
1613
// Invalid Source Type (can't queue on a Static Source)
1570
1614
alSetError(Context, AL_INVALID_OPERATION);
1574
1618
device = Context->Device;
1590
1634
for(i = 0;i < n;i++)
1595
if((buffer=LookupBuffer(device->BufferMap, buffers[i])) == NULL)
1636
ALbuffer *buffer = NULL;
1637
if(buffers[i] && (buffer=LookupBuffer(device, buffers[i])) == NULL)
1639
UnlockContext(Context);
1597
1640
alSetError(Context, AL_INVALID_NAME);
1644
if(!BufferListStart)
1646
BufferListStart = malloc(sizeof(ALbufferlistitem));
1647
BufferListStart->buffer = buffer;
1648
BufferListStart->next = NULL;
1649
BufferListStart->prev = NULL;
1650
BufferList = BufferListStart;
1654
BufferList->next = malloc(sizeof(ALbufferlistitem));
1655
BufferList->next->buffer = buffer;
1656
BufferList->next->next = NULL;
1657
BufferList->next->prev = BufferList;
1658
BufferList = BufferList->next;
1660
if(!buffer) continue;
1662
// Increment reference counter for buffer
1663
IncrementRef(&buffer->ref);
1664
ReadLock(&buffer->lock);
1601
1665
if(BufferFmt == NULL)
1603
1667
BufferFmt = buffer;
1669
Source->NumChannels = ChannelsFromFmt(buffer->FmtChannels);
1670
Source->SampleSize = BytesFromFmt(buffer->FmtType);
1605
1671
if(buffer->FmtChannels == FmtMono)
1606
1672
Source->Update = CalcSourceParams;
1613
1679
BufferFmt->OriginalChannels != buffer->OriginalChannels ||
1614
1680
BufferFmt->OriginalType != buffer->OriginalType)
1682
ReadUnlock(&buffer->lock);
1683
UnlockContext(Context);
1616
1684
alSetError(Context, AL_INVALID_OPERATION);
1687
ReadUnlock(&buffer->lock);
1621
1690
// Change Source Type
1622
1691
Source->lSourceType = AL_STREAMING;
1624
buffer = (ALbuffer*)ALTHUNK_LOOKUPENTRY(buffers[0]);
1626
// All buffers are valid - so add them to the list
1627
BufferListStart = malloc(sizeof(ALbufferlistitem));
1628
BufferListStart->buffer = buffer;
1629
BufferListStart->next = NULL;
1630
BufferListStart->prev = NULL;
1632
// Increment reference counter for buffer
1633
if(buffer) buffer->refcount++;
1635
BufferList = BufferListStart;
1637
for(i = 1;i < n;i++)
1639
buffer = (ALbuffer*)ALTHUNK_LOOKUPENTRY(buffers[i]);
1641
BufferList->next = malloc(sizeof(ALbufferlistitem));
1642
BufferList->next->buffer = buffer;
1643
BufferList->next->next = NULL;
1644
BufferList->next->prev = BufferList;
1646
// Increment reference counter for buffer
1647
if(buffer) buffer->refcount++;
1649
BufferList = BufferList->next;
1652
1693
if(Source->queue == NULL)
1654
1694
Source->queue = BufferListStart;
1655
// Update Current Buffer
1656
Source->Buffer = BufferListStart->buffer;
1660
1697
// Find end of queue
1662
1699
while(BufferList->next != NULL)
1663
1700
BufferList = BufferList->next;
1702
BufferListStart->prev = BufferList;
1665
1703
BufferList->next = BufferListStart;
1666
BufferList->next->prev = BufferList;
1669
1706
// Update number of buffers in queue
1670
1707
Source->BuffersInQueue += n;
1673
ProcessContext(Context);
1709
UnlockContext(Context);
1710
ALCcontext_DecRef(Context);
1714
while(BufferListStart)
1716
BufferList = BufferListStart;
1717
BufferListStart = BufferList->next;
1719
if(BufferList->buffer)
1720
DecrementRef(&BufferList->buffer->ref);
1723
ALCcontext_DecRef(Context);
1714
1766
BufferList = Source->queue;
1715
1767
Source->queue = BufferList->next;
1768
Source->BuffersInQueue--;
1769
Source->BuffersPlayed--;
1717
1771
if(BufferList->buffer)
1719
1773
// Record name of buffer
1720
1774
buffers[i] = BufferList->buffer->buffer;
1721
1775
// Decrement buffer reference counter
1722
BufferList->buffer->refcount--;
1776
DecrementRef(&BufferList->buffer->ref);
1725
1779
buffers[i] = 0;
1727
1781
// Release memory for buffer list item
1728
1782
free(BufferList);
1729
Source->BuffersInQueue--;
1731
1784
if(Source->queue)
1732
1785
Source->queue->prev = NULL;
1734
if(Source->state != AL_PLAYING)
1737
Source->Buffer = Source->queue->buffer;
1739
Source->Buffer = NULL;
1741
Source->BuffersPlayed -= n;
1786
UnlockContext(Context);
1744
ProcessContext(Context);
1789
ALCcontext_DecRef(Context);
1748
1793
static ALvoid InitSourceParams(ALsource *Source)
1750
1797
Source->flInnerAngle = 360.0f;
1751
1798
Source->flOuterAngle = 360.0f;
1752
1799
Source->flPitch = 1.0f;
1775
1822
Source->AirAbsorptionFactor = 0.0f;
1776
1823
Source->RoomRolloffFactor = 0.0f;
1777
1824
Source->DopplerFactor = 1.0f;
1825
Source->DirectChannels = AL_FALSE;
1779
Source->DistanceModel = AL_INVERSE_DISTANCE_CLAMPED;
1827
Source->DistanceModel = DefaultDistanceModel;
1781
1829
Source->Resampler = DefaultResampler;
1783
1831
Source->state = AL_INITIAL;
1832
Source->new_state = AL_NONE;
1784
1833
Source->lSourceType = AL_UNDETERMINED;
1834
Source->lOffset = -1;
1836
Source->DirectGain = 1.0f;
1837
Source->DirectGainHF = 1.0f;
1838
for(i = 0;i < MAX_SENDS;i++)
1840
Source->Send[i].WetGain = 1.0f;
1841
Source->Send[i].WetGainHF = 1.0f;
1786
1844
Source->NeedsUpdate = AL_TRUE;
1788
Source->Buffer = NULL;
1846
Source->HrtfMoving = AL_FALSE;
1847
Source->HrtfCounter = 0;
1854
* Sets the source's new play state given its current state
1856
ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state)
1858
if(state == AL_PLAYING)
1860
ALbufferlistitem *BufferList;
1863
/* Check that there is a queue containing at least one non-null, non zero length AL Buffer */
1864
BufferList = Source->queue;
1867
if(BufferList->buffer != NULL && BufferList->buffer->SampleLen)
1869
BufferList = BufferList->next;
1872
if(Source->state != AL_PLAYING)
1874
for(j = 0;j < MAXCHANNELS;j++)
1876
for(k = 0;k < SRC_HISTORY_LENGTH;k++)
1877
Source->HrtfHistory[j][k] = 0.0f;
1878
for(k = 0;k < HRIR_LENGTH;k++)
1880
Source->HrtfValues[j][k][0] = 0.0f;
1881
Source->HrtfValues[j][k][1] = 0.0f;
1886
if(Source->state != AL_PAUSED)
1888
Source->state = AL_PLAYING;
1889
Source->position = 0;
1890
Source->position_fraction = 0;
1891
Source->BuffersPlayed = 0;
1894
Source->state = AL_PLAYING;
1896
// Check if an Offset has been set
1897
if(Source->lOffset != -1)
1898
ApplyOffset(Source);
1900
/* If there's nothing to play, or device is disconnected, go right to
1902
if(!BufferList || !Context->Device->Connected)
1904
SetSourceState(Source, Context, AL_STOPPED);
1908
for(j = 0;j < Context->ActiveSourceCount;j++)
1910
if(Context->ActiveSources[j] == Source)
1913
if(j == Context->ActiveSourceCount)
1914
Context->ActiveSources[Context->ActiveSourceCount++] = Source;
1916
else if(state == AL_PAUSED)
1918
if(Source->state == AL_PLAYING)
1920
Source->state = AL_PAUSED;
1921
Source->HrtfMoving = AL_FALSE;
1922
Source->HrtfCounter = 0;
1925
else if(state == AL_STOPPED)
1927
if(Source->state != AL_INITIAL)
1929
Source->state = AL_STOPPED;
1930
Source->BuffersPlayed = Source->BuffersInQueue;
1931
Source->HrtfMoving = AL_FALSE;
1932
Source->HrtfCounter = 0;
1934
Source->lOffset = -1;
1936
else if(state == AL_INITIAL)
1938
if(Source->state != AL_INITIAL)
1940
Source->state = AL_INITIAL;
1941
Source->position = 0;
1942
Source->position_fraction = 0;
1943
Source->BuffersPlayed = 0;
1944
Source->HrtfMoving = AL_FALSE;
1945
Source->HrtfCounter = 0;
1947
Source->lOffset = -1;
1793
1952
GetSourceOffset
1828
// Get Current Buffer Size and frequency (in milliseconds)
1829
BufferFreq = Buffer->Frequency;
1830
OriginalType = Buffer->OriginalType;
1831
Channels = ChannelsFromFmt(Buffer->FmtChannels);
1832
Bytes = BytesFromFmt(Buffer->FmtType);
1986
if(updateLen > 0.0 && updateLen < 0.015)
1834
// Get Current BytesPlayed (NOTE : This is the byte offset into the *current* buffer)
1835
readPos = Source->position * Channels * Bytes;
1836
// Add byte length of any processed buffers in the queue
1837
TotalBufferDataSize = 0;
1989
// Get Current SamplesPlayed (NOTE : This is the offset into the *current* buffer)
1990
readPos = Source->position;
1991
// Add length of any processed buffers in the queue
1838
1993
BufferList = Source->queue;
1839
1994
for(i = 0;BufferList;i++)
1841
1996
if(BufferList->buffer)
1843
1998
if(i < Source->BuffersPlayed)
1844
readPos += BufferList->buffer->size;
1845
TotalBufferDataSize += BufferList->buffer->size;
1999
readPos += BufferList->buffer->SampleLen;
2000
totalBufferLen += BufferList->buffer->SampleLen;
1847
2002
BufferList = BufferList->next;
1849
2004
if(Source->state == AL_PLAYING)
1850
writePos = readPos + ((ALuint)(updateLen*BufferFreq) * Channels * Bytes);
2005
writePos = readPos + (ALuint)(updateLen*BufferFreq);
1852
2007
writePos = readPos;
1854
2009
if(Source->bLooping)
1856
readPos %= TotalBufferDataSize;
1857
writePos %= TotalBufferDataSize;
2011
readPos %= totalBufferLen;
2012
writePos %= totalBufferLen;
1861
2016
// Wrap positions back to 0
1862
if(readPos >= TotalBufferDataSize)
2017
if(readPos >= totalBufferLen)
1864
if(writePos >= TotalBufferDataSize)
2019
if(writePos >= totalBufferLen)
1870
2025
case AL_SEC_OFFSET:
1871
offset[0] = (ALdouble)readPos / (Channels * Bytes * BufferFreq);
1872
offset[1] = (ALdouble)writePos / (Channels * Bytes * BufferFreq);
2026
offset[0] = (ALdouble)readPos / Buffer->Frequency;
2027
offset[1] = (ALdouble)writePos / Buffer->Frequency;
1874
2029
case AL_SAMPLE_OFFSET:
1875
2030
case AL_SAMPLE_RW_OFFSETS_SOFT:
1876
offset[0] = (ALdouble)(readPos / (Channels * Bytes));
1877
offset[1] = (ALdouble)(writePos / (Channels * Bytes));
2031
offset[0] = (ALdouble)readPos;
2032
offset[1] = (ALdouble)writePos;
1879
2034
case AL_BYTE_OFFSET:
1880
2035
case AL_BYTE_RW_OFFSETS_SOFT:
1881
2036
// Take into account the original format of the Buffer
1882
if(OriginalType == UserFmtIMA4)
2037
if(Buffer->OriginalType == UserFmtIMA4)
1884
ALuint FrameBlockSize = 65 * Bytes * Channels;
1885
ALuint BlockSize = 36 * Channels;
2039
ALuint BlockSize = 36 * ChannelsFromFmt(Buffer->FmtChannels);
2040
ALuint FrameBlockSize = 65;
1887
2042
// Round down to nearest ADPCM block
1888
2043
offset[0] = (ALdouble)(readPos / FrameBlockSize * BlockSize);
1912
2067
Apply a playback offset to the Source. This function will update the queue (to correctly
1913
2068
mark buffers as 'pending' or 'processed' depending upon the new offset.
1915
static ALboolean ApplyOffset(ALsource *Source)
2070
ALboolean ApplyOffset(ALsource *Source)
1917
2072
const ALbufferlistitem *BufferList;
1918
2073
const ALbuffer *Buffer;
1919
ALint lBufferSize, lTotalBufferSize;
1920
ALint BuffersPlayed;
2074
ALint bufferLen, totalBufferLen;
2075
ALint buffersPlayed;
1923
2078
// Get true byte offset
1924
lByteOffset = GetByteOffset(Source);
2079
offset = GetSampleOffset(Source);
1926
2081
// If the offset is invalid, don't apply it
1927
if(lByteOffset == -1)
1928
2083
return AL_FALSE;
1930
2085
// Sort out the queue (pending and processed states)
1931
2086
BufferList = Source->queue;
1932
lTotalBufferSize = 0;
1935
2090
while(BufferList)
1937
2092
Buffer = BufferList->buffer;
1938
lBufferSize = Buffer ? Buffer->size : 0;
2093
bufferLen = Buffer ? Buffer->SampleLen : 0;
1940
if(lBufferSize <= lByteOffset-lTotalBufferSize)
2095
if(bufferLen <= offset-totalBufferLen)
1942
2097
// Offset is past this buffer so increment BuffersPlayed
1945
else if(lTotalBufferSize <= lByteOffset)
2100
else if(totalBufferLen <= offset)
1947
2102
// Offset is within this buffer
1948
// Set Current Buffer
1949
Source->Buffer = BufferList->buffer;
1950
Source->BuffersPlayed = BuffersPlayed;
2103
Source->BuffersPlayed = buffersPlayed;
1952
2105
// SW Mixer Positions are in Samples
1953
Source->position = (lByteOffset - lTotalBufferSize) /
1954
FrameSizeFromFmt(Buffer->FmtChannels, Buffer->FmtType);
2106
Source->position = offset - totalBufferLen;
1955
2107
return AL_TRUE;
1958
2110
// Increment the TotalBufferSize
1959
lTotalBufferSize += lBufferSize;
2111
totalBufferLen += bufferLen;
1961
2113
// Move on to next buffer in the Queue
1962
2114
BufferList = BufferList->next;
1972
Returns the 'true' byte offset into the Source's queue (from the Sample, Byte or Millisecond
1973
offset supplied by the application). This takes into account the fact that the buffer format
1974
may have been modifed by AL (e.g 8bit samples are converted to float)
2124
Returns the sample offset into the Source's queue (from the Sample, Byte or Millisecond offset
2125
supplied by the application). This takes into account the fact that the buffer format may have
1976
static ALint GetByteOffset(ALsource *Source)
2128
static ALint GetSampleOffset(ALsource *Source)
1978
2130
const ALbuffer *Buffer = NULL;
1979
2131
const ALbufferlistitem *BufferList;
1980
ALint ByteOffset = -1;
1982
2134
// Find the first non-NULL Buffer in the Queue
1983
2135
BufferList = Source->queue;
2003
2155
case AL_BYTE_OFFSET:
2004
2156
// Take into consideration the original format
2005
ByteOffset = Source->lOffset;
2157
Offset = Source->lOffset;
2006
2158
if(Buffer->OriginalType == UserFmtIMA4)
2008
2160
// Round down to nearest ADPCM block
2009
ByteOffset /= 36 * ChannelsFromUserFmt(Buffer->OriginalChannels);
2161
Offset /= 36 * ChannelsFromUserFmt(Buffer->OriginalChannels);
2010
2162
// Multiply by compression rate (65 sample frames per block)
2014
ByteOffset /= FrameSizeFromUserFmt(Buffer->OriginalChannels, Buffer->OriginalType);
2015
ByteOffset *= FrameSizeFromFmt(Buffer->FmtChannels, Buffer->FmtType);
2166
Offset /= FrameSizeFromUserFmt(Buffer->OriginalChannels, Buffer->OriginalType);
2018
2169
case AL_SAMPLE_OFFSET:
2019
ByteOffset = Source->lOffset * FrameSizeFromFmt(Buffer->FmtChannels, Buffer->FmtType);
2170
Offset = Source->lOffset;
2022
2173
case AL_SEC_OFFSET:
2023
2174
// Note - lOffset is internally stored as Milliseconds
2024
ByteOffset = (ALint)(Source->lOffset / 1000.0 * Buffer->Frequency);
2025
ByteOffset *= FrameSizeFromFmt(Buffer->FmtChannels, Buffer->FmtType);
2175
Offset = (ALint)(Source->lOffset / 1000.0 * Buffer->Frequency);
2028
2178
// Clear Offset
2029
Source->lOffset = 0;
2179
Source->lOffset = -1;
2048
2198
temp->queue = BufferList->next;
2050
2200
if(BufferList->buffer != NULL)
2051
BufferList->buffer->refcount--;
2201
DecrementRef(&BufferList->buffer->ref);
2052
2202
free(BufferList);
2055
2205
for(j = 0;j < MAX_SENDS;++j)
2057
2207
if(temp->Send[j].Slot)
2058
temp->Send[j].Slot->refcount--;
2208
DecrementRef(&temp->Send[j].Slot->ref);
2059
2209
temp->Send[j].Slot = NULL;
2062
2212
// Release source structure
2063
ALTHUNK_REMOVEENTRY(temp->source);
2213
FreeThunkEntry(temp->source);
2064
2214
memset(temp, 0, sizeof(ALsource));