{
   "labels" : [
      "sync",
      "looper",
      "pedal"
   ],
   "code" : "/* _______SYNC_LOOPER__________\r\n*/ \r\n(\r\ns.waitForBoot{\r\n\r\nSynthDef(\\syncPhs, {|sync=8, buf, rate=1, t_start=0, t_rec=0, t_stop=0|\r\n\tvar phs, dur;\r\n\tdur = Timer.kr(t_rec+t_stop);\r\n\tphs = Phasor.ar(t_start, BufRateScale.kr(buf)*rate,0, BufFrames.kr(buf)); \r\n\tSendReply.kr(t_stop, '/loopStopRec', dur);\r\n\tOffsetOut.ar(sync,phs);\r\n}).send(s);\r\n\r\nSynthDef(\\syncPlay, {|out=0, sync=8, buf, rate=1, amp=1, stop, atk=0.003, rel=100|\r\n\tvar snd, phs, env, gate;\r\n\tphs = In.ar(sync);\r\n\tgate = A2K.kr(phs) < (BufSamples.kr(buf)-(BufSampleRate.ir(buf)/rel));\r\n\tgate = gate-stop;\r\n\tenv = EnvGen.kr(Env.asr(atk,1,rel.reciprocal), gate);\r\n\tsnd = BufRd.ar(1, buf, phs, 1);\r\n\tsnd = snd*env;\r\n\tOffsetOut.ar(out,snd*amp);\r\n}).send(s);\r\n\r\nSynthDef(\\syncRec, {|sync=8, buf, in=0|\r\n\tvar snd, phs, input;\r\n\tinput = SoundIn.ar(in);\r\n//\tinput = In.ar(in);\r\n\tphs = In.ar(sync);\r\n\tsnd = BufWr.ar(input, buf, phs, 0);\r\n}).send(s);\r\n\r\nSynthDef(\\send, {\r\n\t|in=0,out=0,amp=1|\r\n\tvar son;\r\n\tson = In.ar(in);\r\n\tOffsetOut.ar(out,son*amp);\r\n}).send(s);\r\n\r\n~loop = ();\r\n~gLoop = Group.new(s);\r\ns.sync;\r\n~gLoopPlay = Group.new(~gLoop, 'addAfter').run(false);\r\ns.sync;\r\n~loop.put(\\sync, Bus.audio(s, 1));\r\n~loop.put(\\bus, Bus.audio(s, 1)); \r\n~loop.put(\\buffer, Buffer.alloc(s, s.sampleRate * 60, 1)); // max record : 60 sec\r\n~loop.put(\\bufs, List.newClear);\r\n~loop.put(\\plays, List.newClear);\r\n~loop.put(\\bpm, 0);\r\ns.sync;\r\n~loop.put(\\phasor,  Synth(\\syncPhs, [\\buf, ~loop.buffer, \\sync, ~loop.sync], ~gLoop, 'addToHead'));\r\n~loop.put(\\rec, Synth(\\syncRec, [\\buf, ~loop.buffer, \\sync, ~loop.sync, \\in, 0], ~gLoop, 'addToTail').run(false));\r\n~loop.put(\\out, Synth(\\send, [\\in, ~loop.bus, \\out, 0], ~gLoopPlay, 'addToTail'));\r\ns.sync;\r\nNodeWatcher.register(~loop.rec);\r\nNodeWatcher.register(~gLoopPlay);\r\n\r\nFdef(\\loopRec, {\r\n\tif( ~loop.bufs.size == 0, { ~loop.phasor.set(\\t_start, 1, \\rate, 1, \\t_rec, 1) });\r\n\t~loop.rec.run; \"LOOP REC\".postln;\r\n});\r\n\r\nFdef(\\loopStopRec, {|dur|\r\n\tvar i; \r\n\t~loop.rec.run(false);\r\n\tif(~loop.bufs.size==0, \r\n\t\t{ \r\n\t\t~loop.bufs.add(Buffer.alloc(s, dur)); \r\n\t\t~loop.phasor.set(\\buf, ~loop.bufs[0]);\r\n\t\tFdef(\\loopBPM).value;\r\n\t\t},{ ~loop.bufs.add(Buffer.alloc(s, ~loop.bufs[0].numFrames))}\r\n\t );\r\n\ti = ~loop.bufs.size-1;\r\n\t~loop.buffer.copyData(~loop.bufs[i]);\r\n\t~loop.buffer.zero; \"LOOP REC STOP\".postln;\r\n});\r\n\r\nFdef(\\loopPlay, {\r\n\tvar i = ~loop.bufs.size-1;\r\n\t~gLoopPlay.run;\r\n\t~loop.plays.add(Synth(\\syncPlay, [\\buf, ~loop.bufs[i], \\sync, ~loop.sync, \\out, ~loop.bus], ~loop.out, 'addBefore'));\r\n});\r\n\r\nTdef(\\loopStopPlay, {\r\n\tif( ~gLoopPlay.isRunning, {\r\n\t\t~gLoopPlay.set(\\stop, 1);\r\n\t\t0.01.wait;\r\n\t\t~gLoopPlay.run(false); \"LOOP STOP\".postln;\r\n\t\t},{\r\n\t\t~gLoopPlay.run.set(\\atk, 0.01, \\stop, 0);\r\n\t\t~loop.phasor.set(\\t_start, 1, \\rate, 1); // restart phasor\r\n\t\t\"LOOP PLAY\".postln;\r\n\t});\r\n}).stop;\r\n\r\nFdef(\\loopUndo, {\r\n\tvar x = ~loop.bufs.size-1;\r\n\t~loop.rec.run(false);\r\n\t~loop.plays[x].set(\\stop, 1);\r\n\t~loop.bufs[x].free;\r\n\t~loop.bufs.removeAt(x);\r\n\t~loop.plays[x].free;\r\n\t~loop.plays.removeAt(x);\r\n\tif(~loop.bufs.size == 0, {\r\n\t\t~loop.phasor.set(\\buf, ~loop.buffer);\r\n\t});\r\n\t\"LOOP UNDO\".postln;\r\n});\r\n\r\nFdef(\\loopClear,{\r\n\t~loop.bufs.do{|x| x.free };\r\n\t~loop.bufs.clear;\r\n\t~loop.plays.do{|x| x.free };\r\n\t~loop.plays.clear;\r\n\t~loop.phasor.set(\\buf, ~loop.buffer);\r\n\t~loop.rec.run(false);\r\n\t\"LOOP CLEAR\".postln;\r\n});\r\n\r\nFdef(\\loopBPM, {|beats=4, bars=4|\r\n\tvar bpm;\r\n\tbpm = 60/((~loop.bufs[0].numFrames/s.sampleRate)/(beats*bars));\r\n\t~loop.bpm = bpm;\r\n\t\"LOOP BPM : \".post; bpm.postln;\r\n});\r\n\r\nFdef(\\loopFree, {\r\n\t~gLoop.freeAll; ~gLoop.free;\r\n\t~gLoopPlay.freeAll; ~gLoopPlay.free;\r\n\t~loop.buffer.free; ~loop.bufs.do{|x| x.free};\r\n\t~loop.sync.free; ~loop.bus.free;\r\n\t\"LOOP FREE\".postln;\r\n});\r\n\r\nFdef(\\loopTrig, {\r\n\tif(~loop.rec.isRunning, {~loop.phasor.set(\\t_stop, 1)},{Fdef(\\loopRec).value});\r\n});\r\n\r\nOSCdef(\\loopDur, {|m|\r\n\tvar dur= m[3]*s.sampleRate;\r\n\tFdef(\\loopStopRec).value(dur);\r\n\tFdef(\\loopPlay).value;\r\n}, '\\loopStopRec');\r\n\"SYNC_LOOP OK !\".postln;\r\n})\r\n\r\n/*\r\nFdef(\\loopTrig).value; \t\t// start/stop record\r\nTdef(\\loopStopPlay).play;\r\nFdef(\\loopBPM).value;\r\nFdef(\\loopUndo).value; \t\t// undo last record\r\nFdef(\\loopClear).value; \t// clear all records\r\nFdef(\\loopFree).value \t\t// free loop from server\r\n\r\n~loop.plays[0].run(false);\t// stop first loop\r\n~gLoop.run(false); \t\t// pause all players\r\n~gLoop.run;\t   \t\t// resume all players\r\n~gLoopPlay.run;\r\n~gLoopPlay.run(false);\r\n~loop.phasor.set(\\rate, 1); \t// change rate speed\r\n\r\n~loop.plays.do{|x| x.run(2.rand.asBoolean)}; // rand stop/play itens\r\n~loop.bufs[0].plot\r\n\r\n(\r\nMIDIClient.init; MIDIIn.connectAll;\r\nMIDIdef.program(\\sstep, {|k,f,c|\r\n\tvar x;\r\n//\tk.postln;\r\n\tx = case\r\n\t{ k==5 }{ Fdef(\\loopTrig).value }\r\n\t{ k==4 }{ Tdef(\\loopStopPlay).play }\r\n\t{ k==2 }{ Fdef(\\loopUndo).value }\r\n\t{ k==1 }{ Fdef(\\loopClear).value }\r\n});\r\n)\r\n*/",
   "id" : "1-59L",
   "is_private" : null,
   "author" : "ovo",
   "name" : "sync looper",
   "ancestor_list" : [],
   "description" : "synchronized loop"
}
