00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "HWPS.h"
00020 #include "NumericLib.h"
00021
00022
00023 using std::ostringstream;
00024 using std::min;
00025 using std::max;
00026 using std::abs;
00027
00028 using namespace Marsyas;
00029
00030 HWPS::HWPS(mrs_string name):MarSystem("HWPS", name)
00031 {
00032 addControls();
00033 }
00034
00035 HWPS::HWPS(const HWPS& a) : MarSystem(a)
00036 {
00037 ctrl_histSize_ = getctrl("mrs_natural/histSize");
00038 ctrl_calcDistance_ = getctrl("mrs_bool/calcDistance");
00039 }
00040
00041 HWPS::~HWPS()
00042 {
00043 }
00044
00045 MarSystem*
00046 HWPS::clone() const
00047 {
00048 return new HWPS(*this);
00049 }
00050
00051 void
00052 HWPS::addControls()
00053 {
00054 addctrl("mrs_bool/calcDistance", false, ctrl_calcDistance_);
00055 addctrl("mrs_natural/histSize", 20, ctrl_histSize_);
00056 }
00057
00058 void
00059 HWPS::harmonicWrap(mrs_real peak1Freq, mrs_real peak2Freq, realvec& peak1SetFreqs, realvec& peak2SetFreqs)
00060 {
00061
00062
00063 mrs_real hF;
00064
00065
00066
00067 hF = min(peak1SetFreqs(0), peak2SetFreqs(0));
00068
00069
00070
00071
00072
00073
00074
00075 peak1SetFreqs -= peak1Freq;
00076 peak2SetFreqs -= peak2Freq;
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 peak1SetFreqs /= hF;
00087 peak2SetFreqs /= hF;
00088
00089 for (mrs_natural k=0 ; k<peak1SetFreqs.getSize() ; k++)
00090 {
00091 peak1SetFreqs(k)=fmod(peak1SetFreqs(k), 1);
00092
00093 while(peak1SetFreqs(k)<0)
00094 peak1SetFreqs(k)+=1;
00095 }
00096 for (mrs_natural k=0 ; k<peak2SetFreqs.getSize() ; k++)
00097 {
00098 peak2SetFreqs(k)=fmod(peak2SetFreqs(k), 1);
00099
00100 while(peak2SetFreqs(k)<0)
00101 peak2SetFreqs(k)+=1;
00102 }
00103 }
00104
00105 void
00106 HWPS::discretize(const realvec& peakSetWrapFreqs, const realvec& peakAmps,
00107 const mrs_natural& histSize, realvec& resultHistogram)
00108 {
00109 mrs_natural index;
00110
00111 resultHistogram.create(histSize);
00112
00113 for (mrs_natural i=0 ; i<peakSetWrapFreqs.getSize() ; ++i)
00114 {
00115 index = (mrs_natural) fmod(floor(peakSetWrapFreqs(i)*histSize+.5), histSize);
00116 resultHistogram(index) += peakAmps(i);
00117 }
00118 }
00119
00120 void
00121 HWPS::myUpdate(MarControlPtr sender)
00122 {
00123 (void) sender;
00124 if(inSamples_ > 1)
00125 MRSWARN("HWPS::myUpdate - inSamples > 1 : only first column will be processed!");
00126
00127 ctrl_onObservations_->setValue(1, NOUPDATE);
00128 ctrl_onSamples_->setValue(1, NOUPDATE);
00129 ctrl_osrate_->setValue(ctrl_israte_, NOUPDATE);
00130 ctrl_onObsNames_->setValue("HWPS", NOUPDATE);
00131
00132
00133 if(inObservations_ % 2 != 0)
00134 MRSWARN("HWPS::myUpdate - input flow controls do not seem to be in a valid format!");
00135
00136 vec_i_.create(ctrl_inObservations_->to<mrs_natural>()/2);
00137 vec_j_.create(ctrl_inObservations_->to<mrs_natural>()/2);
00138 }
00139
00140 void
00141 HWPS::myProcess(realvec& in, realvec& out)
00142 {
00143 mrs_natural o;
00144
00145 for(o=0; o < inObservations_/2; ++o)
00146 {
00147 vec_i_(o) = in(o,0);
00148 vec_j_(o) = in(o+inObservations_/2,0);
00149 }
00150
00151
00152
00153
00154
00155 pk_i_freq_ = vec_i_(HWPS::pkFreqIdx);
00156 pk_j_freq_ = vec_j_(HWPS::pkFreqIdx);
00157 i_frameNumPeaks_ = (mrs_natural)vec_i_(HWPS::frameNumPeaksIdx);
00158 j_frameNumPeaks_ = (mrs_natural)vec_j_(HWPS::frameNumPeaksIdx);
00159
00160
00161 pkSet_i_Freqs_.stretch(i_frameNumPeaks_);
00162 pkSet_i_Amps_.stretch(i_frameNumPeaks_);
00163 for(o=0; o < i_frameNumPeaks_; ++o)
00164 {
00165 pkSet_i_Freqs_(o) = vec_i_(o+pkSetFeatsIdx);
00166 pkSet_i_Amps_(o) = vec_i_(o+pkSetFeatsIdx+i_frameNumPeaks_);
00167 }
00168
00169 pkSet_j_Freqs_.stretch(j_frameNumPeaks_);
00170 pkSet_j_Amps_.stretch(j_frameNumPeaks_);
00171 for(o=0; o < j_frameNumPeaks_; ++o)
00172 {
00173 pkSet_j_Freqs_(o) = vec_j_(o+pkSetFeatsIdx);
00174 pkSet_j_Amps_(o) = vec_j_(o+pkSetFeatsIdx+j_frameNumPeaks_);
00175 }
00176
00177
00178 pkSet_i_WrapFreqs_ = pkSet_i_Freqs_;
00179 pkSet_j_WrapFreqs_ = pkSet_j_Freqs_;
00180 harmonicWrap(pk_i_freq_, pk_j_freq_, pkSet_i_WrapFreqs_, pkSet_j_WrapFreqs_);
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 histSize_ = ctrl_histSize_->to<mrs_natural>();
00192 discretize(pkSet_i_WrapFreqs_, pkSet_i_Amps_, histSize_, histogram_i_);
00193 discretize(pkSet_j_WrapFreqs_, pkSet_j_Amps_, histSize_, histogram_j_);
00194
00195
00196
00197
00198
00199
00200
00201 if(ctrl_calcDistance_->isTrue())
00202 {
00203
00204 out(0) = NumericLib::cosineDistance(histogram_i_, histogram_j_);
00205 }
00206 else
00207 {
00208
00209 out(0) = 1.0 - NumericLib::cosineDistance(histogram_i_, histogram_j_);
00210 }
00211 }