Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marsystems/PeakViewMerge.cpp
Go to the documentation of this file.
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