00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "Peaker.h"
00020
00021
00022 using std::ostringstream;
00023 using std::min;
00024 using std::max;
00025 using std::cout;
00026 using std::endl;
00027
00028
00029 using namespace Marsyas;
00030
00031 Peaker::Peaker(mrs_string name):MarSystem("Peaker",name)
00032 {
00033 addControls();
00034 }
00035
00036 Peaker::~Peaker()
00037 {
00038 }
00039
00040 MarSystem*
00041 Peaker::clone() const
00042 {
00043 return new Peaker(*this);
00044 }
00045
00046
00047
00048 void
00049 Peaker::addControls()
00050 {
00051 addctrl("mrs_real/peakSpacing", 0.0);
00052 addctrl("mrs_real/peakStrength", 0.0);
00053 addctrl("mrs_real/peakStrengthRelMax", 0.0);
00054 addctrl("mrs_real/peakStrengthRelThresh", 0.0);
00055 addctrl("mrs_real/peakStrengthAbs", 0.0);
00056 addctrl("mrs_real/peakStrengthThreshLpParam", 0.95);
00057 addctrl("mrs_natural/peakStart", (mrs_natural)0);
00058 addctrl("mrs_natural/peakEnd", (mrs_natural)0);
00059 addctrl("mrs_natural/interpolation", (mrs_natural)0);
00060 addctrl("mrs_real/peakGain", 1.0);
00061 addctrl("mrs_bool/peakHarmonics", false);
00062 addctrl("mrs_bool/rmsNormalize", false);
00063 addctrl("mrs_natural/peakNeighbors", 2);
00064 }
00065
00066
00067 void
00068 Peaker::myUpdate(MarControlPtr sender)
00069 {
00070 (void) sender;
00071 MRSDIAG("Peaker.cpp - Peaker:myUpdate");
00072
00073 MarSystem::myUpdate (sender);
00074
00075 lpThresh_.stretch (getctrl ("mrs_natural/inSamples")->to<mrs_natural>());
00076 }
00077
00078 void
00079 Peaker::myProcess(realvec& in, realvec& out)
00080 {
00081 mrs_natural t,o;
00082
00083 const mrs_natural peakSpacing = (mrs_natural)(inSamples_ *getctrl("mrs_real/peakSpacing")->to<mrs_real>() + .5);
00084 mrs_real peakStrengthRelRms,
00085 peakStrengthRelMax,
00086 peakStrengthRelThresh,
00087 peakStrengthAbs;
00088 mrs_real peakGain;
00089 mrs_bool peakHarmonics;
00090 mrs_bool rmsNormalize;
00091
00092 mrs_natural peakStart;
00093 mrs_natural peakEnd;
00094 mrs_natural interpolationMode;
00095 mrs_natural peakNeighbors;
00096
00097
00098 peakStrengthRelRms = getctrl("mrs_real/peakStrength")->to<mrs_real>();
00099 peakStrengthRelMax = getctrl("mrs_real/peakStrengthRelMax")->to<mrs_real>();
00100 peakStrengthRelThresh = getctrl("mrs_real/peakStrengthRelThresh")->to<mrs_real>();
00101 lpCoeff_ = getctrl("mrs_real/peakStrengthThreshLpParam")->to<mrs_real>();
00102 peakStrengthAbs = getctrl("mrs_real/peakStrengthAbs")->to<mrs_real>();
00103 peakStart = getctrl("mrs_natural/peakStart")->to<mrs_natural>();
00104 peakEnd = getctrl("mrs_natural/peakEnd")->to<mrs_natural>();
00105 interpolationMode = getctrl("mrs_natural/interpolation")->to<mrs_natural>();
00106 peakGain = getctrl("mrs_real/peakGain")->to<mrs_real>();
00107 peakHarmonics = getctrl("mrs_bool/peakHarmonics")->to<mrs_bool>();
00108 rmsNormalize = getctrl("mrs_bool/rmsNormalize")->to<mrs_bool>();
00109 peakNeighbors = getctrl("mrs_natural/peakNeighbors")->to<mrs_natural>();
00110
00111
00112
00113 if (peakEnd == 0)
00114 peakEnd = inSamples_;
00115
00116
00117
00118 out.setval(0.0);
00119
00120
00121
00122
00123
00124
00125 for (o = 0; o < inObservations_; o++)
00126 {
00127 rms_ = 0.0;
00128 max_ = -1e37;
00129
00130 for (t=peakStart; t < peakEnd; t++)
00131 {
00132 rms_ += in(o,t) * in(o,t);
00133 if (max_ < in(o,t))
00134 max_ = in(o,t);
00135 }
00136 if (rms_ != 0.0)
00137 rms_ /= (peakEnd - peakStart);
00138 rms_ = sqrt(rms_);
00139
00140 mrs_real max;
00141 mrs_natural maxIndex;
00142
00143 bool peakFound = false;
00144
00145 if (peakStrengthRelThresh > .0)
00146 {
00147 in.getRow (o,lpThresh_);
00148 compLpThresh (lpThresh_, lpThresh_);
00149 }
00150
00151 for (t=peakStart; t < peakEnd; t++)
00152 {
00153 peakFound = true;
00154
00155
00156 for (int j = 1; j < peakNeighbors; j++)
00157 {
00158 mrs_natural index=t-j;
00159 if (index<0) index=0;
00160 if (in(o,index) >= in(o,t))
00161 {
00162 peakFound = false;
00163 break;
00164 }
00165 index=t+j;
00166 if (index>=inSamples_) index=inSamples_-1;
00167 if (in(o,index) >= in(o,t))
00168 {
00169 peakFound = false;
00170 break;
00171 }
00172 }
00173
00174 if (peakFound)
00175 {
00176 currThresh_ = lpThresh_(t);
00177 peakFound = doThresholding (in(o,t), peakStrengthRelRms, peakStrengthRelMax, peakStrengthRelThresh, peakStrengthAbs);
00178 }
00179
00180 if (peakFound)
00181 {
00182
00183 max = in(o,t);
00184 maxIndex = t;
00185
00186
00187 for (int j=0; j < peakSpacing; j++)
00188 {
00189 if (t+j < peakEnd-1)
00190 if (in(o,t+j) > max)
00191 {
00192 max = in(o,t+j);
00193 maxIndex = t+j;
00194 }
00195 }
00196
00197 t += peakSpacing;
00198
00199 if (rmsNormalize)
00200 {
00201 out(o,maxIndex) = in(o,maxIndex) / rms_;
00202 if(interpolationMode && maxIndex > 0 && maxIndex < inSamples_)
00203 {
00204 out(o,maxIndex-1) = in(o,maxIndex-1) /rms_;
00205 out(o,maxIndex+1) = in(o,maxIndex+1) / rms_;
00206 }
00207 }
00208 else
00209 {
00210 out(o,maxIndex) = in(o,maxIndex);
00211 if(interpolationMode && maxIndex > 0 && maxIndex < inSamples_)
00212 {
00213 out(o,maxIndex-1) = in(o,maxIndex-1);
00214 out(o,maxIndex+1) = in(o,maxIndex+1);
00215 }
00216 }
00217
00218
00219
00220
00221
00222
00223 if (peakHarmonics)
00224 {
00225 twice_ = 2 * maxIndex;
00226 half_ = (mrs_natural) (0.5 * maxIndex + 0.5);
00227 triple_ = 3 * maxIndex;
00228 third_ = (mrs_natural) (0.33 * maxIndex + 0.5);
00229
00230 if (twice_ < (peakEnd - peakStart))
00231 {
00232 peakFound = true;
00233
00234
00235 for (int j = 1; j < peakNeighbors; j++)
00236 {
00237 if (in(o,twice_-j) >= in(o,twice_))
00238 {
00239 peakFound = false;
00240 break;
00241 }
00242 if (in(o,twice_+j) >= in(o,twice_))
00243 {
00244 peakFound = false;
00245 break;
00246 }
00247 }
00248
00249
00250 if (peakFound)
00251 {
00252 out(o, maxIndex) += (in(o, twice_)/rms_);
00253 out(o, twice_) = in(o,twice_)/rms_ + 0.5 * out(o, maxIndex);
00254 }
00255
00256 }
00257
00258 if (half_ < (peakEnd - peakStart))
00259 {
00260 peakFound = true;
00261
00262
00263 for (int j = 1; j < peakNeighbors; j++)
00264 {
00265 if (in(o,half_-j) >= in(o,half_))
00266 {
00267 peakFound = false;
00268 break;
00269 }
00270 if (in(o,half_+j) >= in(o,half_))
00271 {
00272 peakFound = false;
00273 break;
00274 }
00275 }
00276
00277
00278 if (peakFound)
00279 {
00280 out(o, maxIndex) += (in(o, half_)/rms_);
00281 out(o, half_) = in(o,half_)/rms_ + 0.5 * out(o, maxIndex);
00282 }
00283
00284 }
00285
00286
00287 if (triple_ < (peakEnd - peakStart))
00288 {
00289 peakFound = true;
00290
00291
00292 for (int j = 1; j < peakNeighbors; j++)
00293 {
00294 if (in(o,triple_-j) >= in(o,triple_))
00295 {
00296 peakFound = false;
00297 break;
00298 }
00299 if (in(o,triple_+j) >= in(o,triple_))
00300 {
00301 peakFound = false;
00302 break;
00303 }
00304 }
00305
00306
00307 if (peakFound)
00308 {
00309 out(o, maxIndex) += (in(o, triple_)/rms_);
00310 out(o, triple_) = in(o,triple_)/rms_ + 0.5 * out(o, maxIndex);
00311 }
00312
00313 }
00314
00315 if (third_ < (peakEnd - peakStart))
00316 {
00317 peakFound = true;
00318
00319
00320
00321 for (int j = 1; j < peakNeighbors; j++)
00322 {
00323 if (in(o,third_-j) >= in(o,third_))
00324 {
00325 peakFound = false;
00326 break;
00327 }
00328 if (in(o,third_+j) >= in(o,triple_))
00329 {
00330 peakFound = false;
00331 break;
00332 }
00333 }
00334
00335 if (peakFound)
00336 {
00337 out(o, maxIndex) += (in(o, third_)/rms_);
00338 out(o, third_) = in(o,third_)/rms_ + 0.5 * out(o, maxIndex);
00339 }
00340
00341 }
00342 }
00343
00344 peakFound = true;
00345 }
00346
00347 }
00348 }
00349 }
00350
00351 mrs_bool Peaker::doThresholding (mrs_real input, mrs_real peakStrengthRelRms, mrs_real peakStrengthRelMax, mrs_real peakStrengthRelThresh, mrs_real peakStrengthAbs)
00352 {
00353 mrs_real thresh = max (max (max (peakStrengthAbs, peakStrengthRelRms * rms_), peakStrengthRelMax * max_), peakStrengthRelThresh * currThresh_);
00354
00355
00356 if (input <= thresh)
00357 return false;
00358 else
00359 return true;
00360 }
00361
00362 void Peaker::compLpThresh (const mrs_realvec input, mrs_realvec &output)
00363 {
00364 mrs_natural i,
00365 len = input.getCols ();
00366 mrs_real buf = input(0);
00367 for (i = 0; i < len; ++i)
00368 {
00369 buf = input(i) + lpCoeff_ * (buf - input(i));
00370 output(i) = buf;
00371 }
00372
00373 for (i = len-1; i >= 0; i--)
00374 {
00375 buf = output(i) + lpCoeff_ * (buf - output(i));
00376 output(i) = buf;
00377 }
00378 }