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 "PeakerOnset.h" 00020 #include "../common_source.h" 00021 00022 using namespace std; 00023 using namespace Marsyas; 00024 00025 PeakerOnset::PeakerOnset(mrs_string name):MarSystem("PeakerOnset", name) 00026 { 00027 addControls(); 00028 00029 prevValue_ = 0.0; 00030 t_ = 0; 00031 } 00032 00033 PeakerOnset::PeakerOnset(const PeakerOnset& a) : MarSystem(a) 00034 { 00035 ctrl_lookAheadSamples_ = getctrl("mrs_natural/lookAheadSamples"); 00036 ctrl_threshold_ = getctrl("mrs_real/threshold"); 00037 ctrl_onsetDetected_ = getctrl("mrs_bool/onsetDetected"); 00038 ctrl_confidence_ = getctrl("mrs_real/confidence"); 00039 00040 prevValue_ = a.prevValue_; 00041 t_ = a.t_; 00042 } 00043 00044 PeakerOnset::~PeakerOnset() 00045 { 00046 } 00047 00048 MarSystem* 00049 PeakerOnset::clone() const 00050 { 00051 return new PeakerOnset(*this); 00052 } 00053 00054 void 00055 PeakerOnset::addControls() 00056 { 00057 addctrl("mrs_natural/lookAheadSamples", 0, ctrl_lookAheadSamples_); 00058 addctrl("mrs_real/threshold", 0.0, ctrl_threshold_); 00059 addctrl("mrs_bool/onsetDetected", false, ctrl_onsetDetected_); 00060 addctrl("mrs_real/confidence", 0.0, ctrl_confidence_); 00061 } 00062 00063 void 00064 PeakerOnset::myUpdate(MarControlPtr sender) 00065 { 00066 (void) sender; //suppress warning of unused parameter(s) 00067 MRSDIAG("PeakerOnset.cpp - PeakerOnset:myUpdate"); 00068 00069 ctrl_onSamples_->setValue(1, NOUPDATE); 00070 if(inObservations_ > 1) 00071 { 00072 MRSWARN("PeakerOnset::myUpdate() - inObservations is bigget than 1. This MarSystem only takes the first observation into consideration..."); 00073 } 00074 ctrl_onObservations_->setValue(1, NOUPDATE); 00075 ctrl_osrate_->setValue(ctrl_israte_, NOUPDATE); 00076 ctrl_onObsNames_->setValue("onset_confidence"); 00077 00078 if(inSamples_ < 1 + 2 * ctrl_lookAheadSamples_->to<mrs_natural>()) 00079 { 00080 cout << "inSamples_ = " << inSamples_ << endl; 00081 cout << "lookAhead = " << ctrl_lookAheadSamples_->to<mrs_natural>() << endl; 00082 MRSWARN("PeakerOnset::myUpdate() - inSamples is too small for specified onsetWinSize: onset detection not possible to be performed!"); 00083 ctrl_lookAheadSamples_->setValue(0, NOUPDATE); 00084 } 00085 } 00086 00087 void 00088 PeakerOnset::myProcess(realvec& in, realvec& out) 00089 { 00090 mrs_natural o,t; 00091 (void) o; 00092 ctrl_onsetDetected_->setValue(false); 00093 ctrl_confidence_->setValue(0.0); 00094 out.setval(0.0); 00095 00096 mrs_natural w = ctrl_lookAheadSamples_->to<mrs_natural>(); 00097 00098 if(w == 0) 00099 return; 00100 00101 //point to check for an onset 00102 mrs_natural checkPoint = inSamples_-1-w; 00103 mrs_real checkPointValue = in(checkPoint); 00104 mrs_bool isOnset = true; 00105 00106 //check first condition 00107 mrs_natural interval = mrs_natural(2.0/3.0*w); 00108 //for (t = inSamples_-1; t >= inSamples_-1-2*w ; t--) 00109 for(t=checkPoint-interval; t <= checkPoint+interval; t++) 00110 { 00111 if(checkPointValue < in(t)) 00112 { 00113 isOnset = false; 00114 MRSDIAG("PeakerOnset::myProcess() - Failed 1st condition!"); 00115 break; 00116 } 00117 } 00118 00119 // //new check proposed by Fabien Gouyon 00120 // mrs_real ww = w/2; 00121 // mrs_real maxVal = MINREAL; 00122 // for(t = inSamples_-1-ww; t > checkPoint; t--) 00123 // { 00124 // if(in(t) > maxVal) 00125 // { 00126 // maxVal = in(t); 00127 // } 00128 // else 00129 // { 00130 // isOnset = false; 00131 // //cout << "failed 1st condition!" << endl; 00132 // break; 00133 // } 00134 // } 00135 // maxVal = MINREAL; 00136 // for(t = inSamples_-1-2*ww; t < checkPoint; t++) 00137 // { 00138 // if(in(t) > maxVal) 00139 // { 00140 // maxVal = in(t); 00141 // } 00142 // else 00143 // { 00144 // isOnset = false; 00145 // //cout << "failed 1st condition!" << endl; 00146 // break; 00147 // } 00148 // } 00149 00150 /* Last version (by lgmartins) -> corrected (below) for not being strict to the window size defined by the precede ShiftInput 00151 //check second condition 00152 mrs_real m = 0.0; 00153 for(t=0; t < inSamples_; t++) 00154 m += in(t); 00155 m /= inSamples_; 00156 */ 00157 00158 mrs_natural mul = 3; //multiplier proposed in Dixon2006 00159 mrs_real m = 0.0; 00160 for(t=checkPoint-(mul*w); t < inSamples_; t++) 00161 m += in(t); 00162 m /= (w*4+1); 00163 00164 //checkPoint value should be higher than the window mean and mean should 00165 //be a significant value (otherwise we most probably are in a silence segment, 00166 //and we do not want to detect onsets on segments!) 00167 if(checkPointValue <= (m * ctrl_threshold_->to<mrs_real>()) || m < 10e-20) 00168 { 00169 isOnset = false; 00170 MRSDIAG("PeakerOnset::myProcess() - Failed 2nd condition!"); 00171 } 00172 00173 //third condition from Dixon2006 (DAFx paper) is not implemented 00174 //since it was found on that paper that its impact is minimal... 00175 00176 if(isOnset) 00177 { 00178 ctrl_onsetDetected_->setValue(true); 00179 //ctrl_confidence_->setValue(1.0); //[!] must still find a way to output a confidence... 00180 ctrl_confidence_->setValue(checkPointValue/100.0); // ad-hoc value which should still have more meaning than a pure 1.0 vs. 0.0. 00181 out.setval(1.0); 00182 MRSDIAG("PeakerOnset::myProcess() - Onset Detected!"); 00183 } 00184 00185 //used for toy_with_onsets.m (DO NOT DELETE! - COMMENT INSTEAD) 00186 00187 //t_++; 00188 00189 //if(t_ == 0) 00190 // MATLAB_PUT(in, "PeakerOnset_inWIN"); 00191 //MATLAB_PUT(in, "PeakerOnset_in"); 00192 //if(t_ <= 431) 00193 // MATLAB_EVAL("PK_TS2 = [PK_TS2 PeakerOnset_in]"); 00194 //MATLAB_EVAL("plot(PK_TS, 'r');"); 00195 //MATLAB_EVAL("plot(FluxTS); hold on; plot(PK_TS, 'r');"); 00196 //MATLAB_EVAL("plot(PeakerOnset_in,'r');hold on; plot(ShiftInput_out); hold off"); 00197 //MATLAB_PUT(out,"PeakerOnset_out"); 00198 //MATLAB_EVAL("onsetTS = [onsetTS, PeakerOnset_out];"); 00199 }