That’s my first (ambient kind of) track made entirely with Supercollider. Not sure about the kick: maybe the track would better work without it? Only mixed on headphones yet and I need to make the car test.
I recorded the single tracks into Reaper and made some fine adjustements there. The reverb was replaced in Reaper by the Abyss reverb from Saike and Galactic 3 from Airwindows.
If someone is interested in the source code (partially used ChatGPT, especially for the routing stuff):
TempoClock.default.tempo = 60/60;
////////////////////////////////////////////////////////////
// SERVER
////////////////////////////////////////////////////////////
(
s.options.numOutputBusChannels = 18;
s.options.numInputBusChannels = 2;
s.reboot;
)
s.meter;
////////////////////////////////////////////////////////////
// REVERB BUS + REVERB SYNTH
////////////////////////////////////////////////////////////
(
s.waitForBoot({
~verbBus = Bus.audio(s, 2);
SynthDef(\globalVerbStem, {
arg inbus = 0, mainOut = 0, stemOut = 16, mix = 1, room = 1, damp = 0.2, amp = 0.95;
var dry, wet;
dry = In.ar(inbus, 2);
wet = FreeVerb2.ar(dry[0], dry[1], mix, room, damp);
wet = wet * amp;
Out.ar(mainOut, wet);
Out.ar(stemOut, wet);
}).add;
s.sync;
~verbSynth = Synth.tail(s, \globalVerbStem, [
\inbus, ~verbBus,
\mainOut, 0,
\stemOut, 16,
]);
"reverb ready".postln;
});
)
////////////////////////////////////////////////////////////
// SYNTHDEFS
////////////////////////////////////////////////////////////
(
SynthDef(\kick, {
arg mainOut = 0, stemOut = 2, amp = 0.5, pan = 0, atk = 0.001, dec = 0.22, upfq = 110;
var pitchEnv, bodyEnv, body, click, clickEnv, sig;
pitchEnv = EnvGen.kr(Env([upfq, 55], [0.08], -2));
bodyEnv = EnvGen.kr(
Env.perc(atk, dec, 1, -4),
doneAction: 2
);
body = SinOsc.ar(pitchEnv) * bodyEnv;
clickEnv = EnvGen.kr(
Env.perc(0.0005, 0.01, 1, -8)
);
click = BPF.ar(WhiteNoise.ar(1), 2500, 0.8) * clickEnv * 0.25;
sig = body + click;
sig = (sig * 4).tanh * 0.4;
sig = Pan2.ar(sig * amp, pan);
Out.ar(mainOut, sig);
Out.ar(stemOut, sig);
}).add;
SynthDef(\bass, {
arg mainOut = 0, stemOut = 4, freq = 40, amp = 0.15, pan = 0,
atk = 2, dec = 1, sus = 0.8, rel = 6,
ffreq = 120, fmax = 1200, rq = 0.3;
var osc, sub, env, fenv, drift, sig;
drift = SinOsc.kr(0.03).range(0.995, 1.005);
osc = Saw.ar(freq * [0.995, 1.0, 1.005] * drift);
osc = Mix(osc) * 0.5;
sub = SinOsc.ar(freq * 0.5, 0, 0.2);
env = EnvGen.ar(Env.perc(atk, rel), doneAction: 2);
fenv = EnvGen.ar(Env([ffreq, fmax], [rel * 0.7], \exp));
sig = osc + sub;
sig = RLPF.ar(sig, fenv, rq);
sig = sig * env * amp;
sig = Pan2.ar(sig, pan);
Out.ar(mainOut, sig);
Out.ar(stemOut, sig);
}).add;
SynthDef(\whitenoise, {
arg mainOut = 0, stemOut = 6, verbBus = 0, atk = 1, dec = 4, amp = 0.2, pan = 0, filtfreq = 8000, send = 0.2;
var env, sig, comb;
env = EnvGen.ar(Env.perc(atk, dec, 1, -0.1), doneAction: 2);
sig = PinkNoise.ar;
sig = HPF.ar(sig, 4000);
sig = LPF.ar(sig, filtfreq);
comb = CombL.ar(sig, 0.1, 0.04, 0.5) * 0.12;
sig = sig + comb;
sig = sig * LFNoise1.ar(8).range(0, 1);
sig = tanh(sig * 1.1);
sig = sig * env * amp;
sig = Pan2.ar(sig, pan);
Out.ar(verbBus, sig * send);
Out.ar(mainOut, sig);
Out.ar(stemOut, sig);
}).add;
SynthDef(\sinenoise, {
arg mainOut = 0,
stemOut = 8,
verbBus = 0,
amps = 0.05,
ampn = 0.05,
freq = 440,
pan = 0,
reln = 0.3,
rels = 0.8,
send = 0,
lpf = 14000;
var envn, envs;
var white, pink, noiseMix;
var sine, sig;
envn = EnvGen.ar(
Env.perc(0.001, reln, 1, -4),
doneAction: 0
);
envs = EnvGen.ar(
Env.perc(0.001, rels, 1, -4),
doneAction: 2
);
white = WhiteNoise.ar;
pink = PinkNoise.ar;
noiseMix = XFade2.ar(
white,
pink,
SinOsc.kr(0.2)
) * envn;
sine = SinOsc.ar(freq) * envs;
sig = (noiseMix * 0.3 * ampn) + (sine * amps);
sig = HPF.ar(sig, 200);
sig = LPF.ar(sig, lpf);
sig = Pan2.ar(sig, pan);
Out.ar(verbBus, sig * send);
Out.ar(mainOut, sig);
Out.ar(stemOut, sig);
}).add;
SynthDef(\spectrumSwarm, {
arg mainOut = 0, stemOut = 8, verbBus = 0,
freq = 3520, amp = 0.3, panSpread = 0.8, rel = 1, dust = 1, send = 0;
var freqs, sig, grains, env;
freqs = freq * [0.5, 1, 1.01, 1.5, 2, 2.02, 3];
grains = Dust.ar(dust);
env = EnvGen.ar(Env.perc(0.001, rel), doneAction: 2);
sig = Mix.fill(freqs.size, {
var osc;
osc = SinOsc.ar(
freqs.choose * LFNoise1.kr(0.5).range(0.99, 1.01)
);
osc * grains
});
sig = HPF.ar(sig, 300);
sig = Splay.ar(sig, panSpread);
sig = sig * env * amp;
Out.ar(verbBus, sig * send);
Out.ar(mainOut, sig);
Out.ar(stemOut, sig);
}).add;
SynthDef(\saw, {
arg mainOut = 0, stemOut = 10, verbBus = 0,
freq = 220, amp = 0.08, atk = 2, rel = 6, pan = 0,
ffreq = 900, rq = 0.25, detune = 0.015, send = 0.5;
var sig, env, freqs, drift, cutoff, widthMod;
drift = LFNoise1.kr([0.03, 0.05, 0.07, 0.11, 0.13]).range(1 - detune, 1 + detune);
freqs = freq * drift * [0.5, 0.99, 1, 1.01, 2];
sig = Saw.ar(freqs);
widthMod = SinOsc.kr(0.02).range(0.4, 1.0);
sig = Splay.ar(sig, widthMod);
env = EnvGen.ar(Env.perc(atk, rel, 1, -4), doneAction: 2);
cutoff = ffreq * LFNoise1.kr(0.04).range(0.6, 1.2);
cutoff = cutoff.clip(80, 2000);
sig = RLPF.ar(sig, cutoff, rq);
sig = LPF.ar(sig, cutoff * 1.2);
sig = BRF.ar(sig, LFNoise1.kr(0.03).range(300, 1200), 0.3);
sig = tanh(sig * 1.4);
sig = HPF.ar(sig, 300);
sig = sig * env * amp;
sig = Balance2.ar(sig[0], sig[1], pan);
Out.ar(verbBus, sig * send);
Out.ar(mainOut, sig);
Out.ar(stemOut, sig);
}).add;
SynthDef(\klank, {
arg mainOut = 0, stemOut = 12, verbBus = 0, freq = 440, amp = 0.05, pan = 0, rel = 2, send = 0.1;
var harm, amps, ring, exc, sig, env;
harm = [1, 2, 3, 4];
amps = [0.2, 0.15, 0.1, 0.05];
ring = [1, 1.2, 0.8, 1.5];
exc = PinkNoise.ar(0.02) * Decay2.ar(Impulse.ar(1), 0.001, 0.1);
sig = Klank.ar(`[harm, amps, ring], exc, freq);
env = EnvGen.kr(Env.perc(0.01, rel), doneAction: 2);
sig = sig * env * amp;
sig = Pan2.ar(sig, pan);
Out.ar(verbBus, sig * send);
Out.ar(mainOut, sig);
Out.ar(stemOut, sig);
}).add;
////////////////////////////////////////////////////////////
// PATTERNS
////////////////////////////////////////////////////////////
~mixGain = 2.5;
Pdef(\drum1,
Pbind(
\instrument, \kick,
\dur, Pseq([0.25, Prand([1, Rest(1)]), Prand([0.5, Rest(0.5)]), 1, Prand([1, Rest(1)])], inf),
\amp, Pwhite(0.1, 0.12) * ~mixGain,
\dec, Pwhite(0.25, 0.5),
\upfq, Pwhite(100, 120)
)
);
Pdef(\hh,
Pbind(
\instrument, \whitenoise,
\verbBus, ~verbBus,
\dur, Pseq([Rest(1.25), Prand([0.25, Rest(0.25)]), Rest(3.75 + 1.75), Prand([0.25, Rest(0.25)]), Rest(0.25)], inf),
\amp, Pwhite(0.02, 0.03) * ~mixGain,
\dec, Pwhite(4, 8),
\atk, Pwhite(0.01, 0.1),
\filtfreq, Pwhite(5000, 6000),
\timingOffset, Pwhite(0.001, 0.01),
\send, 0.5
)
);
Pdef(\bass,
Pbind(
\instrument, \bass,
\dur, Pseq([4, 2], inf),
\freq, Pseq([45, 52, 60, 48].midicps, inf),
\amp, 0.06 * ~mixGain,
\atk, 0.02,
\dec, 0.5,
\rel, 5,
\ffreq, 80,
\fmax, Pseg(Prand([500, 650, 800, 700, 600, 550] * 1.5, inf), 28),
\rq, 0.1
)
);
Pdef(\sines,
Pbind(
\instrument, \sinenoise,
\verbBus, ~verbBus,
\scale, Scale.minor,
\root, 9,
\degree, Pwrand([0,2,4,5], [0.4,0.3,0.2,0.1], inf),
\octave, Pwhite(4,6),
\dur, Prand([2, 1, Prand([0.5, Rest(0.5)], Rest(4)), 2, 1], inf),
\reln, Pwhite(0.0004, 0.02),
\rels, Pwhite(0.08, 5),
\amps, Pwhite(0.01, 0.02) * ~mixGain,
\ampn, Pwhite(0.01, 0.02),
\pan, Pwhite(-0.8,0.8),
\send, 0.4
)
);
Pdef(\sines2,
Pbind(
\instrument, \sinenoise,
\verbBus, ~verbBus,
\scale, Scale.minor,
\root, 9,
\degree, Pwrand([0,2,4,5], [0.4,0.3,0.2,0.1], inf),
\octave, Pwhite(7,8),
\dur, Prand([2, 0.5, Prand([1, Rest(1)], Rest(2)), 1, 4], inf),
\reln, Pwhite(0.01, 0.02),
\rels, Pwhite(0.08, 5),
\amps, Pwhite(0.005, 0.01) * ~mixGain,
\ampn, Pwhite(0.01, 0.02) * ~mixGain,
\pan, Pwhite(-0.8,0.8),
\send, 0.6
)
);
Pdef(\tom,
Pbind(
\instrument, \sinenoise,
\verbBus, ~verbBus,
\dur, Pseq([Rest(1), 0.25, Rest(0.25), 1.25, Rest(1)], inf),
\reln, Pwhite(0.001, 0.012),
\rels, 0.1,
\amps, Pwhite(0.10, 0.12) * ~mixGain,
\ampn, Pwhite(0.00015, 0.002) * ~mixGain,
\pan, Pwhite(-0.02, 0.02),
\lpf, Pwhite(8000, 9000),
\freq, Pseq([220, 220, 440], inf),
\send, 0.01
)
);
Pdef(\noise3,
Pbind(
\instrument, \sinenoise,
\verbBus, ~verbBus,
\dur, Prand([Pseq([0.1, 0.1, 0.1, 0.1]), Rest(4)], inf),
\reln, Pwhite(0.0001, 0.012),
\rels, 0.1,
\amps, Pwhite(0.002, 0.003) * ~mixGain,
\ampn, Pwhite(0.04, 0.07) * ~mixGain,
\pan, Pwhite(-0.8,0.8),
\send, 1
)
);
Pdef(\particles,
Pbind(
\instrument, \spectrumSwarm,
\verbBus, ~verbBus,
\dur, Pwhite(0.05, 0.2),
\freq, Pseg(Pseq([800, 2000, 5000, 1200], inf), Pseq([12, 18, 10], inf), \exp),
\rel, Pwhite(0.03, 0.2),
\dust, Pwhite(0.25, 1),
\amp, Pwhite(0.01, 0.02) * ~mixGain,
\send, 0.8
)
);
Pdef(\burst,
Pbind(
\instrument, \sinenoise,
\verbBus, ~verbBus,
\dur, Pseq([0.25, 0.25, 0.25, Rest(8)], inf),
\freq, Pexprand(1000, 12000),
\reln, 0.005,
\rels, 0.15,
\amps, Pwhite(0.01, 0.03) * ~mixGain,
\ampn, Pwhite(0.6, 1.2) * ~mixGain,
\pan, Pwhite(-1, 1)
)
);
Pdef(\sawpad,
Pbind(
\instrument, \saw,
\verbBus, ~verbBus,
\dur, Pseq([4], inf),
\midinote, Pseq([45, 52, 60, 48], inf) + Pdup(4, Prand([12, 24], inf)),
\atk, Pwhite(2.0, 4.0),
\rel, Pwhite(5.0, 10.0),
\amp, Pwhite(0.03, 0.035) * ~mixGain,
\ffreq, Pwhite(500, 2200),
\rq, Pwhite(0.18, 0.35),
\pan, Pwhite(-0.4, 0.4),
\send, 0.5
)
);
Pdef(\pklank,
Pbind(
\instrument, \klank,
\verbBus, ~verbBus,
\freq, Pseq([440, 659.29, 523.25, 440], inf),
\amp, Pwhite(0.8, 0.9) * ~mixGain,
\pan, Pwhite(-1,1),
\rel, Pwhite(0.5, 4),
\dur, Pwhite(0.2, 4),
\send, 0.8
)
);
// Play the whole thing
~r = Routine({
"intro".postln;
Pdef(\pklank).play(quant: 0);
Pdef(\bass).play(quant: 0);
32.wait;
"sines".postln;
Pdef(\sines).play(quant: 0);
Pdef(\particles).play(quant: 0);
32.wait;
"drum".postln;
Pdef(\drum1).play(quant: 0);
Pdef(\tom).play(quant: 0);
Pdef(\sines2).play(quant: 0);
Pdef(\pklank).stop;
32.wait;
"bring in saw".postln;
Pdef(\sawpad).play(quant: 0);
Pdef(\noise3).play(quant: 0);
64.wait;
"hh".postln;
Pdef(\pklank).play(quant: 0);
Pdef(\hh).play(quant: 0);
Pdef(\sines2).stop;
64.wait;
"kick break".postln;
Pdef(\drum1).stop;
Pdef(\hh).stop;
Pdef(\tom).stop;
Pdef(\particles).stop;
Pdef(\noise3).stop;
32.wait;
"kick back".postln;
Pdef(\drum1).play(quant: 0);
Pdef(\hh).play(quant: 0);
Pdef(\tom).play(quant: 0);
Pdef(\particles).play(quant: 0);
Pdef(\noise3).play(quant: 0);
Pdef(\pklank).stop;
32.wait;
"bring in pklank and sines2".postln;
Pdef(\pklank).play(quant: 0);
Pdef(\sines2).play(quant: 0);
48.wait;
"stop percussion".postln;
Pdef(\tom).stop;
Pdef(\noise3).stop;
Pdef(\particles).stop;
Pdef(\drum1).stop;
Pdef(\hh).stop;
16.wait;
"stop both sines".postln;
Pdef(\sines).stop;
Pdef(\sines2).stop;
32.wait;
"stop bass and pklank".postln;
Pdef(\bass).stop;
Pdef(\pklank).stop;
32.wait;
Pdef(\sawpad).stop;
}).play;
)
(
~r.stop;
Pdef.all.do(_.stop);
)