summaryrefslogtreecommitdiff
path: root/gr-fft
diff options
context:
space:
mode:
authorTom Rondeau <tom@trondeau.com>2013-11-05 13:52:40 -0500
committerTom Rondeau <tom@trondeau.com>2013-11-05 14:12:38 -0500
commit10be863fab34d9d2ca8a080b623e48f4cac0df48 (patch)
tree514dc7e3197f7a56fd8fa734685f70afefc83949 /gr-fft
parent466c218e78b8a566bb8e6eb5ed33f95a3409eb29 (diff)
fft: Moved all window building functions into C++.
Remove window.py. All windows built using C++ functions. Exported into Python in same module (from gnuradio.fft import window). Removed all window building work in firdes, too. firdes.window now makes a direct call to fft.window.build with same parameters. Added documentation for window functions, including references to where to find coefficients and equations for (most of) the windows. All changes should not affect existing code. f
Diffstat (limited to 'gr-fft')
-rw-r--r--gr-fft/include/gnuradio/fft/CMakeLists.txt1
-rw-r--r--gr-fft/include/gnuradio/fft/window.h270
-rw-r--r--gr-fft/lib/CMakeLists.txt1
-rw-r--r--gr-fft/lib/window.cc333
-rw-r--r--gr-fft/python/fft/CMakeLists.txt1
-rw-r--r--gr-fft/python/fft/__init__.py2
-rw-r--r--gr-fft/python/fft/window.py179
-rw-r--r--gr-fft/swig/fft_swig.i2
8 files changed, 607 insertions, 182 deletions
diff --git a/gr-fft/include/gnuradio/fft/CMakeLists.txt b/gr-fft/include/gnuradio/fft/CMakeLists.txt
index 1dfa220022..55705ee660 100644
--- a/gr-fft/include/gnuradio/fft/CMakeLists.txt
+++ b/gr-fft/include/gnuradio/fft/CMakeLists.txt
@@ -27,6 +27,7 @@ install(FILES
fft_vfc.h
goertzel.h
goertzel_fc.h
+ window.h
DESTINATION ${GR_INCLUDE_DIR}/gnuradio/fft
COMPONENT "fft_devel"
)
diff --git a/gr-fft/include/gnuradio/fft/window.h b/gr-fft/include/gnuradio/fft/window.h
new file mode 100644
index 0000000000..b7479f48fb
--- /dev/null
+++ b/gr-fft/include/gnuradio/fft/window.h
@@ -0,0 +1,270 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2007,2008,2012,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gnuradio/fft/api.h>
+#include <vector>
+#include <cmath>
+#include <gnuradio/gr_complex.h>
+
+namespace gr {
+ namespace fft {
+
+ class FFT_API window {
+ public:
+
+ enum win_type {
+ WIN_NONE = -1, //!< don't use a window
+ WIN_HAMMING = 0, //!< Hamming window; max attenuation 53 dB
+ WIN_HANN = 1, //!< Hann window; max attenuation 44 dB
+ WIN_BLACKMAN = 2, //!< Blackman window; max attenuation 74 dB
+ WIN_RECTANGULAR = 3, //!< Basic rectangular window
+ WIN_KAISER = 4, //!< Kaiser window; max attenuation a function of beta, google it
+ WIN_BLACKMAN_hARRIS = 5, //!< Blackman-harris window
+ WIN_BLACKMAN_HARRIS = 5, //!< alias to WIN_BLACKMAN_hARRIS for capitalization consistency
+ WIN_BARTLETT = 6, //!< Barlett (triangular) window
+ WIN_FLATTOP = 7, //!< flat top window; useful in FFTs
+ };
+
+ /*!
+ * \brief Helper function to build cosine-based windows. 3-coefficient version.
+ */
+ static std::vector<float> coswindow(int ntaps, float c0, float c1, float c2);
+
+ /*!
+ * \brief Helper function to build cosine-based windows. 4-coefficient version.
+ */
+ static std::vector<float> coswindow(int ntaps, float c0, float c1, float c2, float c3);
+
+ /*!
+ * \brief Helper function to build cosine-based windows. 5-coefficient version.
+ */
+ static std::vector<float> coswindow(int ntaps, float c0, float c1, float c2, float c3, float c4);
+
+ /*!
+ * \brief Build a rectangular window.
+ *
+ * Taps are flat across the window.
+ *
+ * \param ntaps Number of coefficients in the window.
+ */
+ static std::vector<float> rectangular(int ntaps);
+
+ /*!
+ * \brief Build a Hamming window.
+ *
+ * See:
+ * <pre>
+ * A. V. Oppenheim and R. W. Schafer, "Discrete-Time
+ * Signal Processing," Upper Saddle River, N.J.: Prentice
+ * Hall, 2010, pp. 535-538.
+ * </pre>
+ *
+ * \param ntaps Number of coefficients in the window.
+ */
+ static std::vector<float> hamming(int ntaps);
+
+ /*!
+ * \brief Build a Hann window (sometimes known as Hanning).
+ *
+ * See:
+ * <pre>
+ * A. V. Oppenheim and R. W. Schafer, "Discrete-Time
+ * Signal Processing," Upper Saddle River, N.J.: Prentice
+ * Hall, 2010, pp. 535-538.
+ * </pre>
+ *
+ * \param ntaps Number of coefficients in the window.
+ */
+ static std::vector<float> hann(int ntaps);
+
+ /*!
+ * \brief Alias to build a Hann window.
+ *
+ * \param ntaps Number of coefficients in the window.
+ */
+ static std::vector<float> hanning(int ntaps);
+
+ /*!
+ * \brief Build an exact Blackman window.
+ *
+ * See:
+ * <pre>
+ * A. V. Oppenheim and R. W. Schafer, "Discrete-Time
+ * Signal Processing," Upper Saddle River, N.J.: Prentice
+ * Hall, 2010, pp. 535-538.
+ * </pre>
+ *
+ * \param ntaps Number of coefficients in the window.
+ */
+ static std::vector<float> blackman(int ntaps);
+
+ /*!
+ * \brief Build Blackman window, variation 1.
+ */
+ static std::vector<float> blackman2(int ntaps);
+
+ /*!
+ * \brief Build Blackman window, variation 2.
+ */
+ static std::vector<float> blackman3(int ntaps);
+
+ /*!
+ * \brief Build Blackman window, variation 3.
+ */
+ static std::vector<float> blackman4(int ntaps);
+
+ /*!
+ * \brief Build a Blackman-harris window with a given attenuation.
+ *
+ * <pre>
+ * f. j. harris, "On the use of windows for harmonic analysis
+ * with the discrete Fourier transforms," Proc. IEEE, Vol. 66,
+ * ppg. 51-83, Jan. 1978.
+ * </pre>
+ *
+ * \param ntaps Number of coefficients in the window.
+
+ * \param atten Attenuation factor. Must be [61, 67, 74, 92].
+ * See the above paper for details.
+ */
+ static std::vector<float> blackman_harris(int ntaps, int atten=92);
+
+ /*!
+ * Alias to gr::fft::window::blakcman_harris.
+ */
+ static std::vector<float> blackmanharris(int ntaps, int atten=92);
+
+ /*!
+ * \brief Build a Nuttal (or Blackman-Nuttal) window.
+ *
+ * See: http://en.wikipedia.org/wiki/Window_function#Blackman.E2.80.93Nuttall_window
+ *
+ * \param ntaps Number of coefficients in the window.
+ */
+ static std::vector<float> nuttal(int ntaps);
+
+ /*!
+ * \brief Alias to the Nuttal window.
+ *
+ * \param ntaps Number of coefficients in the window.
+ */
+ static std::vector<float> blackman_nuttal(int ntaps);
+
+ /*!
+ * \brief Build a Nuttal continuous first derivative window.
+ *
+ * See: http://en.wikipedia.org/wiki/Window_function#Nuttall_window.2C_continuous_first_derivative
+ *
+ * \param ntaps Number of coefficients in the window.
+ */
+ static std::vector<float> nuttal_cfd(int ntaps);
+
+ /*!
+ * \brief Build a Nuttal continuous first derivative window.
+ *
+ * See: http://en.wikipedia.org/wiki/Window_function#Flat_top_window
+ *
+ * \param ntaps Number of coefficients in the window.
+ */
+ static std::vector<float> flattop(int ntaps);
+
+ /*!
+ * \brief Build a Kaiser window with a given beta.
+ *
+ * See:
+ * <pre>
+ * A. V. Oppenheim and R. W. Schafer, "Discrete-Time
+ * Signal Processing," Upper Saddle River, N.J.: Prentice
+ * Hall, 2010, pp. 541-545.
+ * </pre>
+ *
+ * \param ntaps Number of coefficients in the window.
+ * \param beta Shaping parameter of the window. See the
+ * discussion in Oppenheim and Schafer.
+ */
+ static std::vector<float> kaiser(int ntaps, double beta);
+
+ /*!
+ * \brief Build a Barlett (triangular) window.
+ *
+ * See:
+ * <pre>
+ * A. V. Oppenheim and R. W. Schafer, "Discrete-Time
+ * Signal Processing," Upper Saddle River, N.J.: Prentice
+ * Hall, 2010, pp. 535-538.
+ * </pre>
+ *
+ * \param ntaps Number of coefficients in the window.
+ */
+ static std::vector<float> bartlett(int ntaps);
+
+ static std::vector<float> welch(int ntaps);
+
+ /*!
+ * \brief Build a Parzen (or de la Valle-Poussin) window.
+ *
+ * See:
+ * <pre>
+ * A. D. Poularikas, "Handbook of Formulas and Tables for
+ * Signal Processing," Springer, Oct 28, 1998
+ * </pre>
+ *
+ * \param ntaps Number of coefficients in the window.
+ */
+ static std::vector<float> parzen(int ntaps);
+
+ /*!
+ * \brief Build an exponential window with a given decay.
+ *
+ * See: http://en.wikipedia.org/wiki/Window_function#Exponential_or_Poisson_window
+ *
+ * \param ntaps Number of coefficients in the window.
+ * \param d Decay of \p d dB over half the window length.
+ */
+ static std::vector<float> exponential(int ntaps, double d);
+
+ /*!
+ * \brief Build a Riemann window.
+ *
+ * See:
+ * <pre>
+ * A. D. Poularikas, "Handbook of Formulas and Tables for
+ * Signal Processing," Springer, Oct 28, 1998
+ * </pre>
+ *
+ * \param ntaps Number of coefficients in the window.
+ */
+ static std::vector<float> riemann(int ntaps);
+
+ /*!
+ * \brief Build a window using gr::fft::win_type to index the
+ * type of window desired.
+ *
+ * \param type a gr::fft::win_type index for the type of window.
+ * \param ntaps Number of coefficients in the window.
+ * \param beta Used only for building Kaiser windows.
+ */
+ static std::vector<float> build(win_type type, int ntaps, double beta);
+ };
+
+ } /* namespace fft */
+} /* namespace gr */
diff --git a/gr-fft/lib/CMakeLists.txt b/gr-fft/lib/CMakeLists.txt
index c94d588f6a..045df5b4f8 100644
--- a/gr-fft/lib/CMakeLists.txt
+++ b/gr-fft/lib/CMakeLists.txt
@@ -46,6 +46,7 @@ list(APPEND fft_sources
fft_vfc_fftw.cc
goertzel_fc_impl.cc
goertzel.cc
+ window.cc
)
if(ENABLE_GR_CTRLPORT)
diff --git a/gr-fft/lib/window.cc b/gr-fft/lib/window.cc
new file mode 100644
index 0000000000..5a28b3239d
--- /dev/null
+++ b/gr-fft/lib/window.cc
@@ -0,0 +1,333 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2007,2008,2012,2013 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gnuradio/fft/window.h>
+#include <stdexcept>
+
+namespace gr {
+ namespace fft {
+
+#define IzeroEPSILON 1E-21 /* Max error acceptable in Izero */
+
+ static double Izero(double x)
+ {
+ double sum, u, halfx, temp;
+ int n;
+
+ sum = u = n = 1;
+ halfx = x/2.0;
+ do {
+ temp = halfx/(double)n;
+ n += 1;
+ temp *= temp;
+ u *= temp;
+ sum += u;
+ } while (u >= IzeroEPSILON*sum);
+ return(sum);
+ }
+
+ double midn(int ntaps)
+ {
+ return ntaps/2.0;
+ }
+
+ double midm1(int ntaps)
+ {
+ return (ntaps - 1.0)/2.0;
+ }
+
+ double midp1(int ntaps)
+ {
+ return (ntaps + 1.0)/2.0;
+ }
+
+ double freq(int ntaps)
+ {
+ return 2.0*M_PI/ntaps;
+ }
+
+ double rate(int ntaps)
+ {
+ return 1.0/(ntaps >> 1);
+ }
+
+ std::vector<float>
+ window::coswindow(int ntaps, float c0, float c1, float c2)
+ {
+ std::vector<float> taps(ntaps);
+ float M = static_cast<float>(ntaps - 1);
+
+ for(int n = 0; n < ntaps; n++)
+ taps[n] = c0 - c1*cos((2*M_PI*n)/M) + c2*cos((4*M_PI*n)/M);
+ return taps;
+ }
+
+ std::vector<float>
+ window::coswindow(int ntaps, float c0, float c1, float c2, float c3)
+ {
+ std::vector<float> taps(ntaps);
+ float M = static_cast<float>(ntaps - 1);
+
+ for(int n = 0; n < ntaps; n++)
+ taps[n] = c0 - c1*cos((2*M_PI*n)/M) + c2*cos((4*M_PI*n)/M) - c3*cos((6*M_PI*n)/M);
+ return taps;
+ }
+
+ std::vector<float>
+ window::coswindow(int ntaps, float c0, float c1, float c2, float c3, float c4)
+ {
+ std::vector<float> taps(ntaps);
+ float M = static_cast<float>(ntaps - 1);
+
+ for(int n = 0; n < ntaps; n++)
+ taps[n] = c0 - c1*cos((2*M_PI*n)/M) + c2*cos((4*M_PI*n)/M) - c3*cos((6*M_PI*n)/M) + c4*cos((8*M_PI*n)/M);
+ return taps;
+ }
+
+ std::vector<float>
+ window::rectangular(int ntaps)
+ {
+ std::vector<float> taps(ntaps);
+ for(int n = 0; n < ntaps; n++)
+ taps[n] = 1;
+ return taps;
+ }
+
+ std::vector<float>
+ window::hamming(int ntaps)
+ {
+ std::vector<float> taps(ntaps);
+ float M = static_cast<float>(ntaps - 1);
+
+ for(int n = 0; n < ntaps; n++)
+ taps[n] = 0.54 - 0.46 * cos((2 * M_PI * n) / M);
+ return taps;
+ }
+
+ std::vector<float>
+ window::hann(int ntaps)
+ {
+ std::vector<float> taps(ntaps);
+ float M = static_cast<float>(ntaps - 1);
+
+ for(int n = 0; n < ntaps; n++)
+ taps[n] = 0.5 - 0.5 * cos((2 * M_PI * n) / M);
+ return taps;
+ }
+
+ std::vector<float>
+ window::hanning(int ntaps)
+ {
+ return hann(ntaps);
+ }
+
+ std::vector<float>
+ window::blackman(int ntaps)
+ {
+ return coswindow(ntaps, 0.42, 0.5, 0.08);
+ }
+
+ std::vector<float>
+ window::blackman2(int ntaps)
+ {
+ return coswindow(ntaps, 0.34401, 0.49755, 0.15844);
+ }
+
+ std::vector<float>
+ window::blackman3(int ntaps)
+ {
+ return coswindow(ntaps, 0.21747, 0.45325, 0.28256, 0.04672);
+ }
+
+ std::vector<float>
+ window::blackman4(int ntaps)
+ {
+ return coswindow(ntaps, 0.084037, 0.29145, 0.375696, 0.20762, 0.041194);
+ }
+
+ std::vector<float>
+ window::blackman_harris(int ntaps, int atten)
+ {
+ switch(atten) {
+ case(61): return coswindow(ntaps, 0.42323, 0.49755, 0.07922);
+ case(67): return coswindow(ntaps, 0.44959, 0.49364, 0.05677);
+ case(74): return coswindow(ntaps, 0.40271, 0.49703, 0.09392, 0.00183);
+ case(92): return coswindow(ntaps, 0.35875, 0.48829, 0.14128, 0.01168);
+ default:
+ throw std::out_of_range("window::blackman_harris: unknown attenuation value (must be 61, 67, 74, or 92)");
+ }
+ }
+
+ std::vector<float>
+ window::blackmanharris(int ntaps, int atten)
+ {
+ return blackman_harris(ntaps, atten);
+ }
+
+ std::vector<float>
+ window::nuttal(int ntaps)
+ {
+ return coswindow(ntaps, 0.3635819, 0.4891775, 0.1365995, 0.0106411);
+ }
+
+ std::vector<float>
+ window::blackman_nuttal(int ntaps)
+ {
+ return nuttal(ntaps);
+ }
+
+ std::vector<float>
+ window::nuttal_cfd(int ntaps)
+ {
+ return coswindow(ntaps, 0.355768, 0.487396, 0.144232, 0.012604);
+ }
+
+ std::vector<float>
+ window::flattop(int ntaps)
+ {
+ double scale = 4.63867;
+ return coswindow(ntaps, 1.0/scale, 1.93/scale, 1.29/scale, 0.388/scale, 0.028/scale);
+ }
+
+ std::vector<float>
+ window::kaiser(int ntaps, double beta)
+ {
+ if(beta < 0)
+ throw std::out_of_range("window::kaiser: beta must be >= 0");
+
+ std::vector<float> taps(ntaps);
+
+ double IBeta = 1.0/Izero(beta);
+ double inm1 = 1.0/((double)(ntaps-1));
+ double temp;
+
+ for(int i = 0; i <= ntaps; i++) {
+ temp = 2*i*inm1 - 1;
+ taps[i] = Izero(beta*sqrt(1.0-temp*temp)) * IBeta;
+ }
+ return taps;
+ }
+
+ std::vector<float>
+ window::bartlett(int ntaps)
+ {
+ std::vector<float> taps(ntaps);
+ float M = static_cast<float>(ntaps - 1);
+
+ for(int n = 0; n < ntaps/2; n++)
+ taps[n] = 2*n/M;
+ for(int n = ntaps/2; n < ntaps; n++)
+ taps[n] = 2 - 2*n/M;
+
+ return taps;
+ }
+
+ std::vector<float>
+ window::welch(int ntaps)
+ {
+ std::vector<float> taps(ntaps);
+ double m1 = midm1(ntaps);
+ double p1 = midp1(ntaps);
+ for(int i = 0; i < midn(ntaps)+1; i++) {
+ taps[i] = 1.0 - pow((i - m1) / p1, 2);
+ taps[ntaps-i-1] = taps[i];
+ }
+ return taps;
+ }
+
+ std::vector<float>
+ window::parzen(int ntaps)
+ {
+ std::vector<float> taps(ntaps);
+ double m1 = midm1(ntaps);
+ double m = midn(ntaps);
+ int i;
+ for(i = ntaps/4; i < 3*ntaps/4; i++) {
+ taps[i] = 1.0 - 6.0*pow((i-m1)/m, 2.0) * (1.0 - fabs(i-m1)/m);
+ }
+ for(; i < ntaps; i++) {
+ taps[i] = 2.0 * pow(1.0 - fabs(i-m1)/m, 3.0);
+ taps[ntaps-i-1] = taps[i];
+ }
+ return taps;
+ }
+
+ std::vector<float>
+ window::exponential(int ntaps, double d)
+ {
+ if(d < 0)
+ throw std::out_of_range("window::exponential: d must be >= 0");
+
+ double m1 = midm1(ntaps);
+ double p = 1.0 / (8.69*ntaps/(2.0*d));
+ std::vector<float> taps(ntaps);
+ for(int i = 0; i < midn(ntaps)+1; i++) {
+ taps[i] = exp(-fabs(i - m1)*p);
+ taps[ntaps-i-1] = taps[i];
+ }
+ return taps;
+ }
+
+ std::vector<float>
+ window::riemann(int ntaps)
+ {
+ double cx;
+ double sr1 = freq(ntaps);
+ double mid = midn(ntaps);
+ std::vector<float> taps(ntaps);
+ for(int i = 0; i < mid; i++) {
+ if(i == midn(ntaps)) {
+ taps[i] = 1.0;
+ taps[ntaps-i-1] = 1.0;
+ }
+ else {
+ cx = sr1*(i - mid);
+ taps[i] = sin(cx)/cx;
+ taps[ntaps-i-1] = sin(cx)/cx;
+ }
+ }
+ return taps;
+ }
+
+ std::vector<float>
+ window::build(win_type type, int ntaps, double beta)
+ {
+ switch (type) {
+ case WIN_RECTANGULAR: return rectangular(ntaps);
+ case WIN_HAMMING: return hamming(ntaps);
+ case WIN_HANN: return hann(ntaps);
+ case WIN_BLACKMAN: return blackman(ntaps);
+ case WIN_BLACKMAN_hARRIS: return blackman_harris(ntaps);
+ case WIN_KAISER: return kaiser(ntaps, beta);
+ case WIN_BARTLETT: return bartlett(ntaps);
+ case WIN_FLATTOP: return flattop(ntaps);
+ default:
+ throw std::out_of_range("window::build: type out of range");
+ }
+ }
+
+ } /* namespace fft */
+} /* namespace gr */
diff --git a/gr-fft/python/fft/CMakeLists.txt b/gr-fft/python/fft/CMakeLists.txt
index 33d37b51b9..e0bc19124d 100644
--- a/gr-fft/python/fft/CMakeLists.txt
+++ b/gr-fft/python/fft/CMakeLists.txt
@@ -24,7 +24,6 @@ GR_PYTHON_INSTALL(
FILES
__init__.py
logpwrfft.py
- window.py
DESTINATION ${GR_PYTHON_DIR}/gnuradio/fft
COMPONENT "fft_python"
)
diff --git a/gr-fft/python/fft/__init__.py b/gr-fft/python/fft/__init__.py
index e0803cbf38..1864353ed1 100644
--- a/gr-fft/python/fft/__init__.py
+++ b/gr-fft/python/fft/__init__.py
@@ -30,5 +30,3 @@ except ImportError:
dirname, filename = os.path.split(os.path.abspath(__file__))
__path__.append(os.path.join(dirname, "..", "..", "swig"))
from fft_swig import *
-
-from window import *
diff --git a/gr-fft/python/fft/window.py b/gr-fft/python/fft/window.py
deleted file mode 100644
index 0065a08a61..0000000000
--- a/gr-fft/python/fft/window.py
+++ /dev/null
@@ -1,179 +0,0 @@
-#
-# Copyright 2004,2005,2009 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-'''
-Routines for designing window functions.
-'''
-
-import math
-
-def izero(x):
- izeroepsilon = 1e-21
- halfx = x/2.0
- accum = u = n = 1
- while 1:
- temp = halfx/n
- n += 1
- temp *= temp
- u *= temp
- accum += u
- if u >= IzeroEPSILON*sum:
- break
- return accum
-
-def midm1(fft_size):
- return (fft_size - 1)/2
-
-def midp1(fft_size):
- return (fft_size+1)/2
-
-def freq(fft_size):
- return 2.0*math.pi/fft_size
-
-def rate(fft_size):
- return 1.0/(fft_size >> 1)
-
-def expn(fft_size):
- math.log(2.0)/(midn(fft_size) + 1.0)
-
-def hamming(fft_size):
- window = []
- for index in xrange(fft_size):
- window.append(0.54 - 0.46 * math.cos (2 * math.pi / fft_size * index)) # Hamming window
- return window
-
-def hanning(fft_size):
- window = []
- for index in xrange(fft_size):
- window.append(0.5 - 0.5 * math.cos (2 * math.pi / fft_size * index)) # von Hann window
- return window
-
-def welch(fft_size):
- window = [0 for i in range(fft_size)]
- j = fft_size-1
- for index in xrange(midn(fft_size)+1):
- window[j] = window[index] = (1.0 - math.sqrt((index - midm1(fft_size)) / midp1(fft_size)))
- j -= 1
- return window
-
-def parzen(fft_size):
- window = [0 for i in range(fft_size)]
- j = fft_size-1
- for index in xrange(midn(fft_size)+1):
- window[j] = window[index] = (1.0 - math.abs((index - midm1(fft_size)) / midp1(fft_size)))
- j -= 1
- return window
-
-def bartlett(fft_size):
- mfrq = freq(fft_size)
- angle = 0
- window = [0 for i in range(fft_size)]
- j = fft_size-1
- for index in xrange(midn(fft_size)+1):
- window[j] = window[index] = angle
- angle += freq
- j -= 1
- return window
-
-def blackman2(fft_size):
- mfrq = freq(fft_size)
- angle = 0
- window = [0 for i in range(fft_size)]
- j = fft_size-1
- for index in xrange(midn(fft_size)+1):
- cx = math.cos(angle)
- window[j] = window[index] = (.34401 + (cx * (-.49755 + (cx * .15844))))
- angle += freq
- j -= 1
- return window
-
-def blackman3(fft_size):
- mfrq = freq(fft_size)
- angle = 0
- window = [0 for i in range(fft_size)]
- j = fft_size-1
- for index in xrange(midn(fft_size)+1):
- cx = math.cos(angle)
- window[j] = window[index] = (.21747 + (cx * (-.45325 + (cx * (.28256 - (cx * .04672))))))
- angle += freq
- j -= 1
- return window
-
-def blackman4(fft_size):
- mfrq = freq(fft_size)
- angle = 0
- window = [0 for i in range(fft_size)]
- j = fft_size-1
- for index in xrange(midn(fft_size)+1):
- cx = math.cos(angle)
- window[j] = window[index] = (.084037 + (cx * (-.29145 + (cx * (.375696 + (cx * (-.20762 + (cx * .041194))))))))
- angle += freq
- j -= 1
- return window
-
-def exponential(fft_size):
- expsum = 1.0
- window = [0 for i in range(fft_size)]
- j = fft_size-1
- for index in xrange(midn(fft_size)+1):
- window[j] = window[i] = (expsum - 1.0)
- expsum *= expn(fft_size)
- j -= 1
- return window
-
-def riemann(fft_size):
- sr1 = freq(fft_size)
- window = [0 for i in range(fft_size)]
- j = fft_size-1
- for index in xrange(midn(fft_size)):
- if index == midn(fft_size):
- window[index] = window[j] = 1.0
- else:
- cx = sr1*midn(fft_size) - index
- window[index] = window[j] = math.sin(cx)/cx
- j -= 1
- return window
-
-def kaiser(fft_size,beta):
- ibeta = 1.0/izero(beta)
- inm1 = 1.0/(fft_size)
- window = [0 for i in range(fft_size)]
- for index in xrange(fft_size):
- window[index] = izero(beta*math.sqrt(1.0 - (index * inm1)*(index * inm1))) * ibeta
- return window
-
-# Closure to generate functions to create cos windows
-
-def coswindow(coeffs):
- def closure(fft_size):
- window = [0] * fft_size
- #print list(enumerate(coeffs))
- for w_index in range(fft_size):
- for (c_index, coeff) in enumerate(coeffs):
- window[w_index] += (-1)**c_index * coeff * math.cos(2.0*c_index*math.pi*(w_index+0.5)/(fft_size-1))
- return window
- return closure
-
-blackmanharris = coswindow((0.35875,0.48829,0.14128,0.01168))
-nuttall = coswindow((0.3635819,0.4891775,0.1365995,0.0106411)) # Wikipedia calls this Blackman-Nuttall
-nuttall_cfd = coswindow((0.355768,0.487396,0.144232,0.012604)) # Wikipedia calls this Nuttall, continuous first deriv
-flattop = coswindow((1.0,1.93,1.29,0.388,0.032)) # Flat top window, coeffs from Wikipedia
-rectangular = lambda fft_size: [1]*fft_size
diff --git a/gr-fft/swig/fft_swig.i b/gr-fft/swig/fft_swig.i
index edc3c594ac..062328f12a 100644
--- a/gr-fft/swig/fft_swig.i
+++ b/gr-fft/swig/fft_swig.i
@@ -31,11 +31,13 @@
#include "gnuradio/fft/fft_vcc.h"
#include "gnuradio/fft/fft_vfc.h"
#include "gnuradio/fft/goertzel_fc.h"
+#include "gnuradio/fft/window.h"
%}
%include "gnuradio/fft/fft_vcc.h"
%include "gnuradio/fft/fft_vfc.h"
%include "gnuradio/fft/goertzel_fc.h"
+%include "gnuradio/fft/window.h"
GR_SWIG_BLOCK_MAGIC2(fft, fft_vcc);
GR_SWIG_BLOCK_MAGIC2(fft, fft_vfc);