Added 3 term Blackman window to FFTWindow and use it as default in FFT filter

pull/1253/head
f4exb 2022-05-18 01:30:32 +02:00
rodzic d79d121a6b
commit 5447a8caef
6 zmienionych plików z 47 dodań i 13 usunięć

Wyświetl plik

@ -331,6 +331,11 @@
<string>Kai</string>
</property>
</item>
<item>
<property name="text">
<string>Black</string>
</property>
</item>
</widget>
</item>
<item>

Wyświetl plik

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

Wyświetl plik

@ -9,6 +9,7 @@
#include <cmath>
#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);

Wyświetl plik

@ -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;

Wyświetl plik

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

Wyświetl plik

@ -101,6 +101,11 @@
<string>Kai</string>
</property>
</item>
<item>
<property name="text">
<string>Black</string>
</property>
</item>
</widget>
</item>
<item>