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 "CompExp.h" 00020 #include "../common_source.h" 00021 #include <algorithm> 00022 #include <cmath> 00023 00024 using std::ostringstream; 00025 using namespace Marsyas; 00026 00027 CompExp::CompExp(mrs_string name): 00028 MarSystem("CompExp",name) 00029 { 00030 addControls(); 00031 update(); 00032 } 00033 00034 00035 CompExp::~CompExp() 00036 { 00037 } 00038 00039 00040 MarSystem* 00041 CompExp::clone() const 00042 { 00043 return new CompExp(*this); 00044 } 00045 00046 void 00047 CompExp::addControls() 00048 { 00049 addctrl("mrs_real/thresh", 1.0); 00050 addctrl("mrs_real/slope", 1.0); 00051 addctrl("mrs_real/at", 0.0001); 00052 addctrl("mrs_real/rt", 0.130); 00053 setControlState("mrs_real/thresh", true); 00054 setControlState("mrs_real/slope", true); 00055 setControlState("mrs_real/at", true); 00056 setControlState("mrs_real/rt", true); 00057 } 00058 00059 void 00060 CompExp::myUpdate(MarControlPtr sender) 00061 { 00062 (void) sender; //suppress warning of unused parameter(s) 00063 MRSDIAG("CompExp.cpp - CompExp:myUpdate"); 00064 00065 mrs_natural inObservations = getctrl("mrs_natural/inObservations")->to<mrs_natural>(); 00066 mrs_natural inSamples = getctrl("mrs_natural/inSamples")->to<mrs_natural>(); 00067 00068 setctrl("mrs_natural/onSamples", inSamples); 00069 setctrl("mrs_natural/onObservations", inObservations); 00070 setctrl("mrs_real/osrate", getctrl("mrs_real/israte")); 00071 00072 //defaultUpdate(); [!] 00073 00074 mrs_real thresh = getControl("mrs_real/thresh")->to<mrs_real>(); 00075 m_thresh = std::abs(thresh); 00076 m_thresh_log10 = std::log10(m_thresh); 00077 00078 m_slope = getControl("mrs_real/slope")->to<mrs_real>(); 00079 if (thresh < 0.0) 00080 m_slope = 1.0 / m_slope; 00081 00082 mrs_real attack = std::max( getControl("mrs_real/at")->to<mrs_real>(), (mrs_real) 0.0 ); 00083 00084 mrs_real release = std::max( getControl("mrs_real/rt")->to<mrs_real>(), (mrs_real) 0.0 ); 00085 00086 // calculate attack and release coefficients from times 00087 m_k_attack = attack > 0.0 ? 1 - exp(-2.2/(osrate_*attack)) : 1.0; 00088 00089 m_k_release = release > 0.0 ? 1 - exp(-2.2/(osrate_*release)) : 1.0; 00090 00091 if (tinObservations_ != inObservations_) 00092 m_xd.create(inObservations); 00093 } 00094 00095 00096 void 00097 CompExp::myProcess(realvec& in, realvec& out) 00098 { 00099 //checkFlow(in,out); 00100 00101 for (mrs_natural o = 0; o < inObservations_; o++) 00102 { 00103 mrs_real xd_prev = m_xd(o); 00104 00105 for (mrs_natural t = 0; t < inSamples_; t++) 00106 { 00107 mrs_real x = in(o,t); 00108 mrs_real x_abs = std::abs(x); 00109 00110 // Calculates the current amplitude of signal and incorporates 00111 // the at and rt times into xd 00112 mrs_real alpha = std::max( x_abs - xd_prev, (mrs_real) 0 ); 00113 mrs_real xd = xd_prev * (1-m_k_release) + alpha * m_k_attack; 00114 xd_prev = xd; 00115 00116 mrs_real gain; 00117 00118 if (xd > m_thresh) 00119 { 00120 gain = pow((mrs_real)10.0, m_slope * (log10(xd) - m_thresh_log10)) * m_thresh / xd; 00121 } 00122 else 00123 { 00124 gain = 1.0; 00125 } 00126 00127 out(o,t) = gain * x; 00128 } 00129 00130 m_xd(o) = xd_prev; 00131 } 00132 } 00133 00134 00135 00136 00137 00138 00139 00140