Jamoma API  0.6.0.a19
LowPass.cpp
1 // LowPass.h
2 /***************************************************/
3 /*! \class LowPass
4  \brief Low pass filter class
5 
6  A 2nd order low pass filter.
7 
8  Based on:
9  Biquad.h by Gary Scavone and Perry Cook, and
10  hml_shelf~.c by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2006
11 
12  by Tristan Matthews and Nils Peters, 2007-2008.
13  */
14 /***************************************************/
15 
16 #include "Filter.h"
17 #include "LowPass.h"
18 #include "Properties.h"
19 
20 extern bool globWarningFlag;
21 extern bool globReportFlag;
22 
23 LowPass::LowPass() : Filter(), cutOff_(10000)
24 {
25  init();
26 }
27 
28 void LowPass::cutOff(long newCutOff)
29 {
30  if (newCutOff < 500)
31  {
32  newCutOff = 500;
33  if (globWarningFlag)
34  post("Air filter cutoff capped at 500.");
35  }
36  else if (newCutOff > (long) Properties::SAMPLERATE * 0.44)
37  {
38  newCutOff = (long) Properties::SAMPLERATE * 0.44;
39  if (globWarningFlag)
40  post("Air filter cutoff capped at %f.", Properties::SAMPLERATE * 0.44);
41  }
42 
43  cutOff_ = newCutOff;
44  init();
45 }
46 
47 void LowPass::init()
48 {
49  double l, al, bl2, rcp;
50  double tempa0, tempa1, tempa2, tempb1, tempb2;
51 
52  l = cutOff_ * sr_;
53 
54  if (l < 1.0e-20)
55  {
56  l = 1.0e20;
57  if (globWarningFlag)
58  post("l capped at %f", l);
59  }
60  else if (l > 1.57079632)
61  {
62  l = 0.0;
63  if (globWarningFlag)
64  post("l capped at %f", l);
65  }
66  else
67  {
68  double si = sin(l);
69  double co = cos(l);
70  l = co / si;
71  }
72 
73  al = l * 1.41421; // damping
74  bl2 = (l * l) + 1.0;
75  rcp = 1.0 / (al + bl2);
76 
77  tempa0 = rcp;
78  tempa1 = 2.0 * rcp;
79  tempa2 = tempa0;
80  tempb1 = rcp * 2.0 * (bl2 - 2.0);
81  tempb2 = rcp * (al - bl2);
82 
83  //this->clear();
84 
85  /* stability check */
86 
87  double discriminant = tempb1 * tempb1 + 4.0 * tempb2;
88  if (tempb1 <= -1.9999996)
89  tempb1 = -1.9999996;
90  else if (tempb1 >= 1.9999996)
91  tempb1 = 1.9999996;
92 
93  if (tempb2 <= -0.9999998)
94  tempb2 = -0.9999998;
95  else if (tempb2 >= 0.9999998)
96  tempb2 = 0.9999998;
97 
98  if (discriminant >= 0.0)
99  {
100  if (0.9999998 - tempb1 - tempb2 < 0.0)
101  tempb2 = 0.9999998 - tempb1;
102  if (0.9999998 + tempb1 - tempb2 < 0.0)
103  tempb2 = 0.9999998 + tempb1;
104  }
105 
106  a0_ = tempa0;
107  a1_ = tempa1;
108  a2_ = tempa2;
109  b1_ = tempb1;
110  b2_ = tempb2;
111 }
112 
113 void LowPass::print() const
114 {
115  post("b1: %f, b2: %f, a0: %f, a1: %f, a2: %f, cutoff: %f", b1_, b2_, a0_, a1_, a2_, cutOff_);
116 }
117 
118 // vim:sw=4:et:cindent:
void cutOff(long newCutOff)
Set cutoff frequency.
Definition: LowPass.cpp:28
double a2_
Filter coefficient.
Definition: Filter.h:40
double sr_
Pi divided by the sample rate.
Definition: Filter.h:30
Filter class.
Definition: Filter.h:22
LowPass()
Class constructor.
Definition: LowPass.cpp:23
double b1_
Filter coefficient.
Definition: Filter.h:32
double b2_
Filter coefficient.
Definition: Filter.h:34
double a1_
Filter coefficient.
Definition: Filter.h:38
double a0_
Filter coefficient.
Definition: Filter.h:36
virtual void print() const
Print out info about this filter.
Definition: LowPass.cpp:113