00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "common.h"
00020 #include "PeakDistanceHorizontality.h"
00021
00022 using std::ostringstream;
00023 using std::abs;
00024
00025 using namespace Marsyas;
00026
00027
00028
00029
00030 static const mrs_real kIdentityThresh = 1e-6;
00031 static const mrs_real kSteepness = .8;
00032 static const mrs_real kCutoff = 1.;
00033
00034 PeakDistanceHorizontality::PeakDistanceHorizontality(mrs_string name) : MarSystem("PeakDistanceHorizontality", name)
00035 {
00037
00038
00039
00040
00041
00042 addControls();
00043 }
00044
00045 PeakDistanceHorizontality::PeakDistanceHorizontality(const PeakDistanceHorizontality& a) : MarSystem(a)
00046 {
00047 ctrl_horizvert_ = getctrl("mrs_realvec/inpIsHorizontal");
00048 ctrl_rangeX_ = getctrl("mrs_real/rangeX");
00049 ctrl_rangeY_ = getctrl("mrs_real/rangeY");
00050 }
00051
00052
00053 PeakDistanceHorizontality::~PeakDistanceHorizontality()
00054 {
00055 }
00056
00057 MarSystem*
00058 PeakDistanceHorizontality::clone() const
00059 {
00060
00061 return new PeakDistanceHorizontality(*this);
00062 }
00063
00064 void
00065 PeakDistanceHorizontality::addControls()
00066 {
00067 mrs_realvec tmp(1);
00068 tmp(0) = 0;
00069
00070 addctrl("mrs_bool/bypass", false);
00071 addctrl("mrs_realvec/weights", tmp);
00072 addctrl("mrs_natural/numInputs", 0);
00073 addctrl("mrs_realvec/inpIsHorizontal", tmp, ctrl_horizvert_);
00074 addctrl("mrs_real/rangeX", 0., ctrl_rangeX_);
00075 addctrl("mrs_real/rangeY", 0., ctrl_rangeY_);
00076 }
00077
00078 void
00079 PeakDistanceHorizontality::myUpdate(MarControlPtr sender)
00080 {
00081 MRSDIAG("PeakDistanceHorizontality.cpp - PeakDistanceHorizontality:myUpdate");
00082
00084 MarSystem::myUpdate(sender);
00085
00086 weights_.stretch(inSamples_*getctrl ("mrs_natural/numInputs")->to<mrs_natural>(), inSamples_);
00087
00088 sigSteepness_ = kSteepness;
00089 sigCutOff_ = kCutoff;
00090 }
00091
00092 void
00093 PeakDistanceHorizontality::myProcess(realvec& in, realvec& out)
00094 {
00095 mrs_natural i;
00096 const mrs_natural numInputs = getctrl ("mrs_natural/numInputs")->to<mrs_natural>();
00097 const mrs_realvec isHoriz = ctrl_horizvert_->to<mrs_realvec>();
00098 const mrs_real range[2] = {ctrl_rangeX_->to<mrs_real>(), ctrl_rangeY_->to<mrs_real>()};
00099
00100 out = in;
00101
00102 MRSASSERT(range[0] > 0 && range[1] > 0);
00103 if (isHoriz.getSize () != numInputs)
00104 {
00105 MRSWARN("PeakDistanceHorizontality: dimension mismatch");
00106 MRSASSERT(false);
00107 out.setval(0);
00108 return;
00109 }
00110
00111 if (getctrl("mrs_bool/bypass")->to<mrs_bool>())
00112 {
00113 weights_.setval(1.);
00114 setctrl ("mrs_realvec/weights", weights_);
00115 return;
00116 }
00117
00118 for (i = 0; i < inSamples_; i++)
00119 {
00120 for (mrs_natural j = i; j < inSamples_; j++)
00121 {
00122 mrs_natural k;
00123 mrs_real horizontality = ComputeHorizontality ( std::abs(in(1,i)-in(1,j))/range[0],
00124 std::abs(in(0,i)-in(0,j))/range[1]),
00125 norm = 0;
00126
00127 for (k = 0; k < numInputs; k++)
00128 {
00129 mrs_real weight = horizontality;
00130
00131 if (abs(isHoriz(k) - 2) < kIdentityThresh)
00132 weight = .5;
00133 else if (abs(isHoriz(k)) < kIdentityThresh)
00134 weight = 1.-weight;
00135
00136 norm += weight;
00137 weights_(k*inSamples_ + i, j) = weight;
00138 weights_(k*inSamples_ + j, i) = weight;
00139 }
00140 if (norm != 0)
00141 norm = 1./norm;
00142 for (k = 0; k < numInputs; k++)
00143 {
00144 weights_(k*inSamples_ + i, j) *= norm;
00145 if (i != j)
00146 weights_(k*inSamples_ + j, i) *= norm;
00147 }
00148 }
00149 }
00150 setctrl ("mrs_realvec/weights", weights_);
00151 #ifdef MARSYAS_MATLAB
00152 #ifdef MTLB_DBG_LOG
00153 MATLAB_PUT(weights_, "weights");
00154 MATLAB_EVAL("figure(1);imagesc(weights),colorbar;");
00155 #endif
00156 #endif
00157 }
00158
00159 mrs_real
00160 PeakDistanceHorizontality::ComputeHorizontality(mrs_real scaledDiffX, mrs_real scaledDiffY)
00161 {
00162
00163 if (scaledDiffX == 0)
00164 {
00165 if (scaledDiffY == 0)
00166 return .5;
00167 else
00168 return 0.;
00169 }
00170 else if (scaledDiffY == 0)
00171 return 1.;
00172
00173 mrs_real res = scaledDiffX / std::sqrt(scaledDiffX*scaledDiffX + scaledDiffY*scaledDiffY);
00174
00175 return res*res;
00176 }