CLAM-Development  1.4.0
SpectralPeakArrayInterpolator.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 "Complex.hxx"
23 #include "SpecTypeFlags.hxx"
25 #include "BPF.hxx"
26 #include "Point.hxx"
27 #include "Spectrum.hxx"
28 
29 namespace CLAM {
30 
32  {
33  //test
34  AddAll();
35  UpdateData();
36  DefaultValues();
37  }
38 
40  {
41  SetUseSpectralShape(false);
42  }
43 
44 
46  : mMagInterpolationFactorCtl("MagInterpolationFactor",this),
47  mFreqInterpolationFactorCtl("FreqInterpolationFactor",this),
48  mPitchInterpolationFactorCtl("PitchInterpolationFactor",this),
49  mPitch1Ctl("Pitch1",this),
50  mPitch2Ctl("Pitch2",this),
51  mIsHarmonicCtl("IsHarmonic",this),
52  mIn1("Input 1",this),
53  mIn2("Input 2",this),
54  mOut("Output",this),
55  mpSpectralShape(0)
56  {
57  Configure(c);
58  }
59 
60 
61  bool SpectralPeakArrayInterpolator::ConcreteConfigure(const ProcessingConfig&c)
62  {
63  CopyAsConcreteConfig(mConfig, c);
64  //Initialize interpolation factor control from value in the configuration
65  mMagInterpolationFactorCtl.DoControl(mConfig.GetMagInterpolationFactor());
66  mFreqInterpolationFactorCtl.DoControl(mConfig.GetFreqInterpolationFactor());
67  mPitchInterpolationFactorCtl.DoControl(mConfig.GetPitchInterpolationFactor());
68  mIsHarmonicCtl.DoControl(mConfig.GetHarmonic());
69 
70  return true;
71  }
72 
73  // Unsupervised Do() function.
75  {
77  "SpectralPeakArrayInterpolator::Do(): Not in execution mode");
78 
79  //First, we get values of the internal controls
82 
83  TData pitch1=mPitch1Ctl.GetLastValue();
84  TData pitch2=mPitch2Ctl.GetLastValue();
86 
87  //we then chek if interpolation really needs to be done
88  if(magFactor>0.99&&freqFactor>0.99&&pitchFactor>0.99)
89  {
90  //we return target spectral peak array
91  out=in2;
92  return true;
93  }
94  if(magFactor<0.01&&freqFactor<0.01&&pitchFactor<0.01)
95  {
96  //we return source spectral peak array
97  out=in1;
98  return true;
99  }
100 
101 
102  //else, it means we are in a intermediate point and we need to interpolate
103 
104  //we need to copy input peak arrays to convert them to linear
105  SpectralPeakArray tmpIn1=in1;
106  SpectralPeakArray tmpIn2=in2;
107  tmpIn1.ToLinear();
108  tmpIn2.ToLinear();
109 
110  int nPeaks1=in1.GetnPeaks();
111  int nPeaks2=in2.GetnPeaks();
112 
113  if(nPeaks1==0||nPeaks2==0)
114  {
115  out=in1;
116  return true;
117  }
118 
119  //We initialize out with tmpIn1
120  out=tmpIn1;
121 
122  DataArray& in1Mag=tmpIn1.GetMagBuffer();
123  DataArray& in2Mag=tmpIn2.GetMagBuffer();
124  DataArray& outMag=out.GetMagBuffer();
125 
126  DataArray& in1Freq=tmpIn1.GetFreqBuffer();
127  DataArray& in2Freq=tmpIn2.GetFreqBuffer();
128  DataArray& outFreq=out.GetFreqBuffer();
129 
130  IndexArray& in1Index=tmpIn1.GetIndexArray();
131  IndexArray& in2Index=tmpIn2.GetIndexArray();
132  IndexArray& outIndex=out.GetIndexArray();
133 
134 
135  //Unused var: TData factor2=(TData)nPeaks2/nPeaks1;
136 
137 
138  //TODO: this computation is duplicated
139  TData newPitch=pitch1*(1-pitchFactor)+pitch2*pitchFactor;
140 
141  int pos=0,i=0;
142  TData lastFreq=0;
143  do
144  {
146  {
147  TIndex id=in1.GetIndex(i);
148  int posIn2=in2.GetPositionFromIndex(id);
149  if(posIn2>0)//found matching peak
150  {
151  outMag[i]=in1Mag[i]*(1-magFactor)+in2Mag[posIn2]*magFactor;
152  outFreq[i]=in1Freq[i]*(1-freqFactor)+in2Freq[posIn2]*freqFactor;
153  outIndex[i]=id;
154  lastFreq=outFreq[i];
155  }
156  else
157  {
158  outMag[i]=in1Mag[i]*(1-magFactor);
159  outFreq[i]=in1Freq[i];
160  outIndex[i]=id;
161  lastFreq=outFreq[i];
162 
163  }
164 
165  /*outMag[i]=in1Mag[i]*(1-magFactor)+in2Mag[i*factor2]*magFactor;
166  outFreq[i]=in1Freq[i]*(1-freqFactor)+in2Freq[i*factor2]*freqFactor;
167  CLAM_DEBUG_ASSERT(outFreq[i]>=lastFreq,"Error");
168  lastFreq=outFreq[i];
169  CLAM_DEBUG_ASSERT(outMag[i]<1,"Error");
170  CLAM_DEBUG_ASSERT(outMag[i]>-1,"Error");
171  CLAM_DEBUG_ASSERT(outFreq[i]<22000,"Error");
172  CLAM_DEBUG_ASSERT(outFreq[i]>=0,"Error");*/
173  }
174  else if(FindHarmonic(in2Index,in1Index[i],pos))
175  {
176  //Morphing Using Harmonic No*/
177  outMag[i]=in1Mag[i]*(1-magFactor)+in2Mag[pos]*magFactor;
178  outFreq[i]=((in1Freq[i]/pitch1)*(1-freqFactor)+(in2Freq[pos]/pitch2)*freqFactor)*newPitch;
179  CLAM_DEBUG_ASSERT(outFreq[i]>lastFreq,"Error");
180  lastFreq=outFreq[i];
181  CLAM_DEBUG_ASSERT(outMag[i]<1,"Error");
182  CLAM_DEBUG_ASSERT(outMag[i]>-1,"Error");
183  CLAM_DEBUG_ASSERT(outFreq[i]<22000,"Error");
184  CLAM_DEBUG_ASSERT(outFreq[i]>=0,"Error");
185  }
186  else
187  {
188  if(i>in2.GetnPeaks()-1)
189  {
190  out.SetnPeaks(i-1);
191  break;
192  }
193  outMag[i]=TData(0.0000000001);
194  outFreq[i]=lastFreq+=100;
195  }
196  i++;
197  }while(i<nPeaks1);
198 
199  //Finally we convert output to dB
200  out.TodB();
201 
202  return true;
203  }
204 
205  // Unsupervised Do() function.
207  {
209  "SpectralPeakArrayInterpolator::Do(): Not in execution mode");
210 
211  //First, we get values of the internal controls
213 
214  TData pitch1=mPitch1Ctl.GetLastValue();
215  TData pitch2=mPitch2Ctl.GetLastValue();
217 
218  //else, it means we are in a intermediate point and we need to interpolate
219 
220  //we need to copy input peak arrays to convert them to linear
221  SpectralPeakArray tmpIn1=in1;
222  SpectralPeakArray tmpIn2=in2;
223  tmpIn1.ToLinear();
224  tmpIn2.ToLinear();
225 
226  int nPeaks1=in1.GetnPeaks();
227  int nPeaks2=in2.GetnPeaks();
228 
229  if(nPeaks1==0||nPeaks2==0)
230  {
231  out=in1;
232  return true;
233  }
234 
235  //We initialize out with tmpIn1
236  out=tmpIn1;
237 
238  DataArray& in1Mag=tmpIn1.GetMagBuffer();
239  DataArray& in2Mag=tmpIn2.GetMagBuffer();
240  DataArray& outMag=out.GetMagBuffer();
241 
242  DataArray& in1Freq=tmpIn1.GetFreqBuffer();
243  DataArray& in2Freq=tmpIn2.GetFreqBuffer();
244  DataArray& outFreq=out.GetFreqBuffer();
245 
246  IndexArray& in1Index=tmpIn1.GetIndexArray();
247  IndexArray& in2Index=tmpIn2.GetIndexArray();
248 
249 
250 
251  TData factor2=(TData)nPeaks2/nPeaks1;
252 
253 
254  //TODO: this computation is duplicated
255  TData newPitch=pitch1*(1-pitchFactor)+pitch2*pitchFactor;
256 
257  int pos=0,i=0;
258  TData lastFreq=0;
259  TData magFactor;
260  do
261  {
262 
264  {
265  outFreq[i]=in1Freq[i]*(1-freqFactor)+in2Freq[ int(i*factor2) ]*freqFactor;
266  CLAM_DEBUG_ASSERT(outFreq[i]>=lastFreq,"Error");
267  lastFreq=outFreq[i];
268 
269  magFactor=spectralShape.GetMag(outFreq[i]);
270  if(magFactor>1) magFactor=1;
271  if(magFactor<0) magFactor=0;
272  outMag[i]=in1Mag[i]*(1-magFactor)+in2Mag[ int(i*factor2) ]*magFactor;
273  CLAM_DEBUG_ASSERT(outMag[i]<1,"Error");
274  CLAM_DEBUG_ASSERT(outMag[i]>-1,"Error");
275  CLAM_DEBUG_ASSERT(outFreq[i]<22000,"Error");
276  CLAM_DEBUG_ASSERT(outFreq[i]>=0,"Error");
277  }
278  else if(FindHarmonic(in2Index,in1Index[i],pos))
279  {
280  //Morphing Using Harmonic No*/
281 
282  outFreq[i]=((in1Freq[i]/pitch1)*(1-freqFactor)+(in2Freq[pos]/pitch2)*freqFactor)*newPitch;
283  CLAM_DEBUG_ASSERT(outFreq[i]>lastFreq,"Error");
284  lastFreq=outFreq[i];
285 
286  magFactor=spectralShape.GetMag(outFreq[i]);
287  if(magFactor>1) magFactor=1;
288  if(magFactor<0) magFactor=0;
289  outMag[i]=in1Mag[i]*(1-magFactor)+in2Mag[pos]*magFactor;
290  CLAM_DEBUG_ASSERT(outMag[i]<1,"Error");
291  CLAM_DEBUG_ASSERT(outMag[i]>-1,"Error");
292  CLAM_DEBUG_ASSERT(outFreq[i]<22000,"Error");
293  CLAM_DEBUG_ASSERT(outFreq[i]>=0,"Error");
294  }
295  else
296  {
297  if(i>in2.GetnPeaks()-1)
298  {
299  out.SetnPeaks(i-1);
300  break;
301  }
302  outMag[i]=TData(0.0000000001);
303  outFreq[i]=lastFreq+=100;
304  }
305  i++;
306  }while(i<nPeaks1);
307 
308  //Finally we convert output to dB
309  out.TodB();
310 
311  return true;
312  }
313 
315  {
316  if(mConfig.GetUseSpectralShape())
317  return Do( mIn1.GetData(), mIn2.GetData(), *mpSpectralShape, mOut.GetData() );
318  else
319  return Do(mIn1.GetData(),mIn2.GetData(),mOut.GetData());
320  }
321 
322 
324  bool SpectralPeakArrayInterpolator::FindHarmonic(const IndexArray& indexArray,int index,int& lastPosition)
325  {
326  int i;
327  bool found=false;
328  int nPeaks=indexArray.Size();
329  for(i=lastPosition;i<nPeaks;i++)
330  {
331  if(indexArray[i]==index)
332  {
333  lastPosition=i;
334  found=true;
335  break;
336  }
337  }
338  return found;
339 
340  }
341 }
342