Designing Sound in SuperCollider/R2D2

From Wikibooks, open books for an open world
Jump to navigation Jump to search

Fig 57.1: A "random random number generator"[edit | edit source]

Random 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 | edit source]

(
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 | edit source]

"[...] 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;