1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
ix!();
use crate::{
NLFFSaturator,
NonlinearFeedbackFilter,
R,C,
};
impl FilterProcessQuad for NonlinearFeedbackFilter {
fn process_quad(&self, qfu: &mut QuadFilterUnitState, input: __m128) -> __m128 {
let mut input = input;
let stages: i32 = qfu.comb_write_position[0] & 3;
let sat = NLFFSaturator::try_from(((qfu.comb_write_position[0] >> 2) & 3) as usize).unwrap();
for stage in 0..=stages {
let stage = stage as usize;
let a1 = &qfu.coeff[C::A1];
let a2 = &qfu.coeff[C::A2];
let b0 = &qfu.coeff[C::B0];
let b1 = &qfu.coeff[C::B1];
let b2 = &qfu.coeff[C::B2];
let makeup = &qfu.coeff[C::Makeup];
let z1 = &qfu.reg[R::Z1 as usize + stage * 2];
let z2 = &qfu.reg[R::Z2 as usize + stage * 2];
input = unsafe {
let out: __m128 = _mm_add_ps(*z1, _mm_mul_ps(*b0, input));
let nf: __m128 = match sat {
NLFFSaturator::Tanh => fasttanh_sse_clamped(out),
NLFFSaturator::Soft => softclip_ps(out),
NLFFSaturator::Ojd => Self::ojd_waveshaper_ps(&out),
NLFFSaturator::Sine => Self::fastsin_ps(&out),
};
qfu.reg[R::Z1 as usize + stage * 2] = _mm_add_ps(
*z2,
_mm_sub_ps(
_mm_mul_ps(*b1, input),
_mm_mul_ps(*a1, nf)
)
);
qfu.reg[R::Z2 as usize + stage * 2] = _mm_sub_ps(
_mm_mul_ps(*b2, input),
_mm_mul_ps(*a2, nf)
);
_mm_mul_ps(out, *makeup)
}
}
for coeff in 0..C::len() {
let idx = coeff as usize;
qfu.coeff[idx] = unsafe { _mm_add_ps(qfu.coeff[idx], qfu.dcoeff[idx]) };
}
input
}
}