|
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 "Complex.hxx" 00023 #include "SpecTypeFlags.hxx" 00024 #include "SpectralPeakArrayInterpolator.hxx" 00025 #include "BPF.hxx" 00026 #include "Point.hxx" 00027 #include "Spectrum.hxx" 00028 00029 namespace CLAM { 00030 00031 void PeaksInterpConfig::DefaultInit() 00032 { 00033 //test 00034 AddAll(); 00035 UpdateData(); 00036 DefaultValues(); 00037 } 00038 00039 void PeaksInterpConfig::DefaultValues() 00040 { 00041 SetUseSpectralShape(false); 00042 } 00043 00044 00045 SpectralPeakArrayInterpolator::SpectralPeakArrayInterpolator(const PeaksInterpConfig &c) 00046 : mMagInterpolationFactorCtl("MagInterpolationFactor",this), 00047 mFreqInterpolationFactorCtl("FreqInterpolationFactor",this), 00048 mPitchInterpolationFactorCtl("PitchInterpolationFactor",this), 00049 mPitch1Ctl("Pitch1",this), 00050 mPitch2Ctl("Pitch2",this), 00051 mIsHarmonicCtl("IsHarmonic",this), 00052 mIn1("Input 1",this), 00053 mIn2("Input 2",this), 00054 mOut("Output",this), 00055 mpSpectralShape(0) 00056 { 00057 Configure(c); 00058 } 00059 00060 00061 bool SpectralPeakArrayInterpolator::ConcreteConfigure(const ProcessingConfig&c) 00062 { 00063 CopyAsConcreteConfig(mConfig, c); 00064 //Initialize interpolation factor control from value in the configuration 00065 mMagInterpolationFactorCtl.DoControl(mConfig.GetMagInterpolationFactor()); 00066 mFreqInterpolationFactorCtl.DoControl(mConfig.GetFreqInterpolationFactor()); 00067 mPitchInterpolationFactorCtl.DoControl(mConfig.GetPitchInterpolationFactor()); 00068 mIsHarmonicCtl.DoControl(mConfig.GetHarmonic()); 00069 00070 return true; 00071 } 00072 00073 // Unsupervised Do() function. 00074 bool SpectralPeakArrayInterpolator::Do(const SpectralPeakArray& in1, const SpectralPeakArray& in2, SpectralPeakArray& out) 00075 { 00076 CLAM_DEBUG_ASSERT(IsRunning(), 00077 "SpectralPeakArrayInterpolator::Do(): Not in execution mode"); 00078 00079 //First, we get values of the internal controls 00080 TData magFactor=mMagInterpolationFactorCtl.GetLastValue(); 00081 TData freqFactor=mFreqInterpolationFactorCtl.GetLastValue(); 00082 00083 TData pitch1=mPitch1Ctl.GetLastValue(); 00084 TData pitch2=mPitch2Ctl.GetLastValue(); 00085 TData pitchFactor=mPitchInterpolationFactorCtl.GetLastValue(); 00086 00087 //we then chek if interpolation really needs to be done 00088 if(magFactor>0.99&&freqFactor>0.99&&pitchFactor>0.99) 00089 { 00090 //we return target spectral peak array 00091 out=in2; 00092 return true; 00093 } 00094 if(magFactor<0.01&&freqFactor<0.01&&pitchFactor<0.01) 00095 { 00096 //we return source spectral peak array 00097 out=in1; 00098 return true; 00099 } 00100 00101 00102 //else, it means we are in a intermediate point and we need to interpolate 00103 00104 //we need to copy input peak arrays to convert them to linear 00105 SpectralPeakArray tmpIn1=in1; 00106 SpectralPeakArray tmpIn2=in2; 00107 tmpIn1.ToLinear(); 00108 tmpIn2.ToLinear(); 00109 00110 int nPeaks1=in1.GetnPeaks(); 00111 int nPeaks2=in2.GetnPeaks(); 00112 00113 if(nPeaks1==0||nPeaks2==0) 00114 { 00115 out=in1; 00116 return true; 00117 } 00118 00119 //We initialize out with tmpIn1 00120 out=tmpIn1; 00121 00122 DataArray& in1Mag=tmpIn1.GetMagBuffer(); 00123 DataArray& in2Mag=tmpIn2.GetMagBuffer(); 00124 DataArray& outMag=out.GetMagBuffer(); 00125 00126 DataArray& in1Freq=tmpIn1.GetFreqBuffer(); 00127 DataArray& in2Freq=tmpIn2.GetFreqBuffer(); 00128 DataArray& outFreq=out.GetFreqBuffer(); 00129 00130 IndexArray& in1Index=tmpIn1.GetIndexArray(); 00131 IndexArray& in2Index=tmpIn2.GetIndexArray(); 00132 IndexArray& outIndex=out.GetIndexArray(); 00133 00134 00135 //Unused var: TData factor2=(TData)nPeaks2/nPeaks1; 00136 00137 00138 //TODO: this computation is duplicated 00139 TData newPitch=pitch1*(1-pitchFactor)+pitch2*pitchFactor; 00140 00141 int pos=0,i=0; 00142 TData lastFreq=0; 00143 do 00144 { 00145 if(!mIsHarmonicCtl.GetLastValue()) 00146 { 00147 TIndex id=in1.GetIndex(i); 00148 int posIn2=in2.GetPositionFromIndex(id); 00149 if(posIn2>0)//found matching peak 00150 { 00151 outMag[i]=in1Mag[i]*(1-magFactor)+in2Mag[posIn2]*magFactor; 00152 outFreq[i]=in1Freq[i]*(1-freqFactor)+in2Freq[posIn2]*freqFactor; 00153 outIndex[i]=id; 00154 lastFreq=outFreq[i]; 00155 } 00156 else 00157 { 00158 outMag[i]=in1Mag[i]*(1-magFactor); 00159 outFreq[i]=in1Freq[i]; 00160 outIndex[i]=id; 00161 lastFreq=outFreq[i]; 00162 00163 } 00164 00165 /*outMag[i]=in1Mag[i]*(1-magFactor)+in2Mag[i*factor2]*magFactor; 00166 outFreq[i]=in1Freq[i]*(1-freqFactor)+in2Freq[i*factor2]*freqFactor; 00167 CLAM_DEBUG_ASSERT(outFreq[i]>=lastFreq,"Error"); 00168 lastFreq=outFreq[i]; 00169 CLAM_DEBUG_ASSERT(outMag[i]<1,"Error"); 00170 CLAM_DEBUG_ASSERT(outMag[i]>-1,"Error"); 00171 CLAM_DEBUG_ASSERT(outFreq[i]<22000,"Error"); 00172 CLAM_DEBUG_ASSERT(outFreq[i]>=0,"Error");*/ 00173 } 00174 else if(FindHarmonic(in2Index,in1Index[i],pos)) 00175 { 00176 //Morphing Using Harmonic No*/ 00177 outMag[i]=in1Mag[i]*(1-magFactor)+in2Mag[pos]*magFactor; 00178 outFreq[i]=((in1Freq[i]/pitch1)*(1-freqFactor)+(in2Freq[pos]/pitch2)*freqFactor)*newPitch; 00179 CLAM_DEBUG_ASSERT(outFreq[i]>lastFreq,"Error"); 00180 lastFreq=outFreq[i]; 00181 CLAM_DEBUG_ASSERT(outMag[i]<1,"Error"); 00182 CLAM_DEBUG_ASSERT(outMag[i]>-1,"Error"); 00183 CLAM_DEBUG_ASSERT(outFreq[i]<22000,"Error"); 00184 CLAM_DEBUG_ASSERT(outFreq[i]>=0,"Error"); 00185 } 00186 else 00187 { 00188 if(i>in2.GetnPeaks()-1) 00189 { 00190 out.SetnPeaks(i-1); 00191 break; 00192 } 00193 outMag[i]=TData(0.0000000001); 00194 outFreq[i]=lastFreq+=100; 00195 } 00196 i++; 00197 }while(i<nPeaks1); 00198 00199 //Finally we convert output to dB 00200 out.TodB(); 00201 00202 return true; 00203 } 00204 00205 // Unsupervised Do() function. 00206 bool SpectralPeakArrayInterpolator::Do(const SpectralPeakArray& in1, const SpectralPeakArray& in2,const Spectrum& spectralShape, SpectralPeakArray& out) 00207 { 00208 CLAM_DEBUG_ASSERT(IsRunning(), 00209 "SpectralPeakArrayInterpolator::Do(): Not in execution mode"); 00210 00211 //First, we get values of the internal controls 00212 TData freqFactor=mFreqInterpolationFactorCtl.GetLastValue(); 00213 00214 TData pitch1=mPitch1Ctl.GetLastValue(); 00215 TData pitch2=mPitch2Ctl.GetLastValue(); 00216 TData pitchFactor=mPitchInterpolationFactorCtl.GetLastValue(); 00217 00218 //else, it means we are in a intermediate point and we need to interpolate 00219 00220 //we need to copy input peak arrays to convert them to linear 00221 SpectralPeakArray tmpIn1=in1; 00222 SpectralPeakArray tmpIn2=in2; 00223 tmpIn1.ToLinear(); 00224 tmpIn2.ToLinear(); 00225 00226 int nPeaks1=in1.GetnPeaks(); 00227 int nPeaks2=in2.GetnPeaks(); 00228 00229 if(nPeaks1==0||nPeaks2==0) 00230 { 00231 out=in1; 00232 return true; 00233 } 00234 00235 //We initialize out with tmpIn1 00236 out=tmpIn1; 00237 00238 DataArray& in1Mag=tmpIn1.GetMagBuffer(); 00239 DataArray& in2Mag=tmpIn2.GetMagBuffer(); 00240 DataArray& outMag=out.GetMagBuffer(); 00241 00242 DataArray& in1Freq=tmpIn1.GetFreqBuffer(); 00243 DataArray& in2Freq=tmpIn2.GetFreqBuffer(); 00244 DataArray& outFreq=out.GetFreqBuffer(); 00245 00246 IndexArray& in1Index=tmpIn1.GetIndexArray(); 00247 IndexArray& in2Index=tmpIn2.GetIndexArray(); 00248 00249 00250 00251 TData factor2=(TData)nPeaks2/nPeaks1; 00252 00253 00254 //TODO: this computation is duplicated 00255 TData newPitch=pitch1*(1-pitchFactor)+pitch2*pitchFactor; 00256 00257 int pos=0,i=0; 00258 TData lastFreq=0; 00259 TData magFactor; 00260 do 00261 { 00262 00263 if(!mIsHarmonicCtl.GetLastValue()) 00264 { 00265 outFreq[i]=in1Freq[i]*(1-freqFactor)+in2Freq[ int(i*factor2) ]*freqFactor; 00266 CLAM_DEBUG_ASSERT(outFreq[i]>=lastFreq,"Error"); 00267 lastFreq=outFreq[i]; 00268 00269 magFactor=spectralShape.GetMag(outFreq[i]); 00270 if(magFactor>1) magFactor=1; 00271 if(magFactor<0) magFactor=0; 00272 outMag[i]=in1Mag[i]*(1-magFactor)+in2Mag[ int(i*factor2) ]*magFactor; 00273 CLAM_DEBUG_ASSERT(outMag[i]<1,"Error"); 00274 CLAM_DEBUG_ASSERT(outMag[i]>-1,"Error"); 00275 CLAM_DEBUG_ASSERT(outFreq[i]<22000,"Error"); 00276 CLAM_DEBUG_ASSERT(outFreq[i]>=0,"Error"); 00277 } 00278 else if(FindHarmonic(in2Index,in1Index[i],pos)) 00279 { 00280 //Morphing Using Harmonic No*/ 00281 00282 outFreq[i]=((in1Freq[i]/pitch1)*(1-freqFactor)+(in2Freq[pos]/pitch2)*freqFactor)*newPitch; 00283 CLAM_DEBUG_ASSERT(outFreq[i]>lastFreq,"Error"); 00284 lastFreq=outFreq[i]; 00285 00286 magFactor=spectralShape.GetMag(outFreq[i]); 00287 if(magFactor>1) magFactor=1; 00288 if(magFactor<0) magFactor=0; 00289 outMag[i]=in1Mag[i]*(1-magFactor)+in2Mag[pos]*magFactor; 00290 CLAM_DEBUG_ASSERT(outMag[i]<1,"Error"); 00291 CLAM_DEBUG_ASSERT(outMag[i]>-1,"Error"); 00292 CLAM_DEBUG_ASSERT(outFreq[i]<22000,"Error"); 00293 CLAM_DEBUG_ASSERT(outFreq[i]>=0,"Error"); 00294 } 00295 else 00296 { 00297 if(i>in2.GetnPeaks()-1) 00298 { 00299 out.SetnPeaks(i-1); 00300 break; 00301 } 00302 outMag[i]=TData(0.0000000001); 00303 outFreq[i]=lastFreq+=100; 00304 } 00305 i++; 00306 }while(i<nPeaks1); 00307 00308 //Finally we convert output to dB 00309 out.TodB(); 00310 00311 return true; 00312 } 00313 00314 bool SpectralPeakArrayInterpolator::Do(void) 00315 { 00316 if(mConfig.GetUseSpectralShape()) 00317 return Do( mIn1.GetData(), mIn2.GetData(), *mpSpectralShape, mOut.GetData() ); 00318 else 00319 return Do(mIn1.GetData(),mIn2.GetData(),mOut.GetData()); 00320 } 00321 00322 00324 bool SpectralPeakArrayInterpolator::FindHarmonic(const IndexArray& indexArray,int index,int& lastPosition) 00325 { 00326 int i; 00327 bool found=false; 00328 int nPeaks=indexArray.Size(); 00329 for(i=lastPosition;i<nPeaks;i++) 00330 { 00331 if(indexArray[i]==index) 00332 { 00333 lastPosition=i; 00334 found=true; 00335 break; 00336 } 00337 } 00338 return found; 00339 00340 } 00341 } 00342
1.7.6.1