mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-07-31 05:02:24 -04:00
Added Kaiser window
This commit is contained in:
parent
738d069386
commit
8a5daee1b8
@ -18,12 +18,39 @@
|
|||||||
|
|
||||||
#include "dsp/fftwindow.h"
|
#include "dsp/fftwindow.h"
|
||||||
|
|
||||||
|
FFTWindow::FFTWindow() :
|
||||||
|
m_kaiserAlpha(2.15) // beta = 6.76 first sidelobe at -70dB
|
||||||
|
{
|
||||||
|
m_kaiserI0Alpha = zeroethOrderBessel(m_kaiserAlpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FFTWindow::setKaiserAlpha(Real alpha)
|
||||||
|
{
|
||||||
|
m_kaiserAlpha = alpha;
|
||||||
|
m_kaiserI0Alpha = zeroethOrderBessel(m_kaiserAlpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FFTWindow::setKaiserBeta(Real beta)
|
||||||
|
{
|
||||||
|
m_kaiserAlpha = beta / M_PI;
|
||||||
|
m_kaiserI0Alpha = zeroethOrderBessel(m_kaiserAlpha);
|
||||||
|
}
|
||||||
|
|
||||||
void FFTWindow::create(Function function, int n)
|
void FFTWindow::create(Function function, int n)
|
||||||
{
|
{
|
||||||
Real (*wFunc)(Real n, Real i);
|
Real (*wFunc)(Real n, Real i);
|
||||||
|
|
||||||
m_window.clear();
|
m_window.clear();
|
||||||
|
|
||||||
|
if (function == Kaiser) // Kaiser special case
|
||||||
|
{
|
||||||
|
for(int i = 0; i < n; i++) {
|
||||||
|
m_window.push_back(kaiser(n, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch(function) {
|
switch(function) {
|
||||||
case Flattop:
|
case Flattop:
|
||||||
wFunc = flatTop;
|
wFunc = flatTop;
|
||||||
@ -51,8 +78,9 @@ void FFTWindow::create(Function function, int n)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < n; i++)
|
for(int i = 0; i < n; i++) {
|
||||||
m_window.push_back(wFunc(n, i));
|
m_window.push_back(wFunc(n, i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FFTWindow::apply(const std::vector<Real>& in, std::vector<Real>* out)
|
void FFTWindow::apply(const std::vector<Real>& in, std::vector<Real>* out)
|
||||||
|
@ -36,18 +36,25 @@ public:
|
|||||||
Flattop,
|
Flattop,
|
||||||
Hamming,
|
Hamming,
|
||||||
Hanning,
|
Hanning,
|
||||||
Rectangle
|
Rectangle,
|
||||||
|
Kaiser
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FFTWindow();
|
||||||
|
|
||||||
void create(Function function, int n);
|
void create(Function function, int n);
|
||||||
void apply(const std::vector<Real>& in, std::vector<Real>* out);
|
void apply(const std::vector<Real>& in, std::vector<Real>* out);
|
||||||
void apply(const std::vector<Complex>& in, std::vector<Complex>* out);
|
void apply(const std::vector<Complex>& in, std::vector<Complex>* out);
|
||||||
void apply(std::vector<Complex>& in);
|
void apply(std::vector<Complex>& in);
|
||||||
void apply(const Complex* in, Complex* out);
|
void apply(const Complex* in, Complex* out);
|
||||||
void apply(Complex* in);
|
void apply(Complex* in);
|
||||||
|
void setKaiserAlpha(Real alpha); //!< set the Kaiser window alpha factor (default 2.15)
|
||||||
|
void setKaiserBeta(Real beta); //!< set the Kaiser window beta factor = pi * alpha
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<float> m_window;
|
std::vector<float> m_window;
|
||||||
|
Real m_kaiserAlpha; //!< alpha factor for Kaiser window
|
||||||
|
Real m_kaiserI0Alpha; //!< zeroethOrderBessel of alpha above
|
||||||
|
|
||||||
static inline Real flatTop(Real n, Real i)
|
static inline Real flatTop(Real n, Real i)
|
||||||
{
|
{
|
||||||
@ -83,6 +90,36 @@ private:
|
|||||||
{
|
{
|
||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://raw.githubusercontent.com/johnglover/simpl/master/src/loris/KaiserWindow.C
|
||||||
|
inline Real kaiser(Real n, Real i)
|
||||||
|
{
|
||||||
|
Real K = ((2.0*i) / n) - 1.0;
|
||||||
|
Real arg = sqrt(1.0 - (K*K));
|
||||||
|
return zeroethOrderBessel(m_kaiserAlpha*arg) / m_kaiserI0Alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Real zeroethOrderBessel( Real x )
|
||||||
|
{
|
||||||
|
const Real eps = 0.000001;
|
||||||
|
|
||||||
|
// initialize the series term for m=0 and the result
|
||||||
|
Real besselValue = 0;
|
||||||
|
Real term = 1;
|
||||||
|
Real m = 0;
|
||||||
|
|
||||||
|
// accumulate terms as long as they are significant
|
||||||
|
while(term > eps * besselValue)
|
||||||
|
{
|
||||||
|
besselValue += term;
|
||||||
|
|
||||||
|
// update the term
|
||||||
|
++m;
|
||||||
|
term *= (x*x) / (4*m*m);
|
||||||
|
}
|
||||||
|
|
||||||
|
return besselValue;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // INCLUDE_FFTWINDOWS_H
|
#endif // INCLUDE_FFTWINDOWS_H
|
||||||
|
@ -387,6 +387,11 @@
|
|||||||
<string>Rec</string>
|
<string>Rec</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Kai</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
@ -364,6 +364,7 @@ Use this combo box to select which window is applied to the FFT:
|
|||||||
- **Ham**: Hamming
|
- **Ham**: Hamming
|
||||||
- **Han**: Hanning (default)
|
- **Han**: Hanning (default)
|
||||||
- **Rec**: Rectangular (no window)
|
- **Rec**: Rectangular (no window)
|
||||||
|
- **Kai**: Kaiser with alpha = 2.15 (beta = 6.76) gives sidelobes < -70dB
|
||||||
|
|
||||||
<h4>4.2. FFT size</h4>
|
<h4>4.2. FFT size</h4>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user