5778036cymbalsim: scripted plate and cymbal designer with a modal linear model and a von Karman GPU modelJeremy Magland 1// Retarded-time sum over the plate (Rayleigh integral), one workgroup per
2// output sample of the batch, dispatched once at the end of the batch.
3// lw[k] = (weight, delay in samples) for node k; the delay is relative to
4// the closest node so that the ring buffer only has to cover the spread.
5// The ring buffer holds the transverse velocity at the sample instants; the
6// acceleration is the first difference of the delayed velocity, which is the
7// average acceleration over one sample interval (band-limited, and immune to
8// the per-step rounding noise of the force evaluation). The bound StepParams
9// are those of the batch's first audio step; workgroup q handles the sample
10// q slots later.
12@group(0) @binding(0) var<uniform> P: Params;
13@group(0) @binding(1) var<uniform> SP: StepParams;
14@group(0) @binding(2) var<storage, read> hist: array<f32>;
15@group(0) @binding(3) var<storage, read> lw: array<vec2f>;
16@group(0) @binding(4) var<storage, read_write> audioOut: array<f32>;
18var<workgroup> sh: array<f32, 256>;
20@compute @workgroup_size(256)
21fn main(@builtin(local_invocation_id) lid: vec3u, @builtin(workgroup_id) wid: vec3u) {
22 let t = lid.x;
23 let H = i32(P.histLen);
24 let slot = (SP.audioSlot + i32(wid.x)) % H;
25 var acc = 0.0;
26 for (var k = t; k < P.n; k += 256u) {
27 let d = lw[k].y;
28 let k0 = i32(floor(d));
29 let f = d - f32(k0);
30 let s0 = ((slot - k0) % H + H) % H;
31 let s1 = ((slot - k0 - 1) % H + H) % H;
32 let s2 = ((slot - k0 - 2) % H + H) % H;
33 let v0 = hist[u32(s0) * P.n + k];
34 let v1 = hist[u32(s1) * P.n + k];
35 let v2 = hist[u32(s2) * P.n + k];
36 let a = (mix(v0, v1, f) - mix(v1, v2, f)) * P.fs;
37 acc += lw[k].x * a;
38 }
39 sh[t] = acc;
40 workgroupBarrier();
41 for (var stride = 128u; stride > 0u; stride >>= 1u) {
42 if (t < stride) { sh[t] += sh[t + stride]; }
43 workgroupBarrier();
44 }
45 if (t == 0u) { audioOut[u32(SP.audioOut) + wid.x] = sh[0]; }
46}