diff options
Diffstat (limited to 'gr-fft')
-rw-r--r-- | gr-fft/grc/fft_block_tree.xml | 5 | ||||
-rw-r--r-- | gr-fft/grc/fft_logpwrfft_x.xml | 90 | ||||
-rw-r--r-- | gr-fft/python/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gr-fft/python/__init__.py | 2 | ||||
-rw-r--r-- | gr-fft/python/logpwrfft.py | 163 |
5 files changed, 260 insertions, 1 deletions
diff --git a/gr-fft/grc/fft_block_tree.xml b/gr-fft/grc/fft_block_tree.xml index 3bda77eae1..5abbc3ef26 100644 --- a/gr-fft/grc/fft_block_tree.xml +++ b/gr-fft/grc/fft_block_tree.xml @@ -33,4 +33,9 @@ <block>fft_vxx</block> <block>goertzel_fc</block> </cat> + + <cat> + <name>Operators</name> + <block>logpwrfft_x</block> + </cat> </cat> diff --git a/gr-fft/grc/fft_logpwrfft_x.xml b/gr-fft/grc/fft_logpwrfft_x.xml new file mode 100644 index 0000000000..936be1cc71 --- /dev/null +++ b/gr-fft/grc/fft_logpwrfft_x.xml @@ -0,0 +1,90 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Log Power FFT +################################################### + --> +<block> + <name>Log Power FFT</name> + <key>logpwrfft_x</key> + <import>from gnuradio import fft</import> + <make>fft.logpwrfft_$(type.fcn)( + sample_rate=$sample_rate, + fft_size=$fft_size, + ref_scale=$ref_scale, + frame_rate=$frame_rate, + avg_alpha=$avg_alpha, + average=$average, +)</make> + <callback>set_sample_rate($sample_rate)</callback> + <callback>set_avg_alpha($avg_alpha)</callback> + <callback>set_average($average)</callback> + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:c</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:f</opt> + </option> + </param> + <param> + <name>Sample Rate</name> + <key>sample_rate</key> + <value>samp_rate</value> + <type>real</type> + </param> + <param> + <name>FFT Size</name> + <key>fft_size</key> + <value>1024</value> + <type>int</type> + </param> + <param> + <name>Reference Scale</name> + <key>ref_scale</key> + <value>2</value> + <type>real</type> + </param> + <param> + <name>Frame Rate</name> + <key>frame_rate</key> + <value>30</value> + <type>real</type> + </param> + <param> + <name>Average</name> + <key>average</key> + <value>False</value> + <type>bool</type> + <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>1.0</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>$type</type> + </sink> + <source> + <name>out</name> + <type>float</type> + <vlen>$fft_size</vlen> + </source> +</block> diff --git a/gr-fft/python/CMakeLists.txt b/gr-fft/python/CMakeLists.txt index 16c29e5995..3cca444f9a 100644 --- a/gr-fft/python/CMakeLists.txt +++ b/gr-fft/python/CMakeLists.txt @@ -23,6 +23,7 @@ include(GrPython) GR_PYTHON_INSTALL( FILES __init__.py + logpwrfft.py DESTINATION ${GR_PYTHON_DIR}/gnuradio/fft COMPONENT "fft_python" ) diff --git a/gr-fft/python/__init__.py b/gr-fft/python/__init__.py index 0fa643e35d..a532109b70 100644 --- a/gr-fft/python/__init__.py +++ b/gr-fft/python/__init__.py @@ -25,4 +25,4 @@ processing blocks for FFT and related functions. ''' from fft_swig import * - +from logpwrfft import * diff --git a/gr-fft/python/logpwrfft.py b/gr-fft/python/logpwrfft.py new file mode 100644 index 0000000000..42a4757f02 --- /dev/null +++ b/gr-fft/python/logpwrfft.py @@ -0,0 +1,163 @@ +# +# 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, window +from gnuradio.blks2 import stream_to_vector_decimator +import sys, math + +import fft_swig as fft + +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. + @param sample_rate Incoming stream sample rate + @param fft_size Number of FFT bins + @param ref_scale Sets 0 dB value input amplitude + @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 + gr.io_signature(1, 1, gr.sizeof_float*fft_size)) # Output signature + + self._sd = 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 = gr.complex_to_mag_squared(fft_size) + self._avg = filter.single_pole_iir_filter_ff(1.0, fft_size) + self._log = gr.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. + @param decim the new decimation + """ + self._sd.set_decimation(decim) + + def set_vec_rate(self, vec_rate): + """ + Set the vector rate on stream decimator. + @param 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 + @param sample_rate the new rate + """ + self._sd.set_sample_rate(sample_rate) + + def set_average(self, average): + """ + Set the averaging filter on/off. + @param 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. + @param 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, ) + |