// ===================================================================== // SuperCollider Workspace // ===================================================================== b = Buffer.readChannel(s, "non-oneshot-sample-path", channels:[0]); b = Buffer.readChannel(s, "one-shot-sample-path", channels:[0]); b = Buffer.read(s, "/home/lcoogan/snd/live/2025-04-26.Basic_City_Brewery/trax/01-Cantor_Samual_Malavsky_Shomea_Kol_Bichios.wav"); b = Buffer.readChannel(s, "/home/lcoogan/snd/samples/harmonica-steenberge/09 Rip Van Winkle.wav", channels:[0]); b.free; b.play Ndef(\granulator).clear; Ndef(\granulator).ar(2); Ndef(\granulator).set(\bufnum, b.bufnum); ( // one-shot reverb SynthDef(\granulator, { |bufnum, tFreq=20, overlap=2, rate=1, tFreqMF=0, tFreqMD=0, rateMF=0, rateMD=0, posRateMD=0, posRateMF=0, granDur=4| var samplePhasor, phasor, gran, env, bufrd; var bufFrames = BufFrames.ir(bufnum); var t; var tFreqMod = { SinOsc.ar(tFreqMF, Rand(0.0,2pi)) * tFreqMD; }; var rateMod = { SinOsc.ar(rateMF, Rand(0.0,2pi)) * rateMD; }; var posRateMod = { SinOsc.ar(posRateMF, Rand(0.0,2pi)) * posRateMD; }; var playTrig = Impulse.ar(\playTrFr.kr(0.5)); tFreq = tFreq + tFreqMod.dup; rate = rate + rateMod.dup; t = Impulse.ar(tFreq); // t = In.ar(somebus); samplePhasor = EnvGen.ar(Env([0, 0, bufFrames], [0, bufFrames / SampleRate.ir], curve: 0), gate: playTrig); phasor = EnvGen.ar(Env([0, 0, 1], [0, granDur], curve: 0), gate: playTrig); bufrd = BufRd.ar( numChannels: 1, bufnum: bufnum, phase: samplePhasor, interpolation: 4 ); bufrd = LeakDC.ar(bufrd); gran = GrainBufJ.ar( numChannels: 1, trigger: t, dur: tFreq.reciprocal * overlap, sndbuf: bufnum, rate: rate, // pos: phasor + WhiteNoise.ar(posRateMD!2), pos: phasor + posRateMod.dup, interp: 2, pan: 0, envbufnum: -1, maxGrains: 512, loop: 0 ) * EnvGen.ar(Env.perc(0.001, granDur * \grainGate.kr(1), curve: \granCurve.kr(-4)), gate: playTrig); Out.ar(0, Mix([ bufrd * \dry.kr(1.0), gran * \wet.kr(0.5) ]);); // DetectSilence.ar(gran, doneAction: 2); // in case we lauch it without trigger Ugens (with Synth etc) // Out.ar(0,); }).add; ) x = Synth(\granulator, [\bufnum, b]); // // Ndef(\granulator).addSpec( // \overlap, [0.001, 40, \exp], // \rate, [-2, 2], // \posRate, [0, 4], // \tFreq, \widefreq, // \tFreqMF, [0.0,80], // \tFreqMD, [0.0,20], // \rateMF, [0.0,80], // \rateMD, [0.0,2], // \posRateMF, [0.0,80], // \posRateMD, [0.0,2], // \dry, [0.0,1], // \wet, [0.0,1], // \playTrFr, [0.0,1], // \granDur, [0.0,8], // \granCurve, [-10,10], // \grainGate, [0,1], // ).edit; // \overlap, [0.001, 40, \exp], // \rate, [-2, 2], // \posRate, [0, 4], // \tFreq, \widefreq, // \tFreqMF, [0.0,80], // \tFreqMD, [0.0,20], // \rateMF, [0.0,80], // \rateMD, [0.0,2], // \posRateMF, [0.0,80], // \posRateMD, [0.0,2], // \playTrFr, [0.0,1], // \granDur, [0.0,8], // \granCurve, [-10,10], // \grainGate, [0,1], MIDIClient.init; MIDIIn.connectAll; ( MIDIIn.control = { |src, chan, num, val| if (chan == 2) { switch(num, 0, { x.set(\dry, val / 127) }, 1, { x.set(\wet, val / 127) }, 2, { x.set(\rate, val.linlin(0, 127, -2, 2)) }, 3, { x.set(\posRate, val.linlin(0, 127, 0, 4)) }, 4, { x.set(\tFreq, val.linlin(0, 127, 0, 80)) }, 5, { x.set(\tFreqMF, val.linlin(0, 127, 0, 80)) }, 6, { x.set(\tFreqMD, val.linlin(0, 127, 0, 20)) }, 7, { x.set(\rateMF, val.linlin(0, 127, 0, 80)) }, 8, { x.set(\rateMD, val.linlin(0, 127, 0, 2)) }, 9, { x.set(\posRateMF, val.linlin(0, 127, 0, 80)) }, 10, { x.set(\posRateMD, val.linlin(0, 127, 0, 2)) }, 11, { x.set(\playTrFr, val.linlin(0, 127, 0, 1)) }, 12, { x.set(\granDur, val.linlin(0, 127, 0, 8)) }, 13, { x.set(\granCurve, val.linlin(0, 127, -10, 10)) }, 14, { x.set(\grainGate, val.linlin(0, 127, 0, 1)) }, 15, { x.set(\overlap, val.exprand(0.001, 40)) }, // Exponential scaling for overlap // Add more cases if needed ); }; }; )