Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/PvMultiResolution.cpp
Go to the documentation of this file.
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 }