CLAM-Development  1.4.0
FDFilterGen.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 "FDFilterGen.hxx"
23 #include "CLAM_Math.hxx"
24 #include <iostream>
25 
27 #define MINUSINFINITY -99 //Value for an infinitely negative number
28 
29 namespace CLAM {
31  {
32  AddAll();
33  UpdateData();
34 
35  SetGain(0);
36 
37  SetHighCutOff(0);
38  SetLowCutOff(0);
39 
40  SetPassBandSlope(0);
41  SetStopBandSlope(0);
42 
43  SetSpectralRange(22050); //default value for consistency between classes
44 
45  }
46 
48  : Output("Output",this)
49  , Gain("Gain",this, &FDFilterGen::UpdateControlChangedFlag)
50  , HighCutOff( "High Cutoff Frecuency",this, &FDFilterGen::UpdateControlChangedFlag)
51  , LowCutOff( "Low Cutoff Frecuency",this, &FDFilterGen::UpdateControlChangedFlag)
52  , PassBandSlope("Pass Band Slope",this, &FDFilterGen::UpdateControlChangedFlag)
53  , StopBandSlope( "Stop Band Slope",this, &FDFilterGen::UpdateControlChangedFlag)
54  , SpectralRange(0)
55  , Type( EFDFilterType::eLowPass )
56  , mControlChanged( false )
57  {
58  Configure(c); // here all controls are initialized
59  };
60 
61 
62 
63  bool FDFilterGen::ConcreteConfigure(const ProcessingConfig& c)
64  {
65  CopyAsConcreteConfig(mConfig, c);
66 
67  mControlChanged=true; //we want the next Do to perform an action
68  if (mConfig.HasSpectralRange())
69  SpectralRange=mConfig.GetSpectralRange();
70  if (mConfig.HasGain())
71  Gain.DoControl(mConfig.GetGain());
72  if (mConfig.HasHighCutOff())
73  HighCutOff.DoControl(mConfig.GetHighCutOff());
74  if (mConfig.HasLowCutOff())
75  LowCutOff.DoControl(mConfig.GetLowCutOff());
76  if (mConfig.HasPassBandSlope())
77  PassBandSlope.DoControl(mConfig.GetPassBandSlope());
78  if (mConfig.HasStopBandSlope())
79  StopBandSlope.DoControl(mConfig.GetStopBandSlope());
80  if (mConfig.HasType())
81  Type=mConfig.GetType();
82 
83 
84  return true;
85  }
86 
88  {
89  mControlChanged=true;
90  }
91 
92 
94  {
95  return 0;
96  }
97 
99  {
100  // Only do something after have received an incontrol.
101  if (!mControlChanged) return false;
102  mControlChanged=false;
103 
104  // Instantiate the BPF buffer of the spectrum if necessary.
105  out.AddMagBPF();
106  out.AddPhaseBPF();
107  if (out.UpdateData()) {
108  out.SetBPFSize(10);
109  }
110  else if (out.GetBPFSize()<10)
111  out.SetBPFSize(10);
112 
113 
114  EScale originalScale = out.GetScale();
115  out.SetScale(EScale(EScale::eLog));
116 
117  TData g,flc,fhc,spb,ssb,fsr;
118  g=Gain.GetLastValue();
119  flc=LowCutOff.GetLastValue();
120  fhc=HighCutOff.GetLastValue();
123  fsr=SpectralRange;
124 
125  // Legend:
126  // g stands for Gain
127  // flc stands for Lower cutoff frequency
128  // fhc stands for Higher cutoff frequency
129  // spb stands for Slope for the pass band
130  // ssb stands for Slope for the stop band
131  // fsr stands for Sampling Rate Frequency
132 
133  switch((int)Type)
134  {
136  {
137  // We add four points to the BPF ( the four control points for the filter )
138  out.SetBPFSize(4);
139 
140  TData fsr_by_flc = fsr/flc;
141 
142  SetFilterPoint(out,0,0,g);
143  SetFilterPoint(out,1,flc*CLAM_pow(2.0,-3.0/ssb),g);
144  SetFilterPoint(out,2,flc,g-3);
145  SetFilterPoint(out,3,fsr,g-3-ssb*(log(fsr_by_flc)/log(TData(2))));
146  break;
147  }
149  {
150  out.SetBPFSize(4);
151  SetFilterPoint(out,0,0,MINUSINFINITY);
152  SetFilterPoint(out,1,fhc,g-3);
153  SetFilterPoint(out,2,fhc*CLAM_pow(2.0,3.0/spb),g);
154  SetFilterPoint(out,3,fsr,g);
155  break;
156  }
158  {
159  out.SetBPFSize(6);
160  SetFilterPoint(out,0,0,MINUSINFINITY);
161  SetFilterPoint(out,1,flc,g-3);
162  SetFilterPoint(out,2,flc*CLAM_pow(2.0,3.0/spb),g);
163  SetFilterPoint(out,3,fhc*CLAM_pow(2.0,-3.0/ssb),g);
164  SetFilterPoint(out,4,fhc,g-3);
165  SetFilterPoint(out,5,fsr,MINUSINFINITY);
166 
167  break;
168  }
170  {
171  out.SetBPFSize(7);
172  SetFilterPoint(out,0,0,g);
173  SetFilterPoint(out,1,flc*CLAM_pow(2.0,-3.0/ssb),g);
174  SetFilterPoint(out,2,flc,g-3);
175  TData crossFreq=(CLAM_pow((double)flc,(1.0/(1.0-spb/ssb)))/CLAM_pow((double)fhc,(1.0/(ssb/spb-1.0))));
176  TData crossf_by_flc = crossFreq/flc;
177  SetFilterPoint(out,3,crossFreq,g-3-ssb*(log(crossf_by_flc)/log(TData(2))));
178  SetFilterPoint(out,4,fhc,g-3);
179  SetFilterPoint(out,5,fhc*CLAM_pow(2.0,3.0/spb),g);
180  SetFilterPoint(out,6,fsr,g);
181  break;
182  }
183 
184  }
185  if (originalScale==EScale::eLinear)
186  {
187  int bpfSize=out.GetBPFSize();
188  BPF& bpf=out.GetMagBPF();
189 
190  for (int i=0; i<bpfSize; i++) {
191 
192  TData tmpValue = bpf.GetValueFromIndex(i);
193 
194  tmpValue = (tmpValue==0.0001) ? 0 : CLAM_pow(10.0,tmpValue/20.0);
195  bpf.SetValue(i, tmpValue);
196  }
197  out.SetScale(EScale(EScale::eLinear));
198  }
199 
200  return true;
201  }
202 
203  void FDFilterGen::SetFilterPoint(Spectrum& out,TIndex pos,TData freq,TData mag,TData phase)
204  {
205  out.GetMagBPF().SetValue(pos, mag);
206  out.GetMagBPF().SetXValue(pos,freq);
207  out.GetPhaseBPF().SetValue(pos,phase);
208  out.GetPhaseBPF().SetXValue(pos,freq);
209  }
210 
211 }
212