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 "PvMultiResolution.h" 00020 #include "../common_source.h" 00021 00022 using std::ostringstream; 00023 using namespace Marsyas; 00024 00025 PvMultiResolution::PvMultiResolution(mrs_string name):MarSystem("PvMultiResolution", name) 00026 { 00027 flux_ = new Flux("flux"); 00028 r_ = 0.1; 00029 m_ = 0.75; 00030 00031 addControls(); 00032 } 00033 00034 PvMultiResolution::PvMultiResolution(const PvMultiResolution& a) : MarSystem(a) 00035 { 00036 ctrl_mode_ = getctrl("mrs_string/mode"); 00037 ctrl_transient_ = getctrl("mrs_bool/transient"); 00038 ctrl_shortmag_ = getctrl("mrs_realvec/shortmag"); 00039 ctrl_longmag_ = getctrl("mrs_realvec/longmag"); 00040 00041 r_ = 0.1; 00042 m_ = 0.75; 00043 flux_ = new Flux("flux"); 00044 } 00045 00046 00047 PvMultiResolution::~PvMultiResolution() 00048 { 00049 delete flux_; 00050 } 00051 00052 MarSystem* 00053 PvMultiResolution::clone() const 00054 { 00055 return new PvMultiResolution(*this); 00056 } 00057 00058 void 00059 PvMultiResolution::addControls() 00060 { 00061 00062 addctrl("mrs_string/mode", "long", ctrl_mode_); 00063 addctrl("mrs_bool/transient", false, ctrl_transient_); 00064 addctrl("mrs_realvec/shortmag", realvec(), ctrl_shortmag_); 00065 addctrl("mrs_realvec/longmag", realvec(), ctrl_longmag_); 00066 addctrl("mrs_real/flux", 0.0); 00067 } 00068 00069 void 00070 PvMultiResolution::myUpdate(MarControlPtr sender) 00071 { 00072 MRSDIAG("PvMultiResolution.cpp - PvMultiResolution:myUpdate"); 00073 00074 (void) sender; //suppress warning of unused parameter(s) 00075 ctrl_onSamples_->setValue(ctrl_inSamples_, NOUPDATE); 00076 ctrl_onObservations_->setValue(ctrl_inObservations_->to<mrs_natural>() / 2, NOUPDATE); 00077 ctrl_osrate_->setValue(ctrl_israte_, NOUPDATE); 00078 00079 median_buffer_.create(10); 00080 mbindex_ = 0; 00081 00082 00083 powerSpectrum_.create(onObservations_/2,1); 00084 whiteSpectrum_.create(onObservations_/2,1); 00085 00086 { 00087 MarControlAccessor acc(ctrl_shortmag_); 00088 mrs_realvec& shortmag = acc.to<mrs_realvec>(); 00089 shortmag.create(onObservations_/2); 00090 } 00091 00092 { 00093 MarControlAccessor acc(ctrl_longmag_); 00094 mrs_realvec& longmag = acc.to<mrs_realvec>(); 00095 longmag.create(onObservations_/2); 00096 } 00097 00098 00099 flux_->updControl("mrs_natural/inSamples", 1); 00100 flux_->updControl("mrs_natural/inObservations", onObservations_/2); 00101 flux_->updControl("mrs_real/israte", 44100); 00102 flux_->updControl("mrs_string/mode", "DixonDAFX06"); 00103 fluxval_.create(1,1); 00104 00105 } 00106 00107 void 00108 PvMultiResolution::myProcess(realvec& in, realvec& out) 00109 { 00110 mrs_natural t,o; 00111 const mrs_string& mode = ctrl_mode_->to<mrs_string>(); 00112 00113 00114 MarControlAccessor acc1(ctrl_shortmag_); 00115 mrs_realvec& shortmag = acc1.to<mrs_realvec>(); 00116 00117 MarControlAccessor acc2(ctrl_longmag_); 00118 mrs_realvec& longmag = acc2.to<mrs_realvec>(); 00119 00120 00121 00122 00123 if (mode == "short") 00124 { 00125 // short window 00126 for (o=0; o < inObservations_/2; o++) 00127 for (t = 0; t < inSamples_; t++) 00128 { 00129 out(o,t) = in(o, t); 00130 } 00131 for (o=0; o < onObservations_/2; o++) 00132 for (t = 0; t < inSamples_; t++) 00133 { 00134 00135 out(2*o, t) = 0.75 * out(2*o,t); 00136 } 00137 00138 00139 } 00140 else if (mode == "long") 00141 { 00142 00143 // long window 00144 for (o=inObservations_/2; o < inObservations_; o++) 00145 for (t = 0; t < inSamples_; t++) 00146 { 00147 out(o-inObservations_/2,t) = in(o,t); 00148 } 00149 00150 for (o=0; o < onObservations_/2; o++) 00151 for (t = 0; t < inSamples_; t++) 00152 { 00153 out(2*o, t) = out(2*o,t); 00154 } 00155 } 00156 else if (mode == "shortlong_mixture") 00157 { 00158 00159 00160 for (o=0; o < inObservations_/2; o++) 00161 for (t = 0; t < inSamples_; t++) 00162 { 00163 out(o,t) = in(o, t); 00164 } 00165 00166 /* use long window for frequencies lower than approx. 2000 Hz 00167 and short window for higher frequencies */ 00168 for (o=inObservations_/2; o < inObservations_/2 + 200; o++) 00169 for (t = 0; t < inSamples_; t++) 00170 { 00171 out(o-inObservations_/2,t) = in(o,t); 00172 } 00173 00174 for (o=0; o < 200; o++) 00175 for (t = 0; t < inSamples_; t++) 00176 { 00177 out(2*o, t) = 2 * out(2*o,t); 00178 } 00179 } 00180 00181 else if (mode == "transient_switch") 00182 { 00183 00184 // short window 00185 for (o=0; o < inObservations_/2; o++) 00186 for (t = 0; t < inSamples_; t++) 00187 { 00188 out(o,t) = in(o, t); 00189 } 00190 00191 00192 /* calculate power and use median for dynamic thresholding */ 00193 for (o=0; o < onObservations_/2; o++) 00194 for (t = 0; t < inSamples_; t++) 00195 { 00196 powerSpectrum_(o,0) = out(2*o,t) * out(2*o,t); 00197 } 00198 00199 00200 // adaptive pre-whitening 00201 for (o=0; o < onObservations_/2; o++) 00202 { 00203 00204 if (powerSpectrum_(o,0) < r_) 00205 whiteSpectrum_(o,0) = r_; 00206 else 00207 { 00208 if (m_ * whiteSpectrum_(o,0) > powerSpectrum_(o,0)) 00209 whiteSpectrum_(o,0) = m_ * whiteSpectrum_(o,0); 00210 else 00211 whiteSpectrum_(o,0) = powerSpectrum_(o,0); 00212 } 00213 powerSpectrum_(o,0) = powerSpectrum_(o,0) / whiteSpectrum_(o,0); 00214 } 00215 00216 00217 00218 flux_->process(powerSpectrum_, fluxval_); 00219 00220 median_buffer_(mbindex_) = fluxval_(0,0); 00221 mbindex_++; 00222 if (mbindex_ == 10) 00223 { 00224 mbindex_ = 0; 00225 } 00226 00227 00228 updControl("mrs_real/flux", fluxval_(0,0) - median_buffer_.median()); 00229 00230 mrs_real longSum = 0.0; 00231 mrs_real shortSum = 0.0; 00232 00233 mrs_real ratio1; 00234 //mrs_real ratio2; 00235 00236 00237 00238 for (o=0; o < onObservations_/2; o++) 00239 for (t = 0; t < inSamples_; t++) 00240 { 00241 shortmag(o) = in(2*o,t); 00242 longmag(o) = in(2*o + inObservations_/2, t); 00243 shortSum += shortmag(o); 00244 longSum += longmag(o); 00245 } 00246 00247 00248 ratio1 = longSum / shortSum; 00249 //ratio2 = shortSum / longSum; 00250 00251 00252 for (o=0; o < onObservations_/2; o++) 00253 for (t = 0; t < inSamples_; t++) 00254 { 00255 shortmag(o) = ratio1 * shortmag(o); 00256 } 00257 00258 00259 00260 00261 00262 00263 if (fluxval_(0,0) - median_buffer_.median() <= 0.0000010) // steady state use long window 00264 { 00265 00266 // use long 00267 for (o=inObservations_/2; o < inObservations_; o++) 00268 for (t = 0; t < inSamples_; t++) 00269 { 00270 out(o-inObservations_/2,t) = in(o,t); 00271 } 00272 00273 for (o=0; o < onObservations_/2; o++) 00274 for (t = 0; t < inSamples_; t++) 00275 { 00276 out(2*o, t) = out(2*o,t); 00277 } 00278 00279 ctrl_transient_->setValue(false, NOUPDATE); 00280 } 00281 else // transient 00282 { 00283 // use short 00284 for (o=0; o < inObservations_/2; o++) 00285 for (t = 0; t < inSamples_; t++) 00286 { 00287 out(o,t) = in(o, t); 00288 } 00289 00290 for (o=0; o < onObservations_/2; o++) 00291 for (t = 0; t < inSamples_; t++) 00292 { 00293 out(2*o, t) = ratio1 * out(2*o,t); 00294 } 00295 00296 00297 00298 ctrl_transient_->setValue(true, NOUPDATE); 00299 // cout<< fluxval_(0,0)-median_buffer_.median() << endl; 00300 } 00301 // cout << "RATIO = " << ratio << endl; 00302 } 00303 00304 00305 00306 00307 00308 00309 }