package jass.generators; /** Second order Butterworth lowpass filter. @author Kees van den Doel (kvdoel@cs.ubc.ca) */ public class Butter2LowFilter implements Filter { /** Sampling rate in Hertz. */ protected float srate; /** State of filter. */ private float yt_1, yt_2,xt_1,xt_2; /** Cutoff frequency in Hertz. */ protected float f; /** Coefficients (Steiglitz notation). */ protected float cc, dd; /** Gain. A0 is normalized. A is actual gain, gain is user settable*/ protected float A = 1.f, A0=1.f, gain=1; /** Create and initialize. @param srate sampling rate in Hertz. */ public Butter2LowFilter(float srate) { this.srate = srate; reset(); } /** Set the filter cutoff. @param f cutoff frequency in Hertz. */ public synchronized void setCutoffFrequency(float f) { float tt = (float)(Math.sqrt(2)/Math.tan(2*Math.PI*f/srate)); float tp = tt + 1, tm = tt - 1; float den = tp*tp+1; float re = (tm*tp-1)/den; float im = 2*tt/den; cc = -2*re; dd = re*re+im*im; A0 = (1 + cc + dd)/4; A = gain*A0; } /** Set gain. @param gain gain. */ public synchronized void setGain(float gain) { A = gain*A0; this.gain = gain; } /** Reset state. */ public synchronized void reset() { yt_1 = yt_2 = xt_1 = xt_2 = 0; } /** Reset state. @param c value of constant state */ public synchronized void reset(float c) { yt_1 = yt_2 = xt_1 = xt_2 = c; } /** Proces input (may be same as output). @param output user provided buffer for returned result. @param input user provided input buffer. @param nsamples number of samples written to output buffer. @param inputOffset where to start in circular buffer input. */ public synchronized void filter(float [] output, float[] input, int nsamples, int inputOffset) { if(inputOffset == 0) { for(int k=0;k<nsamples;k++) { float ynew = input[k] + 2*xt_1 + xt_2 - cc*yt_1 - dd*yt_2; yt_2 = yt_1; yt_1 = ynew; xt_2 = xt_1; xt_1 = input[k]; output[k] = A*ynew; } } else { int inputLen = input.length; int ii = inputOffset; for(int k=0;k<nsamples;k++) { float ynew = input[ii] + 2*xt_1 + xt_2 - cc*yt_1 - dd*yt_2; yt_2 = yt_1; yt_1 = ynew; xt_2 = xt_1; xt_1 = input[ii]; output[k] = A*ynew; if(ii == inputLen - 1) { ii = 0; } else { ii++; } } } } }