/* Simple synthesizer with one oscillator, LFO and envelope. Author: Leonardo Laguna Ruiz - leonardo@vult-dsp.com Check the API documentation in the basic.vult example */ fun env(gate) { mem x; val k = if gate > x then 0.05 else 0.0002; x = x + (gate - x) * k; return x; } fun edge(x):bool { mem pre_x; val v:bool = (pre_x <> x) && (pre_x == false); pre_x = x; return v; } fun pitchToFreq(cv) { return 261.6256 * exp(cv * 0.69314718056); } fun phasor(pitch, reset){ mem phase; val rate = pitchToFreq(pitch) * sampletime(); phase = phase + rate; if(phase > 1.0) phase = phase - 1.0; if(reset) phase = 0.0; return phase; } fun oscillator(pitch, mod) { mem pre_phase1; // Implements the resonant filter simulation as shown in // http://en.wikipedia.org/wiki/Phase_distortion_synthesis val phase1 = phasor(pitch, false); val comp = 1.0 - phase1; val reset = edge((pre_phase1 - phase1) > 0.5); pre_phase1 = phase1; val phase2 = phasor(pitch + mod, reset); val sine = sin(2.0 * pi() * phase2); return sine * comp; } fun lfo(f, gate){ mem phase; val rate = f * 10.0 * sampletime(); if(edge(gate > 0.0)) phase = 0.0; phase = phase + rate; if(phase > 1.0) phase = phase - 1.0; return sin(phase * 2.0 * pi()) - 0.5; } // Main processing function fun process(cv, gate){ // LFO val lfo_rate = getKnob(3); val lfo_amt = getKnob(4); val lfo_val = lfo(lfo_rate, gate) * lfo_amt; // Oscillator val pitch = getKnob(1) + 10.0 * cv - 2.0; val mod = getKnob(2) * 2.0 + lfo_val; val o = oscillator(pitch, mod); // Envelope val e = env(gate); return o * e; } and update() { _ = display("IN1: CV, IN2: GATE"); }