CLAM-Development  1.4.0
SDIFOut.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 "SDIFOut.hxx"
23 #include "ErrOpenFile.hxx"
24 #include "SpectrumConfig.hxx"
25 #include "Frame.hxx"
26 #include "Segment.hxx"
27 #include "SpectralPeakArray.hxx"
28 #include "Fundamental.hxx"
29 #include "SDIFFile.hxx"
30 #include "SDIFFrame.hxx"
31 #include "SDIFMatrix.hxx"
32 #include "SpectralAnalysis.hxx"
33 
34 using namespace CLAM;
35 
36 
38 {
39  AddAll();
40  UpdateData();
41 
42  SetEnableResidual(true);
43  SetEnablePeakArray(true);
44  SetEnableFundFreq(true);
45  SetSpectralRange(22050);
46  SetMaxNumPeaks(100);
47  SetFileName("nofile");
48 
49  SetSamplingRate(44100);
50  SetFrameSize(1024);
51  SetSpectrumSize(513);
52 }
53 
55 mPrevIndexArray(0),
56 mInputFundamental("Fundamental", this),
57 mInputSinSpectralPeaks("Sinusoidal Peaks", this),
58 mInputResSpectrum("Residual Spectrum", this)
59 {
60  mpFile=NULL;
61  ConnectAndPublishPorts();
63 }
64 
66 mPrevIndexArray(0),
67 mInputFundamental("Fundamental", this),
68 mInputSinSpectralPeaks("Sinusoidal Peaks", this),
69 mInputResSpectrum("Residual Spectrum", this)
70 {
71  mpFile=NULL;
72 
73  ConnectAndPublishPorts();
74  Configure(c);
75 }
76 
78 {
79  mpFile->Close();
80  delete mpFile;
81 }
82 
83 void SDIFOut::ConnectAndPublishPorts()
84 {
87 }
88 
90 {
91 
92  if(mpFile) delete mpFile;
93  mpFile = new SDIF::File(mConfig.GetFileName().c_str(),SDIF::File::eOutput);
94 
95  try
96  {
97  mpFile->Open();
98  return true;
99  }
100  catch ( ErrOpenFile& e )
101  {
102  AddConfigErrorMessage("Inner exception thrown: File could not be opened");
104 
105  return false;
106  }
107 
108  return true;
109 }
110 
112 {
113  mpFile->Close();
114 
115  return true;
116 }
117 
118 bool SDIFOut::ConcreteConfigure(const ProcessingConfig& c)
119 {
120  CopyAsConcreteConfig(mConfig, c);
121 
122  return true;
123 }
124 
125 
127 {
128  return mConfig;
129 }
130 
132 {
133  //CLAM::Fundamental theFundamental = mInputFundamental.GetData();
135  CLAM::Spectrum residualSpectrum = mInputResSpectrum.GetData();
136 
137  //std::cout << "The fundamental is <" << theFundamental.GetFreq() << ">" << std::endl;
138 }
139 
140 bool SDIFOut::Do(const Frame& frame)
141 {
142  if(!mpFile) return false;
143 
144 //If enabled, first frame will contain fundamental frequency
145  if(mConfig.GetEnableFundFreq())
146  {
147  SDIF::Frame tmpSDIFFrame("1FQ0",frame.GetCenterTime(),0);
148  //Note: other Frame Header values could be set but are not available in segment data
150 
151  //First matrix to add to frame
152  pMatrix=new SDIF::ConcreteMatrix<TFloat32>("1FQ0",1,1);
153 
154  //We add fundamental frequency
155  pMatrix->SetValue(0,0,frame.GetFundamental().GetFreq());
156  tmpSDIFFrame.Add(pMatrix);
157  mpFile->Write(tmpSDIFFrame);
158  }
159 //If enabled, second frame will contain residual spectrum
160  if(mConfig.GetEnableResidual())
161  {
162  SDIF::Frame tmpSDIFFrame("1STF",frame.GetCenterTime(),1);
163 
165  //First matrix to add to frame
166  pMatrix=new SDIF::ConcreteMatrix<TFloat32>("ISTF",1,3);
167 
168  pMatrix->SetValue(0,0,mConfig.GetSamplingRate());
169  pMatrix->SetValue(0,1,mConfig.GetFrameSize());
170  pMatrix->SetValue(0,2,mConfig.GetSpectrumSize());
171  tmpSDIFFrame.Add(pMatrix);
172  //Next matrix
173 
174 
175  pMatrix=new SDIF::ConcreteMatrix<TFloat32>("1STF",frame.GetResidualSpec().GetSize(),2);
176 
177  //We have to convert residual spectrum to complex
178  SpectrumConfig Scfg;
179  SpecTypeFlags sflags;
180  frame.GetResidualSpec().GetType(sflags);
181  if(!sflags.bComplex )
182  {
183  sflags.bComplex = 1;
184  frame.GetResidualSpec().SetTypeSynchronize(sflags);
185  }
186  //SDIF only accepts linear data
187  frame.GetResidualSpec().ToLinear();
188 
189  Array<Complex>& complexBuffer=frame.GetResidualSpec().GetComplexArray();
190  for (int r=0;r<pMatrix->Rows();r++) //Write in complex data
191  {
192  pMatrix->SetValue(r,0,complexBuffer[r].Real());
193  pMatrix->SetValue(r,1,complexBuffer[r].Imag());
194  }
195  tmpSDIFFrame.Add(pMatrix);
196  mpFile->Write(tmpSDIFFrame);
197  }
198 //If enabled, third frame will contain sinusoidal spectral peaks
199  if(mConfig.GetEnablePeakArray())
200  {
201  SpectralPeakArray& tmpPeakArray=frame.GetSpectralPeakArray();
202  //SDIF only accepts linear data
203  tmpPeakArray.ToLinear();
204 
205  SDIF::Frame tmpSDIFFrame("1TRC",frame.GetCenterTime(),2);
206 
207  int nElems=tmpPeakArray.GetnPeaks();
208 
210 
211  //First matrix to add to frame
212  pMatrix=new SDIF::ConcreteMatrix<TFloat32>("1TRC",nElems,4);
213  DataArray& pkfreqBuffer=tmpPeakArray.GetFreqBuffer();
214  DataArray& pkmagBuffer=tmpPeakArray.GetMagBuffer();
215  DataArray& pkPhaseBuffer=tmpPeakArray.GetPhaseBuffer();
216  //Unused variable: DataArray& pkBinPosBuffer=tmpPeakArray.GetBinPosBuffer();
217  //Unused variable: DataArray& pkBinWidthBuffer=tmpPeakArray.GetBinWidthBuffer();
218  IndexArray& pkIndexArray=tmpPeakArray.GetIndexArray();
219 
220  for (int r=0;r<nElems;r++)
221  {
222  //write track index
223  pMatrix->SetValue(r,0,pkIndexArray[r]+1); // +1 because SDIF doesnt allow Track 0
224  // write frequency , mag and phase
225  pMatrix->SetValue(r,1,pkfreqBuffer[r]);
226  pMatrix->SetValue(r,2,pkmagBuffer[r]);
227  pMatrix->SetValue(r,3,pkPhaseBuffer[r]);
228  /* cannot store binpos and binwidth in SDIF?
229  pkBinPosBuffer[r];
230  pkBinWidthBuffer[r];*/
231  }
232  tmpSDIFFrame.Add(pMatrix);
233  mpFile->Write(tmpSDIFFrame);
234  }
235  return true;
236 }
237