makepad/platform/script/audio_aot/shaders/fm2_svf.splash

42 lines
980 B
Text

// The benchmark voice: a 2-operator FM pair into a TPT state-variable
// low-pass, with an amp envelope.
let index = param(1.5, 0, 8)
let cutoff = param(2400, 30, 16000)
let res = param(0.3, 0, 0.98)
var pc = 0.0
var pm = 0.0
var ic1 = 0.0
var ic2 = 0.0
var a1 = 0.0
var a2 = 0.0
var a3 = 0.0
var amp = 0.0
var rel = 0.0
fn block() {
let g = tan(PI * min(cutoff, sample_rate * 0.45) / sample_rate)
let k = 2.0 - 2.0 * res
a1 = 1.0 / (1.0 + g * (g + k))
a2 = g * a1
a3 = g * a2
rel = exp(-1.0 / (0.1 * sample_rate))
}
fn voice() {
let dt = freq / sample_rate
pm = fract(pm + dt * 2.0)
pc = fract(pc + dt)
let x = sin(TAU * pc + index * sin(TAU * pm))
let v3 = x - ic2
let v1 = a1 * ic1 + a2 * v3
let v2 = ic2 + a2 * ic1 + a3 * v3
ic1 = 2.0 * v1 - ic1
ic2 = 2.0 * v2 - ic2
if gate > 0.0 {
amp = min(amp + 500.0 / sample_rate, 1.0)
} else {
amp = amp * rel
}
v2 * amp * velocity * 0.3
}