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 "SDIFOut.hxx" 00023 #include "ErrOpenFile.hxx" 00024 #include "SpectrumConfig.hxx" 00025 #include "Frame.hxx" 00026 #include "Segment.hxx" 00027 #include "SpectralPeakArray.hxx" 00028 #include "Fundamental.hxx" 00029 #include "SDIFFile.hxx" 00030 #include "SDIFFrame.hxx" 00031 #include "SDIFMatrix.hxx" 00032 #include "SpectralAnalysis.hxx" 00033 00034 using namespace CLAM; 00035 00036 00037 void SDIFOutConfig::DefaultInit() 00038 { 00039 AddAll(); 00040 UpdateData(); 00041 00042 SetEnableResidual(true); 00043 SetEnablePeakArray(true); 00044 SetEnableFundFreq(true); 00045 SetSpectralRange(22050); 00046 SetMaxNumPeaks(100); 00047 SetFileName("nofile"); 00048 00049 SetSamplingRate(44100); 00050 SetFrameSize(1024); 00051 SetSpectrumSize(513); 00052 } 00053 00054 SDIFOut::SDIFOut(): 00055 mPrevIndexArray(0), 00056 mInputFundamental("Fundamental", this), 00057 mInputSinSpectralPeaks("Sinusoidal Peaks", this), 00058 mInputResSpectrum("Residual Spectrum", this) 00059 { 00060 mpFile=NULL; 00061 ConnectAndPublishPorts(); 00062 Configure(SDIFOutConfig()); 00063 } 00064 00065 SDIFOut::SDIFOut(const SDIFOutConfig& c): 00066 mPrevIndexArray(0), 00067 mInputFundamental("Fundamental", this), 00068 mInputSinSpectralPeaks("Sinusoidal Peaks", this), 00069 mInputResSpectrum("Residual Spectrum", this) 00070 { 00071 mpFile=NULL; 00072 00073 ConnectAndPublishPorts(); 00074 Configure(c); 00075 } 00076 00077 SDIFOut::~SDIFOut() 00078 { 00079 mpFile->Close(); 00080 delete mpFile; 00081 } 00082 00083 void SDIFOut::ConnectAndPublishPorts() 00084 { 00085 RegisterInPort( &mInputSinSpectralPeaks ); 00086 RegisterInPort( &mInputResSpectrum ); 00087 } 00088 00089 bool SDIFOut::ConcreteStart() 00090 { 00091 00092 if(mpFile) delete mpFile; 00093 mpFile = new SDIF::File(mConfig.GetFileName().c_str(),SDIF::File::eOutput); 00094 00095 try 00096 { 00097 mpFile->Open(); 00098 return true; 00099 } 00100 catch ( ErrOpenFile& e ) 00101 { 00102 AddConfigErrorMessage("Inner exception thrown: File could not be opened"); 00103 AddConfigErrorMessage( e.what() ); 00104 00105 return false; 00106 } 00107 00108 return true; 00109 } 00110 00111 bool SDIFOut::ConcreteStop() 00112 { 00113 mpFile->Close(); 00114 00115 return true; 00116 } 00117 00118 bool SDIFOut::ConcreteConfigure(const ProcessingConfig& c) 00119 { 00120 CopyAsConcreteConfig(mConfig, c); 00121 00122 return true; 00123 } 00124 00125 00126 const ProcessingConfig& SDIFOut::GetConfig() const 00127 { 00128 return mConfig; 00129 } 00130 00131 bool SDIFOut::Do() 00132 { 00133 //CLAM::Fundamental theFundamental = mInputFundamental.GetData(); 00134 CLAM::SpectralPeakArray sinePeaks = mInputSinSpectralPeaks.GetData(); 00135 CLAM::Spectrum residualSpectrum = mInputResSpectrum.GetData(); 00136 00137 //std::cout << "The fundamental is <" << theFundamental.GetFreq() << ">" << std::endl; 00138 } 00139 00140 bool SDIFOut::Do(const Frame& frame) 00141 { 00142 if(!mpFile) return false; 00143 00144 //If enabled, first frame will contain fundamental frequency 00145 if(mConfig.GetEnableFundFreq()) 00146 { 00147 SDIF::Frame tmpSDIFFrame("1FQ0",frame.GetCenterTime(),0); 00148 //Note: other Frame Header values could be set but are not available in segment data 00149 SDIF::ConcreteMatrix<TFloat32>* pMatrix; 00150 00151 //First matrix to add to frame 00152 pMatrix=new SDIF::ConcreteMatrix<TFloat32>("1FQ0",1,1); 00153 00154 //We add fundamental frequency 00155 pMatrix->SetValue(0,0,frame.GetFundamental().GetFreq()); 00156 tmpSDIFFrame.Add(pMatrix); 00157 mpFile->Write(tmpSDIFFrame); 00158 } 00159 //If enabled, second frame will contain residual spectrum 00160 if(mConfig.GetEnableResidual()) 00161 { 00162 SDIF::Frame tmpSDIFFrame("1STF",frame.GetCenterTime(),1); 00163 00164 SDIF::ConcreteMatrix<TFloat32>* pMatrix; 00165 //First matrix to add to frame 00166 pMatrix=new SDIF::ConcreteMatrix<TFloat32>("ISTF",1,3); 00167 00168 pMatrix->SetValue(0,0,mConfig.GetSamplingRate()); 00169 pMatrix->SetValue(0,1,mConfig.GetFrameSize()); 00170 pMatrix->SetValue(0,2,mConfig.GetSpectrumSize()); 00171 tmpSDIFFrame.Add(pMatrix); 00172 //Next matrix 00173 00174 00175 pMatrix=new SDIF::ConcreteMatrix<TFloat32>("1STF",frame.GetResidualSpec().GetSize(),2); 00176 00177 //We have to convert residual spectrum to complex 00178 SpectrumConfig Scfg; 00179 SpecTypeFlags sflags; 00180 frame.GetResidualSpec().GetType(sflags); 00181 if(!sflags.bComplex ) 00182 { 00183 sflags.bComplex = 1; 00184 frame.GetResidualSpec().SetTypeSynchronize(sflags); 00185 } 00186 //SDIF only accepts linear data 00187 frame.GetResidualSpec().ToLinear(); 00188 00189 Array<Complex>& complexBuffer=frame.GetResidualSpec().GetComplexArray(); 00190 for (int r=0;r<pMatrix->Rows();r++) //Write in complex data 00191 { 00192 pMatrix->SetValue(r,0,complexBuffer[r].Real()); 00193 pMatrix->SetValue(r,1,complexBuffer[r].Imag()); 00194 } 00195 tmpSDIFFrame.Add(pMatrix); 00196 mpFile->Write(tmpSDIFFrame); 00197 } 00198 //If enabled, third frame will contain sinusoidal spectral peaks 00199 if(mConfig.GetEnablePeakArray()) 00200 { 00201 SpectralPeakArray& tmpPeakArray=frame.GetSpectralPeakArray(); 00202 //SDIF only accepts linear data 00203 tmpPeakArray.ToLinear(); 00204 00205 SDIF::Frame tmpSDIFFrame("1TRC",frame.GetCenterTime(),2); 00206 00207 int nElems=tmpPeakArray.GetnPeaks(); 00208 00209 SDIF::ConcreteMatrix<TFloat32>* pMatrix; 00210 00211 //First matrix to add to frame 00212 pMatrix=new SDIF::ConcreteMatrix<TFloat32>("1TRC",nElems,4); 00213 DataArray& pkfreqBuffer=tmpPeakArray.GetFreqBuffer(); 00214 DataArray& pkmagBuffer=tmpPeakArray.GetMagBuffer(); 00215 DataArray& pkPhaseBuffer=tmpPeakArray.GetPhaseBuffer(); 00216 //Unused variable: DataArray& pkBinPosBuffer=tmpPeakArray.GetBinPosBuffer(); 00217 //Unused variable: DataArray& pkBinWidthBuffer=tmpPeakArray.GetBinWidthBuffer(); 00218 IndexArray& pkIndexArray=tmpPeakArray.GetIndexArray(); 00219 00220 for (int r=0;r<nElems;r++) 00221 { 00222 //write track index 00223 pMatrix->SetValue(r,0,pkIndexArray[r]+1); // +1 because SDIF doesnt allow Track 0 00224 // write frequency , mag and phase 00225 pMatrix->SetValue(r,1,pkfreqBuffer[r]); 00226 pMatrix->SetValue(r,2,pkmagBuffer[r]); 00227 pMatrix->SetValue(r,3,pkPhaseBuffer[r]); 00228 /* cannot store binpos and binwidth in SDIF? 00229 pkBinPosBuffer[r]; 00230 pkBinWidthBuffer[r];*/ 00231 } 00232 tmpSDIFFrame.Add(pMatrix); 00233 mpFile->Write(tmpSDIFFrame); 00234 } 00235 return true; 00236 } 00237