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

3G开发

开发平台:

Visual C++

  1. //
  2. //  File = polar_freq_dom_filt.cpp
  3. //
  4. #include <stdlib.h>
  5. #include <fstream>
  6. #include "parmfile.h"
  7. #include "polar_freq_dom_filt.h"
  8. #include "misdefs.h"
  9. #include "model_graph.h"
  10. #include "sigplot.h"
  11. #include "dit_pino_T.h"
  12. #include "dit_nipo_T.h"
  13. #include "complex_io.h"
  14. extern ParmFile *ParmInput;
  15. extern SignalPlotter SigPlot;
  16. extern int PassNumber;
  17. //ofstream CorrFile("corr_res.txt", ios::out);
  18. //======================================================
  19. PolarFreqDomainFilter::PolarFreqDomainFilter( char* instance_name,
  20.                                          PracSimModel* outer_model,
  21.                                          Signal< std::complex<float> >* in_sig,
  22.                                          Signal< std::complex<float> >* out_sig)
  23.             :PracSimModel(instance_name,
  24.                           outer_model)
  25. {
  26.    MODEL_NAME(PolarFreqDomainFilter);
  27.    ENABLE_MULTIRATE;
  28.    In_Sig = in_sig;
  29.    Out_Sig = out_sig;
  30.    OPEN_PARM_BLOCK;
  31.    GET_INT_PARM(Fft_Size);
  32.    GET_DOUBLE_PARM(Dt_For_Fft);
  33.    GET_FLOAT_PARM(Overlap_Save_Mem);
  34.    GET_BOOL_PARM(Bypass_Enabled);
  35.    Magnitude_Data_Fname = new char[64];
  36.    strcpy(Magnitude_Data_Fname, "");
  37.    GET_STRING_PARM(Magnitude_Data_Fname);
  38.    GET_DOUBLE_PARM(Mag_Freq_Scaling_Factor);
  39.    Phase_Data_Fname = new char[64];
  40.    strcpy(Phase_Data_Fname, "");
  41.    GET_STRING_PARM(Phase_Data_Fname);
  42.    GET_DOUBLE_PARM(Phase_Freq_Scaling_Factor);
  43.    Num_Saved_Samps = int(Overlap_Save_Mem/Dt_For_Fft + 0.5);
  44.    Block_Size = Fft_Size - Num_Saved_Samps;
  45.    MAKE_OUTPUT(Out_Sig);
  46.    MAKE_INPUT(In_Sig);
  47.    SET_SAMP_INTVL(In_Sig, Dt_For_Fft);
  48.    SET_BLOCK_SIZE(In_Sig, Block_Size);
  49.    SET_SAMP_INTVL(Out_Sig, Dt_For_Fft);
  50.    SET_BLOCK_SIZE(Out_Sig, Block_Size);
  51.    //SET_DELAY( In_Sig, Out_Sig, Group_Delay_Offset);
  52. }
  53. PolarFreqDomainFilter::~PolarFreqDomainFilter( void )
  54. {
  55.    if(Full_Buffer != NULL) delete []Full_Buffer;
  56.    delete []Magnitude_Data_Fname;
  57.    delete []Resid_Data_Fname;
  58.    delete []Stretched_Data_Fname;
  59. };
  60. void PolarFreqDomainFilter::Initialize(void)
  61. {
  62.    int i;
  63.    int samp_num, bin_num;
  64.    char line_buf[100];
  65.    char *item;
  66.    double tmp_nsexp, frac_part, int_part;
  67.    double min_data_freq, max_data_freq;
  68.    double left_freq, right_freq;
  69.    double bin_freq, left_val, right_val, slope, base;
  70.    std::complex<float> *time_resp;
  71.    //PointDataFile input_file;
  72.    std::complex<float> exponent;
  73.    std::complex<float> pseudo_complex;
  74.    ofstream *resp_file;
  75.    tmp_nsexp = log10(double(Fft_Size))/log10(2.0);
  76.    frac_part = modf(tmp_nsexp, &int_part);
  77.    double delta_f = 1.0/(Fft_Size*Dt_For_Fft);
  78.    //------------------------------------------------------------
  79.    //  initialize derived parameters
  80.    Ns_Exp = int_part;
  81.    Full_Buffer = new std::complex<float>[Fft_Size];
  82.    for(i=0; i<Fft_Size; i++)
  83.    {
  84.       Full_Buffer[i] = std::complex<float>(0.0,0.0);
  85.    }
  86.    time_resp = new std::complex<float>[Fft_Size];
  87.    for(i=0; i<Fft_Size; i++)
  88.    {
  89.       time_resp[i] = std::complex<float>(0.0,0.0);
  90.    }
  91.    FftDitNipo( time_resp, Fft_Size);
  92.    Mag_Resp = new float[Fft_Size];
  93.    Phase_Resp = new float[Fft_Size];
  94.    //-----------------------------------------------------
  95.    //  Read in the raw response data
  96.    Magnitude_Data_File = new ifstream(Magnitude_Data_Fname, ios::in);
  97.    *Magnitude_Data_File >> Num_Mag_Samps;
  98.    Magnitude_Data_File->getline(line_buf,100);
  99.    Raw_Magnitude_Resp = new float[Num_Mag_Samps];
  100.    Freqs_For_Magnitude = new float[Num_Mag_Samps];
  101.    for(samp_num=0;samp_num<Num_Mag_Samps; samp_num++)
  102.    {
  103.       Magnitude_Data_File->getline(line_buf,100);
  104.       item = strtok(line_buf,",nt");
  105.       Freqs_For_Magnitude[samp_num] = atof(item);
  106.       item = strtok(NULL,",nt");
  107.       Raw_Magnitude_Resp[samp_num] = atof(item);
  108.    }
  109.    Magnitude_Data_File->close();
  110.    resp_file = new ofstream("mag_resp.txt", ios::out);
  111.    min_data_freq = Mag_Freq_Scaling_Factor * Freqs_For_Magnitude[0];
  112.    max_data_freq = Mag_Freq_Scaling_Factor * Freqs_For_Magnitude[Num_Mag_Samps-1];
  113.    samp_num=-1;
  114.    right_freq = Mag_Freq_Scaling_Factor * Freqs_For_Magnitude[0];
  115.    right_val = pow(10.0,(Raw_Magnitude_Resp[0]/20.0));
  116.    left_freq = -delta_f*Fft_Size/2;
  117.    slope = right_val/(right_freq-left_freq);
  118.    base = -left_freq*slope;
  119.    for(bin_num=-Fft_Size/2;bin_num<0;bin_num++)
  120.    {
  121.       bin_freq = bin_num * delta_f;
  122.       if(bin_freq < min_data_freq)
  123.       //
  124.       // put straight-line skirt on negative frequency portion
  125.       // not covered by input data
  126.       {
  127.          Mag_Resp[Fft_Size+bin_num] = bin_freq * slope + base;
  128.       }
  129.       else
  130.       //
  131.       //  do negative-frequency portion that is covered by input data
  132.       {
  133.          if(bin_freq >= right_freq) 
  134.          {
  135.             samp_num++;
  136.             left_freq = right_freq;
  137.             right_freq = Mag_Freq_Scaling_Factor * Freqs_For_Magnitude[samp_num+1];
  138.             left_val = pow(10.0, Raw_Magnitude_Resp[samp_num]/20.0);
  139.             right_val = pow(10.0, Raw_Magnitude_Resp[samp_num+1]/20.0);
  140.             slope = (right_val - left_val)/(right_freq - left_freq);
  141.             base = left_val - left_freq*slope;
  142.          }
  143.          Mag_Resp[Fft_Size+bin_num] = bin_freq * slope + base;
  144.       }
  145.       *resp_file << bin_num << ", " << Mag_Resp[Fft_Size+bin_num] << endl;
  146.    }
  147.    //
  148.    //  do the positive frequency portion which is covered by input data
  149.    bin_freq = 0;
  150.    bin_num = 0;
  151.    while(bin_freq<max_data_freq && bin_num<Fft_Size/2)
  152.    {
  153.       bin_freq = bin_num * delta_f;
  154.       if(bin_freq >= right_freq)
  155.       {
  156.          samp_num++;
  157.          left_freq = right_freq;
  158.          right_freq = Mag_Freq_Scaling_Factor * Freqs_For_Magnitude[samp_num+1];
  159.          left_val = pow(10.0, Raw_Magnitude_Resp[samp_num]/20.0);
  160.          right_val = pow(10.0, Raw_Magnitude_Resp[samp_num+1]/20.0);
  161.          slope = (right_val - left_val)/(right_freq - left_freq);
  162.          base = left_val - left_freq*slope;
  163.       }
  164.       Mag_Resp[bin_num] = bin_freq * slope + base;
  165.       *resp_file << bin_num << ", " << Mag_Resp[bin_num] << endl;
  166.       bin_num++;
  167.    }
  168.    //
  169.    // put straight-line skirt on positive frequency portion not coverd by input data
  170.    left_freq = Mag_Freq_Scaling_Factor * Freqs_For_Magnitude[Num_Mag_Samps-1];
  171.    left_val = pow(10.0,(Raw_Magnitude_Resp[Num_Mag_Samps-1]/20.0));
  172.    right_freq = delta_f*(Fft_Size-2)/2;
  173.    slope = -left_val/(right_freq-left_freq);
  174.    base = left_val-left_freq*slope;
  175.    while(bin_num<Fft_Size/2)
  176.    {
  177.       bin_freq = bin_num * delta_f;
  178.       Mag_Resp[bin_num] = bin_freq * slope + base;
  179.       *resp_file << bin_num << ", " << Mag_Resp[bin_num] << endl;
  180.       bin_num++;
  181.    }
  182.    resp_file->close();
  183.    Phase_Data_File = new ifstream(Phase_Data_Fname, ios::in);
  184.    *Phase_Data_File >> Num_Phase_Samps;
  185.    Phase_Data_File->getline(line_buf,100);
  186.    Raw_Phase_Resp = new float[Num_Phase_Samps];
  187.    Freqs_For_Phase = new float[Num_Phase_Samps];
  188.    for(samp_num=0;samp_num<Num_Phase_Samps; samp_num++)
  189.    {
  190.       Phase_Data_File->getline(line_buf,100);
  191.       item = strtok(line_buf,",nt");
  192.       Freqs_For_Phase[samp_num] = atof(item);
  193.       item = strtok(NULL,",nt");
  194.       Raw_Phase_Resp[samp_num] = atof(item);
  195.    }
  196.    Phase_Data_File->close();
  197.    resp_file = new ofstream("Phase_resp.txt", ios::out);
  198.    min_data_freq = Mag_Freq_Scaling_Factor * Freqs_For_Phase[0];
  199.    max_data_freq = Mag_Freq_Scaling_Factor * Freqs_For_Phase[Num_Phase_Samps-1];
  200.    samp_num=-1;
  201.    right_freq = Phase_Freq_Scaling_Factor * Freqs_For_Phase[0];
  202.    right_val = Raw_Phase_Resp[0];
  203.    left_freq = -delta_f*Fft_Size/2;
  204.    slope = right_val/(right_freq-left_freq);
  205.    base = -left_freq*slope;
  206.    for(bin_num=-Fft_Size/2;bin_num<0;bin_num++)
  207.    {
  208.       bin_freq = bin_num * delta_f;
  209.       if(bin_freq < min_data_freq)
  210.       //
  211.       // put straight-line skirt on negative frequency portion
  212.       // not covered by input data
  213.       {
  214.          //Phase_Resp[Fft_Size+bin_num] = bin_freq * slope + base;
  215.          Phase_Resp[Fft_Size+bin_num] = Raw_Phase_Resp[0];
  216.       }
  217.       else
  218.       //
  219.       //  do negative-frequency portion that is covered by input data
  220.       {
  221.          if(bin_freq >= right_freq) 
  222.          {
  223.             samp_num++;
  224.             left_freq = right_freq;
  225.             right_freq = Phase_Freq_Scaling_Factor * Freqs_For_Phase[samp_num+1];
  226.             left_val = Raw_Phase_Resp[samp_num];
  227.             right_val = Raw_Phase_Resp[samp_num+1];
  228.             slope = (right_val - left_val)/(right_freq - left_freq);
  229.             base = left_val - left_freq*slope;
  230.          }
  231.          Phase_Resp[Fft_Size+bin_num] = bin_freq * slope + base;
  232.       }
  233.       *resp_file << bin_num << ", " << Phase_Resp[Fft_Size+bin_num] << endl;
  234.    }
  235.    //
  236.    //  do the positive frequency portion which is covered by input data
  237.    bin_freq = 0;
  238.    bin_num = 0;
  239.    while(bin_freq<max_data_freq && bin_num<Fft_Size/2)
  240.    {
  241.       bin_freq = bin_num * delta_f;
  242.       if(bin_freq >= right_freq)
  243.       {
  244.          samp_num++;
  245.          left_freq = right_freq;
  246.          right_freq = Phase_Freq_Scaling_Factor * Freqs_For_Phase[samp_num+1];
  247.          left_val = Raw_Phase_Resp[samp_num];
  248.          right_val = Raw_Phase_Resp[samp_num+1];
  249.          slope = (right_val - left_val)/(right_freq - left_freq);
  250.          base = left_val - left_freq*slope;
  251.       }
  252.       Phase_Resp[bin_num] = bin_freq * slope + base;
  253.       *resp_file << bin_num << ", " << Phase_Resp[bin_num] << endl;
  254.       bin_num++;
  255.    }
  256.    //
  257.    // put straight-line skirt on positive frequency portion not coverd by input data
  258.    left_freq = Phase_Freq_Scaling_Factor * Freqs_For_Phase[Num_Phase_Samps-1];
  259.    left_val = Raw_Phase_Resp[Num_Phase_Samps-1];
  260.    right_freq = delta_f*(Fft_Size-2)/2;
  261.    slope = -left_val/(right_freq-left_freq);
  262.    base = left_val-left_freq*slope;
  263.    while(bin_num<Fft_Size/2)
  264.    {
  265.       bin_freq = bin_num * delta_f;
  266.       //Phase_Resp[bin_num] = bin_freq * slope + base;
  267.       Phase_Resp[bin_num] = Raw_Phase_Resp[Num_Phase_Samps-1];
  268.       *resp_file << bin_num << ", " << Phase_Resp[bin_num] << endl;
  269.       bin_num++;
  270.    }
  271.    resp_file->close();
  272.    //-----------------------------------------------------
  273. }
  274. //#define RAD_PER_DEG 0.017453293
  275. int PolarFreqDomainFilter::Execute()
  276. {
  277.    int is, ns_exp;
  278.    int block_size, num_saved_samps;
  279.    int valid_block_size;
  280.    std::complex<float> *in_sig_ptr;
  281.    std::complex<float> *out_sig_ptr;
  282.    float phase, magnitude;
  283.    //-------------------------------------------------------
  284.    //  Copy frequently accessed member vars into local vars
  285.    block_size = Block_Size;
  286.    num_saved_samps = Num_Saved_Samps;
  287.    ns_exp = Ns_Exp;
  288.    //----------------------------------------
  289.    // Get pointers for input and output
  290.    in_sig_ptr = GET_INPUT_PTR(In_Sig);
  291.    out_sig_ptr = GET_OUTPUT_PTR(Out_Sig);
  292.    valid_block_size = In_Sig->GetValidBlockSize();
  293.    Out_Sig->SetValidBlockSize(valid_block_size);
  294.    //--------------------------------------
  295.    memcpy(Full_Buffer, in_sig_ptr, Block_Size*sizeof(std::complex<float>));
  296.    if(PassNumber == 2)
  297.    {
  298.       ofstream *pass_in_file = new ofstream("FftInput_2.txt",ios::out);
  299.       int ii;
  300.       for(ii=Block_Size; ii<Fft_Size; ii++)
  301.       {
  302.          //*pass_in_file << ((PassNumber-2)*Fft_Size+ii) << ", " << Full_Buffer[ii] << endl;
  303.          *pass_in_file << (ii - Fft_Size) << ", " << Full_Buffer[ii] << endl;
  304.       }
  305.       for(ii=0; ii<Fft_Size; ii++)
  306.       {
  307.          //*pass_in_file << ((PassNumber-1)*Fft_Size+ii) << ", " << Full_Buffer[ii] << endl;
  308.          *pass_in_file << ii << ", " << Full_Buffer[ii] << endl;
  309.       }
  310.       pass_in_file->close();
  311.       //exit(77);
  312.    }
  313.    // transform block of input samples
  314.    FftDitNipo( Full_Buffer, Fft_Size);
  315.    if(!Bypass_Enabled)
  316.    {
  317.       // multiply by sampled frequency response
  318.       for( is=0; is<Fft_Size; is++)
  319.       {
  320.          phase = std::arg(Full_Buffer[is]) + RAD_PER_DEG*Phase_Resp[is];
  321.          magnitude = std::abs(Full_Buffer[is]) * Mag_Resp[is];
  322.          Full_Buffer[is]=std::complex<float>(magnitude*cos(phase), magnitude*sin(phase));
  323.       }
  324.    }
  325.    // transform back to time domain
  326.    IfftDitNipo( Full_Buffer, Fft_Size);
  327.    // copy results to output buffer
  328.    memcpy(out_sig_ptr, Full_Buffer, Block_Size*sizeof(std::complex<float>));
  329.    for(int ix=0;ix<Block_Size;ix++)
  330.    {
  331.       out_sig_ptr[ix] /= Fft_Size;
  332.    }
  333. //   if(PassNumber == 2)
  334. //   {
  335. //      ofstream *sing_file = new ofstream("FftOutput_2.txt",ios::out);
  336. //      for(int ii=0; ii<Fft_Size; ii++)
  337. //      {
  338. //         //*sing_file << ((PassNumber-1)*46+ii) << ", " << Full_Buffer[ii] << endl;
  339. //         *sing_file << ii << ", " << Full_Buffer[ii] << endl;
  340. //      }
  341. //      sing_file->close();
  342. //      exit(77);
  343. //   }
  344.    if(Block_Size >= Num_Saved_Samps)
  345.    {
  346.       memcpy(  &Full_Buffer[Block_Size],
  347.                &in_sig_ptr[block_size-num_saved_samps],
  348.                num_saved_samps*sizeof(std::complex<float>));
  349.    }
  350.    else
  351.    {
  352.       memcpy(  &Full_Buffer[Block_Size],
  353.                &in_sig_ptr[2*block_size],
  354.                (num_saved_samps-block_size)*sizeof(std::complex<float>));
  355.       memcpy(  &Full_Buffer[num_saved_samps],
  356.                in_sig_ptr,
  357.                block_size*sizeof(std::complex<float>));
  358.    }
  359.    //---------------------
  360.    return(_MES_AOK);
  361. }