CLAM-Development  1.4.0
SDIFFileReader.cxx
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2004 MUSIC TECHNOLOGY GROUP (MTG)
3  * UNIVERSITAT POMPEU FABRA
4  *
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21 
22 #include "SDIFFileReader.hxx"
23 #include "SpectrumConfig.hxx"
24 #include "ErrOpenFile.hxx"
25 #include "SDIFFile.hxx"
26 #include "SDIFFrame.hxx"
27 #include "SDIFMatrix.hxx"
28 
29 namespace CLAM
30 {
31 
33  mPrevIndexArray(0), isFileOpen(false)
34 {
35  mpFile=NULL;
36  mLastCenterTime=-1;
38 }
39 
41  mPrevIndexArray(0), isFileOpen(false)
42 {
43  mpFile=NULL;
44  mLastCenterTime=-1;
45 
46  Configure(c);
47 }
48 
50 {
51  if (mpFile != NULL)
52  mpFile->Close();
53  delete mpFile;
54 }
55 
57 {
58  mConfig = c;
59 
60  return true;
61 }
62 
63 bool SDIFFileReader::OpenFile()
64 {
65  if(mpFile) delete mpFile;
66  mpFile = new SDIF::File(mConfig.GetFileName().c_str(),SDIF::File::eInput);
67 
68  try
69  {
70  mpFile->Open();
71  isFileOpen = true;
72  return true;
73  }
74  catch ( ErrOpenFile& e )
75  {
76  std::cerr << "Inner exception thrown: File <" << mConfig.GetFileName().c_str() << "> could not be opened" << std::endl;
77 
78  return false;
79  }
80 
81  return true;
82 }
83 
85 {
86  return mConfig;
87 }
88 
90  CLAM::SpectralPeakArray& argSpectralPeaks,
91  CLAM::Spectrum& argResidual)
92 {
93  TTime throwAwayFloat;
94  return SDIFFileReader::ReadFrame( argFundamental,
95  argSpectralPeaks,
96  argResidual,
97  throwAwayFloat);
98 }
99 
101  CLAM::SpectralPeakArray& argSpectralPeaks,
102  CLAM::Spectrum& argResidual,
103  TTime& argFrameCenterTime)
104 {
105  if (!isFileOpen) OpenFile();
106  if(!mpFile) return false;
107  if(mpFile->Done())
108  {
109  mpFile->Close();
110  return false;
111  }
112 
113  //Residual Spectrum in frame should be configured to have the ComplexArray
114  SpectrumConfig Scfg;
115  SpecTypeFlags sflags;
116  sflags.bComplex = 1;
117  sflags.bMagPhase = 0;
118  argResidual.SetType(sflags);
119 
120  double frameTimeTag;
121  int counter = 0;
122  // for most files, we will need to call mpFile->Read() once for each of its parts. if
123  // the SDIF file has a sinusoidal, residual, and fundamental part, we loop here three
124  // times, but not all files have all three parts.
125  // for most frames we will leave this loop when the condition frameTimeTag != mLastCenterTime
126  // obtains. (Look 20 lines down.)
127  // !mpFile->Done() obtains only for the last frame in the file.
128  while ( !mpFile->Done() )
129  {
130  SDIF::Frame tmpSDIFFrame;
131  int currentFilePosition = mpFile->Pos();
132  mpFile->Read(tmpSDIFFrame);
133 
134  frameTimeTag = tmpSDIFFrame.Time();
135 
136  // if this is the first iteration then update the mLastCenterTime variable with the
137  // the center time of the current frame
138  if (counter == 0)
139  {
140  mLastCenterTime = frameTimeTag;
141  argFrameCenterTime = frameTimeTag;
142  }
143  // check to make sure that the frame's center
144  // time hasn't changed. if it has, then we're reading from a new frame, and we need
145  // to return the values from the last frame before we start processing this new frame
146  else if (frameTimeTag != mLastCenterTime) // new SpectralFrame, need to add it to segment
147  {
148  // we've reached the next frame of data.
149  // push the file position back to where it was before we began reading the next frame
150  // AND BREAK HERE IN ORDER TO RETURN THE LAST FRAME.
151  mpFile->Pos(currentFilePosition);
152  break;
153  }
154 
155  CopyFramesDataObjects( tmpSDIFFrame, argFundamental, argSpectralPeaks, argResidual );
156 
157  counter++;
158  }
159 
160  return true;
161 
162 }
163 
164 void SDIFFileReader::CopyFramesDataObjects(SDIF::Frame& tmpSDIFFrame, CLAM::Fundamental& argFundamental,
165  CLAM::SpectralPeakArray& argSpectralPeaks, CLAM::Spectrum& argResidual)
166 {
167  SDIF::Frame::MatrixIterator frameIt = tmpSDIFFrame.Begin();
168 
169  //SDIF::Matrix* pMatrix = tmpSDIFFrame.mpFirst;
170 
172  dynamic_cast< SDIF::ConcreteMatrix<TFloat32>* >(*frameIt);
173 
174  /* its a fundamental frequency ..*/
175  if (tmpSDIFFrame.Type()=="1FQ0" && mConfig.GetEnableFundFreq())
176  {
177  argFundamental.AddElem(pMatrix->GetValue(0,0));
178  }
179  /* it is residual data ..*/
180  else if(tmpSDIFFrame.Type()=="1STF" && mConfig.GetEnableResidual()) // we use always the first 2 matrices
181  {
182  CLAM_ASSERT(pMatrix->Type() == "ISTF","SDIFIn::Add ISTF Header in Matrix expected");
183 
184  // these lines are important. all objects need to be added to the residual
185  // now or later it will not be able to convert from complex format to a
186  // phase / magnitude representation
187  argResidual.AddAll();
188  argResidual.UpdateData();
189 
190  // MRJ: We set the sampling rate for the segment
191  //segment.SetSamplingRate( pMatrix->GetValue( 0, 0 ) );
192  mSamplingRate = pMatrix->GetValue( 0, 0 );
193 
194  argResidual.SetSpectralRange(pMatrix->GetValue(0,0)*0.5);
195 
196  // move pointer to next matrix in frame
197  frameIt++;
198  pMatrix= dynamic_cast< SDIF::ConcreteMatrix<TFloat32>* >(*frameIt);
199  //pMatrix=pMatrix->mpNext;
200 
201  CLAM_ASSERT(pMatrix->Type() =="1STF","SDIFIn::Add 1STF Headerin Matrix expected");
202  argResidual.SetSize(pMatrix->Rows());
203  Array<Complex>& complexBuffer=argResidual.GetComplexArray();
204  for (int r=0;r<pMatrix->Rows();r++) //read in complex data
205  {
206  Complex tmpComplex(pMatrix->GetValue(r,0),pMatrix->GetValue(r,1));
207  complexBuffer[r] = tmpComplex;
208  }
209  }
210  /* its sinusoidal track data */
211  else if(tmpSDIFFrame.Type()=="1TRC" && mConfig.GetEnablePeakArray())
212  {
213  TIndex nElems = pMatrix->Rows();
214 
215  argSpectralPeaks.AddAll();
216  argSpectralPeaks.UpdateData();
217  SpectralPeakArray& tmpPeakArray = argSpectralPeaks;
218  tmpPeakArray.SetScale(EScale::eLinear);
219 
220  tmpPeakArray.SetnMaxPeaks(nElems); //number of peaks in the sdif file
221  tmpPeakArray.SetnPeaks(nElems); //number of peaks in the sdif file
222  tmpPeakArray.ResetIndices(); // resets all indeces, make valid..
223 
224  /* read file data into SpectralPeakArray */
225  DataArray& pkfreqBuffer=tmpPeakArray.GetFreqBuffer();
226  DataArray& pkmagBuffer=tmpPeakArray.GetMagBuffer();
227  DataArray& pkPhaseBuffer=tmpPeakArray.GetPhaseBuffer();
228  DataArray& pkBinPosBuffer=tmpPeakArray.GetBinPosBuffer();
229  DataArray& pkBinWidthBuffer=tmpPeakArray.GetBinWidthBuffer();
230  IndexArray& pkIndexArray=tmpPeakArray.GetIndexArray();
231  if(!mConfig.GetRelativePeakIndices())
232  {
233  for (int r=0;r<nElems;r++)
234  {
235 
236  // get frequency , mag and phase
237  pkfreqBuffer[r]=pMatrix->GetValue(r,1);
238  pkmagBuffer[r]=pMatrix->GetValue(r,2);
239  pkPhaseBuffer[r]=pMatrix->GetValue(r,3);
240  pkBinPosBuffer[r]=-1;
241  pkBinWidthBuffer[r]=-1;
242  pkIndexArray[r]=(int)pMatrix->GetValue(r,0) - 1; // -1 because SDIF doesnt allow Track 0
243  }
244  }
245  else
246  {
247  IndexArray tmpIndexArray;
248  for (int r=0;r<nElems;r++)
249  {
250 
251  // get frequency , mag and phase
252  pkfreqBuffer[r]=pMatrix->GetValue(r,1);
253  pkmagBuffer[r]=pMatrix->GetValue(r,2);
254  pkPhaseBuffer[r]=pMatrix->GetValue(r,3);
255  pkBinPosBuffer[r]=-1;
256  pkBinWidthBuffer[r]=-1;
257  if(mConfig.GetRelativePeakIndices())
258  {
259  pkIndexArray[r]=-1;
260  // track index and buffer it
261  int tempIndex = (int)pMatrix->GetValue(r,0) - 1; // -1 because SDIF doesnt allow Track 0
262  tmpIndexArray.AddElem(tempIndex);
263  }
264  }
265  /* compare new indizes with the previous
266  * the indizes of the current peakarray should hold
267  * then the related
268  * peak positions to the previous peakarray */
269 
270  TIndex nPeaks = tmpIndexArray.Size();
271  TIndex nPrevPeaks = mPrevIndexArray.Size();
272  TIndex currIndex,prevIndex;
273  bool bIndexFound=false;
274 
275  for (int i=0;i<nPeaks;i++)
276  {
277  bIndexFound=false;
278  currIndex = tmpIndexArray[i];
279 
280  for (int j=0;j<nPrevPeaks;j++)
281  {
282  prevIndex = mPrevIndexArray[j];
283  if (prevIndex==currIndex)
284  {
285  pkIndexArray[i]=j;
286  bIndexFound = true;
287  break;
288  }
289  }
290  if (!bIndexFound) pkIndexArray[i]=-1;
291  }
292 
293  /* current IndexArray becomes the Previous */
294  mPrevIndexArray = tmpIndexArray;
295  }
296  }
297 }
298 
300 {
301  return mpFile->Pos();
302 }
303 
304 void SDIFFileReader::SetReadPosition(int readPosition)
305 {
306  mpFile->Pos(readPosition);
307 }
308 
310 {
311  return mSamplingRate;
312 }
313 
315 {
316  return mLastCenterTime;
317 }
318 
319 } // namespace CLAM
320