Marsyas
0.6.0-alpha
|
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 }