42 lines
980 B
Text
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
|
|
}
|