Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/AimHCL2.cpp
Go to the documentation of this file.
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 #include "AimHCL2.h"
00020 #include "../common_source.h"
00021 
00022 using std::ostringstream;
00023 using namespace Marsyas;
00024 
00025 AimHCL2::AimHCL2(mrs_string name):MarSystem("AimHCL2",name)
00026 {
00027   is_initialized = false;
00028   initialized_lowpass_cutoff = 0;
00029 
00030   is_reset = false;
00031   reseted_inobservations = 0;
00032   reseted_lowpass_order = 0;
00033 
00034   addControls();
00035 }
00036 
00037 
00038 AimHCL2::~AimHCL2()
00039 {
00040 }
00041 
00042 
00043 MarSystem*
00044 AimHCL2::clone() const
00045 {
00046   return new AimHCL2(*this);
00047 }
00048 
00049 void
00050 AimHCL2::addControls()
00051 {
00052   addControl("mrs_bool/do_lowpass", true , ctrl_do_lowpass_);
00053   addControl("mrs_bool/do_log", false , ctrl_do_log_);
00054   addControl("mrs_real/lowpass_cutoff", 1200.0 , ctrl_lowpass_cutoff_);
00055   addControl("mrs_natural/lowpass_order", 2 , ctrl_lowpass_order_);
00056 }
00057 
00058 void
00059 AimHCL2::myUpdate(MarControlPtr sender)
00060 {
00061   (void) sender;  //suppress warning of unused parameter(s)
00062   MRSDIAG("AimHCL2.cpp - AimHCL2:myUpdate");
00063   ctrl_onObservations_->setValue(ctrl_inObservations_->to<mrs_natural>(), NOUPDATE);
00064   ctrl_onSamples_->setValue(ctrl_inSamples_->to<mrs_natural>(), NOUPDATE);
00065   ctrl_osrate_->setValue(ctrl_israte_->to<mrs_real>());
00066   ctrl_onObsNames_->setValue("AimHCL2_" + ctrl_inObsNames_->to<mrs_string>() , NOUPDATE);
00067 
00068   //
00069   // Does the MarSystem need initialization?
00070   //
00071   if (initialized_lowpass_cutoff != ctrl_lowpass_cutoff_->to<mrs_real>()) {
00072     is_initialized = false;
00073   }
00074 
00075   if (!is_initialized) {
00076     InitializeInternal();
00077     is_initialized = true;
00078     initialized_lowpass_cutoff = ctrl_lowpass_cutoff_->to<mrs_real>();
00079   }
00080 
00081   //
00082   // Does the MarSystem need a reset?
00083   //
00084   if (reseted_inobservations != ctrl_inObservations_->to<mrs_natural>() ||
00085       reseted_lowpass_order != ctrl_lowpass_order_->to<mrs_natural>()) {
00086     is_reset = false;
00087   }
00088 
00089   if (!is_reset) {
00090     ResetInternal();
00091     is_reset = true;
00092     reseted_inobservations = ctrl_inObservations_->to<mrs_natural>();
00093     reseted_lowpass_order = ctrl_lowpass_order_->to<mrs_natural>();
00094   }
00095 
00096 }
00097 
00098 
00099 bool
00100 AimHCL2::InitializeInternal() {
00101   time_constant_ = 1.0 / (2.0 * PI * ctrl_lowpass_cutoff_->to<mrs_real>());
00102   return true;
00103 }
00104 
00105 void
00106 AimHCL2::ResetInternal() {
00107   xn_ = 0.0;
00108   yn_ = 0.0;
00109   yns_.clear();
00110   yns_.resize(ctrl_inObservations_->to<mrs_natural>());
00111   mrs_natural _lowpass_order = ctrl_lowpass_order_->to<mrs_natural>();
00112   for (int c = 0; c < ctrl_inObservations_->to<mrs_natural>(); ++c) {
00113     yns_[c].resize(_lowpass_order, 0.0);
00114   }
00115 }
00116 
00117 //
00118 // With do_log, the signal is first scaled up so that values <1.0 become
00119 // negligible. This just rescales the sample values to fill the range of a
00120 // 16-bit signed integer, then we lose the bottom bit of resolution. If the
00121 // signal was sampled at 16-bit resolution, there shouldn't be anything to
00122 // speak of there anyway. If it was sampled using a higher resolution, then
00123 // some data will be discarded.
00124 //
00125 void
00126 AimHCL2::myProcess(realvec& in, realvec& out)
00127 {
00128   mrs_natural o,t;
00129   mrs_real _israte = ctrl_israte_->to<mrs_real>();
00130   mrs_natural _inObservations = ctrl_inObservations_->to<mrs_natural>();
00131   mrs_natural _inSamples = ctrl_inSamples_->to<mrs_natural>();
00132   mrs_natural _onSamples = ctrl_onSamples_->to<mrs_natural>();
00133   mrs_natural _lowpass_order = ctrl_lowpass_order_->to<mrs_natural>();
00134   mrs_bool _do_lowpass = ctrl_do_lowpass_->to<mrs_bool>();
00135   mrs_bool _do_log = ctrl_do_log_->to<mrs_bool>();
00136 
00137   mrs_natural _num_channels = _inObservations;
00138   double b = exp(-1.0 / (_israte * time_constant_));
00139   double gain = 1.0 / (1.0 - b);
00140 
00141   for (o = 0; o < _num_channels; ++o) {
00142     for (t = 0; t < _inSamples; ++t) {
00143       // cout << "in(o,t)=" << in(o,t) << endl;
00144       if (in(o,t) < 0.0) {
00145         // cout << "s=zero" << endl;
00146         out(o, t) = 0.0;
00147       } else {
00148         double s = in(o,t);
00149         if (_do_log) {
00150           s *= pow(2.0, 15);
00151           if (s < 1.0) s = 1.0;
00152           s = 20.0 * log10(s);
00153         }
00154         // cout << "s=" << s << endl;
00155         out(o, t) = s;
00156       }
00157     }
00158     if (_do_lowpass) {
00159 
00160       for (int j = 0; j < _lowpass_order; j++) {
00161         for (int k = 0; k < _onSamples; ++k) {
00162           xn_ = out(o,k);
00163           yn_ = xn_ + b * yns_[o][j];
00164           yns_[o][j] = yn_;
00165           // cout << "gain=" << gain << endl;
00166           // cout << "yn_=" << yn_ << endl;
00167           out(o, k) = yn_ / gain;
00168         }
00169       }
00170     }
00171   }
00172 
00173 
00174 
00175 }