supercaw
recently, sqx made caw (source), a lovely crow synth that works in the browser. i wanted to port it to SuperCollider, so here is an attempt:
(
SynthDef(\caw, { |out=0, freq=50, freq1=600, duration=0.5, modfreq=63, envpeak=0.25, envshape=0.3, modgain0=325, modgain1=75, modshape=0.5, bpfreq=1150, bprq=0.1, hpfreq=1100, hprq=0.6, formfreq=1600, formrq=0.5, formgain=0.8, dist=0.4, pan=0, amp=0.5|
var env, mf, sig;
env = EnvGen.ar(Env.perc(envpeak*duration, 1.0-envpeak*duration, curve: \linear), doneAction: Done.freeSelf) ** envshape;
mf = SinOsc.ar(modfreq).max(0) ** modshape;
sig = Saw.ar(env.linlin(0, 1, freq, freq1) + (mf * env.linlin(0, 1, modgain0, modgain1)));
sig = BPF.ar(sig, bpfreq, bprq, bprq.sqrt.reciprocal);
sig = HPF.ar(sig, hpfreq, hprq, hprq.sqrt.reciprocal);
sig = sig + (formgain * BPF.ar(sig, formfreq, formrq, formrq.sqrt.reciprocal));
sig = LeakDC.ar(sig);
sig = (sig * env * dist).tanh * 3 * amp;
sig = Pan2.ar(sig, pan);
Out.ar(out, sig);
}).add;
)
plus a pattern that plays randomized caws:
(
Pdef(\caw, Pbind(
\instrument, \caw,
\duration, Pwhite(0.2, 0.35),
\envpeak, Pwhite(0.3, 0.3),
\envshape, Pwhite(0.2, 0.4),
\freq, Pwhite(0, 100),
\freq1, Pwhite(550, 720),
\modfreq, Pwhite(60, 65),
\modgain0, Pwhite(300, 350),
\modgain1, Pwhite(50, 100),
\modshape, Pwhite(0.4, 0.6),
\dist, Pwhite(0.3, 0.5),
\formfreq, Pwhite(1500, 1700),
\formgain, Pwhite(0.5, 1.1),
\formrq, Pwhite(0.8, 0.9),
\bpfreq, Pwhite(1000, 1300),
\bprq, Pwhite(0.2, 0.3),
\hpfreq, Pwhite(1000, 1200),
\hprq, Pwhite(0.7, 0.8),
\dur, 0.5,
\amp, 0.6
)).play
)
it does not sound quite as good as the original, but it's a start. still need to look deeper into the differences.
also, a SuperDirt version:
SynthDef(\supercaw, { |out=0, freq, voice=0.5, sustain=1, rate=1, speed=1, pan=0, amp=0.5, cawenvpeak=0.3, cawbpf=1150, cawbpq=0.33, cawhpf=550, cawhpq=0.05, cawformf=1600, cawformq=0.1, cawformgain=0.9, cawdist=0.4|
var note, freq0, freq1, dur, env, mf, sig, bprq, formrq;
note = freq.cpsmidi;
freq0 = (freq*0.25) * speed;
freq1 = 600 * (note - 60 * 0.5).midiratio * speed;
dur = 0.5/(rate*speed);
env = EnvGen.ar(Env.perc(cawenvpeak*dur, 1.0-cawenvpeak*dur), doneAction: Done.freeSelf) ** 0.3;
mf = SinOsc.ar(voice.linexp(1, 0, 50, 80)).max(0) ** 0.5;
sig = Saw.ar(env.linlin(0, 1, freq0, freq1) + (mf * env.linlin(0, 1, 325, 75)));
bprq = cawbpq.linexp(0, 1, 1, 0.001);
sig = BPF.ar(sig, cawbpf, bprq, bprq.sqrt.reciprocal);
sig = RHPF.ar(sig, cawhpf*(note - 48 * 0.5).midiratio * speed, cawhpq.linexp(0, 1, 1, 0.001));
formrq = cawformq.linexp(0, 1, 1, 0.001);
sig = sig + (cawformgain * BPF.ar(sig, cawformf, formrq, formrq.sqrt.reciprocal));
sig = LeakDC.ar(sig);
sig = (sig * env * cawdist).tanh * 6 * amp;
sig = Pan2.ar(sig, pan);
Out.ar(out, DirtPan.ar(sig, ~dirt.numChannels, pan, env))
}).add;
why did i name things differently here? we may never know.
try a Tidal pattern like:
d1
$ note "<0 12 24 -12 -24>*2"
# s "supercaw"
# speed (rangex 0.5 2 rand)
# rate (rangex 0.5 2 $ fast 1.1 rand)
# voice (fast 1.2 rand)