00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "common.h"
00020 #include "Biquad.h"
00021
00022 using std::cout;
00023 using std::endl;
00024
00025 using std::ostringstream;
00026 using namespace Marsyas;
00027
00028 Biquad::Biquad(mrs_string name):MarSystem("Biquad",name)
00029 {
00030
00031 filter = new Filter("filter");
00032
00033 b.create(3);
00034 a.create(3);
00035
00036 addControls();
00037 }
00038
00039 Biquad::Biquad(const Biquad& orig): MarSystem(orig)
00040 {
00041 filter = new Filter("filter");
00042 b.create(3);
00043 a.create(3);
00044 }
00045
00046 Biquad::~Biquad()
00047 {
00048 delete filter;;
00049 }
00050
00051
00052 MarSystem* Biquad::clone() const
00053 {
00054 return new Biquad(*this);
00055 }
00056
00057 void Biquad::addControls()
00058 {
00059
00060 addctrl("mrs_string/type","lowpass");
00061 addctrl("mrs_real/resonance", 1.0);
00062 addctrl("mrs_real/frequency", 500.0);
00063
00064 setctrlState("mrs_string/type", true);
00065 setctrlState("mrs_real/resonance", true);
00066 setctrlState("mrs_real/frequency", true);
00067
00068 }
00069
00070 void Biquad::myUpdate(MarControlPtr sender)
00071 {
00072 (void) sender;
00073
00074
00075
00076
00077
00078
00079 mrs_string type = getctrl("mrs_string/type")->to<mrs_string>();
00080
00081 freq_ = getctrl("mrs_real/frequency")->to<mrs_real>();
00082 q_ = getctrl("mrs_real/resonance")->to<mrs_real>();
00083
00084 fs_ = getctrl("mrs_real/israte")->to<mrs_real>();
00085
00086 setctrl("mrs_real/osrate", fs_);
00087 setctrl("mrs_natural/onSamples", getctrl("mrs_natural/inSamples")->to<mrs_natural>());
00088
00089 w0_ = 2 * PI * freq_ / fs_;
00090
00091
00092
00093 if (type == "lowpass")
00094 {
00095 alpha_ = sin(w0_)/(2*q_);
00096
00097 b(0) = (1 - cos(w0_))/2;
00098 b(1) = 1 - cos(w0_);
00099 b(2) = (1 - cos(w0_))/2;
00100
00101 a(0) = 1 + alpha_;
00102 a(1) = -2 * cos(w0_);
00103 a(2) = 1 - alpha_;
00104
00105 filter->updControl("mrs_realvec/ncoeffs", b);
00106 filter->updControl("mrs_realvec/dcoeffs", a);
00107
00108 }
00109 else if (type == "bandpass")
00110 {
00111 alpha_ = sin(w0_)/(2*q_);
00112
00113 b(0) = sin(w0_)/2;
00114 b(1) = 0;
00115 b(2) = -sin(w0_)/2;
00116
00117 a(0) = 1 + alpha_;
00118 a(1) = -2 * cos(w0_);
00119 a(2) = 1 - alpha_;
00120
00121 filter->updControl("mrs_realvec/ncoeffs", b);
00122 filter->updControl("mrs_realvec/dcoeffs", a);
00123 }
00124 else if (type == "highpass")
00125 {
00126 b(0) = (1 + cos(w0_))/2;
00127 b(1) = -(1 + cos(w0_));
00128 b(2) = (1 + cos(w0_))/2;
00129 a(0) = 1 + alpha_;
00130 a(1) = -2*cos(w0_);
00131 a(2) = 1 - alpha_;
00132 filter->updControl("mrs_realvec/ncoeffs", b);
00133 filter->updControl("mrs_realvec/dcoeffs", a);
00134 }
00135 else if (type == "allpass")
00136 {
00137 alpha_ = sin(w0_)/(2*q_);
00138
00139 b(0) = 1 - alpha_;
00140 b(1) = -2 * cos(w0_);
00141 b(2) = 1 + alpha_;
00142
00143 a(0) = 1 + alpha_;
00144 a(1) = -2 * cos(w0_);
00145 a(2) = 1 - alpha_;
00146
00147
00148 filter->updControl("mrs_realvec/ncoeffs", b);
00149 filter->updControl("mrs_realvec/dcoeffs", a);
00150
00151 }
00152
00153
00154
00155
00156 else
00157 {
00158 MRSWARN("BIQUAD: wrong type specified");
00159
00160 }
00161 filter->setctrl("mrs_real/israte", fs_);
00162 filter->setctrl("mrs_real/osrate", fs_);
00163 filter->setctrl("mrs_natural/inObservations", getctrl("mrs_natural/inObservations")->to<mrs_natural>());
00164 filter->setctrl("mrs_natural/onObservations", getctrl("mrs_natural/onObservations")->to<mrs_natural>());
00165 filter->setctrl("mrs_natural/inSamples", getctrl("mrs_natural/inSamples")->to<mrs_natural>());
00166 filter->setctrl("mrs_natural/onSamples", getctrl("mrs_natural/onSamples")->to<mrs_natural>());
00167 }
00168
00169
00170 void Biquad::myProcess(realvec& in, realvec& out)
00171 {
00172 filter->process(in,out);
00173
00174 }