From e8b4e619479dd23d87c3aef042f2452f867a1e18 Mon Sep 17 00:00:00 2001
From: Ben Reynwar <ben@reynwar.net>
Date: Thu, 7 Mar 2013 23:22:22 -0700
Subject: fft: Enabling uninstalled python imports.

---
 gr-fft/python/CMakeLists.txt     |  51 ----------
 gr-fft/python/__init__.py        |  28 -----
 gr-fft/python/fft/CMakeLists.txt |  51 ++++++++++
 gr-fft/python/fft/__init__.py    |  35 +++++++
 gr-fft/python/fft/logpwrfft.py   | 176 ++++++++++++++++++++++++++++++++
 gr-fft/python/fft/qa_fft.py      | 214 +++++++++++++++++++++++++++++++++++++++
 gr-fft/python/fft/qa_goertzel.py |  65 ++++++++++++
 gr-fft/python/fft/window.py      | 179 ++++++++++++++++++++++++++++++++
 gr-fft/python/logpwrfft.py       | 176 --------------------------------
 gr-fft/python/qa_fft.py          | 214 ---------------------------------------
 gr-fft/python/qa_goertzel.py     |  65 ------------
 gr-fft/python/window.py          | 179 --------------------------------
 12 files changed, 720 insertions(+), 713 deletions(-)
 delete mode 100644 gr-fft/python/CMakeLists.txt
 delete mode 100644 gr-fft/python/__init__.py
 create mode 100644 gr-fft/python/fft/CMakeLists.txt
 create mode 100644 gr-fft/python/fft/__init__.py
 create mode 100644 gr-fft/python/fft/logpwrfft.py
 create mode 100755 gr-fft/python/fft/qa_fft.py
 create mode 100755 gr-fft/python/fft/qa_goertzel.py
 create mode 100644 gr-fft/python/fft/window.py
 delete mode 100644 gr-fft/python/logpwrfft.py
 delete mode 100755 gr-fft/python/qa_fft.py
 delete mode 100755 gr-fft/python/qa_goertzel.py
 delete mode 100644 gr-fft/python/window.py

(limited to 'gr-fft/python')

diff --git a/gr-fft/python/CMakeLists.txt b/gr-fft/python/CMakeLists.txt
deleted file mode 100644
index 415d87e2e8..0000000000
--- a/gr-fft/python/CMakeLists.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright 2012 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(GrPython)
-
-GR_PYTHON_INSTALL(
-    FILES
-    __init__.py
-    logpwrfft.py
-    window.py
-    DESTINATION ${GR_PYTHON_DIR}/gnuradio/fft
-    COMPONENT "fft_python"
-)
-
-########################################################################
-# Handle the unit tests
-########################################################################
-if(ENABLE_TESTING)
-
-list(APPEND GR_TEST_PYTHON_DIRS
-    ${CMAKE_BINARY_DIR}/gr-fft/python
-    ${CMAKE_BINARY_DIR}/gr-fft/swig
-    ${CMAKE_BINARY_DIR}/gr-blocks/python
-    ${CMAKE_BINARY_DIR}/gr-blocks/swig
-)
-list(APPEND GR_TEST_TARGET_DEPS gnuradio-fft)
-
-include(GrTest)
-file(GLOB py_qa_test_files "qa_*.py")
-foreach(py_qa_test_file ${py_qa_test_files})
-    get_filename_component(py_qa_test_name ${py_qa_test_file} NAME_WE)
-    GR_ADD_TEST(${py_qa_test_name} ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} ${py_qa_test_file})
-endforeach(py_qa_test_file)
-endif(ENABLE_TESTING)
diff --git a/gr-fft/python/__init__.py b/gr-fft/python/__init__.py
deleted file mode 100644
index 093cc3c696..0000000000
--- a/gr-fft/python/__init__.py
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# Copyright 2012 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.
-#
-
-'''
-This is the gr-fft package. This package provides GNU Radio
-processing blocks for FFT and related functions.
-'''
-
-from fft_swig import *
-from window import *
diff --git a/gr-fft/python/fft/CMakeLists.txt b/gr-fft/python/fft/CMakeLists.txt
new file mode 100644
index 0000000000..415d87e2e8
--- /dev/null
+++ b/gr-fft/python/fft/CMakeLists.txt
@@ -0,0 +1,51 @@
+# Copyright 2012 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(GrPython)
+
+GR_PYTHON_INSTALL(
+    FILES
+    __init__.py
+    logpwrfft.py
+    window.py
+    DESTINATION ${GR_PYTHON_DIR}/gnuradio/fft
+    COMPONENT "fft_python"
+)
+
+########################################################################
+# Handle the unit tests
+########################################################################
+if(ENABLE_TESTING)
+
+list(APPEND GR_TEST_PYTHON_DIRS
+    ${CMAKE_BINARY_DIR}/gr-fft/python
+    ${CMAKE_BINARY_DIR}/gr-fft/swig
+    ${CMAKE_BINARY_DIR}/gr-blocks/python
+    ${CMAKE_BINARY_DIR}/gr-blocks/swig
+)
+list(APPEND GR_TEST_TARGET_DEPS gnuradio-fft)
+
+include(GrTest)
+file(GLOB py_qa_test_files "qa_*.py")
+foreach(py_qa_test_file ${py_qa_test_files})
+    get_filename_component(py_qa_test_name ${py_qa_test_file} NAME_WE)
+    GR_ADD_TEST(${py_qa_test_name} ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} ${py_qa_test_file})
+endforeach(py_qa_test_file)
+endif(ENABLE_TESTING)
diff --git a/gr-fft/python/fft/__init__.py b/gr-fft/python/fft/__init__.py
new file mode 100644
index 0000000000..acb70a2947
--- /dev/null
+++ b/gr-fft/python/fft/__init__.py
@@ -0,0 +1,35 @@
+#
+# Copyright 2012 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.
+#
+
+'''
+This is the gr-fft package. This package provides GNU Radio
+processing blocks for FFT and related functions.
+'''
+import os
+
+try:
+    from fft_swig import *
+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/logpwrfft.py b/gr-fft/python/fft/logpwrfft.py
new file mode 100644
index 0000000000..98303b1e1e
--- /dev/null
+++ b/gr-fft/python/fft/logpwrfft.py
@@ -0,0 +1,176 @@
+#
+# Copyright 2008 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.
+#
+
+from gnuradio import gr
+from gnuradio import blocks
+import sys, math
+
+import fft_swig as fft
+import window
+
+try:
+    from gnuradio import filter
+except ImportError:
+    sys.stderr.write('fft.logpwrfft required gr-filter.\n')
+    sys.exit(1)
+
+class _logpwrfft_base(gr.hier_block2):
+    """
+    Create a log10(abs(fft)) stream chain, with real or complex input.
+    """
+
+    def __init__(self, sample_rate, fft_size, ref_scale, frame_rate, avg_alpha, average, win=None):
+        """
+        Create an log10(abs(fft)) stream chain.
+        Provide access to the setting the filter and sample rate.
+        
+        Args:
+            sample_rate: Incoming stream sample rate
+            fft_size: Number of FFT bins
+            ref_scale: Sets 0 dB value input amplitude
+            frame_rate: Output frame rate
+            avg_alpha: FFT averaging (over time) constant [0.0-1.0]
+            average: Whether to average [True, False]
+            win: the window taps generation function
+        """
+        gr.hier_block2.__init__(self, self._name,
+                                gr.io_signature(1, 1, self._item_size),          # Input signature
+                                gr.io_signature(1, 1, gr.sizeof_float*fft_size)) # Output signature
+
+        self._sd = blocks.stream_to_vector_decimator(item_size=self._item_size,
+                                                     sample_rate=sample_rate,
+                                                     vec_rate=frame_rate,
+                                                     vec_len=fft_size)
+
+        if win is None: win = window.blackmanharris
+        fft_window = win(fft_size)
+        fft = self._fft_block[0](fft_size, True, fft_window)
+        window_power = sum(map(lambda x: x*x, fft_window))
+
+        c2magsq = blocks.complex_to_mag_squared(fft_size)
+        self._avg = filter.single_pole_iir_filter_ff(1.0, fft_size)
+        self._log = blocks.nlog10_ff(10, fft_size,
+                                     -20*math.log10(fft_size)              # Adjust for number of bins
+                                     -10*math.log10(window_power/fft_size) # Adjust for windowing loss
+                                     -20*math.log10(ref_scale/2))      # Adjust for reference scale
+        self.connect(self, self._sd, fft, c2magsq, self._avg, self._log, self)
+
+        self._average = average
+        self._avg_alpha = avg_alpha
+        self.set_avg_alpha(avg_alpha)
+        self.set_average(average)
+
+    def set_decimation(self, decim):
+        """
+        Set the decimation on stream decimator.
+        
+        Args:
+            decim: the new decimation
+        """
+        self._sd.set_decimation(decim)
+
+    def set_vec_rate(self, vec_rate):
+        """
+        Set the vector rate on stream decimator.
+        
+        Args:
+            vec_rate: the new vector rate
+        """
+        self._sd.set_vec_rate(vec_rate)
+
+    def set_sample_rate(self, sample_rate):
+        """
+        Set the new sampling rate
+        
+        Args:
+            sample_rate: the new rate
+        """
+        self._sd.set_sample_rate(sample_rate)
+
+    def set_average(self, average):
+        """
+        Set the averaging filter on/off.
+        
+        Args:
+            average: true to set averaging on
+        """
+        self._average = average
+        if self._average:
+            self._avg.set_taps(self._avg_alpha)
+        else:
+            self._avg.set_taps(1.0)
+
+    def set_avg_alpha(self, avg_alpha):
+        """
+        Set the average alpha and set the taps if average was on.
+        
+        Args:
+            avg_alpha: the new iir filter tap
+        """
+        self._avg_alpha = avg_alpha
+        self.set_average(self._average)
+
+    def sample_rate(self):
+        """
+        Return the current sample rate.
+        """
+        return self._sd.sample_rate()
+
+    def decimation(self):
+        """
+        Return the current decimation.
+        """
+        return self._sd.decimation()
+
+    def frame_rate(self):
+        """
+        Return the current frame rate.
+        """
+        return self._sd.frame_rate()
+
+    def average(self):
+        """
+        Return whether or not averaging is being performed.
+        """
+        return self._average
+
+    def avg_alpha(self):
+        """
+        Return averaging filter constant.
+        """
+        return self._avg_alpha
+
+class logpwrfft_f(_logpwrfft_base):
+        """
+        Create an fft block chain, with real input.
+        """
+        _name = "logpwrfft_f"
+        _item_size = gr.sizeof_float
+        _fft_block = (fft.fft_vfc, )
+
+class logpwrfft_c(_logpwrfft_base):
+        """
+        Create an fft block chain, with complex input.
+        """
+        _name = "logpwrfft_c"
+        _item_size = gr.sizeof_gr_complex
+        _fft_block = (fft.fft_vcc, )
+
diff --git a/gr-fft/python/fft/qa_fft.py b/gr-fft/python/fft/qa_fft.py
new file mode 100755
index 0000000000..0a66a2c1fc
--- /dev/null
+++ b/gr-fft/python/fft/qa_fft.py
@@ -0,0 +1,214 @@
+#!/usr/bin/env python
+#
+# Copyright 2008,2010,2012 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 this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+from gnuradio import gr, gr_unittest
+import fft_swig as fft
+import blocks_swig as blocks
+import sys
+import random
+
+primes = (2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,
+          59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,
+          137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,
+          227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311)
+
+
+class test_fft(gr_unittest.TestCase):
+
+    def setUp(self):
+	pass
+
+    def tearDown(self):
+	pass
+
+    def assert_fft_ok2(self, expected_result, result_data):
+        expected_result = expected_result[:len(result_data)]
+        self.assertComplexTuplesAlmostEqual2 (expected_result, result_data,
+                                              abs_eps=1e-9, rel_eps=4e-4)
+
+    def assert_fft_float_ok2(self, expected_result, result_data, abs_eps=1e-9, rel_eps=4e-4):
+        expected_result = expected_result[:len(result_data)]
+        self.assertFloatTuplesAlmostEqual2 (expected_result, result_data,
+                                            abs_eps, rel_eps)
+
+    def test_001(self):
+	tb = gr.top_block()
+        fft_size = 32
+        src_data = tuple([complex(primes[2*i], primes[2*i+1]) for i in range(fft_size)])
+
+        expected_result = ((4377+4516j),
+                           (-1706.1268310546875+1638.4256591796875j),
+                           (-915.2083740234375+660.69427490234375j),
+                           (-660.370361328125+381.59600830078125j),
+                           (-499.96044921875+238.41630554199219j),
+                           (-462.26748657226562+152.88948059082031j),
+                           (-377.98440551757812+77.5928955078125j),
+                           (-346.85821533203125+47.152004241943359j),
+                           (-295+20j),
+                           (-286.33609008789062-22.257017135620117j),
+                           (-271.52999877929688-33.081821441650391j),
+                           (-224.6358642578125-67.019538879394531j),
+                           (-244.24473571777344-91.524826049804688j),
+                           (-203.09068298339844-108.54627227783203j),
+                           (-198.45195007324219-115.90768432617188j),
+                           (-182.97744750976562-128.12318420410156j),
+                           (-167-180j),
+                           (-130.33688354492188-173.83778381347656j),
+                           (-141.19784545898438-190.28807067871094j),
+                           (-111.09677124023438-214.48896789550781j),
+                           (-70.039543151855469-242.41630554199219j),
+                           (-68.960540771484375-228.30015563964844j),
+                           (-53.049201965332031-291.47097778320312j),
+                           (-28.695289611816406-317.64553833007812j),
+                           (57-300j),
+                           (45.301143646240234-335.69509887695312j),
+                           (91.936195373535156-373.32437133789062j),
+                           (172.09465026855469-439.275146484375j),
+                           (242.24473571777344-504.47515869140625j),
+                           (387.81732177734375-666.6788330078125j),
+                           (689.48553466796875-918.2142333984375j),
+                           (1646.539306640625-1694.1956787109375j))
+
+        src = gr.vector_source_c(src_data)
+        s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, fft_size)
+        op  = fft.fft_vcc(fft_size, True, [], False)
+        v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, fft_size)
+        dst = gr.vector_sink_c()
+        tb.connect(src, s2v, op, v2s, dst)
+        tb.run()
+        result_data = dst.data()
+        #print 'expected:', expected_result
+        #print 'results: ', result_data
+        #self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
+        self.assert_fft_ok2(expected_result, result_data)
+
+    def test_002(self):
+	tb = gr.top_block()
+        fft_size = 32
+
+        tmp_data = ((4377+4516j),
+                    (-1706.1268310546875+1638.4256591796875j),
+                    (-915.2083740234375+660.69427490234375j),
+                    (-660.370361328125+381.59600830078125j),
+                    (-499.96044921875+238.41630554199219j),
+                    (-462.26748657226562+152.88948059082031j),
+                    (-377.98440551757812+77.5928955078125j),
+                    (-346.85821533203125+47.152004241943359j),
+                    (-295+20j),
+                    (-286.33609008789062-22.257017135620117j),
+                    (-271.52999877929688-33.081821441650391j),
+                    (-224.6358642578125-67.019538879394531j),
+                    (-244.24473571777344-91.524826049804688j),
+                    (-203.09068298339844-108.54627227783203j),
+                    (-198.45195007324219-115.90768432617188j),
+                    (-182.97744750976562-128.12318420410156j),
+                    (-167-180j),
+                    (-130.33688354492188-173.83778381347656j),
+                    (-141.19784545898438-190.28807067871094j),
+                    (-111.09677124023438-214.48896789550781j),
+                    (-70.039543151855469-242.41630554199219j),
+                    (-68.960540771484375-228.30015563964844j),
+                    (-53.049201965332031-291.47097778320312j),
+                    (-28.695289611816406-317.64553833007812j),
+                    (57-300j),
+                    (45.301143646240234-335.69509887695312j),
+                    (91.936195373535156-373.32437133789062j),
+                    (172.09465026855469-439.275146484375j),
+                    (242.24473571777344-504.47515869140625j),
+                    (387.81732177734375-666.6788330078125j),
+                    (689.48553466796875-918.2142333984375j),
+                    (1646.539306640625-1694.1956787109375j))
+
+        src_data = tuple([x/fft_size for x in tmp_data])
+
+        expected_result = tuple([complex(primes[2*i], primes[2*i+1]) for i in range(fft_size)])
+
+        src = gr.vector_source_c(src_data)
+        s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, fft_size)
+        op  = fft.fft_vcc(fft_size, False, [], False)
+        v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, fft_size)
+        dst = gr.vector_sink_c()
+        tb.connect(src, s2v, op, v2s, dst)
+        tb.run()
+        result_data = dst.data()
+        #print 'expected:', expected_result
+        #print 'results: ', result_data
+        #self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
+        self.assert_fft_ok2(expected_result, result_data)
+
+    def test_003(self):
+        # Same test as above, only use 2 threads
+
+	tb = gr.top_block()
+        fft_size = 32
+
+        tmp_data = ((4377+4516j),
+                    (-1706.1268310546875+1638.4256591796875j),
+                    (-915.2083740234375+660.69427490234375j),
+                    (-660.370361328125+381.59600830078125j),
+                    (-499.96044921875+238.41630554199219j),
+                    (-462.26748657226562+152.88948059082031j),
+                    (-377.98440551757812+77.5928955078125j),
+                    (-346.85821533203125+47.152004241943359j),
+                    (-295+20j),
+                    (-286.33609008789062-22.257017135620117j),
+                    (-271.52999877929688-33.081821441650391j),
+                    (-224.6358642578125-67.019538879394531j),
+                    (-244.24473571777344-91.524826049804688j),
+                    (-203.09068298339844-108.54627227783203j),
+                    (-198.45195007324219-115.90768432617188j),
+                    (-182.97744750976562-128.12318420410156j),
+                    (-167-180j),
+                    (-130.33688354492188-173.83778381347656j),
+                    (-141.19784545898438-190.28807067871094j),
+                    (-111.09677124023438-214.48896789550781j),
+                    (-70.039543151855469-242.41630554199219j),
+                    (-68.960540771484375-228.30015563964844j),
+                    (-53.049201965332031-291.47097778320312j),
+                    (-28.695289611816406-317.64553833007812j),
+                    (57-300j),
+                    (45.301143646240234-335.69509887695312j),
+                    (91.936195373535156-373.32437133789062j),
+                    (172.09465026855469-439.275146484375j),
+                    (242.24473571777344-504.47515869140625j),
+                    (387.81732177734375-666.6788330078125j),
+                    (689.48553466796875-918.2142333984375j),
+                    (1646.539306640625-1694.1956787109375j))
+
+        src_data = tuple([x/fft_size for x in tmp_data])
+
+        expected_result = tuple([complex(primes[2*i], primes[2*i+1]) for i in range(fft_size)])
+
+        nthreads = 2
+
+        src = gr.vector_source_c(src_data)
+        s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, fft_size)
+        op  = fft.fft_vcc(fft_size, False, [], False, nthreads)
+        v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, fft_size)
+        dst = gr.vector_sink_c()
+        tb.connect(src, s2v, op, v2s, dst)
+        tb.run()
+        result_data = dst.data()
+        self.assert_fft_ok2(expected_result, result_data)
+
+if __name__ == '__main__':
+    gr_unittest.run(test_fft, "test_fft.xml")
+
diff --git a/gr-fft/python/fft/qa_goertzel.py b/gr-fft/python/fft/qa_goertzel.py
new file mode 100755
index 0000000000..27f9d370e1
--- /dev/null
+++ b/gr-fft/python/fft/qa_goertzel.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+#
+# Copyright 2006,2007,2010,2012 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.
+#
+
+from gnuradio import gr, gr_unittest
+from math import pi, cos
+import fft_swig as fft
+
+class test_goertzel(gr_unittest.TestCase):
+
+    def setUp(self):
+        self.tb = gr.top_block()
+
+    def tearDown(self):
+        self.tb = None
+
+    def make_tone_data(self, rate, freq):
+        return [cos(2*pi*x*freq/rate) for x in range(rate)]
+
+    def transform(self, src_data, rate, freq):
+	src = gr.vector_source_f(src_data, False)
+        dft = fft.goertzel_fc(rate, rate, freq)
+	dst = gr.vector_sink_c()
+	self.tb.connect(src, dft, dst)
+	self.tb.run()
+	return dst.data()
+
+    def test_001(self): # Measure single tone magnitude
+	rate = 8000
+	freq = 100
+	bin = freq
+	src_data = self.make_tone_data(rate, freq)
+	expected_result = 0.5
+	actual_result = abs(self.transform(src_data, rate, bin)[0])
+	self.assertAlmostEqual(expected_result, actual_result, places=4)
+
+    def test_002(self): # Measure off frequency magnitude
+	rate = 8000
+	freq = 100
+	bin = freq/2
+	src_data = self.make_tone_data(rate, freq)
+	expected_result = 0.0
+	actual_result = abs(self.transform(src_data, rate, bin)[0])
+	self.assertAlmostEqual(expected_result, actual_result, places=4)
+
+if __name__ == '__main__':
+    gr_unittest.run(test_goertzel, "test_goertzel.xml")
diff --git a/gr-fft/python/fft/window.py b/gr-fft/python/fft/window.py
new file mode 100644
index 0000000000..0065a08a61
--- /dev/null
+++ b/gr-fft/python/fft/window.py
@@ -0,0 +1,179 @@
+#
+# 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/python/logpwrfft.py b/gr-fft/python/logpwrfft.py
deleted file mode 100644
index 98303b1e1e..0000000000
--- a/gr-fft/python/logpwrfft.py
+++ /dev/null
@@ -1,176 +0,0 @@
-#
-# Copyright 2008 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.
-#
-
-from gnuradio import gr
-from gnuradio import blocks
-import sys, math
-
-import fft_swig as fft
-import window
-
-try:
-    from gnuradio import filter
-except ImportError:
-    sys.stderr.write('fft.logpwrfft required gr-filter.\n')
-    sys.exit(1)
-
-class _logpwrfft_base(gr.hier_block2):
-    """
-    Create a log10(abs(fft)) stream chain, with real or complex input.
-    """
-
-    def __init__(self, sample_rate, fft_size, ref_scale, frame_rate, avg_alpha, average, win=None):
-        """
-        Create an log10(abs(fft)) stream chain.
-        Provide access to the setting the filter and sample rate.
-        
-        Args:
-            sample_rate: Incoming stream sample rate
-            fft_size: Number of FFT bins
-            ref_scale: Sets 0 dB value input amplitude
-            frame_rate: Output frame rate
-            avg_alpha: FFT averaging (over time) constant [0.0-1.0]
-            average: Whether to average [True, False]
-            win: the window taps generation function
-        """
-        gr.hier_block2.__init__(self, self._name,
-                                gr.io_signature(1, 1, self._item_size),          # Input signature
-                                gr.io_signature(1, 1, gr.sizeof_float*fft_size)) # Output signature
-
-        self._sd = blocks.stream_to_vector_decimator(item_size=self._item_size,
-                                                     sample_rate=sample_rate,
-                                                     vec_rate=frame_rate,
-                                                     vec_len=fft_size)
-
-        if win is None: win = window.blackmanharris
-        fft_window = win(fft_size)
-        fft = self._fft_block[0](fft_size, True, fft_window)
-        window_power = sum(map(lambda x: x*x, fft_window))
-
-        c2magsq = blocks.complex_to_mag_squared(fft_size)
-        self._avg = filter.single_pole_iir_filter_ff(1.0, fft_size)
-        self._log = blocks.nlog10_ff(10, fft_size,
-                                     -20*math.log10(fft_size)              # Adjust for number of bins
-                                     -10*math.log10(window_power/fft_size) # Adjust for windowing loss
-                                     -20*math.log10(ref_scale/2))      # Adjust for reference scale
-        self.connect(self, self._sd, fft, c2magsq, self._avg, self._log, self)
-
-        self._average = average
-        self._avg_alpha = avg_alpha
-        self.set_avg_alpha(avg_alpha)
-        self.set_average(average)
-
-    def set_decimation(self, decim):
-        """
-        Set the decimation on stream decimator.
-        
-        Args:
-            decim: the new decimation
-        """
-        self._sd.set_decimation(decim)
-
-    def set_vec_rate(self, vec_rate):
-        """
-        Set the vector rate on stream decimator.
-        
-        Args:
-            vec_rate: the new vector rate
-        """
-        self._sd.set_vec_rate(vec_rate)
-
-    def set_sample_rate(self, sample_rate):
-        """
-        Set the new sampling rate
-        
-        Args:
-            sample_rate: the new rate
-        """
-        self._sd.set_sample_rate(sample_rate)
-
-    def set_average(self, average):
-        """
-        Set the averaging filter on/off.
-        
-        Args:
-            average: true to set averaging on
-        """
-        self._average = average
-        if self._average:
-            self._avg.set_taps(self._avg_alpha)
-        else:
-            self._avg.set_taps(1.0)
-
-    def set_avg_alpha(self, avg_alpha):
-        """
-        Set the average alpha and set the taps if average was on.
-        
-        Args:
-            avg_alpha: the new iir filter tap
-        """
-        self._avg_alpha = avg_alpha
-        self.set_average(self._average)
-
-    def sample_rate(self):
-        """
-        Return the current sample rate.
-        """
-        return self._sd.sample_rate()
-
-    def decimation(self):
-        """
-        Return the current decimation.
-        """
-        return self._sd.decimation()
-
-    def frame_rate(self):
-        """
-        Return the current frame rate.
-        """
-        return self._sd.frame_rate()
-
-    def average(self):
-        """
-        Return whether or not averaging is being performed.
-        """
-        return self._average
-
-    def avg_alpha(self):
-        """
-        Return averaging filter constant.
-        """
-        return self._avg_alpha
-
-class logpwrfft_f(_logpwrfft_base):
-        """
-        Create an fft block chain, with real input.
-        """
-        _name = "logpwrfft_f"
-        _item_size = gr.sizeof_float
-        _fft_block = (fft.fft_vfc, )
-
-class logpwrfft_c(_logpwrfft_base):
-        """
-        Create an fft block chain, with complex input.
-        """
-        _name = "logpwrfft_c"
-        _item_size = gr.sizeof_gr_complex
-        _fft_block = (fft.fft_vcc, )
-
diff --git a/gr-fft/python/qa_fft.py b/gr-fft/python/qa_fft.py
deleted file mode 100755
index 0a66a2c1fc..0000000000
--- a/gr-fft/python/qa_fft.py
+++ /dev/null
@@ -1,214 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2008,2010,2012 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 this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-
-from gnuradio import gr, gr_unittest
-import fft_swig as fft
-import blocks_swig as blocks
-import sys
-import random
-
-primes = (2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,
-          59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,
-          137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,
-          227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311)
-
-
-class test_fft(gr_unittest.TestCase):
-
-    def setUp(self):
-	pass
-
-    def tearDown(self):
-	pass
-
-    def assert_fft_ok2(self, expected_result, result_data):
-        expected_result = expected_result[:len(result_data)]
-        self.assertComplexTuplesAlmostEqual2 (expected_result, result_data,
-                                              abs_eps=1e-9, rel_eps=4e-4)
-
-    def assert_fft_float_ok2(self, expected_result, result_data, abs_eps=1e-9, rel_eps=4e-4):
-        expected_result = expected_result[:len(result_data)]
-        self.assertFloatTuplesAlmostEqual2 (expected_result, result_data,
-                                            abs_eps, rel_eps)
-
-    def test_001(self):
-	tb = gr.top_block()
-        fft_size = 32
-        src_data = tuple([complex(primes[2*i], primes[2*i+1]) for i in range(fft_size)])
-
-        expected_result = ((4377+4516j),
-                           (-1706.1268310546875+1638.4256591796875j),
-                           (-915.2083740234375+660.69427490234375j),
-                           (-660.370361328125+381.59600830078125j),
-                           (-499.96044921875+238.41630554199219j),
-                           (-462.26748657226562+152.88948059082031j),
-                           (-377.98440551757812+77.5928955078125j),
-                           (-346.85821533203125+47.152004241943359j),
-                           (-295+20j),
-                           (-286.33609008789062-22.257017135620117j),
-                           (-271.52999877929688-33.081821441650391j),
-                           (-224.6358642578125-67.019538879394531j),
-                           (-244.24473571777344-91.524826049804688j),
-                           (-203.09068298339844-108.54627227783203j),
-                           (-198.45195007324219-115.90768432617188j),
-                           (-182.97744750976562-128.12318420410156j),
-                           (-167-180j),
-                           (-130.33688354492188-173.83778381347656j),
-                           (-141.19784545898438-190.28807067871094j),
-                           (-111.09677124023438-214.48896789550781j),
-                           (-70.039543151855469-242.41630554199219j),
-                           (-68.960540771484375-228.30015563964844j),
-                           (-53.049201965332031-291.47097778320312j),
-                           (-28.695289611816406-317.64553833007812j),
-                           (57-300j),
-                           (45.301143646240234-335.69509887695312j),
-                           (91.936195373535156-373.32437133789062j),
-                           (172.09465026855469-439.275146484375j),
-                           (242.24473571777344-504.47515869140625j),
-                           (387.81732177734375-666.6788330078125j),
-                           (689.48553466796875-918.2142333984375j),
-                           (1646.539306640625-1694.1956787109375j))
-
-        src = gr.vector_source_c(src_data)
-        s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, fft_size)
-        op  = fft.fft_vcc(fft_size, True, [], False)
-        v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, fft_size)
-        dst = gr.vector_sink_c()
-        tb.connect(src, s2v, op, v2s, dst)
-        tb.run()
-        result_data = dst.data()
-        #print 'expected:', expected_result
-        #print 'results: ', result_data
-        #self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
-        self.assert_fft_ok2(expected_result, result_data)
-
-    def test_002(self):
-	tb = gr.top_block()
-        fft_size = 32
-
-        tmp_data = ((4377+4516j),
-                    (-1706.1268310546875+1638.4256591796875j),
-                    (-915.2083740234375+660.69427490234375j),
-                    (-660.370361328125+381.59600830078125j),
-                    (-499.96044921875+238.41630554199219j),
-                    (-462.26748657226562+152.88948059082031j),
-                    (-377.98440551757812+77.5928955078125j),
-                    (-346.85821533203125+47.152004241943359j),
-                    (-295+20j),
-                    (-286.33609008789062-22.257017135620117j),
-                    (-271.52999877929688-33.081821441650391j),
-                    (-224.6358642578125-67.019538879394531j),
-                    (-244.24473571777344-91.524826049804688j),
-                    (-203.09068298339844-108.54627227783203j),
-                    (-198.45195007324219-115.90768432617188j),
-                    (-182.97744750976562-128.12318420410156j),
-                    (-167-180j),
-                    (-130.33688354492188-173.83778381347656j),
-                    (-141.19784545898438-190.28807067871094j),
-                    (-111.09677124023438-214.48896789550781j),
-                    (-70.039543151855469-242.41630554199219j),
-                    (-68.960540771484375-228.30015563964844j),
-                    (-53.049201965332031-291.47097778320312j),
-                    (-28.695289611816406-317.64553833007812j),
-                    (57-300j),
-                    (45.301143646240234-335.69509887695312j),
-                    (91.936195373535156-373.32437133789062j),
-                    (172.09465026855469-439.275146484375j),
-                    (242.24473571777344-504.47515869140625j),
-                    (387.81732177734375-666.6788330078125j),
-                    (689.48553466796875-918.2142333984375j),
-                    (1646.539306640625-1694.1956787109375j))
-
-        src_data = tuple([x/fft_size for x in tmp_data])
-
-        expected_result = tuple([complex(primes[2*i], primes[2*i+1]) for i in range(fft_size)])
-
-        src = gr.vector_source_c(src_data)
-        s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, fft_size)
-        op  = fft.fft_vcc(fft_size, False, [], False)
-        v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, fft_size)
-        dst = gr.vector_sink_c()
-        tb.connect(src, s2v, op, v2s, dst)
-        tb.run()
-        result_data = dst.data()
-        #print 'expected:', expected_result
-        #print 'results: ', result_data
-        #self.assertComplexTuplesAlmostEqual (expected_result, result_data, 5)
-        self.assert_fft_ok2(expected_result, result_data)
-
-    def test_003(self):
-        # Same test as above, only use 2 threads
-
-	tb = gr.top_block()
-        fft_size = 32
-
-        tmp_data = ((4377+4516j),
-                    (-1706.1268310546875+1638.4256591796875j),
-                    (-915.2083740234375+660.69427490234375j),
-                    (-660.370361328125+381.59600830078125j),
-                    (-499.96044921875+238.41630554199219j),
-                    (-462.26748657226562+152.88948059082031j),
-                    (-377.98440551757812+77.5928955078125j),
-                    (-346.85821533203125+47.152004241943359j),
-                    (-295+20j),
-                    (-286.33609008789062-22.257017135620117j),
-                    (-271.52999877929688-33.081821441650391j),
-                    (-224.6358642578125-67.019538879394531j),
-                    (-244.24473571777344-91.524826049804688j),
-                    (-203.09068298339844-108.54627227783203j),
-                    (-198.45195007324219-115.90768432617188j),
-                    (-182.97744750976562-128.12318420410156j),
-                    (-167-180j),
-                    (-130.33688354492188-173.83778381347656j),
-                    (-141.19784545898438-190.28807067871094j),
-                    (-111.09677124023438-214.48896789550781j),
-                    (-70.039543151855469-242.41630554199219j),
-                    (-68.960540771484375-228.30015563964844j),
-                    (-53.049201965332031-291.47097778320312j),
-                    (-28.695289611816406-317.64553833007812j),
-                    (57-300j),
-                    (45.301143646240234-335.69509887695312j),
-                    (91.936195373535156-373.32437133789062j),
-                    (172.09465026855469-439.275146484375j),
-                    (242.24473571777344-504.47515869140625j),
-                    (387.81732177734375-666.6788330078125j),
-                    (689.48553466796875-918.2142333984375j),
-                    (1646.539306640625-1694.1956787109375j))
-
-        src_data = tuple([x/fft_size for x in tmp_data])
-
-        expected_result = tuple([complex(primes[2*i], primes[2*i+1]) for i in range(fft_size)])
-
-        nthreads = 2
-
-        src = gr.vector_source_c(src_data)
-        s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, fft_size)
-        op  = fft.fft_vcc(fft_size, False, [], False, nthreads)
-        v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, fft_size)
-        dst = gr.vector_sink_c()
-        tb.connect(src, s2v, op, v2s, dst)
-        tb.run()
-        result_data = dst.data()
-        self.assert_fft_ok2(expected_result, result_data)
-
-if __name__ == '__main__':
-    gr_unittest.run(test_fft, "test_fft.xml")
-
diff --git a/gr-fft/python/qa_goertzel.py b/gr-fft/python/qa_goertzel.py
deleted file mode 100755
index 27f9d370e1..0000000000
--- a/gr-fft/python/qa_goertzel.py
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2006,2007,2010,2012 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.
-#
-
-from gnuradio import gr, gr_unittest
-from math import pi, cos
-import fft_swig as fft
-
-class test_goertzel(gr_unittest.TestCase):
-
-    def setUp(self):
-        self.tb = gr.top_block()
-
-    def tearDown(self):
-        self.tb = None
-
-    def make_tone_data(self, rate, freq):
-        return [cos(2*pi*x*freq/rate) for x in range(rate)]
-
-    def transform(self, src_data, rate, freq):
-	src = gr.vector_source_f(src_data, False)
-        dft = fft.goertzel_fc(rate, rate, freq)
-	dst = gr.vector_sink_c()
-	self.tb.connect(src, dft, dst)
-	self.tb.run()
-	return dst.data()
-
-    def test_001(self): # Measure single tone magnitude
-	rate = 8000
-	freq = 100
-	bin = freq
-	src_data = self.make_tone_data(rate, freq)
-	expected_result = 0.5
-	actual_result = abs(self.transform(src_data, rate, bin)[0])
-	self.assertAlmostEqual(expected_result, actual_result, places=4)
-
-    def test_002(self): # Measure off frequency magnitude
-	rate = 8000
-	freq = 100
-	bin = freq/2
-	src_data = self.make_tone_data(rate, freq)
-	expected_result = 0.0
-	actual_result = abs(self.transform(src_data, rate, bin)[0])
-	self.assertAlmostEqual(expected_result, actual_result, places=4)
-
-if __name__ == '__main__':
-    gr_unittest.run(test_goertzel, "test_goertzel.xml")
diff --git a/gr-fft/python/window.py b/gr-fft/python/window.py
deleted file mode 100644
index 0065a08a61..0000000000
--- a/gr-fft/python/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
-- 
cgit v1.2.3