fir_dsgn.cpp
上传用户:jtjnyq9001
上传日期:2014-11-21
资源大小:3974k
文件大小:10k
源码类别:

3G开发

开发平台:

Visual C++

  1. //
  2. //  File = fir_dsgn.cpp
  3. //
  4. #include <math.h>
  5. #include <stdlib.h>
  6. #include <iomanip>
  7. #include <strstream>
  8. #include "misdefs.h"   
  9. #include "fir_dsgn.h"
  10. #include "fir_resp_w_noise_bw.h"
  11. #include "parmfile.h"
  12. #include "sinc.h"
  13. extern ParmFile *ParmInput;
  14. extern ofstream DebugFile;
  15. //=========================================
  16. FirFilterDesign::FirFilterDesign( void )
  17. {
  18.  return;
  19. //===============================================
  20. FirFilterDesign::FirFilterDesign( int num_taps )
  21. {
  22.  Num_Taps = num_taps;
  23.  Imp_Resp_Coeff = new double[num_taps];
  24.  Original_Coeff = new double[num_taps];
  25. }
  26. //==========================================================
  27. FirFilterDesign::FirFilterDesign( int num_taps,
  28.                                   double *imp_resp_coeff)
  29. {
  30.  Num_Taps = num_taps;
  31.  Imp_Resp_Coeff = new double[num_taps];
  32.  Original_Coeff = new double[num_taps];
  33.  
  34.  for(int n=0; n<num_taps; n++){
  35.     Imp_Resp_Coeff[n] = imp_resp_coeff[n];
  36.     Original_Coeff[n] = imp_resp_coeff[n];
  37.    }
  38.  return;
  39. //==========================================================
  40. FirFilterDesign::FirFilterDesign( const char* instance_name)
  41. {
  42.   OPEN_PARM_BLOCK;
  43.   GET_INT_PARM(Num_Taps);
  44.   Imp_Resp_Coeff = new double[Num_Taps];
  45.   Original_Coeff = new double[Num_Taps];
  46.   char work[10];
  47.   work[0] = 'C';
  48.   work[2] = 0;
  49.  
  50.   for(int n=0; n<Num_Taps; n++){
  51.     work[1] = 65 + n;
  52.     Imp_Resp_Coeff[n] = ParmInput->GetFloatParm(work);
  53.     Original_Coeff[n] = Imp_Resp_Coeff[n];
  54.     }
  55.   return;
  56. //==========================================================
  57. FirFilterDesign::FirFilterDesign( const char* instance_name,
  58.                                   int type_of_response,
  59.                                   double samp_intvl)
  60. {
  61.   OPEN_PARM_BLOCK;
  62.   GET_INT_PARM(Num_Taps);
  63.   GET_DOUBLE_PARM(Filter_Alpha);
  64.   GET_DOUBLE_PARM(Symbol_Rate);
  65.   double a, b, c, x;
  66.   double epsilon = 0.000001;
  67.   int n;
  68.   Imp_Resp_Coeff = new double[Num_Taps];
  69.   Original_Coeff = new double[Num_Taps];
  70.  
  71.   for( n=0; n <= (Num_Taps-1)/2; n++){
  72.     switch(type_of_response){
  73.       case 0: // raised cosine
  74.         x = n * Symbol_Rate * samp_intvl;
  75.         a = cos( x * PI * Filter_Alpha );
  76.         b = 2.0 * Filter_Alpha * x;
  77.         b = (1.0 - b*b);
  78.         c = sinc(double(x*PI));
  79.         if ( fabs(b) > epsilon){
  80.           Imp_Resp_Coeff[n + (Num_Taps-1)/2] = a * c / b;
  81.           }
  82.         else{
  83.           Imp_Resp_Coeff[n + (Num_Taps-1)/2] = 0;
  84.           }
  85.         break;
  86.       case 1: // root raised cosine
  87.         x = n * Symbol_Rate * samp_intvl;
  88.         a = sin( x * PI * (1.0 - Filter_Alpha));
  89.         b = 4.0 * x * Filter_Alpha;
  90.         b = x * PI * (1.0 - b*b);
  91.         c = 4.0 * x * Filter_Alpha * cos( x * PI * (1.0 + Filter_Alpha));        
  92.         if ( fabs(b) > epsilon){
  93.           Imp_Resp_Coeff[n + (Num_Taps-1)/2] = (a + c) / b;
  94.           }
  95.         else if(n==0){ // t == 0
  96.           Imp_Resp_Coeff[n + (Num_Taps-1)/2] = 1.0 - Filter_Alpha + 4.0*Filter_Alpha/PI;
  97.           }
  98.         else{
  99.           x = PI/(4.0 * Filter_Alpha);
  100.           a = (1.0 + 2.0/PI) * sin(x);
  101.           c = (1.0 - 2.0/PI) * cos(x);
  102.           Imp_Resp_Coeff[n + (Num_Taps-1)/2] = Filter_Alpha * (a+c) / sqrt(2.0);
  103.           }
  104.         break;
  105.       case 2: // pure delay
  106.         if(n==0)
  107.           {
  108.           Imp_Resp_Coeff[n + (Num_Taps-1)/2] = 1.0;
  109.           }
  110.         else
  111.           {
  112.           Imp_Resp_Coeff[n + (Num_Taps-1)/2] = 0.0;
  113.           }
  114.         break;
  115.       }
  116.     Imp_Resp_Coeff[ ((Num_Taps-1)/2) - n] = Imp_Resp_Coeff[n + (Num_Taps-1)/2];
  117.     }
  118.   for( n=0; n < Num_Taps; n++)
  119.     {
  120.     Original_Coeff[n] = Imp_Resp_Coeff[n];
  121.     }
  122.   return;
  123. //==========================================================
  124. // constructor that allocates array of length num_taps 
  125. // and initializes this array to values contained in 
  126. // input array *imp_resp_coeff.  It is assumed that only
  127. // half of the needed values are provided in the array.
  128. // The remaining values are obtained from the given values
  129. // in accordance with the type of symmetry indicated by the
  130. // second argument. 
  131. //----------------------------------------------------------
  132. FirFilterDesign::FirFilterDesign( int num_taps,
  133.                                   FIR_SYM_T symmetry,
  134.                                   double *input_coeff)
  135. {
  136.  int last_left, first_right, n;
  137.  Num_Taps = num_taps;
  138.  Coeff_Symmetry = symmetry;
  139.  Original_Coeff = new double[num_taps];
  140.  Imp_Resp_Coeff = new double[num_taps];
  141.  Quant_Coeff = new long[num_taps];
  142.  if(num_taps%2)
  143.    {  // odd length
  144.    last_left = (num_taps-1)/2;
  145.    first_right = last_left;
  146.    }
  147.  else
  148.    {  // even length
  149.    last_left = (num_taps-2)/2;
  150.    first_right = last_left+1;
  151.    }
  152.  
  153.  switch (symmetry) {
  154.    case FIR_SYM_EVEN_LEFT:
  155.      for(n=0; n<=last_left; n++)
  156.        {
  157.         Original_Coeff[n] = input_coeff[n];
  158.         Imp_Resp_Coeff[n] = input_coeff[n];
  159.         Quant_Coeff[n] = long(Original_Coeff[n]);
  160.        }
  161.      for(n=first_right; n<num_taps; n++)
  162.        {
  163.         Original_Coeff[n] = input_coeff[num_taps-n-1];
  164.         Imp_Resp_Coeff[n] = input_coeff[num_taps-n-1];
  165.         Quant_Coeff[n] = long(Original_Coeff[n]);
  166.        }
  167.     } // end of switch on symmetry
  168.  return;
  169. //============================================== 
  170. // method to allocate coefficient array 
  171. // after default constructor has been used 
  172. //----------------------------------------------
  173. void FirFilterDesign::Initialize( int num_taps )
  174. {
  175.  Num_Taps = num_taps;
  176.  Imp_Resp_Coeff = new double[num_taps];
  177.  Original_Coeff = new double[num_taps];
  178. }
  179. //============================================================
  180. //  method to quantize coefficients
  181. //------------------------------------------------------------
  182. void FirFilterDesign::QuantizeCoefficients( long quant_factor,
  183.                                             bool rounding_enabled )
  184. {
  185.  int n;
  186.  long work_long;
  187.  
  188.  //-----------------------------------
  189.  // if quant_factor == 0, then restore
  190.  // coefficients to their original,
  191.  // unquantized values
  192.  
  193.  if( quant_factor == 0){
  194.     for( n=0; n<Num_Taps; n++){
  195.        Imp_Resp_Coeff[n] = Original_Coeff[n];
  196.       }
  197.     return;
  198.    }
  199.  //-------------------------------------------
  200.  // quantize the original coefficient values
  201.     
  202.  for( n=0; n< Num_Taps; n++)
  203.   {
  204.    if(rounding_enabled)
  205.      {work_long = long((quant_factor * Original_Coeff[n])+0.5);}
  206.    else
  207.      {work_long = long(quant_factor * Original_Coeff[n]);}
  208.      
  209.    Imp_Resp_Coeff[n] = double(work_long)/double(quant_factor);
  210.   }
  211.  return;
  212. }       
  213. //============================================================
  214. //  method to scale coefficients
  215. //------------------------------------------------------------
  216. void FirFilterDesign::ScaleCoefficients( double scale_factor )
  217. {
  218.  int n;
  219.  for( n=0; n< Num_Taps; n++)
  220.   {
  221.    Original_Coeff[n] = scale_factor * Original_Coeff[n];
  222.    Imp_Resp_Coeff[n] = Original_Coeff[n];
  223.   }
  224.  return;
  225. }       
  226. //======================================================
  227. //  scale coefficients so that magnitude response
  228. //  has unity gain at passband peak
  229. //------------------------------------------------------
  230. void FirFilterDesign::NormalizeFilter( void )
  231. {
  232.   int n;
  233.   double passband_peak;
  234.   FirFilterResponse *temp_response;
  235.   temp_response = new FirFilterResponse( this, 500, 0, 0, NULL);
  236.   passband_peak = temp_response->GetIntervalPeak( 0, 499);
  237.   delete temp_response;
  238.   for( n=0; n< Num_Taps; n++)
  239.   {
  240.    Imp_Resp_Coeff[n] = Original_Coeff[n]/passband_peak;
  241.   }
  242.   return;
  243. }
  244. //======================================================
  245. // copy coefficient values from array *Imp_Resp_Coeff
  246. // to output array *coeff
  247. //------------------------------------------------------
  248.  
  249. void FirFilterDesign::CopyCoefficients( double *coeff)
  250. {
  251.  for(int n=0; n<Num_Taps; n++)
  252.    {
  253.     coeff[n] = Imp_Resp_Coeff[n];
  254.    }
  255.  return;
  256. }
  257. void FirFilterDesign::CopyCoefficients( float *coeff)
  258. {
  259.  for(int n=0; n<Num_Taps; n++)
  260.    {
  261.     coeff[n] = float(Imp_Resp_Coeff[n]);
  262.    }
  263.  return;
  264. }
  265. void FirFilterDesign::CopyCoefficients( int *coeff)
  266. {
  267.  for(int n=0; n<Num_Taps; n++)
  268.    {
  269.     coeff[n] = int(Imp_Resp_Coeff[n]);
  270.    }
  271.  return;
  272. }
  273. //===================================
  274. //  get number of filter taps
  275. //-----------------------------------
  276.  
  277. int FirFilterDesign::GetNumTaps(void)
  278. {
  279.  return(Num_Taps);
  280. }
  281. //==============================================================
  282. // dump complete set of coefficients to output_stream
  283. //--------------------------------------------------------------
  284. void FirFilterDesign::DumpCoefficients( ofstream* output_stream)
  285.  //output_stream->setf(ios::scientific, ios::doublefield);
  286.  output_stream->precision(8);
  287.  for(int n=0; n<Num_Taps; n++)
  288.    {
  289.     //(*output_stream) << "h[" << n << "] = " 
  290.     //                 << Imp_Resp_Coeff[n] << endl;
  291.     (*output_stream) << n << ", " 
  292.                      << Imp_Resp_Coeff[n] << endl;
  293.    }
  294.  output_stream->precision(0);
  295.  output_stream->setf(0, ios::floatfield);
  296.  return;
  297. }
  298. //==============================================
  299. //  get pointer to coefficient array
  300. //----------------------------------------------
  301. double* FirFilterDesign::GetCoefficients(void)
  302. {
  303.  cout << "in fs_dsgn, Imp_Resp_Coeff = " << (void*)Imp_Resp_Coeff << endl;
  304.  return(Imp_Resp_Coeff);
  305. }
  306. //========================================================
  307. // apply discrete-time window to filter coefficients
  308. //--------------------------------------------------------
  309. void FirFilterDesign::ApplyWindow( GenericWindow *window)
  310. {
  311.  for(int n=0; n<Num_Taps; n++)
  312.    {
  313.     Imp_Resp_Coeff[n] *= window->GetDataWinCoeff(n);
  314.     Original_Coeff[n] = Imp_Resp_Coeff[n];
  315.    }
  316. //======================================================
  317. // extract a subset of coefficient values for defining
  318. // a polyphase filter 
  319. //------------------------------------------------------
  320.  
  321. void FirFilterDesign::ExtractPolyphaseSet( double *coeff,
  322.                                            int decim_rate,
  323.                                            int rho)
  324. {
  325.  double *local_coeff;
  326.  local_coeff = coeff;
  327.  for(int n=rho; n<Num_Taps; n+=decim_rate)
  328.    {
  329.     *local_coeff++ = Imp_Resp_Coeff[n];
  330.    }
  331.  return;
  332. }