40
static __inline ALfloat point32(const ALfloat *vals, ALint step, ALint frac)
41
{ return vals[0]; (void)step; (void)frac; }
42
static __inline ALfloat lerp32(const ALfloat *vals, ALint step, ALint frac)
43
{ return lerp(vals[0], vals[step], frac * (1.0f/FRACTIONONE)); }
44
static __inline ALfloat cubic32(const ALfloat *vals, ALint step, ALint frac)
45
{ return cubic(vals[-step], vals[0], vals[step], vals[step+step],
46
frac * (1.0f/FRACTIONONE)); }
49
#define LIKELY(x) __builtin_expect(!!(x), 1)
50
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
53
#define UNLIKELY(x) (x)
56
#if defined(__ARM_NEON__) && defined(HAVE_ARM_NEON_H)
59
static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2],
60
ALfloat (*RESTRICT Coeffs)[2],
61
ALfloat left, ALfloat right)
64
float32x4_t leftright4;
66
float32x2_t leftright2 = vdup_n_f32(0.0);
67
leftright2 = vset_lane_f32(left, leftright2, 0);
68
leftright2 = vset_lane_f32(right, leftright2, 1);
69
leftright4 = vcombine_f32(leftright2, leftright2);
71
for(c = 0;c < HRIR_LENGTH;c += 2)
73
const ALuint o0 = (Offset+c)&HRIR_MASK;
74
const ALuint o1 = (o0+1)&HRIR_MASK;
75
float32x4_t vals = vcombine_f32(vld1_f32((float32_t*)&Values[o0][0]),
76
vld1_f32((float32_t*)&Values[o1][0]));
77
float32x4_t coefs = vld1q_f32((float32_t*)&Coeffs[c][0]);
79
vals = vmlaq_f32(vals, coefs, leftright4);
81
vst1_f32((float32_t*)&Values[o0][0], vget_low_f32(vals));
82
vst1_f32((float32_t*)&Values[o1][0], vget_high_f32(vals));
88
static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2],
89
ALfloat (*RESTRICT Coeffs)[2],
90
ALfloat left, ALfloat right)
93
for(c = 0;c < HRIR_LENGTH;c++)
95
const ALuint off = (Offset+c)&HRIR_MASK;
96
Values[off][0] += Coeffs[c][0] * left;
97
Values[off][1] += Coeffs[c][1] * right;
103
#define DECL_TEMPLATE(T, sampler) \
104
static void Mix_Hrtf_##T##_##sampler(ALsource *Source, ALCdevice *Device, \
105
const ALvoid *srcdata, ALuint *DataPosInt, ALuint *DataPosFrac, \
106
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) \
108
const ALuint NumChannels = Source->NumChannels; \
109
const T *RESTRICT data = srcdata; \
110
const ALint *RESTRICT DelayStep = Source->Params.HrtfDelayStep; \
111
ALfloat (*RESTRICT DryBuffer)[MAXCHANNELS]; \
112
ALfloat *RESTRICT ClickRemoval, *RESTRICT PendingClicks; \
113
ALfloat (*RESTRICT CoeffStep)[2] = Source->Params.HrtfCoeffStep; \
121
increment = Source->Params.Step; \
123
DryBuffer = Device->DryBuffer; \
124
ClickRemoval = Device->ClickRemoval; \
125
PendingClicks = Device->PendingClicks; \
126
DryFilter = &Source->Params.iirFilter; \
129
frac = *DataPosFrac; \
131
for(i = 0;i < NumChannels;i++) \
133
ALfloat (*RESTRICT TargetCoeffs)[2] = Source->Params.HrtfCoeffs[i]; \
134
ALuint *RESTRICT TargetDelay = Source->Params.HrtfDelay[i]; \
135
ALfloat *RESTRICT History = Source->HrtfHistory[i]; \
136
ALfloat (*RESTRICT Values)[2] = Source->HrtfValues[i]; \
137
ALint Counter = maxu(Source->HrtfCounter, OutPos) - OutPos; \
138
ALuint Offset = Source->HrtfOffset + OutPos; \
139
ALfloat Coeffs[HRIR_LENGTH][2]; \
141
ALfloat left, right; \
144
frac = *DataPosFrac; \
146
for(c = 0;c < HRIR_LENGTH;c++) \
148
Coeffs[c][0] = TargetCoeffs[c][0] - (CoeffStep[c][0]*Counter); \
149
Coeffs[c][1] = TargetCoeffs[c][1] - (CoeffStep[c][1]*Counter); \
152
Delay[0] = TargetDelay[0] - (DelayStep[0]*Counter) + 32768; \
153
Delay[1] = TargetDelay[1] - (DelayStep[1]*Counter) + 32768; \
155
if(LIKELY(OutPos == 0)) \
157
value = sampler(data + pos*NumChannels + i, NumChannels, frac); \
158
value = lpFilter2PC(DryFilter, i, value); \
160
History[Offset&SRC_HISTORY_MASK] = value; \
161
left = History[(Offset-(Delay[0]>>16))&SRC_HISTORY_MASK]; \
162
right = History[(Offset-(Delay[1]>>16))&SRC_HISTORY_MASK]; \
164
ClickRemoval[FRONT_LEFT] -= Values[(Offset+1)&HRIR_MASK][0] + \
165
Coeffs[0][0] * left; \
166
ClickRemoval[FRONT_RIGHT] -= Values[(Offset+1)&HRIR_MASK][1] + \
167
Coeffs[0][1] * right; \
169
for(BufferIdx = 0;BufferIdx < BufferSize && Counter > 0;BufferIdx++) \
171
value = sampler(data + pos*NumChannels + i, NumChannels, frac); \
172
value = lpFilter2P(DryFilter, i, value); \
174
History[Offset&SRC_HISTORY_MASK] = value; \
175
left = History[(Offset-(Delay[0]>>16))&SRC_HISTORY_MASK]; \
176
right = History[(Offset-(Delay[1]>>16))&SRC_HISTORY_MASK]; \
178
Delay[0] += DelayStep[0]; \
179
Delay[1] += DelayStep[1]; \
181
Values[Offset&HRIR_MASK][0] = 0.0f; \
182
Values[Offset&HRIR_MASK][1] = 0.0f; \
185
for(c = 0;c < HRIR_LENGTH;c++) \
187
const ALuint off = (Offset+c)&HRIR_MASK; \
188
Values[off][0] += Coeffs[c][0] * left; \
189
Values[off][1] += Coeffs[c][1] * right; \
190
Coeffs[c][0] += CoeffStep[c][0]; \
191
Coeffs[c][1] += CoeffStep[c][1]; \
194
DryBuffer[OutPos][FRONT_LEFT] += Values[Offset&HRIR_MASK][0]; \
195
DryBuffer[OutPos][FRONT_RIGHT] += Values[Offset&HRIR_MASK][1]; \
198
pos += frac>>FRACTIONBITS; \
199
frac &= FRACTIONMASK; \
206
for(;BufferIdx < BufferSize;BufferIdx++) \
208
value = sampler(data + pos*NumChannels + i, NumChannels, frac); \
209
value = lpFilter2P(DryFilter, i, value); \
211
History[Offset&SRC_HISTORY_MASK] = value; \
212
left = History[(Offset-Delay[0])&SRC_HISTORY_MASK]; \
213
right = History[(Offset-Delay[1])&SRC_HISTORY_MASK]; \
215
Values[Offset&HRIR_MASK][0] = 0.0f; \
216
Values[Offset&HRIR_MASK][1] = 0.0f; \
219
ApplyCoeffs(Offset, Values, Coeffs, left, right); \
220
DryBuffer[OutPos][FRONT_LEFT] += Values[Offset&HRIR_MASK][0]; \
221
DryBuffer[OutPos][FRONT_RIGHT] += Values[Offset&HRIR_MASK][1]; \
224
pos += frac>>FRACTIONBITS; \
225
frac &= FRACTIONMASK; \
228
if(LIKELY(OutPos == SamplesToDo)) \
230
value = sampler(data + pos*NumChannels + i, NumChannels, frac); \
231
value = lpFilter2PC(DryFilter, i, value); \
233
History[Offset&SRC_HISTORY_MASK] = value; \
234
left = History[(Offset-Delay[0])&SRC_HISTORY_MASK]; \
235
right = History[(Offset-Delay[1])&SRC_HISTORY_MASK]; \
237
PendingClicks[FRONT_LEFT] += Values[(Offset+1)&HRIR_MASK][0] + \
238
Coeffs[0][0] * left; \
239
PendingClicks[FRONT_RIGHT] += Values[(Offset+1)&HRIR_MASK][1] + \
240
Coeffs[0][1] * right; \
242
OutPos -= BufferSize; \
245
for(out = 0;out < Device->NumAuxSends;out++) \
247
ALeffectslot *Slot = Source->Params.Send[out].Slot; \
249
ALfloat *RESTRICT WetBuffer; \
250
ALfloat *RESTRICT WetClickRemoval; \
251
ALfloat *RESTRICT WetPendingClicks; \
257
WetBuffer = Slot->WetBuffer; \
258
WetClickRemoval = Slot->ClickRemoval; \
259
WetPendingClicks = Slot->PendingClicks; \
260
WetFilter = &Source->Params.Send[out].iirFilter; \
261
WetSend = Source->Params.Send[out].WetGain; \
263
for(i = 0;i < NumChannels;i++) \
266
frac = *DataPosFrac; \
268
if(LIKELY(OutPos == 0)) \
270
value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
271
value = lpFilter1PC(WetFilter, i, value); \
273
WetClickRemoval[0] -= value * WetSend; \
275
for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \
277
value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
278
value = lpFilter1P(WetFilter, i, value); \
280
WetBuffer[OutPos] += value * WetSend; \
283
pos += frac>>FRACTIONBITS; \
284
frac &= FRACTIONMASK; \
287
if(LIKELY(OutPos == SamplesToDo)) \
289
value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
290
value = lpFilter1PC(WetFilter, i, value); \
292
WetPendingClicks[0] += value * WetSend; \
294
OutPos -= BufferSize; \
297
*DataPosInt += pos; \
298
*DataPosFrac = frac; \
301
DECL_TEMPLATE(ALfloat, point32)
302
DECL_TEMPLATE(ALfloat, lerp32)
303
DECL_TEMPLATE(ALfloat, cubic32)
308
#define DECL_TEMPLATE(T, sampler) \
309
static void Mix_##T##_##sampler(ALsource *Source, ALCdevice *Device, \
310
const ALvoid *srcdata, ALuint *DataPosInt, ALuint *DataPosFrac, \
311
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) \
313
const ALuint NumChannels = Source->NumChannels; \
314
const T *RESTRICT data = srcdata; \
315
ALfloat (*RESTRICT DryBuffer)[MAXCHANNELS]; \
316
ALfloat *RESTRICT ClickRemoval, *RESTRICT PendingClicks; \
317
ALfloat DrySend[MAXCHANNELS]; \
325
increment = Source->Params.Step; \
327
DryBuffer = Device->DryBuffer; \
328
ClickRemoval = Device->ClickRemoval; \
329
PendingClicks = Device->PendingClicks; \
330
DryFilter = &Source->Params.iirFilter; \
333
frac = *DataPosFrac; \
335
for(i = 0;i < NumChannels;i++) \
337
for(c = 0;c < MAXCHANNELS;c++) \
338
DrySend[c] = Source->Params.DryGains[i][c]; \
341
frac = *DataPosFrac; \
345
value = sampler(data + pos*NumChannels + i, NumChannels, frac); \
347
value = lpFilter2PC(DryFilter, i, value); \
348
for(c = 0;c < MAXCHANNELS;c++) \
349
ClickRemoval[c] -= value*DrySend[c]; \
351
for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \
353
value = sampler(data + pos*NumChannels + i, NumChannels, frac); \
355
value = lpFilter2P(DryFilter, i, value); \
356
for(c = 0;c < MAXCHANNELS;c++) \
357
DryBuffer[OutPos][c] += value*DrySend[c]; \
360
pos += frac>>FRACTIONBITS; \
361
frac &= FRACTIONMASK; \
364
if(OutPos == SamplesToDo) \
366
value = sampler(data + pos*NumChannels + i, NumChannels, frac); \
368
value = lpFilter2PC(DryFilter, i, value); \
369
for(c = 0;c < MAXCHANNELS;c++) \
370
PendingClicks[c] += value*DrySend[c]; \
372
OutPos -= BufferSize; \
375
for(out = 0;out < Device->NumAuxSends;out++) \
377
ALeffectslot *Slot = Source->Params.Send[out].Slot; \
379
ALfloat *WetBuffer; \
380
ALfloat *WetClickRemoval; \
381
ALfloat *WetPendingClicks; \
387
WetBuffer = Slot->WetBuffer; \
388
WetClickRemoval = Slot->ClickRemoval; \
389
WetPendingClicks = Slot->PendingClicks; \
390
WetFilter = &Source->Params.Send[out].iirFilter; \
391
WetSend = Source->Params.Send[out].WetGain; \
393
for(i = 0;i < NumChannels;i++) \
396
frac = *DataPosFrac; \
400
value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
402
value = lpFilter1PC(WetFilter, i, value); \
403
WetClickRemoval[0] -= value * WetSend; \
405
for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \
407
value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
409
value = lpFilter1P(WetFilter, i, value); \
410
WetBuffer[OutPos] += value * WetSend; \
413
pos += frac>>FRACTIONBITS; \
414
frac &= FRACTIONMASK; \
417
if(OutPos == SamplesToDo) \
419
value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
421
value = lpFilter1PC(WetFilter, i, value); \
422
WetPendingClicks[0] += value * WetSend; \
424
OutPos -= BufferSize; \
427
*DataPosInt += pos; \
428
*DataPosFrac = frac; \
431
DECL_TEMPLATE(ALfloat, point32)
432
DECL_TEMPLATE(ALfloat, lerp32)
433
DECL_TEMPLATE(ALfloat, cubic32)
438
MixerFunc SelectMixer(enum Resampler Resampler)
443
return Mix_ALfloat_point32;
444
case LinearResampler:
445
return Mix_ALfloat_lerp32;
447
return Mix_ALfloat_cubic32;
454
MixerFunc SelectHrtfMixer(enum Resampler Resampler)
459
return Mix_Hrtf_ALfloat_point32;
460
case LinearResampler:
461
return Mix_Hrtf_ALfloat_lerp32;
463
return Mix_Hrtf_ALfloat_cubic32;
471
40
static __inline ALfloat Sample_ALbyte(ALbyte val)
472
41
{ return val * (1.0f/127.0f); }
561
137
DataSize64 += DataPosFrac+FRACTIONMASK;
562
138
DataSize64 >>= FRACTIONBITS;
563
139
DataSize64 += BufferPadding+BufferPrePadding;
564
DataSize64 *= NumChannels;
566
BufferSize = (ALuint)mini64(DataSize64, STACK_DATA_SIZE/sizeof(ALfloat));
567
BufferSize /= NumChannels;
569
if(Source->lSourceType == AL_STATIC)
571
const ALbuffer *ALBuffer = Source->queue->buffer;
572
const ALubyte *Data = ALBuffer->data;
576
/* If current pos is beyond the loop range, do not loop */
577
if(Looping == AL_FALSE || DataPosInt >= (ALuint)ALBuffer->LoopEnd)
581
if(DataPosInt >= BufferPrePadding)
582
pos = DataPosInt - BufferPrePadding;
585
DataSize = BufferPrePadding - DataPosInt;
586
DataSize = minu(BufferSize, DataSize);
588
SilenceStack(&SrcData[SrcDataSize*NumChannels],
589
DataSize*NumChannels);
590
SrcDataSize += DataSize;
591
BufferSize -= DataSize;
596
/* Copy what's left to play in the source buffer, and clear the
597
* rest of the temp buffer */
598
DataSize = ALBuffer->SampleLen - pos;
599
DataSize = minu(BufferSize, DataSize);
601
LoadStack(&SrcData[SrcDataSize*NumChannels], &Data[pos*FrameSize],
602
ALBuffer->FmtType, DataSize*NumChannels);
603
SrcDataSize += DataSize;
604
BufferSize -= DataSize;
606
SilenceStack(&SrcData[SrcDataSize*NumChannels],
607
BufferSize*NumChannels);
608
SrcDataSize += BufferSize;
609
BufferSize -= BufferSize;
613
ALuint LoopStart = ALBuffer->LoopStart;
614
ALuint LoopEnd = ALBuffer->LoopEnd;
616
if(DataPosInt >= LoopStart)
618
pos = DataPosInt-LoopStart;
619
while(pos < BufferPrePadding)
620
pos += LoopEnd-LoopStart;
621
pos -= BufferPrePadding;
624
else if(DataPosInt >= BufferPrePadding)
625
pos = DataPosInt - BufferPrePadding;
628
DataSize = BufferPrePadding - DataPosInt;
629
DataSize = minu(BufferSize, DataSize);
631
SilenceStack(&SrcData[SrcDataSize*NumChannels], DataSize*NumChannels);
632
SrcDataSize += DataSize;
633
BufferSize -= DataSize;
638
/* Copy what's left of this loop iteration, then copy repeats
639
* of the loop section */
640
DataSize = LoopEnd - pos;
641
DataSize = minu(BufferSize, DataSize);
643
LoadStack(&SrcData[SrcDataSize*NumChannels], &Data[pos*FrameSize],
644
ALBuffer->FmtType, DataSize*NumChannels);
645
SrcDataSize += DataSize;
646
BufferSize -= DataSize;
648
DataSize = LoopEnd-LoopStart;
649
while(BufferSize > 0)
651
DataSize = minu(BufferSize, DataSize);
653
LoadStack(&SrcData[SrcDataSize*NumChannels], &Data[LoopStart*FrameSize],
654
ALBuffer->FmtType, DataSize*NumChannels);
655
SrcDataSize += DataSize;
656
BufferSize -= DataSize;
662
/* Crawl the buffer queue to fill in the temp buffer */
663
ALbufferlistitem *tmpiter = BufferListItem;
666
if(DataPosInt >= BufferPrePadding)
667
pos = DataPosInt - BufferPrePadding;
670
pos = BufferPrePadding - DataPosInt;
673
if(!tmpiter->prev && !Looping)
675
ALuint DataSize = minu(BufferSize, pos);
677
SilenceStack(&SrcData[SrcDataSize*NumChannels], DataSize*NumChannels);
678
SrcDataSize += DataSize;
679
BufferSize -= DataSize;
686
tmpiter = tmpiter->prev;
690
tmpiter = tmpiter->next;
695
if((ALuint)tmpiter->buffer->SampleLen > pos)
697
pos = tmpiter->buffer->SampleLen - pos;
700
pos -= tmpiter->buffer->SampleLen;
705
while(tmpiter && BufferSize > 0)
707
const ALbuffer *ALBuffer;
708
if((ALBuffer=tmpiter->buffer) != NULL)
710
const ALubyte *Data = ALBuffer->data;
711
ALuint DataSize = ALBuffer->SampleLen;
713
/* Skip the data already played */
718
Data += pos*FrameSize;
722
DataSize = minu(BufferSize, DataSize);
723
LoadStack(&SrcData[SrcDataSize*NumChannels], Data,
724
ALBuffer->FmtType, DataSize*NumChannels);
725
SrcDataSize += DataSize;
726
BufferSize -= DataSize;
729
tmpiter = tmpiter->next;
730
if(!tmpiter && Looping)
731
tmpiter = Source->queue;
734
SilenceStack(&SrcData[SrcDataSize*NumChannels], BufferSize*NumChannels);
735
SrcDataSize += BufferSize;
736
BufferSize -= BufferSize;
741
/* Figure out how many samples we can mix. */
742
DataSize64 = SrcDataSize;
141
SrcBufferSize = (ALuint)mini64(DataSize64, BUFFERSIZE);
143
/* Figure out how many samples we can actually mix from this. */
144
DataSize64 = SrcBufferSize;
743
145
DataSize64 -= BufferPadding+BufferPrePadding;
744
146
DataSize64 <<= FRACTIONBITS;
745
147
DataSize64 -= increment;
746
148
DataSize64 -= DataPosFrac;
748
BufferSize = (ALuint)((DataSize64+(increment-1)) / increment);
749
BufferSize = minu(BufferSize, (SamplesToDo-OutPos));
751
SrcData += BufferPrePadding*NumChannels;
752
Source->Params.DoMix(Source, Device, SrcData, &DataPosInt, &DataPosFrac,
753
OutPos, SamplesToDo, BufferSize);
754
OutPos += BufferSize;
150
DstBufferSize = (ALuint)((DataSize64+(increment-1)) / increment);
151
DstBufferSize = minu(DstBufferSize, (SamplesToDo-OutPos));
153
/* Some mixers like having a multiple of 4, so try to give that unless
154
* this is the last update. */
155
if(OutPos+DstBufferSize < SamplesToDo)
158
for(chan = 0;chan < NumChannels;chan++)
160
ALfloat *SrcData = Device->SampleData1;
161
ALfloat *ResampledData = Device->SampleData2;
162
ALuint SrcDataSize = 0;
164
if(Source->SourceType == AL_STATIC)
166
const ALbuffer *ALBuffer = Source->queue->buffer;
167
const ALubyte *Data = ALBuffer->data;
171
/* If current pos is beyond the loop range, do not loop */
172
if(Looping == AL_FALSE || DataPosInt >= (ALuint)ALBuffer->LoopEnd)
176
if(DataPosInt >= BufferPrePadding)
177
pos = DataPosInt - BufferPrePadding;
180
DataSize = BufferPrePadding - DataPosInt;
181
DataSize = minu(SrcBufferSize - SrcDataSize, DataSize);
183
SilenceData(&SrcData[SrcDataSize], DataSize);
184
SrcDataSize += DataSize;
189
/* Copy what's left to play in the source buffer, and clear the
190
* rest of the temp buffer */
191
DataSize = minu(SrcBufferSize - SrcDataSize, ALBuffer->SampleLen - pos);
193
LoadData(&SrcData[SrcDataSize], &Data[(pos*NumChannels + chan)*SampleSize],
194
NumChannels, ALBuffer->FmtType, DataSize);
195
SrcDataSize += DataSize;
197
SilenceData(&SrcData[SrcDataSize], SrcBufferSize - SrcDataSize);
198
SrcDataSize += SrcBufferSize - SrcDataSize;
202
ALuint LoopStart = ALBuffer->LoopStart;
203
ALuint LoopEnd = ALBuffer->LoopEnd;
205
if(DataPosInt >= LoopStart)
207
pos = DataPosInt-LoopStart;
208
while(pos < BufferPrePadding)
209
pos += LoopEnd-LoopStart;
210
pos -= BufferPrePadding;
213
else if(DataPosInt >= BufferPrePadding)
214
pos = DataPosInt - BufferPrePadding;
217
DataSize = BufferPrePadding - DataPosInt;
218
DataSize = minu(SrcBufferSize - SrcDataSize, DataSize);
220
SilenceData(&SrcData[SrcDataSize], DataSize);
221
SrcDataSize += DataSize;
226
/* Copy what's left of this loop iteration, then copy repeats
227
* of the loop section */
228
DataSize = LoopEnd - pos;
229
DataSize = minu(SrcBufferSize - SrcDataSize, DataSize);
231
LoadData(&SrcData[SrcDataSize], &Data[(pos*NumChannels + chan)*SampleSize],
232
NumChannels, ALBuffer->FmtType, DataSize);
233
SrcDataSize += DataSize;
235
DataSize = LoopEnd-LoopStart;
236
while(SrcBufferSize > SrcDataSize)
238
DataSize = minu(SrcBufferSize - SrcDataSize, DataSize);
240
LoadData(&SrcData[SrcDataSize], &Data[(LoopStart*NumChannels + chan)*SampleSize],
241
NumChannels, ALBuffer->FmtType, DataSize);
242
SrcDataSize += DataSize;
248
/* Crawl the buffer queue to fill in the temp buffer */
249
ALbufferlistitem *tmpiter = BufferListItem;
252
if(DataPosInt >= BufferPrePadding)
253
pos = DataPosInt - BufferPrePadding;
256
pos = BufferPrePadding - DataPosInt;
259
if(!tmpiter->prev && !Looping)
261
ALuint DataSize = minu(SrcBufferSize - SrcDataSize, pos);
263
SilenceData(&SrcData[SrcDataSize], DataSize);
264
SrcDataSize += DataSize;
271
tmpiter = tmpiter->prev;
275
tmpiter = tmpiter->next;
280
if((ALuint)tmpiter->buffer->SampleLen > pos)
282
pos = tmpiter->buffer->SampleLen - pos;
285
pos -= tmpiter->buffer->SampleLen;
290
while(tmpiter && SrcBufferSize > SrcDataSize)
292
const ALbuffer *ALBuffer;
293
if((ALBuffer=tmpiter->buffer) != NULL)
295
const ALubyte *Data = ALBuffer->data;
296
ALuint DataSize = ALBuffer->SampleLen;
298
/* Skip the data already played */
303
Data += (pos*NumChannels + chan)*SampleSize;
307
DataSize = minu(SrcBufferSize - SrcDataSize, DataSize);
308
LoadData(&SrcData[SrcDataSize], Data, NumChannels,
309
ALBuffer->FmtType, DataSize);
310
SrcDataSize += DataSize;
313
tmpiter = tmpiter->next;
314
if(!tmpiter && Looping)
315
tmpiter = Source->queue;
318
SilenceData(&SrcData[SrcDataSize], SrcBufferSize - SrcDataSize);
319
SrcDataSize += SrcBufferSize - SrcDataSize;
324
/* Now resample, then filter and mix to the appropriate outputs. */
325
Source->Params.Resample(&SrcData[BufferPrePadding], DataPosFrac,
326
increment, ResampledData, DstBufferSize);
329
DirectParams *directparms = &Source->Params.Direct;
331
Filter2P(&directparms->iirFilter, chan, SrcData, ResampledData,
333
Source->Params.DryMix(directparms, SrcData, chan, OutPos,
334
SamplesToDo, DstBufferSize);
337
for(j = 0;j < Device->NumAuxSends;j++)
339
SendParams *sendparms = &Source->Params.Send[j];
343
Filter2P(&sendparms->iirFilter, chan, SrcData, ResampledData,
345
Source->Params.WetMix(sendparms, SrcData, OutPos,
346
SamplesToDo, DstBufferSize);
349
/* Update positions */
350
for(j = 0;j < DstBufferSize;j++)
352
DataPosFrac += increment;
353
DataPosInt += DataPosFrac>>FRACTIONBITS;
354
DataPosFrac &= FRACTIONMASK;
356
OutPos += DstBufferSize;
756
358
/* Handle looping sources */