filter.~h

来自「脑电信号分析软件」· ~H 代码 · 共 352 行

~H
352
字号
#ifndef FILTER_H
#define FILTER_H

#include "FilterDesign.h"
#include <string>
#include <map>
#include <algorithm>

#define WIN_OS

#ifdef WIN_OS
	#include <windows.h>
#endif

/*!----------------------------------------------------------------------------
 * \brief 滤波器接口类
 *
 *     定义了所有滤波器所必需实现的接口。 在删除滤波器中预留了两种失败的处理方法接口。
 * 失败可以选择抛出异常或者使用返回值判断。
 *
 * \warning 所有的接口如果出现错误抛出异常, 不返回错误标记。参数设置上的逻辑错误直接抛出。 致命的错误
 * 记录在程序日志中再抛出。
 *
 *     \todo 对缓冲区中特定的导联做滤波。
 *
 * ----------------------------------------------------------------------------*/
class Filter
{
	public:
		//! \todo 有时间用模版将类型定义下移,参照另一个todo
		enum FilterType {BUTTER, CHEBY_ONE, CHEBY_TWO};

		virtual ~Filter();
		
		/*!----------------------------------------------------------------------------
		 * \brief 设置滤波器状态
		 *
		 * \param aActive 设置是否激活滤波器
		 *
		 * ----------------------------------------------------------------------------*/ 
		virtual void SetStatus(bool bActive) = 0;

		/*!----------------------------------------------------------------------------
		 * \brief 获得滤波器是否处于激活状态
		 *
		 * \return bool
		 *
		 * ----------------------------------------------------------------------------*/ 
		virtual bool GetStatus() = 0;

		/*!----------------------------------------------------------------------------
		 * \brief  复位滤波器
		 *
		 * ----------------------------------------------------------------------------*/
		virtual void Reset() = 0;

		//TODO 这种能力很有用。 但目前的滤波功能要求不需要以后再说
		//virtual bool Enabled(FilterType filter, bool bSwitch);
		/*!----------------------------------------------------------------------------
		 * \brief 得到导联数
		 *
		 * \return 数据缓冲区的导联数
		 *
		 * ----------------------------------------------------------------------------*/ 
		virtual int		GetLeadCount() = 0;

		/*!----------------------------------------------------------------------------
		 * \brief 设置导联数
		 *
		 * \param leadCount 缓冲区顺序存储的导联数
		 *
		 * ----------------------------------------------------------------------------*/ 
		virtual void	SetLeadCount(int leadCount) = 0;

		/*!----------------------------------------------------------------------------
		 * \brief 获得采样率
		 *
		 * 采样率是实际值。 如100,200……
		 *
		 * \return 波形数据的采样率
		 *
		 * ----------------------------------------------------------------------------*/ 
		virtual int		GetFs() = 0;

		/*!----------------------------------------------------------------------------
		 * \brief 设置采样率
		 *
		 * ----------------------------------------------------------------------------*/ 
		virtual void	SetFs(int fs) = 0;

		/*!----------------------------------------------------------------------------
		 * \brief 滤波
		 *
		 * 参考:
		 *     Filter::Filtering(short int *buf, int size, int leadCount),
		 *     Filter::Filtering(short int *buf, int size)
		 *     
		 * ----------------------------------------------------------------------------*/ 
		virtual void Filtering(short int *buf, int size) = 0;

		/*!----------------------------------------------------------------------------
		 * \brief 滤波
		 *
		 *     对给定的缓冲区进行滤波。滤波后的数据存在所给的缓冲区
		 *
		 * \param buf	数据缓冲区
		 * \param size	缓冲区大小
		 * \param leadCount 使用已经设置的导联数
		 *
		 * ----------------------------------------------------------------------------*/
		virtual void Filtering(short int *buf, int size, int leadCount) = 0;

		
		/*!----------------------------------------------------------------------------
		 * \brief  计算幅频响应
		 *
		 * \param Freq 要求的频率点
		 *
		 * ----------------------------------------------------------------------------*/
		virtual double MagResponse(double Freq) = 0;

		/* TODO 
		   virtual void FilteringNo(short int *buf, int size, int leadNo) = 0;
		   virtual void FilteringNo(short int *buf, int size, int leadNo, int leadCount) = 0;*/

		/*!----------------------------------------------------------------------------
		 * \brief 添加低通滤波器
		 *
		 * \param filterType 滤波类型
		 * \param fPass		下通带频率
		 * \param fStop		上阻带频率
		 * \param aPass		通带最大衰减
		 * \param aStop		阻带最小衰减
		 *
		 *     在添加高低通滤波器的时候其实不用考虑“下通带频率”“上阻带”只要把两个要设置的
		 * 频率从小到大填入两个参数中就可以了。
		 *
		 * \warning 如果低通已经存在,把它移除然后添加新的低通
		 *
		 * ----------------------------------------------------------------------------*/ 
        virtual void AddLowPass(FilterType filterType, double fPass, double fStop,
                                    double aPass, double aStop) = 0;
		/*!----------------------------------------------------------------------------
		 * \brief 添加低通滤波器
		 *
		 * \param filterType 滤波类型
		 * \param fPass		下通带频率
		 * \param fStop		上阻带频率
		 *
		 *     在添加高低通滤波器的时候其实不用考虑“下通带频率”“上阻带”只要把两个要设置的
		 * 频率从小到大填入两个参数中就可以了。
		 *
		 * \warning 如果低通已经存在,把它移除然后添加新的低通
		 *
		 * ----------------------------------------------------------------------------*/ 
		virtual void AddLowPass(FilterType filterType, double fPass, double fStop) = 0;

		/*----------------------------------------------------------------------------
		 * \brief 设置低通。
		 *
		 * 自动选择下阻带。 
		 *
		 * ----------------------------------------------------------------------------*/
		//virtual void AddLowPass(FilterType filterType, double fPass,
         //                           double aPass, double aStop) = 0;

		/*----------------------------------------------------------------------------
		 * \brief 设置低通。
		 *
		 * 自动选择下阻带。 参考IIRFilter::AddLowPass(FilterType filterType, double fPass, double fStop)
		 *
		 * ----------------------------------------------------------------------------*/
		//virtual void AddLowPass(FilterType filterType, double fPass) = 0;

		/*!----------------------------------------------------------------------------
		 * \brief 添加高通滤波器
		 *
		 * \param filterType 滤波类型
		 * \param fPass		下通带频率
		 * \param fStop		上阻带频率
		 * \param aPass		通带最大衰减
		 * \param aStop		阻带最小衰减
		 *
		 *     在添加高低通滤波器的时候其实不用考虑“上通带频率”“下阻带频率”只要把两个要设置的
		 * 频率从小到大填入两个参数中就可以了。
		 *
		 * \warning 如果高通已经存在,把它移除然后添加新的高通
		 *
		 * ----------------------------------------------------------------------------*/ 
        virtual void AddHeightPass(FilterType filterType, double fPass, double fStop,
                            double aPass, double aStop) = 0;

		/*!----------------------------------------------------------------------------
		 * \brief 添加高通滤波器
		 *
		 * \param filterType	滤波类型
		 * \param fStop			下阻带频率
		 * \param fPass			上通带频率
		 *
		 *     在添加高低通滤波器的时候其实不用考虑“上通带频率”“下阻带频率”只要把两个要设置的
		 * 频率从小到大填入两个参数中就可以了。
		 *
		 * \warning 如果高通已经存在,把它移除然后添加新的高通
		 *
		 * ----------------------------------------------------------------------------*/ 
		virtual void AddHeightPass(FilterType filterType, double fStop, double fPass) = 0;

		/*----------------------------------------------------------------------------
		 * \brief 设置高通。
		 *
		 * 自动选择下阻带。 
		 *
		 * ----------------------------------------------------------------------------*/
        /*virtual void AddHeightPass(FilterType filterType, double fPass,
                                    double aPass, double aStop) = 0;*/

		/*----------------------------------------------------------------------------
		 * \brief 设置高通。
		 *
		 * 自动选择下阻带。 参考IIRFilter::AddHeightPass(FilterType filterType, double fPass, double fStop)
		 *
		 * ----------------------------------------------------------------------------*/
		//virtual void AddHeightPass(FilterType filterType, double fPass) = 0;

		/*!----------------------------------------------------------------------------
		 * \brief 添加陷波器
		 *
		 * \param fre		陷波频率
		 * \param notchName	陷波器名称
		 *
		 * ----------------------------------------------------------------------------*/
		virtual void AddNotch(int fre, std::string notchName) = 0;

		/*!----------------------------------------------------------------------------
		 * \brief 移除特定名称的陷波器
		 *
		 * \return -1 失败, 0 陷波器不存在, 1 陷波器成功移除
		 * ----------------------------------------------------------------------------*/ 
		virtual int RemoveNotch(std::string notchName) = 0;

		/*!----------------------------------------------------------------------------
		 * \brief 移除低通
		 *
		 *  \return int 返回移除的数量。 0 没有低通,无法移除, 1 有低通,移除成功
		 * ----------------------------------------------------------------------------*/ 
		virtual int RemoveLowPass() = 0;

		/*!----------------------------------------------------------------------------
		 * \brief 移除高通
		 *
		 *  \return int 返回移除的数量。 0 没有高通,无法移除, 1 有高通,移除成功
		 * 
		 * ----------------------------------------------------------------------------*/ 
		virtual int RemoveHeightPass() = 0;

		/*!----------------------------------------------------------------------------
		 * \brief 移除所有高低通和陷波器
		 *
		 * \return int 返回移除的数量。 0 没有任何滤波器和陷波器, > 0 成功移除的数量
		 *
		 * ----------------------------------------------------------------------------*/ 
		virtual int RemoveAll() = 0;
};

/*!----------------------------------------------------------------------------
 * \brief 实现Filter接口
 *
 * \todo TODO: 考虑一下AddLowpass的第一个参数在基类中实现为模版,然后再在继承类中特化
 *       那么接口的enum的类型定义就可以往子类移动,以后添加类型什么的都不会涉及到
 *       基类的接口。
 *
 * \todo 很讨厌在最外这样包一层异常的写法。有没有更好的做法?
 *
 * 实现Filter接口。所有的函数功能请参照接口类Filter的说明
 *
 * ----------------------------------------------------------------------------*/ 
class IIRFilter : public Filter
{
	public:
		typedef std::map<std::string, FilterDesign*> StringFilterMap;
		typedef std::map<std::string, FilterDesign*>::iterator FilterMapIterator;

		IIRFilter(int fs, int leadCount);
		virtual ~IIRFilter();

		virtual void SetStatus(bool bActive);
		virtual bool GetStatus();
		
		virtual void Reset();
		
		virtual int		GetLeadCount();
		virtual void	SetLeadCount(int leadCount);

		virtual int		GetFs();
		virtual void	SetFs(int fs);

		virtual void Filtering(short int *buf, int size);
		virtual void Filtering(short int *buf, int size, int leadCount);

		virtual double MagResponse(double Freq);

                virtual void AddLowPass(FilterType filterType, double fPass, double fStop, double aPass, double aStop);
		virtual void AddLowPass(FilterType filterType, double fPass, double fStop);
		
		/*
		virtual void AddLowPass(FilterType filterType, double fPass,
                                double aPass, double aStop);
		virtual void AddLowPass(FilterType filterType, double fPass);*/

                virtual void AddHeightPass(FilterType filterType, double fStop, double fPass,double aPass, double aStop);
		virtual void AddHeightPass(FilterType filterType, double fStop, double fPass);
		/*
        virtual void AddHeightPass(FilterType filterType, double fPass,
                                double aPass, double aStop);
		virtual void AddHeightPass(FilterType filterType, double fPass);*/
		
		virtual void AddNotch(int fre, std::string notchName);

		virtual int RemoveNotch(std::string notchName);
		virtual int RemoveLowPass();
		virtual int RemoveHeightPass();

		virtual int RemoveAll();

//       	StringFilterMap filterList;

	protected:
		double FilterProc(int leadNo, double inDatum);
		//double Transform(int N,double Fenmu[20],double Fenzi[20],double x,
		//					double *z,bool flag,int lead);
		double Transform(int N,double *Fenmu,double *Fenzi,double x,double *z,bool flag,int lead);
		

		//!和滤波的频率不同,采样率限定为整数
		int fs; 
		//!导联数
		int leadCount;
		bool bActive;
		StringFilterMap filterList;

#ifdef WIN_OS
		HANDLE semaphore;
#endif
		

	private:
		int RemoveByName(std::string name);
		void AddPass(FilterType filterType, double lowFre, double heightFre,double aPass, double aStop, FilterDesign::PassType passType);
		
};
#endif

⌨️ 快捷键说明

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