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 "SinusoidalSynthesis.hxx" 00023 00024 #include "SpectrumConfig.hxx" 00025 #include "ProcessingFactory.hxx" 00026 00027 00028 00029 namespace CLAM 00030 { 00031 00032 namespace Hidden 00033 { 00034 static FactoryRegistrator<ProcessingFactory, SinusoidalSynthesis> regSinusoidalSynthesis("SinusoidalSynthesis"); 00035 } 00036 00037 00038 void SinusoidalSynthesis::AttachChildren() 00039 { 00040 mSinSpectralSynthesis.SetParent(this); 00041 mSynthSineSpectrum.SetParent(this); 00042 mPhaseMan.SetParent(this); 00043 mSpectrumAdder.SetParent(this); 00044 mOverlapAddSin.SetParent(this); 00045 } 00046 00047 SinusoidalSynthesis::SinusoidalSynthesis(): 00048 mInputSinSpectralPeaks("InputSinPeaks",this), 00049 mOutputSpectrum("OutputSpectrum",this), 00050 mOutputAudio("OutputAudio",this), 00051 mCurrentTimeControl("CurrentTime",this), 00052 mCurrentPitch("CurrentPitch",this) 00053 { 00054 mCurrentFrame = 0; 00055 Configure(SMSSynthesisConfig()); 00056 AttachChildren(); 00057 } 00058 00059 SinusoidalSynthesis::SinusoidalSynthesis(const SMSSynthesisConfig& cfg): 00060 mInputSinSpectralPeaks("InputSinPeaks",this), 00061 mOutputSpectrum("OutputSpectrum",this), 00062 mOutputAudio("OutputAudio",this), 00063 mCurrentTimeControl("CurrentTime",this), 00064 mCurrentPitch("CurrentPitch",this) 00065 { 00066 mCurrentFrame = 0; 00067 Configure(cfg); 00068 AttachChildren(); 00069 } 00070 00071 SinusoidalSynthesis::~SinusoidalSynthesis() 00072 { 00073 00074 } 00075 00076 bool SinusoidalSynthesis::ConfigureChildren() 00077 { 00078 // mConfig.SetSpectrumSize( mAudioFrame.GetSize()/2+1 ); 00079 00080 //configure sinusoidal spectral synthesis 00081 mConfig.GetSpectralSynth().SetResidual(false); 00082 if(!mSinSpectralSynthesis.Configure(mConfig.GetSpectralSynth())) 00083 return false; 00084 00085 //SynthSineSpectrum 00086 if(!mSynthSineSpectrum.Configure(mConfig.GetSynthSineSpectrum())) 00087 return false; 00088 00089 //Phase Management 00090 if(!mPhaseMan.Configure(mConfig.GetPhaseMan())) 00091 return false; 00092 00093 mPhaseMan.Init(); 00094 00095 //Spectrum Adder 00096 if(!mSpectrumAdder.Configure(SpecAdder2Config())) 00097 return false; 00098 00099 //Overlap and add PO 00100 if(!mOverlapAddSin.Configure(mConfig.GetOverlapAddSin())) 00101 return false; 00102 00103 return true; 00104 } 00105 00106 void SinusoidalSynthesis::ConfigureData() 00107 { 00108 mAudioFrame.SetSize(mConfig.GetHopSize()*2);//audio used as input of the overlap and add 00109 mOutputAudio.SetSize( mAudioFrame.GetSize()/2 ); 00110 00111 mOutputAudio.SetHop( mConfig.GetHopSize() ); 00112 00113 mOutputSpectrum.GetData().SetSize( mAudioFrame.GetSize()/2+1); 00114 mOutputSinSpectrum.GetData().SetSize( mAudioFrame.GetSize()/2+1); 00115 } 00116 00117 00118 bool SinusoidalSynthesis::ConcreteConfigure(const ProcessingConfig& c) 00119 { 00120 CopyAsConcreteConfig(mConfig, c); 00121 ConfigureChildren(); 00122 ConfigureData(); 00123 mCurrentTimeControl.DoControl(-1.0); 00124 return true; 00125 } 00126 00127 bool SinusoidalSynthesis::Do(void) 00128 { 00129 bool result = Do(mInputSinSpectralPeaks.GetData(), 00130 mOutputSpectrum.GetData(), 00131 mOutputAudio.GetAudio()); 00132 00133 mInputSinSpectralPeaks.Consume(); 00134 00135 mOutputSinSpectrum.Produce(); 00136 mOutputSpectrum.Produce(); 00137 mOutputAudio.Produce(); 00138 00139 return result; 00140 } 00141 00142 00143 bool SinusoidalSynthesis::Do( 00144 SpectralPeakArray& inputSinusoidalPeaks, 00145 Audio& outputAudio) 00146 { 00147 Spectrum tmpOutputSpec; 00148 // init its size since we'll operate with these spectrums 00149 // tmpOutputSinSpec.SetSize( inputResidualSpectrum.GetSize() ); 00150 00151 return Do(inputSinusoidalPeaks,tmpOutputSpec,outputAudio); 00152 00153 } 00154 00155 bool SinusoidalSynthesis::Do( 00156 SpectralPeakArray& inputSinusoidalPeaks, 00157 Spectrum& outputSpectrum, // 00158 Audio& outputAudio) 00159 { 00160 //First we do the phase managing. Note that if the Do(frame) overload is not used, 00161 //the time and pitch controls in this processing should be set by hand before this 00162 //method is used 00163 00164 00165 // mPhaseMan.mCurrentTime.DoControl(mCurrentTimeControl.GetLastValue()); //TODO used in SMSBase (Synth from segment) 00166 TData currentTime = 0; 00167 if (mCurrentTimeControl.GetLastValue() < -0.9) 00168 { 00169 int framesize = outputAudio.GetSize(); 00170 //TData samplerate = inputResidualSpectrum.GetSpectralRange()*2; 00171 TData samplerate = mConfig.GetSynthSineSpectrum().GetSamplingRate(); 00172 currentTime = TData( mCurrentFrame*framesize ) / samplerate; 00173 } 00174 else 00175 { 00176 currentTime = mCurrentTimeControl.GetLastValue(); 00177 } 00178 mPhaseMan.mCurrentTime.DoControl( currentTime ); 00179 mCurrentFrame ++; 00180 00181 mPhaseMan.mCurrentPitch.DoControl(mCurrentPitch.GetLastValue()); 00182 mPhaseMan.Do(inputSinusoidalPeaks); 00183 00184 outputSpectrum.SetSize(mConfig.GetSpectrumSize()); 00185 mSynthSineSpectrum.Do(inputSinusoidalPeaks,outputSpectrum); 00186 00187 mSinSpectralSynthesis.Do(outputSpectrum, mAudioFrame); 00188 //Finally the overlap and add is accomplished 00189 00190 mOverlapAddSin.Do(mAudioFrame, outputAudio); 00191 00192 return true; 00193 } 00194 00195 bool SinusoidalSynthesis::Do(Frame& in) 00196 { 00197 if(in.GetCenterTime()<0) return false;//such frames should not be synthesized 00198 00199 //We initialize input frame, adding necessary attributes 00200 InitFrame(in); 00201 //First we set the controls sa mCurrentTimeControl.DoControl(in.GetCenterTime()); 00202 mCurrentPitch.DoControl(in.GetFundamental().GetFreq(0)); 00203 00204 00205 //We make sure that spectrums in input frame has the appropiate size and spectral range. 00206 //Note that the only spectrum we can be sure has the correct spectral range is the residual 00207 //because it its the only one that has been stored in the analysis process. 00208 in.GetOutSpec().SetSize(mConfig.GetSpectrumSize()); 00209 in.GetOutSpec().SetSpectralRange(in.GetResidualSpec().GetSpectralRange()); 00210 in.GetSinusoidalSpec().SetSpectralRange(in.GetResidualSpec().GetSpectralRange()); 00211 00212 return Do(in.GetSpectralPeakArray(),in.GetOutSpec(),in.GetSynthAudioFrame()); 00213 00214 } 00215 00216 bool SinusoidalSynthesis::Do(Segment& in) 00217 { 00218 return Do(in.GetFrame(in.mCurrentFrameIndex++)); 00219 } 00220 00221 00222 void SinusoidalSynthesis::InitFrame(Frame& in) 00223 { 00224 in.AddOutSpec(); 00225 in.AddSinusoidalSpec(); 00226 in.AddSinusoidalAudioFrame(); 00227 in.AddResidualAudioFrame(); 00228 in.AddSynthAudioFrame(); 00229 in.UpdateData(); 00230 00231 in.GetSinusoidalAudioFrame().SetSize(mConfig.GetFrameSize()); 00232 in.GetResidualAudioFrame().SetSize(mConfig.GetFrameSize()); 00233 in.GetSynthAudioFrame().SetSize(mConfig.GetFrameSize()); 00234 00235 } 00236 00237 } // namespace CLAM 00238