SynthMaker

Filters and optimization

Archive · 2008 48 old posts

From the original SynthMaker forum (2004–2014), with its members’ names and dates.

MyCo ·

Hi!

I work on optimizations of filter codes, so I thought I make a thread where everyone can post new filter or optimization of other filters.

Feel free to add your hacks 😈

MyCo ·

SVF3, calculation optimized, using hops, converted to Assembler:

streamin input; streamin cut; streamin resonance; streamout lowpass; streamout highpass; streamout bandpass; streamout notch; streamout peak;

float lp1=0; float bp1=0; float f=0; float nrez=0;

float MULTI=0.33333333333333333333333333333333; float MINCUT=0.00045351473922902494331065759637188; float TSF7=-0.000396825396825396825396825396; float TSF5=0.016666666666666666666666666666; float TSF3=-0.333333333333333333333333333332; float TSF1=0.51945286321522940099128899997997; float F1=1; float DENORM=1e-009;

mov eax,ecx; and eax,127; cmp eax,0; jnz hopend; // hop(128) movaps xmm0,MINCUT; maxps xmm0,cut; minps xmm0,F1; //xmm0 -> cutoff mulps xmm0,TSF1; movaps xmm7,xmm0; // x mulps xmm0,xmm7; // x2 movaps xmm1,xmm0; mulps xmm1,xmm7; // x3 movaps xmm2,xmm0; mulps xmm2,xmm1; // x5 movaps xmm3,xmm0; mulps xmm3,xmm2; // x7

addps xmm7,xmm7; mulps xmm1,TSF3; addps xmm7,xmm1; mulps xmm2,TSF5; addps xmm7,xmm2; mulps xmm3,TSF7; addps xmm7,xmm3; movaps f,xmm7;

movaps xmm0,resonance; subps xmm0,F1;

movaps nrez,xmm0; // end hop hopend:

movaps xmm7,input; addps xmm7,DENORM;

movaps xmm1,lp1; // xmm1 -> lp1 movaps xmm2,bp1; // xmm2 -> bp1

// step 1 movaps xmm0,xmm2; // xmm0 -> bp1 mulps xmm0,f; // xmm0 -> f*bp1 addps xmm1,xmm0; // xmm1 -> lp1 = f*bp1+lp1

movaps xmm0,xmm2; // xmm0 -> bp1 mulps xmm0,nrez; // xmm0 -> -(bp1*rez) addps xmm0,xmm7; // xmm0 -> input-(bp1*rez) subps xmm0,xmm1; // xmm0 -> hp1 = input-lp1-(bp1*rez) movaps xmm3,xmm0; // xmm3 -> hp1

mulps xmm0,f; // xmm0 -> f*hp1 addps xmm2,xmm0; // xmm2 -> bp1=bp1+f*hp1

movaps xmm4,xmm1; // xmm4 -> lowpass = lp1 movaps xmm5,xmm2; // xmm5 -> bandpass = bp1 movaps xmm6,xmm3; // xmm6 -> highpass = hp1

// step 2 movaps xmm0,xmm2; // xmm0 -> bp1 mulps xmm0,f; // xmm0 -> f*bp1 addps xmm1,xmm0; // xmm1 -> lp1 = f*bp1+lp1

movaps xmm0,xmm2; // xmm0 -> bp1 mulps xmm0,nrez; // xmm0 -> -(bp1*rez) addps xmm0,xmm7; // xmm0 -> input-(bp1*rez) subps xmm0,xmm1; // xmm0 -> hp1 = input-lp1-(bp1*rez) movaps xmm3,xmm0; // xmm3 -> hp1

mulps xmm0,f; // xmm0 -> f*hp1 addps xmm2,xmm0; // xmm2 -> bp1=bp1+f*hp1

addps xmm4,xmm1; // xmm4 -> lowpass = lowpass + lp1 addps xmm5,xmm2; // xmm5 -> bandpass = bandpass + bp1 addps xmm6,xmm3; // xmm6 -> highpass = highpass + hp1

// step 3 subps xmm7,DENORM;

movaps xmm0,xmm2; // xmm0 -> bp1 mulps xmm0,f; // xmm0 -> f*bp1 addps xmm1,xmm0; // xmm1 -> lp1 = f*bp1+lp1

movaps xmm0,xmm2; // xmm0 -> bp1 mulps xmm0,nrez; // xmm0 -> -(bp1*rez) addps xmm0,xmm7; // xmm0 -> input-(bp1*rez) subps xmm0,xmm1; // xmm0 -> hp1 = input-lp1-(bp1*rez) movaps xmm3,xmm0; // xmm3 -> hp1

mulps xmm0,f; // xmm0 -> f*hp1 addps xmm2,xmm0; // xmm2 -> bp1=bp1+f*hp1

addps xmm4,xmm1; // xmm4 -> lowpass = lowpass + lp1 addps xmm5,xmm2; // xmm5 -> bandpass = bandpass + bp1 addps xmm6,xmm3; // xmm6 -> highpass = highpass + hp1

// scale mulps xmm4,MULTI; mulps xmm5,MULTI; mulps xmm6,MULTI;

// for next loop movaps lp1,xmm1; movaps bp1,xmm2;

// output movaps lowpass,xmm4; movaps bandpass,xmm5; movaps highpass,xmm6; addps xmm7,xmm5; movaps peak,xmm7; addps xmm4,xmm6; movaps notch,xmm4;

70% reduced

MyCo ·

RBJ Lowpass, calculation optimized, denormalization added, using hops, converted to Assembler:

streamin in; streamin cutoff; streamin resonance; streamout out;

float smIntVarTemp=0.0; float a1=0; float a2=0; float b0=0; float b1=0; float b2=0; float in1=0; float in2=0; float out2=0;

float F65536=65536; float F16384=16384; float F0P001=0.001; float F0P499=0.499; float F0P5=0.5; float F1=1; float RESSCALE = 20.0; float RESOFFSET = 0.4; float DENORM=1e-09;

mov eax,ecx; and eax,127; cmp eax,0; jnz hopend; //hop(128) movaps xmm0,cutoff; mulps xmm0,F0P499; maxps xmm0,F0P001; minps xmm0,F0P499;

// sin mulps xmm0,F65536; movaps xmm1,xmm0;

movaps smIntVarTemp,xmm0; fld smIntVarTemp[0];fistp smIntVarTemp[0];mov eax,smIntVarTemp[0];and eax,65535;shl eax,2;add eax,sine;fld [eax];fstp smIntVarTemp[0]; fld smIntVarTemp[1];fistp smIntVarTemp[1];mov eax,smIntVarTemp[1];and eax,65535;shl eax,2;add eax,sine;fld [eax];fstp smIntVarTemp[1]; fld smIntVarTemp[2];fistp smIntVarTemp[2];mov eax,smIntVarTemp[2];and eax,65535;shl eax,2;add eax,sine;fld [eax];fstp smIntVarTemp[2]; fld smIntVarTemp[3];fistp smIntVarTemp[3];mov eax,smIntVarTemp[3];and eax,65535;shl eax,2;add eax,sine;fld [eax];fstp smIntVarTemp[3]; movaps xmm0,smIntVarTemp;

// cos addps xmm1,F16384; movaps smIntVarTemp,xmm1; fld smIntVarTemp[0];fistp smIntVarTemp[0];mov eax,smIntVarTemp[0];and eax,65535;shl eax,2;add eax,sine;fld [eax];fstp smIntVarTemp[0]; fld smIntVarTemp[1];fistp smIntVarTemp[1];mov eax,smIntVarTemp[1];and eax,65535;shl eax,2;add eax,sine;fld [eax];fstp smIntVarTemp[1]; fld smIntVarTemp[2];fistp smIntVarTemp[2];mov eax,smIntVarTemp[2];and eax,65535;shl eax,2;add eax,sine;fld [eax];fstp smIntVarTemp[2]; fld smIntVarTemp[3];fistp smIntVarTemp[3];mov eax,smIntVarTemp[3];and eax,65535;shl eax,2;add eax,sine;fld [eax];fstp smIntVarTemp[3]; movaps xmm1,smIntVarTemp;

movaps xmm2,resonance; mulps xmm2,RESSCALE; addps xmm2,RESOFFSET; divps xmm0,xmm2;

// xmm0 -> alpha // xmm1 -> cos

movaps xmm7,F1; movaps xmm4,xmm7; movaps xmm5,xmm7; addps xmm4,xmm0; // xmm4 -> 1+alpha divps xmm5,xmm4; // xmm5 -> scale = 1/(1+alpha)

subps xmm0,xmm7; mulps xmm0,xmm5; movaps a2,xmm0; // a2 = (alpha-1)*scale

movaps xmm3,xmm1; addps xmm3,xmm1; mulps xmm3,xmm5; movaps a1,xmm3; // a1 = 2*cos*scale

subps xmm7,xmm1; mulps xmm7,xmm5; movaps b1,xmm7; // b1 = (1-cos)*scale

movaps xmm0,F0P5; mulps xmm1,xmm0; subps xmm0,xmm1; mulps xmm0,xmm5; movaps b0,xmm0; // b0 = (0.5-0.5*cos)*scale // end hop hopend:

movaps xmm0,in2; movaps xmm7,b0; mulps xmm0,xmm7; // in2*b0

movaps xmm1,in1; movaps in2,xmm1; mulps xmm1,b1; addps xmm0,xmm1; // in2*b0+in1*b1

movaps xmm2,in; movaps in1,xmm2; mulps xmm2,xmm7; addps xmm0,xmm2; // in2*b0+in1*b1+in*b0

movaps xmm3,a1; movaps xmm4,a2; movaps xmm5,out; mulps xmm3,xmm5; mulps xmm4,out2; addps xmm0,xmm3; addps xmm0,xmm4; addps xmm0,DENORM; subps xmm0,DENORM; movaps out,xmm0; movaps out2,xmm5;

90% reduced

MyCo ·

RBJ Highpass, similar to the lowpass code above

streamin in; streamin cutoff; streamin resonance; streamout out;

float smIntVarTemp=0.0; float a1=0; float a2=0; float b0=0; float b1=0; float b2=0; float in1=0; float in2=0; float out2=0;

float F65536=65536; float F16384=16384; float F0P001=0.001; float F0P499=0.499; float F0P5=0.5; float F1=1; float RESSCALE = 20.0; float RESOFFSET = 0.4; float DENORM=1e-09;

mov eax,ecx; and eax,127; cmp eax,0; jnz hopend; //hop(128) movaps xmm0,cutoff; mulps xmm0,F0P499; maxps xmm0,F0P001; minps xmm0,F0P499;

// sin mulps xmm0,F65536; movaps xmm1,xmm0;

movaps smIntVarTemp,xmm0; fld smIntVarTemp[0];fistp smIntVarTemp[0];mov eax,smIntVarTemp[0];and eax,65535;shl eax,2;add eax,sine;fld [eax];fstp smIntVarTemp[0]; fld smIntVarTemp[1];fistp smIntVarTemp[1];mov eax,smIntVarTemp[1];and eax,65535;shl eax,2;add eax,sine;fld [eax];fstp smIntVarTemp[1]; fld smIntVarTemp[2];fistp smIntVarTemp[2];mov eax,smIntVarTemp[2];and eax,65535;shl eax,2;add eax,sine;fld [eax];fstp smIntVarTemp[2]; fld smIntVarTemp[3];fistp smIntVarTemp[3];mov eax,smIntVarTemp[3];and eax,65535;shl eax,2;add eax,sine;fld [eax];fstp smIntVarTemp[3]; movaps xmm0,smIntVarTemp;

// cos addps xmm1,F16384; movaps smIntVarTemp,xmm1; fld smIntVarTemp[0];fistp smIntVarTemp[0];mov eax,smIntVarTemp[0];and eax,65535;shl eax,2;add eax,sine;fld [eax];fstp smIntVarTemp[0]; fld smIntVarTemp[1];fistp smIntVarTemp[1];mov eax,smIntVarTemp[1];and eax,65535;shl eax,2;add eax,sine;fld [eax];fstp smIntVarTemp[1]; fld smIntVarTemp[2];fistp smIntVarTemp[2];mov eax,smIntVarTemp[2];and eax,65535;shl eax,2;add eax,sine;fld [eax];fstp smIntVarTemp[2]; fld smIntVarTemp[3];fistp smIntVarTemp[3];mov eax,smIntVarTemp[3];and eax,65535;shl eax,2;add eax,sine;fld [eax];fstp smIntVarTemp[3]; movaps xmm1,smIntVarTemp;

movaps xmm2,resonance; mulps xmm2,RESSCALE; addps xmm2,RESOFFSET; divps xmm0,xmm2;

// xmm0 -> alpha // xmm1 -> cos

movaps xmm7,F1; movaps xmm4,xmm7; movaps xmm5,xmm7; addps xmm4,xmm0; // xmm4 -> 1+alpha divps xmm5,xmm4; // xmm5 -> scale = 1/(1+alpha)

subps xmm0,xmm7; mulps xmm0,xmm5; movaps a2,xmm0; // a2 = (alpha-1)*scale

movaps xmm3,xmm1; addps xmm3,xmm1; mulps xmm3,xmm5; movaps a1,xmm3; // a1 = 2*cos*scale

addps xmm7,xmm1; mulps xmm7,xmm5; movaps b1,xmm7; // b1 = (1+cos)*scale

movaps xmm0,F0P5; mulps xmm1,xmm0; addps xmm0,xmm1; mulps xmm0,xmm5; movaps b0,xmm0; // b0 = (0.5+0.5*cos)*scale // end hop hopend:

movaps xmm0,in2; movaps xmm7,b0; mulps xmm0,xmm7; // in2*b0

movaps xmm1,in1; movaps in2,xmm1; mulps xmm1,b1; subps xmm0,xmm1; // in2*b0+in1*b1

movaps xmm2,in; movaps in1,xmm2; mulps xmm2,xmm7; addps xmm0,xmm2; // in2*b0+in1*b1+in*b0

movaps xmm3,a1; movaps xmm4,a2; movaps xmm5,out; mulps xmm3,xmm5; mulps xmm4,out2; addps xmm0,xmm3; addps xmm0,xmm4; addps xmm0,DENORM; subps xmm0,DENORM; movaps out,xmm0; movaps out2,xmm5;

MyCo ·

6dB Moog Lowpass

streamin input; streamin cutoff; streamin resonance; streamout output;

float p=0; float q=0;

float out1=0;

float lastout=0;

int ABSMASK=2147483647; float F99=99; float F100=100; float HALF=0.5;

float MAXCUT=0.99; float MINCUT=0.01;

float CUBF1=3.2937; float CUBF2=-0.59515; float CUBF3=-0.69346; float CUBOFFSET=-1.0072;

float SQRF1=2e-005; float SQRF2=-0.0069; float SQROFFSET=0.9597;

float ADJUSTGAIN=0.5; float SATLIMIT = 0.95;

mov eax,ecx; and eax,127; cmp eax,0; jnz hopend; // hop(128) movaps xmm0,cutoff; minps xmm0,MAXCUT; maxps xmm0,MINCUT; movaps xmm1,xmm0; movaps xmm2,xmm0; mulps xmm1,xmm0; // cutoff^2 mulps xmm2,xmm1; // cutoff^3 mulps xmm0,CUBF1; mulps xmm1,CUBF2; mulps xmm2,CUBF3; addps xmm0,xmm1; addps xmm0,xmm2; addps xmm0,CUBOFFSET; movaps p,xmm0;

mulps xmm0,F99; addps xmm0,F100; // xmm0=x

movaps xmm1,SQRF1; mulps xmm1,xmm0; mulps xmm1,xmm0; mulps xmm0,SQRF2; addps xmm0,xmm1; addps xmm0,SQROFFSET; //xmm0=gaintable mulps xmm0,resonance; movaps q,xmm0;

// end hop hopend:

movaps xmm0,input; subps xmm0,lastout; mulps xmm0,ADJUSTGAIN; //xmm0 = lastout

// step 1 movaps xmm1,out1; movaps xmm2,xmm0; // xmm2=lastout subps xmm2,xmm1; mulps xmm2,p; addps xmm2,xmm0;

movaps xmm0,xmm2; addps xmm0,SATLIMIT; subps xmm2,SATLIMIT; andps xmm2,ABSMASK; andps xmm0,ABSMASK; subps xmm0,xmm2; mulps xmm0,HALF; movaps out1,xmm0;

addps xmm1,xmm0; movaps xmm0,xmm1; addps xmm0,SATLIMIT; subps xmm1,SATLIMIT; andps xmm1,ABSMASK; andps xmm0,ABSMASK; subps xmm0,xmm1; mulps xmm0,HALF; //xmm0 = lastout

// finish movaps output,xmm0; mulps xmm0,q; movaps lastout,xmm0;

MyCo ·

12 dB Moog Lowpass (original code was made by rl), removed loop and memory access, converted to assembler.

streamin input; streamin cutoff; streamin resonance; streamout output;

float p=0; float q=0;

float out1=0; float out2=0;

float lastout=0;

int ABSMASK=2147483647; float F99=99; float F100=100; float HALF=0.5;

float MAXCUT=0.99; float MINCUT=0.01;

float CUBF1=3.2937; float CUBF2=-0.59515; float CUBF3=-0.69346; float CUBOFFSET=-1.0072;

float SQRF1=2e-005; float SQRF2=-0.0069; float SQROFFSET=0.9597;

float ADJUSTGAIN=0.25; float SATLIMIT = 0.95;

mov eax,ecx; and eax,127; cmp eax,0; jnz hopend; // hop(128) movaps xmm0,cutoff; minps xmm0,MAXCUT; maxps xmm0,MINCUT; movaps xmm1,xmm0; movaps xmm2,xmm0; mulps xmm1,xmm0; // cutoff^2 mulps xmm2,xmm1; // cutoff^3 mulps xmm0,CUBF1; mulps xmm1,CUBF2; mulps xmm2,CUBF3; addps xmm0,xmm1; addps xmm0,xmm2; addps xmm0,CUBOFFSET; movaps p,xmm0;

mulps xmm0,F99; addps xmm0,F100; // xmm0=x

movaps xmm1,SQRF1; mulps xmm1,xmm0; mulps xmm1,xmm0; mulps xmm0,SQRF2; addps xmm0,xmm1; addps xmm0,SQROFFSET; //xmm0=gaintable mulps xmm0,resonance; movaps q,xmm0;

// end hop hopend:

movaps xmm0,input; subps xmm0,lastout; mulps xmm0,ADJUSTGAIN; //xmm0 = lastout

// step 1 movaps xmm1,out1; movaps xmm2,xmm0; // xmm2=lastout subps xmm2,xmm1; mulps xmm2,p; addps xmm2,xmm0;

movaps xmm0,xmm2; addps xmm0,SATLIMIT; subps xmm2,SATLIMIT; andps xmm2,ABSMASK; andps xmm0,ABSMASK; subps xmm0,xmm2; mulps xmm0,HALF; movaps out1,xmm0;

addps xmm1,xmm0; movaps xmm0,xmm1; addps xmm0,SATLIMIT; subps xmm1,SATLIMIT; andps xmm1,ABSMASK; andps xmm0,ABSMASK; subps xmm0,xmm1; mulps xmm0,HALF;

// step 2 movaps xmm1,out2; movaps xmm2,xmm0; // xmm2=lastout subps xmm2,xmm1; mulps xmm2,p; addps xmm2,xmm0;

movaps xmm0,xmm2; addps xmm0,SATLIMIT; subps xmm2,SATLIMIT; andps xmm2,ABSMASK; andps xmm0,ABSMASK; subps xmm0,xmm2; mulps xmm0,HALF; movaps out2,xmm0;

addps xmm1,xmm0; movaps xmm0,xmm1; addps xmm0,SATLIMIT; subps xmm1,SATLIMIT; andps xmm1,ABSMASK; andps xmm0,ABSMASK; subps xmm0,xmm1; mulps xmm0,HALF;

// finish movaps output,xmm0; mulps xmm0,q; movaps lastout,xmm0;

MyCo ·

24dB Moog Lowpass, similar to the 6 and 12 dB version

streamin input; streamin cutoff; streamin resonance; streamout output;

float p=0; float q=0;

float out1=0; float out2=0; float out3=0; float out4=0;

float lastout=0;

int ABSMASK=2147483647; float F99=99; float F100=100; float HALF=0.5;

float MAXCUT=0.99; float MINCUT=0.01;

float CUBF1=3.2937; float CUBF2=-0.59515; float CUBF3=-0.69346; float CUBOFFSET=-1.0072;

float SQRF1=2e-005; float SQRF2=-0.0069; float SQROFFSET=0.9597;

float ADJUSTGAIN=0.0625; float SATLIMIT = 0.95;

mov eax,ecx; and eax,127; cmp eax,0; jnz hopend; // hop(128) movaps xmm0,cutoff; minps xmm0,MAXCUT; maxps xmm0,MINCUT; movaps xmm1,xmm0; movaps xmm2,xmm0; mulps xmm1,xmm0; // cutoff^2 mulps xmm2,xmm1; // cutoff^3 mulps xmm0,CUBF1; mulps xmm1,CUBF2; mulps xmm2,CUBF3; addps xmm0,xmm1; addps xmm0,xmm2; addps xmm0,CUBOFFSET; movaps p,xmm0;

mulps xmm0,F99; addps xmm0,F100; // xmm0=x

movaps xmm1,SQRF1; mulps xmm1,xmm0; mulps xmm1,xmm0; mulps xmm0,SQRF2; addps xmm0,xmm1; addps xmm0,SQROFFSET; //xmm0=gaintable mulps xmm0,resonance; movaps q,xmm0;

// end hop hopend:

movaps xmm0,input; subps xmm0,lastout; mulps xmm0,ADJUSTGAIN; //xmm0 = lastout

// step 1 movaps xmm1,out1; movaps xmm2,xmm0; // xmm2=lastout subps xmm2,xmm1; mulps xmm2,p; addps xmm2,xmm0;

movaps xmm0,xmm2; addps xmm0,SATLIMIT; subps xmm2,SATLIMIT; andps xmm2,ABSMASK; andps xmm0,ABSMASK; subps xmm0,xmm2; mulps xmm0,HALF; movaps out1,xmm0;

addps xmm1,xmm0; movaps xmm0,xmm1; addps xmm0,SATLIMIT; subps xmm1,SATLIMIT; andps xmm1,ABSMASK; andps xmm0,ABSMASK; subps xmm0,xmm1; mulps xmm0,HALF;

// step 2 movaps xmm1,out2; movaps xmm2,xmm0; // xmm2=lastout subps xmm2,xmm1; mulps xmm2,p; addps xmm2,xmm0;

movaps xmm0,xmm2; addps xmm0,SATLIMIT; subps xmm2,SATLIMIT; andps xmm2,ABSMASK; andps xmm0,ABSMASK; subps xmm0,xmm2; mulps xmm0,HALF; movaps out2,xmm0;

addps xmm1,xmm0; movaps xmm0,xmm1; addps xmm0,SATLIMIT; subps xmm1,SATLIMIT; andps xmm1,ABSMASK; andps xmm0,ABSMASK; subps xmm0,xmm1; mulps xmm0,HALF;

// step 3 movaps xmm1,out3; movaps xmm2,xmm0; // xmm2=lastout subps xmm2,xmm1; mulps xmm2,p; addps xmm2,xmm0;

movaps xmm0,xmm2; addps xmm0,SATLIMIT; subps xmm2,SATLIMIT; andps xmm2,ABSMASK; andps xmm0,ABSMASK; subps xmm0,xmm2; mulps xmm0,HALF; movaps out3,xmm0;

addps xmm1,xmm0; movaps xmm0,xmm1; addps xmm0,SATLIMIT; subps xmm1,SATLIMIT; andps xmm1,ABSMASK; andps xmm0,ABSMASK; subps xmm0,xmm1; mulps xmm0,HALF;

// step 4 movaps xmm1,out4; movaps xmm2,xmm0; // xmm2=lastout subps xmm2,xmm1; mulps xmm2,p; addps xmm2,xmm0;

movaps xmm0,xmm2; addps xmm0,SATLIMIT; subps xmm2,SATLIMIT; andps xmm2,ABSMASK; andps xmm0,ABSMASK; subps xmm0,xmm2; mulps xmm0,HALF; movaps out4,xmm0;

addps xmm1,xmm0; movaps xmm0,xmm1; addps xmm0,SATLIMIT; subps xmm1,SATLIMIT; andps xmm1,ABSMASK; andps xmm0,ABSMASK; subps xmm0,xmm1; mulps xmm0,HALF;

// finish movaps output,xmm0; mulps xmm0,q; movaps lastout,xmm0;

MyCo ·

Single pole Lowpass+Highpass converted to assembler:

streamin in; streamin cutoff; streamout LP; streamout HP;

movaps xmm1,in; movaps xmm0,xmm1; subps xmm0,LP; mulps xmm0,cutoff; addps xmm0,LP;

movaps LP,xmm0; subps xmm1,xmm0; movaps HP,xmm1;

MichaelBenjamin ·

very nice, im just at the beginning of understanding the sm codes. your optimisations are great!

MyCo ·

Thanks Michael!

optimized DC blocker in assembler:

streamin in; streamout out;

float SCALE=0.9999; float lastin=0;

movaps xmm1,in; movaps xmm0,out; mulps xmm0,SCALE; subps xmm0,lastin; addps xmm0,xmm1; movaps lastin,xmm1; movaps out,xmm0;

original code is here: DC blocker filter

MyCo ·

Here is a file of all the optimized filters, that I've got til now.

infuzion ·

Thanks alot MyCo 😇

peterv ·

MyCo, Thanks very much for your magical work!

sunsynth ·

Great work! 😀

Danke, Walter

infuzion ·

MyCo wrote: RBJ Highpass, similar to the lowpass code above

... //hop(128) movaps xmm0,cutoff; maxps xmm0,F0P001; minps xmm0,F0P499; ...{left in only code I'm questioning}

movaps xmm3,a1; movaps xmm4,a2; movaps xmm5,out1; mulps xmm3,xmm5; mulps xmm4,out2; addps xmm0,xmm3; addps xmm0,xmm4; addps xmm0,DENORM; subps xmm0,DENORM; movaps out,xmm0; movaps out1,xmm0; movaps out2,xmm5;

I do have 2 observations: 1) I find it strange to hard-limit the cutoff below 4.99; shouldn't the cutoff be multiplied by the said 4.99 first so the entire knob's range can be used? 2) I tip my hat to you MyCo; your ASM-fu is excellent! Seems that out= out1; they both are assigned by the same xmm0 at the very end, & out is not altered before out1 is used. So can out1 can be dropped all together? With my minor hand-interleaving, replacing the end here will save about 4 cycles on my laptop, & a memory location: ... movaps xmm3,a1; movaps xmm4,a2; movaps xmm5,out; //out1 mulps xmm3,xmm5; mulps xmm4,out2; addps xmm0,xmm3; movaps out2,xmm5; addps xmm0,xmm4; addps xmm0,DENORM; subps xmm0,DENORM; movaps out,xmm0; //movaps out1,xmm0; I'm thinking similar adjustments may be made to the RBJ Lowpass & perhaps a few others (not Moog).

MyCo ·

yes... you're right. I've updated the code above.

chironex ·

Many thanks. I am stealing this for my drum vst! 😉

infuzion ·

MyCo wrote: yes... you're right. I've updated the code above.

Cool; I'm glad I was able to help out with your great coding 🙂

Large ·

Myco, this is great, but I tried the first code you posted (the SVF) and it does not work with cutoff modulation. It might be a problem with the other filters as well.

Maybe you could fix? Thanks

MyCo ·

I don't know what you mean, it works as it should as long as your modulation stays below 170Hz... see attachment

Large ·

MyCo wrote: I don't know what you mean, it works as it should as long as your modulation stays below 170Hz... see attachment

I'm not referring to LFO's. When feeding another oscillator into a normal SVF's cutoff modulation, you can get some nice effects, regardless of frequency, but with yours, when I feed an oscillator into your cutoff, it produces flawed sound.

Move the "Talking Text Knob" at the top to compare the normal SVF and your SVF, and let me know if you notice the difference.

MyCo ·

yeah, it's because you feed it with a 1kHz wave. The code isn't made for something like that. If you need it, remove the hop in the code. Here it is for SVF3:

streamin input; streamin cut; streamin resonance; streamout lowpass; streamout highpass; streamout bandpass; streamout notch; streamout peak;

float lp1=0; float bp1=0; float f=0; float nrez=0;

float MULTI=0.33333333333333333333333333333333; float MINCUT=0.00045351473922902494331065759637188; float TSF7=-0.000396825396825396825396825396; float TSF5=0.016666666666666666666666666666; float TSF3=-0.333333333333333333333333333332; float TSF1=0.51945286321522940099128899997997; float F1=1; float DENORM=1e-009;

/*mov eax,ecx; and eax,127; cmp eax,0; jnz hopend;*/ // hop(128) movaps xmm0,MINCUT; maxps xmm0,cut; minps xmm0,F1; //xmm0 -> cutoff mulps xmm0,TSF1; movaps xmm7,xmm0; // x mulps xmm0,xmm7; // x2 movaps xmm1,xmm0; mulps xmm1,xmm7; // x3 movaps xmm2,xmm0; mulps xmm2,xmm1; // x5 movaps xmm3,xmm0; mulps xmm3,xmm2; // x7

addps xmm7,xmm7; mulps xmm1,TSF3; addps xmm7,xmm1; mulps xmm2,TSF5; addps xmm7,xmm2; mulps xmm3,TSF7; addps xmm7,xmm3; movaps f,xmm7;

movaps xmm0,resonance; subps xmm0,F1;

movaps nrez,xmm0; // end hop //hopend:

movaps xmm7,input; addps xmm7,DENORM;

movaps xmm1,lp1; // xmm1 -> lp1 movaps xmm2,bp1; // xmm2 -> bp1

// step 1 movaps xmm0,xmm2; // xmm0 -> bp1 mulps xmm0,f; // xmm0 -> f*bp1 addps xmm1,xmm0; // xmm1 -> lp1 = f*bp1+lp1

movaps xmm0,xmm2; // xmm0 -> bp1 mulps xmm0,nrez; // xmm0 -> -(bp1*rez) addps xmm0,xmm7; // xmm0 -> input-(bp1*rez) subps xmm0,xmm1; // xmm0 -> hp1 = input-lp1-(bp1*rez) movaps xmm3,xmm0; // xmm3 -> hp1

mulps xmm0,f; // xmm0 -> f*hp1 addps xmm2,xmm0; // xmm2 -> bp1=bp1+f*hp1

movaps xmm4,xmm1; // xmm4 -> lowpass = lp1 movaps xmm5,xmm2; // xmm5 -> bandpass = bp1 movaps xmm6,xmm3; // xmm6 -> highpass = hp1

// step 2 movaps xmm0,xmm2; // xmm0 -> bp1 mulps xmm0,f; // xmm0 -> f*bp1 addps xmm1,xmm0; // xmm1 -> lp1 = f*bp1+lp1

movaps xmm0,xmm2; // xmm0 -> bp1 mulps xmm0,nrez; // xmm0 -> -(bp1*rez) addps xmm0,xmm7; // xmm0 -> input-(bp1*rez) subps xmm0,xmm1; // xmm0 -> hp1 = input-lp1-(bp1*rez) movaps xmm3,xmm0; // xmm3 -> hp1

mulps xmm0,f; // xmm0 -> f*hp1 addps xmm2,xmm0; // xmm2 -> bp1=bp1+f*hp1

addps xmm4,xmm1; // xmm4 -> lowpass = lowpass + lp1 addps xmm5,xmm2; // xmm5 -> bandpass = bandpass + bp1 addps xmm6,xmm3; // xmm6 -> highpass = highpass + hp1

// step 3 subps xmm7,DENORM;

movaps xmm0,xmm2; // xmm0 -> bp1 mulps xmm0,f; // xmm0 -> f*bp1 addps xmm1,xmm0; // xmm1 -> lp1 = f*bp1+lp1

movaps xmm0,xmm2; // xmm0 -> bp1 mulps xmm0,nrez; // xmm0 -> -(bp1*rez) addps xmm0,xmm7; // xmm0 -> input-(bp1*rez) subps xmm0,xmm1; // xmm0 -> hp1 = input-lp1-(bp1*rez) movaps xmm3,xmm0; // xmm3 -> hp1

mulps xmm0,f; // xmm0 -> f*hp1 addps xmm2,xmm0; // xmm2 -> bp1=bp1+f*hp1

addps xmm4,xmm1; // xmm4 -> lowpass = lowpass + lp1 addps xmm5,xmm2; // xmm5 -> bandpass = bandpass + bp1 addps xmm6,xmm3; // xmm6 -> highpass = highpass + hp1

// scale mulps xmm4,MULTI; mulps xmm5,MULTI; mulps xmm6,MULTI;

// for next loop movaps lp1,xmm1; movaps bp1,xmm2;

// output movaps lowpass,xmm4; movaps bandpass,xmm5; movaps highpass,xmm6; addps xmm7,xmm5; movaps peak,xmm7; addps xmm4,xmm6; movaps notch,xmm4;

Large ·

Yes, this works now. But I still see "hop" in the code. That part confuses me on how you removed it.

It would be great if you could post all the filters without the hop. You could call them "hopless". Thanks.

MyCo ·

I just commented the part out, that you don't need. It is for every posted filter the same.

aliasant ·

MyCo wrote: I just commented the part out, that you don't need. It is for every posted filter the same.

Thanx MyCo.

Wonderful stuff. The SVF without the hop part sounds great and is only using 50 more cycles or so.

Shouldnt it be pretty easy to implement Low and High Shelving filters in the SVF3 since it already has Low and Hipass?

Something like: Highshelving = in - lopass * boost;

Or something?

It would of course need an additional boost input but that could be used for the Peak filter as well.

matti ·

To my taste hopping in filters is a terrible mistake. In a synth the filter's are usually in motion, following an envelope or lfo's. Hopping works only in static filters.. and in those you could prob remove the code inside the hop completely and do the calculations outside the audio thread, right?

After testing the filters: Ok, the sound isn't that bad. You can get some pretty nasty aliasing tho when modulating..

Acrobat ·

matti wrote: To my taste hopping in filters is a terrible mistake.

I feel the same, well I tossed the hops from these but then the CPU raised again... 😕

electrogear ·

Yes. It seems SM is all about balancing CPU. I learned the hard way...

matti ·

Acrobat wrote: matti wrote: To my taste hopping in filters is a terrible mistake.

I feel the same, well I tossed the hops from these but then the CPU raised again... 😕

It didn't sound bad at all when i started testing the filter. It might be a very good way to reduce the cpu usage of filters (tho they don't take that much to begin with).

djhayman ·

Hello,

I know this thread is old but i thought i would try and make a contribution in return for the fantastic code.

Here is a knob with an exponential curve to increase resolution at low frequencies which is particularly useful for lowpass filters. It also does away with the '0-1 to hz' module. I don't know if it adds CPU usage but hopefully its not much if anything.

Cheers

Dan

infuzion ·

djhayman wrote: Here is a knob with an exponential curve to increase resolution at low frequencies which is particularly useful for lowpass filters. It also does away with the '0-1 to hz' module. I don't know if it adds CPU usage but hopefully its not much if anything.

Thanks; it is handy! The only time it will add CPU is if there is alot of changes in the knob's value ("automation") very rapidly due to the power. If the value is static then there will be no more CPU used since it is green maths.

Acrobat ·

djhayman wrote: Here is a knob with an exponential curve to increase resolution at low frequencies which is particularly useful for lowpass filters.

thanks you and welcome on the forum to a smiling face 😀

MegaHurtz ·

Heres an edit to that, to be compatible with the current standard where a= 440 Hz. Equal tempered so to speak..

Dave ·

Hi,

i wanna add an ADSR module to the cutoff-input of the filter module... but it doesn't work (ADSR will be ignored).

Any ideas?

Thanks, Dave

Nu Audio Science ·

Yeah you have a mono filter so nothing to trigger the envelope If it was poly then the envelope would be triggered with the poly stream 😉

NAS

Dave ·

Ah okay got it 🙂

Nu Audio Science ·

Nope that isn't what i said 😉 You have nothing triggering the envelope Connect it to a poly to MIDI and then convert the output of the envelope to MONO

That should work There are other ways to do it but this way has a bunch of advantages (Oh don't forget you will still need a MIDI note so that the envelope triggers)

NAS

Dave ·

Thanks!

The example is a little bit irritating... the new filter module should replace the old one and not be at the end of the signal 🙂

Large ·

Hi Myco, can you post an example where the SVF filter has a PHASE input?

I want to have a bandpass-only filter, that takes a phase input of 0-1, and acts just like the sine wave oscillator when the phase is altered.

The phase should be able to be modulated real-time without any zipping noise.

Large ·

Bump...

Some help here? Please?

MegaHurtz ·

You can go ahead and find some nice coordinates and use them on the biquad filter. That is the flexible filter you are looking for. On the Pi (or SFV) filter theres no such thing as a phase option because it is an ("Infinite" impulse response) filter or IIR. The biquad is a (finite impulse response) or FIR, the latter can morph into most filter responces.

Large ·

Not sure what you mean "find nice coordinates".

Could you post an OSM example, with a phase input?

MegaHurtz ·

Really?? Take the biquad module and see where the coordinates go.

Large ·

These vague responses are not helping me at all.

Can you please post an OSM of what you are talking about?

Otherwise, can someone else who actually knows DSP please post an OSM example?

aliasant ·

Large wrote: ... Otherwise, can someone else who actually knows DSP please post an OSM example?

There seems to be no one in the SM community that knows DSP the way you would like. Why that is I cant say...

MegaHurtz was trying to encourage you to EXPERIMENT. In your case I think that is a great advice since you have been hitting your head on the same stubborn nail for quite some time now. Maybe experimenting on your own can get you forward for a change?

Large ·

The guy doesn't post examples of what he is talking about. Doesn't help at all.

tor ·

MegaHurtz I will have to arrest you regarding biquad beeing a FIR. It is most definetly a IIR since it also depend on the feedback of the output. Though if one do not get answers it is probably because no one has a good answer to the question and as aliasant mention.. there is experimentaion and also google. In the wiki there is many links to good dsp sites. Good luck 😉

MegaHurtz ·

You may be right, I recall it being comprised of adding alone. Althoug strangely if i`d make one, I would use the differential to make both moog and biquad. Must be me..

Wrote something here? To have a post removed or your name hidden, write to [email protected].

Before your first post

A few rules keep this a friendly place. You agree to them once.

Shown next to what you post, here and in the app. It doesn’t have to be your real name: 3–24 lower-case letters, digits or _ (capitals become lower case, spaces become _).

    Then your post goes up straight away.

    Delete this reply?

    Open it in SynthMaker?

    It goes on the track you’re editing there, in place of that track’s sound, and into My sounds. Your other tracks stay as they are.

    Want to keep that track’s sound? Start a new song in SynthMaker first (Song › New song), then open this.

    Report this reply?

    Only the developer reads reports. The person isn’t told who reported them.

    What’s wrong with it?

    Block this person?

    You won’t see their posts and replies here any more. They aren’t told, and you can unblock them at any time.

    People you’ve blocked

    Their posts and replies are hidden from you. Unblock someone to see them again.

    The community rules

    A few rules keep this a friendly place. Everyone agrees to them once, before their first post.