{
   "labels" : [
      "transition",
      "tutorial",
      "effects"
   ],
   "is_private" : null,
   "id" : "1-57H",
   "code" : "(\r\ns.waitForBoot({\r\n\tvar synthGroup = Group.new;\r\n\tvar transitionGroup = Group.after(synthGroup);\r\n\r\n\tif ((~b1.notNil), { ~b1.free; ~b2.free; });\r\n\t~b1 = Bus.audio(s, 2);\r\n\t~b2 = Bus.audio(s, 2);\r\n\r\n\tSynthDef(\\sound1, {\r\n\t\t| out=0 |\r\n\t\tvar sig = SinOsc.ar(LFNoise0.ar(4, 400, 450), 0, 0.2);\r\n\t\tOut.ar(out, sig!2);\r\n\t}).add;\r\n\r\n\tSynthDef(\\sound2, {\r\n\t\t| out = 0 |\r\n\t\tvar sig = VarSaw.ar(freq:LFPulse.kr(3, 0, 0.3, 200, 200), iphase:0, width:LFTri.kr(1.0).range(0,1), mul:0.1);\r\n\t\tOut.ar(out, sig!2);\r\n\t}).add;\r\n\r\n\tSynthDef(\\transitionCut, { // direct cut, no smooth transition\r\n\t\t| inBusA, inBusB, outBus=0, pos= -1 |\r\n\t\tvar sig1 = In.ar(inBusA, 2);\r\n\t\tvar sig2 = In.ar(inBusB, 2);\r\n\t\t//var testPos = pos;\r\n\t\tvar testPos = EnvGen.kr(Env.new(levels:[-1,-1,1,1,-1,-1], times:[5,5,5,5,5]), doneAction:2);\r\n\t\tOut.ar(outBus, Select.ar(testPos.linlin(-1,1,0,1), [sig1, sig2]));\r\n\t}).add;\r\n\r\n\tSynthDef(\\transitionCrossFadeEqualGain, {  // cross fade linearly\r\n\t\t|  inBusA, inBusB, outBus=0, pos= -1 |\r\n\t\tvar sig1 = In.ar(inBusA, 2);\r\n\t\tvar sig2 = In.ar(inBusB, 2);\r\n\t\t//var testPos = pos;\r\n\t\tvar testPos = EnvGen.kr(Env.new(levels:[-1,-1,1,1,-1,-1], times:[5,5,5,5,5]).plot, doneAction:2);\r\n\t\tOut.ar(outBus, (testPos.linlin(-1,1,0,1)*sig1) + (testPos.linlin(-1,1,1,0)*sig2));\r\n\t}).add;\r\n\r\n\tSynthDef(\\transitionCrossFadeEqualPower, { // cross fade according to square root law\r\n\t\t| inBusA, inBusB, outBus=0, pos= -1 |\r\n\t\tvar sig1 = In.ar(inBusA, 2);\r\n\t\tvar sig2 = In.ar(inBusB, 2);\r\n\t\t//var testPos = pos;\r\n\t\tvar testPos = EnvGen.kr(Env.new(levels:[-1,-1,1,1,-1,-1], times:[5,5,5,5,5]), doneAction:2);\r\n\t\tOut.ar(outBus, ((((1+testPos).sqrt)/2)*sig1) + ((((1-testPos).sqrt)/2)*sig2) );\r\n\t}).add;\r\n\r\n\tSynthDef(\\transitionSpectralCurtainHPF, { // wipe using sweeping hpf filter\r\n\t\t| inBusA, inBusB, outBus=0, pos= -1 |\r\n\t\tvar sig1 = In.ar(inBusA, 2);\r\n\t\tvar sig2 = In.ar(inBusB, 2);\r\n\t\t//var testPos = pos;\r\n\t\tvar testPos = EnvGen.kr(Env.new(levels:[-1,-1,1,1,-1,-1], times:[5,5,5,5,5]), doneAction:2);\r\n\t\tOut.ar(outBus, (HPF.ar(sig1, testPos.linexp(-1,1,2,20000)) + HPF.ar(sig2, testPos.linexp(-1,1,20000,2))));\r\n\t}).add;\r\n\r\n\tSynthDef(\\transitionSpectralCurtainLPF, { // wipe using sweeping lpf filter\r\n\t\t| inBusA, inBusB, outBus=0, pos= -1 |\r\n\t\tvar sig1 = In.ar(inBusA, 2);\r\n\t\tvar sig2 = In.ar(inBusB, 2);\r\n\t\t//var testPos = pos;\r\n\t\tvar testPos = EnvGen.kr(Env.new(levels:[-1,-1,1,1,-1,-1], times:[5,5,5,5,5]), doneAction:2);\r\n\t\tOut.ar(outBus, (LPF.ar(sig1, testPos.linexp(-1,1,20000,2)) + LPF.ar(sig2, testPos.linexp(-1,1,2,20000))));\r\n\t}).add;\r\n\r\n\tSynthDef(\\transitionReverbWash, { // blur out\r\n\t\t| inBusA, inBusB, outBus=0, pos= -1 |\r\n\t\tvar sig1 = In.ar(inBusA, 2);\r\n\t\tvar sig2 = In.ar(inBusB, 2);\r\n\t\t//var testPos = pos;\r\n\t\tvar testPos = EnvGen.kr(Env.new(levels:[-1,-1,1,1,-1,-1], times:[5,5,5,5,5]), doneAction:2);\r\n\t\tOut.ar(outBus,\r\n\t\t\t(testPos.linlin(-1,1,1,0)*FreeVerb.ar(in:sig1, mix:testPos.linlin(-1,1,0,1), room:15, damp:0.01)) +\r\n\t\t\t(testPos.linlin(-1,1,0,1)*FreeVerb.ar(in:sig2, mix:testPos.linlin(-1,1,1,0), room:15, damp:0.01)));\r\n\t}).add;\r\n\r\n\tSynthDef(\\transitionPulseTrain, { // \"pixelate\"\r\n\t\t| inBusA, inBusB, outBus=0, pos= -1 |\r\n\t\tvar sig1 = In.ar(inBusA, 2);\r\n\t\tvar sig2 = In.ar(inBusB, 2);\r\n\t\t//var testPos = pos;\r\n\t\tvar testPos = EnvGen.kr(Env.new(levels:[-1,-1,1,1,-1,-1], times:[5,5,5,5,5]), doneAction:2);\r\n\t\tvar pulsefreq = 15;\r\n\t\t// do some waveshaping with an Env: generate 0,1,2 but stay 10x longer in 1 than in 0 and 2.\r\n\t\t// the generated value will be used in a Select UGen\r\n\t\tvar mapper = Env.new([0,0,1,1,2,2],[0.1,0.01,1,0.01,0.1].normalizeSum);\r\n\t\tvar mappedTestPos = IEnvGen.ar(mapper, testPos.linlin(-1,1,0,1));\r\n\t\tOut.ar(outBus,\r\n\t\t\tSelect.ar(mappedTestPos,\r\n\t\t\t\t[testPos.linlin(-1,1,1,0)*sig1,\r\n\t\t\t\t LeakDC.ar(((testPos.linlin(-1,1,1,0)*(LFPulse.kr(pulsefreq, 0, testPos.linlin(-1,1,1,0))*sig1)) +\r\n\t\t\t    \t\t\t(testPos.linlin(-1,1,0,1)*(LFPulse.kr(pulsefreq, 1, testPos.linlin(-1,1,0,1))*sig2)))),\r\n\t\t\t\t testPos.linlin(-1,1,0,1)*sig2]));\r\n\t}).add;\r\n\r\n\tSynthDef(\\transitionPanLR, { // shift LR\r\n\t\t| inBusA, inBusB, outBus=0, pos= -1 |\r\n\t\tvar sig1 = In.ar(inBusA, 2);\r\n\t\tvar sig2 = In.ar(inBusB, 2);\r\n\t\t//var testPos = pos;\r\n\t\tvar testPos = EnvGen.kr(Env.new(levels:[-1,-1,1,1,-1,-1], times:[5,5,5,5,5]), doneAction:2);\r\n\t\tOut.ar(outBus,\r\n\t\t\tBalance2.ar(sig1[0], sig1[1], testPos.linlin(-1,1,-1,0), testPos.linlin(-1,1,0,1)) +\r\n\t\t\tBalance2.ar(sig2[0], sig2[1], testPos.linlin(-1,1,0,1),  testPos.linlin(-1,1,1,0))\r\n\t\t);\r\n\t}).add;\r\n\r\n\ts.sync;\r\n\r\n\tfork {\r\n\t\tvar s1 = Synth(\\sound1, [\\out, ~b1], synthGroup);\r\n\t\tvar s2 = Synth(\\sound2, [\\out, ~b2], synthGroup);\r\n\r\n\t\t[//\\transitionCut, // boring\r\n\t\t \\transitionCrossFadeEqualGain,\r\n\t\t \\transitionCrossFadeEqualPower,\r\n\t\t \\transitionSpectralCurtainHPF,\r\n\t\t \\transitionSpectralCurtainLPF,\r\n\t\t \\transitionReverbWash,\r\n\t\t \\transitionPulseTrain,\r\n\t\t \\transitionPanLR\r\n\r\n\t\t].do({\r\n\t\t\t| item , idx |\r\n\t\t\t(\"Now switching to transition \"++item).postln;\r\n\t\t\tSynth(item, [\\inBusA, ~b1, \\inBusB, ~b2], transitionGroup);\r\n\t\t\t25.wait;\r\n\t\t});\r\n\t}\r\n\r\n});\r\n)",
   "name" : "audio transitions",
   "author" : "56228375",
   "ancestor_list" : [],
   "description" : "Code used in the blog article about audio transitions https://technogems.blogspot.be/2017/08/audio-transitions-in-supercollider.html \r\nThe program proposes a few ways to gradually switch between 2 sounds that go further than simple crossfading. Can you think of other ways?"
}
