1
0

initial commit

This commit is contained in:
2025-02-26 07:33:14 +01:00
commit 13e794f44b
21 changed files with 515 additions and 0 deletions

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# Scoobidules
A collection of snippets, patches, classes and hybrid SuperCollider bidules

4
bitcrushing.scd Normal file
View File

@ -0,0 +1,4 @@
// bitcrushing
sig = sig.round(0.12);
// sample rate reduction
sig = Latch.ar(sig, Impulse.ar(SampleRate.ir/10));

72
choir.scd Normal file
View File

@ -0,0 +1,72 @@
// create a choir from two formants
(
// https://en.wikipedia.org/wiki/Formant#cite_note-7
var formants = [
[360, 640], // o
[235, 2100], // y
[390, 2300], // e
[585, 1710], // æ
[850, 1610], // a
[750, 940], // ɑ
[820, 1530], // ɶ
[600, 1170], // ʌ
[250, 595], // u
[240, 2400], // i
];
SynthDef(\formoo, {
arg formants = #[850, 1610];
var sig, env;
env = Env.perc(\attack.kr(0), \decay.kr(1)).ar(Done.freeSelf);
sig = 10.collect{
var octave = [1, 2, 0.5, 1.5];
// base freq * octave * detuning over time
// sounds like a chorus fx
var voice = Saw.ar(\freq.kr(220) * LFNoise2.kr(3).linlin(-1, 1, 0.99, 1.1) * octave.choose);
// formant * detuning; very high resonance
voice = RLPF.ar(
voice,
formants *
formants.size.collect{
LFNoise2.kr(3).linlin(-1, 1, 0.98, 1.05)
}, 0.05).sum;
// detune and blur some more
voice = voice + PitchShift.ar(voice, {Rand(0.01, 0.1)}, 0.98) * 0.5;
// a bit of distortion
voice = voice.softclip;
};
sig = Splay.ar(sig);
// narrowing the spectrum a little more
sig = RLPF.ar(
sig,
\ff.kr(4700) *
LFNoise2.kr(1).linlin(-1, 1, 0.95, 1.05),
\qr.kr(0.9)
);
sig = sig * env;
sig = sig * \amp.kr(0.25);
sig = Limiter.ar(sig);
Out.ar(\out.kr(0), sig);
}).add;
)
// example
(
r {
[38 + 3, 38 +5, 38 + 12].do{
|freq|
Synth(\formoo,
[
amp: 0.15,
attack: 2,
decay: 5,
freq: freq.midicps,
formants: [850, 1610],
ff: rrand(550, 2660),
qr: 0.5
]
);
}
}.play;
)

5
chorus.scd Normal file
View File

@ -0,0 +1,5 @@
sig = 8.collect({
var mod = LFTri.kr(ExpRand(0.2, 0.3), Rand(0.0, 2.0)).range(0.001, 0.02);
DelayL.ar(sig, 0.02, mod);
});
sig = Splay.ar(sig, 0.2);

View File

@ -0,0 +1,36 @@
// object provides fading ability and levels
Fadable {
var track, level;
fade {
// exponential fading level toward <target> during <time> seconds
// TODO: what if another fade routine is ongoing? => mischief
|target, time|
r {
var rate = 1 / time * 0.05;
while({((level - target).abs >= 0.01 )}, {
if(
(level >= target),
{
// fade out
level = level - (rate.exp - 1);
if((level < target), { level = target; });
},
{
// fade in
level = level + (rate.exp - 1);
if((level > target), { level = target; });
});
0.05.wait;
track.set(\amp, level);
});
}.play;
}
level_ {
|amp|
level = amp;
track.set(\amp, level);
^this
// ("Amplitude in set to " << amp << "sec").postln;
}
}

View File

@ -0,0 +1,42 @@
// bidule holding a master track receiving from a bus, and a collection
// of Tracks
Mixer : Fadable {
var name, master, masterBus, tracks, track, level;
*new {
|mixerName|
^super.new.init(mixerName);
}
*initClass {
StartUp.add {
SynthDef(\master, {
|in|
var sig, releaser;
sig = In.ar(in, 2) * \amp.kr(0.5);
sig = Limiter.ar(sig);
Out.ar(0, sig);
}).add;
}
}
init {
|mixerName|
name = mixerName;
level = 1;
masterBus = Bus.audio(Server.default, 2);
track = Synth(\master, [in: masterBus.index, amp: level]);
tracks = Dictionary();
}
addTrack {
|trackName|
tracks.put(trackName, Track(masterBus.index));
}
// access tracks like if Mixer was a dict
at {
|name|
^tracks[name]
}
}

View File

@ -0,0 +1,64 @@
// A track receiving from a bus. Synth and FX in their own groups
Track : Fadable {
/*
TODO: don't instanciate if name already exist ?
*/
var out, <group, <groupFX, <groupSynth, <track, busTrack, busFX, level;
*new {
|out|
^super.new.init(out);
}
*initClass {
StartUp.add {
SynthDef(\fader, {
|in, fxIn, out|
var sig, fx, dry, wet;
wet = \wet.kr(1);
// TODO: what if i want 1 or 12 channels
sig = In.ar(in, 2);
fx = In.ar(fxIn, 2);
// FX loop?
dry = (1 - wet).clip(0, 1);
sig = [sig * dry, fx * wet].sum;
sig = Pan2.ar(sig, \pan.kr(0));
sig = sig * \amp.kr(1);
sig = Limiter.ar(sig);
Out.ar(out, sig);
}).add;
}
}
init {
|out|
level = 1;
busTrack = Bus.audio(Server.default, 2);
busFX = Bus.audio(Server.default, 2);
group = Group.new(Server.default);
groupSynth = Group.head(group);
groupFX = Group.after(groupSynth);
track = Synth(
\fader,
[
in: busTrack.index,
fxIn: busFX.index,
out: out
],
target: group,
addAction: \addToTail
);
}
in {
^busTrack.index;
}
inFX {
^busFX.index;
}
// printOn {
// |stream|
// }
}

1
flanger.scd Normal file
View File

@ -0,0 +1 @@
sig = CombC.ar(sig, 0.1, SinOsc.ar(0.1).linlin(-1, 1, 0.009, 0.015), 0.1);

20
fx_chain1.scd Normal file
View File

@ -0,0 +1,20 @@
SynthDef(\fx, {
var sig, lag;
sig = In.ar(\in.kr(0), 2);
// chorus
sig = 8.collect({
var mod = LFTri.kr(ExpRand(0.2, 0.3), Rand(0.0, 4.0)).range(0.001, 0.02);
DelayL.ar(sig, 0.02, mod);
});
sig = Splay.ar(sig, 0.2);
// flanger
sig = DelayL.ar(sig, 0.1, SinOsc.ar(0.04).linlin(-1, 1, 0.009, 0.015));
sig = Splay.ar(sig);
// reverb
sig = [sig, JPverb.ar(sig, 2, 0.3, 0.5)].sum;
sig = Pan2.ar(sig, \pan.kr(0));
sig = sig * \rwet.kr(1);
// sig = Normalizer.ar(sig, 0.3);
sig = Limiter.ar(sig);
ReplaceOut.ar(\out.kr(0), sig);
}).add;

20
granulator.scd Normal file
View File

@ -0,0 +1,20 @@
/* Generic modulable buffer granulator */
(
SynthDef(\grainoo, {
|buf|
var sig;
sig = GrainBuf.ar(
numChannels: 2,
trigger: Impulse.ar(\trig_rate.kr(20)),
dur: \gdur.kr(0.5),
sndbuf: buf,
pos: \gpos.kr(0),
rate: \rate.kr(0.5).lag(1),
);
sig = RLPF.ar(sig, \ff.kr(6000), \rq.kr(1));
sig = Pan2.ar(sig, LFNoise0.ar(0.5));
sig = sig * \amp.kr(1);
sig = Limiter.ar(sig);
Out.ar(\out.kr(0), sig);
}).add;
)

16
hatgen.scd Normal file
View File

@ -0,0 +1,16 @@
(
SynthDef(\hhgen, {
var sig;
sig = Pulse.ar(Array.fill(6, {arg i; \freq.kr(20) * (i + {Rand(1.02, 1.03)})}));
sig = Mix.ar(sig);
sig = BPF.ar(sig, 10000, 0.15);
sig = HPF.ar(sig, 7000);
sig = LPF.ar(sig, 3700);
sig = HPF.ar(sig, \ff.kr(1500)) * 20.dbamp;
sig = sig * Env.perc(0.001, \decay.kr(0.1), curve: \curve.kr(-4)).ar(Done.freeSelf);
sig = Pan2.ar(sig, \pan.kr(0));
Out.ar(\out.kr(0), sig!2);
}).add;
)
// Synth(\hhgen, [freq: 60, decay: 0.1, ff: 6000]);

15
hihat_simple.scd Normal file
View File

@ -0,0 +1,15 @@
(
SynthDef(\hat, {
var sig;
sig = Pulse.ar(Array.fill(6, {|index| 120 * (index + {Rand(1.05, 1.15)})}));
sig = Splay.ar(sig, 0.1);
sig = BPF.ar(sig, 10000, 0.1);
sig = RHPF.ar(sig, 7000, 0.1);
sig = HPF.ar(sig, 5000) * 10.dbamp;
sig = Fold.ar(sig);
sig = sig * Env.perc(0.001, \decay.kr(0.1), curve: -8).ar(Done.freeSelf);
sig = sig * \amp.kr(0.8);
sig = Limiter.ar(sig);
Out.ar(0, sig);
}).add;
)

22
kickgen.scd Normal file
View File

@ -0,0 +1,22 @@
(
SynthDef(\kickgen, {
var curve, sig, envAmp, envPitch, noise, decay;
decay = \decay.kr(0.3);
curve = \curve.kr(-8);
envPitch = 1 + (\envmul.kr(4) * Env.perc(0.001, 0.13, curve: curve).ar);
envAmp = Env.perc(0.001, decay, curve: curve).ar(Done.freeSelf);
noise = BPF.ar(WhiteNoise.ar * Env.perc(0.001, 0.01).ar, \ff.kr(1800), \rq.kr(1));
sig = SinOsc.ar(\freq.kr(50) * envPitch) * envAmp;
sig = sig + noise;
// what happens here
sig = (sig * (1 + (2 * Env.perc(0.001, 0.12).ar))).softclip;
// sig = sig.softclip;
// sig = sig * -4.dbamp;
sig = sig * \amp.kr(0.8);
sig = Pan2.ar(sig, \pan.kr(0));
Out.ar(\out.kr(0), sig);
}
).add;
)
// Synth(\kickgen, [freq: 50, decay: 4, curve:-8, ff: 9800, envmul: 8, amp:1]);

8
main_routine.scd Normal file
View File

@ -0,0 +1,8 @@
r{
loop {
s.bind {
// synth goes here
}
}
exprand(0.1, 1).wait;
};

41
master_fx_bus.scd Normal file
View File

@ -0,0 +1,41 @@
(
// example effect chains
SynthDef(\fx, {
arg in;
var sig, fx, releaser;
sig = In.ar(in, 2);
fx = sig.copy;
fx = DelayL.ar(fx, 2, TRand.kr(0.25, \maxRelease.kr(2) / 3));
fx = GVerb.ar(fx, 250);
fx = LPF.ar(fx, 900);
sig = (sig + fx) * 0.5;
releaser = DetectSilence.ar(fx, doneAction: Done.freeSelf);
OffsetOut.ar(\out.kr(0), sig);
}).add;
// master channel with limiter
SynthDef(\master, {
arg in;
var sig, releaser;
sig = In.ar(in, 2);
sig = Limiter.ar(sig, -6.dbamp);
// releaser = DetectSilence.ar(sig, doneAction: Done.freeSelf);
OffsetOut.ar(\out.kr(0), sig);
}).add;
)
(
var fx, fxBus, master, masterBus;
// audio bus transmitting sound signal to synths below
fxBus = Bus.audio(Server.default, 2);
masterBus = Bus.audio(Server.default, 2);
// fx channel. output to master bus
fx = Synth.new(\fx, [\in, fxBus.index, \out, masterBus.index], Server.default, \addToTail);
// master channel. output to default audio out
master = Synth.new(\master, [\in, masterBus.index], Server.default, \addToTail);
/* sequences or routines go there */
)

27
midi_in_gate.scd Normal file
View File

@ -0,0 +1,27 @@
(
MIDIClient.init;
MIDIIn.connectAll;
MIDIFunc.trace(true);
)
(
~synths = Array.fill(127, nil);
MIDIdef.noteOn(\on, {
arg val, num, chan,src;
if(~synths[num] == nil, { // To be absolutely save
~synths[num] = Synth(\supersaw, [
\amp, 0.1,
\freq, num.midicps,
\harm, exprand(4,20)]);
});
});
MIDIdef.noteOff(\off, {
arg val, num, chan,src;
if(~synths[num] != nil, { // To be absolutely safe
~synths[num].set(\gate, 0);
~synths[num] = nil; // Remove the reference
});
});
)

48
pad.scd Normal file
View File

@ -0,0 +1,48 @@
2.midiratio
(
SynthDef(\pad, {
arg freq = 440, gate = 1;
var env, rel, sig, sig2, detuner1, detuner2;
rel = \rel.kr(1);
env = EnvGen.ar(Env.asr(1.2, 0.5, 3), gate, doneAction: Done.freeSelf);
// this is the key part: several oscillators in UNISON, here using a noise ugen
sig = LFSaw.ar((-5..5).collect({|i| freq + i}), LFTri.kr(0.05).range(1, 2));
sig = Splay.ar(sig, 0.1);
sig = RLPF.ar(sig, [3000, 2000, 1250, 600] * LFNoise2.kr(1).range(0.5, 1.2), 0.4);
sig = Splay.ar(sig, 0.1);
sig = HPF.ar(sig, 150);
sig = sig * env;
sig = sig * \amp.kr(1);
Out.ar(\out.kr(0), Limiter.ar(sig));
}).add;
)
(
MIDIClient.init;
MIDIIn.connectAll;
MIDIFunc.trace(true);
)
(
~synths = Array.fill(127, nil);
MIDIdef.noteOn(\on, {
arg val, num, chan,src;
if(~synths[num] == nil, { // To be absolutely save
~synths[num] = Synth(\pad, [
\amp, 0.5,
\freq, num.midicps,
\harm, exprand(4,20)]);
});
});
MIDIdef.noteOff(\off, {
arg val, num, chan,src;
if(~synths[num] != nil, { // To be absolutely safe
~synths[num].set(\gate, 0);
~synths[num] = nil; // Remove the reference
});
});
)
(-10..10)

12
random_lfo.scd Normal file
View File

@ -0,0 +1,12 @@
(
SynthDef(\randlfo, {
var sig;
sig = LFNoise0.ar(\rate.kr(1)).linlin(
-1,
1,
\min.kr(0),
\max.kr(1),
);
Out.ar(\out.kr(0), sig);
}).add;
)

22
snare_physical_mod.scd Normal file
View File

@ -0,0 +1,22 @@
// https://bzoennchen.github.io/supercollider-book/chapters/sounddesign/physical-modeling.html
(
SynthDef(\snare, {
var sig, exciter, local;
local = LocalIn.ar(2);
exciter = Impulse.ar(0!2);
sig = WhiteNoise.ar() * Decay2.ar(exciter, 0.008, 0.25) * \amp.kr(1.0);
sig = sig + local;
sig = BPF.ar(sig, \cutoff.kr(500));
local = DelayN.ar(sig, 0.01,
delaytime: 1/\freq.kr(220)) * \beta.kr(0.8);
LocalOut.ar(local);
sig = LPF.ar(sig, 5000);
// sig = JPverb.ar(sig, 0.6, 0.1);
sig = sig + PitchShift.ar(sig, 0.01, 0.9);
DetectSilence.ar(sig, doneAction: Done.freeSelf);
sig = Limiter.ar(sig);
Out.ar(0, sig);
}).add;
)

18
supersaw.scd Normal file
View File

@ -0,0 +1,18 @@
(
SynthDef(\supersaw, {
arg gate = 0;
var sig, env, freq, sub, noise, saw, rel;
freq = \freq.kr(122);
rel = \rel.kr(1);
env = EnvGen.ar(Env.asr(\attack.kr(0.01), 1, rel), gate, doneAction: Done.freeSelf);
sub = SinOsc.ar(freq) * 1.5;
noise = WhiteNoise.ar(0.4);
saw = Array.fill(8, {Saw.ar([freq, freq * 0.5] * Rand(1.0, 1.04)).sum});
sig = Splay.ar([saw.sum, sub, noise], 0.1);
sig = RHPF.ar(sig, freq, 0.9);
// sig = sig + DelayC.ar(sig, 0.1, SinOsc.ar(0.02).unipolar.range(0.013, 0.025), 1) / 2;
sig = sig * \amp.kr(0.3);
sig = sig * env;
Out.ar(\out.kr(0), Limiter.ar(sig));
}).add;
)

19
tom_simple.scd Normal file
View File

@ -0,0 +1,19 @@
(
SynthDef(\tom, {
var freq, decay, mod, sig, base, noise, vibrato, pitchEnv, ampEnv, filterEnv;
freq = \freq.kr(120);
decay = \decay.kr(1.6);
ampEnv = Env.perc(0, decay).ar(Done.freeSelf);
filterEnv = Env.perc(0, 0.15).ar;
pitchEnv = Env.perc(0, 0.035).ar;
noise = WhiteNoise.ar;
base = SinOsc.ar(freq + (freq * pitchEnv) * [0.5, 1]).sum;
sig = Splay.ar([base, noise], 0.1) * ampEnv * -2.dbamp;
sig = RLPF.ar(sig, 200 + (\ff.kr(900) * filterEnv), 0.45);
// sig = Fold.ar(sig, -0.6, 0.8);
sig = sig + GVerb.ar(sig, 22, 1, 0.8) * -16.dbamp;
Out.ar(\out.kr(0), sig * \amp.kr(1));
}).add;
)
Synth(\tom, [freq: 90, decay: 2]);