Jump to content

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


Guest skibby

Recommended Posts

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;
Link to post
Share on other sites

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

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
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...