Advertisement
zmatt

em100 iir filters.c

May 5th, 2022 (edited)
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.72 KB | None | 0 0
  1. // variable numbering and array indexing is in reverse chronological order, i.e.
  2. // 0 is the current sample, 1 is the previous sample, etc
  3. //
  4. //  x = filter input samples
  5. //  y = filter output samples
  6.  
  7.  
  8. //================== generic biquad filter =====================================================
  9.  
  10. struct BiquadCoeffs {
  11.     float b2, b1, b0;
  12.     float a2, a1;
  13. };
  14.  
  15. float filter_biquad( struct BiquadCoeffs const *coeffs,
  16.         float x2, float x1, float x0, float y2, float y1 )
  17. {
  18.     float y0 = coeffs->b2 * x2
  19.              + coeffs->b1 * x1
  20.              + coeffs->b0 * x0
  21.  
  22.              - coeffs->a2 * y2
  23.              - coeffs->a1 * y1;
  24.  
  25.     return y0;
  26. }
  27.  
  28.  
  29. //================== biquad lowpass filter =====================================================
  30. //
  31. // same as above, but optimized for lowpass filters, for which
  32. //   b2 = b0
  33. //   b1 = b0 * 2
  34.  
  35. struct LPBiquadCoeffs {
  36.     float b0;
  37.     float a2, a1;
  38. };
  39.  
  40. void filter_lpbiquad( struct BiquadCoeffs const *coeffs,
  41.         float x2, float x1, float x0, float y2, float y1 )
  42. {
  43.     float y0 = coeffs->b0 * (     x2
  44.                             + 2 * x1
  45.                             +     x0 )
  46.  
  47.              - coeffs->a2 *       y2
  48.              - coeffs->a1 *       y1;
  49.  
  50.     return y0;
  51. }
  52.  
  53.  
  54. // resample to half the sample rate, using lowpass biquad filter.
  55. // returns one output sample per two input samples
  56. //
  57. float decimate_biquad( struct LPBiquadCoeffs const *coeffs, float state[2],
  58.         float const in[2], float const in_prev[2] )
  59. {
  60.     state[1] = coeffs->b0 * (     in_prev[1]
  61.                             + 2 * in_prev[0]
  62.                             +     in[1] )
  63.  
  64.              - coeffs->a2 *       state[1]
  65.              - coeffs->a1 *       state[0];
  66.  
  67.  
  68.     state[0] = coeffs->b0 * (     in_prev[0]
  69.                             + 2 * in[1]
  70.                             +     in[0] )
  71.  
  72.              - coeffs->a2 *       state[0]
  73.              - coeffs->a1 *       state[1];
  74.  
  75.     return state[0];
  76. }
  77.  
  78.  
  79. // EM100-G IIR filters:
  80. // (2nd-order Butterworth filters with various cutoff frequencies, 1200 Hz sample rate)
  81. static struct LPBiquadCoeffs const
  82.     em100_iir_1 = { .b0 = 2.11929601e-3, .a2 = 0.910120873, .a1 = -1.90164369 },  // 18 Hz
  83.     em100_iir_2 = { .b0 = 4.29590264e-4, .a2 = 0.958983150, .a1 = -1.95726479 },  // 8 Hz
  84.     em100_iir_3 = { .b0 = 1.08521907e-4, .a2 = 0.979274600, .a1 = -1.97884051 },  // 4 Hz
  85.     em100_iir_4 = { .b0 = 6.12030910e-5, .a2 = 0.984415081, .a1 = -1.98417027 },  // 3 Hz
  86.     em100_iir_5 = { .b0 = 2.72725213e-5, .a2 = 0.989582759, .a1 = -1.98947367 },  // 2 Hz
  87.     em100_iir_6 = { .b0 = 6.83597982e-6, .a2 = 0.994777708, .a1 = -1.99475036 },  // 1 Hz
  88.     em100_iir_7 = { .b0 = 1.71123201e-6, .a2 = 0.997385432, .a1 = -1.99737859 },  // 0.5 Hz
  89.     em100_iir_8 = { .b0 = 4.28088003e-7, .a2 = 0.998691860, .a1 = -1.99869015 };  // 0.25 Hz
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement