s.boot; b = Buffer.read(s, "/home/lcoogan/Misc/grave.wav"); ( SynthDef("tonal_grain_sample", { arg freq = 220, gate = 1, outBus = 0, gain = 0.1; var env, t, grainDur, pos, rate, sig, baseFreq; // Envelope to shape amplitude env = EnvGen.kr( Env.adsr(0.01, 0.1, 0.6, 1.5, curve: -4), gate, doneAction: 2 ); // Trigger for grains t = Impulse.ar(freq); // Duration of each grain grainDur = 0.1; // Playback rate controls pitch: freq / base pitch of sample baseFreq = 220; // You can adjust this depending on your sample rate = freq / baseFreq; // Position in buffer: random or LFO modulation pos = LFNoise1.kr(1).range(0, 0.3); // pick random spots in the buffer // Granulate the sample buffer tonally sig = GrainBuf.ar( numChannels: 2, trigger: t, dur: grainDur, sndbuf: b, // use your sample buffer rate: rate, pos: pos, interp: 2 ); sig = sig * env; sig = FreeVerb.ar(sig, 0.3, 0.9); sig = LeakDC.ar(sig); Out.ar(outBus, sig * gain); }).add; ) Synth(\tonal_grain_sample, [ \grainDur, 0.3, \freq, [50].midicps]);