filter algorithm in mxj~


    Mar 10 2008 | 11:31 pm
    I'm currently trying to implement the following filter algorithm from music-dsp (for school ;):
    --------------------------------------------------------- r = rez amount, from sqrt(2) to ~ 0.1 f = cutoff frequency (from ~0 Hz to SampleRate/2 - though many synths seem to filter only up to SampleRate/4)
    The filter algo: out(n) = a1 * in + a2 * in(n-1) + a3 * in(n-2) - b1*out(n-1) - b2*out(n-2)
    Lowpass: c = 1.0 / tan(pi * f / sample_rate);
    a1 = 1.0 / ( 1.0 + r * c + c * c); a2 = 2* a1; a3 = a1; b1 = 2.0 * ( 1.0 - c*c) * a1; b2 = ( 1.0 - r * c + c * c) * a1;
    Hipass: c = tan(pi * f / sample_rate);
    a1 = 1.0 / ( 1.0 + r * c + c * c); a2 = -2*a1; a3 = a1; b1 = 2.0 * ( c*c - 1.0) * a1; b2 = ( 1.0 - r * c + c * c) * a1; ---------------------------------------------------------
    My code compiles, but I'm not getting any sound from the outlet. I suspect this is because of the algorithm, which uses input and output values from 'back in time':
    out[i] = ( a1 * in[i] + a2 * in[i-1] + a3 * in[i-2] - b1*out[i-1] - b2*out[i-2] );
    Do I need to rewrite this with temp variables?
    My code looks like this:
    --------------------------------------------------------- import com.cycling74.max.*; import com.cycling74.msp.*; import java.lang.Math.*;
    public class filt extends MSPPerformer { private float freq = 500.0f; private float c = 0.0f; private float r = 0.1f;
    private float a1 = 0.0f; private float a2 = 0.0f; private float a3 = 0.0f; private float b1 = 0.0f; private float b2 = 0.0f;
    private float tin1 = 0.0f, tin2 = 0.0f, to3 = 0.0f, to4 = 0.0f;
    private float pi = 3.1415926f;
    private double sr;
    private static final String[] INLET_ASSIST = new String[]{ "input (sig)" }; private static final String[] OUTLET_ASSIST = new String[]{ "output (sig)" };
    public filt(float gain) { declareInlets(new int[]{SIGNAL, DataTypes.FLOAT}); declareOutlets(new int[]{SIGNAL});
    setInletAssist(0, "signal input"); setInletAssist(1, "freq"); setOutletAssist(OUTLET_ASSIST); }
    public void inlet(float f) {
    freq = f;
    }
    public void dspsetup(MSPSignal[] ins, MSPSignal[] outs) { //Max gives us the sample-rate 'sr' on load
    sr = ins[0].sr;
    post("dspsetup was called.'");
    }
    public void perform(MSPSignal[] ins, MSPSignal[] outs) {
    c = 1.0f / (float)Math.tan((double)(pi * freq / (float)sr));
    a1 = 1.0f / ( 1.0f + r * c + c * c); a2 = 2f* a1; a3 = a1; b1 = 2.0f * ( 1.0f - c*c) * a1; b2 = ( 1.0f - r * c + c * c) * a1;
    int i; float[] in = ins[0].vec; float[] out = outs[0].vec; int vec_size = ins[0].n;
    for(i = 0; i < vec_size; i++) {
    out[i] = ( a1 * in[i] + a2 * in[i-1] + a3 * in[i-2] - b1*out[i-1] - b2*out[i-2] );
    } } } ---------------------------------------------------------
    -- Morgan Sutherland

    • Mar 11 2008 | 12:06 am
      Resolved my problem with variable swapping:
      import com.cycling74.max.*; import com.cycling74.msp.*; import java.lang.Math.*;
      public class filt extends MSPPerformer { private float freq = 500.0f; private float c = 0.0f; private float r = 0.1f;
      private float a1 = 0.0f; private float a2 = 0.0f; private float a3 = 0.0f; private float b1 = 0.0f; private float b2 = 0.0f;
      private float tin1 = 0.0f, tin2 = 0.0f, tout1 = 0.0f, tout2 = 0.0f;
      private float pi = 3.1415926f;
      private double sr;
      private static final String[] INLET_ASSIST = new String[]{ "input (sig)" }; private static final String[] OUTLET_ASSIST = new String[]{ "output (sig)" };
      public filt(float gain) { declareInlets(new int[]{SIGNAL, DataTypes.FLOAT}); declareOutlets(new int[]{SIGNAL});
      setInletAssist(0, "signal input"); setInletAssist(1, "freq"); setOutletAssist(OUTLET_ASSIST); }
      public void inlet(float f) {
      freq = f;
      }
      public void dspsetup(MSPSignal[] ins, MSPSignal[] outs) { //Max gives us the sample-rate 'sr' on load
      sr = ins[0].sr;
      post("dspsetup was called.'");
      }
      public void perform(MSPSignal[] ins, MSPSignal[] outs) {
      c = 1.0f / (float)Math.tan((double)(pi * freq / (float)sr));
      a1 = 1.0f / ( 1.0f + r * c + c * c); a2 = 2f* a1; a3 = a1; b1 = 2.0f * ( 1.0f - c*c) * a1; b2 = ( 1.0f - r * c + c * c) * a1;
      int i; float[] in = ins[0].vec; float[] out = outs[0].vec; int vec_size = ins[0].n;
      for(i = 0; i < vec_size; i++) {
      out[i] = ( a1 * in[i] + a2 * tin1 + a3 * tin2 - b1*tout1 - b2*tout2 );
      tin2 = tin1; tin1 = in[i];
      tout2 = tout1; tout1 = out[i];
      } } }