( SynthDef(\rhubarb, { |freq = 440, gate = 1, cutoff = 600, rq = 0.3, amp = 4, modDepth = 0.3, modDepth2 = 0.5, noiseLevel = 0.8, ringFreq = 400| var env, sig1, sig2, sig3, filt1, filt2, filt3, lfo, lfo2, pan1, pan2, pan3, mix, saturatedSig; // Using GrainBuf for granular synthesis var grainBuf1, grainBuf2, grainBuf3; // Grains for the three channels, modulating playback speed for pitch control grainBuf1 = GrainBuf.ar( 2, Impulse.ar(10), // Control grain density 0.1, // Grain duration ~klezmer, // Sound source buffer 2, // Pitch shift factor 1.19, // Frequency modulation 2, // Grain density variation 0, // Start position (set dynamically for random play) -1, // Reverse playback (for added texture) 512 // Buffer size ); grainBuf2 = GrainBuf.ar( 2, Dust.ar(10), 0.08, ~klezmer, -2, // Different pitch for variety 1.25, 2, 0, -1, 512 ); grainBuf3 = GrainBuf.ar( 2, Dust.ar(10), 0.8, ~klezmer, 2, // Higher pitch for more brightness 1.25, 2, 0, -1, 512 ); // LFO to modulate filter frequency (similar to previous LFO setup) lfo = LFNoise0.kr(10).range(1 - modDepth, 1 + modDepth); lfo2 = LFNoise2.kr(4).range(1 - modDepth, 1 + modDepth); // Apply Different Filters to Each GrainBuf Signal filt1 = SVF.ar(grainBuf1, cutoff * lfo, rq); filt2 = LPF.ar(grainBuf2, 400 * lfo, rq); filt3 = HPF.ar(grainBuf3, cutoff * lfo2, rq); // ADSR Envelope for modulation env = EnvGen.kr(Env.adsr(0.0, 0.3, 0.3, 0.1), gate, doneAction: 2); // Panning each signal for stereo effect pan1 = Pan2.ar(filt1 * env * amp, -0.3); // Slightly left pan2 = Pan2.ar(filt2 * env * amp, 0.3); // Slightly right pan3 = Pan2.ar(filt3 * env * amp, 0); // Centered // Mixing the signals together mix = pan1 + pan2 + pan3; // Add all three signals saturatedSig = mix.tanh; // Output the final mixed signal Out.ar(0, saturatedSig); }).play; )