mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-10 10:33:29 -05:00
Added 3 term Blackman window to FFTWindow and use it as default in FFT filter
This commit is contained in:
parent
d79d121a6b
commit
5447a8caef
@ -331,6 +331,11 @@
|
|||||||
<string>Kai</string>
|
<string>Kai</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Black</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
@ -112,7 +112,7 @@ fftfilt::~fftfilt()
|
|||||||
if (ovlbuf) delete [] ovlbuf;
|
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
|
// initialize the filter to zero
|
||||||
std::fill(filter, filter + flen, cmplx{0, 0});
|
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)
|
if (b_highpass && f2 < f1)
|
||||||
filter[flen2 / 2] += 1;
|
filter[flen2 / 2] += 1;
|
||||||
|
|
||||||
for (int i = 0; i < flen2; i++)
|
FFTWindow fwin;
|
||||||
filter[i] *= _blackman(i, flen2);
|
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)
|
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
|
// 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
|
// initialize the filter to zero
|
||||||
std::fill(filter, filter + flen, cmplx{0, 0});
|
std::fill(filter, filter + flen, cmplx{0, 0});
|
||||||
|
|
||||||
for (int i = 0; i < flen2; i++) {
|
for (int i = 0; i < flen2; i++) {
|
||||||
filter[i] = fsinc(f2, i, flen2);
|
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)
|
fft->ComplexFFT(filter); // filter was expressed in the time domain (impulse response)
|
||||||
|
|
||||||
// normalize the output filter for unity gain
|
// 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
|
// 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.
|
// 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
|
// in band
|
||||||
// initialize the filter to zero
|
// 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++) {
|
for (int i = 0; i < flen2; i++) {
|
||||||
filter[i] = fsinc(fin, i, flen2);
|
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)
|
fft->ComplexFFT(filter); // filter was expressed in the time domain (impulse response)
|
||||||
|
|
||||||
// normalize the output filter for unity gain
|
// 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++) {
|
for (int i = 0; i < flen2; i++) {
|
||||||
filterOpp[i] = fsinc(fopp, i, flen2);
|
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)
|
fft->ComplexFFT(filterOpp); // filter was expressed in the time domain (impulse response)
|
||||||
|
|
||||||
// normalize the output filter for unity gain
|
// normalize the output filter for unity gain
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "gfft.h"
|
#include "gfft.h"
|
||||||
|
#include "fftwindow.h"
|
||||||
#include "export.h"
|
#include "export.h"
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
@ -25,9 +26,9 @@ public:
|
|||||||
~fftfilt();
|
~fftfilt();
|
||||||
// f1 < f2 ==> bandpass
|
// f1 < f2 ==> bandpass
|
||||||
// f1 > f2 ==> band reject
|
// f1 > f2 ==> band reject
|
||||||
void create_filter(float f1, float f2);
|
void create_filter(float f1, float f2, FFTWindow::Function wf = FFTWindow::Blackman);
|
||||||
void create_dsb_filter(float f2);
|
void create_dsb_filter(float f2, FFTWindow::Function wf = FFTWindow::Blackman);
|
||||||
void create_asym_filter(float fopp, float fin); //!< two different filters for in band and opposite band
|
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
|
void create_rrc_filter(float fb, float a); //!< root raised cosine. fb is half the band pass
|
||||||
|
|
||||||
int noFilt(const cmplx& in, cmplx **out);
|
int noFilt(const cmplx& in, cmplx **out);
|
||||||
|
@ -51,7 +51,7 @@ void FFTWindow::create(Function function, int n)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(function) {
|
switch (function) {
|
||||||
case Flattop:
|
case Flattop:
|
||||||
wFunc = flatTop;
|
wFunc = flatTop;
|
||||||
break;
|
break;
|
||||||
@ -72,6 +72,10 @@ void FFTWindow::create(Function function, int n)
|
|||||||
wFunc = hanning;
|
wFunc = hanning;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Blackman:
|
||||||
|
wFunc = blackman;
|
||||||
|
break;
|
||||||
|
|
||||||
case Rectangle:
|
case Rectangle:
|
||||||
default:
|
default:
|
||||||
wFunc = rectangle;
|
wFunc = rectangle;
|
||||||
|
@ -33,7 +33,8 @@ public:
|
|||||||
Hamming,
|
Hamming,
|
||||||
Hanning,
|
Hanning,
|
||||||
Rectangle,
|
Rectangle,
|
||||||
Kaiser
|
Kaiser,
|
||||||
|
Blackman
|
||||||
};
|
};
|
||||||
|
|
||||||
FFTWindow();
|
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;
|
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)
|
static inline Real hamming(Real n, Real i)
|
||||||
{
|
{
|
||||||
// amplitude correction = 1.855, energy correction = 1.586
|
// amplitude correction = 1.855, energy correction = 1.586
|
||||||
|
@ -101,6 +101,11 @@
|
|||||||
<string>Kai</string>
|
<string>Kai</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Black</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
Loading…
Reference in New Issue
Block a user