Skip to content

Instantly share code, notes, and snippets.

@catfact
Last active April 3, 2024 03:04
Show Gist options
  • Save catfact/e61f5ce777fb0d574f2a7fabec5a441e to your computer and use it in GitHub Desktop.
Save catfact/e61f5ce777fb0d574f2a7fabec5a441e to your computer and use it in GitHub Desktop.
sines and noise windchimes
s = Server.default;
s.waitForBoot {
r = Routine {
SynthDef.new(\sine_pair_perc, {
var hz = \hz.kr(200);
var beatrate = \beatrate.kr(2);
var beatrate_2 = beatrate/2;
var amp = \amp.kr(-30.dbamp);
var osc = SinOsc.ar([hz-beatrate_2, hz+beatrate_2]);
var width = Lag.ar(K2A.ar(\width.kr), \widthLag.kr(0.2));
var monosum = osc[0] + osc[1];
var monosumclip = ((monosum.clip * 2).clip * 2).clip;
var panned = [
Pan2.ar(osc[0], width.linlin(0, 1, 0, -1)),
Pan2.ar(osc[1], width.linlin(0, 1, 0, 1)),
];
var acomp = AmpCompA.kr(hz);
var aenv = EnvGen.ar(Env.perc(\attack.kr(0.01), \release.kr(6)), doneAction:2);
var snd = ((panned *\cleanAmp.kr(1.0)) + ((monosum * \monoClipAmp.kr(0.1)).dup)) * amp;
Out.ar(\out.kr(0), snd * aenv * acomp);
}).send(s);
SynthDef.new(\noise_low_brown, {
var attack = \attack.kr(4);
var sustain = \sustain.kr(4);
var release = \release.kr(8);
var fc = EnvGen.ar(
Env.new(
[0, 1, 1, 0],
[attack, sustain, release],
)
).linexp(0, 1, \fcMin.kr(100), \fcMax.kr(888));
var snd = LPF.ar(BrownNoise.ar.dup, fc) * \amp.kr(-32.dbamp);
var aenv = EnvGen.ar(
Env.new(
[0, 1, 1, 0],
[attack, sustain, release]
),
doneAction:2);
snd = Balance2.ar(snd[0], snd[1], \balance.kr(0.5));
Out.ar(\out.kr(0), snd * aenv);
}).send(s);
SynthDef.new(\noise_white_band, {
var attack = \attack.kr(4);
var sustain = \sustain.kr(4);
var release = \release.kr(8);
var snd = BPF.ar(WhiteNoise.ar.dup, \fc.kr(3000), \rq.kr(1)) * \amp.kr(-36.dbamp);
var aenv = EnvGen.ar(
Env.new(
[0, 1, 1, 0],
[attack, sustain, release]
),
doneAction:2);
snd = Balance2.ar(snd[0], snd[1], \balance.kr(0.0));
Out.ar(\out.kr(0), snd * aenv);
}).send(s);
s.sync;
n = 4;
i = 0;
~beatbus = Array.fill(n, { Bus.control(s, 1) });
n.do({|i| ~beatbus[i].set(i+1); });
~beat_lfos = Array.fill(n, {
arg i;
{ Out.kr(~beatbus[i].index, LFNoise2.kr(0.1, 0.5, i+1)) }.play
});
// microtonal variations
// ~roff = (9/8).sqrt;
~roff = 1.5;
// ~roff = 1;
~nyquist = s.sampleRate / 2;
~play_sine_note = { arg hz, amp, clipBalance=0.5;
var synth;
var theHz = hz * (~roff ** i);
var theClipLevel;
var theCleanLevel;
theCleanLevel = (clipBalance * pi/2).sin;
theClipLevel = (clipBalance * pi/2).cos * 0.25;
// [theCleanLevel, theClipLevel].postln;
if (hz > ~nyquist, {
// divide down by powers of two until below nyquist
var ratio = ~nyquist / theHz;
ratio = 2 ** (ratio.log2.floor);
theHz = theHz * ratio;
postln("divided down: " ++ ratio);
});
// [hz, theHz].postln;
synth = Synth.new(\sine_pair_perc, [
\hz, theHz, \amp, amp,
\cleanAmp, theCleanLevel,
\monoClipAmp, theClipLevel
]);
synth.map(\beatrate, ~beatbus[i]);
i = (i+1) % n;
synth
};
{ s.scope }.defer;
~fbase= 55;
~tbase = 2;
~gap_seq = Pseq([1, 2, 2, 4, 2, 3, 4, 8, 8, 1].reciprocal, inf).asStream;
~ratio1_seq = Pseq([1, 2, 4, 3, 2, 6, 7, 4, 8], inf).asStream;
~ratio2_seq = Pseq([1, 1, 2, 1, 3, 1, 1, 4], inf).asStream;
~nharm_seq = Pseq([1, 1, 2, 1, 2, 3, 1, 1, 1, 4, 5, 1], inf).asStream;
~harm_gap_seq = Pseq([1, 2, 3, 4, 5] * 0.01, inf).asStream;
~clip_balance_seq = Pseq([0, 1, 0.5, 0.25, 0.25, 0.5, 0.75, 0.5, 0, 1, 0.5], inf).asStream;
~noise_steps_seq = Pseq([10, 11, 13, 16, 17, 23].scramble, inf).asStream;
~noise_type_seq = Pseq([2, 1], inf).asStream;
~noise_balance_seq = Pseq([0, -0.5, 0.5, 0, -0.8, 0.8, 0, -1, 1], inf).asStream;
~noise_steps = ~noise_steps_seq.next;
~cur_step = 0;
~seq_r = Routine {
inf.do {
//// noise?
~cur_step = ~cur_step + 1;
if (~cur_step >= ~noise_steps, {
~noise_steps = ~noise_steps_seq.next;
~cur_step = 0;
~noise_type = ~noise_type_seq.next;
~noise_balance = ~noise_balance_seq.next;
f = ~ratio1_seq.next * ~ratio2_seq.next * ~fbase;
switch(~noise_type,
1, {
postln("!!!! low " ++ [f, ~noise_balance]);
Synth.new(\noise_low_brown, [\fc, f, \balance, ~noise_balance])
},
2, {
postln("!!!! band " ++ [f, ~noise_balance]);
Synth.new(\noise_white_band, [\fc, f*8, \balance, ~noise_balance])
}
);
}, {
//// sine cluster
f = Array.series(~nharm_seq.next, 1);
f = f * ~ratio1_seq.next * ~ratio2_seq.next * ~fbase;
a = (f.size.reciprocal).blend(1, 0.5);
~gap = ~harm_gap_seq.next;
~clip_balance = ~clip_balance_seq.next;
Routine {
// f.postln;
f.do({ arg hz;
~play_sine_note.value(hz, a * -24.dbamp, ~clip_balance);
(~gap + (0.01.rand)).wait;
})
}.play;
});
(~gap_seq.next * ~tbase).wait;
}
}.play;
}.play;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment