diff --git a/doc/img/filter_highpass.xcf b/doc/img/filter_highpass.xcf new file mode 100644 index 000000000..c30c436f3 Binary files /dev/null and b/doc/img/filter_highpass.xcf differ 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 000000000..9e44ac397 Binary files /dev/null and b/sdrgui/resources/filter_highpass.png differ 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