Skip to content

Instantly share code, notes, and snippets.

@xavriley
Last active May 23, 2022 17:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xavriley/7c4a82c3113125024ca52633359faaef to your computer and use it in GitHub Desktop.
Save xavriley/7c4a82c3113125024ca52633359faaef to your computer and use it in GitHub Desktop.
Sennheiser VSM201 Vocoder Emulation in SuperCollider
Server.default.options.numWireBufs = 1024;
s.boot;
Buffer.freeAll;
~b0 = Buffer.read(s, "/Users/xavriley/Dropbox/Public/sounds/sennheiser_demo-1.wav");
// ~b0 = Buffer.read(s, "/Users/xavriley/Dropbox/Public/sounds/ben.wav");
~b0 = Buffer.read(s, "/Users/xavriley/Dropbox/Public/sounds/hbfs/working.aiff");
~b1 = Buffer.read(s, "/Users/xavriley/Dropbox/Public/sounds/sennheiser_demo-1-wet.wav");
~b2 = Buffer.read(s, "/Users/xavriley/Dropbox/Public/sounds/sennheiser_demo-1-wet-noise.wav");
~b0.play;
{ PlayBuf.ar(2, ~b0, loop: 1, rate: 0.5) }.play
(
var vocoder;
vocoder = (
SynthDef('sonic-pi-fx_vocoder', {
arg out_bus = 0, in_bus = 0, note = 53, pan = -1;
var voicedCarrier;
var replacementSound;
var snd, numBands, bandFreqs, bandMuls, carrier;
var perc, chain;
numBands = 20;
bandFreqs = (0..numBands - 1).linexp(0, numBands - 1, 50, 8000);
//bandFreqs = [140,240,350,450,560,690,820,990,1150,1380,1590,
// // K12, ...
// 1850,2190,2550,2900,3400,4000,4800,5800,7400];
bandMuls = [0.6,0.6,1.5,1.5,1.5,1.5,1,1,1,1,1,1,1.5,1.5,1.2,1.2,1.2,1.2,1.2,1.2];
// modulator (i.e. voice) is taken from the right channel of input
snd = In.ar(in_bus+1,1);
// snd = PlayBuf.ar(1, ~b0, loop: 1, rate: 1);
// voicedCarrier = In.ar(in_bus, 1);
voicedCarrier = In.ar(in_bus,1);
replacementSound = LPF.ar(HPF.ar(WhiteNoise.ar(mul: 1), 3000), 8000);
// FFT based voiced/unvoiced detection
chain = FFT(LocalBuf(1024), snd);
perc = SpecPcile.kr(chain, 0.9).explin(2000, 8000, 0, 1);
carrier = SelectX.ar(perc.lag(0.2), [voicedCarrier, replacementSound]);
// carrier = replacementSound ! 2;
// carrier = SelectX.ar((ZeroCrossing.ar(snd).cpsmidi.lag(0.02) > 2500.cpsmidi).lag(0.02), [voicedCarrier, replacementSound]);
// carrier = WhiteNoise.ar();
snd = Amplitude.ar(BPF.ar(snd, bandFreqs, 0.05, bandMuls), 0.01, 0.05);
snd = BPF.ar(carrier, bandFreqs, 0.1, bandMuls) * snd;
// snd = carrier * snd;
snd = snd.sum;
// snd = snd + (ToggleFF.ar(LPF.ar(snd, 100, 0.05)) * 0.01);
snd = snd * 30.dbamp;
// snd = Mix.ar([snd, carrier * 0.3])
// snd = Limiter.ar(snd);
// snd = MoogVCF.ar(snd, 5000, 0.25) ! 2;
//snd = BitstreamPitchCorrection.ar(snd, target_note: 64);
Out.ar(out_bus, Pan2.ar(snd, pos: pan));
}));
vocoder.add;
// vocoder.writeDefFile("/Users/xavriley/Projects/sonic-pi/etc/synthdefs/compiled/"); // change this path to point to Sonic Pi on your system
)
x = Synth("sonic-pi-fx_vocoder");
y = Bus.audio(s, 2);
({
Out.ar(y, [Splay.ar(Saw.ar([60, 64, 67].midicps), spread: 0), PlayBuf.ar(2, ~b0, loop: 1, rate: 1)]);
// Pan2.ar(PlayBuf.ar(1, ~b1, loop: 1), 1);
}.play;)
x.set(\in_bus, y.index);
x.set(\pan, -1);
x.set(\in_bus, 0);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment