Thanks. Nathan Ho also has a good website with great blog entries.
Nathan Ho aka Synthdef on youtube , yes he is a true supercollider wizard
I never got into routines and subroutines and I have the feeling that’s where most of the power lies in supercollider especially for songbuilding
First trial… Just played around, so it’s nothing to take take serious.
Recorded directly from SC. It completely changes my way of thinking and I think I’m still sticking too much to “conventionial music”
So much fun, but SO MUCH to learn ![]()
Use at your own risk:
s.boot;
TempoClock.default.tempo_(122/60);
v = s.volume;
v.gui;
//Change recording directory
//thisProcess.platform.recordingsDir = ('/home/fox/music_projects/SC_samples/');
//not working properly
//Check recording directory
Platform.recordingsDir
//add synthdefs
(
//Kick
SynthDef(\kick, {
arg f2 = 440, f1 = 55, decay = 0.4, decayn = 0.02, dist = 5;
var noise, mult, freqenv, ampenv, sig, sig1, freqb;
//Amplitude envelope
decay = Rand(0.4, 0.5);
ampenv = EnvGen.kr(Env.perc(0.001, decay), doneAction: 2);
//Frequency envelope
freqenv = EnvGen.kr(Env([f2, f1], [0.05],\exp));
mult = IRand(1,33) / 10;
sig1 = SinOsc.ar(freqenv , 0, 1, 0) * ampenv * 0.6;
//Noise
noise = WhiteNoise.ar() * EnvGen.kr(Env.perc(0, 0.01, 1, -10));
noise = BPF.ar(noise, 3000, 0.5); // Highpass to keep only the bright transient
sig = sig1 + (mult* noise);
//sig = (sig*dist).atan * 0.5;
sig = Limiter.ar((sig*dist).tanh * 0.5, 0.8);
Out.ar(0, sig!2);
}).add;
//Impulses
SynthDef(\Impulses, {
arg freq = 4, trig = 0;
var noiseL, noiseR, envL, envR, sigL, sigR;
// Left channel
noiseL = WhiteNoise.ar * Dust.ar(100);
envL = EnvGen.kr(Env.perc(0, 0.05, 1, -4),doneAction:2);
sigL = noiseL * 0.9 * envL;
// Right channel
noiseR = WhiteNoise.ar * Dust.ar(150);
envR = EnvGen.kr(Env.perc(0, 0.05, 1, -4));
sigR = noiseR * 1 * envR;
Out.ar(0, [sigL, sigR]);
}).add;
SynthDef(\noise, {
var sig, amp, env;
env = EnvGen.kr(
Env.perc(0, 0.5,1, -8), doneAction:2
);
amp = SinOsc.kr({ExpRand(0.2, 12)}!8).range(0,1);
//sig = SinOsc.ar({ExpRand(3000, 4000)});
//sig = Limiter.ar(sig * amp, 1);
//sig = Splay.ar(sig) * 0.9 * env;
sig = {WhiteNoise.ar(0.4!2)} * env;
Out.ar(0,sig);
}).add;
SynthDef(\noisernd, {
var sig, amp, env;
env = EnvGen.kr(
Env.perc(0, 0.5,1, -32), doneAction:2
);
amp = SinOsc.kr({ExpRand(0.2, 12)}!8).range(0,1);
//sig = SinOsc.ar({ExpRand(3000, 4000)});
//sig = Limiter.ar(sig * amp, 1);
//sig = Splay.ar(sig) * 0.9 * env;
sig = {WhiteNoise.ar(0.4!2)} * env;
Out.ar(0,sig);
}).add;
SynthDef(\fm, { arg out=0, amp=0.1, gate=1, pan=0, freq=100;
var sig, sig1, sig2;
var env1, env2, mult, cutoff;
mult = IRand(1, 3);
//mult = SinOsc.kr(120/60).range(2, 300).poll;
cutoff = SinOsc.kr(122/60*0.5).exprange(200,3000);
sig1 = SinOsc.ar(freq/2) ;
sig2 = SinOsc.ar(freq * mult * ( sig1 * 5 +1));
sig = sig1 + ( 0.5 * sig2);
sig = sig ;
sig = sig * EnvGen.kr(Env.perc(0, 0.2,1,-4), doneAction: 2);
sig = LPF.ar(sig * AmpComp.kr(freq), cutoff);
//sig = FreeVerb.ar(sig, 0.2, 0.5,0.9,1,0);
sig = Compander.ar(sig, sig, 0.6, 1,0.4,0.01,0.1,1,0);
Out.ar(out, sig!2 * 0.4);
}).add;
SynthDef(\saw, {
arg freq = 44, amp = 1, gate = 1;
var sig, sin, sigv, saw1,saw2, env1, env2;
env1 = EnvGen.kr(Env.adsr(4, 3, 0.2, 2, 1 , -4, 0), gate, doneAction:2);
env2 = EnvGen.kr(Env.adsr(0, 0.3, 0, 2, 1 , -4, 0), gate, doneAction:2);
sin = SinOsc.ar(freq) * env2;
saw1 = Saw.ar(freq + 2) * env1 * 0.5;
saw2 = Saw.ar(freq) * env1 * 0.5;
sig = (sin + saw1 + saw2) * amp;
sigv = FreeVerb.ar(sig, 0.9, 1, 0.8, 1, 0);
Out.ar(0, sigv!2);
}).add;
SynthDef(\sine, {
arg freq = 880, amp = 0.4, gate = 1;
var sig, sin, sigv, saw, env1, env2;
env1 = EnvGen.kr(Env.adsr(0, 0.1, 0, 2, 1 , -2, 0), gate, doneAction:2);
sin = SinOsc.ar(freq) * env1 * amp;
sigv = FreeVerb.ar(sin, 0.2, 0.9, 0.3, 1, 0);
Out.ar(0, sigv!2);
}).add;
)
x = Synth(\sine);
Env.adsr(0, 0.2, 0, 2, 1 , -4, 0).plot
Env.adsr(4, 3, 0.2, 2, 1 , -4, 0).plot
x = Synth(\saw);
x.free;
x.release;
Env.adsr(0, 0.3, 0, 2, 1 , -4, 0).plot
//pattern
// Kick
(
Pdef(\kickPattern,
Pbind(
\instrument, \kick,
\dur, Pseq([1/4, Pwrand([1/4, Rest(1/4)], [0.75, 0.25], 1), Rest(2/4), 1/4,
Rest(3/4), 1/4, Rest(2/4), 1/4,
Rest(2/4), 1/4, Rest(1/4)], inf)
)
).play;
)
// noise
(
Pdef(\noise,
Pbind(
\instrument, \noise,
\dur, Pseq([Rest(2), 2], inf)
)
).play;
)
// noise
(
Pdef(\noisernd,
Pbind(
\instrument, \noisernd,
// Random note from the scale
// Time between emissions
\dur, Prand([0.25, 0.5, 1, 0.25], inf),
\duration, Prand([1, 0.5, 5, 1, 2, 1], inf),
\amp, 0.4
)
).play;
)
//ImpulsesStereo
(
Pdef(\ImpulsesStereo,
Pbind(
\instrument, \Impulses,
\dur, Pseq([Rest(1/8), 1/8], inf),
\trig, 1
)
).play;
)
// Bass
(
Pdef(\fmBass,
Pbind(
\instrument, \fm,
\midinote, Pseq([45, 45, 48, 52] , inf),
//\midinote, Pseq([64, 68, 71, 64] , inf),
\dur, Pseq([1/4, 1/2, 1/4, Rest(1/4), 1/2], inf)
)
).play;
)
//Saw
(
Pdef(\saw,
Pbind(
\instrument, \saw,
//\midinote, Pseq([[45, 48, 52]] , inf),
\midinote, Pseq([[45, 48, 52]] , inf),
//\midinote, Pseq([[64, 68, 71]] , inf),
\dur, Pseq([8], inf),
\amp, 0.22
)
).play;
)
//Sine
(
var notes = Scale.at(\minor).ratios * 880/1;
//var notes = Scale.at(\minor).ratios * 659.3;
Pdef(\sine,
Pbind(
\instrument, \sine,
// Random note from the scale
\freq, Prand(notes, inf),
// Time between emissions
\dur, Prand([0.25, 0.5, 1, 0.25], inf),
\duration, Prand([1, 0.5, 5, 1, 2, 1], inf),
\amp, 0.4
)
).play;
)
Pdef(\sine).stop
Pdef(\saw).stop
Pdef(\kickPattern).play
Pdef(\kickPattern).stop
Pdef(\noise).stop
Pdef(\ImpulsesStereo).play
Pdef(\fmBass).play
Server.default.record;
//x = Synth(\ImpulsesStereo);
x = Synth(\fmbass);
Server.default.stopRecording;
x.free;
Env([100, 40], [0.15],\exp).plot
And where with some minor changes. Much better:
another mod:
Yeah , that’s basically how I did it .
You can assign a sequence of notes to variables and change these on the fly in your pdef’s
Also create a few busses , send fx busses and automate the fx parameters of the send fx , this is where it really comes alive and don’t forget to sequence your synthdef arguments .
Supercollider’s Ugens sound so damn good , even for 20-30 year old software it’s still top notch , James McCartney really is a genius
It’s really itching to get back into it ,but for the moment I am having way to much fun with iteration and the modal bank-sine bank in reaktor , it’s really stellar .
Slowly it turns in to music. Sound different compared to what I usually make in a DAW.
Free book:
You guys are definitely getting me curious about this. I use a lot of Sonic Pi, along with Tidal Cycles and Foxdot sporadically (which are all frontends to Supercollider from what I understand) and I’m weighing the advantages of going directly to the SC source vs the aforementioned, vs platforms like Pure Data and Reaktor (which constantly feel like incredible power tools that can make nearly anything possible).
It seems both intriguing and intimidating. Does anyone have a few advantages or use cases to nudge someone like me into considering SC, or is it purely for the fun / challenge of it all that motivates you to learn it? Thanks in advance!
Regarding Puredata and SuperCollider see this video:
SC is much more efficient.
There’s a similar question
I have choosen SC because LLM can help with the code while it’s difficult with PD.
The lines of code given are really the examples. Just that!
I think that was part of a challenge , to keep the code < 50 characters ( or something like that )
Incredible. So with two lines of code you have a complete track.
As long you know how to do it.