原创 Labwindows/cvi8.5学习日志(49)----滤波器filter

2010-8-12 17:44 4405 10 9 分类: 软件与OS

e8f835df-cfc1-4908-bc30-c6a57473e69f.jpg


//*****************************************************************************
// Labwindows/cvi8.5  滤波器 filter
// szlihongtao
// 2010-08-12
//***************************************************************************** 
#include "toolbox.h"
#include <cvirte.h>  
#include <userint.h>
#include "filter.h"
#include <ansi_c.h>
#include <analysis.h>
 //*****************************************************************************
static double *sinewave;
static double *noisewave;
//*****************************************************************************  
static int wavepoint;    //总采样点数 
static int panelHandle;
void drawnoisegraph (void); //自定义函数,绘制叠加噪声后的波形 
//*****************************************************************************
int main (int argc, char *argv[])
{
 if (InitCVIRTE (0, argv, 0) == 0)
  return -1; /* out of memory */
 if ((panelHandle = LoadPanel (0, "filter.uir", PANEL)) < 0)
  return -1;
 DisplayPanel (panelHandle);
 RunUserInterface ();
 DiscardPanel (panelHandle);
 return 0;
}
//*****************************************************************************
int CVICALLBACK panelCB (int panel, int event, void *callbackData,
  int eventData1, int eventData2)
{
 switch (event)
 {
  case EVENT_CLOSE:
  {   
   free (sinewave);
   free (noisewave);
   QuitUserInterface (0);
   break;
  }
 }
 return 0;
}
//*****************************************************************************
int CVICALLBACK signal1 (int panel, int control, int event,
  void *callbackData, int eventData1, int eventData2)
{
 double phase;
 int samplepoint;
 int cycle;
 double amp;     
 
 switch (event)
 {
  case EVENT_COMMIT:
  { 
   //以下代码为获得采样信号的增益、周期、每周期采样点数及相位
   GetCtrlVal (panelHandle, PANEL_NUMERIC_AMP, &amp);
   GetCtrlVal (panelHandle, PANEL_NUMERIC_CYCLE, &cycle);
   GetCtrlVal (panelHandle, PANEL_NUMERIC_SAMPLEPOINT, &samplepoint);
   GetCtrlVal (panelHandle, PANEL_NUMERIC_PHASE, &phase);
   
   //获得总采样点数
   wavepoint = samplepoint * cycle;
   sinewave = malloc (wavepoint * sizeof (double));
   
   //产生正弦信号
   SinePattern (wavepoint, amp, phase, cycle, sinewave);
   DeleteGraphPlot (panelHandle, PANEL_GRAPH_SIGNAL, -1, VAL_IMMEDIATE_DRAW);
   PlotY (panelHandle, PANEL_GRAPH_SIGNAL, sinewave, wavepoint, VAL_DOUBLE, VAL_THIN_LINE, VAL_EMPTY_SQUARE, VAL_SOLID, 1, VAL_RED);
   SetCtrlVal (panelHandle, PANEL_NUMERIC_SAMPLEFREQ, wavepoint);
   break;
  }
 }
 return 0;
}
//*****************************************************************************
int CVICALLBACK noisetype (int panel, int control, int event,
  void *callbackData, int eventData1, int eventData2)
{
 int type;
 switch (event)
 {
  case EVENT_COMMIT:
  {  
   signal1 (panelHandle, PANEL_NUMERIC_AMP, EVENT_COMMIT, NULL, 0, 0);     // 再执行一次
   
   GetCtrlVal (panelHandle, PANEL_RING_NOISETYPE, &type);     //获得信号叠加噪声类型 
   
   noisewave = malloc (wavepoint * sizeof (double));     
   switch (type)
   {  
    case 0:     //在原信号基础上叠加均匀白噪声信号 
    {
     Uniform (wavepoint, 1, noisewave);
     break; 
    }  
    case 1:     //在原信号基础上叠加白噪声信号
    {
     WhiteNoise (wavepoint, 1.0, 1, noisewave);
     break;
    } 
    case 2:     //在原信号基础上叠加高斯白噪声信号 
    {
     GaussNoise (wavepoint, 1.0, 1, noisewave);
     break;
    }    
    case 3:     //在原信号基础上叠加抽样函数信号 
    {
     Sinc (wavepoint, 1.0, 0.0, Random (0, 1), noisewave);
     break;
    }
    default:
     break;
   }
   drawnoisegraph (); 
   break;
  }
 }
 return 0;
}
//*****************************************************************************
//用巴特沃斯滤波器滤波
//*****************************************************************************
int CVICALLBACK filter (int panel, int control, int event,
  void *callbackData, int eventData1, int eventData2)
{
 IIRFilterPtr filterinformation;  
 double *b;
 double *a;
 double *y;
 double *x;
 int order;
 int method;
 double lowercutoff;
 double highercutoff;
 int type;
 switch (event)
 {
  case EVENT_COMMIT:
  {
   noisetype (panelHandle, PANEL_RING_NOISETYPE, EVENT_COMMIT, NULL, 0, 0);
   
   //以下代码为获得滤波步骤、滤波器类型、上限截止频率、下限截止频率及滤波器阶数
   GetCtrlVal (panelHandle, PANEL_RING_FILTERMETHOD, &method);
   GetCtrlVal (panelHandle, PANEL_RING_FILTERTYPE, &type);
   GetCtrlVal (panelHandle, PANEL_NUMERIC_HIGHERCUTOFF, &highercutoff);
   GetCtrlVal (panelHandle, PANEL_NUMERIC_LOWERCUTOFF, &lowercutoff);
   GetCtrlVal (panelHandle, PANEL_NUMERIC_ORDER, &order);
   switch (method)
   {
    case 0:     //一步法或单步法滤波 
    { 
     //设置滤波条件
     if ((lowercutoff <= wavepoint/2)
      && (highercutoff <= wavepoint/2)
      && (lowercutoff < highercutoff))
     {
      switch (type)
      {
       case 0:    //低通滤波 
        Bw_LPF (noisewave, wavepoint, wavepoint, lowercutoff, order, noisewave);
        break;
       case 1:    //高通滤波  
        Bw_HPF (noisewave, wavepoint, wavepoint, highercutoff, order, noisewave);
        break;
       case 2:    //带通滤波 
        Bw_BPF (noisewave, wavepoint, wavepoint, lowercutoff, highercutoff, order, noisewave);
        break;
       case 3:     //带阻滤波 
        Bw_BSF (noisewave, wavepoint, wavepoint, lowercutoff, highercutoff, order, noisewave);
        break;
      }
     }
     else
      MessagePopup ("错误", "上限截止频率和下限截止频率不能大于采样频率的一半,\n且下限截止频率不能大于上限截止频率!");
     break;
    }    
    case 1:    //二步法或传统滤波法
    {
     if ((lowercutoff <= wavepoint/2)
      && (highercutoff <= wavepoint/2)
      && (lowercutoff < highercutoff))
     {
      a = malloc ((2 * order + 1) * sizeof (double));
      b = malloc ((2 * order + 1) * sizeof (double)); 
      y = malloc ((2 * order + 1) * sizeof (double));
      x = malloc ((2 * order + 1) * sizeof (double));
        
      //设置数组各元素为统一值
      Set1D (x, 2 * order + 1, 0.0);
      Set1D (y, 2 * order + 1, 0.0);
      switch (type)
      {
       case 0:  //构造低通巴特沃斯滤波函数  
        Bw_Coef (LOWPASS, order, wavepoint, lowercutoff, highercutoff, a, order + 1, b, order + 1);
        break;
       case 1:  //构造高通巴特沃斯滤波函数   
        Bw_Coef (HIGHPASS, order, wavepoint, lowercutoff, highercutoff, a, order + 1, b, order + 1);
        break;
       case 2:  //构造带通巴特沃斯滤波函数 
        Bw_Coef (BANDPASS, order, wavepoint, lowercutoff, highercutoff, a, 2 * order + 1, b, 2 * order + 1);
        break;
       case 3:   //构造带阻巴特沃斯滤波函数  
        Bw_Coef (BANDSTOP, order, wavepoint, lowercutoff, highercutoff, a, 2 * order + 1, b, 2 * order + 1);
        break;
      }
      
      //使用滤波函数
      IIRFiltering (noisewave, wavepoint, a, y, 2 * order + 1, b, x, 2 * order + 1, noisewave);
      free (a);
      free (b);
      free (x);
      free (y);
     }
     else
     {
      MessagePopup ("错误", "上限截止频率和下限截止频率不能大于采样频率的一半,\n且下限截止频率不能大于上限截止频率!");
     }     
     break;
    } 
    case 2:      //三步法或多步滤波法  
    {
     if ((lowercutoff <= wavepoint/2)
      && (highercutoff <= wavepoint/2)
      && (lowercutoff < highercutoff))
     {
      switch (type)
      {
       case 0:      //定义低通滤波器结构   
        filterinformation = AllocIIRFilterPtr (LOWPASS, order);
        break;
       case 1:    //定义高通滤波器结构  
        filterinformation = AllocIIRFilterPtr (HIGHPASS, order);
        break;
       case 2:     //定义带通滤波器结构  
        filterinformation = AllocIIRFilterPtr (BANDPASS, order);
        break;
       case 3:       //定义带阻滤波器结构  
        filterinformation = AllocIIRFilterPtr (BANDSTOP, order);
        break;
      }
      
      //产生巴特沃斯滤波器系数
      Bw_CascadeCoef (wavepoint, lowercutoff, highercutoff, filterinformation);
        
      //信号滤波
      IIRCascadeFiltering (noisewave, wavepoint, filterinformation, noisewave);
        
      //释放滤波器结构
      FreeIIRFilterPtr (filterinformation);
     }
     else
     {
      MessagePopup ("错误", "上限截止频率和下限截止频率不能大于采样频率的一半,\n且下限截止频率不能大于上限截止频率!");
     }          
     break;
    }
   }
   DeleteGraphPlot (panelHandle, PANEL_GRAPH_FILTER, -1, VAL_IMMEDIATE_DRAW);
   PlotY (panelHandle, PANEL_GRAPH_FILTER, noisewave, wavepoint, VAL_DOUBLE, VAL_THIN_LINE, VAL_EMPTY_SQUARE, VAL_SOLID, 1, VAL_RED);
   break;
  }
 }
 return 0;
}
//*****************************************************************************
void drawnoisegraph (void)
{
 Add1D (sinewave, noisewave, wavepoint, noisewave);   
 DeleteGraphPlot (panelHandle, PANEL_GRAPH_NOISE, -1, VAL_IMMEDIATE_DRAW);
 PlotY (panelHandle, PANEL_GRAPH_NOISE, noisewave, wavepoint, VAL_DOUBLE, VAL_THIN_LINE, VAL_EMPTY_SQUARE, VAL_SOLID, 1, VAL_RED); 
}
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
10
关闭 站长推荐上一条 /3 下一条