diff --git a/CMakeLists.txt b/CMakeLists.txt
index 487c3ee..6bd2947 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -35,13 +35,17 @@ set(PROJECT_SOURCES
src/qt_serial_datachannel.cpp
src/electrocardiograph_tester.cpp
- src/filter_algo_mgr.cpp
libzqt/widgetplot2d.cpp
libzqt/widgetplot2d.ui
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
)
diff --git a/README.md b/README.md
index e6b29c2..46cb817 100644
--- a/README.md
+++ b/README.md
@@ -43,4 +43,12 @@ V4:
regcache.ch1set = ADS129X_SET_BITS(regcache.ch1set, 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
+
+
```
\ No newline at end of file
diff --git a/mainwindow.cpp b/mainwindow.cpp
index 0ee27b6..5ceeaeb 100644
--- a/mainwindow.cpp
+++ b/mainwindow.cpp
@@ -8,7 +8,6 @@
#include "./ui_mainwindow.h"
#include "ads129x/ads129x_type.h"
-#include "algo/iflytop_simple_filter.h"
#include "electrocardiograph_tester.hpp"
#include "filter_algo_mgr.hpp"
#include "logger.hpp"
@@ -170,6 +169,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
// qInstallMessageHandler(log_output);
wp2d = new WidgetPlot2D();
wp2d->initGraphName(QStringList() << "心电");
+ FilterAlgoMgr::ins()->addFilter("心电");
/*******************************************************************************
* 页面逻辑初始化 *
@@ -369,6 +369,12 @@ void MainWindow::constructUI() {
// 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())); }
@@ -695,7 +701,7 @@ void MainWindow::on_resetDevice_clicked() {
void MainWindow::on_FilterUpdateParameter_clicked() {
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_setCutoffFreqHz(ui->LPFilter_CutoffFreqHz->text().toFloat());
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_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();
on_buttonTabWidget_currentChanged(0);
@@ -716,7 +725,7 @@ void MainWindow::on_FilterUpdateParameter_clicked() {
}
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_CutoffFreqHz->setText(QString::number(FilterAlgoMgr::ins()->LPFilter_getCutoffFreqHz()));
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_NotchWidthHz->setText(QString::number(FilterAlgoMgr::ins()->NOTCHFilter_getNotchWidthHz()));
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() {
@@ -777,8 +789,7 @@ void MainWindow::on_setEcgInNormalMode_clicked() {
}
}
-void MainWindow::on_setEcgReportDataInRawMode__1_clicked()
-{
+void MainWindow::on_setEcgReportDataInRawMode__1_clicked() {
instructionPreviewClear();
try {
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();
try {
ElectrocardiographTester::ins()->set_ecg_report_data_in_raw_mode(0);
@@ -799,6 +808,4 @@ void MainWindow::on_setEcgReportDataInRawMode__0_clicked()
} catch (zexception &exception) {
processException(exception);
}
-
}
-
diff --git a/mainwindow.ui b/mainwindow.ui
index 32e8669..c4ce3af 100644
--- a/mainwindow.ui
+++ b/mainwindow.ui
@@ -869,7 +869,7 @@ p, li { white-space: pre-wrap; }
- 0
+ 2
@@ -2158,8 +2158,8 @@ p, li { white-space: pre-wrap; }
- -
-
+
-
+
1
@@ -2167,11 +2167,24 @@ p, li { white-space: pre-wrap; }
- 数据采样周期(ms)
+ windowsSize
- -
+
-
+
+
+
+ 1
+ 0
+
+
+
+
+
+
+
+ -
Qt::Vertical
@@ -2184,6 +2197,35 @@ p, li { white-space: pre-wrap; }
+ -
+
+
+
+ 1
+ 0
+
+
+
+ 数据采样周期(ms)
+
+
+
+ -
+
+
+
+ 1
+ 0
+
+
+
+ windowsType
+
+
+
+ -
+
+
@@ -2204,6 +2246,13 @@ p, li { white-space: pre-wrap; }
-
+
+
+ GroupBox
+
+
+
+ -
Qt::Vertical
diff --git a/src/filter_algo_mgr.cpp b/src/filter_algo_mgr.cpp
index 76e6eb6..a57c1ac 100644
--- a/src/filter_algo_mgr.cpp
+++ b/src/filter_algo_mgr.cpp
@@ -6,158 +6,212 @@
#include "zexception.hpp"
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 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(¬chfilter[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 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(¬chfilter[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 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();
+ }
+}
diff --git a/src/filter_algo_mgr.hpp b/src/filter_algo_mgr.hpp
index 2fd2ae9..0a89cee 100644
--- a/src/filter_algo_mgr.hpp
+++ b/src/filter_algo_mgr.hpp
@@ -12,109 +12,36 @@
#include
#include
-#include "algo/iflytop_simple_filter.h"
-
+#include "filter_group/fir_filter_group.hpp"
+#include "filter_group/iir_filter_group.hpp"
+//
namespace iflytop {
using namespace std;
#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 {
private:
- FilterGroup filter;
+ map m_filter_map;
public:
FilterAlgoMgr(/* args */) {}
~FilterAlgoMgr() {}
static FilterAlgoMgr* ins();
+ void addFilter(string channel);
int32_t processData(string channel, int32_t data);
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 windowsTypes();
/***********************************************************************************************************************
* 低通滤波器 *
diff --git a/src/filter_group/algo/fir_filter.cpp b/src/filter_group/algo/fir_filter.cpp
new file mode 100644
index 0000000..78a112b
--- /dev/null
+++ b/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 h; // Buffer FIR coefficients
+ std::vector 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 FIR_filter::getCoefficients()
+{
+ return this->h;
+}
+
+std::vector FIR_filter::lowPass_coefficient(int taps, double f)
+{
+ std::vector n(taps, 0);
+ std::vector 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 FIR_filter::highPass_coefficient(int taps, double f)
+{
+ std::vector n(taps, 0);
+ std::vector 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 FIR_filter::bandPass_coefficient(int taps, double f1, double f2)
+{
+ std::vector n(taps, 0);
+ std::vector 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 FIR_filter::bandStop_coefficient(int taps, double f1, double f2)
+{
+ std::vector n(taps, 0);
+ std::vector 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 FIR_filter::window_hammig(int taps)
+{
+ std::vector n(taps, 0);
+ std::vector 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 FIR_filter::window_hanning(int taps)
+{
+ std::vector 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 FIR_filter::window_triangle(int taps)
+{
+ std::vector 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 FIR_filter::window_blackman(int taps)
+{
+ std::vector 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;
+}
\ No newline at end of file
diff --git a/src/filter_group/algo/fir_filter.hpp b/src/filter_group/algo/fir_filter.hpp
new file mode 100644
index 0000000..732df1e
--- /dev/null
+++ b/src/filter_group/algo/fir_filter.hpp
@@ -0,0 +1,37 @@
+#ifndef FIR_FILTER_H
+#define FIR_FILTER_H
+
+#include
+#include
+
+#include
+#include
+
+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 getCoefficients();
+
+ double filter(double new_sample);
+
+ private:
+ std::vector lowPass_coefficient(int taps, double f);
+ std::vector highPass_coefficient(int taps, double f);
+ std::vector bandPass_coefficient(int taps, double f1, double f2);
+ std::vector bandStop_coefficient(int taps, double f1, double f2);
+
+ std::vector window_hammig(int taps);
+ std::vector window_triangle(int taps);
+ std::vector window_hanning(int taps);
+ std::vector window_blackman(int taps);
+
+ std::vector h; // FIR coefficients
+ std::vector samples; // FIR delay
+
+ int idx; // Round robin index
+ int taps; // Number of taps of the filter
+};
+
+#endif // FIR_FILTER_H
\ No newline at end of file
diff --git a/src/algo/iflytop_simple_filter.cpp b/src/filter_group/algo/iflytop_simple_filter.cpp
similarity index 100%
rename from src/algo/iflytop_simple_filter.cpp
rename to src/filter_group/algo/iflytop_simple_filter.cpp
diff --git a/src/algo/iflytop_simple_filter.h b/src/filter_group/algo/iflytop_simple_filter.h
similarity index 100%
rename from src/algo/iflytop_simple_filter.h
rename to src/filter_group/algo/iflytop_simple_filter.h
diff --git a/src/filter_group/fir_filter_group.cpp b/src/filter_group/fir_filter_group.cpp
new file mode 100644
index 0000000..33924a4
--- /dev/null
+++ b/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 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 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());
+}
diff --git a/src/filter_group/fir_filter_group.hpp b/src/filter_group/fir_filter_group.hpp
new file mode 100644
index 0000000..f03a94d
--- /dev/null
+++ b/src/filter_group/fir_filter_group.hpp
@@ -0,0 +1,39 @@
+#pragma once
+#include
+#include
+#include
+#include
+#include