7 #include "alAuxEffectSlot.h"
8 #include "mixer_defs.h"
11 #define LIKELY(x) __builtin_expect(!!(x), 1)
12 #define UNLIKELY(x) __builtin_expect(!!(x), 0)
15 #define UNLIKELY(x) (x)
18 #define REAL_MERGE2(a,b) a##b
19 #define MERGE2(a,b) REAL_MERGE2(a,b)
20 #define REAL_MERGE4(a,b,c,d) a##b##c##d
21 #define MERGE4(a,b,c,d) REAL_MERGE4(a,b,c,d)
24 void MERGE4(MixDirect_Hrtf_
,SAMPLER
,_
,SUFFIX
)(
25 ALsource
*Source
, ALCdevice
*Device
, DirectParams
*params
,
26 const ALfloat
*RESTRICT data
, ALuint srcfrac
,
27 ALuint OutPos
, ALuint SamplesToDo
, ALuint BufferSize
)
29 const ALuint NumChannels
= Source
->NumChannels
;
30 const ALint
*RESTRICT DelayStep
= params
->Hrtf
.DelayStep
;
31 ALfloat (*RESTRICT DryBuffer
)[MaxChannels
];
32 ALfloat
*RESTRICT ClickRemoval
, *RESTRICT PendingClicks
;
33 ALfloat (*RESTRICT CoeffStep
)[2] = params
->Hrtf
.CoeffStep
;
41 increment
= Source
->Params
.Step
;
43 DryBuffer
= Device
->DryBuffer
;
44 ClickRemoval
= Device
->ClickRemoval
;
45 PendingClicks
= Device
->PendingClicks
;
46 DryFilter
= ¶ms
->iirFilter
;
48 for(i
= 0;i
< NumChannels
;i
++)
50 ALfloat (*RESTRICT TargetCoeffs
)[2] = params
->Hrtf
.Coeffs
[i
];
51 ALuint
*RESTRICT TargetDelay
= params
->Hrtf
.Delay
[i
];
52 ALfloat
*RESTRICT History
= Source
->Hrtf
.History
[i
];
53 ALfloat (*RESTRICT Values
)[2] = Source
->Hrtf
.Values
[i
];
54 ALint Counter
= maxu(Source
->Hrtf
.Counter
, OutPos
) - OutPos
;
55 ALuint Offset
= Source
->Hrtf
.Offset
+ OutPos
;
56 ALfloat Coeffs
[HRIR_LENGTH
][2] ALIGN(16);
63 for(c
= 0;c
< HRIR_LENGTH
;c
++)
65 Coeffs
[c
][0] = TargetCoeffs
[c
][0] - (CoeffStep
[c
][0]*Counter
);
66 Coeffs
[c
][1] = TargetCoeffs
[c
][1] - (CoeffStep
[c
][1]*Counter
);
69 Delay
[0] = TargetDelay
[0] - (DelayStep
[0]*Counter
);
70 Delay
[1] = TargetDelay
[1] - (DelayStep
[1]*Counter
);
72 if(LIKELY(OutPos
== 0))
74 value
= SAMPLER(data
+ pos
*NumChannels
+ i
, NumChannels
, frac
);
75 value
= lpFilter2PC(DryFilter
, i
, value
);
77 History
[Offset
&SRC_HISTORY_MASK
] = value
;
78 left
= lerp(History
[(Offset
-(Delay
[0]>>HRTFDELAY_BITS
))&SRC_HISTORY_MASK
],
79 History
[(Offset
-(Delay
[0]>>HRTFDELAY_BITS
)-1)&SRC_HISTORY_MASK
],
80 (Delay
[0]&HRTFDELAY_MASK
)*(1.0f
/HRTFDELAY_FRACONE
));
81 right
= lerp(History
[(Offset
-(Delay
[1]>>HRTFDELAY_BITS
))&SRC_HISTORY_MASK
],
82 History
[(Offset
-(Delay
[1]>>HRTFDELAY_BITS
)-1)&SRC_HISTORY_MASK
],
83 (Delay
[1]&HRTFDELAY_MASK
)*(1.0f
/HRTFDELAY_FRACONE
));
85 ClickRemoval
[FrontLeft
] -= Values
[(Offset
+1)&HRIR_MASK
][0] +
87 ClickRemoval
[FrontRight
] -= Values
[(Offset
+1)&HRIR_MASK
][1] +
90 for(BufferIdx
= 0;BufferIdx
< BufferSize
&& Counter
> 0;BufferIdx
++)
92 value
= SAMPLER(data
+ pos
*NumChannels
+ i
, NumChannels
, frac
);
93 value
= lpFilter2P(DryFilter
, i
, value
);
95 History
[Offset
&SRC_HISTORY_MASK
] = value
;
96 left
= lerp(History
[(Offset
-(Delay
[0]>>HRTFDELAY_BITS
))&SRC_HISTORY_MASK
],
97 History
[(Offset
-(Delay
[0]>>HRTFDELAY_BITS
)-1)&SRC_HISTORY_MASK
],
98 (Delay
[0]&HRTFDELAY_MASK
)*(1.0f
/HRTFDELAY_FRACONE
));
99 right
= lerp(History
[(Offset
-(Delay
[1]>>HRTFDELAY_BITS
))&SRC_HISTORY_MASK
],
100 History
[(Offset
-(Delay
[1]>>HRTFDELAY_BITS
)-1)&SRC_HISTORY_MASK
],
101 (Delay
[1]&HRTFDELAY_MASK
)*(1.0f
/HRTFDELAY_FRACONE
));
103 Delay
[0] += DelayStep
[0];
104 Delay
[1] += DelayStep
[1];
106 Values
[Offset
&HRIR_MASK
][0] = 0.0f
;
107 Values
[Offset
&HRIR_MASK
][1] = 0.0f
;
110 ApplyCoeffsStep(Offset
, Values
, Coeffs
, CoeffStep
, left
, right
);
111 DryBuffer
[OutPos
][FrontLeft
] += Values
[Offset
&HRIR_MASK
][0];
112 DryBuffer
[OutPos
][FrontRight
] += Values
[Offset
&HRIR_MASK
][1];
115 pos
+= frac
>>FRACTIONBITS
;
116 frac
&= FRACTIONMASK
;
121 Delay
[0] >>= HRTFDELAY_BITS
;
122 Delay
[1] >>= HRTFDELAY_BITS
;
123 for(;BufferIdx
< BufferSize
;BufferIdx
++)
125 value
= SAMPLER(data
+ pos
*NumChannels
+ i
, NumChannels
, frac
);
126 value
= lpFilter2P(DryFilter
, i
, value
);
128 History
[Offset
&SRC_HISTORY_MASK
] = value
;
129 left
= History
[(Offset
-Delay
[0])&SRC_HISTORY_MASK
];
130 right
= History
[(Offset
-Delay
[1])&SRC_HISTORY_MASK
];
132 Values
[Offset
&HRIR_MASK
][0] = 0.0f
;
133 Values
[Offset
&HRIR_MASK
][1] = 0.0f
;
136 ApplyCoeffs(Offset
, Values
, Coeffs
, left
, right
);
137 DryBuffer
[OutPos
][FrontLeft
] += Values
[Offset
&HRIR_MASK
][0];
138 DryBuffer
[OutPos
][FrontRight
] += Values
[Offset
&HRIR_MASK
][1];
141 pos
+= frac
>>FRACTIONBITS
;
142 frac
&= FRACTIONMASK
;
145 if(LIKELY(OutPos
== SamplesToDo
))
147 value
= SAMPLER(data
+ pos
*NumChannels
+ i
, NumChannels
, frac
);
148 value
= lpFilter2PC(DryFilter
, i
, value
);
150 History
[Offset
&SRC_HISTORY_MASK
] = value
;
151 left
= History
[(Offset
-Delay
[0])&SRC_HISTORY_MASK
];
152 right
= History
[(Offset
-Delay
[1])&SRC_HISTORY_MASK
];
154 PendingClicks
[FrontLeft
] += Values
[(Offset
+1)&HRIR_MASK
][0] +
156 PendingClicks
[FrontRight
] += Values
[(Offset
+1)&HRIR_MASK
][1] +
157 Coeffs
[0][1] * right
;
159 OutPos
-= BufferSize
;
164 void MERGE4(MixDirect_
,SAMPLER
,_
,SUFFIX
)(
165 ALsource
*Source
, ALCdevice
*Device
, DirectParams
*params
,
166 const ALfloat
*RESTRICT data
, ALuint srcfrac
,
167 ALuint OutPos
, ALuint SamplesToDo
, ALuint BufferSize
)
169 const ALuint NumChannels
= Source
->NumChannels
;
170 ALfloat (*RESTRICT DryBuffer
)[MaxChannels
];
171 ALfloat
*RESTRICT ClickRemoval
, *RESTRICT PendingClicks
;
172 ALfloat DrySend
[MaxChannels
];
180 increment
= Source
->Params
.Step
;
182 DryBuffer
= Device
->DryBuffer
;
183 ClickRemoval
= Device
->ClickRemoval
;
184 PendingClicks
= Device
->PendingClicks
;
185 DryFilter
= ¶ms
->iirFilter
;
187 for(i
= 0;i
< NumChannels
;i
++)
189 for(c
= 0;c
< MaxChannels
;c
++)
190 DrySend
[c
] = params
->Gains
[i
][c
];
197 value
= SAMPLER(data
+ pos
*NumChannels
+ i
, NumChannels
, frac
);
199 value
= lpFilter2PC(DryFilter
, i
, value
);
200 for(c
= 0;c
< MaxChannels
;c
++)
201 ClickRemoval
[c
] -= value
*DrySend
[c
];
203 for(BufferIdx
= 0;BufferIdx
< BufferSize
;BufferIdx
++)
205 value
= SAMPLER(data
+ pos
*NumChannels
+ i
, NumChannels
, frac
);
207 value
= lpFilter2P(DryFilter
, i
, value
);
208 for(c
= 0;c
< MaxChannels
;c
++)
209 DryBuffer
[OutPos
][c
] += value
*DrySend
[c
];
212 pos
+= frac
>>FRACTIONBITS
;
213 frac
&= FRACTIONMASK
;
216 if(OutPos
== SamplesToDo
)
218 value
= SAMPLER(data
+ pos
*NumChannels
+ i
, NumChannels
, frac
);
220 value
= lpFilter2PC(DryFilter
, i
, value
);
221 for(c
= 0;c
< MaxChannels
;c
++)
222 PendingClicks
[c
] += value
*DrySend
[c
];
224 OutPos
-= BufferSize
;
229 void MERGE4(MixSend_
,SAMPLER
,_
,SUFFIX
)(
230 ALsource
*Source
, ALuint sendidx
, SendParams
*params
,
231 const ALfloat
*RESTRICT data
, ALuint srcfrac
,
232 ALuint OutPos
, ALuint SamplesToDo
, ALuint BufferSize
)
234 const ALuint NumChannels
= Source
->NumChannels
;
238 ALfloat
*WetClickRemoval
;
239 ALfloat
*WetPendingClicks
;
247 increment
= Source
->Params
.Step
;
249 Slot
= Source
->Params
.Slot
[sendidx
];
250 WetBuffer
= Slot
->WetBuffer
;
251 WetClickRemoval
= Slot
->ClickRemoval
;
252 WetPendingClicks
= Slot
->PendingClicks
;
253 WetFilter
= ¶ms
->iirFilter
;
254 WetSend
= params
->Gain
;
256 for(i
= 0;i
< NumChannels
;i
++)
263 value
= SAMPLER(data
+ pos
*NumChannels
+ i
, NumChannels
, frac
);
265 value
= lpFilter2PC(WetFilter
, i
, value
);
266 WetClickRemoval
[0] -= value
* WetSend
;
268 for(BufferIdx
= 0;BufferIdx
< BufferSize
;BufferIdx
++)
270 value
= SAMPLER(data
+ pos
*NumChannels
+ i
, NumChannels
, frac
);
272 value
= lpFilter2P(WetFilter
, i
, value
);
273 WetBuffer
[OutPos
] += value
* WetSend
;
276 pos
+= frac
>>FRACTIONBITS
;
277 frac
&= FRACTIONMASK
;
280 if(OutPos
== SamplesToDo
)
282 value
= SAMPLER(data
+ pos
*NumChannels
+ i
, NumChannels
, frac
);
284 value
= lpFilter2PC(WetFilter
, i
, value
);
285 WetPendingClicks
[0] += value
* WetSend
;
287 OutPos
-= BufferSize
;