Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/Limiter.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 "Limiter.h"
00020 #include "../common_source.h"
00021 
00022 using std::ostringstream;
00023 using namespace Marsyas;
00024 
00025 Limiter::Limiter(mrs_string name):MarSystem("Limiter",name)
00026 {
00027   //type_ = "Limiter";
00028   //name_ = name;
00029 
00030   xdprev_ = 0.0;
00031   alpha_ = 0.0;
00032 
00033   addControls();
00034 }
00035 
00036 
00037 Limiter::~Limiter()
00038 {
00039 }
00040 
00041 
00042 MarSystem*
00043 Limiter::clone() const
00044 {
00045   return new Limiter(*this);
00046 }
00047 
00048 void
00049 Limiter::addControls()
00050 {
00051   addctrl("mrs_real/thresh", 1.0);
00052   addctrl("mrs_real/at", 0.0001);
00053   addctrl("mrs_real/rt", 0.130);
00054   addctrl("mrs_real/slope", 1.0);
00055 }
00056 
00057 
00058 void
00059 Limiter::myUpdate(MarControlPtr sender)
00060 {
00061   MRSDIAG("Limiter.cpp - Limiter:myUpdate");
00062 
00063   // setctrl("mrs_natural/onSamples", getctrl("mrs_natural/inSamples"));
00064   // setctrl("mrs_natural/onObservations", getctrl("mrs_natural/inObservations"));
00065   // setctrl("mrs_real/osrate", getctrl("mrs_real/israte"));
00066   // setctrl("mrs_string/onObsNames", getctrl("mrs_string/inObsNames"));
00067   MarSystem::myUpdate(sender); //default myUpdate as defined at parent MarSystem class...
00068 
00069   //defaultUpdate(); [!]
00070   inSamples_ = getctrl("mrs_natural/inSamples")->to<mrs_natural>();
00071 
00072   xd_.create(inSamples_);
00073   gains_.create(inSamples_);
00074 }
00075 
00076 
00077 void
00078 Limiter::myProcess(realvec& in, realvec& out)
00079 {
00080   //checkFlow(in,out);
00081   mrs_natural o,t;
00082   mrs_real thresh = getctrl("mrs_real/thresh")->to<mrs_real>();
00083   mrs_real at = getctrl("mrs_real/at")->to<mrs_real>();
00084   mrs_real rt = getctrl("mrs_real/rt")->to<mrs_real>();
00085   mrs_real slope  = getctrl("mrs_real/slope")->to<mrs_real>();
00086 
00087   // calculate at and rt time
00088   at = 1 - exp(-2.2/(22050*at));
00089   rt = 1 - exp(-2.2/(22050*rt));
00090 
00091   for (o = 0; o < inObservations_; o++)
00092   {
00093     for (t = 0; t < inSamples_; t++)
00094     {
00095       // Calculates the current amplitude of signal and incorporates
00096       // the at and rt times into xd(o,t)
00097       alpha_ = fabs(in(o,t)) - xdprev_;
00098 
00099       if (alpha_<0)
00100       {
00101         alpha_ = 0;
00102       }
00103 
00104       xd_(o,t)=xdprev_*(1-rt)+at*alpha_;
00105       xdprev_ = xd_(o,t);
00106 
00107       // Limiter
00108       if (xd_(o,t) > thresh)
00109       {
00110         gains_(o,t) = pow((mrs_real)10.0,-slope*(log10(xd_(o,t))-log10(thresh)));
00111         //  linear calculation of gains_ = 10^(-Limiter Slope * (current value - Limiter Threshold))
00112       }
00113       else
00114       {
00115         gains_(o,t) = 1;
00116       }
00117 
00118       out(o,t) =  gains_(o,t) * in(o,t);
00119     }
00120   }
00121 }