From 35f5ecbf38b856ce2a04949872f783f3f80cbe7b Mon Sep 17 00:00:00 2001 From: Leo Coogan Date: Fri, 23 May 2025 12:26:13 -0400 Subject: [PATCH] tonal universe experiment --- tonal_universe.scd | 79 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 tonal_universe.scd diff --git a/tonal_universe.scd b/tonal_universe.scd new file mode 100644 index 0000000..676b0ab --- /dev/null +++ b/tonal_universe.scd @@ -0,0 +1,79 @@ +( +u=TonalUniverse(); +~str= +"C,m: I V7/VI VI V VI II II7 IV VII7 I +E,m: V7 I IV V7/V I +C,m: V7/V V7 I +"; +// This function takes a while and logs the progress in the console. +~chords=u.getHarmonyList(~str); +~arrayNotes=~chords.collect({arg ar; ar.notesHarmony[0..1]}); +) +// -> [ [ 0, 3, 7, 12 ], [ -2, 3, 7, 13 ], [ -4, 3, 8, 12 ], [ -5, 2, 7, 11 ], [ -4, 3, 8, 12 ], [ -4, 5, 8, 14 ], [ -7, 2, 8, 12 ], [ -7, 0, 8, 12 ], [ -7, -1, 8, 14 ], [ -9, 0, 7, 15 ], [ -9, -1, 9, 18 ], [ -8, -1, 7, 19 ], [ -8, 0, 9, 21 ], [ -8, 1, 6, 22 ], [ -8, -1, 7, 23 ], [ -10, -3, 6, 24 ], [ -10, -5, 5, 23 ], [ -9, -5, 3, 24 ] ] +( +Pbind( + \instrument, \fm_pulsar_terrain, + // \degree, Pseq(~arrayNotes.flat,1), + \degree, Pseq(~arrayNotes.flat, 1), + \scale, Scale.dorian, + // \tuning, Tuning.et19, + \dur, 0.2 +).play +) +~arrayNotes.flat.plot("Sequence", discrete:true) + +Tuning.directory + + + +( +// Generate a terrain table +~terrain = Buffer.alloc(s, 1024, 1); +~terrain.sine1([1, 0.5, 0.3, 0.2, 0.1], true); // You can sculpt this more chaotically + +SynthDef("fm_pulsar_terrain", { + arg a, e, f, d; + var t, overlap, carfreq, modfreq, mInd, vel, vel_, tblPos, sig; + + f = \freq.kr(100); + + vel = \kel.kr(0.5); + vel_ = vel.clip(0,1.0).linlin( 0, 1, 2, 0.7); + + e = EnvGen.kr( + Env.adsr( + \att.kr(0.025) * vel_, + \dec.kr(0.02) * vel_, + \susl.kr(0.7), + \rel.kr(4), + curve: \curve.kr(-4) + ), + gate: \gate.kr(1), + doneAction:2 + ) * vel; + + carfreq = f * \cf.kr(2) + LFNoise1.kr(3).range(0,50); + modfreq = carfreq * \mf.kr(2) + LFNoise1.kr(3).range(0,100); + + t = Impulse.ar(f); + + mInd = e.pow(3.3); // use envelope shape to shift table pos + overlap = 1.1 - e.pow(0.5); + d = overlap / f; + + // convert modfreq to index between 0 and 1 for VOsc + tblPos = modfreq.linlin(0, 8000, 0, 1).wrap(0, 1); // safer than clip for edge cases + + a = Mix([ + SinOsc.ar(f), + GrainBuf.ar(1, t, d, ~terrain, tblPos, carfreq, 0, 2) + ]); + + a = LeakDC.ar(a * e); + + a = FreeVerb.ar(a, 0.33, 1); + + Out.ar(\outBus.kr(0), a.dup * \gain.kr(0.1)); + +}).add; +) \ No newline at end of file