FDFilterGen.cxx

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG)
00003  *                         UNIVERSITAT POMPEU FABRA
00004  *
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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); //default value for consistency between classes
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); // here all controls are initialized
00059         };
00060 
00061 
00062         
00063         bool FDFilterGen::ConcreteConfigure(const ProcessingConfig& c)
00064         {
00065                 CopyAsConcreteConfig(mConfig, c);
00066 
00067                 mControlChanged=true; //we want the next Do to perform an action
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                 // Only do something after have received an incontrol.
00101                 if (!mControlChanged) return false;
00102                 mControlChanged=false; 
00103                 
00104     // Instantiate the BPF buffer of the spectrum if necessary.
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                 // Legend:
00126                 // g      stands for Gain
00127                 // flc    stands for Lower cutoff frequency
00128                 // fhc    stands for Higher cutoff frequency
00129                 // spb    stands for Slope for the pass band
00130                 // ssb    stands for Slope for the stop band
00131                 // fsr    stands for Sampling Rate Frequency 
00132 
00133                 switch((int)Type)
00134                         {
00135                         case EFDFilterType::eLowPass:
00136                         {
00137                                 // We add four points to the BPF ( the four control points for the filter )
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 
Generated by  doxygen 1.6.3