Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/peakView.cpp
Go to the documentation of this file.
00001 
00002 /*
00003 ** Copyright (C) 1998-2006 George Tzanetakis <gtzan@cs.uvic.ca>
00004 **
00005 ** This program is free software; you can redistribute it and/or modify
00006 ** it under the terms of the GNU General Public License as published by
00007 ** the Free Software Foundation; either version 2 of the License, or
00008 ** (at your option) any later version.
00009 **
00010 ** This program is distributed in the hope that it will be useful,
00011 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 ** GNU General Public License for more details.
00014 **
00015 ** You should have received a copy of the GNU General Public License
00016 ** along with this program; if not, write to the Free Software
00017 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00018 */
00019 
00020 #include <marsyas/peakView.h>
00021 #include <algorithm>
00022 
00023 using namespace std;
00024 using namespace Marsyas;
00025 
00026 peakView::peakView(realvec& vec): vec_(vec), fs_(0), frameSize_(0)
00027 {
00028   //max number of peaks in each frame
00029   frameMaxNumPeaks_ = vec_.getRows() / nbPkParameters;
00030   numFrames_ = vec_.getCols();
00031 }
00032 
00033 peakView::~peakView()
00034 {
00035 
00036 }
00037 
00038 mrs_natural
00039 peakView::getNumGroups()
00040 {
00041   mrs_natural numGroups = 0;
00042 
00043   for(mrs_natural f=0; f < numFrames_; ++f)
00044     for(mrs_natural p = 0; p < this->getFrameNumPeaks(f); ++p)
00045     {
00046       if((*this)(p, pkGroup, f) > numGroups)
00047         numGroups = (mrs_natural)(*this)(p, pkGroup, f);
00048     }
00049   numGroups++;
00050   return numGroups;
00051 }
00052 
00053 mrs_natural
00054 peakView::getFrameNumPeaks(const mrs_natural frame, const mrs_natural group) const
00055 {
00056   if(group==-1)//ignore group information
00057   {
00058     //count the number of detected peaks in the frame
00059     //
00060     //"peaks" with freq == 0 are considered non-existent
00061     //so just count peaks until we get the first "peak" with freq!=0
00062     mrs_natural p;
00063     for(p=0; p < frameMaxNumPeaks_; ++p)
00064     {
00065       if((*this)(p, pkFrequency, frame) == 0)
00066         return p;
00067     }
00068     return frameMaxNumPeaks_;
00069   }
00070   else //count peaks from "group" that exist in "frame"
00071   {
00072     mrs_natural numPeaks = 0;
00073     for(mrs_natural p = 0; p < frameMaxNumPeaks_; ++p)
00074     {
00075       if((*this)(p, pkFrequency, frame) == 0)
00076         return numPeaks;
00077 
00078       if((*this)(p, pkGroup, frame) == group)
00079         numPeaks++;
00080     }
00081     return numPeaks;
00082   }
00083 }
00084 
00085 mrs_natural
00086 peakView::getTotalNumPeaks(const mrs_natural group) const
00087 {
00088   mrs_natural numPeaks = 0;
00089   for(mrs_natural f=0; f < numFrames_; ++f)
00090   {
00091     numPeaks += this->getFrameNumPeaks(f, group);
00092   }
00093   return numPeaks;
00094 }
00095 
00096 void
00097 peakView::removePeak (const mrs_natural peakIndex, const mrs_natural frame)
00098 {
00099   mrs_natural p,
00100               totalNumPeaks = getTotalNumPeaks ();
00101   for (mrs_natural i = peakIndex; i < totalNumPeaks -1; i++)
00102   {
00103     for (p = 0; p < nbPkParameters; p++)
00104       vec_(peakIndex + p * frameMaxNumPeaks_, frame) = vec_(peakIndex + 1 + p * frameMaxNumPeaks_, frame);
00105   }
00106   for (p = 0; p < nbPkParameters; p++)
00107     vec_(totalNumPeaks -1 + p * frameMaxNumPeaks_, frame) = 0;
00108 }
00109 
00110 void
00111 peakView::getPeaksParam(vector<realvec>& result, const pkParameter param, mrs_natural startFrame, mrs_natural endFrame) const
00112 {
00113   if(startFrame < 0 || endFrame < 0)
00114   {
00115     MRSWARN("peakView::getPeaksParam: negative start/stop frame! Returning empty vector.");
00116     return;
00117   }
00118   if(startFrame >= vec_.getCols() || endFrame >= vec_.getCols())
00119   {
00120     MRSWARN("peakView::getPeaksParam: start/end frame bigger than vector column size! Returning empty vector.");
00121     return;
00122   }
00123 
00124   mrs_natural numPeaks;
00125 
00126   for(mrs_natural f = startFrame; f <= endFrame; ++f)
00127   {
00128     //get a vector with the parameter values for all the peaks
00129     //detected in the frame (i.e. whose freq != 0)
00130     numPeaks = getFrameNumPeaks(f);
00131     realvec valVec(numPeaks);
00132 
00133     for(mrs_natural p=0; p<numPeaks; ++p)
00134       valVec(p) = (*this)(p, param, f);
00135 
00136     result.push_back(valVec);
00137   }
00138 }
00139 
00140 mrs_string
00141 peakView::getParamName(mrs_natural paramIdx)
00142 {
00143   switch(paramIdx)
00144   {
00145   case 0:
00146     return "pkFrequency";
00147     break;
00148   case 1:
00149     return "pkAmplitude";
00150     break;
00151   case 2:
00152     return "pkPhase";
00153     break;
00154   case 3:
00155     return "pkDeltaFrequency";
00156     break;
00157   case 4:
00158     return "pkDeltaAmplitude";
00159     break;
00160   case 5:
00161     return "pkFrame";
00162     break;
00163   case 6:
00164     return "pkGroup";
00165     break;
00166   case 7:
00167     return "pkVolume";
00168     break;
00169   case 8:
00170     return "pkPan";
00171     break;
00172   case 9:
00173     return "pkBinLow";
00174     break;
00175   case 10:
00176     return "pkBin";
00177     break;
00178   case 11:
00179     return "pkBinHigh";
00180     break;
00181   case 12:
00182     return "nbPkParameters";
00183     break;
00184   default:
00185     return "MARSYAS_EMPTY";
00186     break;
00187   }
00188 }
00189 
00190 void
00191 peakView::toTable(realvec& vecTable)
00192 {
00193   //resize and initialize the table (assuming the largest possible number of peaks + the header for now...)
00194   vecTable.create(frameMaxNumPeaks_*numFrames_+1, nbPkParameters);
00195 
00196 
00197   //In Table format, the 1st row is a "header row"
00198   vecTable(0, 0) = -1;
00199   vecTable(0, 1) =  fs_;
00200   vecTable(0, 2) =  frameSize_;
00201   vecTable(0, 3) =  frameMaxNumPeaks_;
00202   vecTable(0, 4) =  numFrames_;
00203   vecTable(0, 5) = -1;
00204   vecTable(0, pkGroup) = -2;
00205   for (mrs_natural i = pkGroup+1 ; i < nbPkParameters ; ++i) //i = pkGroup or i = pkGroup+1 [?]
00206     vecTable(0, i)=0;
00207 
00208 
00209   //fill the table with peak data
00210   mrs_natural l = 1; //l = peak index for table format (i.e. row index)
00211   for (mrs_natural j=0 ; j < vec_.getCols(); ++j) //j = frame index
00212     for (mrs_natural i=0 ; i < frameMaxNumPeaks_; ++i) //i = peak index
00213     {
00214       //just output existing peaks at each frame (i.e. freq != 0)
00215       if(vec_(i, j) != 0.0)
00216       {
00217         for(mrs_natural k = 0; k < nbPkParameters; k++)// k = parameter index
00218           vecTable(l, k) = (*this)(i, pkParameter(k), j);
00219         l++;
00220       }
00221     }
00222 
00223   //resize the table to the correct (i.e. possibly smaller)
00224   //number of peaks (i.e. nr of rows)
00225 
00226   vecTable.stretch(l, nbPkParameters);
00227 }
00228 
00229 void
00230 peakView::fromTable(const realvec& vecTable)
00231 {
00232   //get data from header
00233   fs_  = vecTable(0, 1);
00234   frameSize_ = (mrs_natural)vecTable(0, 2);
00235   frameMaxNumPeaks_ = (mrs_natural)vecTable(0, 3);
00236   numFrames_ = (mrs_natural)vecTable(0, 4);
00237 
00238   //get the first frame in table (it may not be 0!!!)
00239   mrs_natural frame = (mrs_natural)vecTable(1, pkFrame); // start frame [!]
00240 
00241   //resize (and set to zero) vec_ for new peak data
00242   //(should accommodate empty frames before the first frame in table!)
00243   vec_.create(frameMaxNumPeaks_*nbPkParameters, numFrames_+frame); //[!]
00244 
00245   mrs_natural p = 0; // peak index inside each frame
00246   mrs_natural r = 1;//peak index in table (i.e. row index) - ignore header row
00247 
00248   //check in case realvec has less parameters than nbPkParameters
00249   mrs_natural actualNbPkParams = (mrs_natural)min((mrs_real)nbPkParameters, (mrs_real)vecTable.getCols());
00250 
00251   //iterate over table rows (i.e. peaks) - excluding header row
00252   while(r < vecTable.getRows()-1)
00253   {
00254     //get parameters for this peak
00255     for(mrs_natural prm = 0; prm < actualNbPkParams; ++prm)
00256     {
00257       (*this)(p, pkParameter(prm), frame) = vecTable(r, prm);
00258     }
00259     ++r; //move on to next table row (i.e. peak)
00260     p++;
00261     //if the next row in table is form a different frame,
00262     //reset peak index and get new frame index
00263     if(vecTable(r, pkFrame) != frame)
00264     {
00265       frame = (mrs_natural)vecTable(r, pkFrame);
00266       p = 0;
00267     }
00268   }
00269 }
00270 
00271 bool
00272 peakView::peakWrite(mrs_string filename, mrs_real fs, mrs_natural frameSize)
00273 {
00274   //we may want to write this peakVector with its internal parameters
00275   if(fs != 0)
00276     fs_ = fs;
00277   if(frameSize != 0)
00278     frameSize_ = frameSize;
00279 
00280 
00281   //convert vec_ to table format and save to file
00282   realvec resVec;
00283   this->toTable(resVec);
00284   return resVec.write(filename);
00285 }
00286 
00287 bool
00288 peakView::peakRead(mrs_string filename)
00289 {
00290   //read .peak into a realvec
00291   realvec vec_Table;
00292   if(vec_Table.read(filename))
00293   {
00294     //read data from the table
00295     this->fromTable(vec_Table);
00296     return true;
00297   }
00298   else
00299     return false; //problem reading .peak file
00300 }