( // ========== Spectral SynthDef with expanded modulation ========== SynthDef(\pv16knob, { arg bufnum, fftSize = 1024, amp = 0.3, smearAmt = 5, randRate = 6, binScrambleAmt = 0.5, pvRouting = 0, grainSize = 0.1, delTime = 0.3, delFeedback = 0.4, verbMix = 0.2, lfoFreq = 0.2, bitcrushAmt = 0.0, distAmt = 1.0, ringFreq = 200, freezeAmt = 0.5, transpose = 1.0, filterCutoff = 8000; var in, chain, lfo, dry, fx, delay, verb; var chain0, chain1, chain2, chain3, chain4; // Audio input and bitcrushing in = PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum) * transpose, loop: 1); in = Decimator.ar(in, (1 - bitcrushAmt).linexp(0, 1, 44100, 1000), 8 - (bitcrushAmt * 7)); // FFT chain = FFT(LocalBuf(fftSize), in); lfo = SinOsc.kr(lfoFreq).range(0.1, 1.0); chain = PV_MagFreeze(chain, freezeAmt); // Spectral branches chain0 = PV_BinScramble(PV_MagSmear(PV_RandComb(chain, 0.1, Impulse.kr(randRate)), smearAmt + lfo), binScrambleAmt, 0); chain1 = PV_BrickWall(chain, lfo.range(0.05, 0.2)); chain2 = PV_BinShift(chain, lfo * 20, 0.5); chain3 = PV_BinWipe(chain, lfo); chain4 = PV_SpectralEnhance(chain, 0.8, 1.5, 0.2); // Select chain = SelectX.kr(pvRouting.clip(0, 4), [chain0, chain1, chain2, chain3, chain4]); dry = IFFT(chain); // Post-PV grain dry = TGrains.ar(2, Impulse.ar(20), bufnum, 1, Phasor.ar(0, 1, 0, BufFrames.ir(bufnum)), grainSize, 0, 0.1, 1); dry = Ringz.ar(dry, ringFreq, 0.2); dry = (dry * distAmt).tanh; dry = LPF.ar(dry, filterCutoff); // FX delay = CombC.ar(dry, 1, delTime, delFeedback); verb = FreeVerb.ar(dry, verbMix, 0.8, 0.3); // Mix and output fx = Mix([dry, delay, verb]); Out.ar(0, fx.dup * amp); }).add; ) ( // ========== Load buffer ========== b = Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav"); // Use your own file if you want ) ( // ========== Instantiate synth ========== ~pvSynth = Synth(\pv16knob, [\bufnum, b]); ) ( // ========== MIDI CC Mapping (channel 2) ========== [ [\amp, 0, 0.0, 1.5], [\smearAmt, 1, 1, 40], [\randRate, 2, 0.5, 20], [\binScrambleAmt, 3, 0.0, 1.0], [\pvRouting, 4, 0, 4], [\grainSize, 5, 0.01, 0.2], [\delTime, 6, 0.05, 1.0], [\delFeedback, 7, 0.0, 0.95], [\verbMix, 8, 0.0, 1.0], [\lfoFreq, 9, 0.01, 5.0], [\bitcrushAmt, 10, 0.0, 1.0], [\distAmt, 11, 0.5, 10.0], [\ringFreq, 12, 50, 2000], [\freezeAmt, 13, 0.0, 1.0], [\transpose, 14, 0.25, 2.0], [\filterCutoff, 15, 100, 15000] ].do { |spec| var param, cc, min, max; #param, cc, min, max = spec; MIDIdef.cc(param.asSymbol, { |val, num, chan, src| if(chan == 2) { var mapped = val.linlin(0, 127, min, max); ~pvSynth.set(param, mapped); } }, cc); }; )