13 static inline void ApplyCoeffsStep(ALuint Offset
, ALfloat (*restrict Values
)[2],
15 ALfloat (*restrict Coeffs
)[2],
16 const ALfloat (*restrict CoeffStep
)[2],
17 ALfloat left
, ALfloat right
)
19 float32x4_t coeffs
, deltas
;
22 for(c
= 0;c
< IrSize
;c
+= 2)
24 const ALuint off
= (Offset
+c
)&HRIR_MASK
;
25 Values
[off
][0] += Coeffs
[c
][0] * left
;
26 Values
[off
][1] += Coeffs
[c
][1] * right
;
27 Coeffs
[c
][0] += CoeffStep
[c
][0];
28 Coeffs
[c
][1] += CoeffStep
[c
][1];
32 static inline void ApplyCoeffs(ALuint Offset
, ALfloat (*restrict Values
)[2],
34 ALfloat (*restrict Coeffs
)[2],
35 ALfloat left
, ALfloat right
)
38 float32x4_t leftright4
;
40 float32x2_t leftright2
= vdup_n_f32(0.0);
41 leftright2
= vset_lane_f32(left
, leftright2
, 0);
42 leftright2
= vset_lane_f32(right
, leftright2
, 1);
43 leftright4
= vcombine_f32(leftright2
, leftright2
);
45 for(c
= 0;c
< IrSize
;c
+= 2)
47 const ALuint o0
= (Offset
+c
)&HRIR_MASK
;
48 const ALuint o1
= (o0
+1)&HRIR_MASK
;
49 float32x4_t vals
= vcombine_f32(vld1_f32((float32_t
*)&Values
[o0
][0]),
50 vld1_f32((float32_t
*)&Values
[o1
][0]));
51 float32x4_t coefs
= vld1q_f32((float32_t
*)&Coeffs
[c
][0]);
53 vals
= vmlaq_f32(vals
, coefs
, leftright4
);
55 vst1_f32((float32_t
*)&Values
[o0
][0], vget_low_f32(vals
));
56 vst1_f32((float32_t
*)&Values
[o1
][0], vget_high_f32(vals
));
62 #include "mixer_inc.c"
66 void MixDirect_Neon(const DirectParams
*params
, const ALfloat
*restrict data
, ALuint srcchan
,
67 ALuint OutPos
, ALuint SamplesToDo
, ALuint BufferSize
)
69 ALfloat (*restrict OutBuffer
)[BUFFERSIZE
] = params
->OutBuffer
;
70 ALfloat
*restrict ClickRemoval
= params
->ClickRemoval
;
71 ALfloat
*restrict PendingClicks
= params
->PendingClicks
;
77 for(c
= 0;c
< MaxChannels
;c
++)
79 DrySend
= params
->Gains
[srcchan
][c
];
80 if(!(DrySend
> GAIN_SILENCE_THRESHOLD
))
84 ClickRemoval
[c
] -= data
[0]*DrySend
;
86 gain
= vdupq_n_f32(DrySend
);
87 for(pos
= 0;BufferSize
-pos
> 3;pos
+= 4)
89 const float32x4_t val4
= vld1q_f32(&data
[pos
]);
90 float32x4_t dry4
= vld1q_f32(&OutBuffer
[c
][OutPos
+pos
]);
91 dry4
= vaddq_f32(dry4
, vmulq_f32(val4
, gain
));
92 vst1q_f32(&OutBuffer
[c
][OutPos
+pos
], dry4
);
94 for(;pos
< BufferSize
;pos
++)
95 OutBuffer
[c
][OutPos
+pos
] += data
[pos
]*DrySend
;
97 if(OutPos
+pos
== SamplesToDo
)
98 PendingClicks
[c
] += data
[pos
]*DrySend
;
103 void MixSend_Neon(const SendParams
*params
, const ALfloat
*restrict data
,
104 ALuint OutPos
, ALuint SamplesToDo
, ALuint BufferSize
)
106 ALfloat (*restrict OutBuffer
)[BUFFERSIZE
] = params
->OutBuffer
;
107 ALfloat
*restrict ClickRemoval
= params
->ClickRemoval
;
108 ALfloat
*restrict PendingClicks
= params
->PendingClicks
;
113 WetGain
= params
->Gain
;
114 if(!(WetGain
> GAIN_SILENCE_THRESHOLD
))
118 ClickRemoval
[0] -= data
[0] * WetGain
;
120 gain
= vdupq_n_f32(WetGain
);
121 for(pos
= 0;BufferSize
-pos
> 3;pos
+= 4)
123 const float32x4_t val4
= vld1q_f32(&data
[pos
]);
124 float32x4_t wet4
= vld1q_f32(&OutBuffer
[0][OutPos
+pos
]);
125 wet4
= vaddq_f32(wet4
, vmulq_f32(val4
, gain
));
126 vst1q_f32(&OutBuffer
[0][OutPos
+pos
], wet4
);
128 for(;pos
< BufferSize
;pos
++)
129 OutBuffer
[0][OutPos
+pos
] += data
[pos
] * WetGain
;
131 if(OutPos
+pos
== SamplesToDo
)
132 PendingClicks
[0] += data
[pos
] * WetGain
;