40
static __inline ALdouble point32(const ALfloat *vals, ALint step, ALint frac)
40
static __inline ALfloat point32(const ALfloat *vals, ALint step, ALint frac)
41
41
{ return vals[0]; (void)step; (void)frac; }
42
static __inline ALdouble lerp32(const ALfloat *vals, ALint step, ALint frac)
43
{ return lerp(vals[0], vals[step], frac * (1.0/FRACTIONONE)); }
44
static __inline ALdouble cubic32(const ALfloat *vals, ALint step, ALint frac)
45
{ return cubic(vals[-step], vals[0], vals[step], vals[step+step],
46
frac * (1.0/FRACTIONONE)); }
48
static __inline ALdouble point16(const ALshort *vals, ALint step, ALint frac)
49
{ return vals[0] * (1.0/32767.0); (void)step; (void)frac; }
50
static __inline ALdouble lerp16(const ALshort *vals, ALint step, ALint frac)
51
{ return lerp(vals[0], vals[step], frac * (1.0/FRACTIONONE)) * (1.0/32767.0); }
52
static __inline ALdouble cubic16(const ALshort *vals, ALint step, ALint frac)
53
{ return cubic(vals[-step], vals[0], vals[step], vals[step+step],
54
frac * (1.0/FRACTIONONE)) * (1.0/32767.0); }
56
static __inline ALdouble point8(const ALubyte *vals, ALint step, ALint frac)
57
{ return (vals[0]-128.0) * (1.0/127.0); (void)step; (void)frac; }
58
static __inline ALdouble lerp8(const ALubyte *vals, ALint step, ALint frac)
59
{ return (lerp(vals[0], vals[step],
60
frac * (1.0/FRACTIONONE))-128.0) * (1.0/127.0); }
61
static __inline ALdouble cubic8(const ALubyte *vals, ALint step, ALint frac)
62
{ return (cubic(vals[-step], vals[0], vals[step], vals[step+step],
63
frac * (1.0/FRACTIONONE))-128.0) * (1.0/127.0); }
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;
66
103
#define DECL_TEMPLATE(T, sampler) \
67
static void Mix_##T##_1_##sampler(ALsource *Source, ALCdevice *Device, \
68
const T *data, ALuint *DataPosInt, ALuint *DataPosFrac, \
104
static void Mix_Hrtf_##T##_##sampler(ALsource *Source, ALCdevice *Device, \
105
const ALvoid *srcdata, ALuint *DataPosInt, ALuint *DataPosFrac, \
69
106
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) \
71
ALfloat (*DryBuffer)[MAXCHANNELS]; \
72
ALfloat *ClickRemoval, *PendingClicks; \
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; \
73
114
ALuint pos, frac; \
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; \
74
317
ALfloat DrySend[MAXCHANNELS]; \
75
318
FILTER *DryFilter; \
81
increment = Source->Params.Step; \
83
DryBuffer = Device->DryBuffer; \
84
ClickRemoval = Device->ClickRemoval; \
85
PendingClicks = Device->PendingClicks; \
86
DryFilter = &Source->Params.iirFilter; \
87
for(c = 0;c < MAXCHANNELS;c++) \
88
DrySend[c] = Source->Params.DryGains[0][c]; \
91
frac = *DataPosFrac; \
95
value = sampler(data+pos, 1, frac); \
97
value = lpFilter4PC(DryFilter, 0, value); \
98
for(c = 0;c < MAXCHANNELS;c++) \
99
ClickRemoval[c] -= value*DrySend[c]; \
101
for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \
103
/* First order interpolator */ \
104
value = sampler(data+pos, 1, frac); \
106
/* Direct path final mix buffer and panning */ \
107
value = lpFilter4P(DryFilter, 0, value); \
108
for(c = 0;c < MAXCHANNELS;c++) \
109
DryBuffer[OutPos][c] += value*DrySend[c]; \
112
pos += frac>>FRACTIONBITS; \
113
frac &= FRACTIONMASK; \
116
if(OutPos == SamplesToDo) \
118
value = sampler(data+pos, 1, frac); \
120
value = lpFilter4PC(DryFilter, 0, value); \
121
for(c = 0;c < MAXCHANNELS;c++) \
122
PendingClicks[c] += value*DrySend[c]; \
125
for(out = 0;out < Device->NumAuxSends;out++) \
128
ALfloat *WetBuffer; \
129
ALfloat *WetClickRemoval; \
130
ALfloat *WetPendingClicks; \
133
if(!Source->Send[out].Slot || \
134
Source->Send[out].Slot->effect.type == AL_EFFECT_NULL) \
137
WetBuffer = Source->Send[out].Slot->WetBuffer; \
138
WetClickRemoval = Source->Send[out].Slot->ClickRemoval; \
139
WetPendingClicks = Source->Send[out].Slot->PendingClicks; \
140
WetFilter = &Source->Params.Send[out].iirFilter; \
141
WetSend = Source->Params.Send[out].WetGain; \
144
frac = *DataPosFrac; \
145
OutPos -= BufferSize; \
149
value = sampler(data+pos, 1, frac); \
151
value = lpFilter2PC(WetFilter, 0, value); \
152
WetClickRemoval[0] -= value*WetSend; \
154
for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \
156
/* First order interpolator */ \
157
value = sampler(data+pos, 1, frac); \
159
/* Room path final mix buffer and panning */ \
160
value = lpFilter2P(WetFilter, 0, value); \
161
WetBuffer[OutPos] += value*WetSend; \
164
pos += frac>>FRACTIONBITS; \
165
frac &= FRACTIONMASK; \
168
if(OutPos == SamplesToDo) \
170
value = sampler(data+pos, 1, frac); \
172
value = lpFilter2PC(WetFilter, 0, value); \
173
WetPendingClicks[0] += value*WetSend; \
176
*DataPosInt += pos; \
177
*DataPosFrac = frac; \
180
DECL_TEMPLATE(ALfloat, point32)
181
DECL_TEMPLATE(ALfloat, lerp32)
182
DECL_TEMPLATE(ALfloat, cubic32)
184
DECL_TEMPLATE(ALshort, point16)
185
DECL_TEMPLATE(ALshort, lerp16)
186
DECL_TEMPLATE(ALshort, cubic16)
188
DECL_TEMPLATE(ALubyte, point8)
189
DECL_TEMPLATE(ALubyte, lerp8)
190
DECL_TEMPLATE(ALubyte, cubic8)
195
#define DECL_TEMPLATE(T, chnct, sampler) \
196
static void Mix_##T##_##chnct##_##sampler(ALsource *Source, ALCdevice *Device,\
197
const T *data, ALuint *DataPosInt, ALuint *DataPosFrac, \
198
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) \
200
const ALuint Channels = chnct; \
201
const ALfloat scaler = 1.0f/chnct; \
202
ALfloat (*DryBuffer)[MAXCHANNELS]; \
203
ALfloat *ClickRemoval, *PendingClicks; \
204
319
ALuint pos, frac; \
205
ALfloat DrySend[chnct][MAXCHANNELS]; \
207
320
ALuint BufferIdx; \
208
321
ALuint increment; \
209
322
ALuint i, out, c; \
215
328
ClickRemoval = Device->ClickRemoval; \
216
329
PendingClicks = Device->PendingClicks; \
217
330
DryFilter = &Source->Params.iirFilter; \
218
for(i = 0;i < Channels;i++) \
220
for(c = 0;c < MAXCHANNELS;c++) \
221
DrySend[i][c] = Source->Params.DryGains[i][c]; \
225
333
frac = *DataPosFrac; \
229
for(i = 0;i < Channels;i++) \
231
value = sampler(data + pos*Channels + i, Channels, frac); \
233
value = lpFilter2PC(DryFilter, i*2, value); \
234
for(c = 0;c < MAXCHANNELS;c++) \
235
ClickRemoval[c] -= value*DrySend[i][c]; \
238
for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \
240
for(i = 0;i < Channels;i++) \
242
value = sampler(data + pos*Channels + i, Channels, frac); \
244
value = lpFilter2P(DryFilter, i*2, value); \
245
for(c = 0;c < MAXCHANNELS;c++) \
246
DryBuffer[OutPos][c] += value*DrySend[i][c]; \
250
pos += frac>>FRACTIONBITS; \
251
frac &= FRACTIONMASK; \
254
if(OutPos == SamplesToDo) \
256
for(i = 0;i < Channels;i++) \
258
value = sampler(data + pos*Channels + i, Channels, frac); \
260
value = lpFilter2PC(DryFilter, i*2, value); \
261
for(c = 0;c < MAXCHANNELS;c++) \
262
PendingClicks[c] += value*DrySend[i][c]; \
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; \
266
375
for(out = 0;out < Device->NumAuxSends;out++) \
377
ALeffectslot *Slot = Source->Params.Send[out].Slot; \
268
378
ALfloat WetSend; \
269
379
ALfloat *WetBuffer; \
270
380
ALfloat *WetClickRemoval; \
271
381
ALfloat *WetPendingClicks; \
272
382
FILTER *WetFilter; \
274
if(!Source->Send[out].Slot || \
275
Source->Send[out].Slot->effect.type == AL_EFFECT_NULL) \
278
WetBuffer = Source->Send[out].Slot->WetBuffer; \
279
WetClickRemoval = Source->Send[out].Slot->ClickRemoval; \
280
WetPendingClicks = Source->Send[out].Slot->PendingClicks; \
387
WetBuffer = Slot->WetBuffer; \
388
WetClickRemoval = Slot->ClickRemoval; \
389
WetPendingClicks = Slot->PendingClicks; \
281
390
WetFilter = &Source->Params.Send[out].iirFilter; \
282
391
WetSend = Source->Params.Send[out].WetGain; \
285
frac = *DataPosFrac; \
286
OutPos -= BufferSize; \
393
for(i = 0;i < NumChannels;i++) \
290
for(i = 0;i < Channels;i++) \
396
frac = *DataPosFrac; \
292
value = sampler(data + pos*Channels + i, Channels, frac); \
400
value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
294
402
value = lpFilter1PC(WetFilter, i, value); \
295
WetClickRemoval[0] -= value*WetSend * scaler; \
403
WetClickRemoval[0] -= value * WetSend; \
298
for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \
300
for(i = 0;i < Channels;i++) \
405
for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \
302
value = sampler(data + pos*Channels + i, Channels, frac); \
407
value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
304
409
value = lpFilter1P(WetFilter, i, value); \
305
WetBuffer[OutPos] += value*WetSend * scaler; \
410
WetBuffer[OutPos] += value * WetSend; \
413
pos += frac>>FRACTIONBITS; \
414
frac &= FRACTIONMASK; \
309
pos += frac>>FRACTIONBITS; \
310
frac &= FRACTIONMASK; \
313
if(OutPos == SamplesToDo) \
315
for(i = 0;i < Channels;i++) \
417
if(OutPos == SamplesToDo) \
317
value = sampler(data + pos*Channels + i, Channels, frac); \
419
value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
319
421
value = lpFilter1PC(WetFilter, i, value); \
320
WetPendingClicks[0] += value*WetSend * scaler; \
422
WetPendingClicks[0] += value * WetSend; \
424
OutPos -= BufferSize; \
324
427
*DataPosInt += pos; \
325
428
*DataPosFrac = frac; \
328
DECL_TEMPLATE(ALfloat, 2, point32)
329
DECL_TEMPLATE(ALfloat, 2, lerp32)
330
DECL_TEMPLATE(ALfloat, 2, cubic32)
332
DECL_TEMPLATE(ALshort, 2, point16)
333
DECL_TEMPLATE(ALshort, 2, lerp16)
334
DECL_TEMPLATE(ALshort, 2, cubic16)
336
DECL_TEMPLATE(ALubyte, 2, point8)
337
DECL_TEMPLATE(ALubyte, 2, lerp8)
338
DECL_TEMPLATE(ALubyte, 2, cubic8)
341
DECL_TEMPLATE(ALfloat, 4, point32)
342
DECL_TEMPLATE(ALfloat, 4, lerp32)
343
DECL_TEMPLATE(ALfloat, 4, cubic32)
345
DECL_TEMPLATE(ALshort, 4, point16)
346
DECL_TEMPLATE(ALshort, 4, lerp16)
347
DECL_TEMPLATE(ALshort, 4, cubic16)
349
DECL_TEMPLATE(ALubyte, 4, point8)
350
DECL_TEMPLATE(ALubyte, 4, lerp8)
351
DECL_TEMPLATE(ALubyte, 4, cubic8)
354
DECL_TEMPLATE(ALfloat, 6, point32)
355
DECL_TEMPLATE(ALfloat, 6, lerp32)
356
DECL_TEMPLATE(ALfloat, 6, cubic32)
358
DECL_TEMPLATE(ALshort, 6, point16)
359
DECL_TEMPLATE(ALshort, 6, lerp16)
360
DECL_TEMPLATE(ALshort, 6, cubic16)
362
DECL_TEMPLATE(ALubyte, 6, point8)
363
DECL_TEMPLATE(ALubyte, 6, lerp8)
364
DECL_TEMPLATE(ALubyte, 6, cubic8)
367
DECL_TEMPLATE(ALfloat, 7, point32)
368
DECL_TEMPLATE(ALfloat, 7, lerp32)
369
DECL_TEMPLATE(ALfloat, 7, cubic32)
371
DECL_TEMPLATE(ALshort, 7, point16)
372
DECL_TEMPLATE(ALshort, 7, lerp16)
373
DECL_TEMPLATE(ALshort, 7, cubic16)
375
DECL_TEMPLATE(ALubyte, 7, point8)
376
DECL_TEMPLATE(ALubyte, 7, lerp8)
377
DECL_TEMPLATE(ALubyte, 7, cubic8)
380
DECL_TEMPLATE(ALfloat, 8, point32)
381
DECL_TEMPLATE(ALfloat, 8, lerp32)
382
DECL_TEMPLATE(ALfloat, 8, cubic32)
384
DECL_TEMPLATE(ALshort, 8, point16)
385
DECL_TEMPLATE(ALshort, 8, lerp16)
386
DECL_TEMPLATE(ALshort, 8, cubic16)
388
DECL_TEMPLATE(ALubyte, 8, point8)
389
DECL_TEMPLATE(ALubyte, 8, lerp8)
390
DECL_TEMPLATE(ALubyte, 8, cubic8)
395
#define DECL_TEMPLATE(T, sampler) \
396
static void Mix_##T##_##sampler(ALsource *Source, ALCdevice *Device, \
397
enum FmtChannels FmtChannels, \
398
const ALvoid *Data, ALuint *DataPosInt, ALuint *DataPosFrac, \
399
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) \
401
switch(FmtChannels) \
404
Mix_##T##_1_##sampler(Source, Device, Data, DataPosInt, DataPosFrac, \
405
OutPos, SamplesToDo, BufferSize); \
409
Mix_##T##_2_##sampler(Source, Device, Data, DataPosInt, DataPosFrac, \
410
OutPos, SamplesToDo, BufferSize); \
413
Mix_##T##_4_##sampler(Source, Device, Data, DataPosInt, DataPosFrac, \
414
OutPos, SamplesToDo, BufferSize); \
417
Mix_##T##_6_##sampler(Source, Device, Data, DataPosInt, DataPosFrac, \
418
OutPos, SamplesToDo, BufferSize); \
421
Mix_##T##_7_##sampler(Source, Device, Data, DataPosInt, DataPosFrac, \
422
OutPos, SamplesToDo, BufferSize); \
425
Mix_##T##_8_##sampler(Source, Device, Data, DataPosInt, DataPosFrac, \
426
OutPos, SamplesToDo, BufferSize); \
431
431
DECL_TEMPLATE(ALfloat, point32)
432
432
DECL_TEMPLATE(ALfloat, lerp32)
433
433
DECL_TEMPLATE(ALfloat, cubic32)
435
DECL_TEMPLATE(ALshort, point16)
436
DECL_TEMPLATE(ALshort, lerp16)
437
DECL_TEMPLATE(ALshort, cubic16)
439
DECL_TEMPLATE(ALubyte, point8)
440
DECL_TEMPLATE(ALubyte, lerp8)
441
DECL_TEMPLATE(ALubyte, cubic8)
443
435
#undef DECL_TEMPLATE
446
#define DECL_TEMPLATE(sampler) \
447
static void Mix_##sampler(ALsource *Source, ALCdevice *Device, \
448
enum FmtChannels FmtChannels, enum FmtType FmtType, \
449
const ALvoid *Data, ALuint *DataPosInt, ALuint *DataPosFrac, \
450
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) \
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
static __inline ALfloat Sample_ALbyte(ALbyte val)
472
{ return val * (1.0f/127.0f); }
474
static __inline ALfloat Sample_ALshort(ALshort val)
475
{ return val * (1.0f/32767.0f); }
477
static __inline ALfloat Sample_ALfloat(ALfloat val)
480
#define DECL_TEMPLATE(T) \
481
static void Load_##T(ALfloat *dst, const T *src, ALuint samples) \
455
Mix_ALubyte_##sampler##8(Source, Device, FmtChannels, \
456
Data, DataPosInt, DataPosFrac, \
457
OutPos, SamplesToDo, BufferSize); \
461
Mix_ALshort_##sampler##16(Source, Device, FmtChannels, \
462
Data, DataPosInt, DataPosFrac, \
463
OutPos, SamplesToDo, BufferSize); \
467
Mix_ALfloat_##sampler##32(Source, Device, FmtChannels, \
468
Data, DataPosInt, DataPosFrac, \
469
OutPos, SamplesToDo, BufferSize); \
484
for(i = 0;i < samples;i++) \
485
dst[i] = Sample_##T(src[i]); \
488
DECL_TEMPLATE(ALbyte)
489
DECL_TEMPLATE(ALshort)
490
DECL_TEMPLATE(ALfloat)
478
492
#undef DECL_TEMPLATE
494
static void LoadStack(ALfloat *dst, const ALvoid *src, enum FmtType srctype, ALuint samples)
499
Load_ALbyte(dst, src, samples);
502
Load_ALshort(dst, src, samples);
505
Load_ALfloat(dst, src, samples);
510
static void SilenceStack(ALfloat *dst, ALuint samples)
513
for(i = 0;i < samples;i++)
481
518
ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
483
520
ALbufferlistitem *BufferListItem;
484
521
ALuint DataPosInt, DataPosFrac;
485
enum FmtChannels FmtChannels;
486
enum FmtType FmtType;
487
522
ALuint BuffersPlayed;
488
523
ALboolean Looping;
489
524
ALuint increment;
490
resampler_t Resampler;
525
enum Resampler Resampler;
493
529
ALuint FrameSize;
494
530
ALint64 DataSize64;