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

3G开发

开发平台:

Visual C++

  1. //
  2. //  File = dan_pdgm.cpp
  3. //
  4. #include <stdlib.h>
  5. #include <fstream>
  6. #include "parmfile.h"
  7. #include "model_graph.h"
  8. #include "dan_pdgm.h"
  9. #include "fft_T.h"
  10. #include "dump_spect.h"
  11. #ifdef _DEBUG
  12.   extern ofstream *DebugFile;
  13. #endif
  14. extern ParmFile *ParmInput;
  15. extern int PassNumber;
  16. //======================================================
  17. template <class T>
  18. DaniellPeriodogram<T>::DaniellPeriodogram( char* instance_name,
  19.                                   PracSimModel* outer_model,
  20.                                   Signal<T>* in_sig )
  21.                 :PracSimModel( instance_name,
  22.                                 outer_model )
  23. {
  24.   MODEL_NAME(DaniellPeriodogram);
  25.   OPEN_PARM_BLOCK;
  26.   GET_INT_PARM(Seg_Len);
  27.   GET_INT_PARM(Fft_Len);
  28.   GET_INT_PARM(Hold_Off);
  29.   GET_INT_PARM(Big_P);
  30.   Psd_File_Name = new char[64];
  31.   strcpy(Psd_File_Name, "");
  32.   GET_STRING_PARM(Psd_File_Name);
  33.   GET_DOUBLE_PARM(Freq_Norm_Factor);
  34.   GET_BOOL_PARM(Output_In_Decibels);
  35.   GET_BOOL_PARM(Plot_Two_Sided);
  36.   GET_BOOL_PARM(Halt_When_Completed);
  37.   In_Sig = in_sig;
  38.   MAKE_INPUT(In_Sig);
  39.   Time_Seg = new T[Seg_Len];
  40.   Dan_Pdgm = new double[Fft_Len];
  41.   Freq_Seg = new std::complex<double>[Fft_Len];
  42.   Psd_File = new ofstream(Psd_File_Name, ios::out);
  43.   Processing_Completed = false;
  44. }
  45. template <class T>
  46. DaniellPeriodogram<T>::~DaniellPeriodogram( void ){ };
  47. template <class T>
  48. void DaniellPeriodogram<T>::Initialize(void)
  49. {
  50.   Samps_Needed = Seg_Len;
  51.   Block_Size = In_Sig->GetBlockSize();
  52.   Samp_Intvl = In_Sig->GetSampIntvl();
  53.   Delta_F = 1.0/(Samp_Intvl*Fft_Len);
  54. };
  55. template <class T>
  56. int DaniellPeriodogram<T>::Execute()
  57. {
  58.    int k, m,is;
  59.    double scale_factor, sum;
  60.    #ifdef _DEBUG
  61.       *DebugFile << "In DaniellPeriodogram::Execute" << endl;
  62.    #endif
  63.    if(Processing_Completed) return(_MES_AOK);
  64.    if(PassNumber < Hold_Off+1) return (_MES_AOK);
  65.    //--------------------------------
  66.    //  Get pointers for buffers
  67.    T *in_sig_ptr = GET_INPUT_PTR(In_Sig);
  68.    int samps_avail = Block_Size;
  69.    while(Samps_Needed <= samps_avail)
  70.    {
  71.       //  The new input block has enough samples to finish a segment.
  72.       //  Fill up FFT buffer by getting Samps_Needed input samples.
  73.       for(is=Samps_Needed; is>0; is--)
  74.       {
  75.          Time_Seg[Seg_Len - is] = *in_sig_ptr++;
  76.       }
  77.       samps_avail -= Samps_Needed;
  78.       scale_factor = Seg_Len*(2*Big_P+1);
  79.       //  Perform FFT
  80.       FFT<double>(   Time_Seg,
  81.                      Freq_Seg,
  82.                      Seg_Len,
  83.                      Fft_Len);
  84.       //--------------------------------------
  85.       // Compute firts P points of periodogram
  86.       for(m=0; m<Big_P; m++)
  87.       {
  88.          sum = 0.0;
  89.          for( k=m-Big_P; k<0; k++)
  90.          {
  91.             sum += std::norm(Freq_Seg[Fft_Len + k]);
  92.          }
  93.          for(k=0; k<=(m+Big_P); k++)
  94.          {
  95.             sum += std::norm(Freq_Seg[k]);
  96.          }
  97.          Dan_Pdgm[m] = Samp_Intvl*sum/scale_factor;
  98.       }
  99.       //-------------------------------------------------------
  100.       //  Compute periodogram points P thru (N/2)-1
  101.       for(m=Big_P; m<(Fft_Len/2); m++)
  102.       {
  103.          sum = 0.0;
  104.          for( k=m-Big_P; k<=m+Big_P; k++)
  105.          {
  106.             sum += std::norm(Freq_Seg[k]);
  107.          }
  108.          Dan_Pdgm[m] = Samp_Intvl*sum/scale_factor;
  109.       }
  110.       // is it time to dump the results?
  111. //      if(Segs_In_Est == Num_Segs_To_Avg)
  112. //      {
  113.          DumpSpectrum(  Dan_Pdgm,
  114.                         Fft_Len,
  115.                         Delta_F,
  116.                         Freq_Norm_Factor,
  117.                         Output_In_Decibels,
  118.                         Plot_Two_Sided,
  119.                         Psd_File);
  120.          Processing_Completed = true;
  121.          Psd_File->close();
  122.          if(Halt_When_Completed)
  123.          {
  124.             #ifdef _DEBUG
  125.                *DebugFile << "Execution halted by " << GetModelName() << endl;
  126.             #endif
  127.             exit(0);
  128.          }
  129. //      }
  130.    }// end of while
  131.   //  The number of avail new samples is not sufficient to finish a segment.
  132.   //  Copy the avaialble samples and then wait for the next pass
  133.   //  to get some more.
  134.    for(is=0; is<samps_avail; is++)
  135.    {
  136.       Time_Seg[Seg_Len - Samps_Needed + is] = *in_sig_ptr++;
  137.    }
  138.    Samps_Needed -= samps_avail;
  139.    return(_MES_AOK);
  140. }
  141. template DaniellPeriodogram<float>;