Jump to content

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


Guest skibby
 Share

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 comment
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 comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Similar Content

    • By user
      Finished soldering my 4th eurorack module today, the turing machine by music thing. Even though I didn't add any extra flux while soldering I noticed the boards were quite sticky and had some specks of solder on them so decided to try to clean them a bit with cotton swabs and 96% alcohol. While doing this a whole bunch of the joints developed a white crust that doesn't look good at all. I googled a bit but got overwhelmed trying to figure out what it could be so I turn to the watmm hive-mind for help. Here's a pic: (feel free to ridicule my crummy soldering skills)

       
      This is after going over the whole board, as you can see not all the joints are as badly affected... I used 60/40 leaded soldering tin with a flux core. There's still a lot of flux but I stopped what I was doing when I noticed the white oxidation or whatever it is.   
      Anyone have any idea what I should do? I've some distilled water as well but don't wanna try anything else before getting some advice from someone who isn't as ignorant as myself. 
       
×
×
  • Create New...