// default s = Server.local; s.boot; ServerOptions.outDevices; s.quit; ( Buffer.freeAll; ~path = PathName(thisProcess.nowExecutingPath).parentPath; b= ( afx1: Buffer.read(s, ~path ++ "afx_bbb1.wav"), afx2: Buffer.read(s, ~path ++ "afx_bbb2.wav"), beeth1: Buffer.read(s, ~path ++ "beeth_59n3_1.wav"), beeth2: Buffer.read(s, ~path ++ "beeth_59n3_2.wav"), beeth3: Buffer.read(s, ~path ++ "beeth_59n3_3.wav"), cym: Buffer.read(s, ~path++ "cym1.wav"), dav1: Buffer.read(s, ~path++ "davis_corner1.wav"), dav2: Buffer.read(s, ~path++ "davis_corner2.wav"), dav3: Buffer.read(s, ~path++ "davis_corner3.wav"), dav4: Buffer.read(s, ~path++ "davis_corner4.wav"), hat: Buffer.read(s, ~path ++ "hat1.wav"), kick: Buffer.read(s, ~path ++ "kick1.wav"), kick: Buffer.read(s, ~path ++ "kick1.wav"), m80: Buffer.read(s, ~path ++ "m080.caf") , calung: Buffer.read(s, ~path ++ "calung2.wav") , gangsalo: Buffer.read(s, ~path ++ "gangsalo2.wav") , gangsa: Buffer.read(s, ~path ++ "gangsamid2.wav") ); ) b.keys; b.afx1.play; ( SynthDef(\sine, { // declare a synth named '\sine' var sig; sig = SinOsc.ar(\freq.ir(440), \phs.ir(0)); // it's a sine wave // it takes arguments: \freq, \phs, \pan, \amp \atk \sus \rel sig = Pan2.ar(sig, \pan.ir(0), \amp.kr(0.2)); // it's sig = sig * Env( // put the \sine sound in an envelope (ASDR) levels: [0,1,1,0], times: [\atk.ir(0.001), \sus.ir(0.03), \rel.ir(0.001)], curve: [\atkcrv.ir(-4), 0, \relcrv.ir(-4)] ).ar(Done.freeSelf); // delete when env is done Out.ar(\out.ir(0), sig); // output to audio channel 0 and 1? }).add; ) ( SynthDef(\samp, { var sig, env, buf = \buf.ir(0); sig = PlayBuf.ar(1, buf, BufRateScale.ir(buf)* \rate.ir(1)); sig = LPF.ar(sig, \lpf.ir(20000)); sig = Pan2.ar(sig, \pan.ir(0), \amp.kr(0.2)); sig = sig * Env( levels: [0,1,1,0], times: [\atk.ir(0.001), \sus.ir(1), \rel.ir(1)], curve: [0, 0, \relcrv.ir(-4)] ).ar(Done.freeSelf); Out.ar(\out.ir(0), sig); }).add; ) Synth(\sine); Synth(\samp, [buf: b.hat]); Synth(\samp, [buf: b.cym]); Synth(\samp, [buf: b.kick]); /////// lect 2 // function decl ( ~makeNotes = { |root=0,ct=4| var scale = [0,2,4,5,7,9,11], notes; scale = scale + root; notes = scale.scramble.keep(ct); }) // function call ~res = ~makeNotes.(4,5); ~res = ~makeNotes.value(4,5); rrand(1,10); // rand # 1..10 exprand(1,10); // exponential distrib; weighted towards first # // makes an attay of size x and fills it w random numbers { rrand(1,100) }.dup(x); { rrand(1,100) } ! x; // operation on all the elemnts of array ( x = [0,2,4,5,7,9,10]; y = x.do({ |item| // for each item in arr, doesn't change x item + rrand(2,3); // add 2 or 3 }); ) ( x = [0,2,4,5,7,9,10]; y = x.collect({ |item| // foreach; x is changed, copied to y item + rrand(2,3); // add 2 or 3 }); ) /////// lect 3 // browse ugens ( x = { PinkNoise.ar * -20.dbamp; }.play; ) ) // ugen framework: a fn defn + call to ".play" ( x = { ugen.ar; }.play; ) // SinOsc, Saw, LFTri, Impulse, PinkNoise, BrownNoise, WhiteNoise, ClipNoise // ctlr-m brings up meter // draws waveform for elapsed time dt ( x = { ugen.ar; }.plot(dt); ) // first modulation example ( x={ var mod, modmod, sig; mod = LFNoise2.kr(10).range(800, 900); sig = SinOsc.ar(mod); sig = sig * 0.2; }.play; ) x.free; // stops x playing // first stereo example ( x={ var sig; sig = [ SinOsc.ar(300), SinOsc.ar(301) ]; sig = sig * 0.5; }.play; ) // first osc array ( x={ var sig; sig = SinOsc.ar(freq: { exprand(100,4000) } ! 50); // make 50 oscillators sig = sig.sum; // add em all together sig = sig * 0.03; }.play; ) // ( x={ var sig; sig = SinOsc.ar(freq: { exprand(100,1000) } ! 10); // make 10 oscillators sig = Splay.ar(inArray: sig); sig = sig * 0.1; }.play; ) /////// lect 4 // parameters ( x={ arg freq=#[300,301], wdt = 0.9, amp = 0.3; // #=> literal var sig; sig = VarSaw.ar(freq: freq, width:wdt); sig = sig * amp; }.play; ) s.scope; x.set(\wdt, 0.5); x.set(\freq, [220, 223]); ( x={ var sig; sig = VarSaw.ar(freq: \freq.kr(330), width:wdt); sig = sig * amp; }.play; ) x.set(\wdt, 0.5); x.set(\freq, [220, 223]); ( x={ arg freq=330, wdt = 0.9, amp = 0.3; // #=> literal var sig; sig = VarSaw.ar(freq: freq.lag(0.5) + [0,3], width:wdt); // "+ [0,3]" adds freq to both; returns an array // '.lag(' adds lerp to freq change sig = sig * amp.varlag(1.0, 3); // '.varlag' adds slerp; 3 controls spline curvature }.play; ) s.scope; x.set(\wdt, 0.5); x.set(\freq, 220); // scsynth.org -> resources -> sort by views // -> token args // envelopes ( e = Env.new( levels: [0,1,0], times: [0.5,2], curve: [-4,-1] ); ) e.plot; ( x={ var sig, env; env = EnvGen.kr( Env.new(levels:[0,1,0], times:[0.5,1], curve:[-4,-1]), doneAction: Done.freeSelf ); sig = VarSaw.ar(freq: [300,305], width: \wtd.kr(0.8)); sig = sig * env; sig = sig * \amp.kr(0.1); }.play; ) x.set(\wdt, 0.5); x.set(\freq, [220, 223]); ( x={ var sig, env; env = Env.new(levels:[0,1,0], times:[0.001,0.88], curve:[-4,-1]) .kr(0, \trig.kr(1)); // <= sig = VarSaw.ar(freq: [300,305], width: \wtd.kr(0.8)); sig = sig * env; sig = sig * \amp.kr(0.1); }.play(fadeTime:0); ) x.set(\trig, 0); x.set(\trig, 1);// have to set to 0, then 1 to trig ( x={ var sig, env; env = Env.new(levels:[0,1,0], times:[0.02,0.1], curve:[-4,-1]) .kr(0, \trig.tr(1)); // <= sets to 1 for 1 cyc sig = VarSaw.ar(freq: [300,305], width: \wtd.kr(0.8)); sig = sig * env; sig = sig * \amp.kr(0.1); }.play(fadeTime:0); ) x.set(\trig, 1);// no need to reset // init starts note w/sustain ( x={ arg gate=1, da=0; var sig, env; env = Env.new(levels:[0,1,0.2,0], times:[0.005,0.25,2], curve:[-4,-1,-1], releaseNode:2).kr(da, gate); sig = VarSaw.ar( freq: [300,305], width: \wtd.kr(0.8)); sig = sig * env; sig = sig * \amp.kr(0.1); }.play(fadeTime:0); ) x.set(\gate, 0);// // stop at L4 (week 5) 47:46 // synthdef & synth ( x={ var sig; sig = VarSaw.ar( freq: [300,305], width: \wtd.kr(0.8)); sig = sig * \amp.kr(0.1); }.play; ) ( SynthDef.new(\pikachu, { var sig; sig = VarSaw.ar( freq: [300,305], width: \wtd.kr(0.8)); sig = sig * \amp.kr(0.1); Out.ar(\out.kr(0), sig); }).add; ) x = Synth.new(\pikachu); /////// end of chapter 2 //// week 5 // 4 filter types: low-pass, hi-pass, // band-pass, and band reject ( x={ var sig; sig = PinkNoise.ar(0.3 ! 2); sig = LPF.ar(in: sig, freq:MouseX.kr(10,2000)); }.play; ) // filters can explode; don't use #s outside 00, // that's a trigger. startPos: 0, // sample index loop: \loop.kr(1) // x=>doneAction: 2 ); sig = sig * env * \amp.kr(0.5); Out.ar(\out.ir(0), sig); }).add; ) x = Synth(\play, [buf:b.beeth3, amp: 2.0, rate:2]); ( SynthDef(\play, { arg buf = 0; var sig, env; env = Env( levels: [0,1,0], times: [\atk.ir(0.001), \rel.ir(0.5)], curve: [0, -4] ).ar(2); sig = PlayBuf.ar( numChannels: 2, bufnum: buf, rate: BufRateScale.ir(buf) * \rate.kr(1), trigger: Impulse.kr(\trighz.kr(6)), startPos: \spos.kr(0), loop: \loop.kr(1) // x=>doneAction: 2 ); sig = sig * env * \amp.kr(0.5); Out.ar(\out.ir(0), sig); }).add; ) ( 2.do({ x = Synth(\play, [ buf: b.beeth2, amp: -1.dbamp, loop: 1, rel: 5.0, rate: rrand(0.3,4.0), spos: rrand(0, b.beeth2.numFrames), trighx: exprand(1,80) ]);});) ( SynthDef(\play, { arg buf = 0; var sig; sig = PlayBuf.ar( numChannels: 2, bufnum: buf, rate: BufRateScale.ir(buf) * \rate.kr(1), trigger: Impulse.kr(MouseY.kr(1,100,1)), startPos: MouseX.kr(0, BufFrames.kr(buf)*0.9), loop: \loop.kr(1) ); sig = sig * \amp.kr(0.5); Out.ar(\out.ir(0), sig); }).add; ) ( x = Synth(\play, [ buf: b.beeth3, amp: 1.0, rate: -1.midiratio, ]);) ( x = Synth(\play, [ buf: b.beeth2, amp: 1.0, rate: -4.midiratio, rel: 8, ]);) ( x = Synth(\play, [ buf: b.dav1, amp: 1.0, rate: -4.midiratio, rel: 8, ]);) /// BufRd ( Buffer.freeAll; ~path = PathName(thisProcess.nowExecutingPath).parentPath; b= ( afx1: Buffer.read(s, ~path ++ "afx_bbb1.wav"), afx2: Buffer.read(s, ~path ++ "afx_bbb2.wav"), beeth1: Buffer.read(s, ~path ++ "beeth_59n3_1.wav"), beeth2: Buffer.read(s, ~path ++ "beeth_59n3_2.wav"), beeth3: Buffer.read(s, ~path ++ "beeth_59n3_3.wav"), cym: Buffer.read(s, ~path++ "cym1.wav"), dav1: Buffer.read(s, ~path++ "davis_corner1.wav"), dav2: Buffer.read(s, ~path++ "davis_corner2.wav"), dav3: Buffer.read(s, ~path++ "davis_corner3.wav"), dav4: Buffer.read(s, ~path++ "davis_corner4.wav"), hat: Buffer.read(s, ~path ++ "hat1.wav"), kick: Buffer.read(s, ~path ++ "kick1.wav"), kick: Buffer.read(s, ~path ++ "kick1.wav"), m80: Buffer.read(s, ~path ++ "m080.caf") , calung: Buffer.read(s, ~path ++ "calung2.wav") , gangsalo: Buffer.read(s, ~path ++ "gangsalo2.wav") , gangsa: Buffer.read(s, ~path ++ "gangsamid2.wav") , ); ) b.keys; b.afx1.play; ( SynthDef(\read, { arg buf = 0; var sig, phs; phs = Line.ar(start: 0, end: BufFrames.ir(buf)-1, dur: BufDur.ir(buf) * \durscl.ir(1), doneAction: 2 ); // note '.ar'-> audio rate reqd for BufRd sig = BufRd.ar(// 'phs' controls which sample is accessed at every read numChannels: 2, bufnum: buf, phase: phs ); sig = sig * \amp.kr(0.75); Out.ar(\out.ir(0), sig); }).add; ) Synth(\read, [buf: b.afx1, durscl:1]); // stopped at 30:27 // BufRd makes it v. easy to play buffers synchronously-- use the same fn for all. // to do it with playbuf, you have to make super-precise start times // and playback speeds. ( SynthDef(\read, { arg buf = 0; var sig, phs; phs = LFSaw.ar( freq: 1.0/BufDur.ir(buf) * \rate.kr(1), iphase:1 ).range(0, BufFrames.ir(buf)-1); sig = BufRd.ar( numChannels: 2, bufnum: buf, phase: phs, loop: 1 // for BufRd, allows out-of-range sample access (wraps em) ); sig = sig * \amp.kr(0.75); Out.ar(\out.ir(0), sig); }).add; ) { LFSaw.ar(2000)}.plot(1/1000); Synth(\read, [buf: b.beeth2, rate:3.midiratio]); // vibrato ( SynthDef(\play4, { arg buf = 0; var sig, env; env = Env( levels: [0,1,0], times: [\atk.ir(0.001), \rel.ir(2.5)], curve: [0, -4] ).ar(2); sig = PlayBuf.ar( numChannels: 2, bufnum: buf, rate: BufRateScale.ir(buf) * \rate.kr(1) * (SinOsc.kr(6).bipolar(\vib.kr(0.5)).midiratio), loop: \loop.kr(1) ); sig = sig * env * \amp.kr(0.5); Out.ar(\out.ir(0), sig); }).add; ) x = Synth(\play4, [buf:b.beeth2, amp: 2.0, rate:1]); //////////////////////////// week 7: sequencing ( SynthDef(\sine, { var sig; sig = SinOsc.ar(\freq.ir(440), \phs.ir(0)); sig = Pan2.ar(sig, \pan.ir(0), \amp.kr(0.2)); sig = sig * Env( levels: [0,1,1,0], times: [\atk.ir(0.001), \sus.ir(0.03), \rel.ir(0.001)], curve: [\atkcrv.ir(-4), 0, \relcrv.ir(-4)] ).ar(Done.freeSelf); Out.ar(\out.ir(0), sig); }).add; ) ( SynthDef(\samp, { var sig, env, buf = \buf.ir(0); sig = PlayBuf.ar(1, buf, BufRateScale.ir(buf)* \rate.ir(1)); sig = LPF.ar(sig, \lpf.ir(20000)); sig = Pan2.ar(sig, \pan.ir(0), \amp.kr(0.2)); sig = sig * Env( levels: [0,1,1,0], times: [\atk.ir(0.001), \sus.ir(1), \rel.ir(1)], curve: [0, 0, \relcrv.ir(-4)] ).ar(Done.freeSelf); Out.ar(\out.ir(0), sig); }).add; ) Synth(\sine); Synth(\samp, [buf: b.hat]); Synth(\samp, [buf: b.cym]); Synth(\samp, [buf: b.kick]); f.(); ( r = Routine({ 0.postln; // prints a "0" 1.yield; // just yields; the 1/any #, irrelevant 10.postln; 2.yield; 100.postln; });) r.next; ( f = { Synth(\samp, [buf: b.m80, atk:0.2, rate: -30.midiratio, amp:0.25]); 1.yield; Synth(\samp, [buf: b.m80, atk:0.2, rate: -23.midiratio, amp:0.25]); 1.yield; Synth(\samp, [buf: b.m80, atk:0.2, rate: -20.midiratio, amp:0.25]); 1.yield; Synth(\samp, [buf: b.m80, atk:0.2, rate: -16.midiratio, amp:0.25]); }; ) ( r = Routine(f);) r.next; r.reset; ( g = { [-30,-23,-20,-16].collect({|rate| Synth(\samp, [buf: b.m80, atk:0.2, rate: rate.midiratio, amp:0.25] ); 1.yield; }); }; ) ( r = Routine(g);) r.next; r.reset; ( g = { [0,3,5,9].collect({|shift| [-30,-23,-20,-16].collect({|rate| Synth(\samp, [buf: b.m80, atk:0.2, rate: (rate+shift).midiratio, amp:0.1] ); exprand(0.1,0.3).yield; }); }); };) r = Routine(g).play; ( g = { loop({ [-30,-23,-20,-16].collect({|rate| s.bind({ // improves timing Synth(\samp, [buf: b.m80, atk:0.1, rate: rate.midiratio, amp:0.1] ); }); exprand(0.1,0.3).yield; // note timing! // if it's not there, plays oo# of sounds at once }); }); };) r = Routine(g).play; r.stop; // stops, but then to restart, you have to use r.reset; r.play; ///// Routine as a sound generator ///////////////////////////// ///// algorithmic data source (eg a pitch generator) ( ~pchFn = { var note; loop{ note = -12; note.yield; 7.do { note = note + [2,5,7,0,1,4].choose; note.yield; }; }; }; ~pchGen = Routine(~pchFn); ) ~pchGen.next; ~pchGen.reset; Synth(\samp, [buf: b.gangsa, rate:~pchGen.next.midiratio]); ( ~synthFn = { loop({ Synth(\samp, [buf: b.gangsa, rate:~pchGen.next.midiratio]); 0.2.wait; // if it's not there, plays oo# of sounds at once }); }; ~synthGen = ~synthFn.r; // is the same as nxt line // ~synthGen = Routine(~synthFn); ) ~synthGen.play; ~synthGen.stop; // or maybe even! ~synthGen = Routine(~synthFn).play; // still more inscrutably! ~synthGen = r(~synthFn).play; // conceptual note: fns are the score; Routines are performers of fns // TempoClock // DAWs usually got a vertical grid for timing. // for supercol, TempoClock is that thing. TempoClock.default.beats; t = TempoClock.new(98/60); ( ~pchFn2 = { var note; loop{ note = -12; note.yield; 3.do { note = note + [2,5,7].choose; note.yield; }; }; }; ~pchGen2 = Routine(~pchFn2); ~synthFn2 = { loop({ Synth(\samp, [buf: b.gangsa, rate:~pchGen2.next.midiratio]); 0.2.wait; }); }; ~synthGen2 = r(~synthFn2).play(t); ) // F3 deletes all TempoClocks (except the permanent ones) // (TempoClock.default is permanent) ( ~post = { t.beats.postln; 1; }; // return 1; schedAbs uses it t.schedAbs(t.nextBar, { ~post.(); }); // to know which measure to run fn on again ) // heh, this is me not following the lecture ( ~aclock = TempoClock.new(60/60); ~synthFn3 = { // fast tapping hat loop({ Synth(\samp, [buf: b.hat]); 0.125.wait; }); }; ~synthGen3 = r(~synthFn3).play(clock: ~aclock); ~pchFn2 = { var note; loop{ note = -12; note.yield; 4.do { note = note + [2,5,7,1,5,3].choose; note.yield; }; }; }; ~pchGen2 = Routine(~pchFn2); ~synthFn2 = { loop({ Synth(\samp, [buf: b.gangsa, rate:~pchGen2.next.midiratio]); 0.5.wait; }); }; ~synthGen2 = r(~synthFn2).play(clock: ~aclock); ~synthFn3 = { loop({ Synth(\samp, [ buf: b.calung, amp: 0.05, rate:(12+~pchGen2.next.midiratio)]); 0.25.wait; }); }; ~synthGen3 = r(~synthFn3).play(clock: ~aclock); ) // quantization ( ~aclock = TempoClock.new(98/60); // pitch generator, v3, same as the other two ~pchFn3 = { var note; loop{ note = -12; note.yield; 3.do { note = note + [2,5,7].choose; note.yield; }; }; }; ~pchGen3 = Routine(~pchFn3); // hihat to mark the beat ~hatSynth = { loop({ Synth(\samp, [buf: b.hat]); 1.wait; }); }; ~hatGen = r(~hatSynth).play(clock: ~aclock, quant: 1); ~r0 = r{ loop({ Synth(\samp, [buf: b.calung, rate:[0,3,5].choose.midiratio, amp:0.2]); 2.5.wait; }); }.play(~aclock, quant:4); ~r1 = r{ loop({ Synth(\samp, [buf: b.calung, rate:[0,3,5,7].choose.midiratio/2, amp:0.2]); 0.5.wait; }); }.play(~aclock, quant:4); ~r2 = r{ loop({ Synth(\samp, [buf: b.calung, rate:[0,3,5,7].choose.midiratio/3, amp:0.5, rel:0.2, sus:0]); 1.3333333.wait; }); }.play(~aclock, quant:4); ~r3 = r{ loop({ Synth(\samp, [buf: b.calung, rate:[0,3,5,7,9,10].choose.midiratio*2, amp:0.05, rel:0.2, sus:0]); 0.25.wait; }); }.play(~aclock, quant:4); ) // "a baby livecoding session" /////////////////////////////////////////////////////////// // week 8: patterns, events, streams //Browse -> Document Browser -> streams-patters-events -> // a-practical-guide: recommended // patterns define sequences // events deliver seqs // streams perform them? // there is a document he wants you to just read thru // get familiar with the core set of common patterns // common_patterns.scd // all pattern classes start with a "P" ( p = Pseq([4,9,3], inf); // output in order, oo loop q = p.asStream; ) q.next; q.nextN(20); // => [4,9,3,4,9,3,...] ( p = Prand([4,9,3], inf); // randomly choose q = p.asStream; ) q.nextN(20); ( p = Pxrand([4,9,3], inf); // as Prand, but nothing twice in a row q = p.asStream.nextN(20); ) ( p = Pwrand([4,9,3], [1,10,30].normalizeSum, inf); // weighted liklihood of selection q = p.asStream.nextN(20); ) ( p = Pshuf([4,9,3,2,7,1], inf); // reorder, then as Pseq q = p.asStream.nextN(20); ) ( p = Pseries(1, 3, inf); // n[i] = n[i-1]+3 q = p.asStream.nextN(20); ) ( p = Pgeom(1, 2.1, inf); // n[i]=n[i-1]*2.1 q = p.asStream.nextN(20); ) ( p = Pwhite(1, 1000, inf); // output numbers in a range q = p.asStream.nextN(20); ) ( p = Pbrown(1, 1000, inf); // random #s in range, exp distrib q = p.asStream.nextN(20); ) ( p = Plprand(1, 100, inf); // call Pwhite twice, return lower q = p.asStream.nextN(20); ) ( p = Phprand(1, 100, inf); // call Pwhite twice, return higher q = p.asStream.nextN(20); ) ( p = Pn( Pshuf([1,2,3,4,5], 1), inf); // concat calls to Pshuf q = p.asStream.nextN(20); ) ( p = Pfin(15, Pwhite(1, 9, inf)); // returns nil after value# 15 q = p.asStream.nextN(20); ) ( p = Pdup(3, Pwhite(1, 9, inf)); // generate pattern and repeat q = p.asStream.nextN(20); // ->[ 2, 2, 2, 3, 3, 3, 6, 6, 6, 6, 6, 6, 1, 1, 1, 9, 9, 9, 8, 8 ] ) ( // Pfunc: use a fn to make #s p = Pfunc({ var num; num = rrand(1,9); if (num>7, {num=num+[2,4,6].choose}, {num}); if (rrand(1,9)<3, {num=num.neg}, {num}); }); q = p.asStream.nextN(20); ) ( // Plazy - IDK p = Pn( Plazy({ Pseq([rrand(10,30)], [1,3,5].choose ); }), inf); q = p.asStream.nextN(20); ) // there is more in "common patterns.scd" ////////////////////// // examples of other pattern generators ~pchFn2 = { var note; loop{ note = -12; note.yield; 3.do { note = note + [2,5,7].choose; note.yield; }; }; }; ~pchGen2 = Routine(~pchFn2); ( ~pat = { var num=50, inc=7, count=0; while ({count<6}, { num.yield; num = num + inc; count = count + 1; }); }; ~seq = r(~pat); ) ~seq.next; ( // rewriting previous pat, more simply, with a Pseries ~pat = Pseries(50,7,6); ~seq = ~pat.asStream.nextN(20); ) ( ~pat = Pseq([1,2,3], inf); ~pat = ~pat + Pseq([10,20], inf); ~seq = ~pat.asStream.nextN(20); ) ( // illustrating the use of several Ps within a P ~pat = Pseq([ 5, Pwhite(lo:1, hi:9, length: 1), 12, Pseq([2,3],2)], 3); ~seq = ~pat.asStream.nextN(20); // [5,rand#,12,2,3,2,3,5,rand#,12,2,3,2,3,5,r#,12,2,3,2,3,nil,..] ) // output number -14 // but SC can play them ().play; // def instrument, def pitch, duration, ect: piano playing 'c' Event.eventTypes.keys.postln; // -> ( 'instrument': default, 'msgFunc': a Function, // 'amp': 0.1, 'server': localhost, 'sustain': 0.8, // 'isPlaying': true, 'freq': 261.6255653006, 'hasGate': true, // 'id': [ 1001 ] ) (amp:1, midinote:60).play; Event.partialEvents.pitchEvent[\midinote].postcs; //-> #{ (((~note.value + ~gtranspose + ~root) / ~scale.respondsTo(\stepsPerOctave).if( { ~scale.stepsPerOctave }, ~stepsPerOctave) + ~octave - 5.0) * (12.0 * ~scale.respondsTo(\octaveRatio).if ({ ~scale.octaveRatio }, ~octaveRatio).log2) + 60.0);} Event.partialEvents.pitchEvent[\freq].postcs; // -> #{(~midinote.value + ~ctranspose).midicps * ~harmonic;} Event.partialEvents.pitchEvent[\ctranspose].postcs; //-> 0.0 Event.partialEvents.pitchEvent[\harmonic].postcs; //-> 1.0 ( (amp:1, degree:0).play; (amp:1, degree:2).play; (amp:1, degree:4).play; ) ( (amp:1, note:0).play; (amp:1, note:4).play; // ?? ... many fns available for freq generation (amp:1, note:7).play; ) (instrument: \sine).play; ( SynthDef(\saw, { // define a sawtooth that demands explicit on/off msgs var sig, buf = \buf.ir(0); sig = Saw.ar(\freq.ir(200), mul: 0.5); sig = RLPF.ar(in: sig, freq: \lpf.ir(20000).clip(20,20000), rq: \rq.ir(1)); sig = sig * Env.adsr().ar(2, \gate.kr(1)); // sounds till gate=0 sig = Pan2.ar(sig, \pan.ir(0), \amp.ir(0.5)); Out.ar(\out.ir(0), sig); }).add; ) x = Synth(\saw); // plays till you run next line x.set(\gate, 0); (instrument:\saw).play; // plays 1sec; events have lots of default behavior (instrument:\saw, sendGate: false).play; (instrument:\saw, sustain: 2.0).play; // back to patterns // Pbind defines a seq of events ( ~pat = Pbind( \instrument, \saw, \freq, 300, \sustain, 0.2); ~seq = ~pat.asStream; ) ~seq.next(()).play; // note proffered empty event for filling ( // ensleeken! ~pat = Pbind( \instrument, \saw, \dur, 0.1, \midinote, 72, \sustain, 0.2 ); ~seq = ~pat.play; ) ~seq.stop; ( // but Pbind is a seq; put seqs into it ~pat = Pbind( \instrument, \saw, \dur, Prand([0.2,0.4,0.6], inf), \midinote, Pwhite(40,80, inf), \sustain, 0.2); ~seq = ~pat.play; ) ~seq.stop; // but that sounds really stupid: fix that ( ~pat = Pbind( \instrument, \samp, \rel, 0.1, \buf, b.calung, \dur, Pseq([Pseq([0.05],6), Pwhite(0.2,1,1)], inf), \rate, Pseq([Pseries(0,-1,7)], inf).midiratio, \midinote, Pwhite(40,80, inf), \sustain, 0.2); ~seq = ~pat.play; ) ~seq.stop; ///////////////////////////////////////////// week 9 ( SynthDef(\echo, { var sig, fx; sig = SinOsc.ar(\freq.ir(500) + [0,3]); sig = sig * Env.perc(0.001, \rel.ir(1), 1, \crv.ir(-10)).ar(2); sig = sig * \amp.ir(0.3); Out.ar(\out.ir(0), sig); }).add; ) Synth(\echo, [freq: rrand(45,85).midicps, amp:0.5]); ( SynthDef(\echo2, { var sig, fx; sig = SinOsc.ar(\freq.ir(500) + [0,3]); sig = sig * Env.perc(0.001, \rel.ir(1), 1, \crv.ir(-10)).ar(2); fx = CombL.ar(sig, 0.2, 0.2, 4); sig = sig + fx; sig = sig * \amp.ir(0.3);// adds echo, but Env clips it @ end Out.ar(\out.ir(0), sig); }).add; ) Synth(\echo2, [freq: rrand(45,85).midicps, amp:0.5]); ( SynthDef(\echo3, { var sig, fx; sig = SinOsc.ar(\freq.ir(500) + [0,3]); sig = sig * Env.perc(0.001, \rel.ir(1), 1, \crv.ir(-10)).ar(0);//! // removes env, but they'll all run forever & crush yr RAM fx = CombL.ar(sig, 0.2, 0.2, 4); sig = sig + fx; sig = sig * \amp.ir(0.3); Out.ar(\out.ir(0), sig); }).add; ) Synth(\echo3, [freq: rrand(45,85).midicps, amp:0.5]); ( SynthDef(\echo4, { var sig, fx; sig = SinOsc.ar(\freq.ir(500) + [0,3]); sig = sig * Env.perc(0.001, \rel.ir(1), 1, \crv.ir(-10)).ar(0);//! fx = CombL.ar(sig, 0.2, 0.2, 4); sig = sig + fx; Line.ar(0,0,4, doneAction:2); // deletes, but not keyed to need sig = sig * \amp.ir(0.3); Out.ar(\out.ir(0), sig); }).add; ) Synth(\echo4, [freq: rrand(45,85).midicps, amp:0.5]); // do it right! ( // never mind the echo for now SynthDef(\ook, { var sig, fx; sig = SinOsc.ar(\freq.ir(500) + [0,3]); sig = sig * Env.perc(0.001, \rel.ir(1), 1, \crv.ir(-10)).ar(2); sig = sig * \amp.ir(0.3); Out.ar(\out.ir(0), sig); }).add; ) ( // this does the echo, echos whatever's on the input bus, outs to 0 SynthDef(\echoer, { var sig; sig = In.ar(\in.ir(7), 2); // l and rt channel inputs sig = sig + CombL.ar(sig, 0.2,0.2,4); Out.ar(\out.ir(0), sig); }).add; ) Synth(\echoer); Synth(\ook, [freq: rrand(45,85).midicps, amp:0.5, out:7]); s.newBusAllocators; // clears all bus allocations ~delayer = Bus.audio(s, 2); // sets up 2 channels for fx Synth(\echoer, [in:~delayer]); // attaches an echoer to ~delayer Synth(\ook, [freq: rrand(45,85).midicps, amp:0.125, out:~delayer]); // ok then (SynthDef(\mic, { var sig; sig = In.ar(\in.ir(2), 1); sig = sig * \amp.kr(0.25); Out.ar(\out.ir(0), sig); }).add; ) SynthDef(\mic, [out:~delayer]); // Order of Exe ( SynthDef(\boobelly, { var sig, freq; freq = LFNoise0.kr([7,8]).range(45,85).midicps; sig = SinOsc.ar(freq); sig = sig * Env.adsr().ar(2, \gate.kr(1)); sig = sig * \amp.ir(0.3); Out.ar(\out.ir(0), sig); // you should always specify I and O }).add) Synth(\echoer, [in:~delayer, out:0]); x = Synth(\boobelly, [out: ~delayer]); x.set(\gate, 0); // if you make echoer after you start the boobelly, no sound. // => order of execution matters // the order in which synths are defined, sets the order in which // they are evaluated. // processing is done to fill a control block (array), and they're // cleared beforehand // if you eval echo before boobelly, boobelly is cleared: no sound // sooo, boobelly must be closer to the head of the nodetree // so define processes before effects! // or use tools! : // Groups, Targets, AddActions stopped @ 41:00 // groups ~fxGp = Group.new; ~srcGp = Group.new; ~fx = Synth(\echoer, [in:~toDelay, out:0], ~fxGp); ~src = Synth(\boobelly, [out: ~delayer], ~scrGp); ~src.set(\gate, 0); ~fx.free; ~fxGp.free; ~srcGp.free; // addActions s.newBusAllocators; // clears all bus allocations ~delayer = Bus.audio(s, 2); // sets up 2 channels for fx ~fx = Synth(\echoer, [in:~toDelay, out:0]); ~src = Synth(\boobelly, [out: ~toDelay], addAction: \addToHead); ///// dry/wet mixing ( SynthDef(\boobelly, { var sig, freq; freq = LFNoise0.kr([7,8]).range(45,85).midicps; sig = SinOsc.ar(freq); sig = sig * Env.adsr().ar(2, \gate.kr(1)); sig = sig * \amp.ir(0.3); Out.ar(\out.ir(0), sig); // you should always specify I and O }).add) ( // this does the echo, echos whatever's on the input bus, outs to 0 SynthDef(\echoer, { var sig, fx; sig = In.ar(\in.ir(0), 2); // lf and rt channel inputs fx = CombL.ar(sig, 0.2,0.2,4); sig = sig.blend(fx, \mix.kr(0.5)); Out.ar(\out.ir(0), sig); }).add; ) ~srcGp = Group.new; ~fxGp = Group.after(~srcGp); ~fx = Synth(\echoer, [in:~toDelay, out:0], ~fxGp); ~fx.set(\mix, 0.1); Synth(\boobelly, [out: ~toDelay, amp:0.1], ~srcGp); Synth(\boobelly, [out: ~toDelay, amp:0.1], ~srcGp); Synth(\boobelly, [out: ~toDelay, amp:0.1], ~srcGp); Synth(\boobelly, [out: ~toDelay, amp:0.1], ~srcGp); ~srcGp.set(\gate, 0); s.freeAll; //////////////////////////////// week 10 signal flow 2 // to review ( s.newBusAllocators; ~abus = Bus.audio(s, 2); SynthDef(\sin, { var sig, trig; trig = Impulse.kr(0.5); sig = SinOsc.ar(\freq.kr(1000) + [0,5], mul:0.2); sig = sig * Env.perc().ar(0, trig); Out.ar(\out.kr(0), sig); // out is "kr"-- can be rerouted }).add; SynthDef(\rev, { var sig = In.ar(\in.kr(0), 2); // rev==reverb sig = FreeVerb.ar(sig, 0.3, 0.999, 0.7); Out.ar(\out.kr(0), sig); }).add; ) s.scope; ~src = Synth(\sin, [out: ~abus]); ~fx = Synth(\rev, [in: ~abus, out:0], ~src, \addAfter); // there aare 1024 audio busses; we've looked at them // there are 16384 control busses x = { Out.kr(3, SinOsc.kr(1)) }.play; x.free; ~bussey = Bus.control(s, 4); ~bussey.setn([.1,.2,.3,.4]); // 11:00 // using a kontrol bus on two oscillators ( s.newBusAllocators; ~abus = Bus.audio(s, 2); ~kbus = Bus.control(s, 2); SynthDef(\lfo, { var sig = SinOsc.kr(8).exprange(200,400); Out.kr(\out.kr(0), sig); }).add; SynthDef(\sin, { var sig, trig, freq; freq = In.kr(\in.kr(0),1); trig = Impulse.kr(0.5); sig = SinOsc.ar(freq + [0,5], mul:0.2); sig = sig * Env.perc().ar(0, trig); Out.ar(\out.kr(0), sig); // out is "kr"-- can be rerouted }).add; SynthDef(\saw, { var sig, trig, freq; freq = In.kr(\in.kr(0),1); trig = Impulse.kr(0.5); sig = SinOsc.ar(freq * 1.5 + [0,5], mul:0.2); sig = sig * Env.perc().ar(0, trig); Out.ar(\out.kr(0), sig); // out is "kr"-- can be rerouted }).add; SynthDef(\rev, { var sig = In.ar(\in.kr(0), 2); // rev==reverb sig = FreeVerb.ar(sig, 0.3, 0.999, 0.7); Out.ar(\out.kr(0), sig); }).add; ) s.scope; ~lfo = Synth(\lfo, [out: ~kbus]); ~src = Synth(\sin, [in:~kbus, out:~abus], ~lfo, \addAfter); ~src.set(\out, ~abus); ~fx = Synth(\rev, [in: ~abus, out:0], ~src, \addAfter); ~saw = Synth(\saw, [in: ~kbus, out:~abus], ~src, \addAfter); // 15:49 ( s.newBusAllocators; ~abus = Bus.audio(s, 2); ~kbus = Bus.control(s, 2); SynthDef(\sin, { var sig, trig; trig = Impulse.kr(0.5); sig = SinOsc.ar(\freq.kr(1000) + [0,5], mul:0.2); sig = sig * Env.perc().ar(0, trig); Out.ar(\out.kr(0), sig); }).add; SynthDef(\rev, { var sig = In.ar(\in.kr(0), 2); // rev==reverb sig = FreeVerb.ar(sig, 0.3, 0.999, 0.7); Out.ar(\out.kr(0), sig); }).add; ) ( s.scope; ~src = Synth(\sin, [in:~kbus, out:~abus]); ~fx = Synth(\rev, [in: ~abus, out:0], ~src, \addAfter); ~src.set(\freq, ~kbus.asMap); ~lfo = { Out.kr(~kbus, SinOsc.kr(12).range(200,800)); }.play; ) ~lfo.free; // 25:58 // a modular synth ( s.newBusAllocators; ~bus = (); ~bus.lfo = Bus.control(s, 1); ~bus.trig = Bus.control(s, 1); ~bus.env = Bus.control(s, 1); ~bus.vco = Bus.audio(s, 1); ~bus.vcf = Bus.audio(s, 1); ~bus.vca = Bus.audio(s, 1); SynthDef(\lfo, { var sig = SinOsc.kr(\freq.kr(1)).unipolar(1); Out.kr(\out.kr(~bus.lfo), sig); }).add; SynthDef(\trig, { var sig = Impulse.kr(\freq.kr(1)); Out.kr(\out.kr(~bus.trig), sig); }).add; SynthDef(\env, { var sig = Env.perc(\atk.kr(0.001), \rel.kr(0.5)).kr(0, \trig.kr(0)); sig = sig * \amp.kr(0.5); Out.kr(\out.kr(~bus.env), sig); }).add; SynthDef(\vco, { var sig = Saw.ar( \freq.kr(0.1).linexp(0,1,\fmin.kr(20),\fmax.kr(20000))); Out.ar(\out.kr(~bus.vco), sig); }).add; SynthDef(\vcf, { var sig = In.ar(\in.kr(~bus.vco), 1); sig = MoogFF.ar(in:sig, freq: \freq.kr(1).linexp(0,1,\fmin.kr(20),\fmax.kr(15000)), gain:2 ); Out.ar(\out.kr(~bus.vcf), sig); }).add; SynthDef(\vca, { var sig = In.ar(\in.kr(~bus.vcf), 1); sig = sig * \amp.kr(1); Out.ar(\out.kr(~bus.vca), sig); }).add; SynthDef(\rev, { var sig = In.ar(~bus.vca, 1); sig = sig.blend( LPF.ar(GVerb.ar(sig, 200, 4), \lpf.kr(1200)), \mix.kr(0.2)); Out.ar(\out.kr(0), sig); }).add; ) s.scope; s.plotTree; ( ~lfo = Synth(\lfo, []); ~trig = Synth.after(~lfo, \trig); ~env = Synth.after(~trig, \env); ~vco = Synth.after(~env, \vco); ~vcf = Synth.after(~vco, \vcf); ~vca = Synth.after(~vcf, \vca); ~rev = Synth.after(~vca, \rev); ) // do sequentially; ~freqspec = \freq.asSpec; ~freqspec.map(0.5); ~freqspec.unmap(440); ~vca.set(\amp, -1.dbamp); ~vcf.set(\freq, 0.6); ~vcf.set(\freq, 0.2); ~vcf.set(\freq, 0.4); ~vco.set(\freq, ~freqspec.unmap(exprand(40,400).round(40))); ~rev.set(\mix, 0.35); ~vca.set(\amp, ~bus.env.asMap); ~env.set(\rel, 0.5); ~env.set(\atk, 0.001); ~env.set(\trig, ~bus.trig.asMap); ~vcf.set(\fmin, 100); ~vcf.set(\freq, ~bus.lfo.asMap); ~lfo.set(\trig, 3); ///////// lect 11 MIDI // issue: I don't have a MIDI controller-- resolved! ( Buffer.freeAll; ~path = PathName(thisProcess.nowExecutingPath).parentPath; b= ( beeth1: Buffer.read(s, ~path ++ "beeth_59n3_1.wav"), beeth2: Buffer.read(s, ~path ++ "beeth_59n3_2.wav"), beeth3: Buffer.read(s, ~path ++ "beeth_59n3_3.wav"), cym: Buffer.read(s, ~path++ "cym1.wav"), hat: Buffer.read(s, ~path ++ "hat1.wav"), kick: Buffer.read(s, ~path ++ "kick1.wav"), kick: Buffer.read(s, ~path ++ "kick1.wav"), calung: Buffer.read(s, ~path ++ "calung2.wav") , gangsalo: Buffer.read(s, ~path ++ "gangsalo2.wav") , gangsa: Buffer.read(s, ~path ++ "gangsamid2.wav") , ); SynthDef(\samp, { var sig, buf = \buf.ir(0); sig = PlayBuf.ar(1, buf, BufRateScale.ir(buf)* \rate.ir(1), doneAction:2); sig = Pan2.ar(sig, \pan.ir(0), \amp.kr(0.2)); Out.ar(\out.ir(0), sig); }).add; SynthDef(\saw, { // define a sawtooth that demands explicit on/off msgs var sig, env; env = Env([0,1,0], [0.001, \rel.ir(1)], [0,-10]).kr(2); sig = Saw.ar(\freq.ir(200)!2); sig = LPF.ar(sig, 1500); sig = sig * \amp.ir(0.2) * env; Out.ar(\out.ir(0), sig); }).add; ) // btw ( c = (); PathName(PathName(thisProcess.nowExecutingPath).parentPath; ).entries.collect({ |path| c[path.fileNameWithoutExtension.asSymbol] = Buffer.read(s,path.fullPath); }) ) c.keys; c.kick1.play; MIDIIn.connectAll; MIDIFunc.trace(true); // posts all incoming events MIDIFunc.trace(false); // stopit Synth(\saw, [\freq, 200]); ( MIDIdef.noteOn(\note, { arg val, // velocity ([0,127]) num, // note number chan, // channel -- settable src; // device# -- fixed per hardware [val, num, chan, src].postln; // posts }); MIDIdef.noteOff(\note, { arg val, // velocity ([0,127]) num, // note number chan, // channel -- settable src; // device# -- fixed per hardware [val, num, chan, src].postln; // posts }); ) ( ~notes = Array.newClear(128); // the array lets us find the synth for noteoff MIDIdef.noteOn(\note, { arg val, num; ~notes.at(num) = Synth(\saw, [freq: num.midicps, amp: val.linlin(0,127,-40,-6).dbamp ]); }); )// he skipped going over the the noteoff part // it's in last year's lecture // "I covered this in last year's lecture" -- !? // we do that now? MIDIdef(\note).disable; MIDIdef(\note).enable; ( ~cfbus = Bus.control(s, 1); MINIdef.cc(\cf, { arg val, num; ~cfbus.value_(val/127); }, ccNum:26); // 26 is the MIDI channel# // makes a scaled 0->1 bus that holds a control's val // gets set when the controller is moved ) // use the midi-controlled chan for fx ( SynthDef(\saw, { var sig, env, cf; cf = In.kr(\inBus.ir(~cfbus), 1); cf = cf.linexp(0,1,30,15000); env = Env([0,1,0], [0.001, \rel.ir(1)], [0,-10]).kr(2); sig = Saw.ar(\freq.ir(200)!2); sig = LPF.ar(sig, cf); sig = sig * \amp.ir(0.2) * env; Out.ar(\out.ir(0), sig); }).add; ) ( MIDIdef.cc(\modwheel, { arg val; if (val==127) { MIDIdef(\note).enable; "enabled".postln;}; if (val==0) { MIDIdef(\note).disable; "disabled".postln;}; }, ccNum:1)) // lets you turn keybd on/off // maps keys to drum sounds, silences others MIDIdef.noteOn(\samp, { arg val, num; var buffer; buffer = switch(num) {35} {b.kick} {40} {b.snare} {42} {b.hat} {46} {b.chh} {true} {nil}; if (buffer.notNil) { Synth(\samp, [buf:buffer]); }; }); ///////////////////////////// notes from MIDI lect (11) Fall 22 ( SynthDef(\saw, { var sig, env; sig = Saw.ar(\freq.kr(440) * { Rand(-0.2, 0.2).midiratio }.dup(4)); sig = Splay.ar(sig); sig = RLPF.ar(sig, \cf.kr(2000), \rq.kr(0.4)); env = Env.adsr().kr(2, \gate.kr(1)); sig = sig *env * \amp.kr(0.25); Out.ar(\out.kr(0), sig); }).add; ) x = Synth(\saw, [freq:50]); x.set(\gate, 0); // plug MIDI devices in *before* starting the server MIDIClient.init; // prints out midi sources and destinations MIDIIn.connect(); // port, device); // connects one thing MIDIIn.connectAll; // connects everything MIDIFunc.trace(true); // causes language-side to echo MIDI evts MIDIFunc.trace(false); // stops that ( MIDIdef.noteOn(\on, { arg val, num, chan, src; [val, num,chan,src].postln; }); ) MIDIdef(\on).disable; MIDIdef(\on).enable; MIDIdef(\on).free; MIDIdef.freeAll; ( ~ar = nil ! 128; MIDIdef.noteOn(\on, { arg val, num, chan, src; ~ar.put(num, Synth(\saw, [freq: num.midicps, amp: val.linexp(0,127,0.02,0.2)])); }); MIDIdef.noteOff(\off, { arg val, num, chan, src; ~ar.at(num).set(\gate, 0); }); ) ~cfbus = Bus.control(s, 1); ~cfbus.value_(3000); // sets val of cfbus ~cfbus.getSynchronous; // returns cfbus's current value ( SynthDef(\saw, { var sig, env, cf; cf = In.kr(\cfbus.kr(0), 1); sig = Saw.ar(\freq.kr(440) * { Rand(-0.2, 0.2).midiratio }.dup(4)); sig = Splay.ar(sig); sig = RLPF.ar(sig, cf, \rq.kr(0.4)); env = Env.adsr().kr(2, \gate.kr(1)); sig = sig *env * \amp.kr(0.25); Out.ar(\out.kr(0), sig); }).add; ) ( ~ar = nil ! 128; MIDIdef.cc(\cf, { arg val, num,chan,src; [val, num].postln; ~cfbus.value_(val.linexp(0,127,50,5000)); }, ccNum:23); MIDIdef.noteOn(\on, { arg val, num, chan, src; ~ar.put(num, Synth(\saw, [freq: num.midicps, cfbus: ~cfbus, amp: val.linexp(0,127,0.02,0.2)])); }); MIDIdef.noteOff(\off, { arg val, num, chan, src; ~ar.at(num).set(\gate, 0); }); ) MIDIdef.freeAll; //// MIDI OUT MIDIClient.destinations; // enumerates m = MIDIOut.newByName("nanoKEY Studio", "nanoKEY Studio"); // connects m.noteOn(0,60,60); // sends m.noteOff(0,60,60); m.noteOn(0, rrand(0,127), 60); (0..127).do({arg note; m.noteOFf(0,note,60)}); // with an event ( ( type: \midi, midiout: m, midicmd: \noteOn, midinote: 72, sustain: 2, amp: 0.5, ).play; ) // pbind; makes an inf series of events ( p = Pbind( \type, \midi, \midiout, m, \midicmd, \noteOn, \midinote, Pwhite(1,127,inf), \sustain, 0.08, \amp, Pexprand(0.1,0.5,inf), \dur, Prand([0.1, 0.2], inf) ); q = p.play; ) /////////////////// livecoding // === you make music, live, and you show the code // titlecycles, foxtrot, sonic pi are other systems used for // the basic problem: you want to improv, but SC is fancy // JITlib! has tutorials // NodeProxy lets you start processes before they're fully // defined. //eg y = {x}+2; y.value; //-> a BinaryOpFunction x=3; y.value; //->5! // the difference between setting something and having // a pointer to a thing to set, with some extra safeguards // added, bearing in mind the audio problem context // exe sequentially n = NodeProxy.new; n.isPlaying; //->no n.play; n.isPlaying; //->true s.plotTree; //-> there are nodes // two groups, one with two monitor channels? n.clear; // dels everything n.play; //-> they're back! n.source; //-> nil n.source = { PinkNoise.ar(0.1!2); } //->sound! // n was already playing n.source = { SinOsc.ar([440,441], mul:0.04); } //->sin! n.source = { SinOsc.ar([440,441]/2, mul:0.3); } n.source = { SinOsc.ar([440,520]/2, mul:0.3) * LFPulse.kr([3,4])}; n.clear(5); // fades in 5s n.play; // source is gone; no sound n.source = { PinkNoise.ar(0.1!2); } //->sound! n.source_({ LPF.ar(Saw.ar([60, 60.2], mul:0.04), 1000) }); n.fadeTime_(3); n.source_({ LPF.ar(Saw.ar([60, 60.2]* -2.midiratio, mul:0.04), 1500) }); n.source_({ }); n.stop; // hard stop but node tree remains n.play; // n.monitor.fadeTime_(1); n.release; // disconnects n.send; // re-evals & reattaches n.source_({ LPF.ar(Saw.ar([60, 60.2]* Rand(-5.0,5.0).midiratio, mul:0.04), 1500) }); n.pause; n.resume; m = NodeProxy.new; m.play; m.fadeTime_(5); m.source_({ Impulse.ar([5,5.1], mul:0.5)*SinOsc.kr(0.2, 3pi/2).exprange(0.1,1) }); ( n.clear; m.clear; ) // there is a JITlib tutorial set // developing as a livecoder: developing a bag of tricks // that you use live but don't invent on the spot. //////////////////////////////////////////// // Ndef-- exists to prevent dangling-pointer issues n = NodeProxy.new.play; Ndef(\n).play; Ndef(\n).fadeTime_(3); ( Ndef(\n, { var sig, mod; mod = SinOsc.ar(MouseX.kr(200,2000,1), mul: MouseY.kr(1,10000, 1)); sig = SinOsc.ar(300 + mod, mul:0.2!2); sig = sig*LFNoise1.kr(8!2).exprange(0.2,0.8); }); ) Ndef(\n).clear(3); n.source_({ LPF.ar(Saw.ar([60, 60.2], mul:0.04), 1000) }); /////////////////// proxyspace -- envt stacking /////////////////////////////////// lect 13-- live coding cotd ( p = ProxySpace( server: s, clock: t = TempoClock(90/60).permanent_(true) ).push; ) p.clock.tempo; p.fadeTime_(4); ~a.play; ~a.fadeTime; p.pop; ( //Buffer.freeAll; ~path = PathName(thisProcess.nowExecutingPath).parentPath; b= ( afx1: Buffer.read(s, ~path ++ "afx_bbb1.wav"), afx2: Buffer.read(s, ~path ++ "afx_bbb2.wav"), beeth1: Buffer.read(s, ~path ++ "beeth_59n3_1.wav"), beeth2: Buffer.read(s, ~path ++ "beeth_59n3_2.wav"), beeth3: Buffer.read(s, ~path ++ "beeth_59n3_3.wav"), cym: Buffer.read(s, ~path++ "cym1.wav"), dav1: Buffer.read(s, ~path++ "davis_corner1.wav"), dav2: Buffer.read(s, ~path++ "davis_corner2.wav"), dav3: Buffer.read(s, ~path++ "davis_corner3.wav"), dav4: Buffer.read(s, ~path++ "davis_corner4.wav"), hat: Buffer.read(s, ~path ++ "hat1.wav"), kick: Buffer.read(s, ~path ++ "kick1.wav"), kick: Buffer.read(s, ~path ++ "kick1.wav"), m80: Buffer.read(s, ~path ++ "m080.caf") , calung: Buffer.read(s, ~path ++ "calung2.wav") , gangsalo: Buffer.read(s, ~path ++ "gangsalo2.wav") , gangsa: Buffer.read(s, ~path ++ "gangsamid2.wav") ); ) b.keys; b.afx1.play; // b.glitch = PathName(thisProcess.nowExecutingPath.parentPath). // entries.collect({|n| // Buffer.readChannel(s, n.fullPath, channels:{0]); // }); ( SynthDef(\a, { var sig; sig = Saw.ar(\freq.ir(400)); sig = MoogFF.ar(sig, \cf.ir(400), \gain.ir(2)); sig = Pan2.ar(sig, \pan.ir(0), \amp.kr(0.5)); sig = sig * Env.perc(\atk.ir(0.001), \rel.ir(0.1)).ar(2); Out.ar(\out.ir(0), sig); }).add; SynthDef(\b, { var sig = PlayBuf.ar(1, \buf.ir(0), \rate.ir(1)); sig = Pan2.ar(sig, \pan.ir(0), \amp.ir(0.2)); sig = sig * Env.perc(\atk.ir(0.001),\rel.ir(0.1)).ar(2); Out.ar(\out.ir(0), sig); }).add; ) Synth(\a, [freq:60, amp:0.5, rel:2, cf:3000]); ///// setup done ~a.play; ~a.quant;