Marsyas
0.6.0-alpha
|
00001 /* 00002 ** Copyright (C) 1998-2006 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 "PvFold.h" 00020 00021 using std::ostringstream; 00022 using namespace Marsyas; 00023 00024 PvFold::PvFold(mrs_string name):MarSystem("PvFold",name) 00025 { 00026 //type_ = "PvFold"; 00027 //name_ = name; 00028 00029 N_ = 0; 00030 Nw_ = 0; 00031 PNw_ = 0; 00032 PN_ = 0; 00033 00034 addControls(); 00035 } 00036 00037 PvFold::PvFold(const PvFold& a):MarSystem(a) 00038 { 00039 N_ = 0; 00040 Nw_ = 0; 00041 PNw_ = 0; 00042 PN_ = 0; 00043 ctrl_rmsIn_ = getctrl("mrs_real/rmsIn"); 00044 } 00045 00046 00047 00048 PvFold::~PvFold() 00049 { 00050 } 00051 00052 MarSystem* 00053 PvFold::clone() const 00054 { 00055 return new PvFold(*this); 00056 } 00057 00058 00059 void 00060 PvFold::addControls() 00061 { 00062 addctrl("mrs_natural/FFTSize", MRS_DEFAULT_SLICE_NSAMPLES); 00063 setctrlState("mrs_natural/FFTSize", true); 00064 addctrl("mrs_real/rmsIn", 0.0, ctrl_rmsIn_); 00065 n_ = 0; 00066 } 00067 00068 00069 00070 void 00071 PvFold::myUpdate(MarControlPtr sender) 00072 { 00073 (void) sender; //suppress warning of unused parameter(s) 00074 mrs_natural t; 00075 setctrl("mrs_natural/onSamples", getctrl("mrs_natural/FFTSize")); 00076 setctrl("mrs_natural/onObservations", (mrs_natural)1); 00077 setctrl("mrs_real/osrate", getctrl("mrs_real/israte")); 00078 00079 N_ = getctrl("mrs_natural/onSamples")->to<mrs_natural>(); 00080 00081 Nw_ = getctrl("mrs_natural/inSamples")->to<mrs_natural>(); 00082 00083 // create analysis window if necessary 00084 if ((Nw_ != PNw_)||(N_ != PN_)) 00085 { 00086 n_ = -Nw_; 00087 awin_.stretch(Nw_); 00088 00089 00090 00091 for (t=0; t < Nw_; t++) 00092 { 00093 awin_(t) = (mrs_real)(0.5 * (1 - cos(TWOPI * t/(Nw_-1)))); 00094 } 00095 /* when Nw_ > N also apply interpolating (sinc) windows 00096 * to ensure that window are 0 at increments of N (the 00097 * FFT length) aways from the center of the analysis 00098 * window 00099 */ 00100 /* if (Nw_ > N_) 00101 { 00102 00103 mrs_real x; 00104 x = (mrs_real)(-(Nw_ -1) / 2.0); 00105 for (t=0; t < Nw_; t++, x += 1.0) 00106 { 00107 if (x != 0.0) 00108 awin_(t) *= N_ * sin (PI * x/N_) / (PI *x); 00109 } 00110 } 00111 */ 00112 /* normalize window for unit gain */ 00113 00114 mrs_real sum = 0.0; 00115 for (t =0; t < Nw_; t++) 00116 { 00117 sum += awin_(t); 00118 } 00119 00120 mrs_real afac = (mrs_real)(2.0/ sum); 00121 00122 awin_ *= afac; 00123 } 00124 00125 00126 00127 00128 00129 00130 PNw_ = Nw_; 00131 PN_ = N_; 00132 00133 } 00134 00135 void 00136 PvFold::myProcess(realvec& in, realvec& out) 00137 { 00138 00139 mrs_natural t; 00140 00141 for (t=0; t < Nw_; t++) 00142 { 00143 out(0,t) = in(0,t)*awin_(t); 00144 // rmsIn += in(0,t) * in(0,t); 00145 } 00146 // rmsIn /= Nw_; 00147 // rmsIn = sqrt(rmsIn); 00148 // ctrl_rmsIn_->setValue(rmsIn ); 00149 00150 00151 // circular shift 00152 int half_Nw_ = Nw_/2; 00153 mrs_real tmp; 00154 for (t=0; t < half_Nw_; t++) 00155 { 00156 tmp = out(0,t); 00157 out(0,t) = out(0, t+half_Nw_); 00158 out(0,t+half_Nw_) = tmp; 00159 } 00160 00161 00162 00163 } 00164 00165 00166 00167 00168 00169 00170 00171 00172 00173 00174