CLAM-Development
1.1
|
00001 /* 00002 * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG) 00003 * UNIVERSITAT POMPEU FABRA 00004 * 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 * 00020 */ 00021 00022 #include "SDIFFileReader.hxx" 00023 #include "SpectrumConfig.hxx" 00024 #include "ErrOpenFile.hxx" 00025 #include "SDIFFile.hxx" 00026 #include "SDIFFrame.hxx" 00027 #include "SDIFMatrix.hxx" 00028 00029 namespace CLAM 00030 { 00031 00032 SDIFFileReader::SDIFFileReader(): 00033 mPrevIndexArray(0), isFileOpen(false) 00034 { 00035 mpFile=NULL; 00036 mLastCenterTime=-1; 00037 Configure(SDIFInConfig()); 00038 } 00039 00040 SDIFFileReader::SDIFFileReader(const SDIFInConfig& c): 00041 mPrevIndexArray(0), isFileOpen(false) 00042 { 00043 mpFile=NULL; 00044 mLastCenterTime=-1; 00045 00046 Configure(c); 00047 } 00048 00049 SDIFFileReader::~SDIFFileReader() 00050 { 00051 if (mpFile != NULL) 00052 mpFile->Close(); 00053 delete mpFile; 00054 } 00055 00056 bool SDIFFileReader::Configure(const SDIFInConfig& c) 00057 { 00058 mConfig = c; 00059 00060 return true; 00061 } 00062 00063 bool SDIFFileReader::OpenFile() 00064 { 00065 if(mpFile) delete mpFile; 00066 mpFile = new SDIF::File(mConfig.GetFileName().c_str(),SDIF::File::eInput); 00067 00068 try 00069 { 00070 mpFile->Open(); 00071 isFileOpen = true; 00072 return true; 00073 } 00074 catch ( ErrOpenFile& e ) 00075 { 00076 std::cerr << "Inner exception thrown: File <" << mConfig.GetFileName().c_str() << "> could not be opened" << std::endl; 00077 00078 return false; 00079 } 00080 00081 return true; 00082 } 00083 00084 const ProcessingConfig& SDIFFileReader::GetConfig() const 00085 { 00086 return mConfig; 00087 } 00088 00089 bool SDIFFileReader::ReadFrame( CLAM::Fundamental& argFundamental, 00090 CLAM::SpectralPeakArray& argSpectralPeaks, 00091 CLAM::Spectrum& argResidual) 00092 { 00093 TTime throwAwayFloat; 00094 return SDIFFileReader::ReadFrame( argFundamental, 00095 argSpectralPeaks, 00096 argResidual, 00097 throwAwayFloat); 00098 } 00099 00100 bool SDIFFileReader::ReadFrame( CLAM::Fundamental& argFundamental, 00101 CLAM::SpectralPeakArray& argSpectralPeaks, 00102 CLAM::Spectrum& argResidual, 00103 TTime& argFrameCenterTime) 00104 { 00105 if (!isFileOpen) OpenFile(); 00106 if(!mpFile) return false; 00107 if(mpFile->Done()) 00108 { 00109 mpFile->Close(); 00110 return false; 00111 } 00112 00113 //Residual Spectrum in frame should be configured to have the ComplexArray 00114 SpectrumConfig Scfg; 00115 SpecTypeFlags sflags; 00116 sflags.bComplex = 1; 00117 sflags.bMagPhase = 0; 00118 argResidual.SetType(sflags); 00119 00120 double frameTimeTag; 00121 int counter = 0; 00122 // for most files, we will need to call mpFile->Read() once for each of its parts. if 00123 // the SDIF file has a sinusoidal, residual, and fundamental part, we loop here three 00124 // times, but not all files have all three parts. 00125 // for most frames we will leave this loop when the condition frameTimeTag != mLastCenterTime 00126 // obtains. (Look 20 lines down.) 00127 // !mpFile->Done() obtains only for the last frame in the file. 00128 while ( !mpFile->Done() ) 00129 { 00130 SDIF::Frame tmpSDIFFrame; 00131 int currentFilePosition = mpFile->Pos(); 00132 mpFile->Read(tmpSDIFFrame); 00133 00134 frameTimeTag = tmpSDIFFrame.Time(); 00135 00136 // if this is the first iteration then update the mLastCenterTime variable with the 00137 // the center time of the current frame 00138 if (counter == 0) 00139 { 00140 mLastCenterTime = frameTimeTag; 00141 argFrameCenterTime = frameTimeTag; 00142 } 00143 // check to make sure that the frame's center 00144 // time hasn't changed. if it has, then we're reading from a new frame, and we need 00145 // to return the values from the last frame before we start processing this new frame 00146 else if (frameTimeTag != mLastCenterTime) // new SpectralFrame, need to add it to segment 00147 { 00148 // we've reached the next frame of data. 00149 // push the file position back to where it was before we began reading the next frame 00150 // AND BREAK HERE IN ORDER TO RETURN THE LAST FRAME. 00151 mpFile->Pos(currentFilePosition); 00152 break; 00153 } 00154 00155 CopyFramesDataObjects( tmpSDIFFrame, argFundamental, argSpectralPeaks, argResidual ); 00156 00157 counter++; 00158 } 00159 00160 return true; 00161 00162 } 00163 00164 void SDIFFileReader::CopyFramesDataObjects(SDIF::Frame& tmpSDIFFrame, CLAM::Fundamental& argFundamental, 00165 CLAM::SpectralPeakArray& argSpectralPeaks, CLAM::Spectrum& argResidual) 00166 { 00167 SDIF::Frame::MatrixIterator frameIt = tmpSDIFFrame.Begin(); 00168 00169 //SDIF::Matrix* pMatrix = tmpSDIFFrame.mpFirst; 00170 00171 SDIF::ConcreteMatrix<TFloat32>* pMatrix= 00172 dynamic_cast< SDIF::ConcreteMatrix<TFloat32>* >(*frameIt); 00173 00174 /* its a fundamental frequency ..*/ 00175 if (tmpSDIFFrame.Type()=="1FQ0" && mConfig.GetEnableFundFreq()) 00176 { 00177 argFundamental.AddElem(pMatrix->GetValue(0,0)); 00178 } 00179 /* it is residual data ..*/ 00180 else if(tmpSDIFFrame.Type()=="1STF" && mConfig.GetEnableResidual()) // we use always the first 2 matrices 00181 { 00182 CLAM_ASSERT(pMatrix->Type() == "ISTF","SDIFIn::Add ISTF Header in Matrix expected"); 00183 00184 // these lines are important. all objects need to be added to the residual 00185 // now or later it will not be able to convert from complex format to a 00186 // phase / magnitude representation 00187 argResidual.AddAll(); 00188 argResidual.UpdateData(); 00189 00190 // MRJ: We set the sampling rate for the segment 00191 //segment.SetSamplingRate( pMatrix->GetValue( 0, 0 ) ); 00192 mSamplingRate = pMatrix->GetValue( 0, 0 ); 00193 00194 argResidual.SetSpectralRange(pMatrix->GetValue(0,0)*0.5); 00195 00196 // move pointer to next matrix in frame 00197 frameIt++; 00198 pMatrix= dynamic_cast< SDIF::ConcreteMatrix<TFloat32>* >(*frameIt); 00199 //pMatrix=pMatrix->mpNext; 00200 00201 CLAM_ASSERT(pMatrix->Type() =="1STF","SDIFIn::Add 1STF Headerin Matrix expected"); 00202 argResidual.SetSize(pMatrix->Rows()); 00203 Array<Complex>& complexBuffer=argResidual.GetComplexArray(); 00204 for (int r=0;r<pMatrix->Rows();r++) //read in complex data 00205 { 00206 Complex tmpComplex(pMatrix->GetValue(r,0),pMatrix->GetValue(r,1)); 00207 complexBuffer[r] = tmpComplex; 00208 } 00209 } 00210 /* its sinusoidal track data */ 00211 else if(tmpSDIFFrame.Type()=="1TRC" && mConfig.GetEnablePeakArray()) 00212 { 00213 TIndex nElems = pMatrix->Rows(); 00214 00215 argSpectralPeaks.AddAll(); 00216 argSpectralPeaks.UpdateData(); 00217 SpectralPeakArray& tmpPeakArray = argSpectralPeaks; 00218 tmpPeakArray.SetScale(EScale::eLinear); 00219 00220 tmpPeakArray.SetnMaxPeaks(nElems); //number of peaks in the sdif file 00221 tmpPeakArray.SetnPeaks(nElems); //number of peaks in the sdif file 00222 tmpPeakArray.ResetIndices(); // resets all indeces, make valid.. 00223 00224 /* read file data into SpectralPeakArray */ 00225 DataArray& pkfreqBuffer=tmpPeakArray.GetFreqBuffer(); 00226 DataArray& pkmagBuffer=tmpPeakArray.GetMagBuffer(); 00227 DataArray& pkPhaseBuffer=tmpPeakArray.GetPhaseBuffer(); 00228 DataArray& pkBinPosBuffer=tmpPeakArray.GetBinPosBuffer(); 00229 DataArray& pkBinWidthBuffer=tmpPeakArray.GetBinWidthBuffer(); 00230 IndexArray& pkIndexArray=tmpPeakArray.GetIndexArray(); 00231 if(!mConfig.GetRelativePeakIndices()) 00232 { 00233 for (int r=0;r<nElems;r++) 00234 { 00235 00236 // get frequency , mag and phase 00237 pkfreqBuffer[r]=pMatrix->GetValue(r,1); 00238 pkmagBuffer[r]=pMatrix->GetValue(r,2); 00239 pkPhaseBuffer[r]=pMatrix->GetValue(r,3); 00240 pkBinPosBuffer[r]=-1; 00241 pkBinWidthBuffer[r]=-1; 00242 pkIndexArray[r]=(int)pMatrix->GetValue(r,0) - 1; // -1 because SDIF doesnt allow Track 0 00243 } 00244 } 00245 else 00246 { 00247 IndexArray tmpIndexArray; 00248 for (int r=0;r<nElems;r++) 00249 { 00250 00251 // get frequency , mag and phase 00252 pkfreqBuffer[r]=pMatrix->GetValue(r,1); 00253 pkmagBuffer[r]=pMatrix->GetValue(r,2); 00254 pkPhaseBuffer[r]=pMatrix->GetValue(r,3); 00255 pkBinPosBuffer[r]=-1; 00256 pkBinWidthBuffer[r]=-1; 00257 if(mConfig.GetRelativePeakIndices()) 00258 { 00259 pkIndexArray[r]=-1; 00260 // track index and buffer it 00261 int tempIndex = (int)pMatrix->GetValue(r,0) - 1; // -1 because SDIF doesnt allow Track 0 00262 tmpIndexArray.AddElem(tempIndex); 00263 } 00264 } 00265 /* compare new indizes with the previous 00266 * the indizes of the current peakarray should hold 00267 * then the related 00268 * peak positions to the previous peakarray */ 00269 00270 TIndex nPeaks = tmpIndexArray.Size(); 00271 TIndex nPrevPeaks = mPrevIndexArray.Size(); 00272 TIndex currIndex,prevIndex; 00273 bool bIndexFound=false; 00274 00275 for (int i=0;i<nPeaks;i++) 00276 { 00277 bIndexFound=false; 00278 currIndex = tmpIndexArray[i]; 00279 00280 for (int j=0;j<nPrevPeaks;j++) 00281 { 00282 prevIndex = mPrevIndexArray[j]; 00283 if (prevIndex==currIndex) 00284 { 00285 pkIndexArray[i]=j; 00286 bIndexFound = true; 00287 break; 00288 } 00289 } 00290 if (!bIndexFound) pkIndexArray[i]=-1; 00291 } 00292 00293 /* current IndexArray becomes the Previous */ 00294 mPrevIndexArray = tmpIndexArray; 00295 } 00296 } 00297 } 00298 00299 int SDIFFileReader::GetReadPosition() 00300 { 00301 return mpFile->Pos(); 00302 } 00303 00304 void SDIFFileReader::SetReadPosition(int readPosition) 00305 { 00306 mpFile->Pos(readPosition); 00307 } 00308 00309 int SDIFFileReader::GetSamplingRate() 00310 { 00311 return mSamplingRate; 00312 } 00313 00314 int SDIFFileReader::GetFrameCenterTime() 00315 { 00316 return mLastCenterTime; 00317 } 00318 00319 } // namespace CLAM 00320