Browse Source

添加滤波器

master
zhaohe 1 year ago
parent
commit
e0a1efdd91
  1. 8
      CMakeLists.txt
  2. 8
      README.md
  3. 27
      mainwindow.cpp
  4. 59
      mainwindow.ui
  5. 294
      src/filter_algo_mgr.cpp
  6. 99
      src/filter_algo_mgr.hpp
  7. 204
      src/filter_group/algo/fir_filter.cpp
  8. 37
      src/filter_group/algo/fir_filter.hpp
  9. 0
      src/filter_group/algo/iflytop_simple_filter.cpp
  10. 0
      src/filter_group/algo/iflytop_simple_filter.h
  11. 41
      src/filter_group/fir_filter_group.cpp
  12. 39
      src/filter_group/fir_filter_group.hpp
  13. 100
      src/filter_group/if/if_filter_group.hpp
  14. 119
      src/filter_group/iir_filter_group.cpp
  15. 102
      src/filter_group/iir_filter_group.hpp

8
CMakeLists.txt

@ -35,13 +35,17 @@ set(PROJECT_SOURCES
src/qt_serial_datachannel.cpp src/qt_serial_datachannel.cpp
src/electrocardiograph_tester.cpp src/electrocardiograph_tester.cpp
src/filter_algo_mgr.cpp
libzqt/widgetplot2d.cpp libzqt/widgetplot2d.cpp
libzqt/widgetplot2d.ui libzqt/widgetplot2d.ui
libzqt/qcustomplot.cpp libzqt/qcustomplot.cpp
src/algo/iflytop_simple_filter.cpp
src/filter_algo_mgr.cpp
src/filter_group/algo/iflytop_simple_filter.cpp
src/filter_group/iir_filter_group.cpp
src/filter_group/fir_filter_group.cpp
src/filter_group/algo/fir_filter.cpp
app.rc app.rc
) )

8
README.md

@ -44,3 +44,11 @@ V4:
regcache.ch2set = ADS129X_SET_BITS(regcache.ch2set, ADS129X_MUXx, ADS129X_CHx_INPUT_TEST); regcache.ch2set = ADS129X_SET_BITS(regcache.ch2set, ADS129X_MUXx, ADS129X_CHx_INPUT_TEST);
``` ```
```
滤波器参考
https://github.com/TcheL/Road2Filter/blob/master/FIR/bpFIR.py
```

27
mainwindow.cpp

@ -8,7 +8,6 @@
#include "./ui_mainwindow.h" #include "./ui_mainwindow.h"
#include "ads129x/ads129x_type.h" #include "ads129x/ads129x_type.h"
#include "algo/iflytop_simple_filter.h"
#include "electrocardiograph_tester.hpp" #include "electrocardiograph_tester.hpp"
#include "filter_algo_mgr.hpp" #include "filter_algo_mgr.hpp"
#include "logger.hpp" #include "logger.hpp"
@ -170,6 +169,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
// qInstallMessageHandler(log_output); // qInstallMessageHandler(log_output);
wp2d = new WidgetPlot2D(); wp2d = new WidgetPlot2D();
wp2d->initGraphName(QStringList() << "心电"); wp2d->initGraphName(QStringList() << "心电");
FilterAlgoMgr::ins()->addFilter("心电");
/******************************************************************************* /*******************************************************************************
* * * *
@ -369,6 +369,12 @@ void MainWindow::constructUI() {
// rawDataPreviewShow("[CH4 ] %s", zhex2str(hex, hexlen).c_str()); // rawDataPreviewShow("[CH4 ] %s", zhex2str(hex, hexlen).c_str());
} }
}); });
// FilterCommon_WindowsType
auto windowsTypes = FilterAlgoMgr::ins()->windowsTypes();
for (auto &type : windowsTypes) {
ui->FilterCommon_WindowsType->addItem(type.c_str());
}
} }
void MainWindow::processException(zexception &e) { ishow("%s:%s", e.what(), ify_hrs_error_code_to_string((ify_hrs_error_code_t)e.ecode())); } void MainWindow::processException(zexception &e) { ishow("%s:%s", e.what(), ify_hrs_error_code_to_string((ify_hrs_error_code_t)e.ecode())); }
@ -695,7 +701,7 @@ void MainWindow::on_resetDevice_clicked() {
void MainWindow::on_FilterUpdateParameter_clicked() { void MainWindow::on_FilterUpdateParameter_clicked() {
instructionPreviewClear(); instructionPreviewClear();
FilterAlgoMgr::ins()->FilterCommon_setSampleTimeMs(ui->FilterCommon_SampleTimeMs->text().toFloat());
FilterAlgoMgr::ins()->setSampleTimeMs(ui->FilterCommon_SampleTimeMs->text().toFloat());
FilterAlgoMgr::ins()->LPFilter_setEnable(ui->LPFilter_Enable->isChecked()); FilterAlgoMgr::ins()->LPFilter_setEnable(ui->LPFilter_Enable->isChecked());
FilterAlgoMgr::ins()->LPFilter_setCutoffFreqHz(ui->LPFilter_CutoffFreqHz->text().toFloat()); FilterAlgoMgr::ins()->LPFilter_setCutoffFreqHz(ui->LPFilter_CutoffFreqHz->text().toFloat());
FilterAlgoMgr::ins()->LPFilter_setOrder(ui->LPFilter_Order->text().toInt()); FilterAlgoMgr::ins()->LPFilter_setOrder(ui->LPFilter_Order->text().toInt());
@ -709,6 +715,9 @@ void MainWindow::on_FilterUpdateParameter_clicked() {
FilterAlgoMgr::ins()->NOTCHFilter_setNotchWidthHz(ui->NOTCHFilter_NotchWidthHz->text().toFloat()); FilterAlgoMgr::ins()->NOTCHFilter_setNotchWidthHz(ui->NOTCHFilter_NotchWidthHz->text().toFloat());
FilterAlgoMgr::ins()->NOTCHFilter_setOrder(ui->NOTCHFilter_Order->text().toInt()); FilterAlgoMgr::ins()->NOTCHFilter_setOrder(ui->NOTCHFilter_Order->text().toInt());
FilterAlgoMgr::ins()->setWindowsSize(ui->FilterCommon_windowsSize->text().toInt());
FilterAlgoMgr::ins()->setWindowsType(ui->FilterCommon_WindowsType->currentText().toStdString());
FilterAlgoMgr::ins()->updateParameter(); FilterAlgoMgr::ins()->updateParameter();
on_buttonTabWidget_currentChanged(0); on_buttonTabWidget_currentChanged(0);
@ -716,7 +725,7 @@ void MainWindow::on_FilterUpdateParameter_clicked() {
} }
void MainWindow::on_buttonTabWidget_currentChanged(int index) { void MainWindow::on_buttonTabWidget_currentChanged(int index) {
ui->FilterCommon_SampleTimeMs->setText(QString::number(FilterAlgoMgr::ins()->FilterCommon_getSampleTimeMs()));
ui->FilterCommon_SampleTimeMs->setText(QString::number(FilterAlgoMgr::ins()->getSampleTimeMs()));
ui->LPFilter_Enable->setChecked(FilterAlgoMgr::ins()->LPFilter_getEnable()); ui->LPFilter_Enable->setChecked(FilterAlgoMgr::ins()->LPFilter_getEnable());
ui->LPFilter_CutoffFreqHz->setText(QString::number(FilterAlgoMgr::ins()->LPFilter_getCutoffFreqHz())); ui->LPFilter_CutoffFreqHz->setText(QString::number(FilterAlgoMgr::ins()->LPFilter_getCutoffFreqHz()));
ui->LPFilter_Order->setText(QString::number(FilterAlgoMgr::ins()->LPFilter_getOrder())); ui->LPFilter_Order->setText(QString::number(FilterAlgoMgr::ins()->LPFilter_getOrder()));
@ -729,6 +738,9 @@ void MainWindow::on_buttonTabWidget_currentChanged(int index) {
ui->NOTCHFilter_CenterFreqHz->setText(QString::number(FilterAlgoMgr::ins()->NOTCHFilter_getCenterFreqHz())); ui->NOTCHFilter_CenterFreqHz->setText(QString::number(FilterAlgoMgr::ins()->NOTCHFilter_getCenterFreqHz()));
ui->NOTCHFilter_NotchWidthHz->setText(QString::number(FilterAlgoMgr::ins()->NOTCHFilter_getNotchWidthHz())); ui->NOTCHFilter_NotchWidthHz->setText(QString::number(FilterAlgoMgr::ins()->NOTCHFilter_getNotchWidthHz()));
ui->NOTCHFilter_Order->setText(QString::number(FilterAlgoMgr::ins()->NOTCHFilter_getOrder())); ui->NOTCHFilter_Order->setText(QString::number(FilterAlgoMgr::ins()->NOTCHFilter_getOrder()));
ui->FilterCommon_windowsSize->setText(QString::number(FilterAlgoMgr::ins()->getWindowsSize()));
ui->FilterCommon_WindowsType->setCurrentText(QString::fromStdString(FilterAlgoMgr::ins()->getWindowType()));
} }
void MainWindow::on_TestCmd_writeSubICAllReg_clicked() { void MainWindow::on_TestCmd_writeSubICAllReg_clicked() {
@ -777,8 +789,7 @@ void MainWindow::on_setEcgInNormalMode_clicked() {
} }
} }
void MainWindow::on_setEcgReportDataInRawMode__1_clicked()
{
void MainWindow::on_setEcgReportDataInRawMode__1_clicked() {
instructionPreviewClear(); instructionPreviewClear();
try { try {
ElectrocardiographTester::ins()->set_ecg_report_data_in_raw_mode(1); ElectrocardiographTester::ins()->set_ecg_report_data_in_raw_mode(1);
@ -788,9 +799,7 @@ void MainWindow::on_setEcgReportDataInRawMode__1_clicked()
} }
} }
void MainWindow::on_setEcgReportDataInRawMode__0_clicked()
{
void MainWindow::on_setEcgReportDataInRawMode__0_clicked() {
instructionPreviewClear(); instructionPreviewClear();
try { try {
ElectrocardiographTester::ins()->set_ecg_report_data_in_raw_mode(0); ElectrocardiographTester::ins()->set_ecg_report_data_in_raw_mode(0);
@ -799,6 +808,4 @@ void MainWindow::on_setEcgReportDataInRawMode__0_clicked()
} catch (zexception &exception) { } catch (zexception &exception) {
processException(exception); processException(exception);
} }
} }

59
mainwindow.ui

@ -869,7 +869,7 @@ p, li { white-space: pre-wrap; }
</size> </size>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>0</number>
<number>2</number>
</property> </property>
<widget class="QWidget" name="buttonTabWidgetPage1"> <widget class="QWidget" name="buttonTabWidgetPage1">
<attribute name="title"> <attribute name="title">
@ -2158,8 +2158,8 @@ p, li { white-space: pre-wrap; }
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0">
<widget class="QLabel" name="label_10">
<item row="2" column="0">
<widget class="QLabel" name="label_12">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch> <horstretch>1</horstretch>
@ -2167,11 +2167,24 @@ p, li { white-space: pre-wrap; }
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text"> <property name="text">
<string>数据采样周期(ms)</string>
<string>windowsSize</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0">
<item row="2" column="1">
<widget class="QLineEdit" name="FilterCommon_windowsSize">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer_10"> <spacer name="verticalSpacer_10">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
@ -2184,6 +2197,35 @@ p, li { white-space: pre-wrap; }
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="0" column="0">
<widget class="QLabel" name="label_10">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>数据采样周期(ms)</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_15">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>windowsType</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="FilterCommon_WindowsType"/>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
@ -2204,6 +2246,13 @@ p, li { white-space: pre-wrap; }
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>GroupBox</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_12"> <spacer name="verticalSpacer_12">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>

294
src/filter_algo_mgr.cpp

@ -6,158 +6,212 @@
#include "zexception.hpp" #include "zexception.hpp"
using namespace iflytop; using namespace iflytop;
/***********************************************************************************************************************
* FilterAlgoMgr *
***********************************************************************************************************************/
void FilterGroup::initialize() {}
FilterAlgoMgr* FilterAlgoMgr::ins() {
static FilterAlgoMgr ins;
return &ins;
}
int32_t FilterGroup::processData(int32_t data) { //
std::lock_guard<std::recursive_mutex> lock(lock_);
void FilterAlgoMgr::addFilter(string channel) {
IF_FilterGroup* f = new IIRFilterGroup();
f->initialize();
m_filter_map[channel] = f;
}
float v0 = (float)data;
for (int i = 0; i < _lpfilter_order; i++) {
v0 = LPFilter_Update(&lpfilter[i], v0);
int32_t FilterAlgoMgr::processData(string channel, int32_t data) {
IF_FilterGroup* f = m_filter_map[channel];
if (f) {
return f->processData(data);
} else {
return data;
} }
}
for (int i = 0; i < _hpfilter_order; i++) {
v0 = HPFilter_Update(&hpfilter[i], v0);
void FilterAlgoMgr::LPFilter_setEnable(bool enable) {
for (auto& it : m_filter_map) {
it.second->LPFilter_setEnable(enable);
} }
}
void FilterAlgoMgr::LPFilter_setCutoffFreqHz(float cutoffFreqHz) { //
// filter.LPFilter_setCutoffFreqHz(cutoffFreqHz);
for (auto& it : m_filter_map) {
it.second->LPFilter_setCutoffFreqHz(cutoffFreqHz);
}
}
for (int i = 0; i < _notchfilter_order; i++) {
v0 = NOTCHFilter_Update(&notchfilter[i], v0);
bool FilterAlgoMgr::LPFilter_getEnable() { //
// return filter.LPFilter_getEnable();
for (auto& it : m_filter_map) {
return it.second->LPFilter_getEnable();
} }
return 0;
}
float FilterAlgoMgr::LPFilter_getCutoffFreqHz() { //
// return filter.LPFilter_getCutoffFreqHz();
for (auto& it : m_filter_map) {
return it.second->LPFilter_getCutoffFreqHz();
}
return 0;
}
return (int32_t)v0;
void FilterAlgoMgr::HPFilter_setEnable(bool enable) { //
// filter.HPFilter_setEnable(enable);
for (auto& it : m_filter_map) {
it.second->HPFilter_setEnable(enable);
}
}
void FilterAlgoMgr::HPFilter_setCutoffFreqHz(float cutoffFreqHz) { //
// filter.HPFilter_setCutoffFreqHz(cutoffFreqHz);
for (auto& it : m_filter_map) {
it.second->HPFilter_setCutoffFreqHz(cutoffFreqHz);
}
} }
void FilterGroup::updateParameter() {
std::lock_guard<std::recursive_mutex> lock(lock_);
bool FilterAlgoMgr::HPFilter_getEnable() { //
// return filter.HPFilter_getEnable();
for (auto& it : m_filter_map) {
return it.second->HPFilter_getEnable();
}
return 0;
}
float FilterAlgoMgr::HPFilter_getCutoffFreqHz() { //
// return filter.HPFilter_getCutoffFreqHz();
for (auto& it : m_filter_map) {
return it.second->HPFilter_getCutoffFreqHz();
}
return 0;
}
for (int i = 0; i < FILTER_MAX_ORDER; i++) {
LPFilter_Init(&lpfilter[i], LPFilter_cutoffFreqHz, sampleTimeMs / 1000.0, lpfilter_enable);
void FilterAlgoMgr::NOTCHFilter_setEnable(bool enable) { //
// filter.NOTCHFilter_setEnable(enable);
for (auto& it : m_filter_map) {
it.second->NOTCHFilter_setEnable(enable);
} }
for (int i = 0; i < FILTER_MAX_ORDER; i++) {
HPFilter_Init(&hpfilter[i], HPFilter_cutoffFreqHz, sampleTimeMs / 1000.0, hpfilter_enable);
}
void FilterAlgoMgr::NOTCHFilter_setCenterFreqHz(float centerFreqHz) { //
// filter.NOTCHFilter_setCenterFreqHz(centerFreqHz);
for (auto& it : m_filter_map) {
it.second->NOTCHFilter_setCenterFreqHz(centerFreqHz);
} }
for (int i = 0; i < FILTER_MAX_ORDER; i++) {
NOTCHFilter_Init(&notchfilter[i], NOTCHFilter_centerFreqHz, NOTCHFilter_notchWidthHz, sampleTimeMs / 1000.0, notchfilter_enable);
}
void FilterAlgoMgr::NOTCHFilter_setNotchWidthHz(float notchWidthHz) { //
// filter.NOTCHFilter_setNotchWidthHz(notchWidthHz);
for (auto& it : m_filter_map) {
it.second->NOTCHFilter_setNotchWidthHz(notchWidthHz);
} }
_lpfilter_order = lpfilter_order;
_hpfilter_order = hpfilter_order;
_notchfilter_order = notchfilter_order;
} }
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
void FilterGroup::setSampleTimeMs(float sampleTimeMs) {
if (sampleTimeMs < 0.4) {
throw zexception(kifyhrs_ecode_upper_exception, "sampleTimeMs must be greater than 0.4ms");
bool FilterAlgoMgr::NOTCHFilter_getEnable() { //
// return filter.NOTCHFilter_getEnable();
for (auto& it : m_filter_map) {
return it.second->NOTCHFilter_getEnable();
} }
this->sampleTimeMs = sampleTimeMs;
return 0;
}
float FilterAlgoMgr::NOTCHFilter_getCenterFreqHz() { //
// return filter.NOTCHFilter_getCenterFreqHz();
for (auto& it : m_filter_map) {
return it.second->NOTCHFilter_getCenterFreqHz();
}
return 0;
}
float FilterAlgoMgr::NOTCHFilter_getNotchWidthHz() { //
// return filter.NOTCHFilter_getNotchWidthHz();
for (auto& it : m_filter_map) {
return it.second->NOTCHFilter_getNotchWidthHz();
}
return 0;
} }
float FilterGroup::getSampleTimeMs() { return sampleTimeMs; }
void FilterGroup::LPFilter_setOrder(int order) {
if (order < 1) {
order = 1;
void FilterAlgoMgr::setSampleTimeMs(float sampleTimeMs) { //
// filter.setSampleTimeMs(sampleTimeMs);
for (auto& it : m_filter_map) {
it.second->setSampleTimeMs(sampleTimeMs);
} }
if (order > FILTER_MAX_ORDER) {
order = FILTER_MAX_ORDER;
}
float FilterAlgoMgr::getSampleTimeMs() { //
// return filter.getSampleTimeMs();
for (auto& it : m_filter_map) {
return it.second->getSampleTimeMs();
} }
lpfilter_order = order;
return 0;
} }
int FilterGroup::LPFilter_getOrder() { return lpfilter_order; }
void FilterGroup::HPFilter_setOrder(int order) {
if (order < 1) {
order = 1;
void FilterAlgoMgr::setWindowsSize(int windows_size) {
for (auto& it : m_filter_map) {
it.second->setWindowsSize(windows_size);
} }
if (order > FILTER_MAX_ORDER) {
order = FILTER_MAX_ORDER;
}
int FilterAlgoMgr::getWindowsSize() {
for (auto& it : m_filter_map) {
return it.second->getWindowsSize();
} }
hpfilter_order = order;
return 0;
} }
int FilterGroup::HPFilter_getOrder() { return hpfilter_order; }
void FilterGroup::NOTCHFilter_setOrder(int order) {
if (order < 1) {
order = 1;
void FilterAlgoMgr::setWindowsType(string windowType) {
for (auto& it : m_filter_map) {
it.second->setWindowsType(windowType);
} }
if (order > FILTER_MAX_ORDER) {
order = FILTER_MAX_ORDER;
}
string FilterAlgoMgr::getWindowType() {
for (auto& it : m_filter_map) {
return it.second->getWindowType();
} }
notchfilter_order = order;
return "";
} }
int FilterGroup::NOTCHFilter_getOrder() { return notchfilter_order; }
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
void FilterGroup::LPFilter_setEnable(bool enable) { lpfilter_enable = enable; }
void FilterGroup::LPFilter_setCutoffFreqHz(float cutoffFreqHz) { LPFilter_cutoffFreqHz = cutoffFreqHz; }
bool FilterGroup::LPFilter_getEnable() { return lpfilter_enable; }
float FilterGroup::LPFilter_getCutoffFreqHz() { return LPFilter_cutoffFreqHz; }
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
void FilterGroup::HPFilter_setEnable(bool enable) { hpfilter_enable = enable; }
void FilterGroup::HPFilter_setCutoffFreqHz(float cutoffFreqHz) { HPFilter_cutoffFreqHz = cutoffFreqHz; }
bool FilterGroup::HPFilter_getEnable() { return hpfilter_enable; }
float FilterGroup::HPFilter_getCutoffFreqHz() { return HPFilter_cutoffFreqHz; }
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
void FilterGroup::NOTCHFilter_setEnable(bool enable) { notchfilter_enable = enable; }
void FilterGroup::NOTCHFilter_setCenterFreqHz(float centerFreqHz) { NOTCHFilter_centerFreqHz = centerFreqHz; }
void FilterGroup::NOTCHFilter_setNotchWidthHz(float notchWidthHz) { NOTCHFilter_notchWidthHz = notchWidthHz; }
bool FilterGroup::NOTCHFilter_getEnable() { return notchfilter_enable; }
float FilterGroup::NOTCHFilter_getCenterFreqHz() { return NOTCHFilter_centerFreqHz; }
float FilterGroup::NOTCHFilter_getNotchWidthHz() { return NOTCHFilter_notchWidthHz; }
/***********************************************************************************************************************
* FilterAlgoMgr *
***********************************************************************************************************************/
FilterAlgoMgr* FilterAlgoMgr::ins() {
static FilterAlgoMgr ins;
return &ins;
vector<string> FilterAlgoMgr::windowsTypes() {
return IF_FilterGroup::windowsTypes();
} }
int32_t FilterAlgoMgr::processData(string channel, int32_t data) { return filter.processData(data); }
void FilterAlgoMgr::LPFilter_setEnable(bool enable) { filter.LPFilter_setEnable(enable); }
void FilterAlgoMgr::LPFilter_setCutoffFreqHz(float cutoffFreqHz) { filter.LPFilter_setCutoffFreqHz(cutoffFreqHz); }
bool FilterAlgoMgr::LPFilter_getEnable() { return filter.LPFilter_getEnable(); }
float FilterAlgoMgr::LPFilter_getCutoffFreqHz() { return filter.LPFilter_getCutoffFreqHz(); }
void FilterAlgoMgr::HPFilter_setEnable(bool enable) { filter.HPFilter_setEnable(enable); }
void FilterAlgoMgr::HPFilter_setCutoffFreqHz(float cutoffFreqHz) { filter.HPFilter_setCutoffFreqHz(cutoffFreqHz); }
bool FilterAlgoMgr::HPFilter_getEnable() { return filter.HPFilter_getEnable(); }
float FilterAlgoMgr::HPFilter_getCutoffFreqHz() { return filter.HPFilter_getCutoffFreqHz(); }
void FilterAlgoMgr::NOTCHFilter_setEnable(bool enable) { filter.NOTCHFilter_setEnable(enable); }
void FilterAlgoMgr::NOTCHFilter_setCenterFreqHz(float centerFreqHz) { filter.NOTCHFilter_setCenterFreqHz(centerFreqHz); }
void FilterAlgoMgr::NOTCHFilter_setNotchWidthHz(float notchWidthHz) { filter.NOTCHFilter_setNotchWidthHz(notchWidthHz); }
void FilterAlgoMgr::LPFilter_setOrder(int order) { //
// filter.LPFilter_setOrder(order);
for (auto& it : m_filter_map) {
it.second->LPFilter_setOrder(order);
}
}
int FilterAlgoMgr::LPFilter_getOrder() { //
// return filter.LPFilter_getOrder();
for (auto& it : m_filter_map) {
return it.second->LPFilter_getOrder();
}
return 0;
bool FilterAlgoMgr::NOTCHFilter_getEnable() { return filter.NOTCHFilter_getEnable(); }
float FilterAlgoMgr::NOTCHFilter_getCenterFreqHz() { return filter.NOTCHFilter_getCenterFreqHz(); }
float FilterAlgoMgr::NOTCHFilter_getNotchWidthHz() { return filter.NOTCHFilter_getNotchWidthHz(); }
}
void FilterAlgoMgr::HPFilter_setOrder(int order) { //
// filter.HPFilter_setOrder(order);
for (auto& it : m_filter_map) {
it.second->HPFilter_setOrder(order);
}
}
int FilterAlgoMgr::HPFilter_getOrder() { //
// return filter.HPFilter_getOrder();
for (auto& it : m_filter_map) {
return it.second->HPFilter_getOrder();
}
return 0;
void FilterAlgoMgr::FilterCommon_setSampleTimeMs(float sampleTimeMs) { filter.setSampleTimeMs(sampleTimeMs); }
float FilterAlgoMgr::FilterCommon_getSampleTimeMs() { return filter.getSampleTimeMs(); }
}
void FilterAlgoMgr::NOTCHFilter_setOrder(int order) { //
// filter.NOTCHFilter_setOrder(order);
for (auto& it : m_filter_map) {
it.second->NOTCHFilter_setOrder(order);
}
}
int FilterAlgoMgr::NOTCHFilter_getOrder() { //
// return filter.NOTCHFilter_getOrder();
for (auto& it : m_filter_map) {
return it.second->NOTCHFilter_getOrder();
}
return 0;
void FilterAlgoMgr::LPFilter_setOrder(int order) { filter.LPFilter_setOrder(order); }
int FilterAlgoMgr::LPFilter_getOrder() { return filter.LPFilter_getOrder(); }
void FilterAlgoMgr::HPFilter_setOrder(int order) { filter.HPFilter_setOrder(order); }
int FilterAlgoMgr::HPFilter_getOrder() { return filter.HPFilter_getOrder(); }
void FilterAlgoMgr::NOTCHFilter_setOrder(int order) { filter.NOTCHFilter_setOrder(order); }
int FilterAlgoMgr::NOTCHFilter_getOrder() { return filter.NOTCHFilter_getOrder(); }
}
void FilterAlgoMgr::updateParameter() { filter.updateParameter(); }
void FilterAlgoMgr::updateParameter() { //
// filter.updateParameter();
for (auto& it : m_filter_map) {
it.second->updateParameter();
}
}

99
src/filter_algo_mgr.hpp

@ -12,109 +12,36 @@
#include <thread> #include <thread>
#include <vector> #include <vector>
#include "algo/iflytop_simple_filter.h"
#include "filter_group/fir_filter_group.hpp"
#include "filter_group/iir_filter_group.hpp"
//
namespace iflytop { namespace iflytop {
using namespace std; using namespace std;
#define FILTER_MAX_ORDER 10 #define FILTER_MAX_ORDER 10
class FilterGroup {
private:
LPFilter_t lpfilter[10] = {0};
HPFilter_t hpfilter[10] = {0};
NOTCHFilter_t notchfilter[10] = {0};
int _lpfilter_order = 1;
int _hpfilter_order = 1;
int _notchfilter_order = 1;
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
bool lpfilter_enable = false;
bool hpfilter_enable = false;
bool notchfilter_enable = false;
int lpfilter_order = 1;
int hpfilter_order = 1;
int notchfilter_order = 1;
float LPFilter_cutoffFreqHz = 0;
float HPFilter_cutoffFreqHz = 0;
float NOTCHFilter_centerFreqHz = 0;
float NOTCHFilter_notchWidthHz = 0;
float sampleTimeMs = 2; // 1ms
std::recursive_mutex lock_;
public:
void initialize();
int32_t processData(int32_t data);
void updateParameter();
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
void setSampleTimeMs(float sampleTimeMs);
float getSampleTimeMs();
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
void LPFilter_setEnable(bool enable);
void LPFilter_setCutoffFreqHz(float cutoffFreqHz);
void LPFilter_setOrder(int order);
bool LPFilter_getEnable();
float LPFilter_getCutoffFreqHz();
int LPFilter_getOrder();
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
void HPFilter_setEnable(bool enable);
void HPFilter_setCutoffFreqHz(float cutoffFreqHz);
void HPFilter_setOrder(int order);
bool HPFilter_getEnable();
float HPFilter_getCutoffFreqHz();
int HPFilter_getOrder();
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
void NOTCHFilter_setEnable(bool enable);
void NOTCHFilter_setCenterFreqHz(float centerFreqHz);
void NOTCHFilter_setNotchWidthHz(float notchWidthHz);
void NOTCHFilter_setOrder(int order);
bool NOTCHFilter_getEnable();
float NOTCHFilter_getCenterFreqHz();
float NOTCHFilter_getNotchWidthHz();
int NOTCHFilter_getOrder();
};
class FilterAlgoMgr { class FilterAlgoMgr {
private: private:
FilterGroup filter;
map<string, IF_FilterGroup*> m_filter_map;
public: public:
FilterAlgoMgr(/* args */) {} FilterAlgoMgr(/* args */) {}
~FilterAlgoMgr() {} ~FilterAlgoMgr() {}
static FilterAlgoMgr* ins(); static FilterAlgoMgr* ins();
void addFilter(string channel);
int32_t processData(string channel, int32_t data); int32_t processData(string channel, int32_t data);
void updateParameter(); void updateParameter();
void FilterCommon_setSampleTimeMs(float sampleTimeMs);
float FilterCommon_getSampleTimeMs();
void setSampleTimeMs(float sampleTimeMs);
float getSampleTimeMs();
void setWindowsSize(int windows_size);
int getWindowsSize();
void setWindowsType(string windowType);
string getWindowType();
vector<string> windowsTypes();
/*********************************************************************************************************************** /***********************************************************************************************************************
* * * *

204
src/filter_group/algo/fir_filter.cpp

@ -0,0 +1,204 @@
#include "fir_filter.hpp"
static double sinc(const double x)
{
if (x == 0)
return 1;
return sin(M_PI * x) / (M_PI * x);
}
FIR_filter::FIR_filter( int taps, double f1, double f2, const char* type,
const char* window): h(taps, 0), samples(taps, 0)
{
this->idx = 0;
this->taps = taps;
std::vector<double> h; // Buffer FIR coefficients
std::vector<double> w; // Buffer window coefficients
// Calculate the coefficient corresponding to the filter type
if (!strcmp(type, "lp")) {
h = lowPass_coefficient(taps, f1);
}
else if (!strcmp(type, "hp")) {
h = highPass_coefficient(taps, f1);
}
else if (!strcmp(type, "bp")) {
h = bandPass_coefficient(taps, f1, f2);
}
else if (!strcmp(type, "sb")) {
h = bandStop_coefficient(taps, f1, f2);
}
// Calculate the window to improve the FIR filter
if (!strcmp(window, "hamming")) {
w = window_hammig(taps);
}
else if (!strcmp(window, "triangle")) {
w = window_triangle(taps);
}
else if (!strcmp(window, "hanning")) {
w = window_hanning(taps);
}
else if (!strcmp(window, "blackman")) {
w = window_blackman(taps);
}
if (!strcmp(window, "")) {
this->h = h;
}
else
{
for(int n = 0; n < taps; n++) {
this->h[n] = h[n] * w[n];
}
}
}
FIR_filter::~FIR_filter()
{
}
std::vector<double> FIR_filter::getCoefficients()
{
return this->h;
}
std::vector<double> FIR_filter::lowPass_coefficient(int taps, double f)
{
std::vector<int> n(taps, 0);
std::vector<double> h(taps, 0);
for(int i = 0; i < taps; i++) {
n[i] = i - int(taps/2);
}
for(int i = 0; i < taps; i++) {
h[i] = 2.0*f*sinc(2.0*f*n[i]);
}
return h;
}
std::vector<double> FIR_filter::highPass_coefficient(int taps, double f)
{
std::vector<int> n(taps, 0);
std::vector<double> h(taps, 0);
for(int i = 0; i < taps; i++) {
n[i] = i - int(taps/2);
}
for(int i = 0; i < taps; i++) {
h[i] = sinc(n[i]) - 2.0*f*sinc(2.0*f*n[i]);
}
return h;
}
std::vector<double> FIR_filter::bandPass_coefficient(int taps, double f1, double f2)
{
std::vector<int> n(taps, 0);
std::vector<double> h(taps, 0);
for(int i = 0; i < taps; i++) {
n[i] = i - int(taps/2);
}
for(int i = 0; i < taps; i++) {
h[i] = 2.0*f1*sinc(2.0*f1*n[i]) - 2.0*f2*sinc(2.0*f2*n[i]);
}
return h;
}
std::vector<double> FIR_filter::bandStop_coefficient(int taps, double f1, double f2)
{
std::vector<int> n(taps, 0);
std::vector<double> h(taps, 0);
for(int i = 0; i < taps; i++) {
n[i] = i - int(taps/2);
}
for(int i = 0; i < taps; i++) {
h[i] = 2.0*f1*sinc(2.0*f1*n[i]) - 2.0*f2*sinc(2.0*f2*n[i]) + sinc(n[i]);
}
return h;
}
std::vector<double> FIR_filter::window_hammig(int taps)
{
std::vector<int> n(taps, 0);
std::vector<double> w(taps, 0);
double alpha = 0.54;
double beta = 0.46;
for(int i = 0; i < taps; i++) {
w[i] = alpha - beta * cos(2.0 * M_PI * i / (taps - 1));
}
return w;
}
std::vector<double> FIR_filter::window_hanning(int taps)
{
std::vector<double> w(taps, 0);
for(int i = 0; i < taps; i++) {
w[i] = sin(((double) M_PI * i) / (taps - 1)) *
sin(((double) M_PI * i) / (taps - 1));
}
return w;
}
std::vector<double> FIR_filter::window_triangle(int taps)
{
std::vector<double> w(taps, 0);
double l = taps;
for(int i = 0; i < taps; i++) {
w[i] = 1 - abs((i - (((double)(taps-1)) / 2.0)) / (((double)l) / 2.0));
}
return w;
}
std::vector<double> FIR_filter::window_blackman(int taps)
{
std::vector<double> w(taps, 0);
double alpha0 = 0.42;
double alpha1 = 0.5;
double alpha2 = 0.08;
for(int i = 0; i < taps; i++) {
w[i] = alpha0 - alpha1 * cos(2.0 * M_PI * i / (taps - 1))
- alpha2 * cos(4.0 * M_PI * i / (taps - 1));
}
return w;
}
double FIR_filter::filter(double new_sample)
{
double result = 0;
// Save the new sample
this->samples[this->idx] = new_sample;
// Calculate the output
for(int n = 0; n < this->taps; n++)
result += this->samples[(this->idx + n) % this->taps] * this->h[n];
// Increase the round robin index
this->idx = (this->idx + 1) % this->taps;
return result;
}

37
src/filter_group/algo/fir_filter.hpp

@ -0,0 +1,37 @@
#ifndef FIR_FILTER_H
#define FIR_FILTER_H
#include <stdlib.h>
#include <string.h>
#include <cmath>
#include <vector>
class FIR_filter {
public:
FIR_filter(int taps = 0, double f1 = 0, double f2 = 0, const char* type = "", const char* window = "");
~FIR_filter();
std::vector<double> getCoefficients();
double filter(double new_sample);
private:
std::vector<double> lowPass_coefficient(int taps, double f);
std::vector<double> highPass_coefficient(int taps, double f);
std::vector<double> bandPass_coefficient(int taps, double f1, double f2);
std::vector<double> bandStop_coefficient(int taps, double f1, double f2);
std::vector<double> window_hammig(int taps);
std::vector<double> window_triangle(int taps);
std::vector<double> window_hanning(int taps);
std::vector<double> window_blackman(int taps);
std::vector<double> h; // FIR coefficients
std::vector<double> samples; // FIR delay
int idx; // Round robin index
int taps; // Number of taps of the filter
};
#endif // FIR_FILTER_H

0
src/algo/iflytop_simple_filter.cpp → src/filter_group/algo/iflytop_simple_filter.cpp

0
src/algo/iflytop_simple_filter.h → src/filter_group/algo/iflytop_simple_filter.h

41
src/filter_group/fir_filter_group.cpp

@ -0,0 +1,41 @@
#include "fir_filter_group.hpp"
using namespace iflytop;
void FirFilterGroup::initialize() {
lpfilter = new FIR_filter(1000, 0.1, 0, "lp", "hamming");
hpfilter = new FIR_filter(1000, 0.1, 0, "hp", "hamming");
notchfilter = new FIR_filter(1000, 0.1, 0, "bp", "hamming");
}
int32_t FirFilterGroup::processData(int32_t data) {
std::lock_guard<std::recursive_mutex> lock(lock_);
float v0 = (float)data;
if (lpfilter) {
v0 = lpfilter->filter(v0);
v0 = lpfilter->filter(v0);
}
if (lpfilter) {
v0 = hpfilter->filter(v0);
v0 = hpfilter->filter(v0);
}
if (notchfilter) {
v0 = notchfilter->filter(v0);
v0 = notchfilter->filter(v0);
}
return (int32_t)v0;
}
void FirFilterGroup::updateParameter() {
std::lock_guard<std::recursive_mutex> lock(lock_);
if(lpfilter) delete lpfilter;
if(hpfilter) delete hpfilter;
if(notchfilter) delete notchfilter;
if (_LPFilter_Enable) lpfilter = new FIR_filter(_windows_size, _LPFilter_CutoffFreqHz, 0, "lp", _windowType.c_str());
if (_HPFilter_Enable) hpfilter = new FIR_filter(_windows_size, _HPFilter_CutoffFreqHz, 0, "hp", _windowType.c_str());
if (_NOTCHFilter_Enable) notchfilter = new FIR_filter(_windows_size, _NOTCHFilter_CenterFreqHz - _NOTCHFilter_NotchWidthHz, _NOTCHFilter_CenterFreqHz + _NOTCHFilter_NotchWidthHz, "sb", _windowType.c_str());
}

39
src/filter_group/fir_filter_group.hpp

@ -0,0 +1,39 @@
#pragma once
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <set>
#include <sstream>
#include <string>
#include <thread>
#include <vector>
#include "algo/fir_filter.hpp"
#include "algo/iflytop_simple_filter.h"
#include "if/if_filter_group.hpp"
namespace iflytop {
using namespace std;
class FirFilterGroup : public IF_FilterGroup {
private:
std::recursive_mutex lock_;
FIR_filter* lpfilter = nullptr;
FIR_filter* hpfilter = nullptr;
FIR_filter* notchfilter = nullptr;
public:
virtual void initialize() override;
virtual int32_t processData(int32_t data) override;
virtual void updateParameter() override;
};
} // namespace iflytop

100
src/filter_group/if/if_filter_group.hpp

@ -0,0 +1,100 @@
#pragma once
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <set>
#include <sstream>
#include <string>
#include <thread>
#include <vector>
namespace iflytop {
using namespace std;
class IF_FilterGroup {
protected:
float _sampleTimeMs;
bool _LPFilter_Enable = false;
float _LPFilter_CutoffFreqHz = 0;
float _LPFilter_Order = 1;
bool _HPFilter_Enable = false;
float _HPFilter_CutoffFreqHz = 0;
float _HPFilter_Order = 1;
bool _NOTCHFilter_Enable = false;
float _NOTCHFilter_CenterFreqHz = 0;
float _NOTCHFilter_NotchWidthHz = 0;
float _NOTCHFilter_Order = 1;
int _windows_size = 1000;
const string kwindow_type_hamming = "hamming";
const string kwindow_type_triangle = "triangle";
const string kwindow_type_hanning = "hanning";
const string kwindow_type_blackman = "blackman";
string _windowType = "hamming";
public:
virtual ~IF_FilterGroup() {}
virtual void initialize() = 0;
virtual int32_t processData(int32_t data) = 0;
virtual void updateParameter() = 0;
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
virtual void setSampleTimeMs(float sampleTimeMs) { _sampleTimeMs = sampleTimeMs; }
virtual float getSampleTimeMs() { return _sampleTimeMs; }
virtual void setWindowsSize(int windows_size) { _windows_size = windows_size; }
virtual int getWindowsSize() { return _windows_size; }
virtual void setWindowsType(string windowType) { _windowType = windowType; }
virtual string getWindowType() { return _windowType; }
static vector<string> windowsTypes() { return {"hamming", "triangle", "hanning", "blackman"}; }
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
virtual void LPFilter_setEnable(bool enable) { _LPFilter_Enable = enable; }
virtual void LPFilter_setCutoffFreqHz(float cutoffFreqHz) { _LPFilter_CutoffFreqHz = cutoffFreqHz; }
virtual void LPFilter_setOrder(int order) { _LPFilter_Order = order; }
virtual bool LPFilter_getEnable() { return _LPFilter_Enable; }
virtual float LPFilter_getCutoffFreqHz() { return _LPFilter_CutoffFreqHz; }
virtual int LPFilter_getOrder() { return _LPFilter_Order; }
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
virtual void HPFilter_setEnable(bool enable) { _HPFilter_Enable = enable; }
virtual void HPFilter_setCutoffFreqHz(float cutoffFreqHz) { _HPFilter_CutoffFreqHz = cutoffFreqHz; }
virtual void HPFilter_setOrder(int order) { _HPFilter_Order = order; }
virtual bool HPFilter_getEnable() { return _HPFilter_Enable; }
virtual float HPFilter_getCutoffFreqHz() { return _HPFilter_CutoffFreqHz; }
virtual int HPFilter_getOrder() { return _HPFilter_Order; }
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
virtual void NOTCHFilter_setEnable(bool enable) { _NOTCHFilter_Enable = enable; }
virtual void NOTCHFilter_setCenterFreqHz(float centerFreqHz) { _NOTCHFilter_CenterFreqHz = centerFreqHz; }
virtual void NOTCHFilter_setNotchWidthHz(float notchWidthHz) { _NOTCHFilter_NotchWidthHz = notchWidthHz; }
virtual void NOTCHFilter_setOrder(int order) { _NOTCHFilter_Order = order; }
virtual bool NOTCHFilter_getEnable() { return _NOTCHFilter_Enable; }
virtual float NOTCHFilter_getCenterFreqHz() { return _NOTCHFilter_CenterFreqHz; }
virtual float NOTCHFilter_getNotchWidthHz() { return _NOTCHFilter_NotchWidthHz; }
virtual int NOTCHFilter_getOrder() { return _NOTCHFilter_Order; }
};
} // namespace iflytop

119
src/filter_group/iir_filter_group.cpp

@ -0,0 +1,119 @@
#include "iir_filter_group.hpp"
#include "libzqt\zexception.hpp"
#include "ify_hrs_protocol\heart_rate_sensor_protocol.h"
#include <mutex>
using namespace iflytop;
void IIRFilterGroup::initialize() {}
int32_t IIRFilterGroup::processData(int32_t data) { //
std::lock_guard<std::recursive_mutex> lock(lock_);
float v0 = (float)data;
for (int i = 0; i < __lpfilter_order; i++) {
v0 = LPFilter_Update(&lpfilter[i], v0);
}
for (int i = 0; i < __hpfilter_order; i++) {
v0 = HPFilter_Update(&hpfilter[i], v0);
}
for (int i = 0; i < __notchfilter_order; i++) {
v0 = NOTCHFilter_Update(&notchfilter[i], v0);
}
return (int32_t)v0;
}
void IIRFilterGroup::updateParameter() {
std::lock_guard<std::recursive_mutex> lock(lock_);
for (int i = 0; i < FILTER_MAX_ORDER; i++) {
LPFilter_Init(&lpfilter[i], LPFilter_cutoffFreqHz, sampleTimeMs / 1000.0, lpfilter_enable);
}
for (int i = 0; i < FILTER_MAX_ORDER; i++) {
HPFilter_Init(&hpfilter[i], HPFilter_cutoffFreqHz, sampleTimeMs / 1000.0, hpfilter_enable);
}
for (int i = 0; i < FILTER_MAX_ORDER; i++) {
NOTCHFilter_Init(&notchfilter[i], NOTCHFilter_centerFreqHz, NOTCHFilter_notchWidthHz, sampleTimeMs / 1000.0, notchfilter_enable);
}
__lpfilter_order = lpfilter_order;
__hpfilter_order = hpfilter_order;
__notchfilter_order = notchfilter_order;
}
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
void IIRFilterGroup::setSampleTimeMs(float sampleTimeMs) {
if (sampleTimeMs < 0.4) {
throw zexception(kifyhrs_ecode_upper_exception, "sampleTimeMs must be greater than 0.4ms");
}
this->sampleTimeMs = sampleTimeMs;
}
float IIRFilterGroup::getSampleTimeMs() { return sampleTimeMs; }
void IIRFilterGroup::LPFilter_setOrder(int order) {
if (order < 1) {
order = 1;
}
if (order > FILTER_MAX_ORDER) {
order = FILTER_MAX_ORDER;
}
lpfilter_order = order;
}
int IIRFilterGroup::LPFilter_getOrder() { return lpfilter_order; }
void IIRFilterGroup::HPFilter_setOrder(int order) {
if (order < 1) {
order = 1;
}
if (order > FILTER_MAX_ORDER) {
order = FILTER_MAX_ORDER;
}
hpfilter_order = order;
}
int IIRFilterGroup::HPFilter_getOrder() { return hpfilter_order; }
void IIRFilterGroup::NOTCHFilter_setOrder(int order) {
if (order < 1) {
order = 1;
}
if (order > FILTER_MAX_ORDER) {
order = FILTER_MAX_ORDER;
}
notchfilter_order = order;
}
int IIRFilterGroup::NOTCHFilter_getOrder() { return notchfilter_order; }
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
void IIRFilterGroup::LPFilter_setEnable(bool enable) { lpfilter_enable = enable; }
void IIRFilterGroup::LPFilter_setCutoffFreqHz(float cutoffFreqHz) { LPFilter_cutoffFreqHz = cutoffFreqHz; }
bool IIRFilterGroup::LPFilter_getEnable() { return lpfilter_enable; }
float IIRFilterGroup::LPFilter_getCutoffFreqHz() { return LPFilter_cutoffFreqHz; }
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
void IIRFilterGroup::HPFilter_setEnable(bool enable) { hpfilter_enable = enable; }
void IIRFilterGroup::HPFilter_setCutoffFreqHz(float cutoffFreqHz) { HPFilter_cutoffFreqHz = cutoffFreqHz; }
bool IIRFilterGroup::HPFilter_getEnable() { return hpfilter_enable; }
float IIRFilterGroup::HPFilter_getCutoffFreqHz() { return HPFilter_cutoffFreqHz; }
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
void IIRFilterGroup::NOTCHFilter_setEnable(bool enable) { notchfilter_enable = enable; }
void IIRFilterGroup::NOTCHFilter_setCenterFreqHz(float centerFreqHz) { NOTCHFilter_centerFreqHz = centerFreqHz; }
void IIRFilterGroup::NOTCHFilter_setNotchWidthHz(float notchWidthHz) { NOTCHFilter_notchWidthHz = notchWidthHz; }
bool IIRFilterGroup::NOTCHFilter_getEnable() { return notchfilter_enable; }
float IIRFilterGroup::NOTCHFilter_getCenterFreqHz() { return NOTCHFilter_centerFreqHz; }
float IIRFilterGroup::NOTCHFilter_getNotchWidthHz() { return NOTCHFilter_notchWidthHz; }

102
src/filter_group/iir_filter_group.hpp

@ -0,0 +1,102 @@
#pragma once
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <set>
#include <sstream>
#include <string>
#include <thread>
#include <vector>
#include "algo/iflytop_simple_filter.h"
#include "if/if_filter_group.hpp"
namespace iflytop {
using namespace std;
#define FILTER_MAX_ORDER 20
class IIRFilterGroup : public IF_FilterGroup {
private:
LPFilter_t lpfilter[FILTER_MAX_ORDER] = {0};
HPFilter_t hpfilter[FILTER_MAX_ORDER] = {0};
NOTCHFilter_t notchfilter[FILTER_MAX_ORDER] = {0};
int __lpfilter_order = 1;
int __hpfilter_order = 1;
int __notchfilter_order = 1;
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
bool lpfilter_enable = false;
bool hpfilter_enable = false;
bool notchfilter_enable = false;
int lpfilter_order = 1;
int hpfilter_order = 1;
int notchfilter_order = 1;
float LPFilter_cutoffFreqHz = 0;
float HPFilter_cutoffFreqHz = 0;
float NOTCHFilter_centerFreqHz = 0;
float NOTCHFilter_notchWidthHz = 0;
float sampleTimeMs = 2; // 1ms
std::recursive_mutex lock_;
public:
virtual void initialize() override;
virtual int32_t processData(int32_t data) override;
virtual void updateParameter() override;
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
virtual void setSampleTimeMs(float sampleTimeMs) override;
virtual float getSampleTimeMs() override;
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
virtual void LPFilter_setEnable(bool enable) override;
virtual void LPFilter_setCutoffFreqHz(float cutoffFreqHz) override;
virtual void LPFilter_setOrder(int order) override;
virtual bool LPFilter_getEnable() override;
virtual float LPFilter_getCutoffFreqHz() override;
virtual int LPFilter_getOrder() override;
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
virtual void HPFilter_setEnable(bool enable) override;
virtual void HPFilter_setCutoffFreqHz(float cutoffFreqHz) override;
virtual void HPFilter_setOrder(int order) override;
virtual bool HPFilter_getEnable() override;
virtual float HPFilter_getCutoffFreqHz() override;
virtual int HPFilter_getOrder() override;
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
virtual void NOTCHFilter_setEnable(bool enable) override;
virtual void NOTCHFilter_setCenterFreqHz(float centerFreqHz) override;
virtual void NOTCHFilter_setNotchWidthHz(float notchWidthHz) override;
virtual void NOTCHFilter_setOrder(int order) override;
virtual bool NOTCHFilter_getEnable() override;
virtual float NOTCHFilter_getCenterFreqHz() override;
virtual float NOTCHFilter_getNotchWidthHz() override;
virtual int NOTCHFilter_getOrder() override;
};
} // namespace iflytop
Loading…
Cancel
Save