Jump to content
Sign in to follow this  
Guest skibby

so I wrote a Vocoder in JS to sound like a Bode

Recommended Posts

Guest skibby

https://soundcloud.com/zhaozhou/zhaozhous-vocoder-test-14-nov-2014

 

it was designed to perform super well with super low saw waves like that one song in Syro *thanks Richard*

it uses the same frequencies as a bode vocoder

i spent the past four days actually coding this because i wasnt happy with any other vocoders.

theres still room for improvement, lots of optimisation, etc

 

and the code, for use in ReaJS

//Vocoder 14 nov 2014 Thanks SaulT and Amateur Tools DSP

//This plugin contains ideas and code techniques by RBJ, SaulT, Moog, Bode, Loser, etc.

//USE AT OWN RISK. This plugin could turn you into a human centipede.

//////////////////////////////////////////////////////////////////////



desc:Zhaozhou's Vocoder - carrier chans 1+2, modulator chans 3+4



slider1:0<-50,1000,0.5>Frequency Base Shift (hz)

slider6:0<-24,24,1>Carrier Amt

slider8:0<-24,24,1>Mod Amt

slider14:-90<-120,6,1>Threshold (db)

slider16:20<1,100,1>Fadein (ms)

slider18:20<1,100,1>Fadeout (ms)

slider20:20<1,100,1> RMS smoothing (ms)

slider60:-120<-120,6,0.01>Dry Mod Signal

slider62:7000<104.5,20000,1>Dry Mod Highpass Filter

slider64:0<-120,6,0.01> Main Out Amp



@init



// Freqs from Bode Vocoder (centered) \

f1=104.5; f2=179.5; f3=226; f4=284.5;

f5=358.5; f6=452; f7=569.5; f8=717.5;

f9=904; f10=1139; f11=1435; f12=1808;

f13=2260; f14=2852; f15=3616; f16=4556;



// Q's aka 'damp' for bandpass filters

q1=0.008; q2=0.05; q3=0.02; q4=0.03;

q5=0.03; q6=0.03; q7=0.03; q8=0.04;

q9=0.04; q10=0.04; q11=0.04; q12=0.04;

q13=.03; q14=0.05; q15=0.05; q16=0.05; q17=0.3;



// PCB trimpots for adjusting carriers after filters

trim1=0.2; trim2=0.2; trim3=0.01; trim4=0.4;

trim5=0.4; trim6=0.4; trim7=0.5; trim8=0.5;

trim9=0.6; trim10=0.6; trim11=0.7; trim12=0.7;

trim13=0.8; trim14=0.8; trim15=0.9; trim16=0.9;



// PCB trimpots for adjusting modulators after filters

// trim17=1.25; trim18=0.25; trim19=0.35; trim20=0.35;

// trim21=0.45; trim22=0.45; trim23=0.6; trim24=0.65;

// trim25=0.8; trim26=0.9; trim27=1; trim28=1.25;

// trim29=1.5; trim30=1.5; trim31=2; trim32=2;



// PCB trimpots for adjusting modulators after filters

trim17=49; trim18=3; trim19=100; trim20=4;

trim21=6; trim22=9; trim23=12; trim24=12;

trim25=15; trim26=25; trim27=30; trim28=40;

trim29=55; trim30=60; trim31=90; trim32=110;



// used by rbj filter

cDcAdd = 10^-30;

cDenorm = 10^-30;



// bandpass filter

function bp(in,freq,damp)

instance(c,a,fa,fb,fk,damp,d,fd,fc)

(

damp=damp*0.999 + 0.001;

c = ( 1 / tan( $pi*freq / srate ) );

a = 1 + c*(c+damp);

fa = 2 * (1 - c*c) / a;

fb = (1 + c*(c-damp)) / a;

fk = c*damp / a;

d = fk*in - (fa*fd + fb*fc);

in = d - fc;

fc = fd;

fd = d;

);



// lowpass for c1,m1

function lp(in,freq)

instance(in,freq,a9,s9,q9,w09,cosw09,sin209,alpha9,sinw09,b09,b19,b29,a09,a19,a29,b09,b19,b29,old,x19,x29,y19,y29)

(

a9 = 1;

s9 = 2;

q9 = 1 / (sqrt((a9 + 1/a9)*(1/s9 - 1) + 2));

w09 = 2 * $pi * freq/srate;

cosw09 = cos(w09);

sinw09 = sin(w09);

alpha9 = sinw09 / (2 * q9);

b09 = (1 - cosw09)/2;

b19 = (1 - cosw09);

b29 = (1 - cosw09)/2;

a09 = 1 + alpha9;

a19 = -2 * cosw09;

a29 = 1 - alpha9;

b09 /= a09;

b19 /= a09;

b29 /= a09;

a19 /= a09;

a29 /= a09;

old = in;

in = b09 * in + b19 * x19 + b29 * x29 - a19 * y19 - a29 * y29;

x29 = x19;

x19 = old;

y29 = y19;

y19 = in;

);



//highpass filter rbj

function hp(in,freq)

instance(in,hp_f,a0,s0,q0,cosw00,sinw00,alpha0,b00,b10,b20,a00,a10,a20,x10,x20,y20,y10,old_in)

(

hp_f = 2 * $pi * freq/srate;

a0 = 1; //start coeffs

s0 = 1;

q0 = 1 / (sqrt((a0 + 1/a0)*(1/s0 - 1) + 2));

cosw00 = cos(hp_f);

sinw00 = sin(hp_f);

alpha0 = sinw00 / (2 * q0);

b00 = (1 + cosw00)/2;

b10 = -(1 + cosw00);

b20 = (1 + cosw00)/2;

a00 = 1 + alpha0;

a10 = -2 * cosw00;

a20 = 1 - alpha0;

b00 /= a00;

b10 /= a00;

b20 /= a00;

a10 /= a00;

a20 /= a00;

hp_f != 0 ? ( //start hp filter

old_in = in;

in = b00 * in + b10 * x10 + b20 * x20 - a10 * y10 - a20 * y20;

x20 = x10;

x10 = old_in;

y20 = y10;

y10 = abs(in) < cDenorm ? 0 : in;

);

);



function g(in) // gate

instance(a,silentcnt,seekto,g8) //fadein and out are global

(

a=abs(in) > thresh;

a ?

(

silentcnt=0;

seekto=1;

) : (

(silentcnt+=1) > 2205 ? seekto=0;

);

seekto > 0.5 ?

(

g8=g8*fadein + (1-fadein);

) : (

g8=g8*fadeout);

in*=g8;

);



// smoothing out the audio rate stuff

function rms(in)

instance(rms_s,in)

(

rms_coeff = exp(-1/(slider20 * srate * 0.001));

rms_s = (rms_s * rms_coeff) + ((1 - rms_coeff) * in * in);

sqrt(rms_s);

);



@slider



//freqs and freq adjust

f1=104.5+slider1; f2=179.5+slider1; f3=226+slider1; f4=284.5+slider1;

f5=358.5+slider1; f6=452+slider1; f7=569.5+slider1; f8=717.5+slider1;

f9=904+slider1; f10=1139+slider1; f11=1435+slider1; f12=1808+slider1;

f13=2260+slider1; f14=2852+slider1; f15=3616+slider1; f16=4556+slider1;



//gate

thresh = 2 ^ (slider14/6);

fadein = 1/pow(10,1/(srate*slider16/1000));

fadeout = 1/pow(10,1/(srate*slider18/1000));



//rms

rms_coeff = exp(-1/(slider20 * srate * 0.001));



// gain amps

c_amt = 10^(slider6/20); //Carrier amt

m_amt = 10^(slider8/20); //Modulator amt

d_amt = 10^(slider60/20); //Dry Mod amt

o_amt = 10^(slider64/20); //main out



@sample



// dc fix, denormals

spl0 += cDcAdd;

spl1 += cDcAdd;



c_in=((spl0+spl1)*0.5)*c_amt;

m_in=((spl2+spl3)*0.5;)*m_amt;

dry_m=m_in;



//carrier filter array \\\\\\\\

c1= c1_lp.lp( c_in,f1 ) *trim1;

c2=c2_.hp( c2_bp.bp( c_in,f2,q2 ) ,f2 )*trim2;

c3=c3_.hp( c3_bp.bp( c_in,f3,q3 ) ,f3 )*trim3;

c4=c4_.hp( c4_bp.bp( c_in,f4,q4 ) ,f4 )*trim4;

c5=c5_.hp( c5_bp.bp( c_in,f5,q5 ) ,f5 )*trim5;

c6=c6_.hp( c6_bp.bp( c_in,f6,q6 ) ,f6 )*trim6;

c7=c7_.hp( c7_bp.bp( c_in,f7,q7 ) ,f7 )*trim7;

c8=c8_.hp( c8_bp.bp( c_in,f8,q8 ) ,f8 )*trim8;



c9=c9_.hp( c9_bp.bp( c_in,f9,q9 ) ,f9 )*trim9;

c10=c10_.hp( c10_bp.bp( c_in,f10,q10 ),f10 )*trim10;

c11=c11_.hp( c11_bp.bp( c_in,f11,q11 ),f11 )*trim11;

c12=c12_.hp( c12_bp.bp( c_in,f12,q12 ),f12 )*trim12;

c13=c13_.hp( c13_bp.bp( c_in,f13,q13 ),f13 )*trim13;

c14=c14_.hp( c14_bp.bp( c_in,f14,q14 ),f14 )*trim14;

c15=c15_.hp( c15_bp.bp( c_in,f15,q15 ),f15 )*trim15;

c16=c16_.hp( c16_bp.bp( c_in,f16,q16 ),f16 )*trim16;



//Modu Sig Chain

m1=m1.rms( m1_g.g( m1_lp.lp( m_in,f1 ))) *trim17;

m2=m2.rms(m2_.hp( m2_g.g( m2_bp.bp( m_in,f2,q2 )),f2 )) *trim18;

m3=m3.rms(m3_.hp( m3_g.g( m3_bp.bp( m_in,f3,q3 )),f3 )) *trim19;

m4=m4.rms(m4_.hp( m4_g.g( m4_bp.bp( m_in,f4,q4 )),f4 )) *trim20;

m5=m5.rms(m5_.hp( m5_g.g( m5_bp.bp( m_in,f5,q5 )),f5 )) *trim21;

m6=m6.rms(m6_.hp( m6_g.g( m6_bp.bp( m_in,f6,q6 )),f6 )) *trim22;

m7=m7.rms(m7_.hp( m7_g.g( m7_bp.bp( m_in,f7,q7 )),f7 )) *trim23;

m8=m8.rms(m8_.hp( m8_g.g( m8_bp.bp( m_in,f8,q8 )),f8 )) *trim24;



m9=m9.rms(m9_.hp( m9_g.g( m9_bp.bp( m_in,f9,q9 )),f9 )) *trim25;

m10=m10.rms(m10_.hp( m10_g.g( m10_bp.bp( m_in,f10,q10 )),f10 )) *trim26;

m11=m11.rms(m11_.hp( m11_g.g( m11_bp.bp( m_in,f11,q11 )),f11 )) *trim27;

m12=m12.rms(m12_.hp( m12_g.g( m12_bp.bp( m_in,f12,q12 )),f12 )) *trim28;

m13=m13.rms(m13_.hp( m13_g.g( m13_bp.bp( m_in,f13,q13 )),f13 )) *trim29;

m14=m14.rms(m14_.hp( m14_g.g( m14_bp.bp( m_in,f14,q14 )),f14 )) *trim30;

m15=m15.rms(m15_.hp( m15_g.g( m15_bp.bp( m_in,f15,q15 )),f15 )) *trim31;

m16=m16.rms(m16_.hp( m16_g.g( m16_bp.bp( m_in,f16,q16 )),f16 )) *trim32;



// Modulation Block

c1*=m1; c2*=m2; c3*=m3; c4*=m4;

c5*=m5; c6*=m6; c7*=m7; c8*=m8;

c9*=m9; c10*=m10; c11*=m11; c12*=m12;

c13*=m13; c14*=m14; c15*=m15; c16*=m16;


//the final summing and amp section

dry_m=(dry.hp(dry.bp((g(dry_m)),9000,q17),5080)*d_amt);

spl1=(c1+c2+c3+c4+c5+c6+c7+c8+c9+c10+c11+c12+c13+c14+c15+c16+dry_m)*o_amt;

//spl1=(m1+m2+m3+m4+m5+m6+m7+m8+m9+m10+m11+m12+m13+m14+m15+m16+dry_m)*o_amt;

//spl1=(m16)*o_amt;



spl0=spl1;

Share this post


Link to post
Share on other sites

noice

Share this post


Link to post
Share on other sites
Guest skibby

that code will be out of date, just check the reaper forum js thread for updates i reckon.

Share this post


Link to post
Share on other sites

Huge fan of the original Bode here, will there be a vst version?

Share this post


Link to post
Share on other sites

wicked. I need a good software vocoder. gonna have to check this out!

Share this post


Link to post
Share on other sites
Guest skibby

still missing:

 

noise generator
better sibilance filter+saturation

 

much to come.

Share this post


Link to post
Share on other sites
Guest wyvern

Very cool. I was looking into timbre.js, which wraps Web Audio API, for browser embedded synth. Those are fun to play with.

Share this post


Link to post
Share on other sites
Guest skibby

as it stands, this plugin is very expensive CPU wise. just like real life, since a real Bode would also be expensive. even the gear required to make one would cost a lot.

 

a good thing to do would is devirtualise this down to a pcb and make it into hardware someday.

 

before then, some optimisation will imminent itself

Share this post


Link to post
Share on other sites

is there a vst version?

Share this post


Link to post
Share on other sites
Guest skibby

reajs has a third party hostable vst version, but only for pc right now.

comes bundled at http://www.reaper.fm/reaplugs/

 

otherwise, reaper comes with reajs and runs on all platforms.

Share this post


Link to post
Share on other sites

Impressive! How long did this take?

 

I'm starting research on a web midi thing. This is amazing. :D

Share this post


Link to post
Share on other sites
Guest skibby

took 3 or 4 days to implement so far, but it took ages to both understand how actually simple it is and get around to doing it.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...