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
00048
00049 FDFilterGen::FDFilterGen() :
00050 Output("Output",this),
00051 Gain("Gain",this, &FDFilterGen::UpdateControlChangedFlag),
00052 HighCutOff( "High Cutoff Frequency",this, &FDFilterGen::UpdateControlChangedFlag),
00053 LowCutOff( "Low Cutoff Frequency",this, &FDFilterGen::UpdateControlChangedFlag),
00054 PassBandSlope("Pass Band Slope",this, &FDFilterGen::UpdateControlChangedFlag),
00055 StopBandSlope( "Stop Band Slope",this, &FDFilterGen::UpdateControlChangedFlag),
00056 SpectralRange(0),
00057 Type( EFDFilterType::eLowPass ),
00058 mControlChanged( false )
00059
00060 {
00061 Configure(FDFilterGenConfig());
00062 };
00063
00064 FDFilterGen::FDFilterGen( const FDFilterGenConfig& c) :
00065 Output("Output",this),
00066 Gain("Gain",this, &FDFilterGen::UpdateControlChangedFlag),
00067 HighCutOff( "High Cutoff Frecuency",this, &FDFilterGen::UpdateControlChangedFlag),
00068 LowCutOff( "Low Cutoff Frecuency",this, &FDFilterGen::UpdateControlChangedFlag),
00069 PassBandSlope("Pass Band Slope",this, &FDFilterGen::UpdateControlChangedFlag),
00070 StopBandSlope( "Stop Band Slope",this, &FDFilterGen::UpdateControlChangedFlag),
00071 SpectralRange(0),
00072 Type( EFDFilterType::eLowPass ),
00073 mControlChanged( false )
00074 {
00075 Configure(c);
00076 };
00077
00078
00079
00080 bool FDFilterGen::ConcreteConfigure(const ProcessingConfig& c)
00081 {
00082 CopyAsConcreteConfig(mConfig, c);
00083
00084 mControlChanged=true;
00085 if (mConfig.HasSpectralRange())
00086 SpectralRange=mConfig.GetSpectralRange();
00087 if (mConfig.HasGain())
00088 Gain.DoControl(mConfig.GetGain());
00089 if (mConfig.HasHighCutOff())
00090 HighCutOff.DoControl(mConfig.GetHighCutOff());
00091 if (mConfig.HasLowCutOff())
00092 LowCutOff.DoControl(mConfig.GetLowCutOff());
00093 if (mConfig.HasPassBandSlope())
00094 PassBandSlope.DoControl(mConfig.GetPassBandSlope());
00095 if (mConfig.HasStopBandSlope())
00096 StopBandSlope.DoControl(mConfig.GetStopBandSlope());
00097 if (mConfig.HasType())
00098 Type=mConfig.GetType();
00099
00100
00101 return true;
00102 }
00103
00104 int FDFilterGen::UpdateControlChangedFlag(TControlData val)
00105 {
00106 mControlChanged=true;
00107 return 0;
00108 }
00109
00110
00111 bool FDFilterGen::Do(void)
00112 {
00113 return 0;
00114 }
00115
00116 bool FDFilterGen::Do(Spectrum &out)
00117 {
00118
00119 if (!mControlChanged) return false;
00120 mControlChanged=false;
00121
00122
00123 out.AddMagBPF();
00124 out.AddPhaseBPF();
00125 if (out.UpdateData()) {
00126 out.SetBPFSize(10);
00127 }
00128 else if (out.GetBPFSize()<10)
00129 out.SetBPFSize(10);
00130
00131
00132 EScale originalScale = out.GetScale();
00133 out.SetScale(EScale(EScale::eLog));
00134
00135 TData g,flc,fhc,spb,ssb,fsr;
00136 g=Gain.GetLastValue();
00137 flc=LowCutOff.GetLastValue();
00138 fhc=HighCutOff.GetLastValue();
00139 spb=PassBandSlope.GetLastValue();
00140 ssb=StopBandSlope.GetLastValue();
00141 fsr=SpectralRange;
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 switch((int)Type)
00152 {
00153 case EFDFilterType::eLowPass:
00154 {
00155
00156 out.SetBPFSize(4);
00157
00158 TData fsr_by_flc = fsr/flc;
00159
00160 SetFilterPoint(out,0,0,g);
00161 SetFilterPoint(out,1,flc*CLAM_pow(2.0,-3.0/ssb),g);
00162 SetFilterPoint(out,2,flc,g-3);
00163 SetFilterPoint(out,3,fsr,g-3-ssb*(log(fsr_by_flc)/log(TData(2))));
00164 break;
00165 }
00166 case EFDFilterType::eHighPass:
00167 {
00168 out.SetBPFSize(4);
00169 SetFilterPoint(out,0,0,MINUSINFINITY);
00170 SetFilterPoint(out,1,fhc,g-3);
00171 SetFilterPoint(out,2,fhc*CLAM_pow(2.0,3.0/spb),g);
00172 SetFilterPoint(out,3,fsr,g);
00173 break;
00174 }
00175 case EFDFilterType::eBandPass:
00176 {
00177 out.SetBPFSize(6);
00178 SetFilterPoint(out,0,0,MINUSINFINITY);
00179 SetFilterPoint(out,1,flc,g-3);
00180 SetFilterPoint(out,2,flc*CLAM_pow(2.0,3.0/spb),g);
00181 SetFilterPoint(out,3,fhc*CLAM_pow(2.0,-3.0/ssb),g);
00182 SetFilterPoint(out,4,fhc,g-3);
00183 SetFilterPoint(out,5,fsr,MINUSINFINITY);
00184
00185 break;
00186 }
00187 case EFDFilterType::eStopBand:
00188 {
00189 out.SetBPFSize(7);
00190 SetFilterPoint(out,0,0,g);
00191 SetFilterPoint(out,1,flc*CLAM_pow(2.0,-3.0/ssb),g);
00192 SetFilterPoint(out,2,flc,g-3);
00193 TData crossFreq=(CLAM_pow((double)flc,(1.0/(1.0-spb/ssb)))/CLAM_pow((double)fhc,(1.0/(ssb/spb-1.0))));
00194 TData crossf_by_flc = crossFreq/flc;
00195 SetFilterPoint(out,3,crossFreq,g-3-ssb*(log(crossf_by_flc)/log(TData(2))));
00196 SetFilterPoint(out,4,fhc,g-3);
00197 SetFilterPoint(out,5,fhc*CLAM_pow(2.0,3.0/spb),g);
00198 SetFilterPoint(out,6,fsr,g);
00199 break;
00200 }
00201
00202 }
00203 if (originalScale==EScale::eLinear)
00204 {
00205 int bpfSize=out.GetBPFSize();
00206 BPF& bpf=out.GetMagBPF();
00207
00208 for (int i=0; i<bpfSize; i++) {
00209
00210 TData tmpValue = bpf.GetValueFromIndex(i);
00211
00212 tmpValue = (tmpValue==0.0001) ? 0 : CLAM_pow(10.0,tmpValue/20.0);
00213 bpf.SetValue(i, tmpValue);
00214 }
00215 out.SetScale(EScale(EScale::eLinear));
00216 }
00217
00218 return true;
00219 }
00220
00221 void FDFilterGen::SetFilterPoint(Spectrum& out,TIndex pos,TData freq,TData mag,TData phase)
00222 {
00223 out.GetMagBPF().SetValue(pos, mag);
00224 out.GetMagBPF().SetXValue(pos,freq);
00225 out.GetPhaseBPF().SetValue(pos,phase);
00226 out.GetPhaseBPF().SetXValue(pos,freq);
00227 }
00228
00229 }
00230