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
+
+
-