Designing Sound in SuperCollider/R2D2
Fig 57.1: A "random random number generator"
editRandom line slides. Outputs the generated numbers/slides in the post window.
(
x = { |metro=1, slideTime=0.2|
var trig, target, time, output;
// Instead of a [metro] the Impulse.kr UGen is used here to generate 1
// "bang" every second. To select 1 number out of 4 randomly generated
// ones it is more classy in SuperCollider to define a CoinGate with
// the probability of 1/4.
trig = CoinGate.kr(0.25, Impulse.kr(metro));
# target, time = TIRand.kr(0, [800,1],trig);
output = Ramp.kr(target + 20, time * 5 * slideTime);
// This envelope follower differs from the pure data object signifcantly
// in its output. Since in this patch it is used as simple demonstration with
// no further use, it is left unmodified here.
output = EnvFollow.kr(output).poll;
}.play;
)
// To stop:
x.free;
Fig 57.2: FM synthesiser for computer noises
edit(
SynthDef(\fmSynth, { |carrierFreq=100, carrierLvl=0.5, modulatorRatio=5, modulatorIndex=1.5, outputAmp=0.2, sig, out=0|
// the simple FM core
sig = LFSaw.ar(carrierFreq, 1, 0.5, 0.5) * carrierLvl;
sig = sig + SinOsc.ar(carrierFreq * modulatorRatio) * modulatorIndex;
sig = cos( sig * 2pi) * outputAmp * 0.06;
Out.ar(out, sig);
},1!5).add;
)
// At first start the synth:
g = Synth(\fmSynth);
// Play with the parameters:
g.set(\carrierFreq, 800);
g.set(\carrierFreq, 50);
g.set(\carrierFreq, 100, \modulatorRatio, 5, \modulatorIndex, 0.5);
g.set(\carrierFreq, 40, \modulatorRatio, 7, \modulatorIndex, 1.5);
g.set(\carrierFreq, 955, \carrierLvl, 0.4, \modulatorRatio, 3, \modulatorIndex, 4);
// ... etc.
// To stop:
g.free;
Fig 57.3: Babbling R2D2 computer noises
edit"[...] it might not even make any good noises for a while, but sometimes it makes great computer babble sounds". (Andy Farnell)
(
w = { |period=0|
var change, rate, sig, carrierFreq, cfRamp, carrierLvl, clRamp,
modulatorRatio, mrRamp, modulatorIndex, miRamp, outputAmplitude, oaRamp;
period = period * 600 + 100;
// Calculation of a recursive working metronome (Impulse.kr) that generates its
// changing frequency out of its own impulses.
change = Impulse.kr(LocalIn.kr(1,10));
rate = CoinGate.kr(1/3, change);
rate = (TChoose.kr(rate, period/((0..1) + 1))/1000).reciprocal;
LocalOut.kr(rate);
# carrierFreq, cfRamp = TIRand.kr(0, [1000, 1], change);
carrierFreq = Ramp.kr( carrierFreq / 1000, (cfRamp * period) / 1000 ) * 0.6;
# carrierLvl, clRamp = TIRand.kr(0, [9000, 1], CoinGate.kr(1/3, change));
carrierLvl = Ramp.kr( carrierLvl, (clRamp * period) / 1000) + 100;
# modulatorRatio, mrRamp = TIRand.kr([800,1], CoinGate.kr(1/4, change));
modulatorRatio = Ramp.kr(modulatorRatio, (mrRamp * period) / 1000) + 20;
# modulatorIndex, miRamp = TIRand.kr(0, [100, 1], CoinGate.kr(1/4, change));
modulatorIndex = Ramp.kr(modulatorIndex / 200, (miRamp * period) / 1000) + 0.2;
# outputAmplitude, oaRamp = TIRand.kr(0!2, 1!2, CoinGate.kr(1/2, change));
outputAmplitude = Ramp.kr(outputAmplitude, (oaRamp * period + 3) / 1000);
// jointed FM Synthesizer
sig = LFSaw.ar(carrierFreq, 1, 0.5, 0.5) * carrierLvl;
sig = sig + SinOsc.ar(carrierFreq * modulatorRatio) * modulatorIndex;
sig = cos(sig * 2pi) * outputAmplitude;
// One pole filters:
sig = OnePole.ar(sig, exp(-2pi * (10000 * SampleDur.ir)));
sig = OnePole.ar(sig, exp(-2pi * (10000 * SampleDur.ir)));
sig = (sig - OnePole.ar(sig, exp(-2pi * (100 * SampleDur.ir))));
sig = (sig - OnePole.ar(sig, exp(-2pi * (100 * SampleDur.ir))));
sig = sig!2 * 0.06;
}.play;
)
// period controls the talk-speed. range: 0-1. 0 matches to fast, 1 to slow:
w.set(\period, 1);
w.set(\period, 0);
w.set(\period, 0.5);
w.set(\period, 0.7);
w.set(\period, 0.3);
// To stop:
w.free;