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 + -
显示快捷键?