filterdesign.~h
来自「脑电信号分析软件」· ~H 代码 · 共 326 行
~H
326 行
//---------------------------------------------------------------------------
#ifndef FilterDesignH
#define FilterDesignH
//---------------------------------------------------------------------------
#endif
#ifndef FILTERDESIGN_H
#define FILTERDESIGN_H
#include <math.h>
#include <iostream>
#include <iomanip>
#include <map>
#include <string>
#include <algorithm>
//#define MAXLEADNO 40
#define FILTER_ERROR(arg) filter_error(__FILE__, __LINE__, arg)
#define MAXFILTERLEAD 40
//!越接近1,陷波器宽度越窄
#define SETR 0.98
//!越接近1,陷波器衰减越厉害
#define SETr 0.99999
#define PI 4.0*atan(1.0)
void filter_error(char* pFile, int line, const std::string& what_arg);
/*!----------------------------------------------------------------------------
* \brief 滤波设计器的基类接口
*
* 这个类只定义了一些最基本的接口。把Conv卷积放在这里是因为没有时间把它和
* 那个差分函数合并起来了。所以实现在接口里了。
* \todo 发现在处理Z数组的时候的方法比较糟糕。数据和算法太紧密了? @i 2005-02-01 09:39
* \todo \varepsilon_{stop} 前的六条公式,可以往上一层的类提。 @i 2005-03-29 15:26
*
* ----------------------------------------------------------------------------*/
class FilterDesign
{
public:
enum PassType{HEIGHT_PASS, LOW_PASS, NOTCH}; //!滤波器类型
/*!----------------------------------------------------------------------------
* \brief 返回分子数组的指针
*
* \return double类型的数组指针
*
* ----------------------------------------------------------------------------*/
virtual double* GetNum() = 0;
/*!----------------------------------------------------------------------------
* \brief 返回分母数组的指针
*
* \return double类型的数组指针
*
* ----------------------------------------------------------------------------*/
virtual double* GetDen() = 0;
/*!----------------------------------------------------------------------------
* \brief 返回中间系数的指针
*
* \return double类型数组指针
*
* ----------------------------------------------------------------------------*/
virtual double* GetZ() = 0;
/*!----------------------------------------------------------------------------
* \brief 复位滤波设计器
*
* ----------------------------------------------------------------------------*/
virtual void Reset() = 0;
/*!----------------------------------------------------------------------------
* \brief 获取采样率
*
* \return int的采样率
*
* ----------------------------------------------------------------------------*/
virtual int GetFs() = 0;
/*!----------------------------------------------------------------------------
* \brief 设置采样率
* \param fs 采样率数值,实际数值如: 100,200...
*
* 设置采样率后重新生成阶数和系数
*
* ----------------------------------------------------------------------------*/
virtual void SetFs(int fs) = 0;
/*!----------------------------------------------------------------------------
* \brief 获取阶数
*
* \return int类型的滤波器阶数
*
* ----------------------------------------------------------------------------*/
virtual int GetOrder() = 0;
/*!----------------------------------------------------------------------------
* \brief
* 幅频响应
*
* \param freq 要求幅频值的频率点
*
* \return 幅频值
*
* ----------------------------------------------------------------------------*/
virtual double MagResponse(double freq) = 0;
virtual ~FilterDesign();
};
/*!----------------------------------------------------------------------------
* \brief IIR Filter Design 的接口类。
*
* 所有的IIR Filter Design 的通用代码放在这个类中。
*
* ----------------------------------------------------------------------------*/
class IIRFilterDesign : public FilterDesign
{
public:
//IIRFilterDesign(PassType passType, double fs, double aPass, double aStop);
IIRFilterDesign(PassType passType, double fs);
virtual ~IIRFilterDesign();
virtual void Reset();
virtual void GenerateCoe(); // 生成阶数, 系数。
virtual double MagResponse(double Freq);
virtual double* GetNum();
virtual double* GetDen();
virtual double* GetZ();
virtual int GetFs();
virtual void SetFs(int fs);
virtual int GetOrder();
protected:
int Conv(int M,double h[3],int L,double x[20],double y[20]);
double CN(int N,double x);//切比雪夫多项式
virtual void AllocateArray(); //分配分子分母数组
virtual void ReleaseArray();//释放已经分配的数组
virtual void ZeroZ();
//virtual void SetType(PassType passType, double lowFre, double heightFre);
//!通带类型
PassType passType;
//! 分母数组
double* pDen;
//! 分子数组
double* pNum;
//! 中间系数数组
double* pZ;
//! Ω0 ,3dB点
double OMEGA;
//! 阶数
int order;
//! 采样率
double fs;
private:
//void Init(PassType passType, double fs, double aPass, double aStop);
};
/*!----------------------------------------------------------------------------
* \brief Butterworth 滤波设计器,实现了FilterDesign接口
*
* 所有接口函数功能请参照IIRFilterDesign, FilterDesign。
*
* ----------------------------------------------------------------------------*/
class Butter: public IIRFilterDesign
{
public:
Butter(PassType passType, double fs, double lowFre, double heightFre, double aPass, double aStop);
Butter(PassType passType, double fs, double lowFre, double heightFre);
virtual ~Butter();
virtual void GenerateCoe(); // 生成阶数, 系数。
virtual double MagResponse(double Freq);
protected:
void GenerateLowCoe();
void GenerateHeightCoe();
private:
void Init(double lowFre, double heightFre, double aPass, double aStop);
//----------------------------------------------------------------
void Butter_Lowpass_N();
void Den_Butter_Lowpass();
void Num_Butter_Lowpass();
void Butter_Highpass_N();
void Den_Butter_Highpass();
void Num_Butter_Highpass();
double lowFre;
double heightFre;
//! 最大通带衰减
double Ap;
//! 最小止带衰减
double As;
};
/*!----------------------------------------------------------------------------
* \brief Chebyshev I 滤波设计器,实现了FilterDesign接口
*
* 所有接口函数功能请参照FilterDesign。
*
* ----------------------------------------------------------------------------*/
class ChebyOne : public IIRFilterDesign
{
public:
ChebyOne(PassType passType, double fs, double lowFre, double heightFre, double aPass, double aStop);
ChebyOne(PassType passType, double fs, double lowFre, double heightFre);
virtual ~ChebyOne();
virtual void GenerateCoe(); // 生成阶数, 系数。
virtual double MagResponse(double Freq);
protected:
void GenerateLowCoe();
void GenerateHeightCoe();
private:
void Init(double lowFre, double heightFre, double aPass, double aStop);
void Cheby_Lowpass_N();
void Den_Cheby_Lowpass();
void Num_Cheby_Lowpass();
void Cheby_Highpass_N();
void Den_Cheby_Highpass();
void Num_Cheby_Highpass();
double lowFre;
double heightFre;
//! 最大通带衰减
double Ap;
//! 最小止带衰减
double As;
};
/*!----------------------------------------------------------------------------
* \brief Chebyshev II 滤波设计器,实现了FilterDesign接口
*
* 所有接口函数功能请参照IIRFilterDesign, FilterDesign。
*
* \todo 通用的算法本来就不该是类。以后再把一些通用算法独立出来
*
* ----------------------------------------------------------------------------*/
class ChebyTwo : public IIRFilterDesign
{
public:
ChebyTwo(PassType passType, double fs, double lowFre, double heightFre, double aPass, double aStop);
ChebyTwo(PassType passType, double fs, double lowFre, double heightFre);
virtual ~ChebyTwo();
virtual void GenerateCoe(); // 生成阶数, 系数。
virtual double MagResponse(double Freq);
protected:
void GenerateLowCoe();
void GenerateHeightCoe();
private:
void Init(double lowFre, double heightFre, double aPass, double aStop);
void Cheby2_Lowpass_N();
void Den_Cheby2_Lowpass();
void Num_Cheby2_Lowpass();
void Cheby2_Highpass_N();
void Den_Cheby2_Highpass();
void Num_Cheby2_Highpass();
double lowFre;
double heightFre;
//! 最大通带衰减
double Ap;
//! 最小止带衰减
double As;
};
/*!----------------------------------------------------------------------------
* \brief 陷波器在f衰减为-65dB,在(f-1)和(f+1)点衰减为-1dB
*
* ----------------------------------------------------------------------------*/
class Notch : public IIRFilterDesign
{
public:
Notch(PassType passType, double fs, double fre);
virtual ~Notch();
virtual void GenerateCoe();
virtual double MagResponse(double Freq);
private:
void GenerateNotch();
//!这个陷波还是整数的好。只做整数陷波
int fre;
};
//TODO
//FilterCmp 滤波设计器排序类 不能用map的op排序value 郁闷。
//
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?