~ubuntu-branches/ubuntu/utopic/openal-soft/utopic

« back to all changes in this revision

Viewing changes to Alc/mixer.c

  • Committer: Package Import Robot
  • Author(s): Michael Terry
  • Date: 2012-05-22 10:14:53 UTC
  • mfrom: (7.1.9 sid)
  • Revision ID: package-import@ubuntu.com-20120522101453-knsv1m1m8vl5ccfp
Tags: 1:1.14-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  - Add a symbols file for libopenal1
* debian/libopenal1.symbols:
  - Update for 1.14

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
#include "bs2b.h"
38
38
 
39
39
 
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)); }
47
 
 
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); }
55
 
 
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); }
64
 
 
 
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)); }
 
47
 
 
48
#ifdef __GNUC__
 
49
#define LIKELY(x) __builtin_expect(!!(x), 1)
 
50
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
 
51
#else
 
52
#define LIKELY(x) (x)
 
53
#define UNLIKELY(x) (x)
 
54
#endif
 
55
 
 
56
#if defined(__ARM_NEON__) && defined(HAVE_ARM_NEON_H)
 
57
#include <arm_neon.h>
 
58
 
 
59
static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2],
 
60
                                 ALfloat (*RESTRICT Coeffs)[2],
 
61
                                 ALfloat left, ALfloat right)
 
62
{
 
63
    ALuint c;
 
64
    float32x4_t leftright4;
 
65
    {
 
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);
 
70
    }
 
71
    for(c = 0;c < HRIR_LENGTH;c += 2)
 
72
    {
 
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]);
 
78
 
 
79
        vals = vmlaq_f32(vals, coefs, leftright4);
 
80
 
 
81
        vst1_f32((float32_t*)&Values[o0][0], vget_low_f32(vals));
 
82
        vst1_f32((float32_t*)&Values[o1][0], vget_high_f32(vals));
 
83
    }
 
84
}
 
85
 
 
86
#else
 
87
 
 
88
static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2],
 
89
                                 ALfloat (*RESTRICT Coeffs)[2],
 
90
                                 ALfloat left, ALfloat right)
 
91
{
 
92
    ALuint c;
 
93
    for(c = 0;c < HRIR_LENGTH;c++)
 
94
    {
 
95
        const ALuint off = (Offset+c)&HRIR_MASK;
 
96
        Values[off][0] += Coeffs[c][0] * left;
 
97
        Values[off][1] += Coeffs[c][1] * right;
 
98
    }
 
99
}
 
100
 
 
101
#endif
65
102
 
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)                       \
70
107
{                                                                             \
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;                                                         \
 
115
    FILTER *DryFilter;                                                        \
 
116
    ALuint BufferIdx;                                                         \
 
117
    ALuint increment;                                                         \
 
118
    ALuint i, out, c;                                                         \
 
119
    ALfloat value;                                                            \
 
120
                                                                              \
 
121
    increment = Source->Params.Step;                                          \
 
122
                                                                              \
 
123
    DryBuffer = Device->DryBuffer;                                            \
 
124
    ClickRemoval = Device->ClickRemoval;                                      \
 
125
    PendingClicks = Device->PendingClicks;                                    \
 
126
    DryFilter = &Source->Params.iirFilter;                                    \
 
127
                                                                              \
 
128
    pos = 0;                                                                  \
 
129
    frac = *DataPosFrac;                                                      \
 
130
                                                                              \
 
131
    for(i = 0;i < NumChannels;i++)                                            \
 
132
    {                                                                         \
 
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];                                       \
 
140
        ALuint Delay[2];                                                      \
 
141
        ALfloat left, right;                                                  \
 
142
                                                                              \
 
143
        pos = 0;                                                              \
 
144
        frac = *DataPosFrac;                                                  \
 
145
                                                                              \
 
146
        for(c = 0;c < HRIR_LENGTH;c++)                                        \
 
147
        {                                                                     \
 
148
            Coeffs[c][0] = TargetCoeffs[c][0] - (CoeffStep[c][0]*Counter);    \
 
149
            Coeffs[c][1] = TargetCoeffs[c][1] - (CoeffStep[c][1]*Counter);    \
 
150
        }                                                                     \
 
151
                                                                              \
 
152
        Delay[0] = TargetDelay[0] - (DelayStep[0]*Counter) + 32768;           \
 
153
        Delay[1] = TargetDelay[1] - (DelayStep[1]*Counter) + 32768;           \
 
154
                                                                              \
 
155
        if(LIKELY(OutPos == 0))                                               \
 
156
        {                                                                     \
 
157
            value = sampler(data + pos*NumChannels + i, NumChannels, frac);   \
 
158
            value = lpFilter2PC(DryFilter, i, value);                         \
 
159
                                                                              \
 
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];        \
 
163
                                                                              \
 
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;                \
 
168
        }                                                                     \
 
169
        for(BufferIdx = 0;BufferIdx < BufferSize && Counter > 0;BufferIdx++)  \
 
170
        {                                                                     \
 
171
            value = sampler(data + pos*NumChannels + i, NumChannels, frac);   \
 
172
            value = lpFilter2P(DryFilter, i, value);                          \
 
173
                                                                              \
 
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];        \
 
177
                                                                              \
 
178
            Delay[0] += DelayStep[0];                                         \
 
179
            Delay[1] += DelayStep[1];                                         \
 
180
                                                                              \
 
181
            Values[Offset&HRIR_MASK][0] = 0.0f;                               \
 
182
            Values[Offset&HRIR_MASK][1] = 0.0f;                               \
 
183
            Offset++;                                                         \
 
184
                                                                              \
 
185
            for(c = 0;c < HRIR_LENGTH;c++)                                    \
 
186
            {                                                                 \
 
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];                              \
 
192
            }                                                                 \
 
193
                                                                              \
 
194
            DryBuffer[OutPos][FRONT_LEFT]  += Values[Offset&HRIR_MASK][0];    \
 
195
            DryBuffer[OutPos][FRONT_RIGHT] += Values[Offset&HRIR_MASK][1];    \
 
196
                                                                              \
 
197
            frac += increment;                                                \
 
198
            pos  += frac>>FRACTIONBITS;                                       \
 
199
            frac &= FRACTIONMASK;                                             \
 
200
            OutPos++;                                                         \
 
201
            Counter--;                                                        \
 
202
        }                                                                     \
 
203
                                                                              \
 
204
        Delay[0] >>= 16;                                                      \
 
205
        Delay[1] >>= 16;                                                      \
 
206
        for(;BufferIdx < BufferSize;BufferIdx++)                              \
 
207
        {                                                                     \
 
208
            value = sampler(data + pos*NumChannels + i, NumChannels, frac);   \
 
209
            value = lpFilter2P(DryFilter, i, value);                          \
 
210
                                                                              \
 
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];              \
 
214
                                                                              \
 
215
            Values[Offset&HRIR_MASK][0] = 0.0f;                               \
 
216
            Values[Offset&HRIR_MASK][1] = 0.0f;                               \
 
217
            Offset++;                                                         \
 
218
                                                                              \
 
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];    \
 
222
                                                                              \
 
223
            frac += increment;                                                \
 
224
            pos  += frac>>FRACTIONBITS;                                       \
 
225
            frac &= FRACTIONMASK;                                             \
 
226
            OutPos++;                                                         \
 
227
        }                                                                     \
 
228
        if(LIKELY(OutPos == SamplesToDo))                                     \
 
229
        {                                                                     \
 
230
            value = sampler(data + pos*NumChannels + i, NumChannels, frac);   \
 
231
            value = lpFilter2PC(DryFilter, i, value);                         \
 
232
                                                                              \
 
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];              \
 
236
                                                                              \
 
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;               \
 
241
        }                                                                     \
 
242
        OutPos -= BufferSize;                                                 \
 
243
    }                                                                         \
 
244
                                                                              \
 
245
    for(out = 0;out < Device->NumAuxSends;out++)                              \
 
246
    {                                                                         \
 
247
        ALeffectslot *Slot = Source->Params.Send[out].Slot;                   \
 
248
        ALfloat  WetSend;                                                     \
 
249
        ALfloat *RESTRICT WetBuffer;                                          \
 
250
        ALfloat *RESTRICT WetClickRemoval;                                    \
 
251
        ALfloat *RESTRICT WetPendingClicks;                                   \
 
252
        FILTER  *WetFilter;                                                   \
 
253
                                                                              \
 
254
        if(Slot == NULL)                                                      \
 
255
            continue;                                                         \
 
256
                                                                              \
 
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;                           \
 
262
                                                                              \
 
263
        for(i = 0;i < NumChannels;i++)                                        \
 
264
        {                                                                     \
 
265
            pos = 0;                                                          \
 
266
            frac = *DataPosFrac;                                              \
 
267
                                                                              \
 
268
            if(LIKELY(OutPos == 0))                                           \
 
269
            {                                                                 \
 
270
                value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
 
271
                value = lpFilter1PC(WetFilter, i, value);                     \
 
272
                                                                              \
 
273
                WetClickRemoval[0] -= value * WetSend;                        \
 
274
            }                                                                 \
 
275
            for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++)             \
 
276
            {                                                                 \
 
277
                value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
 
278
                value = lpFilter1P(WetFilter, i, value);                      \
 
279
                                                                              \
 
280
                WetBuffer[OutPos] += value * WetSend;                         \
 
281
                                                                              \
 
282
                frac += increment;                                            \
 
283
                pos  += frac>>FRACTIONBITS;                                   \
 
284
                frac &= FRACTIONMASK;                                         \
 
285
                OutPos++;                                                     \
 
286
            }                                                                 \
 
287
            if(LIKELY(OutPos == SamplesToDo))                                 \
 
288
            {                                                                 \
 
289
                value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
 
290
                value = lpFilter1PC(WetFilter, i, value);                     \
 
291
                                                                              \
 
292
                WetPendingClicks[0] += value * WetSend;                       \
 
293
            }                                                                 \
 
294
            OutPos -= BufferSize;                                             \
 
295
        }                                                                     \
 
296
    }                                                                         \
 
297
    *DataPosInt += pos;                                                       \
 
298
    *DataPosFrac = frac;                                                      \
 
299
}
 
300
 
 
301
DECL_TEMPLATE(ALfloat, point32)
 
302
DECL_TEMPLATE(ALfloat, lerp32)
 
303
DECL_TEMPLATE(ALfloat, cubic32)
 
304
 
 
305
#undef DECL_TEMPLATE
 
306
 
 
307
 
 
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)                       \
 
312
{                                                                             \
 
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;                                                        \
76
 
    ALuint BufferIdx;                                                         \
77
 
    ALuint increment;                                                         \
78
 
    ALuint out, c;                                                            \
79
 
    ALfloat value;                                                            \
80
 
                                                                              \
81
 
    increment = Source->Params.Step;                                          \
82
 
                                                                              \
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];                           \
89
 
                                                                              \
90
 
    pos = 0;                                                                  \
91
 
    frac = *DataPosFrac;                                                      \
92
 
                                                                              \
93
 
    if(OutPos == 0)                                                           \
94
 
    {                                                                         \
95
 
        value = sampler(data+pos, 1, frac);                                   \
96
 
                                                                              \
97
 
        value = lpFilter4PC(DryFilter, 0, value);                             \
98
 
        for(c = 0;c < MAXCHANNELS;c++)                                        \
99
 
            ClickRemoval[c] -= value*DrySend[c];                              \
100
 
    }                                                                         \
101
 
    for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++)                     \
102
 
    {                                                                         \
103
 
        /* First order interpolator */                                        \
104
 
        value = sampler(data+pos, 1, frac);                                   \
105
 
                                                                              \
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];                         \
110
 
                                                                              \
111
 
        frac += increment;                                                    \
112
 
        pos  += frac>>FRACTIONBITS;                                           \
113
 
        frac &= FRACTIONMASK;                                                 \
114
 
        OutPos++;                                                             \
115
 
    }                                                                         \
116
 
    if(OutPos == SamplesToDo)                                                 \
117
 
    {                                                                         \
118
 
        value = sampler(data+pos, 1, frac);                                   \
119
 
                                                                              \
120
 
        value = lpFilter4PC(DryFilter, 0, value);                             \
121
 
        for(c = 0;c < MAXCHANNELS;c++)                                        \
122
 
            PendingClicks[c] += value*DrySend[c];                             \
123
 
    }                                                                         \
124
 
                                                                              \
125
 
    for(out = 0;out < Device->NumAuxSends;out++)                              \
126
 
    {                                                                         \
127
 
        ALfloat  WetSend;                                                     \
128
 
        ALfloat *WetBuffer;                                                   \
129
 
        ALfloat *WetClickRemoval;                                             \
130
 
        ALfloat *WetPendingClicks;                                            \
131
 
        FILTER  *WetFilter;                                                   \
132
 
                                                                              \
133
 
        if(!Source->Send[out].Slot ||                                         \
134
 
           Source->Send[out].Slot->effect.type == AL_EFFECT_NULL)             \
135
 
            continue;                                                         \
136
 
                                                                              \
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;                           \
142
 
                                                                              \
143
 
        pos = 0;                                                              \
144
 
        frac = *DataPosFrac;                                                  \
145
 
        OutPos -= BufferSize;                                                 \
146
 
                                                                              \
147
 
        if(OutPos == 0)                                                       \
148
 
        {                                                                     \
149
 
            value = sampler(data+pos, 1, frac);                               \
150
 
                                                                              \
151
 
            value = lpFilter2PC(WetFilter, 0, value);                         \
152
 
            WetClickRemoval[0] -= value*WetSend;                              \
153
 
        }                                                                     \
154
 
        for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++)                 \
155
 
        {                                                                     \
156
 
            /* First order interpolator */                                    \
157
 
            value = sampler(data+pos, 1, frac);                               \
158
 
                                                                              \
159
 
            /* Room path final mix buffer and panning */                      \
160
 
            value = lpFilter2P(WetFilter, 0, value);                          \
161
 
            WetBuffer[OutPos] += value*WetSend;                               \
162
 
                                                                              \
163
 
            frac += increment;                                                \
164
 
            pos  += frac>>FRACTIONBITS;                                       \
165
 
            frac &= FRACTIONMASK;                                             \
166
 
            OutPos++;                                                         \
167
 
        }                                                                     \
168
 
        if(OutPos == SamplesToDo)                                             \
169
 
        {                                                                     \
170
 
            value = sampler(data+pos, 1, frac);                               \
171
 
                                                                              \
172
 
            value = lpFilter2PC(WetFilter, 0, value);                         \
173
 
            WetPendingClicks[0] += value*WetSend;                             \
174
 
        }                                                                     \
175
 
    }                                                                         \
176
 
    *DataPosInt += pos;                                                       \
177
 
    *DataPosFrac = frac;                                                      \
178
 
}
179
 
 
180
 
DECL_TEMPLATE(ALfloat, point32)
181
 
DECL_TEMPLATE(ALfloat, lerp32)
182
 
DECL_TEMPLATE(ALfloat, cubic32)
183
 
 
184
 
DECL_TEMPLATE(ALshort, point16)
185
 
DECL_TEMPLATE(ALshort, lerp16)
186
 
DECL_TEMPLATE(ALshort, cubic16)
187
 
 
188
 
DECL_TEMPLATE(ALubyte, point8)
189
 
DECL_TEMPLATE(ALubyte, lerp8)
190
 
DECL_TEMPLATE(ALubyte, cubic8)
191
 
 
192
 
#undef DECL_TEMPLATE
193
 
 
194
 
 
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)                       \
199
 
{                                                                             \
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];                                      \
206
 
    FILTER *DryFilter;                                                        \
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++)                                               \
219
 
    {                                                                         \
220
 
        for(c = 0;c < MAXCHANNELS;c++)                                        \
221
 
            DrySend[i][c] = Source->Params.DryGains[i][c];                    \
222
 
    }                                                                         \
223
331
                                                                              \
224
332
    pos = 0;                                                                  \
225
333
    frac = *DataPosFrac;                                                      \
226
334
                                                                              \
227
 
    if(OutPos == 0)                                                           \
228
 
    {                                                                         \
229
 
        for(i = 0;i < Channels;i++)                                           \
230
 
        {                                                                     \
231
 
            value = sampler(data + pos*Channels + i, Channels, frac);         \
232
 
                                                                              \
233
 
            value = lpFilter2PC(DryFilter, i*2, value);                       \
234
 
            for(c = 0;c < MAXCHANNELS;c++)                                    \
235
 
                ClickRemoval[c] -= value*DrySend[i][c];                       \
236
 
        }                                                                     \
237
 
    }                                                                         \
238
 
    for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++)                     \
239
 
    {                                                                         \
240
 
        for(i = 0;i < Channels;i++)                                           \
241
 
        {                                                                     \
242
 
            value = sampler(data + pos*Channels + i, Channels, frac);         \
243
 
                                                                              \
244
 
            value = lpFilter2P(DryFilter, i*2, value);                        \
245
 
            for(c = 0;c < MAXCHANNELS;c++)                                    \
246
 
                DryBuffer[OutPos][c] += value*DrySend[i][c];                  \
247
 
        }                                                                     \
248
 
                                                                              \
249
 
        frac += increment;                                                    \
250
 
        pos  += frac>>FRACTIONBITS;                                           \
251
 
        frac &= FRACTIONMASK;                                                 \
252
 
        OutPos++;                                                             \
253
 
    }                                                                         \
254
 
    if(OutPos == SamplesToDo)                                                 \
255
 
    {                                                                         \
256
 
        for(i = 0;i < Channels;i++)                                           \
257
 
        {                                                                     \
258
 
            value = sampler(data + pos*Channels + i, Channels, frac);         \
259
 
                                                                              \
260
 
            value = lpFilter2PC(DryFilter, i*2, value);                       \
261
 
            for(c = 0;c < MAXCHANNELS;c++)                                    \
262
 
                PendingClicks[c] += value*DrySend[i][c];                      \
263
 
        }                                                                     \
 
335
    for(i = 0;i < NumChannels;i++)                                            \
 
336
    {                                                                         \
 
337
        for(c = 0;c < MAXCHANNELS;c++)                                        \
 
338
            DrySend[c] = Source->Params.DryGains[i][c];                       \
 
339
                                                                              \
 
340
        pos = 0;                                                              \
 
341
        frac = *DataPosFrac;                                                  \
 
342
                                                                              \
 
343
        if(OutPos == 0)                                                       \
 
344
        {                                                                     \
 
345
            value = sampler(data + pos*NumChannels + i, NumChannels, frac);   \
 
346
                                                                              \
 
347
            value = lpFilter2PC(DryFilter, i, value);                         \
 
348
            for(c = 0;c < MAXCHANNELS;c++)                                    \
 
349
                ClickRemoval[c] -= value*DrySend[c];                          \
 
350
        }                                                                     \
 
351
        for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++)                 \
 
352
        {                                                                     \
 
353
            value = sampler(data + pos*NumChannels + i, NumChannels, frac);   \
 
354
                                                                              \
 
355
            value = lpFilter2P(DryFilter, i, value);                          \
 
356
            for(c = 0;c < MAXCHANNELS;c++)                                    \
 
357
                DryBuffer[OutPos][c] += value*DrySend[c];                     \
 
358
                                                                              \
 
359
            frac += increment;                                                \
 
360
            pos  += frac>>FRACTIONBITS;                                       \
 
361
            frac &= FRACTIONMASK;                                             \
 
362
            OutPos++;                                                         \
 
363
        }                                                                     \
 
364
        if(OutPos == SamplesToDo)                                             \
 
365
        {                                                                     \
 
366
            value = sampler(data + pos*NumChannels + i, NumChannels, frac);   \
 
367
                                                                              \
 
368
            value = lpFilter2PC(DryFilter, i, value);                         \
 
369
            for(c = 0;c < MAXCHANNELS;c++)                                    \
 
370
                PendingClicks[c] += value*DrySend[c];                         \
 
371
        }                                                                     \
 
372
        OutPos -= BufferSize;                                                 \
264
373
    }                                                                         \
265
374
                                                                              \
266
375
    for(out = 0;out < Device->NumAuxSends;out++)                              \
267
376
    {                                                                         \
 
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;                                                   \
273
383
                                                                              \
274
 
        if(!Source->Send[out].Slot ||                                         \
275
 
           Source->Send[out].Slot->effect.type == AL_EFFECT_NULL)             \
 
384
        if(Slot == NULL)                                                      \
276
385
            continue;                                                         \
277
386
                                                                              \
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;                           \
283
392
                                                                              \
284
 
        pos = 0;                                                              \
285
 
        frac = *DataPosFrac;                                                  \
286
 
        OutPos -= BufferSize;                                                 \
287
 
                                                                              \
288
 
        if(OutPos == 0)                                                       \
 
393
        for(i = 0;i < NumChannels;i++)                                        \
289
394
        {                                                                     \
290
 
            for(i = 0;i < Channels;i++)                                       \
 
395
            pos = 0;                                                          \
 
396
            frac = *DataPosFrac;                                              \
 
397
                                                                              \
 
398
            if(OutPos == 0)                                                   \
291
399
            {                                                                 \
292
 
                value = sampler(data + pos*Channels + i, Channels, frac);     \
 
400
                value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
293
401
                                                                              \
294
402
                value = lpFilter1PC(WetFilter, i, value);                     \
295
 
                WetClickRemoval[0] -= value*WetSend * scaler;                 \
 
403
                WetClickRemoval[0] -= value * WetSend;                        \
296
404
            }                                                                 \
297
 
        }                                                                     \
298
 
        for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++)                 \
299
 
        {                                                                     \
300
 
            for(i = 0;i < Channels;i++)                                       \
 
405
            for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++)             \
301
406
            {                                                                 \
302
 
                value = sampler(data + pos*Channels + i, Channels, frac);     \
 
407
                value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
303
408
                                                                              \
304
409
                value = lpFilter1P(WetFilter, i, value);                      \
305
 
                WetBuffer[OutPos] += value*WetSend * scaler;                  \
 
410
                WetBuffer[OutPos] += value * WetSend;                         \
 
411
                                                                              \
 
412
                frac += increment;                                            \
 
413
                pos  += frac>>FRACTIONBITS;                                   \
 
414
                frac &= FRACTIONMASK;                                         \
 
415
                OutPos++;                                                     \
306
416
            }                                                                 \
307
 
                                                                              \
308
 
            frac += increment;                                                \
309
 
            pos  += frac>>FRACTIONBITS;                                       \
310
 
            frac &= FRACTIONMASK;                                             \
311
 
            OutPos++;                                                         \
312
 
        }                                                                     \
313
 
        if(OutPos == SamplesToDo)                                             \
314
 
        {                                                                     \
315
 
            for(i = 0;i < Channels;i++)                                       \
 
417
            if(OutPos == SamplesToDo)                                         \
316
418
            {                                                                 \
317
 
                value = sampler(data + pos*Channels + i, Channels, frac);     \
 
419
                value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
318
420
                                                                              \
319
421
                value = lpFilter1PC(WetFilter, i, value);                     \
320
 
                WetPendingClicks[0] += value*WetSend * scaler;                \
 
422
                WetPendingClicks[0] += value * WetSend;                       \
321
423
            }                                                                 \
 
424
            OutPos -= BufferSize;                                             \
322
425
        }                                                                     \
323
426
    }                                                                         \
324
427
    *DataPosInt += pos;                                                       \
325
428
    *DataPosFrac = frac;                                                      \
326
429
}
327
430
 
328
 
DECL_TEMPLATE(ALfloat, 2, point32)
329
 
DECL_TEMPLATE(ALfloat, 2, lerp32)
330
 
DECL_TEMPLATE(ALfloat, 2, cubic32)
331
 
 
332
 
DECL_TEMPLATE(ALshort, 2, point16)
333
 
DECL_TEMPLATE(ALshort, 2, lerp16)
334
 
DECL_TEMPLATE(ALshort, 2, cubic16)
335
 
 
336
 
DECL_TEMPLATE(ALubyte, 2, point8)
337
 
DECL_TEMPLATE(ALubyte, 2, lerp8)
338
 
DECL_TEMPLATE(ALubyte, 2, cubic8)
339
 
 
340
 
 
341
 
DECL_TEMPLATE(ALfloat, 4, point32)
342
 
DECL_TEMPLATE(ALfloat, 4, lerp32)
343
 
DECL_TEMPLATE(ALfloat, 4, cubic32)
344
 
 
345
 
DECL_TEMPLATE(ALshort, 4, point16)
346
 
DECL_TEMPLATE(ALshort, 4, lerp16)
347
 
DECL_TEMPLATE(ALshort, 4, cubic16)
348
 
 
349
 
DECL_TEMPLATE(ALubyte, 4, point8)
350
 
DECL_TEMPLATE(ALubyte, 4, lerp8)
351
 
DECL_TEMPLATE(ALubyte, 4, cubic8)
352
 
 
353
 
 
354
 
DECL_TEMPLATE(ALfloat, 6, point32)
355
 
DECL_TEMPLATE(ALfloat, 6, lerp32)
356
 
DECL_TEMPLATE(ALfloat, 6, cubic32)
357
 
 
358
 
DECL_TEMPLATE(ALshort, 6, point16)
359
 
DECL_TEMPLATE(ALshort, 6, lerp16)
360
 
DECL_TEMPLATE(ALshort, 6, cubic16)
361
 
 
362
 
DECL_TEMPLATE(ALubyte, 6, point8)
363
 
DECL_TEMPLATE(ALubyte, 6, lerp8)
364
 
DECL_TEMPLATE(ALubyte, 6, cubic8)
365
 
 
366
 
 
367
 
DECL_TEMPLATE(ALfloat, 7, point32)
368
 
DECL_TEMPLATE(ALfloat, 7, lerp32)
369
 
DECL_TEMPLATE(ALfloat, 7, cubic32)
370
 
 
371
 
DECL_TEMPLATE(ALshort, 7, point16)
372
 
DECL_TEMPLATE(ALshort, 7, lerp16)
373
 
DECL_TEMPLATE(ALshort, 7, cubic16)
374
 
 
375
 
DECL_TEMPLATE(ALubyte, 7, point8)
376
 
DECL_TEMPLATE(ALubyte, 7, lerp8)
377
 
DECL_TEMPLATE(ALubyte, 7, cubic8)
378
 
 
379
 
 
380
 
DECL_TEMPLATE(ALfloat, 8, point32)
381
 
DECL_TEMPLATE(ALfloat, 8, lerp32)
382
 
DECL_TEMPLATE(ALfloat, 8, cubic32)
383
 
 
384
 
DECL_TEMPLATE(ALshort, 8, point16)
385
 
DECL_TEMPLATE(ALshort, 8, lerp16)
386
 
DECL_TEMPLATE(ALshort, 8, cubic16)
387
 
 
388
 
DECL_TEMPLATE(ALubyte, 8, point8)
389
 
DECL_TEMPLATE(ALubyte, 8, lerp8)
390
 
DECL_TEMPLATE(ALubyte, 8, cubic8)
391
 
 
392
 
#undef DECL_TEMPLATE
393
 
 
394
 
 
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)                       \
400
 
{                                                                             \
401
 
    switch(FmtChannels)                                                       \
402
 
    {                                                                         \
403
 
    case FmtMono:                                                             \
404
 
        Mix_##T##_1_##sampler(Source, Device, Data, DataPosInt, DataPosFrac,  \
405
 
                              OutPos, SamplesToDo, BufferSize);               \
406
 
        break;                                                                \
407
 
    case FmtStereo:                                                           \
408
 
    case FmtRear:                                                             \
409
 
        Mix_##T##_2_##sampler(Source, Device, Data, DataPosInt, DataPosFrac,  \
410
 
                              OutPos, SamplesToDo, BufferSize);               \
411
 
        break;                                                                \
412
 
    case FmtQuad:                                                             \
413
 
        Mix_##T##_4_##sampler(Source, Device, Data, DataPosInt, DataPosFrac,  \
414
 
                              OutPos, SamplesToDo, BufferSize);               \
415
 
        break;                                                                \
416
 
    case FmtX51:                                                              \
417
 
        Mix_##T##_6_##sampler(Source, Device, Data, DataPosInt, DataPosFrac,  \
418
 
                              OutPos, SamplesToDo, BufferSize);               \
419
 
        break;                                                                \
420
 
    case FmtX61:                                                              \
421
 
        Mix_##T##_7_##sampler(Source, Device, Data, DataPosInt, DataPosFrac,  \
422
 
                              OutPos, SamplesToDo, BufferSize);               \
423
 
        break;                                                                \
424
 
    case FmtX71:                                                              \
425
 
        Mix_##T##_8_##sampler(Source, Device, Data, DataPosInt, DataPosFrac,  \
426
 
                              OutPos, SamplesToDo, BufferSize);               \
427
 
        break;                                                                \
428
 
    }                                                                         \
429
 
}
430
 
 
431
431
DECL_TEMPLATE(ALfloat, point32)
432
432
DECL_TEMPLATE(ALfloat, lerp32)
433
433
DECL_TEMPLATE(ALfloat, cubic32)
434
434
 
435
 
DECL_TEMPLATE(ALshort, point16)
436
 
DECL_TEMPLATE(ALshort, lerp16)
437
 
DECL_TEMPLATE(ALshort, cubic16)
438
 
 
439
 
DECL_TEMPLATE(ALubyte, point8)
440
 
DECL_TEMPLATE(ALubyte, lerp8)
441
 
DECL_TEMPLATE(ALubyte, cubic8)
442
 
 
443
435
#undef DECL_TEMPLATE
444
436
 
445
437
 
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)
 
439
{
 
440
    switch(Resampler)
 
441
    {
 
442
        case PointResampler:
 
443
            return Mix_ALfloat_point32;
 
444
        case LinearResampler:
 
445
            return Mix_ALfloat_lerp32;
 
446
        case CubicResampler:
 
447
            return Mix_ALfloat_cubic32;
 
448
        case ResamplerMax:
 
449
            break;
 
450
    }
 
451
    return NULL;
 
452
}
 
453
 
 
454
MixerFunc SelectHrtfMixer(enum Resampler Resampler)
 
455
{
 
456
    switch(Resampler)
 
457
    {
 
458
        case PointResampler:
 
459
            return Mix_Hrtf_ALfloat_point32;
 
460
        case LinearResampler:
 
461
            return Mix_Hrtf_ALfloat_lerp32;
 
462
        case CubicResampler:
 
463
            return Mix_Hrtf_ALfloat_cubic32;
 
464
        case ResamplerMax:
 
465
            break;
 
466
    }
 
467
    return NULL;
 
468
}
 
469
 
 
470
 
 
471
static __inline ALfloat Sample_ALbyte(ALbyte val)
 
472
{ return val * (1.0f/127.0f); }
 
473
 
 
474
static __inline ALfloat Sample_ALshort(ALshort val)
 
475
{ return val * (1.0f/32767.0f); }
 
476
 
 
477
static __inline ALfloat Sample_ALfloat(ALfloat val)
 
478
{ return val; }
 
479
 
 
480
#define DECL_TEMPLATE(T)                                                      \
 
481
static void Load_##T(ALfloat *dst, const T *src, ALuint samples)              \
451
482
{                                                                             \
452
 
    switch(FmtType)                                                           \
453
 
    {                                                                         \
454
 
    case FmtUByte:                                                            \
455
 
        Mix_ALubyte_##sampler##8(Source, Device, FmtChannels,                 \
456
 
                                 Data, DataPosInt, DataPosFrac,               \
457
 
                                 OutPos, SamplesToDo, BufferSize);            \
458
 
        break;                                                                \
459
 
                                                                              \
460
 
    case FmtShort:                                                            \
461
 
        Mix_ALshort_##sampler##16(Source, Device, FmtChannels,                \
462
 
                                  Data, DataPosInt, DataPosFrac,              \
463
 
                                  OutPos, SamplesToDo, BufferSize);           \
464
 
        break;                                                                \
465
 
                                                                              \
466
 
    case FmtFloat:                                                            \
467
 
        Mix_ALfloat_##sampler##32(Source, Device, FmtChannels,                \
468
 
                                  Data, DataPosInt, DataPosFrac,              \
469
 
                                  OutPos, SamplesToDo, BufferSize);           \
470
 
        break;                                                                \
471
 
    }                                                                         \
 
483
    ALuint i;                                                                 \
 
484
    for(i = 0;i < samples;i++)                                                \
 
485
        dst[i] = Sample_##T(src[i]);                                          \
472
486
}
473
487
 
474
 
DECL_TEMPLATE(point)
475
 
DECL_TEMPLATE(lerp)
476
 
DECL_TEMPLATE(cubic)
 
488
DECL_TEMPLATE(ALbyte)
 
489
DECL_TEMPLATE(ALshort)
 
490
DECL_TEMPLATE(ALfloat)
477
491
 
478
492
#undef DECL_TEMPLATE
479
493
 
 
494
static void LoadStack(ALfloat *dst, const ALvoid *src, enum FmtType srctype, ALuint samples)
 
495
{
 
496
    switch(srctype)
 
497
    {
 
498
        case FmtByte:
 
499
            Load_ALbyte(dst, src, samples);
 
500
            break;
 
501
        case FmtShort:
 
502
            Load_ALshort(dst, src, samples);
 
503
            break;
 
504
        case FmtFloat:
 
505
            Load_ALfloat(dst, src, samples);
 
506
            break;
 
507
    }
 
508
}
 
509
 
 
510
static void SilenceStack(ALfloat *dst, ALuint samples)
 
511
{
 
512
    ALuint i;
 
513
    for(i = 0;i < samples;i++)
 
514
        dst[i] = 0.0f;
 
515
}
 
516
 
480
517
 
481
518
ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
482
519
{
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;
491
526
    ALenum State;
492
527
    ALuint OutPos;
 
528
    ALuint NumChannels;
493
529
    ALuint FrameSize;
494
530
    ALint64 DataSize64;
495
531
    ALuint i;
501
537
    DataPosFrac   = Source->position_fraction;
502
538
    Looping       = Source->bLooping;
503
539
    increment     = Source->Params.Step;
504
 
    Resampler     = (increment == FRACTIONONE) ? POINT_RESAMPLER :
505
 
                                                 Source->Resampler;
506
 
 
507
 
    /* Get buffer info */
508
 
    FrameSize = 0;
509
 
    FmtChannels = FmtMono;
510
 
    FmtType = FmtUByte;
511
 
    BufferListItem = Source->queue;
512
 
    for(i = 0;i < Source->BuffersInQueue;i++)
513
 
    {
514
 
        const ALbuffer *ALBuffer;
515
 
        if((ALBuffer=BufferListItem->buffer) != NULL)
516
 
        {
517
 
            FmtChannels = ALBuffer->FmtChannels;
518
 
            FmtType = ALBuffer->FmtType;
519
 
            FrameSize = FrameSizeFromFmt(FmtChannels, FmtType);
520
 
            break;
521
 
        }
522
 
        BufferListItem = BufferListItem->next;
523
 
    }
 
540
    Resampler     = Source->Resampler;
 
541
    NumChannels   = Source->NumChannels;
 
542
    FrameSize     = NumChannels * Source->SampleSize;
524
543
 
525
544
    /* Get current buffer queue item */
526
545
    BufferListItem = Source->queue;
531
550
    do {
532
551
        const ALuint BufferPrePadding = ResamplerPrePadding[Resampler];
533
552
        const ALuint BufferPadding = ResamplerPadding[Resampler];
534
 
        ALubyte StackData[STACK_DATA_SIZE];
535
 
        ALubyte *SrcData = StackData;
 
553
        ALfloat StackData[STACK_DATA_SIZE/sizeof(ALfloat)];
 
554
        ALfloat *SrcData = StackData;
536
555
        ALuint SrcDataSize = 0;
537
556
        ALuint BufferSize;
538
557
 
542
561
        DataSize64 += DataPosFrac+FRACTIONMASK;
543
562
        DataSize64 >>= FRACTIONBITS;
544
563
        DataSize64 += BufferPadding+BufferPrePadding;
545
 
        DataSize64 *= FrameSize;
 
564
        DataSize64 *= NumChannels;
546
565
 
547
 
        BufferSize = min(DataSize64, STACK_DATA_SIZE);
548
 
        BufferSize -= BufferSize%FrameSize;
 
566
        BufferSize  = (ALuint)mini64(DataSize64, STACK_DATA_SIZE/sizeof(ALfloat));
 
567
        BufferSize /= NumChannels;
549
568
 
550
569
        if(Source->lSourceType == AL_STATIC)
551
570
        {
552
 
            const ALbuffer *ALBuffer = Source->Buffer;
 
571
            const ALbuffer *ALBuffer = Source->queue->buffer;
553
572
            const ALubyte *Data = ALBuffer->data;
554
573
            ALuint DataSize;
555
574
            ALuint pos;
560
579
                Looping = AL_FALSE;
561
580
 
562
581
                if(DataPosInt >= BufferPrePadding)
563
 
                    pos = (DataPosInt-BufferPrePadding)*FrameSize;
 
582
                    pos = DataPosInt - BufferPrePadding;
564
583
                else
565
584
                {
566
 
                    DataSize = (BufferPrePadding-DataPosInt)*FrameSize;
567
 
                    DataSize = min(BufferSize, DataSize);
 
585
                    DataSize = BufferPrePadding - DataPosInt;
 
586
                    DataSize = minu(BufferSize, DataSize);
568
587
 
569
 
                    memset(&SrcData[SrcDataSize], (FmtType==FmtUByte)?0x80:0, DataSize);
 
588
                    SilenceStack(&SrcData[SrcDataSize*NumChannels],
 
589
                                 DataSize*NumChannels);
570
590
                    SrcDataSize += DataSize;
571
591
                    BufferSize -= DataSize;
572
592
 
575
595
 
576
596
                /* Copy what's left to play in the source buffer, and clear the
577
597
                 * rest of the temp buffer */
578
 
                DataSize = ALBuffer->size - pos;
579
 
                DataSize = min(BufferSize, DataSize);
 
598
                DataSize = ALBuffer->SampleLen - pos;
 
599
                DataSize = minu(BufferSize, DataSize);
580
600
 
581
 
                memcpy(&SrcData[SrcDataSize], &Data[pos], DataSize);
 
601
                LoadStack(&SrcData[SrcDataSize*NumChannels], &Data[pos*FrameSize],
 
602
                          ALBuffer->FmtType, DataSize*NumChannels);
582
603
                SrcDataSize += DataSize;
583
604
                BufferSize -= DataSize;
584
605
 
585
 
                memset(&SrcData[SrcDataSize], (FmtType==FmtUByte)?0x80:0, BufferSize);
 
606
                SilenceStack(&SrcData[SrcDataSize*NumChannels],
 
607
                             BufferSize*NumChannels);
586
608
                SrcDataSize += BufferSize;
587
609
                BufferSize -= BufferSize;
588
610
            }
598
620
                        pos += LoopEnd-LoopStart;
599
621
                    pos -= BufferPrePadding;
600
622
                    pos += LoopStart;
601
 
                    pos *= FrameSize;
602
623
                }
603
624
                else if(DataPosInt >= BufferPrePadding)
604
 
                    pos = (DataPosInt-BufferPrePadding)*FrameSize;
 
625
                    pos = DataPosInt - BufferPrePadding;
605
626
                else
606
627
                {
607
 
                    DataSize = (BufferPrePadding-DataPosInt)*FrameSize;
608
 
                    DataSize = min(BufferSize, DataSize);
 
628
                    DataSize = BufferPrePadding - DataPosInt;
 
629
                    DataSize = minu(BufferSize, DataSize);
609
630
 
610
 
                    memset(&SrcData[SrcDataSize], (FmtType==FmtUByte)?0x80:0, DataSize);
 
631
                    SilenceStack(&SrcData[SrcDataSize*NumChannels], DataSize*NumChannels);
611
632
                    SrcDataSize += DataSize;
612
633
                    BufferSize -= DataSize;
613
634
 
616
637
 
617
638
                /* Copy what's left of this loop iteration, then copy repeats
618
639
                 * of the loop section */
619
 
                DataSize = LoopEnd*FrameSize - pos;
620
 
                DataSize = min(BufferSize, DataSize);
 
640
                DataSize = LoopEnd - pos;
 
641
                DataSize = minu(BufferSize, DataSize);
621
642
 
622
 
                memcpy(&SrcData[SrcDataSize], &Data[pos], DataSize);
 
643
                LoadStack(&SrcData[SrcDataSize*NumChannels], &Data[pos*FrameSize],
 
644
                          ALBuffer->FmtType, DataSize*NumChannels);
623
645
                SrcDataSize += DataSize;
624
646
                BufferSize -= DataSize;
625
647
 
626
 
                DataSize = (LoopEnd-LoopStart) * FrameSize;
 
648
                DataSize = LoopEnd-LoopStart;
627
649
                while(BufferSize > 0)
628
650
                {
629
 
                    DataSize = min(BufferSize, DataSize);
 
651
                    DataSize = minu(BufferSize, DataSize);
630
652
 
631
 
                    memcpy(&SrcData[SrcDataSize], &Data[LoopStart*FrameSize], DataSize);
 
653
                    LoadStack(&SrcData[SrcDataSize*NumChannels], &Data[LoopStart*FrameSize],
 
654
                              ALBuffer->FmtType, DataSize*NumChannels);
632
655
                    SrcDataSize += DataSize;
633
656
                    BufferSize -= DataSize;
634
657
                }
637
660
        else
638
661
        {
639
662
            /* Crawl the buffer queue to fill in the temp buffer */
640
 
            ALbufferlistitem *BufferListIter = BufferListItem;
 
663
            ALbufferlistitem *tmpiter = BufferListItem;
641
664
            ALuint pos;
642
665
 
643
666
            if(DataPosInt >= BufferPrePadding)
644
 
                pos = (DataPosInt-BufferPrePadding)*FrameSize;
 
667
                pos = DataPosInt - BufferPrePadding;
645
668
            else
646
669
            {
647
 
                pos = (BufferPrePadding-DataPosInt)*FrameSize;
 
670
                pos = BufferPrePadding - DataPosInt;
648
671
                while(pos > 0)
649
672
                {
650
 
                    if(!BufferListIter->prev && !Looping)
 
673
                    if(!tmpiter->prev && !Looping)
651
674
                    {
652
 
                        ALuint DataSize = min(BufferSize, pos);
 
675
                        ALuint DataSize = minu(BufferSize, pos);
653
676
 
654
 
                        memset(&SrcData[SrcDataSize], (FmtType==FmtUByte)?0x80:0, DataSize);
 
677
                        SilenceStack(&SrcData[SrcDataSize*NumChannels], DataSize*NumChannels);
655
678
                        SrcDataSize += DataSize;
656
679
                        BufferSize -= DataSize;
657
680
 
659
682
                        break;
660
683
                    }
661
684
 
662
 
                    if(BufferListIter->prev)
663
 
                        BufferListIter = BufferListIter->prev;
 
685
                    if(tmpiter->prev)
 
686
                        tmpiter = tmpiter->prev;
664
687
                    else
665
688
                    {
666
 
                        while(BufferListIter->next)
667
 
                            BufferListIter = BufferListIter->next;
 
689
                        while(tmpiter->next)
 
690
                            tmpiter = tmpiter->next;
668
691
                    }
669
692
 
670
 
                    if(BufferListIter->buffer)
 
693
                    if(tmpiter->buffer)
671
694
                    {
672
 
                        if((ALuint)BufferListIter->buffer->size > pos)
 
695
                        if((ALuint)tmpiter->buffer->SampleLen > pos)
673
696
                        {
674
 
                            pos = BufferListIter->buffer->size - pos;
 
697
                            pos = tmpiter->buffer->SampleLen - pos;
675
698
                            break;
676
699
                        }
677
 
                        pos -= BufferListIter->buffer->size;
 
700
                        pos -= tmpiter->buffer->SampleLen;
678
701
                    }
679
702
                }
680
703
            }
681
704
 
682
 
            while(BufferListIter && BufferSize > 0)
 
705
            while(tmpiter && BufferSize > 0)
683
706
            {
684
707
                const ALbuffer *ALBuffer;
685
 
                if((ALBuffer=BufferListIter->buffer) != NULL)
 
708
                if((ALBuffer=tmpiter->buffer) != NULL)
686
709
                {
687
710
                    const ALubyte *Data = ALBuffer->data;
688
 
                    ALuint DataSize = ALBuffer->size;
 
711
                    ALuint DataSize = ALBuffer->SampleLen;
689
712
 
690
713
                    /* Skip the data already played */
691
714
                    if(DataSize <= pos)
692
715
                        pos -= DataSize;
693
716
                    else
694
717
                    {
695
 
                        Data += pos;
 
718
                        Data += pos*FrameSize;
696
719
                        DataSize -= pos;
697
720
                        pos -= pos;
698
721
 
699
 
                        DataSize = min(BufferSize, DataSize);
700
 
                        memcpy(&SrcData[SrcDataSize], Data, DataSize);
 
722
                        DataSize = minu(BufferSize, DataSize);
 
723
                        LoadStack(&SrcData[SrcDataSize*NumChannels], Data,
 
724
                                  ALBuffer->FmtType, DataSize*NumChannels);
701
725
                        SrcDataSize += DataSize;
702
726
                        BufferSize -= DataSize;
703
727
                    }
704
728
                }
705
 
                BufferListIter = BufferListIter->next;
706
 
                if(!BufferListIter && Looping)
707
 
                    BufferListIter = Source->queue;
708
 
                else if(!BufferListIter)
 
729
                tmpiter = tmpiter->next;
 
730
                if(!tmpiter && Looping)
 
731
                    tmpiter = Source->queue;
 
732
                else if(!tmpiter)
709
733
                {
710
 
                    memset(&SrcData[SrcDataSize], (FmtType==FmtUByte)?0x80:0, BufferSize);
 
734
                    SilenceStack(&SrcData[SrcDataSize*NumChannels], BufferSize*NumChannels);
711
735
                    SrcDataSize += BufferSize;
712
736
                    BufferSize -= BufferSize;
713
737
                }
715
739
        }
716
740
 
717
741
        /* Figure out how many samples we can mix. */
718
 
        DataSize64  = SrcDataSize / FrameSize;
 
742
        DataSize64  = SrcDataSize;
719
743
        DataSize64 -= BufferPadding+BufferPrePadding;
720
744
        DataSize64 <<= FRACTIONBITS;
721
745
        DataSize64 -= increment;
722
746
        DataSize64 -= DataPosFrac;
723
747
 
724
748
        BufferSize = (ALuint)((DataSize64+(increment-1)) / increment);
725
 
        BufferSize = min(BufferSize, (SamplesToDo-OutPos));
 
749
        BufferSize = minu(BufferSize, (SamplesToDo-OutPos));
726
750
 
727
 
        SrcData += BufferPrePadding*FrameSize;
728
 
        switch(Resampler)
729
 
        {
730
 
            case POINT_RESAMPLER:
731
 
                Mix_point(Source, Device, FmtChannels, FmtType,
732
 
                          SrcData, &DataPosInt, &DataPosFrac,
733
 
                          OutPos, SamplesToDo, BufferSize);
734
 
                break;
735
 
            case LINEAR_RESAMPLER:
736
 
                Mix_lerp(Source, Device, FmtChannels, FmtType,
737
 
                         SrcData, &DataPosInt, &DataPosFrac,
738
 
                         OutPos, SamplesToDo, BufferSize);
739
 
                break;
740
 
            case CUBIC_RESAMPLER:
741
 
                Mix_cubic(Source, Device, FmtChannels, FmtType,
742
 
                          SrcData, &DataPosInt, &DataPosFrac,
743
 
                          OutPos, SamplesToDo, BufferSize);
744
 
                break;
745
 
            case RESAMPLER_MIN:
746
 
            case RESAMPLER_MAX:
747
 
            break;
748
 
        }
 
751
        SrcData += BufferPrePadding*NumChannels;
 
752
        Source->Params.DoMix(Source, Device, SrcData, &DataPosInt, &DataPosFrac,
 
753
                             OutPos, SamplesToDo, BufferSize);
749
754
        OutPos += BufferSize;
750
755
 
751
756
        /* Handle looping sources */
758
763
 
759
764
            if((ALBuffer=BufferListItem->buffer) != NULL)
760
765
            {
761
 
                DataSize = ALBuffer->size / FrameSize;
 
766
                DataSize = ALBuffer->SampleLen;
762
767
                LoopStart = ALBuffer->LoopStart;
763
768
                LoopEnd = ALBuffer->LoopEnd;
764
769
                if(LoopEnd > DataPosInt)
767
772
 
768
773
            if(Looping && Source->lSourceType == AL_STATIC)
769
774
            {
770
 
                BufferListItem = Source->queue;
771
775
                DataPosInt = ((DataPosInt-LoopStart)%(LoopEnd-LoopStart)) + LoopStart;
772
776
                break;
773
777
            }
804
808
    Source->BuffersPlayed     = BuffersPlayed;
805
809
    Source->position          = DataPosInt;
806
810
    Source->position_fraction = DataPosFrac;
807
 
    Source->Buffer            = BufferListItem->buffer;
 
811
    Source->HrtfOffset       += OutPos;
 
812
    if(State == AL_PLAYING)
 
813
    {
 
814
        Source->HrtfCounter = maxu(Source->HrtfCounter, OutPos) - OutPos;
 
815
        Source->HrtfMoving  = AL_TRUE;
 
816
    }
 
817
    else
 
818
    {
 
819
        Source->HrtfCounter = 0;
 
820
        Source->HrtfMoving  = AL_FALSE;
 
821
    }
808
822
}