From e1d7ada5ddd8bb37b6783189a37c2f6875dd21d0 Mon Sep 17 00:00:00 2001 From: f4exb Date: Tue, 26 Dec 2017 10:59:51 +0100 Subject: [PATCH] DSD demod: highpass filtering for audio (1) --- doc/img/filter_highpass.xcf | Bin 0 -> 2419 bytes plugins/channelrx/demoddsd/dsddemodgui.ui | 14 ++ .../channelrx/demoddsd/dsddemodsettings.cpp | 3 + plugins/channelrx/demoddsd/dsddemodsettings.h | 1 + sdrbase/CMakeLists.txt | 1 + sdrbase/dsp/iirfilter.h | 127 ++++++++++++++++++ sdrbase/sdrbase.pro | 1 + sdrgui/resources/filter_highpass.png | Bin 0 -> 569 bytes sdrgui/resources/res.qrc | 1 + 9 files changed, 148 insertions(+) create mode 100644 doc/img/filter_highpass.xcf create mode 100644 sdrbase/dsp/iirfilter.h create mode 100644 sdrgui/resources/filter_highpass.png diff --git a/doc/img/filter_highpass.xcf b/doc/img/filter_highpass.xcf new file mode 100644 index 0000000000000000000000000000000000000000..c30c436f3c78472f165240c3d243023f7e12c171 GIT binary patch literal 2419 zcmeHI%Wl(95FJ0_IDRA)XjG*|vPyx3651}{1L&ec0;wOs#z`EPlX|{|5FHPcT)U&$daG1o&!s|-aUxWkSJA8U5WeqthTs@=?)})qx z@9%_D&(gU+jAo&CRK5$w%W~vnHSB5lOW~%WIRrT?AHc4`%hDDxtz-9P>Aw{ zsP?8@LGvB)74WHA$8j_tB>qC4oC*tz0q_M0z$`dNHwq3#I~8tKxLx5+g}W8r0_W$l z)C=(YSgOU5TS$!yQtlkF>if$!RhE`ZbCD`2h@RGpg|h6 zCTzgN+6G#rO6`I-VYh%5z-yZnu>sC;9M3*}jtSfc44@5L1MkzpH_3$0fwrJ6Xb0Ma zt_c+|uwR#Mc73&H{RGwV_`g(!>a1K;eqJ1pPz*gl{VuUuequIr9s+7 zW9i82fSb@7ur0Zc=FYi=#$ua;#&=~CYqEj)eKyujoVx@64w{Y|o?}-ecr&_uunNtS zp#vvR3dS}P4J2yd_h=<>418-A?#dJg2yEVb4~~Wh-*vv91KifW9Ksi_uHes$=kUd+ V54+UC<>sSU6+b>Zv~|tD<|kCN8uI`E literal 0 HcmV?d00001 diff --git a/plugins/channelrx/demoddsd/dsddemodgui.ui b/plugins/channelrx/demoddsd/dsddemodgui.ui index 9dd65adb2..1e8777b28 100644 --- a/plugins/channelrx/demoddsd/dsddemodgui.ui +++ b/plugins/channelrx/demoddsd/dsddemodgui.ui @@ -825,6 +825,20 @@ + + + + Toggle audio high pass filter for mbelib (>300 Hz) + + + + + + + :/filter_highpass.png:/filter_highpass.png + + + diff --git a/plugins/channelrx/demoddsd/dsddemodsettings.cpp b/plugins/channelrx/demoddsd/dsddemodsettings.cpp index 729caa1db..6c04cba8b 100644 --- a/plugins/channelrx/demoddsd/dsddemodsettings.cpp +++ b/plugins/channelrx/demoddsd/dsddemodsettings.cpp @@ -52,6 +52,7 @@ void DSDDemodSettings::resetToDefaults() m_udpPort = 9999; m_rgbColor = QColor(0, 255, 255).rgb(); m_title = "DSD Demodulator"; + m_highPassFilter = false; } QByteArray DSDDemodSettings::serialize() const @@ -83,6 +84,7 @@ QByteArray DSDDemodSettings::serialize() const } s.writeString(18, m_title); + s.writeBool(19, m_highPassFilter); return s.final(); } @@ -136,6 +138,7 @@ bool DSDDemodSettings::deserialize(const QByteArray& data) d.readBool(15, &m_slot2On, false); d.readBool(16, &m_tdmaStereo, false); d.readString(18, &m_title, "DSD Demodulator"); + d.readBool(19, &m_highPassFilter, false); return true; } diff --git a/plugins/channelrx/demoddsd/dsddemodsettings.h b/plugins/channelrx/demoddsd/dsddemodsettings.h index 6c2e17e5c..48a272890 100644 --- a/plugins/channelrx/demoddsd/dsddemodsettings.h +++ b/plugins/channelrx/demoddsd/dsddemodsettings.h @@ -45,6 +45,7 @@ struct DSDDemodSettings quint16 m_udpPort; quint32 m_rgbColor; QString m_title; + bool m_highPassFilter; Serializable *m_channelMarker; Serializable *m_scopeGUI; diff --git a/sdrbase/CMakeLists.txt b/sdrbase/CMakeLists.txt index 0eef2ca69..51a407ad0 100644 --- a/sdrbase/CMakeLists.txt +++ b/sdrbase/CMakeLists.txt @@ -108,6 +108,7 @@ set(sdrbase_HEADERS dsp/filtermbe.h dsp/filerecord.h dsp/gfft.h + dsp/iirfilter.h dsp/interpolator.h dsp/hbfiltertraits.h dsp/inthalfbandfilter.h diff --git a/sdrbase/dsp/iirfilter.h b/sdrbase/dsp/iirfilter.h new file mode 100644 index 000000000..c29571171 --- /dev/null +++ b/sdrbase/dsp/iirfilter.h @@ -0,0 +1,127 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017 F4EXB // +// written by Edouard Griffiths // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef SDRBASE_DSP_IIRFILTER_H_ +#define SDRBASE_DSP_IIRFILTER_H_ + +#include +#include + +template class IIRFilter +{ +public: + IIRFilter(const Type *a, const Type *b); + ~IIRFilter(); + Type run(Type sample); + +private: + Type *m_a; + Type *m_b; + Type *m_x; + Type *m_y; +}; + +template class IIRFilter +{ +public: + IIRFilter(const Type *a, const Type *b); + ~IIRFilter(); + Type run(Type sample); + +private: + Type m_a[3]; + Type m_b[3]; + Type m_x[2]; + Type m_y[2]; +}; + +template +IIRFilter::IIRFilter(const Type *a, const Type *b) +{ + assert(Order > 1); + + m_a = new Type[Order+1]; + m_b = new Type[Order+1]; + m_x = new Type[Order]; + m_y = new Type[Order]; + + memcpy(m_a, a, (Order+1)*sizeof(Type)); + memcpy(m_b, b, (Order+1)*sizeof(Type)); + + for (int i = 0; i < Order; i++) + { + m_x[i] = 0; + m_y[i] = 0; + } +} + +template +IIRFilter::~IIRFilter() +{ + delete[] m_y; + delete[] m_x; + delete[] m_b; + delete[] m_a; +} + +template +Type IIRFilter::run(Type sample) +{ + Type y = m_a[0] * sample; + + for (int i = 0; i < Order; i++) + { + y += m_a[i+1] * m_x[i] + m_b[i+1] * m_y[i]; + } + + m_x[0] = sample; + m_y[0] = y; + + memcpy(&m_x[1], &m_x[0], (Order-1)*sizeof(Type)); +} + +template +IIRFilter::IIRFilter(const Type *a, const Type *b) +{ + m_a[0] = a[0]; + m_a[1] = a[1]; + m_a[2] = a[2]; + m_b[0] = b[0]; + m_b[1] = b[1]; + m_b[2] = b[2]; +} + +template +IIRFilter::~IIRFilter() +{ +} + +template +Type IIRFilter::run(Type sample) +{ + Type y = m_a[0]*sample + m_a[1]*m_x[0] + m_a[2]*m_x[1] + m_b[1]*m_y[0] + m_b[2]*m_y[1]; // this is y[n] + + m_x[1] = m_x[0]; + m_x[0] = sample; + + m_y[1] = m_y[0]; + m_y[0] = y; + + return y; +} + +#endif /* SDRBASE_DSP_IIRFILTER_H_ */ diff --git a/sdrbase/sdrbase.pro b/sdrbase/sdrbase.pro index c1cb2b32b..20ed349e9 100644 --- a/sdrbase/sdrbase.pro +++ b/sdrbase/sdrbase.pro @@ -146,6 +146,7 @@ HEADERS += audio/audiodeviceinfo.h\ dsp/filerecord.h\ dsp/gfft.h\ dsp/hbfiltertraits.h\ + dsp/iirfilter.h\ dsp/interpolator.h\ dsp/inthalfbandfilter.h\ dsp/inthalfbandfilterdb.h\ diff --git a/sdrgui/resources/filter_highpass.png b/sdrgui/resources/filter_highpass.png new file mode 100644 index 0000000000000000000000000000000000000000..9e44ac397536165f2434d19f01f554b8f6b431ab GIT binary patch literal 569 zcmV-90>=G`P)FW6S^m02y>e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{00E&%L_t(Y$L-Y5YtL~U2k?Er zY-4d462*bEgK6Pn9ClbK#5lqiwzg$!#n6LE{LPs}&r*^1;yq?@FK0Hs-o=vd zz+3#lK!bk(Kk*7%S|wkDJO10r68u!K>*$(?V+ehy7r_IG{5HBve(uJth@2?FYd919 zDmsf7*5ep9&hyG`7{>?fEnu7Q8ecGo+CnL-qrLc4oKBQeb4AbHN9ni=Rq9e}BD_DH z^$ing<3G5(l(Vu6&l2@ChO7MChX+Z;6O1+~YQ2@n_Th6n>P1o@1GlQ--f;|7CEuNV z&R`_It+)}9Yw?}OZ(OWGz8Q~0bhdzXB~@SXFvUGr!qJX?Y$y{r67tcq++t5U=Q|FU z;2pRWj=?g4l~{`vO~l9Zf+@Vgy272E!JcD#mDC+gR5!6YgZ2yWvOYSpBtK<}4^}OF zKduxO+Wm-5;BFe@BMvQQuxbt8ofyN*2tA#Pe8C;GY(@JA%%^xXOKU+m00000NkvXX Hu0mjfe7N|e literal 0 HcmV?d00001 diff --git a/sdrgui/resources/res.qrc b/sdrgui/resources/res.qrc index 72082d716..a085780ff 100644 --- a/sdrgui/resources/res.qrc +++ b/sdrgui/resources/res.qrc @@ -81,5 +81,6 @@ choose.png clocksource.png flip_sidebands.png + filter_highpass.png