Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/ChromaFilter.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 
00020 #include "ChromaFilter.h"
00021 #include "Filter.h"
00022 #include <sstream>
00023 
00024 
00025 using std::ostringstream;
00026 using std::stringstream;
00027 using std::cout;
00028 using std::endl;
00029 
00030 using namespace Marsyas;
00031 
00032 ChromaFilter::ChromaFilter(mrs_string name):MarSystem("ChromaFilter", name),
00033   filterBank (0)
00034 {
00035   fs          = 0;
00036   octaves     = 0;
00037   freq        = 0;
00038   q           = 0;
00039   filterBank  = NULL;
00040 
00041   addControls();
00042 }
00043 
00044 
00045 ChromaFilter::~ChromaFilter()
00046 {
00047   if (filterBank) delete filterBank;
00048 }
00049 
00050 MarSystem*
00051 ChromaFilter::clone() const
00052 {
00053   return new ChromaFilter(*this);
00054 }
00055 
00056 
00057 void
00058 ChromaFilter::addControls()
00059 {
00060   addctrl("mrs_natural/octaves", 2);
00061   addctrl("mrs_real/freq", 440.0f);
00062   addctrl("mrs_real/q", 1.0f);
00063 
00064   setctrlState("mrs_natural/octaves", true);
00065   setctrlState("mrs_real/freq", true);
00066   setctrlState("mrs_real/q", true);
00067 }
00068 
00069 void
00070 ChromaFilter::myUpdate(MarControlPtr sender)
00071 {
00072   (void) sender;
00073 //  MRSDIAG("ChromaFilter.cpp - ChromaFilter:myUpdate");
00074 
00075   //FilterBank creation
00076   if (octaves != getctrl("mrs_natural/octaves")->to<mrs_natural>()) {
00077     octaves = getctrl("mrs_natural/octaves")->to<mrs_natural>();
00078     if (filterBank) delete filterBank;
00079     filterBank = new Fanout("filterBank");
00080     stringstream name;
00081     for(mrs_natural i = 0; i < 12*octaves+1; ++i) {
00082       name.str("");
00083       name << "filter_" << i;
00084       Filter* filter = new Filter(name.str());
00085       filterBank->addMarSystem(filter);
00086     }
00087     fcoefs.create(12*octaves+1, 6);
00088   }
00089 
00090   setctrl("mrs_natural/onSamples", getctrl("mrs_natural/inSamples")->to<mrs_natural>());
00091   setctrl("mrs_natural/onObservations", (12*octaves+1)*getctrl("mrs_natural/inObservations")->to<mrs_natural>());
00092   setctrl("mrs_real/osrate", getctrl("mrs_real/israte"));
00093 
00094 
00095   //Coefficients computation
00096   fs = getctrl("mrs_real/israte")->to<mrs_real>();
00097   freq = getctrl("mrs_real/freq")->to<mrs_real>();
00098   q = getctrl("mrs_real/q")->to<mrs_real>();
00099 
00100   for (mrs_natural i = 0; i < 12*octaves+1; ++i) {
00101 
00102     mrs_real fc, r;
00103 
00104     fc = freq*pow(2.0, ((i-6*octaves)*100.0)/1200.0);
00105     r  = (q-PI*fc/fs)/q;
00106 
00107     fcoefs(i,0) = 1.0;
00108     fcoefs(i,1) = -2.0*r*cos(2*PI*fc/fs);
00109     fcoefs(i,2) = pow(r, 2.0);
00110     fcoefs(i,3) = (1-pow(r, 2.0))/2.0;
00111     fcoefs(i,4) = 0.0;
00112     fcoefs(i,5) = -fcoefs(i,3);
00113   }
00114 
00115   //Controls update
00116   stringstream channel,filter,ctrl;
00117   realvec b(1,3),a(1,3);
00118 
00119   filterBank->setctrl("mrs_natural/inSamples", getctrl("mrs_natural/inSamples")->to<mrs_natural>());
00120   filterBank->setctrl("mrs_natural/inObservations", getctrl("mrs_natural/inObservations")->to<mrs_natural>());
00121   filterBank->setctrl("mrs_natural/onObservations", getctrl("mrs_natural/onObservations")->to<mrs_natural>());
00122   filterBank->setctrl("mrs_real/israte", getctrl("mrs_real/israte")->to<mrs_real>());
00123 
00124 
00125   for(mrs_natural i = 0; i < 12*octaves+1; ++i) {
00126 
00127     // Low Filter
00128     filter.str("");
00129     filter << channel.str() << "Filter/filter_" << i << "/";
00130     ctrl.str("");
00131     ctrl << filter.str() << "mrs_natural/inSamples";
00132     filterBank->setctrl(ctrl.str(), getctrl("mrs_natural/inSamples")->to<mrs_natural>());
00133     ctrl.str("");
00134     ctrl << filter.str() << "mrs_natural/inObservations";
00135     filterBank->setctrl(ctrl.str(), getctrl("mrs_natural/inObservations")->to<mrs_natural>());
00136     ctrl.str("");
00137     ctrl << filter.str() << "mrs_natural/onObservations";
00138     filterBank->setctrl(ctrl.str(), getctrl("mrs_natural/inObservations")->to<mrs_natural>());
00139     ctrl.str("");
00140     ctrl << filter.str() << "mrs_real/israte";
00141     filterBank->setctrl(ctrl.str(), getctrl("mrs_real/israte")->to<mrs_real>());
00142 
00143     a(0) = fcoefs(i,0);
00144     a(1) = fcoefs(i,1);
00145     a(2) = fcoefs(i,2);
00146     b(0) = fcoefs(i,3);
00147     b(1) = fcoefs(i,4);
00148     b(2) = fcoefs(i,5);
00149     ctrl.str("");
00150     ctrl << filter.str() << "mrs_realvec/ncoeffs";
00151     filterBank->setctrl(ctrl.str(), b);
00152     ctrl.str("");
00153     ctrl << filter.str() << "mrs_realvec/dcoeffs";
00154     filterBank->setctrl(ctrl.str(), a);
00155 
00156     //  a.dumpDataOnly();
00157     //    cout << " ";
00158     //    b.dumpDataOnly();
00159     //    cout << endl;
00160   }
00161   //update the whole filter bank
00162   filterBank->update();
00163 
00164 }
00165 
00166 void
00167 ChromaFilter::myProcess(realvec& in, realvec& out)
00168 {
00169   //checkFlow(in,out);
00170   //lmartins: if (mute_) return;
00171   if(getctrl("mrs_bool/mute")->to<mrs_bool>()) return;
00172 
00173   filterBank->process(in, out);
00174 }