Marsyas
0.6.0-alpha
|
00001 /* 00002 ** Copyright (C) 1998-2010 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 "../common_source.h" 00020 #include "PeakViewMerge.h" 00021 #include <marsyas/peakView.h> 00022 00023 00024 using namespace Marsyas; 00025 00026 using std::abs; 00027 00028 static const mrs_real freqResolution = 15.; // Hertz 00029 00030 static inline mrs_natural FindDuplicate (peakView *peaks, mrs_real frequency, mrs_natural numPeaks) 00031 { 00032 for (mrs_natural i = 0; i < numPeaks; i++) 00033 { 00034 mrs_real freq = (*peaks)(i, peakView::pkFrequency); 00035 if (abs(freq - frequency) <= freqResolution) 00036 return i; 00037 } 00038 return -1; 00039 } 00040 00041 static inline void WriteOutput (peakView &Out, peakView *In, mrs_natural inputIdx, mrs_natural outputIdx) 00042 { 00043 for (mrs_natural i = 0; i < peakView::nbPkParameters; i++) 00044 Out(outputIdx, (peakView::pkParameter)i) = (*In)(inputIdx, (peakView::pkParameter)i); 00045 } 00046 00047 00048 PeakViewMerge::PeakViewMerge(mrs_string name):MarSystem("PeakViewMerge",name) 00049 { 00050 addControls(); 00051 } 00052 00053 PeakViewMerge::PeakViewMerge(const PeakViewMerge& a):MarSystem(a) 00054 { 00055 ctrl_mode_ = getctrl("mrs_string/mode"); 00056 ctrl_totalNumPeaks_ = getctrl("mrs_natural/totalNumPeaks"); 00057 ctrl_frameMaxNumPeaks1_ = getctrl("mrs_natural/frameMaxNumPeaks1"); 00058 ctrl_frameMaxNumPeaks2_ = getctrl("mrs_natural/frameMaxNumPeaks2"); 00059 ctrl_noNegativeGroups_ = getctrl("mrs_bool/discardNegativeGroups"); 00060 } 00061 00062 PeakViewMerge::~PeakViewMerge() 00063 { 00064 } 00065 00066 MarSystem* 00067 PeakViewMerge::clone() const 00068 { 00069 return new PeakViewMerge(*this); 00070 } 00071 00072 void 00073 PeakViewMerge::addControls() 00074 { 00075 addControl("mrs_string/mode", "AND", ctrl_mode_); 00076 addControl("mrs_natural/totalNumPeaks", 0, ctrl_totalNumPeaks_); 00077 addControl("mrs_natural/frameMaxNumPeaks1", 0, ctrl_frameMaxNumPeaks1_); 00078 addControl("mrs_natural/frameMaxNumPeaks2", 0, ctrl_frameMaxNumPeaks2_); 00079 addControl("mrs_bool/discardNegativeGroups", false, ctrl_noNegativeGroups_); 00080 } 00081 00082 00083 void 00084 PeakViewMerge::myUpdate(MarControlPtr sender) 00085 { 00086 (void) sender; //suppress warning of unused parameter(s) 00087 MRSDIAG("PeakViewMerge.cpp - PeakViewMerge:myUpdate"); 00088 00089 ctrl_onObservations_->setValue(ctrl_inObservations_, NOUPDATE); 00090 ctrl_onSamples_->setValue(ctrl_inSamples_, NOUPDATE); 00091 ctrl_osrate_->setValue(ctrl_israte_, NOUPDATE); 00092 ctrl_onObsNames_->setValue(ctrl_inObsNames_, NOUPDATE); 00093 } 00094 00095 void 00096 PeakViewMerge::myProcess(realvec& in, realvec& out) 00097 { 00098 peakView *In[kNumMatrices], 00099 Out (out); 00100 mrs_natural i, rowIdx = 0, 00101 numPeaks[kNumMatrices], 00102 outputIdx = 0; 00103 const mrs_bool discNegGroups = ctrl_noNegativeGroups_->to<mrs_bool>(); 00104 00105 out.setval(0.); 00106 00107 for (i = 0; i < kNumMatrices; i++) 00108 { 00109 mrs_natural numRows = (i==kMat1)? ctrl_frameMaxNumPeaks1_->to<mrs_natural>() : ctrl_frameMaxNumPeaks2_->to<mrs_natural>(); 00110 numRows *= peakView::nbPkParameters; 00111 if (numRows == 0) // if the controls have not been set assume both matrixes to be of equal size 00112 numRows = in.getRows ()/kNumMatrices; 00113 peakViewIn_[i].stretch (numRows, in.getCols ()); 00114 in.getSubMatrix (rowIdx, 0, peakViewIn_[i]); 00115 rowIdx += numRows; 00116 In[i] = new peakView(peakViewIn_[i]); 00117 numPeaks[i] = In[i]->getTotalNumPeaks (); 00118 } 00119 00120 if (ctrl_mode_->to<mrs_string>() == "OR") 00121 { 00122 // write all entries of the second peakView to output 00123 for (i = 0; i < numPeaks[1]; i++) 00124 { 00125 if (discNegGroups && (*In[1])(i,peakView::pkGroup) < 0) 00126 continue; 00127 WriteOutput (Out, In[1], i, outputIdx); 00128 outputIdx++; 00129 } 00130 00131 // write all entries of the first peakView to output except duplicates 00132 for (i = 0; i < numPeaks[0]; i++) 00133 { 00134 mrs_natural Idx; 00135 if (discNegGroups && (*In[0])(i,peakView::pkGroup) < 0) 00136 continue; 00137 for (mrs_natural k = 1; k < kNumMatrices; k++) 00138 Idx = FindDuplicate (In[k], (*In[0])(i, peakView::pkFrequency), numPeaks[k]); 00139 00140 if (Idx < 0) 00141 { 00142 WriteOutput (Out, In[0], i, outputIdx); 00143 outputIdx++; 00144 } 00145 } 00146 } 00147 else if (ctrl_mode_->to<mrs_string>() == "AND") 00148 { 00149 // find duplicates and write only them to output 00150 for (i = 0; i < numPeaks[0]; i++) 00151 { 00152 mrs_natural Idx; 00153 if (discNegGroups && (*In[0])(i,peakView::pkGroup) < 0) 00154 continue; 00155 for (mrs_natural k = 1; k < kNumMatrices; k++) 00156 Idx = FindDuplicate (In[k], (*In[0])(i, peakView::pkFrequency), numPeaks[k]); 00157 00158 if (Idx >= 0) 00159 { 00160 if (discNegGroups && (*In[1])(Idx,peakView::pkGroup) < 0) 00161 continue; 00162 WriteOutput (Out, In[0], i, outputIdx); 00163 outputIdx++; 00164 } 00165 } 00166 } 00167 else if (ctrl_mode_->to<mrs_string>() == "ANDOR") 00168 { 00169 // keep the input[0] peaks that are not in input[1] 00170 for (i = 0; i < numPeaks[0]; i++) 00171 { 00172 mrs_natural Idx; 00173 if (discNegGroups && (*In[0])(i,peakView::pkGroup) < 0) 00174 continue; 00175 for (mrs_natural k = 1; k < kNumMatrices; k++) 00176 Idx = FindDuplicate (In[k], (*In[0])(i, peakView::pkFrequency), numPeaks[k]); 00177 00178 if (Idx < 0) 00179 { 00180 WriteOutput (Out, In[0], i, outputIdx); 00181 outputIdx++; 00182 } 00183 } 00184 } 00185 else if (ctrl_mode_->to<mrs_string>() == "XOR") 00186 { 00187 // find duplicates and write only residual to output 00188 for (i = 0; i < numPeaks[0]; i++) 00189 { 00190 if (discNegGroups && (*In[0])(i,peakView::pkGroup) < 0) 00191 continue; 00192 mrs_natural Idx = FindDuplicate (In[1], (*In[0])(i, peakView::pkFrequency), numPeaks[1]); 00193 00194 if (Idx < 0) 00195 { 00196 WriteOutput (Out, In[0], i, outputIdx); 00197 outputIdx++; 00198 } 00199 } 00200 // find duplicates and write only residual to output 00201 for (i = 0; i < numPeaks[1]; i++) 00202 { 00203 if (discNegGroups && (*In[1])(i,peakView::pkGroup) < 0) 00204 continue; 00205 mrs_natural Idx= FindDuplicate (In[0], (*In[1])(i, peakView::pkFrequency), numPeaks[0]); 00206 00207 if (Idx < 0) 00208 { 00209 WriteOutput (Out, In[1], i, outputIdx); 00210 outputIdx++; 00211 } 00212 } 00213 } 00214 else 00215 { 00216 MRSERR("PeakViewMerfe::myProcess() : illegal mode string: " << ctrl_mode_->to<mrs_string>()); 00217 } 00218 00219 for (i = 0; i < kNumMatrices; i++) 00220 { 00221 delete In[i]; 00222 } 00223 00224 ctrl_totalNumPeaks_->setValue(outputIdx); 00225 } 00226