[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] [gnuradio] 06/14: gr-filter: Add a convenience freq_xl
From: |
git |
Subject: |
[Commit-gnuradio] [gnuradio] 06/14: gr-filter: Add a convenience freq_xlating_fft_filter block |
Date: |
Fri, 9 May 2014 22:28:43 +0000 (UTC) |
This is an automated email from the git hooks/post-receive script.
jcorgan pushed a commit to branch master
in repository gnuradio.
commit 78d7d59f28e8fb1c792bbb1a80dd989c60a7214b
Author: Sylvain Munaut <address@hidden>
Date: Thu May 8 15:15:29 2014 +0200
gr-filter: Add a convenience freq_xlating_fft_filter block
It's meant as a GRC convenience mainly. It's in python only and implemented
as a hier block encapsulating a FFT filter + rotator
Signed-off-by: Sylvain Munaut <address@hidden>
---
gr-filter/grc/CMakeLists.txt | 1 +
gr-filter/grc/filter_block_tree.xml | 1 +
.../grc/filter_freq_xlating_fft_filter_ccc.xml | 62 +++++++++
gr-filter/python/filter/CMakeLists.txt | 1 +
gr-filter/python/filter/__init__.py | 1 +
gr-filter/python/filter/freq_xlating_fft_filter.py | 80 +++++++++++
.../python/filter/qa_freq_xlating_fft_filter.py | 147 +++++++++++++++++++++
7 files changed, 293 insertions(+)
diff --git a/gr-filter/grc/CMakeLists.txt b/gr-filter/grc/CMakeLists.txt
index 8c3dc64..575f667 100644
--- a/gr-filter/grc/CMakeLists.txt
+++ b/gr-filter/grc/CMakeLists.txt
@@ -26,6 +26,7 @@ install(FILES
filter_filterbank_vcvcf.xml
filter_fractional_interpolator_xx.xml
filter_fractional_resampler_xx.xml
+ filter_freq_xlating_fft_filter_ccc.xml
filter_freq_xlating_fir_filter_xxx.xml
filter_hilbert_fc.xml
filter_iir_filter_xxx.xml
diff --git a/gr-filter/grc/filter_block_tree.xml
b/gr-filter/grc/filter_block_tree.xml
index f85f3f1..ea0ffd3 100644
--- a/gr-filter/grc/filter_block_tree.xml
+++ b/gr-filter/grc/filter_block_tree.xml
@@ -56,6 +56,7 @@
</cat>
<cat>
<name>Channelizers</name>
+ <block>freq_xlating_fft_filter_ccc</block>
<block>freq_xlating_fir_filter_xxx</block>
<block>pfb_channelizer_ccf</block>
<block>pfb_channelizer_hier_ccf</block>
diff --git a/gr-filter/grc/filter_freq_xlating_fft_filter_ccc.xml
b/gr-filter/grc/filter_freq_xlating_fft_filter_ccc.xml
new file mode 100644
index 0000000..ec27a4f
--- /dev/null
+++ b/gr-filter/grc/filter_freq_xlating_fft_filter_ccc.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Frequency Xlating FFT Filter
+###################################################
+ -->
+<block>
+ <name>Frequency Xlating FFT Filter</name>
+ <key>freq_xlating_fft_filter_ccc</key>
+ <import>from gnuradio import filter</import>
+ <import>from gnuradio.filter import firdes</import>
+ <make>filter.freq_xlating_fft_filter_ccc($decim, $taps, $center_freq,
$samp_rate)
+self.$(id).set_nthreads($nthreads)
+self.$(id).declare_sample_delay($samp_delay)</make>
+ <callback>set_taps($taps)</callback>
+ <callback>set_center_freq($center_freq)</callback>
+ <callback>set_nthreads($nthreads)</callback>
+ <param>
+ <name>Decimation</name>
+ <key>decim</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Taps</name>
+ <key>taps</key>
+ <type>complex_vector</type>
+ </param>
+ <param>
+ <name>Center Frequency</name>
+ <key>center_freq</key>
+ <value>0</value>
+ <type>real</type>
+ </param>
+ <param>
+ <name>Sample Rate</name>
+ <key>samp_rate</key>
+ <value>samp_rate</value>
+ <type>real</type>
+ </param>
+ <param>
+ <name>Sample Delay</name>
+ <key>samp_delay</key>
+ <value>0</value>
+ <type>int</type>
+ <hide>part</hide>
+ </param>
+ <param>
+ <name>Num. Threads</name>
+ <key>nthreads</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>complex</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>complex</type>
+ </source>
+</block>
diff --git a/gr-filter/python/filter/CMakeLists.txt
b/gr-filter/python/filter/CMakeLists.txt
index e83e6dd..c708f0a 100644
--- a/gr-filter/python/filter/CMakeLists.txt
+++ b/gr-filter/python/filter/CMakeLists.txt
@@ -24,6 +24,7 @@ GR_PYTHON_INSTALL(
FILES
__init__.py
filterbank.py
+ freq_xlating_fft_filter.py
optfir.py
pfb.py
rational_resampler.py
diff --git a/gr-filter/python/filter/__init__.py
b/gr-filter/python/filter/__init__.py
index 80dc422..cbbc80f 100644
--- a/gr-filter/python/filter/__init__.py
+++ b/gr-filter/python/filter/__init__.py
@@ -31,6 +31,7 @@ except ImportError:
__path__.append(os.path.join(dirname, "..", "..", "swig"))
from filter_swig import *
from filterbank import *
+from freq_xlating_fft_filter import *
from rational_resampler import *
import pfb
import optfir
diff --git a/gr-filter/python/filter/freq_xlating_fft_filter.py
b/gr-filter/python/filter/freq_xlating_fft_filter.py
new file mode 100644
index 0000000..f6ebe05
--- /dev/null
+++ b/gr-filter/python/filter/freq_xlating_fft_filter.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+#
+# Copyright 2013 Sylvain Munaut <address@hidden>
+#
+# This 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.
+#
+# This software 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 software; see the file COPYING. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+import math
+import cmath
+
+from gnuradio import gr
+from gnuradio.blocks import rotator_cc
+
+from filter_swig import fft_filter_ccc
+
+
+__all__ = [ 'freq_xlating_fft_filter_ccc' ]
+
+
+class freq_xlating_fft_filter_ccc(gr.hier_block2):
+
+ def __init__(self, decim, taps, center_freq, samp_rate):
+ gr.hier_block2.__init__(
+ self,
+ 'freq_xlating_fft_filter_ccc',
+ gr.io_signature(1, 1, gr.sizeof_gr_complex),
+ gr.io_signature(1, 1, gr.sizeof_gr_complex),
+ )
+
+ # Save args
+ self.decim = decim
+ self.taps = taps
+ self.center_freq = center_freq
+ self.samp_rate = samp_rate
+
+ # Sub blocks
+ self._filter = fft_filter_ccc(decim, taps)
+ self._rotator = rotator_cc(0.0)
+
+ self.connect(self, self._filter, self._rotator, self)
+
+ # Refresh
+ self._refresh()
+
+ def _rotate_taps(self, taps, phase_inc):
+ return [ x * cmath.exp(i * phase_inc * 1j) for i,x in enumerate(taps) ]
+
+ def _refresh(self):
+ phase_inc = (2.0 * math.pi * self.center_freq) / self.samp_rate
+ rtaps = self._rotate_taps(self.taps, phase_inc)
+ self._filter.set_taps(rtaps)
+ self._rotator.set_phase_inc(- self.decim * phase_inc)
+
+ def set_taps(self, taps):
+ self.taps = taps
+ self._refresh()
+
+ def set_center_freq(self, center_freq):
+ self.center_freq = center_freq
+ self._refresh()
+
+ def set_nthreads(self, nthreads):
+ self._filter.set_nthreads(nthreads)
+
+ def declare_sample_delay(self, samp_delay):
+ self._filter.declare_sample_delay(samp_delay)
diff --git a/gr-filter/python/filter/qa_freq_xlating_fft_filter.py
b/gr-filter/python/filter/qa_freq_xlating_fft_filter.py
new file mode 100755
index 0000000..a9adfa0
--- /dev/null
+++ b/gr-filter/python/filter/qa_freq_xlating_fft_filter.py
@@ -0,0 +1,147 @@
+#!/usr/bin/env python
+#
+# Copyright 2008,2010,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 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, filter, blocks
+
+import cmath, math
+
+def fir_filter(x, taps, decim=1):
+ y = []
+ x2 = (len(taps)-1)*[0,] + x
+ for i in range(0, len(x), decim):
+ yi = 0
+ for j in range(len(taps)):
+ yi += taps[len(taps)-1-j] * x2[i+j]
+ y.append(yi)
+ return y
+
+def sig_source_s(samp_rate, freq, amp, N):
+ t = map(lambda x: float(x)/samp_rate, xrange(N))
+ y = map(lambda x: int(100*math.sin(2.*math.pi*freq*x)), t)
+ return y
+
+def sig_source_c(samp_rate, freq, amp, N):
+ t = map(lambda x: float(x)/samp_rate, xrange(N))
+ y = map(lambda x: math.cos(2.*math.pi*freq*x) + \
+ 1j*math.sin(2.*math.pi*freq*x), t)
+ return y
+
+def mix(lo, data):
+ y = [lo_i*data_i for lo_i, data_i in zip(lo, data)]
+ return y
+
+class test_freq_xlating_filter(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block ()
+
+ def tearDown(self):
+ self.tb = None
+
+ def generate_ccf_source(self):
+ self.fs = fs = 1
+ self.fc = fc = 0.3
+ self.bw = bw = 0.1
+ self.taps = filter.firdes.low_pass(1, fs, bw, bw/4)
+ times = xrange(1024)
+ self.src_data = map(lambda t: cmath.exp(-2j*cmath.pi*fc/fs*(t/100.0)),
times)
+
+ def generate_ccc_source(self):
+ self.fs = fs = 1
+ self.fc = fc = 0.3
+ self.bw = bw = 0.1
+ self.taps = filter.firdes.complex_band_pass(1, fs, -bw/2, bw/2, bw/4)
+ times = xrange(1024)
+ self.src_data = map(lambda t: cmath.exp(-2j*cmath.pi*fc/fs*(t/100.0)),
times)
+
+ def assert_fft_ok(self, expected_result, result_data):
+ expected_result = expected_result[:len(result_data)]
+ self.assertComplexTuplesAlmostEqual2 (expected_result, result_data,
+ abs_eps=1e-9, rel_eps=1e-3)
+
+
+ def test_fft_filter_ccf_001(self):
+ self.generate_ccf_source()
+
+ decim = 1
+ lo = sig_source_c(self.fs, -self.fc, 1, len(self.src_data))
+ despun = mix(lo, self.src_data)
+ expected_data = fir_filter(despun, self.taps, decim)
+
+ src = blocks.vector_source_c(self.src_data)
+ op = filter.freq_xlating_fft_filter_ccc(decim, self.taps, self.fc,
self.fs)
+ dst = blocks.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assert_fft_ok(expected_data, result_data)
+
+ def test_fft_filter_ccf_002(self):
+ self.generate_ccf_source()
+
+ decim = 4
+ lo = sig_source_c(self.fs, -self.fc, 1, len(self.src_data))
+ despun = mix(lo, self.src_data)
+ expected_data = fir_filter(despun, self.taps, decim)
+
+ src = blocks.vector_source_c(self.src_data)
+ op = filter.freq_xlating_fft_filter_ccc(decim, self.taps, self.fc,
self.fs)
+ dst = blocks.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assert_fft_ok(expected_data, result_data)
+
+ def test_fft_filter_ccc_001(self):
+ self.generate_ccc_source()
+
+ decim = 1
+ lo = sig_source_c(self.fs, -self.fc, 1, len(self.src_data))
+ despun = mix(lo, self.src_data)
+ expected_data = fir_filter(despun, self.taps, decim)
+
+ src = blocks.vector_source_c(self.src_data)
+ op = filter.freq_xlating_fft_filter_ccc(decim, self.taps, self.fc,
self.fs)
+ dst = blocks.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assert_fft_ok(expected_data, result_data)
+
+ def test_fft_filter_ccc_002(self):
+ self.generate_ccc_source()
+
+ decim = 4
+ lo = sig_source_c(self.fs, -self.fc, 1, len(self.src_data))
+ despun = mix(lo, self.src_data)
+ expected_data = fir_filter(despun, self.taps, decim)
+
+ src = blocks.vector_source_c(self.src_data)
+ op = filter.freq_xlating_fft_filter_ccc(decim, self.taps, self.fc,
self.fs)
+ dst = blocks.vector_sink_c()
+ self.tb.connect(src, op, dst)
+ self.tb.run()
+ result_data = dst.data()
+ self.assert_fft_ok(expected_data, result_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_freq_xlating_filter, "test_freq_xlating_filter.xml")
+
- [Commit-gnuradio] [gnuradio] branch master updated (8c97b7c -> 432e3b7), git, 2014/05/09
- [Commit-gnuradio] [gnuradio] 04/14: Merge branch 'master' of git.gnuradio.org:gnuradio, git, 2014/05/09
- [Commit-gnuradio] [gnuradio] 06/14: gr-filter: Add a convenience freq_xlating_fft_filter block,
git <=
- [Commit-gnuradio] [gnuradio] 11/14: Merge remote-tracking branch 'smunaut/fft-filter', git, 2014/05/09
- [Commit-gnuradio] [gnuradio] 08/14: Merge remote-tracking branch 'osh/typo_fix', git, 2014/05/09
- [Commit-gnuradio] [gnuradio] 13/14: Merge branch 'maint', git, 2014/05/09
- [Commit-gnuradio] [gnuradio] 14/14: Merge remote-tracking branch 'tom/cmake_ice_libs', git, 2014/05/09
- [Commit-gnuradio] [gnuradio] 05/14: cmake: fixing up FindICE to handle more possible install cases., git, 2014/05/09
- [Commit-gnuradio] [gnuradio] 01/14: cmake: better setup for finding QWT; otherwise, it can be forced to incorrectly "find" non-existent QWT libs., git, 2014/05/09
- [Commit-gnuradio] [gnuradio] 09/14: gr-digital: update the HDLC blocks., git, 2014/05/09
- [Commit-gnuradio] [gnuradio] 10/14: Merge branch 'hdlc_update', git, 2014/05/09
- [Commit-gnuradio] [gnuradio] 12/14: Merge remote-tracking branch 'osh/cpx_to_ishort_vector', git, 2014/05/09
- [Commit-gnuradio] [gnuradio] 07/14: blocks: add vector output option param to complex_to_interleaved_short to match interleaved_short_to_complex, git, 2014/05/09