CLAM-Development
1.1
|
00001 /* 00002 * Copyright (c) 2001-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 "Frame.hxx" 00023 #include "Segment.hxx" 00024 #include "Fundamental.hxx" 00025 #include "SpectrumConfig.hxx" 00026 #include "SMSAnalysisCore.hxx" 00027 #include "ProcessingFactory.hxx" 00028 00029 namespace CLAM 00030 { 00031 namespace Hidden 00032 { 00033 static const char * metadata[] = { 00034 "key", "SMSAnalysisCore", 00035 "category", "Analysis", 00036 "description", "SMSAnalysisCore", 00037 0 00038 }; 00039 static FactoryRegistrator<ProcessingFactory, SMSAnalysisCore> reg = metadata; 00040 } 00041 00042 00043 SMSAnalysisCore::SMSAnalysisCore() 00044 : mInputAudio("Input Audio",this ), 00045 mOutputResSpectrum("Residual Branch Spectrum",this ), 00046 mOutputSinSpectrum("Sinusoidal Branch Spectrum",this ), 00047 mOutputSpectralPeaks("Sinusoidal Peaks",this ), 00048 mOutputFundamental("Fundamental",this ), 00049 mOutputSubstractedSpectrum("Residual Spectrum", this ) 00050 { 00051 AttachChildren(); 00052 ConnectAndPublishPorts(); 00053 Configure(SMSAnalysisConfig()); 00054 } 00055 00056 SMSAnalysisCore::SMSAnalysisCore(SMSAnalysisConfig& cfg) 00057 : mInputAudio("Input Audio",this ), 00058 mOutputResSpectrum("Residual Branch Spectrum",this ), 00059 mOutputSinSpectrum("Sinusoidal Branch Spectrum",this ), 00060 mOutputSpectralPeaks("Sinusoidal Peaks",this ), 00061 mOutputFundamental("Fundamental",this ), 00062 mOutputSubstractedSpectrum("Residual Spectrum", this ) 00063 { 00064 AttachChildren(); 00065 ConnectAndPublishPorts(); 00066 Configure(cfg); 00067 } 00068 00069 00070 00071 SMSAnalysisCore::~SMSAnalysisCore() 00072 { 00073 } 00074 00075 bool SMSAnalysisCore::ConcreteConfigure(const ProcessingConfig& cfg) 00076 { 00077 CopyAsConcreteConfig(mConfig,cfg); 00078 ConfigureChildren(); 00079 ConfigureData(); 00080 return true; 00081 } 00082 00083 00084 bool SMSAnalysisCore::ConfigureChildren() 00085 { 00086 mSinSpectralAnalysis.Configure(mConfig.GetSinSpectralAnalysis()); 00087 mResSpectralAnalysis.Configure(mConfig.GetResSpectralAnalysis()); 00088 mPeakDetect.Configure(mConfig.GetPeakDetect()); 00089 mFundDetect.Configure(mConfig.GetFundFreqDetect()); 00090 mSinTracking.Configure(mConfig.GetSinTracking()); 00091 mSynthSineSpectrum.Configure(mConfig.GetSynthSineSpectrum()); 00092 00093 /*Initializing and configuring member circular buffers*/ 00094 00095 TSize frameSize=mConfig.GetHopSize(); 00096 TSize sinWindowSize=mConfig.GetSinWindowSize(); 00097 TSize resWindowSize=mConfig.GetResWindowSize(); 00098 00099 mSinSpectralAnalysis.GetInPort("Input").SetSize( sinWindowSize - 1 ); 00100 mSinSpectralAnalysis.GetInPort("Input").SetHop( frameSize ); 00101 mResSpectralAnalysis.GetInPort("Input").SetSize( resWindowSize - 1 ); 00102 mResSpectralAnalysis.GetInPort("Input").SetHop( frameSize ); 00103 00104 return true; 00105 00106 } 00107 00108 void SMSAnalysisCore::ConfigureData() 00109 { 00110 // XR: TODO - Get Sampling Rate from input audio? 00111 //Unused variable: TData samplingRate=mConfig.GetSamplingRate(); 00112 00113 Spectrum resSpec; 00114 Spectrum sinSpec; 00115 00116 // Spectrum used for temporary residual analysis 00117 SpectrumConfig scfg; 00118 scfg.SetSize(mConfig.GetResSpectralAnalysis().GetFFT().GetAudioSize()/2+1); // s.AudioFrameSize is the size of the generated frames 00119 scfg.SetSpectralRange(mConfig.GetSamplingRate()*0.5); 00120 resSpec.Configure(scfg); 00121 00122 00123 // Spectrum used for temporary sinusoidal analysis 00124 scfg.SetSize(mConfig.GetSinSpectralAnalysis().GetFFT().GetAudioSize()/2+1); 00125 sinSpec.Configure(scfg); 00126 00127 /* Now we set prototype of SpectrumSubstracter: we want to substract two spectrums: 00128 the first on in MagPhase format, the second in Complex format and get the result back 00129 in Mag Phase.*/ 00130 00131 SpectrumConfig Scfg; 00132 SpecTypeFlags sflags; 00133 sflags.bComplex = 1; 00134 sflags.bPolar = 0; 00135 sflags.bMagPhase = 0; 00136 sflags.bMagPhaseBPF = 0; 00137 Scfg.SetType(sflags); 00138 Scfg.SetSize(resSpec.GetSize()); 00139 Scfg.SetSpectralRange(mConfig.GetSamplingRate()*0.5); 00140 Spectrum tmpSpecIn(Scfg); 00141 00142 mSpecSubstracter.SetPrototypes(resSpec,tmpSpecIn,resSpec); 00143 } 00144 00145 void SMSAnalysisCore::AttachChildren() 00146 { 00147 mSinSpectralAnalysis.SetParent(this); 00148 mResSpectralAnalysis.SetParent(this); 00149 mPeakDetect.SetParent(this); 00150 mFundDetect.SetParent(this); 00151 mSinTracking.SetParent(this); 00152 mSynthSineSpectrum.SetParent( this ); 00153 mSpecSubstracter.SetParent(this); 00154 } 00155 00156 bool SMSAnalysisCore::ConcreteStart() 00157 { 00158 CLAM_ASSERT( mSinSpectralAnalysis.GetInPort("Input").GetVisuallyConnectedOutPort(), 00159 "SMSAnalysisCore::ConcreteStart in port 'Input' needs an attached out port, to start"); 00160 00161 // TODO: port sizes negitiation should be managed by the flow control 00162 if (mSinSpectralAnalysis.GetInPort("Input").GetVisuallyConnectedOutPort()->GetSize()%2!=0) 00163 { 00164 00165 int sinSize = mSinSpectralAnalysis.GetInPort("Input").GetSize(); 00166 mSinSpectralAnalysis.GetInPort("Input").GetVisuallyConnectedOutPort()->SetSize( sinSize ); 00167 std::cout << "SMSAnalysisCore::ConcreteStart() Alert!! setting size mSinSpec... : "<< sinSize <<"\n"; 00168 00169 mSinSpectralAnalysis.GetInPort("Input").GetVisuallyConnectedOutPort()->SetHop( sinSize ); 00170 00171 // mInputAudio.GetVisuallyConnectedOutPort()->SetSize( mInputAudio.GetSize() ); 00172 // mInputAudio.GetVisuallyConnectedOutPort()->SetHop( mInputAudio.GetSize() ); 00173 } 00174 00175 // mSinSpectralAnalysis.GetInPort("Input").GetVisuallyConnectedOutPort()->CenterEvenRegions(); 00176 mInputAudio.GetVisuallyConnectedOutPort()->CenterEvenRegions(); 00177 00178 return ProcessingComposite::ConcreteStart(); 00179 } 00180 00181 bool SMSAnalysisCore::Do() 00182 { 00183 if( mSinSpectralAnalysis.CanConsumeAndProduce() && mResSpectralAnalysis.CanConsumeAndProduce() ) 00184 { 00185 mSinSpectralAnalysis.Do(); 00186 mResSpectralAnalysis.Do(); 00187 00188 CLAM_DEBUG_ASSERT( mPeakDetect.CanConsumeAndProduce(), 00189 "SMSAnalysisCore::Do() mPeakDetect should have data feeded"); 00190 mPeakDetect.Do(); 00191 00192 CLAM_DEBUG_ASSERT( mFundDetect.CanConsumeAndProduce(), 00193 "SMSAnalysisCore::Do() mFundDetect should have data feeded"); 00194 mFundDetect.Do(); 00195 00196 CLAM_DEBUG_ASSERT( mSinTracking.CanConsumeAndProduce(), 00197 "SMSAnalysisCore::Do() mSinTracking should have data feeded"); 00198 mSinTracking.Do(); 00199 00200 CLAM_DEBUG_ASSERT( mSynthSineSpectrum.CanConsumeAndProduce(), 00201 "SMSAnalysisCore::Do() mSynthSineSpectrum should have data feeded"); 00202 mSynthSineSpectrum.Do(); 00203 00204 CLAM_DEBUG_ASSERT( mSpecSubstracter.CanConsumeAndProduce(), 00205 "SMSAnalysisCore::Do() specSubstracter should have data feeded"); 00206 mSpecSubstracter.Do(); 00207 00208 return true; 00209 } 00210 00211 return false; 00212 } 00213 00214 void SMSAnalysisCore::ConnectAndPublishPorts() 00215 { 00216 mInputAudio.PublishInPort( mSinSpectralAnalysis.GetInPort("Input")); 00217 mInputAudio.PublishInPort( mResSpectralAnalysis.GetInPort("Input")); 00218 00219 mSinSpectralAnalysis.GetOutPort("Output").ConnectToIn( mPeakDetect.GetInPort("Input spectrum")); 00220 mPeakDetect.GetOutPort( "Output spectral peak array" ).ConnectToIn( mFundDetect.GetInPort("Input")); 00221 mPeakDetect.GetOutPort( "Output spectral peak array" ).ConnectToIn( mSinTracking.GetInPort( "Input" )); 00222 mFundDetect.GetOutControl( "Fund Freq Value").AddLink( mSinTracking.GetInControl( "Fund Freq Value" )); 00223 mSinTracking.GetOutPort( "Output").ConnectToIn( mSynthSineSpectrum.GetInPort( "Input" )); 00224 00225 mResSpectralAnalysis.GetOutPort("Output").ConnectToIn( mSpecSubstracter.GetInPort( "Input 1")); 00226 mSynthSineSpectrum.GetOutPort("Output").ConnectToIn( mSpecSubstracter.GetInPort( "Input 2")); 00227 00228 mOutputResSpectrum.PublishOutPort( mResSpectralAnalysis.GetOutPort("Output") ); 00229 mOutputSinSpectrum.PublishOutPort( mSinSpectralAnalysis.GetOutPort("Output") ); 00230 mOutputSpectralPeaks.PublishOutPort( mSinTracking.GetOutPort( "Output") ); 00231 mOutputFundamental.PublishOutPort( mFundDetect.GetOutPort( "Output" ) ); 00232 mOutputSubstractedSpectrum.PublishOutPort( mSpecSubstracter.GetOutPort( "Output") ); 00233 } 00234 00235 } // namespace CLAM 00236 00237