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