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