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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
ix!();
pub const CONVOLVE_NODC: bool = false;
use crate::*;
impl Convolute for SurgeSuperOscillator {
fn convolute(&mut self, cfg: ConvolutionCfg) {
let voice = cfg.voice;
let stereo = cfg.stereo;
let fm = cfg.fm;
let mut detune: f32 = self.drift * self.blitter.driftlfo[voice];
if self.blitter.n_unison > 1 {
let f: f32 = self.pvalf_extended(SSOParam::UniSpread);
detune += f * ( self.blitter.detune_bias *
(voice as f32) +
self.blitter.detune_offset );
}
let wf: f32 = self.l_shape.v;
let sub: f32 = self.l_sub.v;
let p24: f32 = (1 << 24) as f32;
let ipos: u32;
if self.l_sync.v > 0.0 && self.blitter.syncstate[voice] < self.blitter.oscstate[voice] {
ipos = match fm {
true => p24 * (self.blitter.syncstate[voice] * self.blitter.pitchmult_inv * self.fm_mul_inv),
false => p24 * (self.blitter.syncstate[voice] * self.blitter.pitchmult_inv),
} as u32;
let t: f32 = (self.tuner.n2pinv_tuningctr(detune as f64) as f32) * 2.0;
self.blitter.state[voice] = 0;
self.last_level[voice] += self.dc_uni[voice] * (self.blitter.oscstate[voice] - self.blitter.syncstate[voice]);
self.blitter.oscstate[voice] = self.blitter.syncstate[voice];
self.blitter.syncstate[voice] += t;
self.blitter.syncstate[voice] = maxf(0.0, self.blitter.syncstate[voice]);
} else {
ipos = match fm {
true => p24 * (self.blitter.oscstate[voice] * self.blitter.pitchmult_inv * self.fm_mul_inv),
false => p24 * (self.blitter.oscstate[voice] * self.blitter.pitchmult_inv),
} as u32;
}
let delay = self.get_delay(fm,ipos);
let m: i32 = (((ipos >> 16) & 0xff) as i32) * ((FIR_IPOL_N << 1) as i32);
let lipolui16: i32 = (ipos & 0xffff).try_into().unwrap();
let lipol128 = unsafe {
let mut lipol128: __m128 = z128![];
lipol128 = _mm_cvtsi32_ss(lipol128, lipolui16);
lipol128 = _mm_shuffle_ps(lipol128, lipol128, _MM_SHUFFLE(0, 0, 0, 0));
lipol128
};
let sync: f64 = mind(
self.l_sync.v as f64,
(12.0_f64 + 72.0 + 72.0) - (self.pitch as f64)
);
let (t, t_inv) = self.get_t(sync, detune as f64);
let (g, g_r) = self.get_g(voice, wf, sub, stereo);
match stereo {
true => self.convolve_stereo(g, g_r, delay as usize, m as usize, lipol128),
false => self.convolve_mono(g, delay as usize, m as usize, lipol128),
}
if !CONVOLVE_NODC {
let olddc: f32 = self.dc_uni[voice];
let idx = (self.blitter.bufpos as usize) + (FIR_OFFSET as usize) + (delay as usize);
self.dc_uni[voice] = t_inv * (1.0 + wf) * (1.0 - sub);
self.blitter.dcbuffer[idx] += self.dc_uni[voice] - olddc;
}
self.blitter.rate[voice] = match self.blitter.state[voice] & 1 {
0 => t * self.pwidth[voice],
_ => t * (1.0 - self.pwidth[voice]),
};
self.blitter.rate[voice] *= match (self.blitter.state[voice] + 1) & 2 {
0 => self.pwidth2[voice],
_ => (2.0 - self.pwidth2[voice]),
};
self.blitter.oscstate[voice] += self.blitter.rate[voice];
self.blitter.oscstate[voice] = maxf(0.0, self.blitter.oscstate[voice]);
self.blitter.state[voice] = (self.blitter.state[voice] + 1) & 3;
}
}