Merge branch 'flattopwindow' of http://gnuradio.org/git/jblum
authorJohnathan Corgan <jcorgan@corganenterprises.com>
Thu, 29 Oct 2009 13:52:53 +0000 (06:52 -0700)
committerJohnathan Corgan <jcorgan@corganenterprises.com>
Thu, 29 Oct 2009 13:52:53 +0000 (06:52 -0700)
Merge-fix: Remove debugging print
Merge-fix: Update copyrights

* 'flattopwindow' of http://gnuradio.org/git/jblum:
  Added window option to wxgui fft and waterfall sink.
  redid cos windows, added flattop and nuttall_cfd

gnuradio-core/src/python/gnuradio/blks2impl/logpwrfft.py
gnuradio-core/src/python/gnuradio/window.py
gr-wxgui/src/python/fftsink_gl.py
gr-wxgui/src/python/fftsink_nongl.py
gr-wxgui/src/python/waterfallsink_gl.py
grc/blocks/wxgui_fftsink2.xml
grc/blocks/wxgui_numbersink2.xml
grc/blocks/wxgui_waterfallsink2.xml

index 7ef40be40a92bb4f55a872e05802e95fd2b3f0c2..200c4cfbe86a6b8c8c38c2bd366329df650b7c8a 100644 (file)
@@ -28,7 +28,7 @@ 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):
+    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.
@@ -38,6 +38,7 @@ class _logpwrfft_base(gr.hier_block2):
         @param frame_rate        Output frame rate
         @param avg_alpha        FFT averaging (over time) constant [0.0-1.0]
         @param average                Whether to average [True, False]
+        @param win              the window taps generation function
         """
         gr.hier_block2.__init__(self, self._name,
                                 gr.io_signature(1, 1, self._item_size),          # Input signature
@@ -48,7 +49,8 @@ class _logpwrfft_base(gr.hier_block2):
                                               vec_rate=frame_rate,
                                               vec_len=fft_size)
 
-        fft_window = window.blackmanharris(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))
 
index fb4a10675be587c1371d1d4156d7ce3fc3e6554e..e109a98920300a14df862e5fede79fd21cd27b93 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2004,2005 Free Software Foundation, Inc.
+# Copyright 2004,2005,2009 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -153,32 +153,6 @@ def riemann(fft_size):
         j -= 1
     return window
 
-def blackmanharris(fft_size):
-    a0 = 0.35875
-    a1 = 0.48829
-    a2 = 0.14128
-    a3 = 0.01168
-    window = [0 for i in range(fft_size)]
-    for index in xrange(fft_size):
-        window[index] = a0 
-        window[index] -= a1*math.cos(2.0*math.pi*(index+0.5)/(fft_size - 1))
-        window[index] += a2*math.cos(4.0*math.pi*(index+0.5)/(fft_size - 1))
-        window[index] -= a3*math.cos(6.0*math.pi*(index+0.5)/(fft_size - 1))
-    return window
-
-def nuttall(fft_size):
-    a0 = 0.3635819
-    a1 = 0.4891775
-    a2 = 0.1365995
-    a3 = 0.0106411
-    window = [0 for i in range(fft_size)]
-    for index in xrange(fft_size):
-        window[index] = a0 
-        window[index] -= a1*math.cos(2.0*math.pi*(index+0.5)/(fft_size - 1))
-        window[index] += a2*math.cos(4.0*math.pi*(index+0.5)/(fft_size - 1))
-        window[index] -= a3*math.cos(6.0*math.pi*(index+0.5)/(fft_size - 1))
-    return window
-
 def kaiser(fft_size,beta):
     ibeta = 1.0/izero(beta)
     inm1 = 1.0/(fft_size)
@@ -187,4 +161,20 @@ def kaiser(fft_size,beta):
         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
index 9d683d69795c3cf7f7fe320a5fb5dd262a215347..8ddea9a8e3fd0109a737a8f5f49a28478e604b5d 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2008 Free Software Foundation, Inc.
+# Copyright 2008,2009 Free Software Foundation, Inc.
 #
 # This file is part of GNU Radio
 #
@@ -52,6 +52,8 @@ class _fft_sink_base(gr.hier_block2, common.wxgui_hb):
                title='',
                size=fft_window.DEFAULT_WIN_SIZE,
                peak_hold=False,
+               win=None,
+               **kwargs #do not end with a comma
        ):
                #ensure avg alpha
                if avg_alpha is None: avg_alpha = 2.0/fft_rate
@@ -70,6 +72,7 @@ class _fft_sink_base(gr.hier_block2, common.wxgui_hb):
                        ref_scale=ref_scale,
                        avg_alpha=avg_alpha,
                        average=average,
+                       win=win,
                )
                msgq = gr.msg_queue(2)
                sink = gr.message_sink(gr.sizeof_float*fft_size, msgq, True)
index ca5e91fdbea3d708a7927281505c8a133ad105bf..937eb27cce936ad14c5243ecc66568bb750833cb 100644 (file)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Copyright 2003,2004,2005,2006,2007 Free Software Foundation, Inc.
+# Copyright 2003,2004,2005,2006,2007,2009 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -93,7 +93,7 @@ class fft_sink_f(gr.hier_block2, fft_sink_base):
     def __init__(self, parent, baseband_freq=0, ref_scale=2.0,
                  y_per_div=10, y_divs=8, ref_level=50, sample_rate=1, fft_size=512,
                  fft_rate=default_fft_rate, average=False, avg_alpha=None,
-                 title='', size=default_fftsink_size, peak_hold=False):
+                 title='', size=default_fftsink_size, peak_hold=False, **kwargs):
 
         gr.hier_block2.__init__(self, "fft_sink_f",
                                 gr.io_signature(1, 1, gr.sizeof_float),
@@ -136,7 +136,7 @@ class fft_sink_c(gr.hier_block2, fft_sink_base):
     def __init__(self, parent, baseband_freq=0, ref_scale=2.0,
                  y_per_div=10, y_divs=8, ref_level=50, sample_rate=1, fft_size=512,
                  fft_rate=default_fft_rate, average=False, avg_alpha=None,
-                 title='', size=default_fftsink_size, peak_hold=False):
+                 title='', size=default_fftsink_size, peak_hold=False, **kwargs):
 
         gr.hier_block2.__init__(self, "fft_sink_c",
                                 gr.io_signature(1, 1, gr.sizeof_gr_complex),
index 37844399ed6337e1a9fdf992c3dc0b63b2b98b1c..c2c4e8df7a1481ce165c5746ae7f65610aebd3ef 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright 2008 Free Software Foundation, Inc.
+# Copyright 2008,2009 Free Software Foundation, Inc.
 #
 # This file is part of GNU Radio
 #
@@ -51,6 +51,7 @@ class _waterfall_sink_base(gr.hier_block2, common.wxgui_hb):
                ref_scale=2.0,
                dynamic_range=80,
                num_lines=256,
+               win=None,
                **kwargs #do not end with a comma
        ):
                #ensure avg alpha
@@ -70,6 +71,7 @@ class _waterfall_sink_base(gr.hier_block2, common.wxgui_hb):
                        ref_scale=ref_scale,
                        avg_alpha=avg_alpha,
                        average=average,
+                       win=win,
                )
                msgq = gr.msg_queue(2)
                sink = gr.message_sink(gr.sizeof_float*fft_size, msgq, True)
index 42bca5ccf3174d82f0152e2d7ded2d802416a4db..8df8f90d0192de8a5e21d8cdadcb6070c85ddd53 100644 (file)
@@ -7,6 +7,7 @@
 <block>
        <name>FFT Sink</name>
        <key>wxgui_fftsink2</key>
+       <import>from gnuradio import window</import>
        <import>from gnuradio.wxgui import fftsink2</import>
        <make>#set $parent = $notebook() and 'self.%s.GetPage(%s)'%$notebook() or 'self'
 fftsink2.$(type.fcn)(
@@ -23,6 +24,9 @@ fftsink2.$(type.fcn)(
        avg_alpha=#if $avg_alpha() then $avg_alpha else 'None'#,
        title=$title,
        peak_hold=$peak_hold,
+#if $win()
+       win=$win,
+#end if
 #if $win_size()
        size=$win_size,
 #end if
@@ -144,7 +148,7 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <key>average</key>
                <value>False</value>
                <type>enum</type>
-               <hide>#if $average() == 'True' then 'none' else 'part'#</hide>
+               <hide>part</hide>
                <option>
                        <name>On</name>
                        <key>True</key>
@@ -161,6 +165,37 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <type>real</type>
                <hide>#if $average() == 'True' then 'none' else 'all'#</hide>
        </param>
+       <param>
+               <name>Window</name>
+               <key>win</key>
+               <value>None</value>
+               <type>raw</type>
+               <hide>#if $win() is None then 'part' else 'none'#</hide>
+               <option>
+                       <name>Automatic</name>
+                       <key>None</key>
+               </option>
+               <option>
+                       <name>Blackman-Harris</name>
+                       <key>window.blackmanharris</key>
+               </option>
+               <option>
+                       <name>Hamming</name>
+                       <key>window.hamming</key>
+               </option>
+               <option>
+                       <name>Hanning</name>
+                       <key>window.hanning</key>
+               </option>
+               <option>
+                       <name>Rectangular</name>
+                       <key>window.rectangular</key>
+               </option>
+               <option>
+                       <name>Flattop</name>
+                       <key>window.flattop</key>
+               </option>
+       </param>
        <param>
                <name>Window Size</name>
                <key>win_size</key>
index 5289db8af9f1351338a886e30aa077054fdde9f2..ad93dec08db14d59504bfe998fb59eb29d2a0ecd 100644 (file)
@@ -123,7 +123,7 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <key>average</key>
                <value>False</value>
                <type>enum</type>
-               <hide>#if $average() == 'True' then 'none' else 'part'#</hide>
+               <hide>part</hide>
                <option>
                        <name>On</name>
                        <key>True</key>
index cee598990e230da499006ff0658eadbec114f4a2..3de67597f7bb24097e9b5adebf762bb38d06f7a1 100644 (file)
@@ -7,6 +7,7 @@
 <block>
        <name>Waterfall Sink</name>
        <key>wxgui_waterfallsink2</key>
+       <import>from gnuradio import window</import>
        <import>from gnuradio.wxgui import waterfallsink2</import>
        <make>#set $parent = $notebook() and 'self.%s.GetPage(%s)'%$notebook() or 'self'
 waterfallsink2.$(type.fcn)(
@@ -18,9 +19,12 @@ waterfallsink2.$(type.fcn)(
        sample_rate=$samp_rate,
        fft_size=$fft_size,
        fft_rate=$fft_rate,
-       average=$options.average,
+       average=$average,
        avg_alpha=#if $avg_alpha() then $avg_alpha else 'None'#,
        title=$title,
+#if $win()
+       win=$win,
+#end if
 #if $win_size()
        size=$win_size,
 #end if
@@ -96,26 +100,57 @@ $(parent).GridAdd(self.$(id).win, $(', '.join(map(str, $grid_pos()))))
                <value>15</value>
                <type>int</type>
        </param>
+       <param>
+               <name>Average</name>
+               <key>average</key>
+               <value>False</value>
+               <type>enum</type>
+               <hide>part</hide>
+               <option>
+                       <name>On</name>
+                       <key>True</key>
+               </option>
+               <option>
+                       <name>Off</name>
+                       <key>False</key>
+               </option>
+       </param>
        <param>
                <name>Average Alpha</name>
                <key>avg_alpha</key>
                <value>0</value>
                <type>real</type>
+               <hide>#if $average() == 'True' then 'none' else 'all'#</hide>
        </param>
        <param>
-               <name>Options</name>
-               <key>options</key>
-               <value>none</value>
-               <type>enum</type>
+               <name>Window</name>
+               <key>win</key>
+               <value>None</value>
+               <type>raw</type>
+               <hide>#if $win() is None then 'part' else 'none'#</hide>
+               <option>
+                       <name>Automatic</name>
+                       <key>None</key>
+               </option>
+               <option>
+                       <name>Blackman-Harris</name>
+                       <key>window.blackmanharris</key>
+               </option>
+               <option>
+                       <name>Hamming</name>
+                       <key>window.hamming</key>
+               </option>
+               <option>
+                       <name>Hanning</name>
+                       <key>window.hanning</key>
+               </option>
                <option>
-                       <name>None</name>
-                       <key>none</key>
-                       <opt>average:False</opt>
+                       <name>Rectangular</name>
+                       <key>window.rectangular</key>
                </option>
                <option>
-                       <name>Average</name>
-                       <key>average</key>
-                       <opt>average:True</opt>
+                       <name>Flattop</name>
+                       <key>window.flattop</key>
                </option>
        </param>
        <param>