00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "FDFilterGen.hxx"
00023 #include "CLAM_Math.hxx"
00024 #include <iostream>
00025
00027 #define MINUSINFINITY -99 //Value for an infinitely negative number
00028
00029 namespace CLAM {
00030 void FDFilterGenConfig::DefaultInit(void)
00031 {
00032 AddAll();
00033 UpdateData();
00034
00035 SetGain(0);
00036
00037 SetHighCutOff(0);
00038 SetLowCutOff(0);
00039
00040 SetPassBandSlope(0);
00041 SetStopBandSlope(0);
00042
00043 SetSpectralRange(22050);
00044
00045 }
00046
00047 FDFilterGen::FDFilterGen( const FDFilterGenConfig& c)
00048 : Output("Output",this)
00049 , Gain("Gain",this, &FDFilterGen::UpdateControlChangedFlag)
00050 , HighCutOff( "High Cutoff Frecuency",this, &FDFilterGen::UpdateControlChangedFlag)
00051 , LowCutOff( "Low Cutoff Frecuency",this, &FDFilterGen::UpdateControlChangedFlag)
00052 , PassBandSlope("Pass Band Slope",this, &FDFilterGen::UpdateControlChangedFlag)
00053 , StopBandSlope( "Stop Band Slope",this, &FDFilterGen::UpdateControlChangedFlag)
00054 , SpectralRange(0)
00055 , Type( EFDFilterType::eLowPass )
00056 , mControlChanged( false )
00057 {
00058 Configure(c);
00059 };
00060
00061
00062
00063 bool FDFilterGen::ConcreteConfigure(const ProcessingConfig& c)
00064 {
00065 CopyAsConcreteConfig(mConfig, c);
00066
00067 mControlChanged=true;
00068 if (mConfig.HasSpectralRange())
00069 SpectralRange=mConfig.GetSpectralRange();
00070 if (mConfig.HasGain())
00071 Gain.DoControl(mConfig.GetGain());
00072 if (mConfig.HasHighCutOff())
00073 HighCutOff.DoControl(mConfig.GetHighCutOff());
00074 if (mConfig.HasLowCutOff())
00075 LowCutOff.DoControl(mConfig.GetLowCutOff());
00076 if (mConfig.HasPassBandSlope())
00077 PassBandSlope.DoControl(mConfig.GetPassBandSlope());
00078 if (mConfig.HasStopBandSlope())
00079 StopBandSlope.DoControl(mConfig.GetStopBandSlope());
00080 if (mConfig.HasType())
00081 Type=mConfig.GetType();
00082
00083
00084 return true;
00085 }
00086
00087 void FDFilterGen::UpdateControlChangedFlag(TControlData val)
00088 {
00089 mControlChanged=true;
00090 }
00091
00092
00093 bool FDFilterGen::Do()
00094 {
00095 return 0;
00096 }
00097
00098 bool FDFilterGen::Do(Spectrum &out)
00099 {
00100
00101 if (!mControlChanged) return false;
00102 mControlChanged=false;
00103
00104
00105 out.AddMagBPF();
00106 out.AddPhaseBPF();
00107 if (out.UpdateData()) {
00108 out.SetBPFSize(10);
00109 }
00110 else if (out.GetBPFSize()<10)
00111 out.SetBPFSize(10);
00112
00113
00114 EScale originalScale = out.GetScale();
00115 out.SetScale(EScale(EScale::eLog));
00116
00117 TData g,flc,fhc,spb,ssb,fsr;
00118 g=Gain.GetLastValue();
00119 flc=LowCutOff.GetLastValue();
00120 fhc=HighCutOff.GetLastValue();
00121 spb=PassBandSlope.GetLastValue();
00122 ssb=StopBandSlope.GetLastValue();
00123 fsr=SpectralRange;
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 switch((int)Type)
00134 {
00135 case EFDFilterType::eLowPass:
00136 {
00137
00138 out.SetBPFSize(4);
00139
00140 TData fsr_by_flc = fsr/flc;
00141
00142 SetFilterPoint(out,0,0,g);
00143 SetFilterPoint(out,1,flc*CLAM_pow(2.0,-3.0/ssb),g);
00144 SetFilterPoint(out,2,flc,g-3);
00145 SetFilterPoint(out,3,fsr,g-3-ssb*(log(fsr_by_flc)/log(TData(2))));
00146 break;
00147 }
00148 case EFDFilterType::eHighPass:
00149 {
00150 out.SetBPFSize(4);
00151 SetFilterPoint(out,0,0,MINUSINFINITY);
00152 SetFilterPoint(out,1,fhc,g-3);
00153 SetFilterPoint(out,2,fhc*CLAM_pow(2.0,3.0/spb),g);
00154 SetFilterPoint(out,3,fsr,g);
00155 break;
00156 }
00157 case EFDFilterType::eBandPass:
00158 {
00159 out.SetBPFSize(6);
00160 SetFilterPoint(out,0,0,MINUSINFINITY);
00161 SetFilterPoint(out,1,flc,g-3);
00162 SetFilterPoint(out,2,flc*CLAM_pow(2.0,3.0/spb),g);
00163 SetFilterPoint(out,3,fhc*CLAM_pow(2.0,-3.0/ssb),g);
00164 SetFilterPoint(out,4,fhc,g-3);
00165 SetFilterPoint(out,5,fsr,MINUSINFINITY);
00166
00167 break;
00168 }
00169 case EFDFilterType::eStopBand:
00170 {
00171 out.SetBPFSize(7);
00172 SetFilterPoint(out,0,0,g);
00173 SetFilterPoint(out,1,flc*CLAM_pow(2.0,-3.0/ssb),g);
00174 SetFilterPoint(out,2,flc,g-3);
00175 TData crossFreq=(CLAM_pow((double)flc,(1.0/(1.0-spb/ssb)))/CLAM_pow((double)fhc,(1.0/(ssb/spb-1.0))));
00176 TData crossf_by_flc = crossFreq/flc;
00177 SetFilterPoint(out,3,crossFreq,g-3-ssb*(log(crossf_by_flc)/log(TData(2))));
00178 SetFilterPoint(out,4,fhc,g-3);
00179 SetFilterPoint(out,5,fhc*CLAM_pow(2.0,3.0/spb),g);
00180 SetFilterPoint(out,6,fsr,g);
00181 break;
00182 }
00183
00184 }
00185 if (originalScale==EScale::eLinear)
00186 {
00187 int bpfSize=out.GetBPFSize();
00188 BPF& bpf=out.GetMagBPF();
00189
00190 for (int i=0; i<bpfSize; i++) {
00191
00192 TData tmpValue = bpf.GetValueFromIndex(i);
00193
00194 tmpValue = (tmpValue==0.0001) ? 0 : CLAM_pow(10.0,tmpValue/20.0);
00195 bpf.SetValue(i, tmpValue);
00196 }
00197 out.SetScale(EScale(EScale::eLinear));
00198 }
00199
00200 return true;
00201 }
00202
00203 void FDFilterGen::SetFilterPoint(Spectrum& out,TIndex pos,TData freq,TData mag,TData phase)
00204 {
00205 out.GetMagBPF().SetValue(pos, mag);
00206 out.GetMagBPF().SetXValue(pos,freq);
00207 out.GetPhaseBPF().SetValue(pos,phase);
00208 out.GetPhaseBPF().SetXValue(pos,freq);
00209 }
00210
00211 }
00212