diff --git a/sdrbase/CMakeLists.txt b/sdrbase/CMakeLists.txt index f358bd71b..0cfb3cfbd 100644 --- a/sdrbase/CMakeLists.txt +++ b/sdrbase/CMakeLists.txt @@ -7,6 +7,7 @@ set(sdrbase_SOURCES audio/audiocompressor.cpp audio/audiodevicemanager.cpp audio/audiofifo.cpp + audio/audiofilter.cpp audio/audiooutput.cpp audio/audioinput.cpp audio/audionetsink.cpp @@ -99,6 +100,7 @@ set(sdrbase_HEADERS audio/audiocompressor.h audio/audiodevicemanager.h audio/audiofifo.h + audio/audiofilter.h audio/audiooutput.h audio/audioinput.h audio/audionetsink.h diff --git a/sdrbase/audio/audiofilter.cpp b/sdrbase/audio/audiofilter.cpp new file mode 100644 index 000000000..696a94299 --- /dev/null +++ b/sdrbase/audio/audiofilter.cpp @@ -0,0 +1,48 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2019 Edouard Griffiths, F4EXB // +// // +// 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 . // +/////////////////////////////////////////////////////////////////////////////////// + +#include "audiofilter.h" + +const float AudioFilter::m_lpa[3] = {1.0, 1.392667E+00, -5.474446E-01}; +const float AudioFilter::m_lpb[3] = {3.869430E-02, 7.738860E-02, 3.869430E-02}; +// f(-3dB) = 300 Hz @ 8000 Hz SR (w = 0.075): +const float AudioFilter::m_hpa[3] = {1.000000e+00, 1.667871e+00, -7.156964e-01}; +const float AudioFilter::m_hpb[3] = {8.459039e-01, -1.691760e+00, 8.459039e-01}; + +AudioFilter::AudioFilter() : + m_filterLP(m_lpa, m_lpb), + m_filterHP(m_hpa, m_hpb), + m_useHP(false) +{ +} + +AudioFilter::~AudioFilter() +{} + +float AudioFilter::run(const float& sample) +{ + return m_useHP ? m_filterLP.run(m_filterHP.run(sample)) : m_filterLP.run(sample); +} + +float AudioFilter::runHP(const float& sample) +{ + return m_filterHP.run(sample); +} + +float AudioFilter::runLP(const float& sample) +{ + return m_filterLP.run(sample); +} \ No newline at end of file diff --git a/sdrbase/audio/audiofilter.h b/sdrbase/audio/audiofilter.h new file mode 100644 index 000000000..4a003fc55 --- /dev/null +++ b/sdrbase/audio/audiofilter.h @@ -0,0 +1,62 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2019 Edouard Griffiths, F4EXB // +// // +// 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_AUDIO_AUDIOFILTER_H_ +#define _SDRBASE_AUDIO_AUDIOFILTER_H_ + +#include "export.h" +#include "dsp/iirfilter.h" + +/** + * This is a 2 pole lowpass Chebyshev (recursive) filter at fc=0.075 using coefficients found in table 20-1 of + * http://www.analog.com/media/en/technical-documentation/dsp-book/dsp_book_Ch20.pdf + * + * At the interpolated sampling frequency of 48 kHz the -3 dB corner is at 48 * .075 = 3.6 kHz which is perfect for voice + * + * a0= 3.869430E-02 + * a1= 7.738860E-02 b1= 1.392667E+00 + * a2= 3.869430E-02 b2= -5.474446E-01 + * + * given x[n] is the new input sample and y[n] the returned output sample: + * + * y[n] = a0*x[n] + a1*x[n] + a2*x[n] + b1*y[n-1] + b2*y[n-2] + * + * This one works directly with floats + * + */ + +class SDRBASE_API AudioFilter { +public: + AudioFilter(); + ~AudioFilter(); + + void useHP(bool useHP) { m_useHP = useHP; } + bool usesHP() const { return m_useHP; } + float run(const float& sample); + float runHP(const float& sample); + float runLP(const float& sample); + +private: + IIRFilter m_filterLP; + IIRFilter m_filterHP; + bool m_useHP; + static const float m_lpa[3]; + static const float m_lpb[3]; + static const float m_hpa[3]; + static const float m_hpb[3]; +}; + +#endif // _SDRBASE_AUDIO_AUDIOFILTER_H_ \ No newline at end of file diff --git a/sdrbase/sdrbase.pro b/sdrbase/sdrbase.pro index 2ac290486..3538849e2 100644 --- a/sdrbase/sdrbase.pro +++ b/sdrbase/sdrbase.pro @@ -56,6 +56,7 @@ MINGW32 || MINGW64 || MSVC { SOURCES += audio/audiodevicemanager.cpp\ audio/audiocompressor.cpp\ audio/audiofifo.cpp\ + audio/audiofilter.cpp\ audio/audiooutput.cpp\ audio/audioinput.cpp\ audio/audionetsink.cpp\ @@ -134,6 +135,7 @@ SOURCES += audio/audiodevicemanager.cpp\ HEADERS += audio/audiodevicemanager.h\ audio/audiocompressor.h\ audio/audiofifo.h\ + audio/audiofilter.h\ audio/audiooutput.h\ audio/audioinput.h\ audio/audionetsink.h\