CLAM-Development  1.4.0
Vocoder.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 "Vocoder.hxx"
23 #include "ProcessingFactory.hxx"
24 
25 namespace CLAM
26 {
27 namespace Hidden
28 {
29  static const char * metadata[] = {
30  "key", "Vocoder",
31  "category", "Spectral Transformations",
32  "description", "Vocoder",
33  0
34  };
35  static FactoryRegistrator<ProcessingFactory, Vocoder> reg = metadata;
36 }
37 
38 bool Vocoder::Do(const Spectrum& in, Spectrum& out)
39 {
40  if ( !mConfig.GetPreserveOuts() )
41  {
42  out = in; //TODO big cludge for streaming
43  }
44 
45  int nBands = mNumBandsCtl.GetLastValue();
46  int nGainBands = 5; //it is one more than the actual gains
47  int firstBand = 5;
48  TData fFirstBand = 100;
49 
50  DataArray gains(4);
51  gains[0] = log2lin(mBand0GainCtl.GetLastValue());
52  gains[1] = log2lin(mBand1GainCtl.GetLastValue());
53  gains[2] = log2lin(mBand2GainCtl.GetLastValue());
54  gains[3] = log2lin(mBand3GainCtl.GetLastValue());
55 
56  int spectrumSize = in.GetSize();
57  TData spectralRange = in.GetSpectralRange();
58  TData spectralResolution = spectrumSize/spectralRange;
59 
60  mMagBuffer.Resize(0);// make sure all bins are set to zero
61  mMagBuffer.Resize(spectrumSize);
62  mMagBuffer.SetSize(spectrumSize);
63 
64  TData bandFactor = pow(TData(spectrumSize),1./nBands);
65  TData fBandFactor = pow(TData(spectralRange),1./nBands);
66 
67  TData fCurrentBandLimit = fFirstBand;
68  int currentBandLimit = Round(fFirstBand*spectralResolution);
69  int lastBandLimit = 0;
70  TData fLastBandLimit = 0.;
71 
72  int freqShift = Round(mFreqShiftCtl.GetLastValue()*spectralResolution);
73 
74  int currentOscBin = int(spectrumSize/nBands) + freqShift;
75  TData fCurrentOsc = spectralRange/nBands;
76 
77  int currentGainIndex = 0;
78  TData fCurrentGainBandLimit = fCurrentBandLimit*2;
79  int currentGainBandLimit = Round(fCurrentGainBandLimit*spectralResolution);
80 
81  TData gainBandFactor = pow(TData(spectrumSize/currentBandLimit),1./nGainBands);
82  TData fGainBandFactor = pow(TData(spectralRange/fCurrentGainBandLimit),1./nGainBands);
83 
84  TData bandEnergy =0;
85  DataArray& inMag = in.GetMagBuffer();
86  int currentBand = 0;
87  for(int i = 0; i<spectrumSize; i++)
88  {
89  if(i>currentBandLimit)
90  {
91  bandEnergy = sqrt(bandEnergy);
92  mMagBuffer[currentOscBin] = bandEnergy*gains[currentGainIndex];
93  lastBandLimit = currentBandLimit;
94  fCurrentBandLimit*=fBandFactor;
95  currentBandLimit = Round(fCurrentBandLimit*spectralResolution);
96  if(currentBandLimit>spectrumSize) currentBandLimit = spectrumSize;
97  currentOscBin = int ((currentBandLimit-lastBandLimit)*0.5 + lastBandLimit) + freqShift;
98  bandEnergy = 0;
99  currentBand++;
100  if(currentBand>nBands) break;
101  }
102  if (i>currentGainBandLimit)
103  {
104  if(currentGainIndex<3)
105  currentGainIndex++;
106  fCurrentGainBandLimit*=fGainBandFactor;
107  currentGainBandLimit = Round(fCurrentGainBandLimit*spectralResolution);
108  }
109  bandEnergy += inMag[i];
110 
111  }
112  out.SetMagBuffer(mMagBuffer);
113  return true;
114 }
115 
116 
117 }
118