Marsyas
0.6.0-alpha
|
00001 /* 00002 ** Copyright (C) 1998-2011 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 "PeakerAdaptive.h" 00020 00021 using std::ostringstream; 00022 using namespace Marsyas; 00023 00024 PeakerAdaptive::PeakerAdaptive(mrs_string name):MarSystem("PeakerAdaptive",name) 00025 { 00026 rms_ = 0.0; 00027 winCount_ = 1; 00028 peakHysterisis_ = 0; 00029 addControls(); 00030 } 00031 00032 PeakerAdaptive::~PeakerAdaptive() 00033 { 00034 } 00035 00036 MarSystem* 00037 PeakerAdaptive::clone() const 00038 { 00039 return new PeakerAdaptive(*this); 00040 } 00041 00042 void 00043 PeakerAdaptive::addControls() 00044 { 00045 addctrl("mrs_real/peakSpacing", 0.0); 00046 addctrl("mrs_real/peakStrength", 0.7); 00047 addctrl("mrs_natural/peakStart", (mrs_natural)0); 00048 addctrl("mrs_natural/peakEnd", (mrs_natural)0); 00049 //addctrl("mrs_real/peakGain", 1.0); 00050 addctrl("mrs_natural/peakStrengthReset", 4); 00051 addctrl("mrs_real/peakDecay", 0.9); 00052 addctrl("mrs_bool/peakFound", false); 00053 } 00054 00055 void 00056 PeakerAdaptive::myProcess(realvec& in, realvec& out) 00057 { 00058 mrs_natural t,o; 00059 mrs_real peakSpacing; 00060 mrs_real peakStrength; 00061 //mrs_real peakGain; 00062 00063 mrs_natural peakStart; 00064 mrs_natural peakEnd; 00065 mrs_natural peakStrengthReset; 00066 mrs_real peakDecay; 00067 00068 peakSpacing = getctrl("mrs_real/peakSpacing")->to<mrs_real>(); 00069 peakStrength = getctrl("mrs_real/peakStrength")->to<mrs_real>(); 00070 peakStart = getctrl("mrs_natural/peakStart")->to<mrs_natural>(); 00071 peakEnd = getctrl("mrs_natural/peakEnd")->to<mrs_natural>(); 00072 //peakGain = getctrl("mrs_real/peakGain")->to<mrs_real>(); 00073 peakStrengthReset = getctrl("mrs_natural/peakStrengthReset")->to<mrs_natural>(); 00074 peakDecay = getctrl("mrs_real/peakDecay")->to<mrs_real>(); 00075 00076 out.setval(0.0); 00077 00078 00079 00080 for (o = 0; o < inObservations_; o++) 00081 { 00082 peakSpacing = (mrs_real)(peakSpacing * inSamples_); 00083 mrs_real max; 00084 mrs_natural maxIndex = 0; 00085 00086 bool peakFound = false; 00087 00088 for (t=peakStart+1; t < peakEnd-1; t++) 00089 { 00090 if (fabs(in(o,t)) > rms_) 00091 rms_ = fabs(in(o,t)); 00092 } 00093 00094 for (t=peakStart+1; t < peakEnd-1; t++) 00095 { 00096 // peak has to be larger than neighbors 00097 if ((in(o,t -1) < in(o,t)) 00098 && (in(o,t+1) < in(o,t)) 00099 && (fabs(in(o,t)) > peakStrength * rms_) 00100 ) 00101 { 00102 max = in(o,t); 00103 maxIndex = t; 00104 00105 for (int j=0; j < (mrs_natural)peakSpacing; j++) 00106 { 00107 if (t+j < peakEnd-1) 00108 if (in(o,t+j) > max) 00109 { 00110 max = in(o,t+j); 00111 maxIndex = t+j; 00112 } 00113 } 00114 00115 t += (mrs_natural)peakSpacing; 00116 if ((peakHysterisis_ > peakStrengthReset) || 00117 (peakHysterisis_ == 0) 00118 ) 00119 { 00120 out(o,maxIndex) = fabs(in(o,maxIndex)); 00121 peakHysterisis_ = 1; 00122 } 00123 00124 rms_ = fabs(in(o,maxIndex)); 00125 peakFound = true; 00126 00127 00128 } 00129 } 00130 00131 if (!peakFound) 00132 { 00133 rms_ *= peakDecay; 00134 setctrl("mrs_bool/peakFound", false); 00135 } 00136 else 00137 setctrl("mrs_bool/peakFound", true); 00138 peakHysterisis_ ++; 00139 } 00140 }