CLAM-Development  1.4.0
SMSAnalysis.cxx
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2001-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 "Audio.hxx"
23 #include "Frame.hxx"
24 #include "Segment.hxx"
25 #include "Fundamental.hxx"
26 #include "SpectrumConfig.hxx"
27 #include "SMSAnalysis.hxx"
28 
29 namespace CLAM
30 {
31 
33  : mAudioProvider( "Audio provider", 0 )
34 {
35  mAudioProvider.ConnectToIn( mCore.GetInPort( "Input Audio" ));
36  AttachChildren();
38 }
39 
41  : mAudioProvider( "Audio provider", 0 )
42 {
43  AttachChildren();
44  Configure(cfg);
45 }
46 
48 {
49 }
50 
51 bool SMSAnalysis::ConcreteConfigure(const ProcessingConfig& cfg)
52 {
53  CopyAsConcreteConfig(mConfig,cfg);
54  ConfigureChildren();
55  ConfigureData();
56  return true;
57 }
58 
59 
60 bool SMSAnalysis::ConfigureChildren()
61 {
62  mCore.Configure( mConfig );
63  return true;
64 
65 }
66 
67 void SMSAnalysis::ConfigureData()
68 {
69  mAudioFrameIndex=0;
70 
71  mAudioProvider.SetSize( mConfig.GetHopSize() );
72  mAudioProvider.SetHop( mConfig.GetHopSize() );
73 }
74 
75 void SMSAnalysis::AttachChildren()
76 {
77  mCore.SetParent( this );
78 }
79 
81 {
82  //we have to initialize internal counter
83  mAudioFrameIndex=0;
85 }
86 
88 {
89  return mCore.Do();
90 }
91 
93 {
94  InitFrame(in);
95 
96  //we set spectrum size and fundamental number of candidates
97  in.GetSpectrum().SetSize(mConfig.GetSinSpectralAnalysis().GetFFT().GetAudioSize()/2+1);
98  in.GetFundamental().SetnMaxCandidates(1);
99 
100  bool result=false;
101 
102  if(mAudioProvider.CanProduce())
103  {
104 
105  mAudioProvider.SetSampleRate( in.GetAudioFrame().GetSampleRate() );
106  mAudioProvider.GetAudio().GetBuffer() = in.GetAudioFrame().GetBuffer();
107  mAudioProvider.Produce();
108  }
109 
110  if(mCore.CanConsumeAndProduce())
111  result = mCore.Do();
112  else
113  return false;
114 
115  OutPortBase & outSinSpectrum = mCore.GetOutPort("Sinusoidal Branch Spectrum");
116  in.GetSinusoidalAnalSpectrum() = dynamic_cast<OutPortPublisher<Spectrum>&>(outSinSpectrum).GetLastWrittenData();
117 
118  OutPortBase & outResSpectrum = mCore.GetOutPort("Residual Spectrum");
119  in.GetResidualSpec() = dynamic_cast<OutPortPublisher<Spectrum>&>(outResSpectrum).GetLastWrittenData();
120 
121  OutPortBase & outSpectrum = mCore.GetOutPort("Residual Branch Spectrum");
122  in.GetSpectrum() = dynamic_cast<OutPortPublisher<Spectrum>&>(outSpectrum).GetLastWrittenData();
123 
124  OutPortBase & fundamental = mCore.GetOutPort("Fundamental");
125  in.GetFundamental() = dynamic_cast<OutPortPublisher<Fundamental>&>(fundamental).GetLastWrittenData();
126 
127  OutPortBase & peaks = mCore.GetOutPort("Sinusoidal Peaks");
128  in.GetSpectralPeakArray() = dynamic_cast<OutPortPublisher<SpectralPeakArray>&>(peaks).GetLastWrittenData();
129 
130  // MRJ: Let's check the poscondition...
131  CLAM_DEBUG_ASSERT( in.GetResidualSpec().GetSpectralRange() > 0,
132  "Residual spectrum is not being properly configured" );
133 
134  if (result) // TODO: refactor
135  //if we have been able to analyze something we set whether frame is voiced or not
136  in.SetIsHarmonic(in.GetFundamental().GetFreq(0)>0);
137  return result;
138 }
139 
141 {
142  //first we compute necessary sizes, indices and parameters
143  TIndex frameIndex=in.mCurrentFrameIndex;
144  int step=mConfig.GetHopSize();
145  TData samplingRate=mConfig.GetSamplingRate();
146  TTime frameCenterTime=frameIndex*step/samplingRate;
147  //Audio center time is different from frame center time. This index corresponds to
148  //the audio that is being written into member stream buffer
149  TIndex audioCenterSample=(mAudioFrameIndex)*step;
150  //Unused variable: TTime audioCenterTime=audioCenterSample/samplingRate;
151 
153  //If we have reached end of input audio we return false
154  if(frameCenterTime>in.GetAudio().GetDuration()*0.001)
155  return false;
156 
157  tmpFrame.SetDuration(step/samplingRate);
158  tmpFrame.SetCenterTime(TData(frameCenterTime));
159  tmpFrame.AddAudioFrame();
160  tmpFrame.UpdateData();
161  tmpFrame.GetAudioFrame().SetBeginTime(((float)frameIndex - 0.5f)*step/samplingRate);
162  tmpFrame.GetAudioFrame().SetSampleRate(in.GetAudio().GetSampleRate());
163 
164  /* Note: Here we are just taking the "new" audio belonging to each frame. That is, the
165  HopSize samples centered around CenterTime */
166  in.GetAudio().GetAudioChunk(audioCenterSample-step/2,audioCenterSample+step/2,
167  tmpFrame.GetAudioFrame(),true);
168 
169  //we have taken a new audio chunk and must increment internal counter
170  mAudioFrameIndex++;
171 
172  //tmpFrame.SetAudioFrame(tmpAudio);
173  bool hasProcessed=Do(tmpFrame);
174 
175  if(hasProcessed)
176  {//we have been able to do an analysis and write the result into tmpFrame's attributes
177  in.mCurrentFrameIndex++;
178  in.AddFrame(tmpFrame);
179  }
180 
181  return true;
182 }
183 
184 void SMSAnalysis::InitFrame(Frame& in)
185 {
186  //We add necessary attributes to input frame
187  if ( !in.HasSpectrum() )
188  in.AddSpectrum();
189  if ( !in.HasSpectralPeakArray() )
190  in.AddSpectralPeakArray();
191  if ( !in.HasFundamental() )
192  in.AddFundamental();
193  if ( !in.HasResidualSpec() )
194  in.AddResidualSpec();
195  if ( !in.HasIsHarmonic() )
196  in.AddIsHarmonic();
197  if ( !in.HasSinusoidalAnalSpectrum() )
198  in.AddSinusoidalAnalSpectrum();
199 
200  in.UpdateData();
201 }
202 
203 } // namespace CLAM
204