// Brad's first attempt at an SC3 app-thingy. Yeah, I know, everyone // builds a granular synth thing, but it was a true Learning Experience. // click-select from the "(" below and it should load and run ok. // // As with all gran-synth apps, be careful of your grain rate coupled // with the grain dur, it's easy to really soak the processor. // // -- BGG 3/2003 // // -- modified for SC3.3/3.4, 2/2011 ( var s, w, b, c, nchans, nframes, buf, buftext, bufenter, soundbutt, soundtext, gotext, gobutt, rateslide, ratetext, ratelo, ratehi, durslide, durtext, durlo, durhi, pchslide, pchtext, pchlo, pchhi, posslide, postext, poslo, poshi, locslide, loctext, loclo, lochi, locspread, speedslide, speedtext, speed; s = Server.local; if (s.serverRunning == false, { s.boot; }); SynthDef("plbuf1", { arg trig = 1, start = 0, gdur = 0.05, prate = 1.0, pos = 0.5, bno = 0; var out, e, amp, c1, c2; e = Env.triangle(dur: gdur, level: 1.0); amp = EnvGen.ar(e, doneAction: 2); out = PlayBuf.ar(1, bno, prate, trig, startPos: start, loop: 0); c1 = out*amp*pos; c2 = out*amp*(1.0-pos); Out.ar(0, [c1, c2]); }).load(s); SynthDef("plbuf2", { arg trig = 1, start = 0, gdur = 0.05, prate = 1.0, pos = 0.5, bno = 0; var out, e, amp, c1, c2; e = Env.triangle(dur: gdur, level: 1.0); amp = EnvGen.ar(e, doneAction: 2); out = PlayBuf.ar(2, bno, prate, trig, startPos: start, loop: 0); c1 = out.at(0)*amp*pos; c2 = out.at(1)*amp*(1.0-pos); Out.ar(0, [c1, c2]); }).load(s); ratelo = 0.2; ratehi = 0.21; durlo = 0.04; durhi = 0.06; pchlo = 1.0; pchhi = 1.0; poslo = 0.5; poshi = 0.5; loclo = 0.1; lochi = 0.2; locspread = 0.1; speed = 0.005; buf = 0; w = SCWindow("hi there!", Rect(100, 500, 300, 425)); soundtext = SCStaticText(w, Rect(30,5, 60,20)); soundtext.font = Font("Helvetica", 10); soundtext.stringColor = Color.blue; soundtext.align = \center; soundtext.string = "soundfile"; soundbutt = SCButton(w, Rect(30,30, 60, 20)); soundbutt.states = [ ["load", Color.black, Color.new(0.0, 0.5, 0.9)], ]; soundbutt.action = { arg view; buf = bufenter.value; // get the value of the current buffer File.openDialog("hey hey hey", { arg path; var sf; sf = SoundFile.new; sf.openRead(path); nchans = sf.numChannels; nframes = sf.numFrames; sf.close; s.sendMsg("/b_allocRead", buf, path, 0, nframes); gobutt.enabled = true; }); }; buftext = SCStaticText(w, Rect(120,5, 60,20)); buftext.font = Font("Helvetica", 10); buftext.stringColor = Color.blue; buftext.align = \center; buftext.string = "buffer #"; bufenter = SCNumberBox(w, Rect(140,30, 20,20)); bufenter.align = \center; bufenter.setProperty(\background, Color.new(0.8, 0.5, 0.9)); bufenter.value = 0; gotext = SCStaticText(w, Rect(210,5, 70,20)); gotext.font = Font("Helvetica", 10); gotext.stringColor = Color.blue; gotext.align = \center; gotext.string = "granulatarize..."; gobutt = SCButton(w, Rect(210,30, 60, 20)); gobutt.states = [ ["GO!", Color.black, Color.new(0.0, 0.5, 0.9)], ["nomore!", Color.white, Color.new(0.8, 0.5, 0.9)], ]; gobutt.action = { arg view; if (gobutt.value == 1, { b = Routine({ loop ({ if (nchans == 1, { Synth("plbuf1", ["start", rrand(loclo, lochi)*(nframes- (durhi*(44100*pchhi))), "gdur", rrand(durlo, durhi), "prate", rrand(pchlo, pchhi), "pos", rrand(poslo, poshi), "bno", buf]); },{ Synth("plbuf2", ["start", rrand(loclo, lochi)*(nframes- (durhi*(44100*pchhi))), "gdur", rrand(durlo, durhi), "prate", rrand(pchlo, pchhi), "pos", rrand(poslo, poshi), "bno", buf]); }); rrand(ratelo, ratehi).wait; }) }).play; c = Routine({ loop ({ 0.01.wait; loclo = loclo + speed; lochi = lochi + speed; if (lochi > 1.0, { loclo = 0.0; lochi = loclo+locspread; }); if (loclo < 0.0, { lochi = 1.0; loclo = lochi-locspread; }); locslide.setProperty(\lo, loclo); locslide.setProperty(\hi, lochi); }); }); AppClock.play(c); },{ b.stop; c.stop; }); }; gobutt.enabled = false; ratetext = SCStaticText(w, Rect(10,60, 90,20)); ratetext.font = Font("Helvetica", 10); ratetext.stringColor = Color.blue; ratetext.align = \left; ratetext.string = "grain rate"; rateslide = SCRangeSlider(w, Rect(10,85, 280,20)); rateslide.lo = ratelo+0.01; rateslide.hi = ratehi+0.01; rateslide.action = { arg slider; ratelo = rateslide.lo+0.0025; ratehi = rateslide.hi+0.0025; //the "ratelo" multiplier protects a bit against CPU overload durlo = (durslide.lo+0.0025)*(ratelo*10.0); durhi = (durslide.hi+0.0025)*(ratelo*10.0); }; durtext = SCStaticText(w, Rect(10,120, 90,20)); durtext.font = Font("Helvetica", 10); durtext.stringColor = Color.blue; durtext.align = \left; durtext.string = "grain duration"; durslide = SCRangeSlider(w, Rect(10,145, 280,20)); durslide.lo = durlo+0.01; durslide.hi = durhi+0.01; durslide.action = { arg slider; //the "ratelo" multiplier protects a bit against CPU overload durlo = (durslide.lo+0.0025)*(ratelo*10.0); durhi = (durslide.hi+0.0025)*(ratelo*10.0); }; pchtext = SCStaticText(w, Rect(10,180, 90,20)); pchtext.font = Font("Helvetica", 10); pchtext.stringColor = Color.blue; pchtext.align = \left; pchtext.string = "pitch variance"; pchslide = SCRangeSlider(w, Rect(10,205, 280,20)); pchslide.lo = pchlo/2.0; pchslide.hi = pchhi/2.0; pchslide.action = { arg slider; pchlo = (pchslide.lo*2.0); pchhi = (pchslide.hi*2.0); }; postext = SCStaticText(w, Rect(10,240, 90,20)); postext.font = Font("Helvetica", 10); postext.stringColor = Color.blue; postext.align = \left; postext.string = "stereo variance"; posslide = SCRangeSlider(w, Rect(10,265, 280,20)); posslide.lo = poslo; posslide.hi = poshi; posslide.action = { arg slider; poslo = posslide.lo; poshi = posslide.hi; }; loctext = SCStaticText(w, Rect(10,300, 90,20)); loctext.font = Font("Helvetica", 10); loctext.stringColor = Color.blue; loctext.align = \left; loctext.string = "playback location"; locslide = SCRangeSlider(w, Rect(10,325, 280,20)); locslide.lo = loclo; locslide.hi = lochi; locslide.action = { arg slider; loclo = locslide.lo; lochi = locslide.hi; locspread = lochi-loclo; }; speedtext = SCStaticText(w, Rect(10,360, 90,20)); speedtext.font = Font("Helvetica", 10); speedtext.stringColor = Color.blue; speedtext.align = \left; speedtext.string = "playback speed"; speedslide = SCSlider(w, Rect(10,385, 280,20)); speedslide.value = (speed/0.05)+0.5; speedslide.action = { arg slider; speed = (speedslide.value-0.5)*0.05; }; w.front; )