|
CLAM-Development
1.3
|
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
1.7.6.1