diff --git a/plugins/channelrx/demodchirpchat/chirpchatdemodgui.ui b/plugins/channelrx/demodchirpchat/chirpchatdemodgui.ui index 4415af525..8c14b944e 100644 --- a/plugins/channelrx/demodchirpchat/chirpchatdemodgui.ui +++ b/plugins/channelrx/demodchirpchat/chirpchatdemodgui.ui @@ -331,6 +331,11 @@ Kai + + + Black + + diff --git a/sdrbase/dsp/fftfilt.cpp b/sdrbase/dsp/fftfilt.cpp index b350c8177..8ca8a28d6 100644 --- a/sdrbase/dsp/fftfilt.cpp +++ b/sdrbase/dsp/fftfilt.cpp @@ -112,7 +112,7 @@ fftfilt::~fftfilt() if (ovlbuf) delete [] ovlbuf; } -void fftfilt::create_filter(float f1, float f2) +void fftfilt::create_filter(float f1, float f2, FFTWindow::Function wf) { // initialize the filter to zero std::fill(filter, filter + flen, cmplx{0, 0}); @@ -135,8 +135,12 @@ void fftfilt::create_filter(float f1, float f2) if (b_highpass && f2 < f1) filter[flen2 / 2] += 1; - for (int i = 0; i < flen2; i++) - filter[i] *= _blackman(i, flen2); + FFTWindow fwin; + fwin.create(wf, flen2); + fwin.apply(filter); + + // for (int i = 0; i < flen2; i++) + // filter[i] *= _blackman(i, flen2); fft->ComplexFFT(filter); // filter was expressed in the time domain (impulse response) @@ -153,16 +157,20 @@ void fftfilt::create_filter(float f1, float f2) } // Double the size of FFT used for equivalent SSB filter or assume FFT is half the size of the one used for SSB -void fftfilt::create_dsb_filter(float f2) +void fftfilt::create_dsb_filter(float f2, FFTWindow::Function wf) { // initialize the filter to zero std::fill(filter, filter + flen, cmplx{0, 0}); for (int i = 0; i < flen2; i++) { filter[i] = fsinc(f2, i, flen2); - filter[i] *= _blackman(i, flen2); + // filter[i] *= _blackman(i, flen2); } + FFTWindow fwin; + fwin.create(wf, flen2); + fwin.apply(filter); + fft->ComplexFFT(filter); // filter was expressed in the time domain (impulse response) // normalize the output filter for unity gain @@ -179,7 +187,7 @@ void fftfilt::create_dsb_filter(float f2) // Double the size of FFT used for equivalent SSB filter or assume FFT is half the size of the one used for SSB // used with runAsym for in band / opposite band asymmetrical filtering. Can be used for vestigial sideband modulation. -void fftfilt::create_asym_filter(float fopp, float fin) +void fftfilt::create_asym_filter(float fopp, float fin, FFTWindow::Function wf) { // in band // initialize the filter to zero @@ -187,9 +195,13 @@ void fftfilt::create_asym_filter(float fopp, float fin) for (int i = 0; i < flen2; i++) { filter[i] = fsinc(fin, i, flen2); - filter[i] *= _blackman(i, flen2); + // filter[i] *= _blackman(i, flen2); } + FFTWindow fwin; + fwin.create(wf, flen2); + fwin.apply(filter); + fft->ComplexFFT(filter); // filter was expressed in the time domain (impulse response) // normalize the output filter for unity gain @@ -209,9 +221,10 @@ void fftfilt::create_asym_filter(float fopp, float fin) for (int i = 0; i < flen2; i++) { filterOpp[i] = fsinc(fopp, i, flen2); - filterOpp[i] *= _blackman(i, flen2); + // filterOpp[i] *= _blackman(i, flen2); } + fwin.apply(filterOpp); fft->ComplexFFT(filterOpp); // filter was expressed in the time domain (impulse response) // normalize the output filter for unity gain diff --git a/sdrbase/dsp/fftfilt.h b/sdrbase/dsp/fftfilt.h index 55bae9c33..1aba83b90 100644 --- a/sdrbase/dsp/fftfilt.h +++ b/sdrbase/dsp/fftfilt.h @@ -9,6 +9,7 @@ #include #include "gfft.h" +#include "fftwindow.h" #include "export.h" //---------------------------------------------------------------------- @@ -25,9 +26,9 @@ public: ~fftfilt(); // f1 < f2 ==> bandpass // f1 > f2 ==> band reject - void create_filter(float f1, float f2); - void create_dsb_filter(float f2); - void create_asym_filter(float fopp, float fin); //!< two different filters for in band and opposite band + void create_filter(float f1, float f2, FFTWindow::Function wf = FFTWindow::Blackman); + void create_dsb_filter(float f2, FFTWindow::Function wf = FFTWindow::Blackman); + void create_asym_filter(float fopp, float fin, FFTWindow::Function wf = FFTWindow::Blackman); //!< two different filters for in band and opposite band void create_rrc_filter(float fb, float a); //!< root raised cosine. fb is half the band pass int noFilt(const cmplx& in, cmplx **out); diff --git a/sdrbase/dsp/fftwindow.cpp b/sdrbase/dsp/fftwindow.cpp index 74beebf31..3ded5e75f 100644 --- a/sdrbase/dsp/fftwindow.cpp +++ b/sdrbase/dsp/fftwindow.cpp @@ -51,7 +51,7 @@ void FFTWindow::create(Function function, int n) return; } - switch(function) { + switch (function) { case Flattop: wFunc = flatTop; break; @@ -72,6 +72,10 @@ void FFTWindow::create(Function function, int n) wFunc = hanning; break; + case Blackman: + wFunc = blackman; + break; + case Rectangle: default: wFunc = rectangle; diff --git a/sdrbase/dsp/fftwindow.h b/sdrbase/dsp/fftwindow.h index 32fbd7ca7..a64dc3337 100644 --- a/sdrbase/dsp/fftwindow.h +++ b/sdrbase/dsp/fftwindow.h @@ -33,7 +33,8 @@ public: Hamming, Hanning, Rectangle, - Kaiser + Kaiser, + Blackman }; FFTWindow(); @@ -70,6 +71,11 @@ private: return (0.35875 - 0.48829 * cos((2.0 * M_PI * i) / n) + 0.14128 * cos((4.0 * M_PI * i) / n) - 0.01168 * cos((6.0 * M_PI * i) / n)) * 2.79; } + static inline Real blackman(Real n, Real i) + { + return (0.42438 - 0.49734 * cos(2.0 * M_PI * i / n) + 0.078279 * cos(4.0 * M_PI * i / n)) * 2.37; + } + static inline Real hamming(Real n, Real i) { // amplitude correction = 1.855, energy correction = 1.586 diff --git a/sdrgui/gui/glspectrumgui.ui b/sdrgui/gui/glspectrumgui.ui index 68fa381d2..d676195b8 100644 --- a/sdrgui/gui/glspectrumgui.ui +++ b/sdrgui/gui/glspectrumgui.ui @@ -101,6 +101,11 @@ Kai + + + Black + +