Last active
April 3, 2024 03:04
-
-
Save catfact/e61f5ce777fb0d574f2a7fabec5a441e to your computer and use it in GitHub Desktop.
sines and noise windchimes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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