Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/Biquad.cpp
Go to the documentation of this file.
00001 /*
00002  ** Copyright (C) 1998-2010 George Tzanetakis <gtzan@cs.uvic.ca>
00003  **
00004  ** This program is free software; you can redistribute it and/or modify
00005  ** it under the terms of the GNU General Public License as published by
00006  ** the Free Software Foundation; either version 2 of the License, or
00007  ** (at your option) any later version.
00008  **
00009  ** This program is distributed in the hope that it will be useful,
00010  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  ** GNU General Public License for more details.
00013  **
00014  ** You should have received a copy of the GNU General Public License
00015  ** along with this program; if not, write to the Free Software
00016  ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018 
00019 #include "../common_source.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;  //suppress warning of unused parameter(s)
00073   /*
00074       Formula utilized is from "Audio-EQ-Cookbook" by Robert Bristow-Johnson
00075       http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
00076       Last retrieved March 20, 2007.
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_); // Arian: was positive
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_); // Arian: was positive
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 }