|
@@ -1,10 +1,42 @@
|
|
|
(
|
|
(
|
|
|
|
|
+
|
|
|
|
|
+// 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
|
|
// RGB-controlled synthesizer with amplitude envelope
|
|
|
SynthDef(\rgbSynth, { |out=0, freq=440, amp=1, ampAttack=0.01, ampRelease=1,
|
|
SynthDef(\rgbSynth, { |out=0, freq=440, amp=1, ampAttack=0.01, ampRelease=1,
|
|
|
pitchAttack=0, pitchRelease=0, pitchRatio=2,
|
|
pitchAttack=0, pitchRelease=0, pitchRatio=2,
|
|
|
- redAmt=0.5, greenAmt=0.5, blueAmt=0.5|
|
|
|
|
|
|
|
+ redAmt=0.5, greenAmt=0.5, blueAmt=0.5,
|
|
|
|
|
+ lfoBus=(-1), lfoDepth=0|
|
|
|
|
|
|
|
|
- var env, gate, pitchEnv, red, green, blue, sig;
|
|
|
|
|
|
|
+ var env, gate, pitchEnv, red, green, blue, sig, modFreq, lfo;
|
|
|
|
|
|
|
|
gate = \gate.kr(0);
|
|
gate = \gate.kr(0);
|
|
|
|
|
|
|
@@ -14,13 +46,17 @@ SynthDef(\rgbSynth, { |out=0, freq=440, amp=1, ampAttack=0.01, ampRelease=1,
|
|
|
// Pitch envelope
|
|
// Pitch envelope
|
|
|
pitchEnv = EnvGen.kr(Env.adsr(pitchAttack, 0, 1, pitchRelease), gate);
|
|
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
|
|
// Calculate modulated frequency
|
|
|
- freq = freq * (1 + (pitchEnv * (pitchRatio - 1)));
|
|
|
|
|
|
|
+ modFreq = freq * (1 + (pitchEnv * (pitchRatio - 1))) * (1 + (lfo * lfoDepth));
|
|
|
|
|
|
|
|
// Different waveforms for RGB components
|
|
// Different waveforms for RGB components
|
|
|
- red = SinOsc.ar(freq) * redAmt;
|
|
|
|
|
- green = Saw.ar(freq) * greenAmt;
|
|
|
|
|
- blue = Pulse.ar(freq, 0.5) * blueAmt;
|
|
|
|
|
|
|
+ red = SinOsc.ar(modFreq) * redAmt;
|
|
|
|
|
+ green = Saw.ar(modFreq) * greenAmt;
|
|
|
|
|
+ blue = Pulse.ar(modFreq, 0.5) * blueAmt;
|
|
|
|
|
|
|
|
// Mix the waveforms
|
|
// Mix the waveforms
|
|
|
sig = (red + green + blue) / 3;
|
|
sig = (red + green + blue) / 3;
|
|
@@ -31,5 +67,40 @@ SynthDef(\rgbSynth, { |out=0, freq=440, amp=1, ampAttack=0.01, ampRelease=1,
|
|
|
}).add;
|
|
}).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;
|
|
"RGB-controlled synthesizer loaded".postln;
|
|
|
-)
|
|
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|