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