⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iirswept.cpp

📁 Digital filter designer s handbook C++ code source
💻 CPP
字号:
//
//  File = iirswept.cpp
//

#include <fstream.h>
#include <math.h> 
#include <stdlib.h>
#include "iirswept.h"
#include "typedefs.h"
#include "misdefs.h"
extern ofstream DebugFile;

SweptResponse::SweptResponse( FilterImplementation *filter_implem,
                              double sampling_interval,
                              istream& uin,
                              ostream& uout )
{
 int resp_indx;
 double lambda, phase_lag, old_phase_lag;
 double input_val;
 double *output_tone;
 int samp_indx;
 int num_holdoff_samps;
 logical default_file_ok;
 Filter_Implem = filter_implem;

 int phase_indx;
 int num_worsening_phases, max_worsening_phases;
 int max_num_samps;
 int samps_per_corr;
 double cycles_per_corr;
 double max_correl, phase_offset, sum;
 double phase_delta, peak_mag;
 
 uout << "number of points in plot of frequency response?" << endl;
 uin >> Num_Resp_Pts;

 uout << "maximum swept frequency?" << endl;
 uin >> Max_Sweep_Freq;
 if(Max_Sweep_Freq > (0.5/sampling_interval) )
   {
    uout << "maximum swept frequency will be limited\n"
         << "to folding frequency of " 
         << (0.5/sampling_interval) << endl;
    Max_Sweep_Freq = 0.5/sampling_interval;
   }
 
 uout << "scaling?\n"
      << "  0 = linear, 1 = dB"  << endl;
 uin >> Db_Scale_Enabled;

 uout << "phase resolution?\n"
      << "  (in degrees)" << endl;
 uin >> phase_delta;
 if(phase_delta > 0.0) phase_delta = -phase_delta;

 uout << "number of worsening phases allowed\n"
      << "before aborting search and accepting\n"
      << "best found up to that point?" << endl;
 uin >> max_worsening_phases;

 uout << "numb sinewave cycles per correlation?" << endl;
 uin >> cycles_per_corr;
  
 if( Db_Scale_Enabled != 0) Db_Scale_Enabled = 1;
  
 uout << "default name for magnitude response output\n"
      << "file is win_resp.txt\n\n"
      << "is this okay?"
      << "  0 = NO, 1 = YES"
      << endl;
 uin >> default_file_ok;
  
 if( default_file_ok) 
    {
     Response_File = new ofstream("win_resp.txt", ios::out);
    }
  else
    {
     char *file_name;
     file_name = new char[31];
     
     uout << "enter complete name for output file (30 chars max)"
          << endl;
     uin >> file_name;
     Response_File = new ofstream(file_name, ios::out);
     delete []file_name;
    }
 Mag_Resp = new double[Num_Resp_Pts];
 Phase_Resp = new double[Num_Resp_Pts];
 max_num_samps = int((cycles_per_corr+1)*Num_Resp_Pts/
                 (Max_Sweep_Freq * sampling_interval));
 output_tone = new double[max_num_samps+2]; 
 old_phase_lag = 0.0;
 for( resp_indx=1; resp_indx<Num_Resp_Pts; resp_indx++)
   {
    lambda = resp_indx * Max_Sweep_Freq * 
              sampling_interval / (double) Num_Resp_Pts;
    samps_per_corr = int(Num_Resp_Pts*cycles_per_corr/
         (resp_indx * Max_Sweep_Freq * sampling_interval));
    num_holdoff_samps = int(Num_Resp_Pts/
         (resp_indx * Max_Sweep_Freq * sampling_interval));

    for( samp_indx=0; 
         samp_indx<(samps_per_corr+num_holdoff_samps);
         samp_indx++)
      {
       input_val = cos(lambda*samp_indx);
       output_tone[samp_indx] = 
                  filter_implem->ProcessSample(input_val);
      }
    exit(0);

    // look for peak output magnitude
    peak_mag = 0.0;
    for( samp_indx=num_holdoff_samps; 
         samp_indx<(samps_per_corr+num_holdoff_samps);
         samp_indx++)
      {
        if( fabs(output_tone[samp_indx]) > peak_mag)
          peak_mag = fabs(output_tone[samp_indx]);
      } 

   //===============================================
   // Create sinusoids in phase increments of 
   // phase_delta degrees and correlate them 
   // with the stored output tone.  Phase of sine
   // with maximum correlation will be taken as
   // phase response at that frquency.

   max_correl = 0.0;
   num_worsening_phases = 0;
   for(phase_indx=0; phase_indx < int(-360./phase_delta);
                     phase_indx++)
     {
      num_worsening_phases++;
      phase_offset = (old_phase_lag + 
                  (phase_indx * phase_delta)) * PI /180.0;
      sum = 0.0;
      for( samp_indx=num_holdoff_samps; 
           samp_indx<(samps_per_corr+num_holdoff_samps);
           samp_indx++)
        {
         sum += (output_tone[samp_indx]*
                cos(lambda*samp_indx + phase_offset));
        }
      if(sum > max_correl)
        {
          max_correl = sum;
          phase_lag = double(old_phase_lag + phase_indx*phase_delta);
          num_worsening_phases = 0;
        }
      if(num_worsening_phases > max_worsening_phases) break;
     }
   //---------------------------------------
   // "unwrap" phase to keep it all negative

   old_phase_lag = phase_lag
                   - max_worsening_phases * phase_delta;
   while(phase_lag >= 180.0)
     { phase_lag -= 360.0; }

   Phase_Resp[resp_indx] = phase_lag;
   if(Db_Scale_Enabled)
     {
     Mag_Resp[resp_indx] = 
          20.0 * log10(peak_mag);
     }
   else
     {Mag_Resp[resp_indx] = peak_mag;}
   }
 //if(Normalize_Enabled) NormalizeResponse();
 return;
}
//=======================================================
// destructor
//-------------------------------------------------------

SweptResponse::~SweptResponse()
{
 delete []Mag_Resp;
 delete Response_File;
}
//=======================================================
//  method to normalize magnitude response
//-------------------------------------------------------

void SweptResponse::NormalizeResponse( void )
{
 int n;
 double biggest;
 
 if(Db_Scale_Enabled)
   {
    biggest = -100.0; 
    
    for( n=1; n < Num_Resp_Pts; n++)
      {if(Mag_Resp[n]>biggest) biggest = Mag_Resp[n];}
    for( n=1; n < Num_Resp_Pts; n++)
      {Mag_Resp[n] = Mag_Resp[n] - biggest;}
   }
 else
   {
    biggest = 0.0;
    
    for( n=1; n < Num_Resp_Pts; n++)
      {if(Mag_Resp[n]>biggest) biggest = Mag_Resp[n];}
    for( n=1; n < Num_Resp_Pts; n++)
      {Mag_Resp[n] = Mag_Resp[n] / biggest;}
   }
 return;
}
//===========================================================
//  method to dump magnitude response to the stream
//  designated by Response_File
//-----------------------------------------------------------

void SweptResponse::DumpMagResp( void )
{
 double freq;
 
 //Response_File->setf(ios::fixed, ios::floatfield);
 for(int n=1; n<Num_Resp_Pts; n++)
   {
    freq = n * Max_Sweep_Freq / (double) Num_Resp_Pts;
    (*Response_File) << freq << ", " 
                     << Mag_Resp[n] << ", "
                     << Phase_Resp[n] << endl;
   }
 //Response_File->setf(0, ios::floatfield);
 return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -