Submit
Browse
Anonymous
Login
RSS
SuperCollider Code
Fork Code: audio transitions
name
code content
( s.waitForBoot({ var synthGroup = Group.new; var transitionGroup = Group.after(synthGroup); if ((~b1.notNil), { ~b1.free; ~b2.free; }); ~b1 = Bus.audio(s, 2); ~b2 = Bus.audio(s, 2); SynthDef(\sound1, { | out=0 | var sig = SinOsc.ar(LFNoise0.ar(4, 400, 450), 0, 0.2); Out.ar(out, sig!2); }).add; SynthDef(\sound2, { | out = 0 | var 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); Out.ar(out, sig!2); }).add; SynthDef(\transitionCut, { // direct cut, no smooth transition | inBusA, inBusB, outBus=0, pos= -1 | var sig1 = In.ar(inBusA, 2); var sig2 = In.ar(inBusB, 2); //var testPos = pos; var testPos = EnvGen.kr(Env.new(levels:[-1,-1,1,1,-1,-1], times:[5,5,5,5,5]), doneAction:2); Out.ar(outBus, Select.ar(testPos.linlin(-1,1,0,1), [sig1, sig2])); }).add; SynthDef(\transitionCrossFadeEqualGain, { // cross fade linearly | inBusA, inBusB, outBus=0, pos= -1 | var sig1 = In.ar(inBusA, 2); var sig2 = In.ar(inBusB, 2); //var testPos = pos; var testPos = EnvGen.kr(Env.new(levels:[-1,-1,1,1,-1,-1], times:[5,5,5,5,5]).plot, doneAction:2); Out.ar(outBus, (testPos.linlin(-1,1,0,1)*sig1) + (testPos.linlin(-1,1,1,0)*sig2)); }).add; SynthDef(\transitionCrossFadeEqualPower, { // cross fade according to square root law | inBusA, inBusB, outBus=0, pos= -1 | var sig1 = In.ar(inBusA, 2); var sig2 = In.ar(inBusB, 2); //var testPos = pos; var testPos = EnvGen.kr(Env.new(levels:[-1,-1,1,1,-1,-1], times:[5,5,5,5,5]), doneAction:2); Out.ar(outBus, ((((1+testPos).sqrt)/2)*sig1) + ((((1-testPos).sqrt)/2)*sig2) ); }).add; SynthDef(\transitionSpectralCurtainHPF, { // wipe using sweeping hpf filter | inBusA, inBusB, outBus=0, pos= -1 | var sig1 = In.ar(inBusA, 2); var sig2 = In.ar(inBusB, 2); //var testPos = pos; var testPos = EnvGen.kr(Env.new(levels:[-1,-1,1,1,-1,-1], times:[5,5,5,5,5]), doneAction:2); Out.ar(outBus, (HPF.ar(sig1, testPos.linexp(-1,1,2,20000)) + HPF.ar(sig2, testPos.linexp(-1,1,20000,2)))); }).add; SynthDef(\transitionSpectralCurtainLPF, { // wipe using sweeping lpf filter | inBusA, inBusB, outBus=0, pos= -1 | var sig1 = In.ar(inBusA, 2); var sig2 = In.ar(inBusB, 2); //var testPos = pos; var testPos = EnvGen.kr(Env.new(levels:[-1,-1,1,1,-1,-1], times:[5,5,5,5,5]), doneAction:2); Out.ar(outBus, (LPF.ar(sig1, testPos.linexp(-1,1,20000,2)) + LPF.ar(sig2, testPos.linexp(-1,1,2,20000)))); }).add; SynthDef(\transitionReverbWash, { // blur out | inBusA, inBusB, outBus=0, pos= -1 | var sig1 = In.ar(inBusA, 2); var sig2 = In.ar(inBusB, 2); //var testPos = pos; var testPos = EnvGen.kr(Env.new(levels:[-1,-1,1,1,-1,-1], times:[5,5,5,5,5]), doneAction:2); Out.ar(outBus, (testPos.linlin(-1,1,1,0)*FreeVerb.ar(in:sig1, mix:testPos.linlin(-1,1,0,1), room:15, damp:0.01)) + (testPos.linlin(-1,1,0,1)*FreeVerb.ar(in:sig2, mix:testPos.linlin(-1,1,1,0), room:15, damp:0.01))); }).add; SynthDef(\transitionPulseTrain, { // "pixelate" | inBusA, inBusB, outBus=0, pos= -1 | var sig1 = In.ar(inBusA, 2); var sig2 = In.ar(inBusB, 2); //var testPos = pos; var testPos = EnvGen.kr(Env.new(levels:[-1,-1,1,1,-1,-1], times:[5,5,5,5,5]), doneAction:2); var pulsefreq = 15; // do some waveshaping with an Env: generate 0,1,2 but stay 10x longer in 1 than in 0 and 2. // the generated value will be used in a Select UGen var mapper = Env.new([0,0,1,1,2,2],[0.1,0.01,1,0.01,0.1].normalizeSum); var mappedTestPos = IEnvGen.ar(mapper, testPos.linlin(-1,1,0,1)); Out.ar(outBus, Select.ar(mappedTestPos, [testPos.linlin(-1,1,1,0)*sig1, LeakDC.ar(((testPos.linlin(-1,1,1,0)*(LFPulse.kr(pulsefreq, 0, testPos.linlin(-1,1,1,0))*sig1)) + (testPos.linlin(-1,1,0,1)*(LFPulse.kr(pulsefreq, 1, testPos.linlin(-1,1,0,1))*sig2)))), testPos.linlin(-1,1,0,1)*sig2])); }).add; SynthDef(\transitionPanLR, { // shift LR | inBusA, inBusB, outBus=0, pos= -1 | var sig1 = In.ar(inBusA, 2); var sig2 = In.ar(inBusB, 2); //var testPos = pos; var testPos = EnvGen.kr(Env.new(levels:[-1,-1,1,1,-1,-1], times:[5,5,5,5,5]), doneAction:2); Out.ar(outBus, Balance2.ar(sig1[0], sig1[1], testPos.linlin(-1,1,-1,0), testPos.linlin(-1,1,0,1)) + Balance2.ar(sig2[0], sig2[1], testPos.linlin(-1,1,0,1), testPos.linlin(-1,1,1,0)) ); }).add; s.sync; fork { var s1 = Synth(\sound1, [\out, ~b1], synthGroup); var s2 = Synth(\sound2, [\out, ~b2], synthGroup); [//\transitionCut, // boring \transitionCrossFadeEqualGain, \transitionCrossFadeEqualPower, \transitionSpectralCurtainHPF, \transitionSpectralCurtainLPF, \transitionReverbWash, \transitionPulseTrain, \transitionPanLR ].do({ | item , idx | ("Now switching to transition "++item).postln; Synth(item, [\inBusA, ~b1, \inBusB, ~b2], transitionGroup); 25.wait; }); } }); )
code description
Code used in the blog article about audio transitions https://technogems.blogspot.be/2017/08/audio-transitions-in-supercollider.html The program proposes a few ways to gradually switch between 2 sounds that go further than simple crossfading. Can you think of other ways?
use markdown for formating
category tags
comma separated, i.g. "wild, siren" (do not enter default SC class names, please)
ancestor(s)
comma separated identificators, i.g. "1-C,1-1,1-4M,1-x"
Private?
the code will be accessible by direct url and not visible in public activity
signup to submit public code without captcha
comment of change