This is a digital resonant filter, similar to that used in analog synthesizers such as TB-303. Disclaimer: I am not an electrical engineer; I just looked up an algorithm in a textbook on computer music and then implemented it in C.
#include <math.h>

/* The equation for an IIR resonant filter:

S = sampling rate in Hz = OUT_FREQ
c = center frequency of filter
B = bandwidth of filter
x(n) = nth sample of signal

Calculate coefficients:
R = e^(-Pi*B/S) (approximation for pole radius)
G = 1 - R
b1 = 2*R*cos(2*Pi*c/S)
b2 = -R^2

y(n) = G*(x(n) - R*x(n - 2)) + b1*y(n - 1) + b2*y(n - 2)

Algorithm after page 269 of
Moore, F. Richard. _Elements_of_Computer_Music_.
Upper Saddle River: PTR Prentice Hall, 1990.


typedef struct REZFILTER
  float R, b1, b2;
  float xnm1, xnm2, ynm1, ynm2;

/* resonate() **************************
* Compute the next sample of a resonant filter.
float resonate(REZFILTER *r, float xn)
  float yn;

  yn = (1 - r->R)*(xn - r->R*r->xnm2) +
       r->b1*r->ynm1 + r->b2*r->ynm2;
  r->xnm2 = r->xnm1;
  r->xnm1 = xn;
  r->ynm2 = r->ynm1;

  r->ynm1 = yn;

  return yn;

/* set_resonate() **********************
 * Set a resonant filter's center frequency and bandwidth,
 * both in fractions of sample rate. For instance, 1000 Hz
 * in a 44100 Hz sample is represented as (1000./44100)
void set_resonate(REZFILTER *r, 
                  float center, float bandwidth)
  float R = exp(-M_PI * bandwidth);

  r->R = R;
  r->b1 = 2*R*cos(2 * M_PI * center);
  r->b2 = -R*R;

To use this filter, first initialize all state elements (xnm1, xnm2, ynm1, ynm2) to 0, as set_resonate() doesn't do this (so as to avoid pops in time-varying filters). Then call set_resonate() with your desired center frequency and bandwidth (as real fractions of the sampling rate).

set_resonate(&my_filter, 1000./OUT_FREQ, 40./OUT_FREQ);
Then call the resonate() function with each sample, in order:
yn += resonate(&my_filter, xn);

Log in or register to write something here or to contact authors.