From 32a5bc7298fcef2dcb9af54f62b13b3f5dd3b42b Mon Sep 17 00:00:00 2001 From: Leo Coogan Date: Sun, 20 Apr 2025 10:39:14 -0400 Subject: [PATCH] fm pulsar graintable with midi cc --- fm pulsar graintable with midi cc.scd | 104 ++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 fm pulsar graintable with midi cc.scd diff --git a/fm pulsar graintable with midi cc.scd b/fm pulsar graintable with midi cc.scd new file mode 100644 index 0000000..4fe1934 --- /dev/null +++ b/fm pulsar graintable with midi cc.scd @@ -0,0 +1,104 @@ +( +// Generate a terrain table +~terrain = Buffer.alloc(s, 1024, 1); +~terrain.sine1([1, 0.5, 0.3, 0.2, 0.1], true); + +SynthDef("fm_pulsar_terrain", { + arg freq=440, gate=1, amp=0.2, att=0.01, dec=0.05, susl=0.6, rel=1.0, curve=(-4), + cf=2, mf=2, kel=0.5, gain=0.1, outBus=0; + var e, vel_, carfreq, modfreq, mInd, overlap, d, t, tblPos, a; + + vel_ = kel.clip(0,1.0).linlin(0, 1, 2, 0.7); + + e = EnvGen.kr( + Env.adsr(att * vel_, dec * vel_, susl, rel, curve: curve), + gate: gate, + doneAction:2 + ) * kel; + + carfreq = freq * cf + LFNoise1.kr(3).range(0,50); + modfreq = carfreq * mf + LFNoise1.kr(3).range(0,100); + + t = Dust.ar(freq); + mInd = e.pow(3.3); + overlap = 1.1 - e.pow(0.5); + d = overlap / freq; + tblPos = modfreq.linlin(0, 8000, 0, 1).wrap(0, 1); + + a = Mix([ + SinOsc.ar(freq), + 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, a.dup * gain); +}).add; +) + + +( +~notes = Array.newClear(128); + +MIDIdef.noteOn(\noteOnTerrain, { |vel, nn, chan, src| + if (chan == 0) { + var freq = nn.midicps; + var amp = vel.linexp(1,127,0.01,0.3); + var p = ~ccVals; // current cc values + + ~notes[nn] = Synth(\fm_pulsar_terrain, [ + \freq, freq, + \amp, amp, + \att, p[0].linlin(0,1, 0.001, 0.3), + \dec, p[1].linlin(0,1, 0.001, 0.3), + + \susl, p[2].linlin(0,1, 0.1, 1.0), + \rel, p[3].linlin(0,1, 0.1, 8.0), + \cf, p[4].linlin(0,1, 0.5, 5.0), + \mf, p[5].linlin(0,1, 0.5, 5.0), + + \curve, p[6].linlin(0,1, -8, 8), + \gain, p[7].linlin(0,1, 0.01, 0.5), + \kel, p[8].linlin(0,1, 0.1, 1.0) + ]); + } +}); + +MIDIdef.noteOff(\noteOffTerrain, { |vel, nn, chan| + if (chan == 0 and: { ~notes[nn].notNil }) { + ~notes[nn].set(\gate, 0); + ~notes[nn] = nil; + } +}); +) + + + +( +var paramName, adjustedValue; + +// Init array to store CC values +~ccVals = Array.fill(16, 0.5); // defaults to 0.5 (midpoint) + +// Assigning names to the parameters +~paramNames = [ + "Attack", "Decay", "Sustain Level", "Release", + "Carrier Frequency", "Modulation Frequency", "Envelope Curve" + "Gain", "Kelvin", "Unused", "Unused", "Unused", + "Unused", "Unused", "Unused", "Unused" +]; + +MIDIdef.cc(\ccTerrainKnobs, { |val, num, chan, src| + if (chan == 0 and: { num < 16 }) { + // Map CC value (0–127) to the range [0.0, 1.0] + ~ccVals[num] = val.linlin(0, 127, 0.0, 1.0); + + // Print the parameter name and the adjusted value + paramName = ~paramNames[num]; + adjustedValue = ~ccVals[num].round(2); // Rounded for readability + ("CC " ++ num ++ " (" ++ paramName ++ ") = " ++ val ++ " → " ++ adjustedValue).postln; + } +}); +) +