SMSAnalysis.cxx

Go to the documentation of this file.
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 "Audio.hxx"
00023 #include "Frame.hxx"
00024 #include "Segment.hxx"
00025 #include "Fundamental.hxx"
00026 #include "SpectrumConfig.hxx"
00027 #include "SMSAnalysis.hxx"
00028 
00029 namespace CLAM
00030 {
00031 
00032 SMSAnalysis::SMSAnalysis()
00033         : mAudioProvider( "Audio provider", 0 )
00034 {
00035         mAudioProvider.ConnectToIn( mCore.GetInPort( "Input Audio" ));
00036         AttachChildren();
00037         Configure(SMSAnalysisConfig());
00038 }
00039 
00040 SMSAnalysis::SMSAnalysis(SMSAnalysisConfig& cfg)
00041         : mAudioProvider( "Audio provider", 0 )
00042 {
00043         AttachChildren();
00044         Configure(cfg);
00045 }
00046 
00047 SMSAnalysis::~SMSAnalysis()
00048 {
00049 }
00050 
00051 bool SMSAnalysis::ConcreteConfigure(const ProcessingConfig& cfg)
00052 {
00053         CopyAsConcreteConfig(mConfig,cfg);
00054         ConfigureChildren();
00055         ConfigureData();
00056         return true;
00057 }
00058 
00059 
00060 bool SMSAnalysis::ConfigureChildren()
00061 {
00062         mCore.Configure( mConfig );
00063         return true;
00064 
00065 }
00066 
00067 void SMSAnalysis::ConfigureData()
00068 {
00069         mAudioFrameIndex=0;
00070         
00071         mAudioProvider.SetSize( mConfig.GetHopSize() );
00072         mAudioProvider.SetHop( mConfig.GetHopSize() );
00073 }
00074 
00075 void SMSAnalysis::AttachChildren()
00076 {
00077         mCore.SetParent( this );
00078 }
00079 
00080 bool SMSAnalysis::ConcreteStart()
00081 {
00082         //we have to initialize internal counter
00083         mAudioFrameIndex=0;
00084         return ProcessingComposite::ConcreteStart();
00085 }
00086 
00087 bool SMSAnalysis::Do()
00088 {
00089         return mCore.Do();
00090 }
00091 
00092 bool SMSAnalysis::Do(Frame& in)
00093 {
00094         InitFrame(in);
00095 
00096         //we set spectrum size and fundamental number of candidates
00097         in.GetSpectrum().SetSize(mConfig.GetSinSpectralAnalysis().GetFFT().GetAudioSize()/2+1);
00098         in.GetFundamental().SetnMaxCandidates(1);
00099 
00100         bool result=false;
00101 
00102         if(mAudioProvider.CanProduce())
00103         {
00104                 
00105                 mAudioProvider.SetSampleRate( in.GetAudioFrame().GetSampleRate() );
00106                 mAudioProvider.GetAudio().GetBuffer() = in.GetAudioFrame().GetBuffer();
00107                 mAudioProvider.Produce();
00108         }
00109 
00110         if(mCore.CanConsumeAndProduce())
00111                 result = mCore.Do();
00112         else
00113                 return false;
00114 
00115         OutPortBase & outSinSpectrum  = mCore.GetOutPort("Sinusoidal Branch Spectrum");
00116         in.GetSinusoidalAnalSpectrum() =  dynamic_cast<OutPortPublisher<Spectrum>&>(outSinSpectrum).GetLastWrittenData();
00117 
00118         OutPortBase & outResSpectrum  = mCore.GetOutPort("Residual Spectrum");
00119         in.GetResidualSpec() =  dynamic_cast<OutPortPublisher<Spectrum>&>(outResSpectrum).GetLastWrittenData();
00120 
00121         OutPortBase & outSpectrum  = mCore.GetOutPort("Residual Branch Spectrum");
00122         in.GetSpectrum() =  dynamic_cast<OutPortPublisher<Spectrum>&>(outSpectrum).GetLastWrittenData();
00123 
00124         OutPortBase & fundamental  = mCore.GetOutPort("Fundamental");
00125         in.GetFundamental() =  dynamic_cast<OutPortPublisher<Fundamental>&>(fundamental).GetLastWrittenData();
00126 
00127         OutPortBase & peaks  = mCore.GetOutPort("Sinusoidal Peaks");
00128         in.GetSpectralPeakArray() = dynamic_cast<OutPortPublisher<SpectralPeakArray>&>(peaks).GetLastWrittenData();
00129 
00130         // MRJ: Let's check the poscondition...
00131         CLAM_DEBUG_ASSERT( in.GetResidualSpec().GetSpectralRange() > 0, 
00132                            "Residual spectrum is not being properly configured" );
00133 
00134         if (result) // TODO: refactor
00135                 //if we have been able to analyze something we set whether frame is voiced or not
00136                 in.SetIsHarmonic(in.GetFundamental().GetFreq(0)>0);
00137         return result;
00138 }
00139 
00140 bool SMSAnalysis::Do(Segment& in)
00141 {
00142         //first we compute necessary sizes, indices and parameters
00143         TIndex frameIndex=in.mCurrentFrameIndex;
00144         int step=mConfig.GetHopSize();
00145         TData samplingRate=mConfig.GetSamplingRate();
00146         TTime frameCenterTime=frameIndex*step/samplingRate;
00147         //Audio center time is different from frame center time. This index corresponds to
00148         //the audio that is being written into member stream buffer
00149         TIndex audioCenterSample=(mAudioFrameIndex)*step;
00150         //Unused variable: TTime audioCenterTime=audioCenterSample/samplingRate;
00151         
00153         //If we have reached end of input audio we return false
00154         if(frameCenterTime>in.GetAudio().GetDuration()*0.001)
00155                 return false;
00156 
00157         tmpFrame.SetDuration(step/samplingRate);
00158         tmpFrame.SetCenterTime(TData(frameCenterTime));
00159         tmpFrame.AddAudioFrame();
00160         tmpFrame.UpdateData();
00161         tmpFrame.GetAudioFrame().SetBeginTime(((float)frameIndex - 0.5f)*step/samplingRate);
00162         tmpFrame.GetAudioFrame().SetSampleRate(in.GetAudio().GetSampleRate());
00163         
00164         /*      Note: Here we are just taking the "new" audio belonging to each frame. That is, the
00165         HopSize samples centered around CenterTime */
00166         in.GetAudio().GetAudioChunk(audioCenterSample-step/2,audioCenterSample+step/2,
00167                 tmpFrame.GetAudioFrame(),true);
00168         
00169         //we have taken a new audio chunk and must increment internal counter
00170         mAudioFrameIndex++;
00171         
00172         //tmpFrame.SetAudioFrame(tmpAudio);
00173         bool hasProcessed=Do(tmpFrame);
00174         
00175         if(hasProcessed)
00176         {//we have been able to do an analysis and write the result into tmpFrame's attributes
00177                 in.mCurrentFrameIndex++;
00178                 in.AddFrame(tmpFrame);
00179         }
00180 
00181         return true;
00182 }
00183 
00184 void SMSAnalysis::InitFrame(Frame& in)
00185 {
00186         //We add necessary attributes to input frame
00187         if ( !in.HasSpectrum() )
00188                 in.AddSpectrum();
00189         if ( !in.HasSpectralPeakArray() )
00190                 in.AddSpectralPeakArray();
00191         if ( !in.HasFundamental() )
00192                 in.AddFundamental();
00193         if ( !in.HasResidualSpec() )
00194                 in.AddResidualSpec();
00195         if ( !in.HasIsHarmonic() )
00196                 in.AddIsHarmonic();
00197         if ( !in.HasSinusoidalAnalSpectrum() )
00198                 in.AddSinusoidalAnalSpectrum();
00199 
00200         in.UpdateData();
00201 }
00202 
00203 } // namespace CLAM
00204 
Generated by  doxygen 1.6.3