Hi,
I’m happy to share some code I came up with to create a vocoder.
Here’s the code, let me know what do you think about it:
// 1. first: start the server
s.boot;
// 2. the load an audio file on a buffer (spoken words work better!)
b = Buffer.read(s,"/your/spoken/word/sample/here.wav"
// 3. create a group to put all the carrie synths inside
~grp_vocoders = Group.new(s, \addToTail);
// 4. create a bus to connect the modulator synth to the carrier synths
~bus_modulator = Bus.audio(s,1);
// if you want you can debug the bus you hav just created
~bus_modulator.scope;
// 5. define the carrier synth
(
SynthDef(\vocoder_synth, {
|
out=0, in=2, amp=1.0, freq=440,
atk=0.1, dcy=0.1, sus=0.7, rel=1,
width=0.5, pan=0.0
|
var sig, env, chainMod, chainCarr, chain, input;
env = EnvGen.ar(Env.perc(atk, rel), doneAction:2);
sig = VarSaw.ar(freq, width:width);
input = In.ar(in,1) * env;
chainMod = FFT(LocalBuf(1024), input);
// uncomment the line below if you want a gate-like effect
//chainMod = PV_MagAbove(chainMod, 0.2);
chainCarr = FFT(LocalBuf(1024), sig);
chain = PV_MagMul(chainCarr, chainMod);
// I'm using the line below in order to limit the overall amplitude of the bins
chain = PV_MagClip(chain, 50);
sig = IFFT(chain);
sig = sig * amp;
Out.ar(out, Pan2.ar(sig, pan));
}).add;
)
// 6. define the modulator synth
(
SynthDef(\playbuffer, {
|out=0, in=2, amp=1.0, bufnum|
var sig = PlayBuf.ar(1, bufnum, BufRateScale.kr(bufnum), loop: 1);
Out.ar(out, sig);
}).add;
)
// 7. instantiate the carrier synth (here I'm using a Pbindef)
(
Pbindef(\chords,
\instrument, \vocoder_synth,
\scale, Scale.minor,
\root, 1,
\octave, Prand([[3,4,5,6]], inf),
\degree, Prand([ [0,2,4,7] ], inf),
\mtranspose, Pwhite(-0.02, 0.02, inf),
\width, 0.01, //Pwhite(0.01, 0.5, inf),
\in, ~bus_modulator,
\atk, 0.5,
\rel, 1,
\amp, 0.125,
\dur, Pseq([Pn(0.25,8)], inf),
\group, ~grp_vocoders,
\pan, Pwhite(-1.0, 1.0, inf).clump(4)
).quant_([4]).play;
)
// 8. instantiate the modulator synth
~voice = Synth(\playbuffer, [\bufnum, b, \out, ~bus_modulator], addAction:\addToHead);
// you can plot the tree in order to better understand what is happening
s.plotTree;
// try changing the chords
Pbindef(\chords, \degree, 0 + Prand([ [0,1,2] ], inf));
Pbindef(\chords, \degree, -1 + Prand([ [0,1,2] ], inf));
Pbindef(\chords, \degree, -2 + Prand([ [0,1,2] ], inf));
Pbindef(\chords, \degree, Prand([ [-1,0,2] ], inf));
Pbindef(\chords, \degree, Prand([ [0,2,3,6] ], inf));
// some clean up code
(
~voice.free;
~bus_modulator.free;
Pbindef(\chords).stop;
~grp_vocoders.free;
)