( // Define the bus to send the audio to the filter ~bus = Bus.audio(s, 2); ~synthGroup = Group.head(s); // synths go here ~filterGroup = Group.after(~synthGroup); // filter comes after ~lfoBus = Bus.control(s, 1); // 1-channel control bus for the LFO ~filterEnvBus = Bus.control(s, 1); // 1-channel control bus for the filter envelope // Low Frequency Oscillator for parameter modulation SynthDef(\lfo, { |out=0, freq=2, min=(-0.5), max=0.5, waveform=0| var lfo; // Select waveform based on parameter lfo = Select.kr(waveform, [ SinOsc.kr(freq), // Sine wave (waveform=0) LFTri.kr(freq), // Triangle wave (waveform=1) LFSaw.kr(freq, 0, -1), // Decreasing sawtooth wave (waveform=2) LFPulse.kr(freq, 0, 0.5) // Square wave (waveform=3) ]); // Scale to range lfo = lfo.range(min, max); // Output to control bus Out.kr(out, lfo); }).add; // RGB-controlled synthesizer with amplitude envelope SynthDef(\rgbSynth, { |out=0, freq=440, amp=1, ampAttack=0.01, ampRelease=1, pitchAttack=0, pitchRelease=0, pitchRatio=2, redAmt=0.5, greenAmt=0.5, blueAmt=0.5, lfoBus=(-1), lfoDepth=0| var env, gate, pitchEnv, red, green, blue, sig, modFreq, lfo; gate = \gate.kr(0); // Amplitude envelope env = EnvGen.kr(Env.adsr(ampAttack, 0, 1, ampRelease), gate); // Pitch envelope pitchEnv = EnvGen.kr(Env.adsr(pitchAttack, 0, 1, pitchRelease), gate); // If lfoBus < 0, read from bus 0 (assumed silent) lfo = In.kr(lfoBus.max(0)); lfo.postln(); // Calculate modulated frequency modFreq = freq * (1 + (pitchEnv * (pitchRatio - 1))) * (1 + (lfo * lfoDepth)); // Different waveforms for RGB components red = SinOsc.ar(modFreq) * redAmt; green = Saw.ar(modFreq) * greenAmt; blue = Pulse.ar(modFreq, 0.5) * blueAmt; // Mix the waveforms sig = (red + green + blue) / 3; // Apply envelope and output sig = sig * env * amp; Out.ar(out, sig!2); }).add; SynthDef(\filterEnv, { |out=0, gate=1, attack=0.01, decay=0, sustain=1, release=0.5| var env = EnvGen.kr(Env.adsr(attack, decay, sustain, release), gate); Out.kr(out, env); }).add; // The sound goes into a LPF SynthDef(\lpf, { |in=0, out=0, cutoff=18000, resonance=1, lfoBus=(-1), lfoDepth=0, envBus=(-1), envDepth=0| var sig, lfo, env, modCutoff, rq; // Read audio and control signals from buses sig = In.ar(in, 2); lfo = In.kr(lfoBus.max(0)); env = In.kr(envBus.max(0)); modCutoff = cutoff * (1 + (lfo * lfoDepth)) * (1 + (env * envDepth)); modCutoff = modCutoff.clip(20, 18000); // safety rq = resonance.linexp(0, 1, 1, 0.07); // Transforms resonance amount to rq with exp interpolation sig = RLPF.ar(sig, modCutoff, rq); // low-pass filter Out.ar(out, sig); }).add; "RGB-controlled synthesizer loaded".postln; )