1 2declare name "karplusplus -- Karplus-Strong + Fuzz"; 3declare author "Yann Orlarey, Albert Graef"; 4declare version "1.0"; 5 6import("music.lib"); 7 8// control variables 9 10// master volume and pan 11vol = hslider("vol", 0.3, 0, 10, 0.01); // % 12pan = hslider("pan", 0.5, 0, 1, 0.01); // % 13 14// excitator and resonator parameters 15size = hslider("samples", 512, 1, 1024, 1); // #samples 16dtime = hslider("decay time", 4, 0, 10, 0.01);// -60db decay time 17 18// fuzz parameters 19drive = hslider("drive", 0, 0, 50, 0.1); // overdrive factor 20res = hslider("res", 0, 0, 20, 0.1); // filter resonance 21tone = hslider("tone", 20, 1, 20, 0.1); // filter cutoff harmonic 22level = hslider("level", 1, 0, 10, 0.01); // output gain (%) 23 24// voice parameters 25freq = nentry("freq", 440, 20, 20000, 1); // Hz 26gain = nentry("gain", 1, 0, 10, 0.01); // % 27gate = button("gate"); // 0/1 28 29/* The excitator: */ 30 31upfront(x) = (x-x') > 0.0; 32decay(n,x) = x - (x>0)/n; 33release(n) = + ~ decay(n); 34trigger(n) = upfront : release(n) : >(0.0) : +(leak); 35leak = 1.0/65536.0; // avoid denormals on Pentium 36excitator = trigger(size); 37 38/* The resonator: */ 39 40average(x) = (x+x')/2; 41att(d,t) = 1-1/pow(db2linear(60), d/(SR*t)); 42comb(d,a) = (+ : fdelay(4096, d-1.5)) ~ (average : *(1.0-a)); 43resonator(d) = comb(d,att(d,dtime)); 44 45/* DC blocker (see http://ccrma.stanford.edu/~jos/filters/DC_Blocker.html): */ 46 47dcblocker(x) = (x-x') : (+ ~ *(0.995)); 48 49// resonant lowpass 50 51// This is a tweaked Butterworth filter by David Werner and Patrice Tarrabia, 52// see http://www.musicdsp.org and http://www.experimentalscene.com for 53// details. 54 55// res = resonance in dB above DC gain 56// freq = cutoff frequency 57 58lowpass(res,freq) = f : (+ ~ g) : *(a) 59with { 60 f(x) = a0*x+a1*x'+a2*x''; 61 g(y) = 0-b1*y-b2*y'; 62 a = 1/db2linear(0.5*res); 63 64 c = 1.0/tan(PI*(freq/SR)); 65 c2 = c*c; 66 r = 1/db2linear(2.0*res); 67 q = sqrt(2.0)*r; 68 a0 = 1.0/(1.0+(q*c)+(c2)); 69 a1 = 2.0*a0; 70 a2 = a0; 71 b1 = 2.0*a0*(1.0-c2); 72 b2 = a0*(1.0-q*c+c2); 73}; 74 75/* Fuzz effect. */ 76 77clip(x) = f*x+1-f with { f = abs(drive*x)<=1; }; 78fuzz(freq) = clip : lowpass(res,tone*freq) : *(level); 79 80/* Karplus-Strong string synthesizer: */ 81 82process = vgroup("1-excitator", noise*gain : *(gate : excitator)) 83 : vgroup("2-resonator", resonator(SR/freq)) : dcblocker 84 : vgroup("3-fuzz", fuzz(freq)) 85 : vgroup("4-master", *(vol) : panner(pan)); 86