Marsyas
0.6.0-alpha
|
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 }