Avoid mixing silence to output
[openal-soft.git] / Alc / mixer_c.c
blob44ef5dedc173c451f5ad7a26379f40d9a491fe12
1 #include "config.h"
3 #include "alMain.h"
4 #include "alu.h"
5 #include "alSource.h"
6 #include "alAuxEffectSlot.h"
9 static __inline ALfloat point32(const ALfloat *vals, ALint step, ALint frac)
10 { return vals[0]; (void)step; (void)frac; }
11 static __inline ALfloat lerp32(const ALfloat *vals, ALint step, ALint frac)
12 { return lerp(vals[0], vals[step], frac * (1.0f/FRACTIONONE)); }
13 static __inline ALfloat cubic32(const ALfloat *vals, ALint step, ALint frac)
14 { return cubic(vals[-step], vals[0], vals[step], vals[step+step],
15 frac * (1.0f/FRACTIONONE)); }
17 #define DECL_TEMPLATE(Sampler) \
18 void Resample_##Sampler##_C(const ALfloat *data, ALuint frac, \
19 ALuint increment, ALuint NumChannels, ALfloat *RESTRICT OutBuffer, \
20 ALuint BufferSize) \
21 { \
22 ALuint pos = 0; \
23 ALfloat value; \
24 ALuint i; \
26 for(i = 0;i < BufferSize+1;i++) \
27 { \
28 value = Sampler(data + pos*NumChannels, NumChannels, frac); \
29 OutBuffer[i] = value; \
31 frac += increment; \
32 pos += frac>>FRACTIONBITS; \
33 frac &= FRACTIONMASK; \
34 } \
37 DECL_TEMPLATE(point32)
38 DECL_TEMPLATE(lerp32)
39 DECL_TEMPLATE(cubic32)
41 #undef DECL_TEMPLATE
44 static __inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*RESTRICT Values)[2],
45 const ALuint IrSize,
46 ALfloat (*RESTRICT Coeffs)[2],
47 ALfloat (*RESTRICT CoeffStep)[2],
48 ALfloat left, ALfloat right)
50 ALuint c;
51 for(c = 0;c < IrSize;c++)
53 const ALuint off = (Offset+c)&HRIR_MASK;
54 Values[off][0] += Coeffs[c][0] * left;
55 Values[off][1] += Coeffs[c][1] * right;
56 Coeffs[c][0] += CoeffStep[c][0];
57 Coeffs[c][1] += CoeffStep[c][1];
61 static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2],
62 const ALuint IrSize,
63 ALfloat (*RESTRICT Coeffs)[2],
64 ALfloat left, ALfloat right)
66 ALuint c;
67 for(c = 0;c < IrSize;c++)
69 const ALuint off = (Offset+c)&HRIR_MASK;
70 Values[off][0] += Coeffs[c][0] * left;
71 Values[off][1] += Coeffs[c][1] * right;
75 #define SUFFIX C
76 #include "mixer_inc.c"
77 #undef SUFFIX
80 void MixDirect_C(ALsource *Source, ALCdevice *Device, DirectParams *params,
81 const ALfloat *RESTRICT data, ALuint srcchan,
82 ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
84 ALfloat (*RESTRICT DryBuffer)[BUFFERSIZE] = Device->DryBuffer;
85 ALfloat *RESTRICT ClickRemoval = Device->ClickRemoval;
86 ALfloat *RESTRICT PendingClicks = Device->PendingClicks;
87 ALfloat DrySend[MaxChannels];
88 ALuint pos;
89 ALuint c;
90 (void)Source;
92 for(c = 0;c < MaxChannels;c++)
93 DrySend[c] = params->Gains[srcchan][c];
95 pos = 0;
96 if(OutPos == 0)
98 for(c = 0;c < MaxChannels;c++)
99 ClickRemoval[c] -= data[pos]*DrySend[c];
101 for(c = 0;c < MaxChannels;c++)
103 if(DrySend[c] < 0.00001f)
104 continue;
106 for(pos = 0;pos < BufferSize;pos++)
107 DryBuffer[c][OutPos+pos] += data[pos]*DrySend[c];
109 pos = BufferSize;
110 if(OutPos+pos == SamplesToDo)
112 for(c = 0;c < MaxChannels;c++)
113 PendingClicks[c] += data[pos]*DrySend[c];
118 void MixSend_C(SendParams *params, const ALfloat *RESTRICT data,
119 ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
121 ALeffectslot *Slot = params->Slot;
122 ALfloat (*RESTRICT WetBuffer)[BUFFERSIZE] = Slot->WetBuffer;
123 ALfloat *RESTRICT WetClickRemoval = Slot->ClickRemoval;
124 ALfloat *RESTRICT WetPendingClicks = Slot->PendingClicks;
125 ALfloat WetSend = params->Gain;
126 ALuint pos;
128 pos = 0;
129 if(OutPos == 0)
131 WetClickRemoval[0] -= data[pos] * WetSend;
133 for(pos = 0;pos < BufferSize;pos++)
135 WetBuffer[0][OutPos] += data[pos] * WetSend;
136 OutPos++;
138 if(OutPos == SamplesToDo)
140 WetPendingClicks[0] += data[pos] * WetSend;