Skip to content

Instantly share code, notes, and snippets.

@kode54
Created March 9, 2014 02:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kode54/9442296 to your computer and use it in GitHub Desktop.
Save kode54/9442296 to your computer and use it in GitHub Desktop.
#define _USE_MATH_DEFINES
#include "iirfilters.h"
#include <math.h>
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795
#endif
IIRFilter::IIRFilter()
{
}
IIRFilter::~IIRFilter()
{
}
void IIRFilter::setFrequency(float val)
{
pf_freq = val;
}
void IIRFilter::setQuality(float val)
{
pf_qfact = val;
}
void IIRFilter::setGain(float val)
{
pf_gain = val;
}
void IIRFilter::init(int samplerate, int filter_type)
{
xn1=0;
xn2=0;
yn1=0;
yn2=0;
omega = 2 * M_PI * pf_freq/samplerate;
cs = cos(omega);
sn = sin(omega);
a1pha = sn / (2.0 * pf_qfact);
beta = sqrt(A + A);
A = exp(log(10.0) * pf_gain / 40);
//Set up filter coefficients according to type
switch (filter_type)
{
case LPF:
b0 = (1.0 - cs) / 2.0 ;
b1 = 1.0 - cs ;
b2 = (1.0 - cs) / 2.0 ;
a0 = 1.0 + a1pha ;
a1 = -2.0 * cs ;
a2 = 1.0 - a1pha ;
break;
case HPF:
b0 = (1.0 + cs) / 2.0 ;
b1 = -(1.0 + cs) ;
b2 = (1.0 + cs) / 2.0 ;
a0 = 1.0 + a1pha ;
a1 = -2.0 * cs ;
a2 = 1.0 - a1pha ;
break;
case APF:
b0=1.0-a1pha;
b1=-2.0*cs;
b2=1.0+a1pha;
a0=1.0+a1pha;
a1=-2.0*cs;
a2=1.0-a1pha;
break;
case BPZPGF:
b0 = a1pha ;
b1 = 0.0 ;
b2 = -a1pha ;
a0 = 1.0 + a1pha ;
a1 = -2.0 * cs ;
a2 = 1.0 - a1pha ;
break;
case BPCSGF:
b0=sn/2.0;
b1=0.0;
b2=-sn/2;
a0=1.0+a1pha;
a1=-2.0*cs;
a2=1.0-a1pha;
break;
case NOTCH:
b0 = 1;
b1 = -2 * cs;
b2 = 1;
a0 = 1 + a1pha;
a1 = -2 * cs;
a2 = 1 - a1pha;
break;
case PEQ:
b0 = 1 + a1pha * A ;
b1 = -2 * cs ;
b2 = 1 - a1pha * A ;
a0 = 1 + a1pha / A ;
a1 = -2 * cs ;
a2 = 1 - a1pha / A ;
break;
case BBOOST:
beta = sqrt((A * A + 1) / 1.0 - (pow((A - 1), 2)));
b0 = A * ((A + 1) - (A - 1) * cs + beta * sn);
b1 = 2 * A * ((A - 1) - (A + 1) * cs);
b2 = A * ((A + 1) - (A - 1) * cs - beta * sn);
a0 = ((A + 1) + (A - 1) * cs + beta * sn);
a1 = -2 * ((A - 1) + (A + 1) * cs);
a2 = (A + 1) + (A - 1) * cs - beta * sn;
break;
case LSH:
b0 = A * ((A + 1) - (A - 1) * cs + beta * sn);
b1 = 2 * A * ((A - 1) - (A + 1) * cs);
b2 = A * ((A + 1) - (A - 1) * cs - beta * sn);
a0 = (A + 1) + (A - 1) * cs + beta * sn;
a1 = -2 * ((A - 1) + (A + 1) * cs);
a2 = (A + 1) + (A - 1) * cs - beta * sn;
break;
case HSH:
b0 = A * ((A + 1) + (A - 1) * cs + beta * sn);
b1 = -2 * A * ((A - 1) + (A + 1) * cs);
b2 = A * ((A + 1) + (A - 1) * cs - beta * sn);
a0 = (A + 1) - (A - 1) * cs + beta * sn;
a1 = 2 * ((A - 1) - (A + 1) * cs);
a2 = (A + 1) - (A - 1) * cs - beta * sn;
break;
default:
break;
}
}
float IIRFilter::Process(float samp)
{
float out, in = 0;
in = samp;
out = (b0 * in + b1 * xn1 + b2 * xn2 - a1 * yn1 - a2 * yn2) / a0;
xn2 = xn1;
xn1 = in;
yn2 = yn1;
yn1 = out;
return out;
}
#ifndef IIRFILTERS_H
#define IIRFILTERS_H
/* filter types */
enum {
LPF, /* low pass filter */
HPF, /* High pass filter */
BPCSGF,/* band pass filter 1 */
BPZPGF,/* band pass filter 2 */
APF, /* Allpass filter*/
NOTCH, /* Notch Filter */
PEQ, /* Peaking band EQ filter */
BBOOST, /* Bassboost filter */
LSH, /* Low shelf filter */
HSH /* High shelf filter */
};
class IIRFilter
{
private:
float pf_freq, pf_qfact, pf_gain;
int type, pf_q_is_bandwidth;
float xn1,xn2,yn1,yn2;
float omega, cs, a1pha, beta, b0, b1, b2, a0, a1,a2, A, sn;
public:
IIRFilter();
~IIRFilter();
float Process(float samp);
void setFrequency(float val);
void setQuality(float val);
void setGain(float val);
void init(int samplerate,int filter_type);
};
#endif //IIRFILTERS_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment