summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt5
-rw-r--r--README154
-rw-r--r--docs/doxygen/other/build_guide.dox32
-rw-r--r--gnuradio-core/src/lib/swig/gnuradio.i3
-rw-r--r--gnuradio-core/src/lib/swig/gr_swig_block_magic.i10
-rw-r--r--gnuradio-core/src/python/build_utils.py4
-rw-r--r--gr-digital/grc/digital_additive_scrambler_bb.xml44
-rw-r--r--gr-digital/grc/digital_block_tree.xml16
-rw-r--r--gr-digital/grc/digital_bytes_to_syms.xml20
-rw-r--r--gr-digital/grc/digital_chunks_to_symbols.xml77
-rw-r--r--gr-digital/grc/digital_descrambler_bb.xml38
-rw-r--r--gr-digital/grc/digital_diff_decoder_bb.xml25
-rw-r--r--gr-digital/grc/digital_diff_encoder_bb.xml25
-rw-r--r--gr-digital/grc/digital_diff_phasor_cc.xml20
-rw-r--r--gr-digital/grc/digital_framer_sink_1.xml21
-rw-r--r--gr-digital/grc/digital_glfsr_source_x.xml61
-rw-r--r--gr-digital/grc/digital_map_bb.xml25
-rw-r--r--gr-digital/grc/digital_packet_sink.xml31
-rw-r--r--gr-digital/grc/digital_pfb_clock_sync.xml104
-rw-r--r--gr-digital/grc/digital_pn_correlator_cc.xml37
-rw-r--r--gr-digital/grc/digital_probe_density_b.xml29
-rw-r--r--gr-digital/grc/digital_scrambler_bb.xml38
-rw-r--r--gr-digital/grc/digital_simple_framer.xml25
-rw-r--r--gr-digital/include/CMakeLists.txt84
-rw-r--r--gr-digital/include/digital_additive_scrambler_bb.h73
-rw-r--r--gr-digital/include/digital_bytes_to_syms.h62
-rw-r--r--gr-digital/include/digital_chunks_to_symbols_XX.h.t75
-rw-r--r--gr-digital/include/digital_correlate_access_code_tag_bb.h89
-rw-r--r--gr-digital/include/digital_cpmmod_bc.h7
-rw-r--r--gr-digital/include/digital_descrambler_bb.h62
-rw-r--r--gr-digital/include/digital_diff_decoder_bb.h56
-rw-r--r--gr-digital/include/digital_diff_encoder_bb.h57
-rw-r--r--gr-digital/include/digital_diff_phasor_cc.h59
-rw-r--r--gr-digital/include/digital_framer_sink_1.h107
-rw-r--r--gr-digital/include/digital_glfsr_source_b.h78
-rw-r--r--gr-digital/include/digital_glfsr_source_f.h78
-rw-r--r--gr-digital/include/digital_impl_glfsr.h57
-rw-r--r--gr-digital/include/digital_map_bb.h62
-rw-r--r--gr-digital/include/digital_packet_sink.h131
-rw-r--r--gr-digital/include/digital_pfb_clock_sync_ccf.h376
-rw-r--r--gr-digital/include/digital_pfb_clock_sync_fff.h376
-rw-r--r--gr-digital/include/digital_pn_correlator_cc.h72
-rw-r--r--gr-digital/include/digital_probe_density_b.h75
-rw-r--r--gr-digital/include/digital_scrambler_bb.h62
-rw-r--r--gr-digital/include/digital_simple_framer.h66
-rw-r--r--gr-digital/include/digital_simple_framer_sync.h51
-rw-r--r--gr-digital/lib/CMakeLists.txt88
-rw-r--r--gr-digital/lib/digital_additive_scrambler_bb.cc69
-rw-r--r--gr-digital/lib/digital_bytes_to_syms.cc74
-rw-r--r--gr-digital/lib/digital_chunks_to_symbols_XX.cc.t74
-rw-r--r--gr-digital/lib/digital_correlate_access_code_tag_bb.cc131
-rw-r--r--gr-digital/lib/digital_descrambler_bb.cc56
-rw-r--r--gr-digital/lib/digital_diff_decoder_bb.cc61
-rw-r--r--gr-digital/lib/digital_diff_encoder_bb.cc62
-rw-r--r--gr-digital/lib/digital_diff_phasor_cc.cc61
-rw-r--r--gr-digital/lib/digital_framer_sink_1.cc192
-rw-r--r--gr-digital/lib/digital_glfsr_source_b.cc86
-rw-r--r--gr-digital/lib/digital_glfsr_source_f.cc86
-rw-r--r--gr-digital/lib/digital_impl_glfsr.cc67
-rw-r--r--gr-digital/lib/digital_map_bb.cc61
-rw-r--r--gr-digital/lib/digital_packet_sink.cc207
-rw-r--r--gr-digital/lib/digital_pfb_clock_sync_ccf.cc440
-rw-r--r--gr-digital/lib/digital_pfb_clock_sync_fff.cc434
-rw-r--r--gr-digital/lib/digital_pn_correlator_cc.cc80
-rw-r--r--gr-digital/lib/digital_probe_density_b.cc68
-rw-r--r--gr-digital/lib/digital_scrambler_bb.cc57
-rw-r--r--gr-digital/lib/digital_simple_framer.cc102
-rw-r--r--gr-digital/python/generic_mod_demod.py24
-rwxr-xr-xgr-digital/python/qa_bytes_to_syms.py51
-rwxr-xr-xgr-digital/python/qa_chunks_to_symbols.py140
-rwxr-xr-xgr-digital/python/qa_correlate_access_code.py21
-rwxr-xr-xgr-digital/python/qa_diff_encoder.py87
-rwxr-xr-xgr-digital/python/qa_diff_phasor_cc.py49
-rwxr-xr-xgr-digital/python/qa_framer_sink.py98
-rwxr-xr-xgr-digital/python/qa_glfsr_source.py95
-rwxr-xr-xgr-digital/python/qa_map.py60
-rwxr-xr-xgr-digital/python/qa_pfb_clock_sync.py142
-rwxr-xr-xgr-digital/python/qa_pn_correlator_cc.py (renamed from volk/python/qa_square.py)34
-rwxr-xr-xgr-digital/python/qa_probe_density.py71
-rwxr-xr-xgr-digital/python/qa_scrambler.py65
-rwxr-xr-xgr-digital/python/qa_simple_framer.py59
-rw-r--r--gr-digital/swig/CMakeLists.txt122
-rw-r--r--gr-digital/swig/digital_additive_scrambler_bb.i (renamed from volk/python/volk_square_ff.i)26
-rw-r--r--gr-digital/swig/digital_bytes_to_syms.i29
-rw-r--r--gr-digital/swig/digital_chunks_to_symbols_XX.i.t38
-rw-r--r--gr-digital/swig/digital_constellation_decoder_cb.i2
-rw-r--r--gr-digital/swig/digital_correlate_access_code_tag_bb.i35
-rw-r--r--gr-digital/swig/digital_descrambler_bb.i30
-rw-r--r--gr-digital/swig/digital_diff_decoder_bb.i30
-rw-r--r--gr-digital/swig/digital_diff_encoder_bb.i30
-rw-r--r--gr-digital/swig/digital_diff_phasor_cc.i30
-rw-r--r--gr-digital/swig/digital_framer_sink_1.i30
-rw-r--r--gr-digital/swig/digital_glfsr_source_b.i35
-rw-r--r--gr-digital/swig/digital_glfsr_source_f.i35
-rw-r--r--gr-digital/swig/digital_map_bb.i31
-rw-r--r--gr-digital/swig/digital_packet_sink.i34
-rw-r--r--gr-digital/swig/digital_pfb_clock_sync_ccf.i58
-rw-r--r--gr-digital/swig/digital_pfb_clock_sync_fff.i58
-rw-r--r--gr-digital/swig/digital_pn_correlator_cc.i32
-rw-r--r--gr-digital/swig/digital_probe_density_b.i33
-rw-r--r--gr-digital/swig/digital_scrambler_bb.i30
-rw-r--r--gr-digital/swig/digital_simple_framer.i30
-rw-r--r--gr-digital/swig/digital_swig.i47
-rw-r--r--gr-fft/CMakeLists.txt111
-rw-r--r--gr-fft/doc/CMakeLists.txt23
-rw-r--r--gr-fft/doc/README.fft13
-rw-r--r--gr-fft/doc/fft.dox29
-rw-r--r--gr-fft/gnuradio-fft.pc.in11
-rw-r--r--gr-fft/grc/CMakeLists.txt26
-rw-r--r--gr-fft/grc/fft_block_tree.xml36
-rw-r--r--gr-fft/grc/fft_vxx.xml88
-rw-r--r--gr-fft/grc/goertzel_fc.xml37
-rw-r--r--gr-fft/include/fft/CMakeLists.txt33
-rw-r--r--gr-fft/include/fft/api.h33
-rw-r--r--gr-fft/include/fft/fft.h195
-rw-r--r--gr-fft/include/fft/fft_vcc.h57
-rw-r--r--gr-fft/include/fft/fft_vfc.h57
-rw-r--r--gr-fft/include/fft/goertzel.h64
-rw-r--r--gr-fft/include/fft/goertzel_fc.h57
-rw-r--r--gr-fft/lib/CMakeLists.txt59
-rw-r--r--gr-fft/lib/fft.cc338
-rw-r--r--gr-fft/lib/fft_vcc_fftw.cc147
-rw-r--r--gr-fft/lib/fft_vcc_fftw.h60
-rw-r--r--gr-fft/lib/fft_vfc_fftw.cc124
-rw-r--r--gr-fft/lib/fft_vfc_fftw.h59
-rw-r--r--gr-fft/lib/goertzel.cc84
-rw-r--r--gr-fft/lib/goertzel_fc_impl.cc85
-rw-r--r--gr-fft/lib/goertzel_fc_impl.h60
-rw-r--r--gr-fft/python/CMakeLists.txt47
-rw-r--r--gr-fft/python/__init__.py28
-rwxr-xr-xgr-fft/python/qa_fft.py213
-rwxr-xr-xgr-fft/python/qa_goertzel.py65
-rw-r--r--gr-fft/swig/CMakeLists.txt51
-rw-r--r--gr-fft/swig/fft_swig.i42
-rwxr-xr-xgr-uhd/apps/uhd_fft6
-rw-r--r--gr-uhd/apps/uhd_siggen_base.py6
-rw-r--r--gr-wxgui/grc/top_block_gui.py8
-rw-r--r--grc/blocks/options.xml17
-rw-r--r--grc/python/flow_graph.tmpl16
-rw-r--r--volk/CMakeLists.txt24
-rw-r--r--volk/apps/CMakeLists.txt7
-rw-r--r--volk/cmake/GrPython.cmake233
-rw-r--r--volk/cmake/msvc/config.h58
-rw-r--r--volk/cmake/msvc/inttypes.h (renamed from volk/msvc/inttypes.h)0
-rw-r--r--volk/cmake/msvc/stdint.h (renamed from volk/msvc/stdint.h)0
-rw-r--r--volk/gen/archs.xml230
-rw-r--r--volk/gen/compilers.xml30
-rw-r--r--volk/gen/machines.xml39
-rw-r--r--volk/gen/make_c.py88
-rw-r--r--volk/gen/make_config_fixed.py21
-rw-r--r--volk/gen/make_config_in.py13
-rw-r--r--volk/gen/make_cpuid_c.py283
-rw-r--r--volk/gen/make_cpuid_h.py48
-rw-r--r--volk/gen/make_each_machine_c.py90
-rw-r--r--volk/gen/make_environment_init_c.py32
-rw-r--r--volk/gen/make_environment_init_h.py18
-rw-r--r--volk/gen/make_h.py38
-rw-r--r--volk/gen/make_machines_c.py41
-rw-r--r--volk/gen/make_machines_h.py59
-rw-r--r--volk/gen/make_makefile_am.py123
-rw-r--r--volk/gen/make_proccpu_sim.py47
-rw-r--r--volk/gen/make_set_simd.py166
-rw-r--r--volk/gen/make_typedefs.py23
-rw-r--r--volk/gen/volk_arch_defs.py92
-rw-r--r--volk/gen/volk_compile_utils.py58
-rw-r--r--volk/gen/volk_kernel_defs.py224
-rw-r--r--volk/gen/volk_machine_defs.py78
-rw-r--r--volk/gen/volk_regexp.py13
-rw-r--r--volk/gen/volk_register.py303
-rw-r--r--volk/gen/volk_tmpl_utils.py74
-rw-r--r--volk/lib/CMakeLists.txt364
-rw-r--r--volk/lib/gcc_x86_cpuid.h6
-rw-r--r--volk/lib/testqa.cc2
-rwxr-xr-xvolk/libvector_replace.sh18
-rw-r--r--volk/python/__init__.py53
-rw-r--r--volk/python/volk.i47
-rw-r--r--volk/tmpl/volk.tmpl.c92
-rw-r--r--volk/tmpl/volk.tmpl.h48
-rw-r--r--volk/tmpl/volk_config_fixed.tmpl.h29
-rw-r--r--volk/tmpl/volk_cpu.tmpl.c184
-rw-r--r--volk/tmpl/volk_cpu.tmpl.h42
-rw-r--r--volk/tmpl/volk_machine_xxx.tmpl.c73
-rw-r--r--volk/tmpl/volk_machines.tmpl.c34
-rw-r--r--volk/tmpl/volk_machines.tmpl.h51
-rw-r--r--volk/tmpl/volk_typedefs.tmpl.h32
185 files changed, 11314 insertions, 2135 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 73473c5f3..dad398e8c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -41,8 +41,8 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
# Set the version information here
set(VERSION_INFO_MAJOR_VERSION 3)
set(VERSION_INFO_API_COMPAT 6)
-set(VERSION_INFO_MINOR_VERSION 0)
-set(VERSION_INFO_MAINT_VERSION 0)
+set(VERSION_INFO_MINOR_VERSION 1)
+set(VERSION_INFO_MAINT_VERSION git)
include(GrVersion) #setup version info
# Append -O2 optimization flag for Debug builds
@@ -228,6 +228,7 @@ add_subdirectory(gruel)
add_subdirectory(gnuradio-core)
add_subdirectory(grc)
+add_subdirectory(gr-fft)
add_subdirectory(gr-atsc)
add_subdirectory(gr-audio)
add_subdirectory(gr-comedi)
diff --git a/README b/README
index 09af3d985..d8d7e0ebc 100644
--- a/README
+++ b/README
@@ -46,21 +46,16 @@ http://gnuradio.org/redmine/projects/gnuradio/wiki/DevelopingWithGit
How to Build GNU Radio:
- (1) Ensure that you've satisfied the external dependencies listed
- below. The word "system" is used to mean "operating system
- and/or distribution", and means a full operating system,
- including kernel, user-space utilties, and a packaging system
- for additional software. On Linux, this means what
- "distribution" means.
-
- The following GNU/Linux distributions are known to come with all
- required dependencies pre-packaged: Ubuntu >8.10, SuSE 10.0 (the
- pay version, not the free download), Fedora Core >9. Other
- distribution may work too. We know these three are easy. The
- required packages may be contained on your installation CD/DVD,
- or may be loaded over the net. The specifics vary depending on
- your GNU/Linux distribution.
+For more complete instructions, see the "Building GNU Radio" page in
+the GNU Radio manual (can be built or found online at
+http://gnuradio.org/doc/doxygen/page_build.html).
+See these steps fow a quick build guide.
+
+ (1) Ensure that you've satisfied the external dependencies. These
+ dependencies are listed in the manual's build page and are not
+ presented here to reduce duplication errors.
+
On systems using pkgsrc (e.g. NetBSD and Dragonfly), build
meta-packages/gnuradio, which will build a previous release and
force installation of the dependencies. Then pkg_delete the
@@ -105,147 +100,20 @@ with '-O3', which is the default.
-------------------------------------------------------------------------------
- External dependencies
+ NOTES
-------------------------------------------------------------------------------
-Prerequisites: Before trying to build these from source, please try
-your system's installation tool (apt-get, pkg_install, YaST, yum,
-urpmi, etc.) first. Most recent systems have these packages
-available.
-
-You'll need to do a bit of sleuthing to figure out what your OS and
-packaging system calls these. If your system uses the convention of
-splitting files needed to run programs compiled with foo and files
-needed to do the compilation into packages named foo and foo-devel,
-install both packages. (Most GNU/Linux systems are like this, but
-pkgsrc is not and instead uses -devel to indicate a package of a
-not-yet-released or unstable version.)
-
-For those using pkgsrc, see gnuradio-pkg_chk.conf. Those not using
-pkgsrc may also find the list useful.
-
-(0) GNU make
-
-It used to be required to have a "reasonable make", meaning GNU make,
-BSD make, or perhaps Solaris make. It is now required to use GNU
-make. Version 3.81 should certainly work; the intent is not to
-require the bleeding edge.
-
-Note that the examples below are written with "make". They probably
-should say "gmake", as GNU make is installed as gmake when it is not
-the native make.
-
-(1) cmake 2.6 or later http://www.cmake.org/cmake/resources/software.html
-
-(2) pkgconfig 0.15.0 or later http://www.freedesktop.org/Software/pkgconfig
-
-From the web site:
-
-pkgconfig is a system for managing library compile/link flags that
-works with automake and autoconf. It replaces the ubiquitous *-config
-scripts you may have seen with a single tool.
-
-
-(3) FFTW 3.0 or later http://www.fftw.org
-
-IMPORTANT!!! When building FFTW, you MUST use the --enable-single and
---enable-shared configure options. This builds the single precision
-floating point version which we use. You should also use either the
---enable-3dnow or --enable-sse options if you're on an Athlon or Pentium
-respectively.
-
-GNU/Linux packages of single-precision fftw are typically called
-fftw3f.
-
-In systems using pkgsrc, install math/fftwf, which provides the
-single-precision libraries.
-
-
-(4) Python 2.5 or later http://www.python.org
-
-Python 2.5 or later is now required. If your system splits
-python into a bunch of separate packages including python-devel or
-libpython you'll most likely need those too.
-
-
-(5) Numpy python library http://numeric.scipy.org
-
-Provides a high performance array type for Python.
-http://numpy.scipy.org
-http://sourceforge.net/project/showfiles.php?group_id=1369&package_id=175103
-
-
-(6) The Boost C++ Libraries (1.35 or later) http://www.boost.org
-
-We use Smart Pointers, the thread library and a bunch of other boost stuff.
-If your system doesn't have boost 1.35 or later, see README.building-boost
-for additional info. (Note: Mac OSX systems require 1.37 or later.)
-
-
-(7) cppunit 1.9.14 or later. http://cppunit.sourceforge.net
-
-Unit testing framework for C++.
-
-
-(8) Simple Wrapper Interface Generator. http://www.swig.org
-
-As of repository version 4045, gnuradio requires version 1.3.31 or newer.
-
-
-(9) GNU Scientific Library (gsl) 1.10 or later
-
-The GNU Radio core library uses some routines from here.
-
-
-Optional, but nice to have:
-
-(10) wxPython. Python binding for the wxWidgets GUI framework. Use
-version 2.8 or later. Again, almost all systems have this
-available.
-
-As a last resort, build it from source (not recommended!)
-http://www.wxpython.org
-
-(11) xmlto version ? or later. http://cyberelk.net/tim/xmlto/index.html
-
-Wrapper for XML conversion tools to ease e.g. making html from docbook.
-
-(12) Python Cheetah extensions 2.0.0 or later
-(13) Python lxml wrappers 2.0.0 or later
-(14) Python gtk wrappers 2.10.0 or later
-
-The GNU Radio Companion application requires these additional Python libraries
-to be installed.
-
-The gr-qtgui requires these packages:
-
-(15) Qt 4.4 or later
-(16) Qwt 5.2 or later
-(17) PyQt 4.4 or later
-(18) PyQwt 5.2 or later
-
-It is also useful to have Python's Scipy and Matplot lib packages to
-run some of the example.
-
-----------------------------------------------------------------
-
-If you have doxygen installed, the build process creates
-documentation for the class hierarchy etc. Point your browser at
-gnuradio/gnuradio-core/doc/html/index.html
-
-
To run the examples you may need to set PYTHONPATH. Note that the
prefix and python version number in the path needs to match your
installed version of python.
- $ export PYTHONPATH=/usr/local/lib/python2.5/site-packages
+ $ export PYTHONPATH=/usr/local/lib/python2.7/dist-packages
You may want to add this to your shell init file (~/.bash_profile if
you use bash).
-
Another handy trick if for example your fftw includes and libs are
installed in, say ~/local/include and ~/local/lib, instead of
/usr/local is this:
diff --git a/docs/doxygen/other/build_guide.dox b/docs/doxygen/other/build_guide.dox
index 780976d62..629a0f89f 100644
--- a/docs/doxygen/other/build_guide.dox
+++ b/docs/doxygen/other/build_guide.dox
@@ -19,13 +19,16 @@ components is determined by what the user requires from GNU Radio. If,
for example, you do not use any Comedi-based hardware, do not worry
about building gr-comedi.
+Before trying to build these from source, please try your system's
+installation tool (apt-get, pkg_install, YaST, yum, urpmi, etc.)
+first. Most recent systems have these packages available.
+
\subsection dep_global Global Dependencies
\li git http://code.google.com/p/msysgit
\li cmake (>= 2.6) http://www.cmake.org/cmake/resources/software.html
\li boost (>= 1.35) http://www.boostpro.com/download
\li cppunit (>= 1.9.14) http://gaiacrtn.free.fr/cppunit/index.html
\li fftw3f (>= 3.0) http://www.fftw.org/install/windows.html
-\li gsl (>= 1.10) http://gnuwin32.sourceforge.net/packages/gsl.htm
\subsection dep_python Python Wrappers
\li python (>= 2.5) http://www.python.org/download/
@@ -39,6 +42,9 @@ about building gr-comedi.
\li Cheetah (>= 2.0) http://www.cheetahtemplate.org/
\li pygtk (>= 2.10) http://www.pygtk.org/downloads.html
+\subsection dep_wavelet gr-wavelet: Collection of wavelet blocks
+\li gsl (>= 1.10) http://gnuwin32.sourceforge.net/packages/gsl.htm
+
\subsection dep_gr_qtgui gr-qtgui: The QT-based Graphical User Interface
\li qt (>= 4.4) http://qt.nokia.com/downloads/
\li qwt (>= 5.2) http://sourceforge.net/projects/qwt/
@@ -57,6 +63,10 @@ about building gr-comedi.
\li audio-osx
\li audio-windows
+It is not necessary to satisfy all of these dependencies; just the
+one(s) that are right for your system. On Linux, don't expect
+audio-osx and audio-windows to be either satisfied or built.
+
\subsection dep_uhd uhd: The Ettus USRP Hardware Driver Interface
\li uhd (>= 3.0.0) http://code.ettus.com/redmine/ettus/projects/uhd/wiki
@@ -146,23 +156,3 @@ cmake -DCMAKE_CXX_FLAGS:STRING="-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -g
-DCMAKE_C_FLAGS:STRING="-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -g" \
<gr_source_dir>
\endcode
-
-
-\section build_old_autotools Building Using Old Autotools Method
-
-As of version 3.5, we have moved to using Cmake as the default,
-preferred build system. If for some reason, Cmake fails on your
-system, GNU Radio still includes the old autotools build process as a
-parallel build method. To build:
-
-\code
-$ cd $(srcdir)
-$ ./bootstrap // only if not building from a tarball
-$ cd $(builddir)
-$ $(srcdir)/configure [options]
-$ make [-jN]
-$ make check
-$ sudo make install
-\endcode
-
-*/
diff --git a/gnuradio-core/src/lib/swig/gnuradio.i b/gnuradio-core/src/lib/swig/gnuradio.i
index 239223851..3a421ad5d 100644
--- a/gnuradio-core/src/lib/swig/gnuradio.i
+++ b/gnuradio-core/src/lib/swig/gnuradio.i
@@ -20,6 +20,9 @@
* Boston, MA 02110-1301, USA.
*/
+// Disable warning about base class types
+#pragma SWIG nowarn=401
+
////////////////////////////////////////////////////////////////////////
// gnuradio.i
// SWIG interface definition
diff --git a/gnuradio-core/src/lib/swig/gr_swig_block_magic.i b/gnuradio-core/src/lib/swig/gr_swig_block_magic.i
index cdc9fbe49..4016ae772 100644
--- a/gnuradio-core/src/lib/swig/gr_swig_block_magic.i
+++ b/gnuradio-core/src/lib/swig/gr_swig_block_magic.i
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2010 Free Software Foundation, Inc.
+ * Copyright 2004,2010,2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -40,3 +40,11 @@ FULL_NAME ## _sptr.__repr__ = lambda self: "<gr_block %s (%d)>" % (self.name(),
%}
%enddef
#endif
+
+%define GR_SWIG_BLOCK_MAGIC2(PKG, BASE_NAME)
+%template(BASE_NAME ## _sptr) boost::shared_ptr<gr:: ## PKG ## :: ## BASE_NAME>;
+%pythoncode %{
+BASE_NAME ## _sptr.__repr__ = lambda self: "<gr_block %s (%d)>" % (self.name(), self.unique_id())
+BASE_NAME = BASE_NAME.make;
+%}
+%enddef
diff --git a/gnuradio-core/src/python/build_utils.py b/gnuradio-core/src/python/build_utils.py
index 0660941d5..ce0757912 100644
--- a/gnuradio-core/src/python/build_utils.py
+++ b/gnuradio-core/src/python/build_utils.py
@@ -176,11 +176,11 @@ def is_complex (code3):
return '0'
-def standard_dict (name, code3):
+def standard_dict (name, code3, package='gr'):
d = {}
d['NAME'] = name
d['GUARD_NAME'] = 'INCLUDED_%s_H' % name.upper ()
- d['BASE_NAME'] = re.sub ('^gr_', '', name)
+ d['BASE_NAME'] = re.sub ('^' + package + '_', '', name)
d['SPTR_NAME'] = '%s_sptr' % name
d['WARNING'] = 'WARNING: this file is machine generated. Edits will be over written'
d['COPYRIGHT'] = copyright
diff --git a/gr-digital/grc/digital_additive_scrambler_bb.xml b/gr-digital/grc/digital_additive_scrambler_bb.xml
new file mode 100644
index 000000000..5ae5ba06f
--- /dev/null
+++ b/gr-digital/grc/digital_additive_scrambler_bb.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## Additive Scrambler
+###################################################
+ -->
+<block>
+ <name>Additive Scrambler</name>
+ <key>digital_additive_scrambler_bb</key>
+ <import>from gnuradio import digital</import>
+ <make>digital.additive_scrambler_bb($mask, $seed, $len, $count)</make>
+ <param>
+ <name>Mask</name>
+ <key>mask</key>
+ <value>0x8A</value>
+ <type>hex</type>
+ </param>
+ <param>
+ <name>Seed</name>
+ <key>seed</key>
+ <value>0x7F</value>
+ <type>hex</type>
+ </param>
+ <param>
+ <name>Length</name>
+ <key>len</key>
+ <value>7</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Count</name>
+ <key>count</key>
+ <value>0</value>
+ <type>int</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ </source>
+</block>
diff --git a/gr-digital/grc/digital_block_tree.xml b/gr-digital/grc/digital_block_tree.xml
index 3ef4d0b1d..9efa0d3fb 100644
--- a/gr-digital/grc/digital_block_tree.xml
+++ b/gr-digital/grc/digital_block_tree.xml
@@ -30,19 +30,35 @@
<name></name> <!-- Blank for Root Name -->
<cat>
<name>Digital</name>
+ <block>digital_additive_scrambler_bb</block>
<block>digital_binary_slicer_fb</block>
+ <block>digital_bytes_to_syms</block>
+ <block>digital_chunks_to_symbols_xx</block>
<block>digital_clock_recovery_mm_xx</block>
<block>digital_cma_equalizer_cc</block>
<block>digital_constellation_decoder_cb</block>
<block>digital_constellation_receiver_cb</block>
<block>digital_correlate_access_code_bb</block>
<block>digital_costas_loop_cc</block>
+ <block>digital_descrambler_bb</block>
<block>digital_fll_band_edge_cc</block>
+ <block>digital_glfsr_source_x</block>
<block>digital_kurtotic_equalizer_cc</block>
<block>digital_lms_dd_equalizer_cc</block>
+ <block>digital_map_bb</block>
<block>digital_mpsk_receiver_cc</block>
<block>digital_mpsk_snr_est_cc</block>
+ <block>digital_pfb_clock_sync_xxx</block>
+ <block>digital_pn_correlator_cc</block>
+ <block>digital_probe_density_b</block>
<block>digital_probe_mpsk_snr_est_c</block>
+ <block>digital_scrambler_bb</block>
+ <block>digital_diff_decoder_bb</block>
+ <block>digital_diff_encoder_bb</block>
+ <block>digital_diff_phasor_cc</block>
+ <block>digital_framer_sink_1</block>
+ <block>digital_packet_sink</block>
+ <block>digital_simple_framer</block>
</cat>
<cat>
<name>Digital Modulators</name>
diff --git a/gr-digital/grc/digital_bytes_to_syms.xml b/gr-digital/grc/digital_bytes_to_syms.xml
new file mode 100644
index 000000000..fb17bb6de
--- /dev/null
+++ b/gr-digital/grc/digital_bytes_to_syms.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## Bytes to Syms
+###################################################
+ -->
+<block>
+ <name>Bytes to Symbols</name>
+ <key>digital_bytes_to_syms</key>
+ <import>from gnuradio import digital</import>
+ <make>digital.bytes_to_syms()</make>
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>float</type>
+ </source>
+</block>
diff --git a/gr-digital/grc/digital_chunks_to_symbols.xml b/gr-digital/grc/digital_chunks_to_symbols.xml
new file mode 100644
index 000000000..494be274d
--- /dev/null
+++ b/gr-digital/grc/digital_chunks_to_symbols.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Chunks to Symbols
+###################################################
+ -->
+<block>
+ <name>Chunks to Symbols</name>
+ <key>digital_chunks_to_symbols_xx</key>
+ <import>from gnuradio import digital</import>
+ <make>digital.chunks_to_symbols_$(in_type.fcn)$(out_type.fcn)($symbol_table, $dimension)</make>
+ <param>
+ <name>Input Type</name>
+ <key>in_type</key>
+ <type>enum</type>
+ <option>
+ <name>Int</name>
+ <key>int</key>
+ <opt>fcn:i</opt>
+ </option>
+ <option>
+ <name>Short</name>
+ <key>short</key>
+ <opt>fcn:s</opt>
+ </option>
+ <option>
+ <name>Byte</name>
+ <key>byte</key>
+ <opt>fcn:b</opt>
+ </option>
+ </param>
+ <param>
+ <name>Output Type</name>
+ <key>out_type</key>
+ <type>enum</type>
+ <option>
+ <name>Complex</name>
+ <key>complex</key>
+ <opt>fcn:c</opt>
+ <opt>table:complex_vector</opt>
+ </option>
+ <option>
+ <name>Float</name>
+ <key>float</key>
+ <opt>fcn:f</opt>
+ <opt>table:real_vector</opt>
+ </option>
+ </param>
+ <param>
+ <name>Symbol Table</name>
+ <key>symbol_table</key>
+ <type>$out_type.table</type>
+ </param>
+ <param>
+ <name>Dimension</name>
+ <key>dimension</key>
+ <value>2</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Num Ports</name>
+ <key>num_ports</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <check>$num_ports &gt; 0</check>
+ <sink>
+ <name>in</name>
+ <type>$in_type</type>
+ <nports>$num_ports</nports>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>$out_type</type>
+ <nports>$num_ports</nports>
+ </source>
+</block>
diff --git a/gr-digital/grc/digital_descrambler_bb.xml b/gr-digital/grc/digital_descrambler_bb.xml
new file mode 100644
index 000000000..4f52c7964
--- /dev/null
+++ b/gr-digital/grc/digital_descrambler_bb.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## Descrambler
+###################################################
+ -->
+<block>
+ <name>Descrambler</name>
+ <key>digital_descrambler_bb</key>
+ <import>from gnuradio import digital</import>
+ <make>digital.descrambler_bb($mask, $seed, $len)</make>
+ <param>
+ <name>Mask</name>
+ <key>mask</key>
+ <value>0x8A</value>
+ <type>hex</type>
+ </param>
+ <param>
+ <name>Seed</name>
+ <key>seed</key>
+ <value>0x7F</value>
+ <type>hex</type>
+ </param>
+ <param>
+ <name>Length</name>
+ <key>len</key>
+ <value>7</value>
+ <type>int</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ </source>
+</block>
diff --git a/gr-digital/grc/digital_diff_decoder_bb.xml b/gr-digital/grc/digital_diff_decoder_bb.xml
new file mode 100644
index 000000000..a7c94b834
--- /dev/null
+++ b/gr-digital/grc/digital_diff_decoder_bb.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Differential Decoder
+###################################################
+ -->
+<block>
+ <name>Differential Decoder</name>
+ <key>digital_diff_decoder_bb</key>
+ <import>from gnuradio import digital</import>
+ <make>digital.diff_decoder_bb($modulus)</make>
+ <param>
+ <name>Modulus</name>
+ <key>modulus</key>
+ <type>int</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ </source>
+</block>
diff --git a/gr-digital/grc/digital_diff_encoder_bb.xml b/gr-digital/grc/digital_diff_encoder_bb.xml
new file mode 100644
index 000000000..3885bed9a
--- /dev/null
+++ b/gr-digital/grc/digital_diff_encoder_bb.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Differential Encoder
+###################################################
+ -->
+<block>
+ <name>Differential Encoder</name>
+ <key>digital_diff_encoder_bb</key>
+ <import>from gnuradio import digital</import>
+ <make>digital.diff_encoder_bb($modulus)</make>
+ <param>
+ <name>Modulus</name>
+ <key>modulus</key>
+ <type>int</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ </source>
+</block>
diff --git a/gr-digital/grc/digital_diff_phasor_cc.xml b/gr-digital/grc/digital_diff_phasor_cc.xml
new file mode 100644
index 000000000..506bf400b
--- /dev/null
+++ b/gr-digital/grc/digital_diff_phasor_cc.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Differential Phasor
+###################################################
+ -->
+<block>
+ <name>Differential Phasor</name>
+ <key>digital_diff_phasor_cc</key>
+ <import>from gnuradio import digital</import>
+ <make>digital.diff_phasor_cc()</make>
+ <sink>
+ <name>in</name>
+ <type>complex</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>complex</type>
+ </source>
+</block>
diff --git a/gr-digital/grc/digital_framer_sink_1.xml b/gr-digital/grc/digital_framer_sink_1.xml
new file mode 100644
index 000000000..9124e6d0d
--- /dev/null
+++ b/gr-digital/grc/digital_framer_sink_1.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## Framer Sink 1
+###################################################
+ -->
+<block>
+ <name>Framer Sink 1</name>
+ <key>digital_framer_sink_1</key>
+ <import>from gnuradio import digital</import>
+ <make>digital.framer_sink_1($target_queue)</make>
+ <param>
+ <name>Target Message Queue</name>
+ <key>target_queue</key>
+ <type>raw</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ </sink>
+</block>
diff --git a/gr-digital/grc/digital_glfsr_source_x.xml b/gr-digital/grc/digital_glfsr_source_x.xml
new file mode 100644
index 000000000..654dfa71c
--- /dev/null
+++ b/gr-digital/grc/digital_glfsr_source_x.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##GLFSR Source
+###################################################
+ -->
+<block>
+ <name>GLFSR Source</name>
+ <key>digital_glfsr_source_x</key>
+ <import>from gnuradio import digital</import>
+ <make>digital.glfsr_source_$(type.fcn)($degree, $repeat, $mask, $seed)</make>
+ <param>
+ <name>Type</name>
+ <key>type</key>
+ <type>enum</type>
+ <option>
+ <name>Float</name>
+ <key>float</key>
+ <opt>fcn:f</opt>
+ </option>
+ <option>
+ <name>Byte</name>
+ <key>byte</key>
+ <opt>fcn:b</opt>
+ </option>
+ </param>
+ <param>
+ <name>Degree</name>
+ <key>degree</key>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Repeat</name>
+ <key>repeat</key>
+ <type>enum</type>
+ <option>
+ <name>Yes</name>
+ <key>True</key>
+ </option>
+ <option>
+ <name>No</name>
+ <key>False</key>
+ </option>
+ </param>
+ <param>
+ <name>Mask</name>
+ <key>mask</key>
+ <value>0</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Seed</name>
+ <key>seed</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <source>
+ <name>out</name>
+ <type>$type</type>
+ </source>
+</block>
diff --git a/gr-digital/grc/digital_map_bb.xml b/gr-digital/grc/digital_map_bb.xml
new file mode 100644
index 000000000..1435c5ac7
--- /dev/null
+++ b/gr-digital/grc/digital_map_bb.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Map
+###################################################
+ -->
+<block>
+ <name>Map</name>
+ <key>digital_map_bb</key>
+ <import>from gnuradio import digital</import>
+ <make>digital.map_bb($map)</make>
+ <param>
+ <name>Map</name>
+ <key>map</key>
+ <type>int_vector</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ </source>
+</block>
diff --git a/gr-digital/grc/digital_packet_sink.xml b/gr-digital/grc/digital_packet_sink.xml
new file mode 100644
index 000000000..e9231bd05
--- /dev/null
+++ b/gr-digital/grc/digital_packet_sink.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## Packet Sink
+###################################################
+ -->
+<block>
+ <name>Packet Sink</name>
+ <key>digital_packet_sink</key>
+ <import>from gnuradio import digital</import>
+ <make>digital.packet_sink($sync_vector, $target_queue, $threshold)</make>
+ <param>
+ <name>Sync Vector</name>
+ <key>sync_vector</key>
+ <type>int_vector</type>
+ </param>
+ <param>
+ <name>Target Message Queue</name>
+ <key>target_queue</key>
+ <type>raw</type>
+ </param>
+ <param>
+ <name>Threshold</name>
+ <key>threshold</key>
+ <type>int</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>float</type>
+ </sink>
+</block>
diff --git a/gr-digital/grc/digital_pfb_clock_sync.xml b/gr-digital/grc/digital_pfb_clock_sync.xml
new file mode 100644
index 000000000..9e2a4cd5e
--- /dev/null
+++ b/gr-digital/grc/digital_pfb_clock_sync.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+## Polyphase Filter based Clock Sync
+###################################################
+ -->
+<block>
+ <name>Polyphase Clock Sync</name>
+ <key>digital_pfb_clock_sync_xxx</key>
+ <import>from gnuradio import digital</import>
+ <make>digital.pfb_clock_sync_$(type)($sps, $alpha, $taps, $filter_size, $init_phase, $max_dev, $osps)
+self.$(id).set_beta($beta)</make>
+ <callback>set_taps($taps)</callback>
+ <callback>set_alpha($alpha)</callback>
+ <callback>set_beta($beta)</callback>
+
+ <param>
+ <name>Type</name>
+ <key>type</key>
+ <type>enum</type>
+ <option>
+ <name>Complex->Complex (Real Taps)</name>
+ <key>ccf</key>
+ <opt>input:complex</opt>
+ <opt>output:complex</opt>
+ <opt>taps:real_vector</opt>
+ </option>
+ <option>
+ <name>Float->Float (Real Taps)</name>
+ <key>fff</key>
+ <opt>input:float</opt>
+ <opt>output:float</opt>
+ <opt>taps:real_vector</opt>
+ </option>
+ </param>
+
+ <param>
+ <name>Samples/Symbol</name>
+ <key>sps</key>
+ <type>real</type>
+ </param>
+ <param>
+ <name>Alpha</name>
+ <key>alpha</key>
+ <type>real</type>
+ </param>
+ <param>
+ <name>Beta</name>
+ <key>beta</key>
+ <type>real</type>
+ </param>
+ <param>
+ <name>Taps</name>
+ <key>taps</key>
+ <type>real_vector</type>
+ </param>
+ <param>
+ <name>Filter Size</name>
+ <key>filter_size</key>
+ <value>32</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Initial Phase</name>
+ <key>init_phase</key>
+ <value>16</value>
+ <type>real</type>
+ </param>
+ <param>
+ <name>Maximum Rate Deviation</name>
+ <key>max_dev</key>
+ <value>1.5</value>
+ <type>real</type>
+ </param>
+ <param>
+ <name>Output SPS</name>
+ <key>osps</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>$type.input</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>$type.output</type>
+ </source>
+ <source>
+ <name>err</name>
+ <type>float</type>
+ <optional>1</optional>
+ </source>
+ <source>
+ <name>rate</name>
+ <type>float</type>
+ <optional>1</optional>
+ </source>
+ <source>
+ <name>phase</name>
+ <type>float</type>
+ <optional>1</optional>
+ </source>
+</block>
diff --git a/gr-digital/grc/digital_pn_correlator_cc.xml b/gr-digital/grc/digital_pn_correlator_cc.xml
new file mode 100644
index 000000000..999cea15d
--- /dev/null
+++ b/gr-digital/grc/digital_pn_correlator_cc.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##PN Correlator
+###################################################
+ -->
+<block>
+ <name>PN Correlator</name>
+ <key>digital_pn_correlator_cc</key>
+ <import>from gnuradio import digital</import>
+ <make>digital.pn_correlator_cc($degree, $mask, $seed)</make>
+ <param>
+ <name>Degree</name>
+ <key>degree</key>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Mask</name>
+ <key>mask</key>
+ <value>0</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Seed</name>
+ <key>seed</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-digital/grc/digital_probe_density_b.xml b/gr-digital/grc/digital_probe_density_b.xml
new file mode 100644
index 000000000..8cf5dd894
--- /dev/null
+++ b/gr-digital/grc/digital_probe_density_b.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Probe Density
+###################################################
+ -->
+<block>
+ <name>Probe Density</name>
+ <key>digital_probe_density_b</key>
+ <import>from gnuradio import digital</import>
+ <make>digital.probe_density_b($alpha)</make>
+ <callback>set_alpha($alpha)</callback>
+ <param>
+ <name>Alpha</name>
+ <key>alpha</key>
+ <value>1</value>
+ <type>real</type>
+ </param>
+ <param>
+ <name>Probe Rate</name>
+ <key>probe_rate</key>
+ <value>10</value>
+ <type>real</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ </sink>
+</block>
diff --git a/gr-digital/grc/digital_scrambler_bb.xml b/gr-digital/grc/digital_scrambler_bb.xml
new file mode 100644
index 000000000..9c40b49f6
--- /dev/null
+++ b/gr-digital/grc/digital_scrambler_bb.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Descrambler
+###################################################
+ -->
+<block>
+ <name>Scrambler</name>
+ <key>digital_scrambler_bb</key>
+ <import>from gnuradio import digital</import>
+ <make>digital.scrambler_bb($mask, $seed, $len)</make>
+ <param>
+ <name>Mask</name>
+ <key>mask</key>
+ <value>0x8A</value>
+ <type>hex</type>
+ </param>
+ <param>
+ <name>Seed</name>
+ <key>seed</key>
+ <value>0x7F</value>
+ <type>hex</type>
+ </param>
+ <param>
+ <name>Length</name>
+ <key>len</key>
+ <value>7</value>
+ <type>int</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ </source>
+</block>
diff --git a/gr-digital/grc/digital_simple_framer.xml b/gr-digital/grc/digital_simple_framer.xml
new file mode 100644
index 000000000..bbeed32d3
--- /dev/null
+++ b/gr-digital/grc/digital_simple_framer.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Simple Framer
+###################################################
+ -->
+<block>
+ <name>Simple Framer</name>
+ <key>digital_simple_framer</key>
+ <import>from gnuradio import gr</import>
+ <make>gr.simple_framer($payload_bytesize)</make>
+ <param>
+ <name>Payload Byte Size</name>
+ <key>payload_bytesize</key>
+ <type>int</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>byte</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>byte</type>
+ </source>
+</block>
diff --git a/gr-digital/include/CMakeLists.txt b/gr-digital/include/CMakeLists.txt
index 81ed8d368..f863b2875 100644
--- a/gr-digital/include/CMakeLists.txt
+++ b/gr-digital/include/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright 2011 Free Software Foundation, Inc.
+# Copyright 2011,2012 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -17,25 +17,94 @@
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
+
+########################################################################
+# generate helper scripts to expand templated files
+########################################################################
+include(GrPython)
+
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py "
+#!${PYTHON_EXECUTABLE}
+
+import sys, os, re
+sys.path.append('${GR_CORE_PYTHONPATH}')
+os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
+os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
+
+if __name__ == '__main__':
+ import build_utils
+ root, inp = sys.argv[1:3]
+ for sig in sys.argv[3:]:
+ name = re.sub ('X+', sig, root)
+ d = build_utils.standard_dict(name, sig, 'digital')
+ build_utils.expand_template(d, inp)
+
+")
+
+macro(expand_h root)
+ #make a list of all the generated files
+ unset(expanded_files_h)
+ foreach(sig ${ARGN})
+ string(REGEX REPLACE "X+" ${sig} name ${root})
+ list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h)
+ endforeach(sig)
+
+ #create a command to generate the files
+ add_custom_command(
+ OUTPUT ${expanded_files_h}
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t
+ COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
+ ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
+ ${root} ${root}.h.t ${ARGN}
+ )
+
+ #install rules for the generated h files
+ list(APPEND generated_includes ${expanded_files_h})
+endmacro(expand_h)
+
+########################################################################
+# Invoke macro to generate various sources
+########################################################################
+expand_h(digital_chunks_to_symbols_XX bf bc sf sc if ic)
+
+add_custom_target(digital_generated_includes DEPENDS
+ ${generated_includes}
+)
+
########################################################################
# Install header files
########################################################################
install(FILES
+ ${generated_includes}
digital_api.h
+ digital_impl_glfsr.h
digital_impl_mpsk_snr_est.h
+ digital_additive_scrambler_bb.h
digital_binary_slicer_fb.h
+ digital_bytes_to_syms.h
digital_clock_recovery_mm_cc.h
digital_clock_recovery_mm_ff.h
+ digital_cma_equalizer_cc.h
+ digital_cpmmod_bc.h
digital_constellation.h
digital_constellation_receiver_cb.h
digital_constellation_decoder_cb.h
digital_correlate_access_code_bb.h
+ digital_correlate_access_code_tag_bb.h
digital_costas_loop_cc.h
- digital_cma_equalizer_cc.h
digital_crc32.h
+ digital_descrambler_bb.h
+ digital_diff_decoder_bb.h
+ digital_diff_encoder_bb.h
+ digital_diff_phasor_cc.h
+ digital_framer_sink_1.h
digital_fll_band_edge_cc.h
+ digital_glfsr_source_b.h
+ digital_glfsr_source_f.h
+ digital_gmskmod_bc.h
digital_lms_dd_equalizer_cc.h
digital_kurtotic_equalizer_cc.h
+ digital_map_bb.h
digital_metric_type.h
digital_mpsk_receiver_cc.h
digital_mpsk_snr_est_cc.h
@@ -45,9 +114,16 @@ install(FILES
digital_ofdm_insert_preamble.h
digital_ofdm_mapper_bcv.h
digital_ofdm_sampler.h
+ digital_packet_sink.h
+ digital_pfb_clock_sync_ccf.h
+ digital_pfb_clock_sync_fff.h
+ digital_pn_correlator_cc.h
+ digital_probe_density_b.h
digital_probe_mpsk_snr_est_c.h
- digital_gmskmod_bc.h
- digital_cpmmod_bc.h
+ digital_scrambler_bb.h
+ digital_simple_framer.h
+ digital_simple_framer_sync.h
DESTINATION ${GR_INCLUDE_DIR}/gnuradio
COMPONENT "digital_devel"
)
+
diff --git a/gr-digital/include/digital_additive_scrambler_bb.h b/gr-digital/include/digital_additive_scrambler_bb.h
new file mode 100644
index 000000000..d4bd7d4ae
--- /dev/null
+++ b/gr-digital/include/digital_additive_scrambler_bb.h
@@ -0,0 +1,73 @@
+/* -*- c++ -*- */
+/*
+ * 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 GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_GR_ADDITIVE_SCRAMBLER_BB_H
+#define INCLUDED_GR_ADDITIVE_SCRAMBLER_BB_H
+
+#include <digital_api.h>
+#include <gr_sync_block.h>
+#include <gri_lfsr.h>
+
+class digital_additive_scrambler_bb;
+typedef boost::shared_ptr<digital_additive_scrambler_bb> digital_additive_scrambler_bb_sptr;
+
+DIGITAL_API digital_additive_scrambler_bb_sptr
+digital_make_additive_scrambler_bb(int mask, int seed,
+ int len, int count=0);
+
+/*!
+ * Scramble an input stream using an LFSR. This block works on the LSB only
+ * of the input data stream, i.e., on an "unpacked binary" stream, and
+ * produces the same format on its output.
+ *
+ * \param mask Polynomial mask for LFSR
+ * \param seed Initial shift register contents
+ * \param len Shift register length
+ * \param count Number of bits after which shift register is reset, 0=never
+ *
+ * The scrambler works by XORing the incoming bit stream by the output of
+ * the LFSR. Optionally, after 'count' bits have been processed, the shift
+ * register is reset to the seed value. This allows processing fixed length
+ * vectors of samples.
+ *
+ * \ingroup coding_blk
+ */
+
+class DIGITAL_API digital_additive_scrambler_bb : public gr_sync_block
+{
+ friend DIGITAL_API digital_additive_scrambler_bb_sptr
+ digital_make_additive_scrambler_bb(int mask, int seed,
+ int len, int count);
+
+ gri_lfsr d_lfsr;
+ int d_count;
+ int d_bits;
+
+ digital_additive_scrambler_bb(int mask, int seed,
+ int len, int count);
+
+public:
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_ADDITIVE_SCRAMBLER_BB_H */
diff --git a/gr-digital/include/digital_bytes_to_syms.h b/gr-digital/include/digital_bytes_to_syms.h
new file mode 100644
index 000000000..3062366b9
--- /dev/null
+++ b/gr-digital/include/digital_bytes_to_syms.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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.
+ */
+#ifndef INCLUDED_GR_BYTES_TO_SYMS_H
+#define INCLUDED_GR_BYTES_TO_SYMS_H
+
+#include <digital_api.h>
+#include <gr_sync_interpolator.h>
+
+class digital_bytes_to_syms;
+typedef boost::shared_ptr<digital_bytes_to_syms> digital_bytes_to_syms_sptr;
+
+DIGITAL_API digital_bytes_to_syms_sptr digital_make_bytes_to_syms();
+
+/*!
+ * \brief Convert stream of bytes to stream of +/- 1 symbols
+ * \ingroup converter_blk
+ *
+ * input: stream of bytes; output: stream of float
+ *
+ * This block is deprecated.
+ *
+ * The combination of gr_packed_to_unpacked_bb followed by
+ * gr_chunks_to_symbols_bf or gr_chunks_to_symbols_bc handles the
+ * general case of mapping from a stream of bytes into arbitrary float
+ * or complex symbols.
+ *
+ * \sa gr_packed_to_unpacked_bb, gr_unpacked_to_packed_bb,
+ * \sa gr_chunks_to_symbols_bf, gr_chunks_to_symbols_bc.
+ */
+class DIGITAL_API digital_bytes_to_syms : public gr_sync_interpolator
+{
+ friend DIGITAL_API digital_bytes_to_syms_sptr
+ digital_make_bytes_to_syms();
+
+ digital_bytes_to_syms();
+
+ public:
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_BYTES_TO_SYMS_H */
diff --git a/gr-digital/include/digital_chunks_to_symbols_XX.h.t b/gr-digital/include/digital_chunks_to_symbols_XX.h.t
new file mode 100644
index 000000000..92b7c94d5
--- /dev/null
+++ b/gr-digital/include/digital_chunks_to_symbols_XX.h.t
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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.
+ */
+
+// @WARNING@
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
+
+#include <digital_api.h>
+#include <gr_sync_interpolator.h>
+
+class @NAME@;
+typedef boost::shared_ptr<@NAME@> @SPTR_NAME@;
+
+DIGITAL_API @SPTR_NAME@
+digital_make_@BASE_NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D = 1);
+
+/*!
+ * \brief Map a stream of symbol indexes (unpacked bytes or shorts) to stream of float or complex constellation points in D dimensions (D = 1 by default)
+ * \ingroup converter_blk
+ *
+ * input: stream of @I_TYPE@; output: stream of @O_TYPE@
+ *
+ * out[n D + k] = symbol_table[in[n] D + k], k=0,1,...,D-1
+ *
+ * The combination of gr_packed_to_unpacked_XX followed by
+ * gr_chunks_to_symbols_XY handles the general case of mapping
+ * from a stream of bytes or shorts into arbitrary float
+ * or complex symbols.
+ *
+ * \sa gr_packed_to_unpacked_bb, gr_unpacked_to_packed_bb,
+ * \sa gr_packed_to_unpacked_ss, gr_unpacked_to_packed_ss,
+ * \sa digital_chunks_to_symbols_bf, digital_chunks_to_symbols_bc.
+ * \sa digital_chunks_to_symbols_sf, digital_chunks_to_symbols_sc.
+ */
+
+class DIGITAL_API @NAME@ : public gr_sync_interpolator
+{
+ friend DIGITAL_API @SPTR_NAME@ digital_make_@BASE_NAME@
+ (const std::vector<@O_TYPE@> &symbol_table, const int D);
+
+ int d_D;
+ std::vector<@O_TYPE@> d_symbol_table;
+ @NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D = 1);
+
+ public:
+ int D () const { return d_D; }
+ std::vector<@O_TYPE@> symbol_table () const { return d_symbol_table; }
+ int work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ bool check_topology(int ninputs, int noutputs) { return ninputs == noutputs; }
+};
+
+#endif
diff --git a/gr-digital/include/digital_correlate_access_code_tag_bb.h b/gr-digital/include/digital_correlate_access_code_tag_bb.h
new file mode 100644
index 000000000..b4a12108f
--- /dev/null
+++ b/gr-digital/include/digital_correlate_access_code_tag_bb.h
@@ -0,0 +1,89 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2006,2011,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.
+ */
+
+#ifndef INCLUDED_digital_correlate_access_code_tag_bb_H
+#define INCLUDED_digital_correlate_access_code_tag_bb_H
+
+#include <digital_api.h>
+#include <gr_sync_block.h>
+#include <string>
+
+class digital_correlate_access_code_tag_bb;
+typedef boost::shared_ptr<digital_correlate_access_code_tag_bb> digital_correlate_access_code_tag_bb_sptr;
+
+/*!
+ * \param access_code is represented with 1 byte per bit, e.g., "010101010111000100"
+ * \param threshold maximum number of bits that may be wrong
+ * \param tag_name key of the tag inserted into the tag stream
+ */
+DIGITAL_API digital_correlate_access_code_tag_bb_sptr
+digital_make_correlate_access_code_tag_bb(const std::string &access_code,
+ int threshold,
+ const std::string &tag_name);
+
+/*!
+ * \brief Examine input for specified access code, one bit at a time.
+ * \ingroup sync_blk
+ *
+ * input: stream of bits, 1 bit per input byte (data in LSB)
+ * output: unaltered stream of bits (plus tags)
+ *
+ * This block annotates the input stream with tags. The tags have key
+ * name [tag_name], specified in the constructor. Used for searching
+ * an input data stream for preambles, etc.
+ */
+class DIGITAL_API digital_correlate_access_code_tag_bb : public gr_sync_block
+{
+ friend DIGITAL_API digital_correlate_access_code_tag_bb_sptr
+ digital_make_correlate_access_code_tag_bb(const std::string &access_code,
+ int threshold,
+ const std::string &tag_name);
+ private:
+ unsigned long long d_access_code; // access code to locate start of packet
+ // access code is left justified in the word
+ unsigned long long d_data_reg; // used to look for access_code
+ unsigned long long d_mask; // masks access_code bits (top N bits are set where
+ // N is the number of bits in the access code)
+ unsigned int d_threshold; // how many bits may be wrong in sync vector
+ unsigned int d_len; // the length of the access code
+
+ pmt::pmt_t d_key, d_me; //d_key is the tag name, d_me is the block name + unique ID
+
+ protected:
+ digital_correlate_access_code_tag_bb(const std::string &access_code,
+ int threshold,
+ const std::string &tag_name);
+
+ public:
+ ~digital_correlate_access_code_tag_bb();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ /*!
+ * \param access_code is represented with 1 byte per bit, e.g., "010101010111000100"
+ */
+ bool set_access_code(const std::string &access_code);
+};
+
+#endif /* INCLUDED_digital_correlate_access_code_tag_bb_H */
diff --git a/gr-digital/include/digital_cpmmod_bc.h b/gr-digital/include/digital_cpmmod_bc.h
index 332856afc..f0f11ee30 100644
--- a/gr-digital/include/digital_cpmmod_bc.h
+++ b/gr-digital/include/digital_cpmmod_bc.h
@@ -74,9 +74,10 @@ digital_make_cpmmod_bc(int type, float h,
*/
class DIGITAL_API digital_cpmmod_bc : public gr_hier_block2
{
- friend DIGITAL_API digital_cpmmod_bc_sptr digital_make_cpmmod_bc(int type, float h,
- unsigned samples_per_sym,
- unsigned L, double beta);
+ friend DIGITAL_API digital_cpmmod_bc_sptr
+ digital_make_cpmmod_bc(int type, float h,
+ unsigned samples_per_sym,
+ unsigned L, double beta);
std::vector<float> d_taps;
gr_char_to_float_sptr d_char_to_float;
diff --git a/gr-digital/include/digital_descrambler_bb.h b/gr-digital/include/digital_descrambler_bb.h
new file mode 100644
index 000000000..b719803f3
--- /dev/null
+++ b/gr-digital/include/digital_descrambler_bb.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,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.
+ */
+#ifndef INCLUDED_GR_DESCRAMBLER_BB_H
+#define INCLUDED_GR_DESCRAMBLER_BB_H
+
+#include <digital_api.h>
+#include <gr_sync_block.h>
+#include "gri_lfsr.h"
+
+class digital_descrambler_bb;
+typedef boost::shared_ptr<digital_descrambler_bb> digital_descrambler_bb_sptr;
+
+DIGITAL_API digital_descrambler_bb_sptr
+digital_make_descrambler_bb(int mask, int seed, int len);
+
+/*!
+ * Descramble an input stream using an LFSR. This block works on the LSB only
+ * of the input data stream, i.e., on an "unpacked binary" stream, and
+ * produces the same format on its output.
+ *
+ * \param mask Polynomial mask for LFSR
+ * \param seed Initial shift register contents
+ * \param len Shift register length
+ *
+ * \ingroup coding_blk
+ */
+
+class DIGITAL_API digital_descrambler_bb : public gr_sync_block
+{
+ friend DIGITAL_API digital_descrambler_bb_sptr
+ digital_make_descrambler_bb(int mask, int seed, int len);
+
+ gri_lfsr d_lfsr;
+
+ digital_descrambler_bb(int mask, int seed, int len);
+
+public:
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_DESCRAMBLER_BB_H */
diff --git a/gr-digital/include/digital_diff_decoder_bb.h b/gr-digital/include/digital_diff_decoder_bb.h
new file mode 100644
index 000000000..928035d0e
--- /dev/null
+++ b/gr-digital/include/digital_diff_decoder_bb.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,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.
+ */
+
+#ifndef INCLUDED_GR_DIFF_DECODER_BB_H
+#define INCLUDED_GR_DIFF_DECODER_BB_H
+
+#include <digital_api.h>
+#include <gr_sync_block.h>
+
+class digital_diff_decoder_bb;
+typedef boost::shared_ptr<digital_diff_decoder_bb> digital_diff_decoder_bb_sptr;
+
+DIGITAL_API digital_diff_decoder_bb_sptr
+digital_make_diff_decoder_bb(unsigned int modulus);
+
+/*!
+ * \brief y[0] = (x[0] - x[-1]) % M
+ * \ingroup coding_blk
+ *
+ * Uses current and previous symbols and the alphabet modulus to
+ * perform differential decoding.
+ */
+class DIGITAL_API digital_diff_decoder_bb : public gr_sync_block
+{
+ friend DIGITAL_API digital_diff_decoder_bb_sptr
+ digital_make_diff_decoder_bb(unsigned int modulus);
+ digital_diff_decoder_bb(unsigned int modulus);
+
+ unsigned int d_modulus;
+
+ public:
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gr-digital/include/digital_diff_encoder_bb.h b/gr-digital/include/digital_diff_encoder_bb.h
new file mode 100644
index 000000000..d4be69cad
--- /dev/null
+++ b/gr-digital/include/digital_diff_encoder_bb.h
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,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.
+ */
+
+#ifndef INCLUDED_GR_DIFF_ENCODER_BB_H
+#define INCLUDED_GR_DIFF_ENCODER_BB_H
+
+#include <digital_api.h>
+#include <gr_sync_block.h>
+
+class digital_diff_encoder_bb;
+typedef boost::shared_ptr<digital_diff_encoder_bb> digital_diff_encoder_bb_sptr;
+
+DIGITAL_API digital_diff_encoder_bb_sptr
+digital_make_diff_encoder_bb(unsigned int modulus);
+
+/*!
+ * \brief y[0] = (x[0] + y[-1]) % M
+ * \ingroup coding_blk
+ *
+ * Uses current and previous symbols and the alphabet modulus to
+ * perform differential encoding.
+ */
+class DIGITAL_API digital_diff_encoder_bb : public gr_sync_block
+{
+ friend DIGITAL_API digital_diff_encoder_bb_sptr
+ digital_make_diff_encoder_bb(unsigned int modulus);
+ digital_diff_encoder_bb(unsigned int modulus);
+
+ unsigned int d_last_out;
+ unsigned int d_modulus;
+
+ public:
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gr-digital/include/digital_diff_phasor_cc.h b/gr-digital/include/digital_diff_phasor_cc.h
new file mode 100644
index 000000000..32a2464b2
--- /dev/null
+++ b/gr-digital/include/digital_diff_phasor_cc.h
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,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.
+ */
+
+#ifndef INCLUDED_GR_DIFF_PHASOR_CC_H
+#define INCLUDED_GR_DIFF_PHASOR_CC_H
+
+#include <digital_api.h>
+#include <gr_sync_block.h>
+
+/*!
+ * \brief Differential decoding based on phase change.
+ * \ingroup coding_blk
+ *
+ * Uses the phase difference between two symbols to determine the
+ * output symbol:
+ *
+ * out[i] = in[i] * conj(in[i-1]);
+ */
+class digital_diff_phasor_cc;
+typedef boost::shared_ptr<digital_diff_phasor_cc> digital_diff_phasor_cc_sptr;
+
+DIGITAL_API digital_diff_phasor_cc_sptr digital_make_diff_phasor_cc();
+
+
+class DIGITAL_API digital_diff_phasor_cc : public gr_sync_block
+{
+ friend DIGITAL_API digital_diff_phasor_cc_sptr
+ digital_make_diff_phasor_cc();
+
+ digital_diff_phasor_cc(); //constructor
+
+ public:
+ ~digital_diff_phasor_cc(); //destructor
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gr-digital/include/digital_framer_sink_1.h b/gr-digital/include/digital_framer_sink_1.h
new file mode 100644
index 000000000..bb82bf5a7
--- /dev/null
+++ b/gr-digital/include/digital_framer_sink_1.h
@@ -0,0 +1,107 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2006,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.
+ */
+
+#ifndef INCLUDED_GR_FRAMER_SINK_1_H
+#define INCLUDED_GR_FRAMER_SINK_1_H
+
+#include <digital_api.h>
+#include <gr_sync_block.h>
+#include <gr_msg_queue.h>
+
+class digital_framer_sink_1;
+typedef boost::shared_ptr<digital_framer_sink_1> digital_framer_sink_1_sptr;
+
+DIGITAL_API digital_framer_sink_1_sptr
+digital_make_framer_sink_1(gr_msg_queue_sptr target_queue);
+
+/*!
+ * \brief Given a stream of bits and access_code flags, assemble packets.
+ * \ingroup sink_blk
+ *
+ * input: stream of bytes from gr_correlate_access_code_bb
+ * output: none. Pushes assembled packet into target queue
+ *
+ * The framer expects a fixed length header of 2 16-bit shorts
+ * containing the payload length, followed by the payload. If the
+ * 2 16-bit shorts are not identical, this packet is ignored. Better
+ * algs are welcome.
+ *
+ * The input data consists of bytes that have two bits used.
+ * Bit 0, the LSB, contains the data bit.
+ * Bit 1 if set, indicates that the corresponding bit is the
+ * the first bit of the packet. That is, this bit is the first
+ * one after the access code.
+ */
+class DIGITAL_API digital_framer_sink_1 : public gr_sync_block
+{
+ friend DIGITAL_API digital_framer_sink_1_sptr
+ digital_make_framer_sink_1(gr_msg_queue_sptr target_queue);
+
+ private:
+ enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER};
+
+ static const int MAX_PKT_LEN = 4096;
+ static const int HEADERBITLEN = 32;
+
+ gr_msg_queue_sptr d_target_queue; // where to send the packet when received
+ state_t d_state;
+ unsigned int d_header; // header bits
+ int d_headerbitlen_cnt; // how many so far
+
+ unsigned char d_packet[MAX_PKT_LEN]; // assembled payload
+ unsigned char d_packet_byte; // byte being assembled
+ int d_packet_byte_index; // which bit of d_packet_byte we're working on
+ int d_packetlen; // length of packet
+ int d_packet_whitener_offset; // offset into whitener string to use
+ int d_packetlen_cnt; // how many so far
+
+ protected:
+ digital_framer_sink_1(gr_msg_queue_sptr target_queue);
+
+ void enter_search();
+ void enter_have_sync();
+ void enter_have_header(int payload_len, int whitener_offset);
+
+ bool header_ok()
+ {
+ // confirm that two copies of header info are identical
+ return ((d_header >> 16) ^ (d_header & 0xffff)) == 0;
+ }
+
+ void header_payload(int *len, int *offset)
+ {
+ // header consists of two 16-bit shorts in network byte order
+ // payload length is lower 12 bits
+ // whitener offset is upper 4 bits
+ *len = (d_header >> 16) & 0x0fff;
+ *offset = (d_header >> 28) & 0x000f;
+ }
+
+ public:
+ ~digital_framer_sink_1();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_FRAMER_SINK_1_H */
diff --git a/gr-digital/include/digital_glfsr_source_b.h b/gr-digital/include/digital_glfsr_source_b.h
new file mode 100644
index 000000000..92e5e81f5
--- /dev/null
+++ b/gr-digital/include/digital_glfsr_source_b.h
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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.
+ */
+
+#ifndef INCLUDED_GR_GLFSR_SOURCE_B_H
+#define INCLUDED_GR_GLFSR_SOURCE_B_H
+
+#include <digital_api.h>
+#include <gr_sync_block.h>
+
+class gri_glfsr;
+
+class digital_glfsr_source_b;
+typedef boost::shared_ptr<digital_glfsr_source_b> digital_glfsr_source_b_sptr;
+
+DIGITAL_API digital_glfsr_source_b_sptr
+digital_make_glfsr_source_b(int degree, bool repeat=true,
+ int mask=0, int seed=1);
+
+/*!
+ * \brief Galois LFSR pseudo-random source
+ * \ingroup source_blk
+ *
+ * \param degree Degree of shift register must be in [1, 32]. If mask
+ * is 0, the degree determines a default mask (see
+ * digital_impl_glfsr.cc for the mapping).
+ * \param repeat Set to repeat sequence.
+ * \param mask Allows a user-defined bit mask for indexes of the shift
+ * register to feed back.
+ * \param seed Initial setting for values in shift register.
+ */
+class DIGITAL_API digital_glfsr_source_b : public gr_sync_block
+{
+ private:
+ friend DIGITAL_API digital_glfsr_source_b_sptr
+ digital_make_glfsr_source_b(int degree, bool repeat,
+ int mask, int seed);
+
+ gri_glfsr *d_glfsr;
+
+ bool d_repeat;
+ unsigned int d_index;
+ unsigned int d_length;
+
+ digital_glfsr_source_b(int degree, bool repeat,
+ int mask, int seed);
+
+ public:
+
+ ~digital_glfsr_source_b();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ unsigned int period() const { return d_length; }
+ int mask() const;
+};
+
+#endif /* INCLUDED_GR_GLFSR_SOURCE_B_H */
diff --git a/gr-digital/include/digital_glfsr_source_f.h b/gr-digital/include/digital_glfsr_source_f.h
new file mode 100644
index 000000000..77d7b0f74
--- /dev/null
+++ b/gr-digital/include/digital_glfsr_source_f.h
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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.
+ */
+
+#ifndef INCLUDED_GR_GLFSR_SOURCE_F_H
+#define INCLUDED_GR_GLFSR_SOURCE_F_H
+
+#include <digital_api.h>
+#include <gr_sync_block.h>
+
+class gri_glfsr;
+
+class digital_glfsr_source_f;
+typedef boost::shared_ptr<digital_glfsr_source_f> digital_glfsr_source_f_sptr;
+
+DIGITAL_API digital_glfsr_source_f_sptr
+digital_make_glfsr_source_f(int degree, bool repeat=true,
+ int mask=0, int seed=1);
+
+/*!
+ * \brief Galois LFSR pseudo-random source generating float outputs -1.0 - 1.0.
+ * \ingroup source_blk
+ *
+ * \param degree Degree of shift register must be in [1, 32]. If mask
+ * is 0, the degree determines a default mask (see
+ * digital_impl_glfsr.cc for the mapping).
+ * \param repeat Set to repeat sequence.
+ * \param mask Allows a user-defined bit mask for indexes of the shift
+ * register to feed back.
+ * \param seed Initial setting for values in shift register.
+ */
+class DIGITAL_API digital_glfsr_source_f : public gr_sync_block
+{
+ private:
+ friend DIGITAL_API digital_glfsr_source_f_sptr
+ digital_make_glfsr_source_f(int degree, bool repeat,
+ int mask, int seed);
+
+ gri_glfsr *d_glfsr;
+
+ bool d_repeat;
+ unsigned int d_index;
+ unsigned int d_length;
+
+ digital_glfsr_source_f(int degree, bool repeat,
+ int mask, int seed);
+
+ public:
+
+ ~digital_glfsr_source_f();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ unsigned int period() const { return d_length; }
+ int mask() const;
+};
+
+#endif /* INCLUDED_GR_GLFSR_SOURCE_F_H */
diff --git a/gr-digital/include/digital_impl_glfsr.h b/gr-digital/include/digital_impl_glfsr.h
new file mode 100644
index 000000000..3aadf7cf2
--- /dev/null
+++ b/gr-digital/include/digital_impl_glfsr.h
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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.
+ */
+
+#ifndef INCLUDED_DIGITAL_IMPL_GLFSR_H
+#define INCLUDED_DIGITAL_IMPL_GLFSR_H
+
+#include <digital_api.h>
+
+/*!
+ * \brief Galois Linear Feedback Shift Register using specified polynomial mask
+ * \ingroup misc
+ *
+ * Generates a maximal length pseudo-random sequence of length 2^degree-1
+ */
+
+class DIGITAL_API digital_impl_glfsr
+{
+ private:
+ int d_shift_register;
+ int d_mask;
+
+ public:
+
+ digital_impl_glfsr(int mask, int seed) { d_shift_register = seed; d_mask = mask; }
+ static int glfsr_mask(int degree);
+
+ unsigned char next_bit() {
+ unsigned char bit = d_shift_register & 1;
+ d_shift_register >>= 1;
+ if (bit)
+ d_shift_register ^= d_mask;
+ return bit;
+ }
+
+ int mask() const { return d_mask; }
+};
+
+#endif /* INCLUDED_DIGITAL_IMPL_GLFSR_H */
diff --git a/gr-digital/include/digital_map_bb.h b/gr-digital/include/digital_map_bb.h
new file mode 100644
index 000000000..4aca66fbe
--- /dev/null
+++ b/gr-digital/include/digital_map_bb.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,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.
+ */
+#ifndef INCLUDED_GR_MAP_BB_H
+#define INCLUDED_GR_MAP_BB_H
+
+#include <digital_api.h>
+#include <gr_sync_block.h>
+
+class digital_map_bb;
+typedef boost::shared_ptr<digital_map_bb> digital_map_bb_sptr;
+
+DIGITAL_API digital_map_bb_sptr
+digital_make_map_bb(const std::vector<int> &map);
+
+/*!
+ * \brief output[i] = map[input[i]]
+ * \ingroup coding_blk
+ *
+ * This block maps an incoming signal to the value in the map.
+ * The block expects that the incoming signal has a maximum
+ * value of len(map)-1.
+ *
+ * -> output[i] = map[input[i]]
+ *
+ * \param map a vector of integers.
+ */
+
+class DIGITAL_API digital_map_bb : public gr_sync_block
+{
+ friend DIGITAL_API digital_map_bb_sptr
+ digital_make_map_bb(const std::vector<int> &map);
+
+ unsigned char d_map[0x100];
+
+ digital_map_bb(const std::vector<int> &map);
+
+public:
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_MAP_BB_H */
diff --git a/gr-digital/include/digital_packet_sink.h b/gr-digital/include/digital_packet_sink.h
new file mode 100644
index 000000000..7ab41c0ef
--- /dev/null
+++ b/gr-digital/include/digital_packet_sink.h
@@ -0,0 +1,131 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,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.
+ */
+
+#ifndef INCLUDED_GR_PACKET_SINK_H
+#define INCLUDED_GR_PACKET_SINK_H
+
+#include <digital_api.h>
+#include <gr_sync_block.h>
+#include <gr_msg_queue.h>
+
+class digital_packet_sink;
+typedef boost::shared_ptr<digital_packet_sink> digital_packet_sink_sptr;
+
+DIGITAL_API digital_packet_sink_sptr
+digital_make_packet_sink(const std::vector<unsigned char>& sync_vector,
+ gr_msg_queue_sptr target_queue,
+ int threshold = -1); // -1 -> use default
+
+/*!
+ * \brief process received bits looking for packet sync, header, and process bits into packet
+ * \ingroup sink_blk
+ *
+ * input: stream of symbols to be sliced.
+ *
+ * output: none. Pushes assembled packet into target queue
+ *
+ * The packet sink takes in a stream of binary symbols that are sliced
+ * around 0. The bits are then checked for the \p sync_vector to
+ * determine find and decode the packet. It then expects a fixed
+ * length header of 2 16-bit shorts containing the payload length,
+ * followed by the payload. If the 2 16-bit shorts are not identical,
+ * this packet is ignored. Better algs are welcome.
+ *
+ * This block is not very useful anymore as it only works with 2-level
+ * modulations such as BPSK or GMSK. The block can generally be
+ * replaced with a correlate access code and frame sink blocks.
+ *
+ * \param sync_vector The synchronization vector as a vector of 1's and 0's.
+ * \param target_queue The message queue that packets are sent to.
+ * \param threshold Number of bits that can be incorrect in the \p sync_vector.
+ */
+class DIGITAL_API digital_packet_sink : public gr_sync_block
+{
+ friend DIGITAL_API digital_packet_sink_sptr
+ digital_make_packet_sink(const std::vector<unsigned char>& sync_vector,
+ gr_msg_queue_sptr target_queue,
+ int threshold);
+
+ private:
+ enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER};
+
+ static const int MAX_PKT_LEN = 4096;
+ static const int HEADERBITLEN = 32;
+
+ gr_msg_queue_sptr d_target_queue; // where to send the packet when received
+ unsigned long long d_sync_vector; // access code to locate start of packet
+ unsigned int d_threshold; // how many bits may be wrong in sync vector
+
+ state_t d_state;
+
+ unsigned long long d_shift_reg; // used to look for sync_vector
+
+ unsigned int d_header; // header bits
+ int d_headerbitlen_cnt; // how many so far
+
+ unsigned char d_packet[MAX_PKT_LEN]; // assembled payload
+ unsigned char d_packet_byte; // byte being assembled
+ int d_packet_byte_index; // which bit of d_packet_byte we're working on
+ int d_packetlen; // length of packet
+ int d_packetlen_cnt; // how many so far
+
+ protected:
+ digital_packet_sink(const std::vector<unsigned char>& sync_vector,
+ gr_msg_queue_sptr target_queue,
+ int threshold);
+
+ void enter_search();
+ void enter_have_sync();
+ void enter_have_header(int payload_len);
+
+ int slice(float x) { return x > 0 ? 1 : 0; }
+
+ bool header_ok()
+ {
+ // confirm that two copies of header info are identical
+ return ((d_header >> 16) ^ (d_header & 0xffff)) == 0;
+ }
+
+ int header_payload_len()
+ {
+ // header consists of two 16-bit shorts in network byte order
+ int t = (d_header >> 16) & 0xffff;
+ return t;
+ }
+
+ public:
+ ~digital_packet_sink();
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+
+ //! return true if we detect carrier
+ bool carrier_sensed() const
+ {
+ return d_state != STATE_SYNC_SEARCH;
+ }
+
+};
+
+#endif /* INCLUDED_GR_PACKET_SINK_H */
diff --git a/gr-digital/include/digital_pfb_clock_sync_ccf.h b/gr-digital/include/digital_pfb_clock_sync_ccf.h
new file mode 100644
index 000000000..f7996d175
--- /dev/null
+++ b/gr-digital/include/digital_pfb_clock_sync_ccf.h
@@ -0,0 +1,376 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,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.
+ */
+
+
+#ifndef INCLUDED_DIGITAL_PFB_CLOCK_SYNC_CCF_H
+#define INCLUDED_DIGITAL_PFB_CLOCK_SYNC_CCF_H
+
+#include <digital_api.h>
+#include <gr_block.h>
+
+class digital_pfb_clock_sync_ccf;
+typedef boost::shared_ptr<digital_pfb_clock_sync_ccf> digital_pfb_clock_sync_ccf_sptr;
+DIGITAL_API digital_pfb_clock_sync_ccf_sptr
+digital_make_pfb_clock_sync_ccf(double sps, float loop_bw,
+ const std::vector<float> &taps,
+ unsigned int filter_size=32,
+ float init_phase=0,
+ float max_rate_deviation=1.5,
+ int osps=1);
+
+class gr_fir_ccf;
+
+/*!
+ * \class digital_pfb_clock_sync_ccf
+ *
+ * \brief Timing synchronizer using polyphase filterbanks
+ *
+ * \ingroup filter_blk
+ * \ingroup pfb_blk
+ *
+ * This block performs timing synchronization for PAM signals by
+ * minimizing the derivative of the filtered signal, which in turn
+ * maximizes the SNR and minimizes ISI.
+ *
+ * This approach works by setting up two filterbanks; one filterbank
+ * contains the signal's pulse shaping matched filter (such as a root
+ * raised cosine filter), where each branch of the filterbank contains
+ * a different phase of the filter. The second filterbank contains
+ * the derivatives of the filters in the first filterbank. Thinking of
+ * this in the time domain, the first filterbank contains filters that
+ * have a sinc shape to them. We want to align the output signal to be
+ * sampled at exactly the peak of the sinc shape. The derivative of
+ * the sinc contains a zero at the maximum point of the sinc (sinc(0)
+ * = 1, sinc(0)' = 0). Furthermore, the region around the zero point
+ * is relatively linear. We make use of this fact to generate the
+ * error signal.
+ *
+ * If the signal out of the derivative filters is d_i[n] for the ith
+ * filter, and the output of the matched filter is x_i[n], we
+ * calculate the error as: e[n] = (Re{x_i[n]} * Re{d_i[n]} +
+ * Im{x_i[n]} * Im{d_i[n]}) / 2.0 This equation averages the error in
+ * the real and imaginary parts. There are two reasons we multiply by
+ * the signal itself. First, if the symbol could be positive or
+ * negative going, but we want the error term to always tell us to go
+ * in the same direction depending on which side of the zero point we
+ * are on. The sign of x_i[n] adjusts the error term to do
+ * this. Second, the magnitude of x_i[n] scales the error term
+ * depending on the symbol's amplitude, so larger signals give us a
+ * stronger error term because we have more confidence in that
+ * symbol's value. Using the magnitude of x_i[n] instead of just the
+ * sign is especially good for signals with low SNR.
+ *
+ * The error signal, e[n], gives us a value proportional to how far
+ * away from the zero point we are in the derivative signal. We want
+ * to drive this value to zero, so we set up a second order loop. We
+ * have two variables for this loop; d_k is the filter number in the
+ * filterbank we are on and d_rate is the rate which we travel through
+ * the filters in the steady state. That is, due to the natural clock
+ * differences between the transmitter and receiver, d_rate represents
+ * that difference and would traverse the filter phase paths to keep
+ * the receiver locked. Thinking of this as a second-order PLL, the
+ * d_rate is the frequency and d_k is the phase. So we update d_rate
+ * and d_k using the standard loop equations based on two error
+ * signals, d_alpha and d_beta. We have these two values set based on
+ * each other for a critically damped system, so in the block
+ * constructor, we just ask for "gain," which is d_alpha while d_beta
+ * is equal to (gain^2)/4.
+ *
+ * The block's parameters are:
+ *
+ * \li \p sps: The clock sync block needs to know the number of samples per
+ * symbol, because it defaults to return a single point representing
+ * the symbol. The sps can be any positive real number and does not
+ * need to be an integer.
+ *
+ * \li \p loop_bw: The loop bandwidth is used to set the gain of the
+ * inner control loop (see:
+ * http://gnuradio.squarespace.com/blog/2011/8/13/control-loop-gain-values.html).
+ * This should be set small (a value of around 2pi/100 is suggested in
+ * that blog post as the step size for the number of radians around
+ * the unit circle to move relative to the error).
+ *
+ * \li \p taps: One of the most important parameters for this block is
+ * the taps of the filter. One of the benefits of this algorithm is
+ * that you can put the matched filter in here as the taps, so you get
+ * both the matched filter and sample timing correction in one go. So
+ * create your normal matched filter. For a typical digital
+ * modulation, this is a root raised cosine filter. The number of taps
+ * of this filter is based on how long you expect the channel to be;
+ * that is, how many symbols do you want to combine to get the current
+ * symbols energy back (there's probably a better way of stating
+ * that). It's usually 5 to 10 or so. That gives you your filter, but
+ * now we need to think about it as a filter with different phase
+ * profiles in each filter. So take this number of taps and multiply
+ * it by the number of filters. This is the number you would use to
+ * create your prototype filter. When you use this in the PFB
+ * filerbank, it segments these taps into the filterbanks in such a
+ * way that each bank now represents the filter at different phases,
+ * equally spaced at 2pi/N, where N is the number of filters.
+ *
+ * \li \p filter_size (default=32): The number of filters can also be
+ * set and defaults to 32. With 32 filters, you get a good enough
+ * resolution in the phase to produce very small, almost unnoticeable,
+ * ISI. Going to 64 filters can reduce this more, but after that
+ * there is very little gained for the extra complexity.
+ *
+ * \li \p init_phase (default=0): The initial phase is another
+ * settable parameter and refers to the filter path the algorithm
+ * initially looks at (i.e., d_k starts at init_phase). This value
+ * defaults to zero, but it might be useful to start at a different
+ * phase offset, such as the mid-point of the filters.
+ *
+ * \li \p max_rate_deviation (default=1.5): The next parameter is the
+ * max_rate_devitation, which defaults to 1.5. This is how far we
+ * allow d_rate to swing, positive or negative, from 0. Constraining
+ * the rate can help keep the algorithm from walking too far away to
+ * lock during times when there is no signal.
+ *
+ * \li \p osps (default=1): The osps is the number of output samples per symbol. By default,
+ * the algorithm produces 1 sample per symbol, sampled at the exact
+ * sample value. This osps value was added to better work with
+ * equalizers, which do a better job of modeling the channel if they
+ * have 2 samps/sym.
+ */
+
+class GR_CORE_API digital_pfb_clock_sync_ccf : public gr_block
+{
+ private:
+ /*!
+ * Build the polyphase filterbank timing synchronizer.
+ * \param sps (double) The number of samples per symbol in the incoming signal
+ * \param loop_bw (float) The bandwidth of the control loop; set's alpha and beta.
+ * \param taps (vector<int>) The filter taps.
+ * \param filter_size (uint) The number of filters in the filterbank (default = 32).
+ * \param init_phase (float) The initial phase to look at, or which filter to start
+ * with (default = 0).
+ * \param max_rate_deviation (float) Distance from 0 d_rate can get (default = 1.5).
+ * \param osps (int) The number of output samples per symbol (default=1).
+ *
+ */
+ friend DIGITAL_API digital_pfb_clock_sync_ccf_sptr
+ digital_make_pfb_clock_sync_ccf(double sps, float loop_bw,
+ const std::vector<float> &taps,
+ unsigned int filter_size,
+ float init_phase,
+ float max_rate_deviation,
+ int osps);
+
+ bool d_updated;
+ double d_sps;
+ double d_sample_num;
+ float d_loop_bw;
+ float d_damping;
+ float d_alpha;
+ float d_beta;
+
+ int d_nfilters;
+ int d_taps_per_filter;
+ std::vector<gr_fir_ccf*> d_filters;
+ std::vector<gr_fir_ccf*> d_diff_filters;
+ std::vector< std::vector<float> > d_taps;
+ std::vector< std::vector<float> > d_dtaps;
+
+ float d_k;
+ float d_rate;
+ float d_rate_i;
+ float d_rate_f;
+ float d_max_dev;
+ int d_filtnum;
+ int d_osps;
+ float d_error;
+ int d_out_idx;
+
+ /*!
+ * Build the polyphase filterbank timing synchronizer.
+ */
+ digital_pfb_clock_sync_ccf(double sps, float loop_bw,
+ const std::vector<float> &taps,
+ unsigned int filter_size,
+ float init_phase,
+ float max_rate_deviation,
+ int osps);
+
+ void create_diff_taps(const std::vector<float> &newtaps,
+ std::vector<float> &difftaps);
+
+public:
+ ~digital_pfb_clock_sync_ccf();
+
+ /*! \brief update the system gains from omega and eta
+ *
+ * This function updates the system gains based on the loop
+ * bandwidth and damping factor of the system.
+ * These two factors can be set separately through their own
+ * set functions.
+ */
+ void update_gains();
+
+ /*!
+ * Resets the filterbank's filter taps with the new prototype filter
+ */
+ void set_taps(const std::vector<float> &taps,
+ std::vector< std::vector<float> > &ourtaps,
+ std::vector<gr_fir_ccf*> &ourfilter);
+
+ /*!
+ * Returns all of the taps of the matched filter
+ */
+ std::vector< std::vector<float> > get_taps();
+
+ /*!
+ * Returns all of the taps of the derivative filter
+ */
+ std::vector< std::vector<float> > get_diff_taps();
+
+ /*!
+ * Returns the taps of the matched filter for a particular channel
+ */
+ std::vector<float> get_channel_taps(int channel);
+
+ /*!
+ * Returns the taps in the derivative filter for a particular channel
+ */
+ std::vector<float> get_diff_channel_taps(int channel);
+
+ /*!
+ * Return the taps as a formatted string for printing
+ */
+ std::string get_taps_as_string();
+
+ /*!
+ * Return the derivative filter taps as a formatted string for printing
+ */
+ std::string get_diff_taps_as_string();
+
+
+ /*******************************************************************
+ SET FUNCTIONS
+ *******************************************************************/
+
+
+ /*!
+ * \brief Set the loop bandwidth
+ *
+ * Set the loop filter's bandwidth to \p bw. This should be between
+ * 2*pi/200 and 2*pi/100 (in rads/samp). It must also be a positive
+ * number.
+ *
+ * When a new damping factor is set, the gains, alpha and beta, of the loop
+ * are recalculated by a call to update_gains().
+ *
+ * \param bw (float) new bandwidth
+ *
+ */
+ void set_loop_bandwidth(float bw);
+
+ /*!
+ * \brief Set the loop damping factor
+ *
+ * Set the loop filter's damping factor to \p df. The damping factor
+ * should be sqrt(2)/2.0 for critically damped systems.
+ * Set it to anything else only if you know what you are doing. It must
+ * be a number between 0 and 1.
+ *
+ * When a new damping factor is set, the gains, alpha and beta, of the loop
+ * are recalculated by a call to update_gains().
+ *
+ * \param df (float) new damping factor
+ *
+ */
+ void set_damping_factor(float df);
+
+ /*!
+ * \brief Set the loop gain alpha
+ *
+ * Set's the loop filter's alpha gain parameter.
+ *
+ * This value should really only be set by adjusting the loop bandwidth
+ * and damping factor.
+ *
+ * \param alpha (float) new alpha gain
+ *
+ */
+ void set_alpha(float alpha);
+
+ /*!
+ * \brief Set the loop gain beta
+ *
+ * Set's the loop filter's beta gain parameter.
+ *
+ * This value should really only be set by adjusting the loop bandwidth
+ * and damping factor.
+ *
+ * \param beta (float) new beta gain
+ *
+ */
+ void set_beta(float beta);
+
+ /*!
+ * Set the maximum deviation from 0 d_rate can have
+ */
+ void set_max_rate_deviation(float m)
+ {
+ d_max_dev = m;
+ }
+
+ /*******************************************************************
+ GET FUNCTIONS
+ *******************************************************************/
+
+ /*!
+ * \brief Returns the loop bandwidth
+ */
+ float get_loop_bandwidth() const;
+
+ /*!
+ * \brief Returns the loop damping factor
+ */
+ float get_damping_factor() const;
+
+ /*!
+ * \brief Returns the loop gain alpha
+ */
+ float get_alpha() const;
+
+ /*!
+ * \brief Returns the loop gain beta
+ */
+ float get_beta() const;
+
+ /*!
+ * \brief Returns the current clock rate
+ */
+ float get_clock_rate() const;
+
+ /*******************************************************************
+ *******************************************************************/
+
+ bool check_topology(int ninputs, int noutputs);
+
+ int general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gr-digital/include/digital_pfb_clock_sync_fff.h b/gr-digital/include/digital_pfb_clock_sync_fff.h
new file mode 100644
index 000000000..e571100d7
--- /dev/null
+++ b/gr-digital/include/digital_pfb_clock_sync_fff.h
@@ -0,0 +1,376 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,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.
+ */
+
+
+#ifndef INCLUDED_DIGITAL_PFB_CLOCK_SYNC_FFF_H
+#define INCLUDED_DIGITAL_PFB_CLOCK_SYNC_FFF_H
+
+#include <digital_api.h>
+#include <gr_block.h>
+
+class digital_pfb_clock_sync_fff;
+typedef boost::shared_ptr<digital_pfb_clock_sync_fff> digital_pfb_clock_sync_fff_sptr;
+DIGITAL_API digital_pfb_clock_sync_fff_sptr
+digital_make_pfb_clock_sync_fff(double sps, float gain,
+ const std::vector<float> &taps,
+ unsigned int filter_size=32,
+ float init_phase=0,
+ float max_rate_deviation=1.5,
+ int osps=1);
+
+class gr_fir_fff;
+
+/*!
+ * \class digital_pfb_clock_sync_fff
+ *
+ * \brief Timing synchronizer using polyphase filterbanks
+ *
+ * \ingroup filter_blk
+ * \ingroup pfb_blk
+ *
+ * This block performs timing synchronization for PAM signals by
+ * minimizing the derivative of the filtered signal, which in turn
+ * maximizes the SNR and minimizes ISI.
+ *
+ * This approach works by setting up two filterbanks; one filterbank
+ * contains the signal's pulse shaping matched filter (such as a root
+ * raised cosine filter), where each branch of the filterbank contains
+ * a different phase of the filter. The second filterbank contains
+ * the derivatives of the filters in the first filterbank. Thinking of
+ * this in the time domain, the first filterbank contains filters that
+ * have a sinc shape to them. We want to align the output signal to be
+ * sampled at exactly the peak of the sinc shape. The derivative of
+ * the sinc contains a zero at the maximum point of the sinc (sinc(0)
+ * = 1, sinc(0)' = 0). Furthermore, the region around the zero point
+ * is relatively linear. We make use of this fact to generate the
+ * error signal.
+ *
+ * If the signal out of the derivative filters is d_i[n] for the ith
+ * filter, and the output of the matched filter is x_i[n], we
+ * calculate the error as: e[n] = (Re{x_i[n]} * Re{d_i[n]} +
+ * Im{x_i[n]} * Im{d_i[n]}) / 2.0 This equation averages the error in
+ * the real and imaginary parts. There are two reasons we multiply by
+ * the signal itself. First, if the symbol could be positive or
+ * negative going, but we want the error term to always tell us to go
+ * in the same direction depending on which side of the zero point we
+ * are on. The sign of x_i[n] adjusts the error term to do
+ * this. Second, the magnitude of x_i[n] scales the error term
+ * depending on the symbol's amplitude, so larger signals give us a
+ * stronger error term because we have more confidence in that
+ * symbol's value. Using the magnitude of x_i[n] instead of just the
+ * sign is especially good for signals with low SNR.
+ *
+ * The error signal, e[n], gives us a value proportional to how far
+ * away from the zero point we are in the derivative signal. We want
+ * to drive this value to zero, so we set up a second order loop. We
+ * have two variables for this loop; d_k is the filter number in the
+ * filterbank we are on and d_rate is the rate which we travel through
+ * the filters in the steady state. That is, due to the natural clock
+ * differences between the transmitter and receiver, d_rate represents
+ * that difference and would traverse the filter phase paths to keep
+ * the receiver locked. Thinking of this as a second-order PLL, the
+ * d_rate is the frequency and d_k is the phase. So we update d_rate
+ * and d_k using the standard loop equations based on two error
+ * signals, d_alpha and d_beta. We have these two values set based on
+ * each other for a critically damped system, so in the block
+ * constructor, we just ask for "gain," which is d_alpha while d_beta
+ * is equal to (gain^2)/4.
+ *
+ * The block's parameters are:
+ *
+ * \li \p sps: The clock sync block needs to know the number of samples per
+ * symbol, because it defaults to return a single point representing
+ * the symbol. The sps can be any positive real number and does not
+ * need to be an integer.
+ *
+ * \li \p loop_bw: The loop bandwidth is used to set the gain of the
+ * inner control loop (see:
+ * http://gnuradio.squarespace.com/blog/2011/8/13/control-loop-gain-values.html).
+ * This should be set small (a value of around 2pi/100 is suggested in
+ * that blog post as the step size for the number of radians around
+ * the unit circle to move relative to the error).
+ *
+ * \li \p taps: One of the most important parameters for this block is
+ * the taps of the filter. One of the benefits of this algorithm is
+ * that you can put the matched filter in here as the taps, so you get
+ * both the matched filter and sample timing correction in one go. So
+ * create your normal matched filter. For a typical digital
+ * modulation, this is a root raised cosine filter. The number of taps
+ * of this filter is based on how long you expect the channel to be;
+ * that is, how many symbols do you want to combine to get the current
+ * symbols energy back (there's probably a better way of stating
+ * that). It's usually 5 to 10 or so. That gives you your filter, but
+ * now we need to think about it as a filter with different phase
+ * profiles in each filter. So take this number of taps and multiply
+ * it by the number of filters. This is the number you would use to
+ * create your prototype filter. When you use this in the PFB
+ * filerbank, it segments these taps into the filterbanks in such a
+ * way that each bank now represents the filter at different phases,
+ * equally spaced at 2pi/N, where N is the number of filters.
+ *
+ * \li \p filter_size (default=32): The number of filters can also be
+ * set and defaults to 32. With 32 filters, you get a good enough
+ * resolution in the phase to produce very small, almost unnoticeable,
+ * ISI. Going to 64 filters can reduce this more, but after that
+ * there is very little gained for the extra complexity.
+ *
+ * \li \p init_phase (default=0): The initial phase is another
+ * settable parameter and refers to the filter path the algorithm
+ * initially looks at (i.e., d_k starts at init_phase). This value
+ * defaults to zero, but it might be useful to start at a different
+ * phase offset, such as the mid-point of the filters.
+ *
+ * \li \p max_rate_deviation (default=1.5): The next parameter is the
+ * max_rate_devitation, which defaults to 1.5. This is how far we
+ * allow d_rate to swing, positive or negative, from 0. Constraining
+ * the rate can help keep the algorithm from walking too far away to
+ * lock during times when there is no signal.
+ *
+ * \li \p osps (default=1): The osps is the number of output samples
+ * per symbol. By default, the algorithm produces 1 sample per symbol,
+ * sampled at the exact sample value. This osps value was added to
+ * better work with equalizers, which do a better job of modeling the
+ * channel if they have 2 samps/sym.
+ */
+
+class GR_CORE_API digital_pfb_clock_sync_fff : public gr_block
+{
+ private:
+ /*!
+ * Build the polyphase filterbank timing synchronizer.
+ * \param sps (double) The number of samples per second in the incoming signal
+ * \param gain (float) The alpha gain of the control loop; beta = (gain^2)/4 by default.
+ * \param taps (vector<int>) The filter taps.
+ * \param filter_size (uint) The number of filters in the filterbank (default = 32).
+ * \param init_phase (float) The initial phase to look at, or which filter to start
+ * with (default = 0).
+ * \param max_rate_deviation (float) Distance from 0 d_rate can get (default = 1.5).
+ * \param osps (int) The number of output samples per symbol (default=1).
+ *
+ */
+ friend DIGITAL_API digital_pfb_clock_sync_fff_sptr
+ digital_make_pfb_clock_sync_fff(double sps, float gain,
+ const std::vector<float> &taps,
+ unsigned int filter_size,
+ float init_phase,
+ float max_rate_deviation,
+ int osps);
+
+ bool d_updated;
+ double d_sps;
+ double d_sample_num;
+ float d_loop_bw;
+ float d_damping;
+ float d_alpha;
+ float d_beta;
+
+ int d_nfilters;
+ int d_taps_per_filter;
+ std::vector<gr_fir_fff*> d_filters;
+ std::vector<gr_fir_fff*> d_diff_filters;
+ std::vector< std::vector<float> > d_taps;
+ std::vector< std::vector<float> > d_dtaps;
+
+ float d_k;
+ float d_rate;
+ float d_rate_i;
+ float d_rate_f;
+ float d_max_dev;
+ int d_filtnum;
+ int d_osps;
+ float d_error;
+ int d_out_idx;
+
+ /*!
+ * Build the polyphase filterbank timing synchronizer.
+ */
+ digital_pfb_clock_sync_fff(double sps, float gain,
+ const std::vector<float> &taps,
+ unsigned int filter_size,
+ float init_phase,
+ float max_rate_deviation,
+ int osps);
+
+ void create_diff_taps(const std::vector<float> &newtaps,
+ std::vector<float> &difftaps);
+
+public:
+ ~digital_pfb_clock_sync_fff ();
+
+ /*! \brief update the system gains from omega and eta
+ *
+ * This function updates the system gains based on the loop
+ * bandwidth and damping factor of the system.
+ * These two factors can be set separately through their own
+ * set functions.
+ */
+ void update_gains();
+
+ /*!
+ * Resets the filterbank's filter taps with the new prototype filter
+ */
+ void set_taps(const std::vector<float> &taps,
+ std::vector< std::vector<float> > &ourtaps,
+ std::vector<gr_fir_fff*> &ourfilter);
+
+ /*!
+ * Returns all of the taps of the matched filter
+ */
+ std::vector< std::vector<float> > get_taps();
+
+ /*!
+ * Returns all of the taps of the derivative filter
+ */
+ std::vector< std::vector<float> > get_diff_taps();
+
+ /*!
+ * Returns the taps of the matched filter for a particular channel
+ */
+ std::vector<float> get_channel_taps(int channel);
+
+ /*!
+ * Returns the taps in the derivative filter for a particular channel
+ */
+ std::vector<float> get_diff_channel_taps(int channel);
+
+ /*!
+ * Return the taps as a formatted string for printing
+ */
+ std::string get_taps_as_string();
+
+ /*!
+ * Return the derivative filter taps as a formatted string for printing
+ */
+ std::string get_diff_taps_as_string();
+
+
+ /*******************************************************************
+ SET FUNCTIONS
+ *******************************************************************/
+
+
+ /*!
+ * \brief Set the loop bandwidth
+ *
+ * Set the loop filter's bandwidth to \p bw. This should be between
+ * 2*pi/200 and 2*pi/100 (in rads/samp). It must also be a positive
+ * number.
+ *
+ * When a new damping factor is set, the gains, alpha and beta, of the loop
+ * are recalculated by a call to update_gains().
+ *
+ * \param bw (float) new bandwidth
+ *
+ */
+ void set_loop_bandwidth(float bw);
+
+ /*!
+ * \brief Set the loop damping factor
+ *
+ * Set the loop filter's damping factor to \p df. The damping factor
+ * should be sqrt(2)/2.0 for critically damped systems.
+ * Set it to anything else only if you know what you are doing. It must
+ * be a number between 0 and 1.
+ *
+ * When a new damping factor is set, the gains, alpha and beta, of the loop
+ * are recalculated by a call to update_gains().
+ *
+ * \param df (float) new damping factor
+ *
+ */
+ void set_damping_factor(float df);
+
+ /*!
+ * \brief Set the loop gain alpha
+ *
+ * Set's the loop filter's alpha gain parameter.
+ *
+ * This value should really only be set by adjusting the loop bandwidth
+ * and damping factor.
+ *
+ * \param alpha (float) new alpha gain
+ *
+ */
+ void set_alpha(float alpha);
+
+ /*!
+ * \brief Set the loop gain beta
+ *
+ * Set's the loop filter's beta gain parameter.
+ *
+ * This value should really only be set by adjusting the loop bandwidth
+ * and damping factor.
+ *
+ * \param beta (float) new beta gain
+ *
+ */
+ void set_beta(float beta);
+
+ /*!
+ * Set the maximum deviation from 0 d_rate can have
+ */
+ void set_max_rate_deviation(float m)
+ {
+ d_max_dev = m;
+ }
+
+ /*******************************************************************
+ GET FUNCTIONS
+ *******************************************************************/
+
+ /*!
+ * \brief Returns the loop bandwidth
+ */
+ float get_loop_bandwidth() const;
+
+ /*!
+ * \brief Returns the loop damping factor
+ */
+ float get_damping_factor() const;
+
+ /*!
+ * \brief Returns the loop gain alpha
+ */
+ float get_alpha() const;
+
+ /*!
+ * \brief Returns the loop gain beta
+ */
+ float get_beta() const;
+
+ /*!
+ * \brief Returns the current clock rate
+ */
+ float get_clock_rate() const;
+
+ /*******************************************************************
+ *******************************************************************/
+
+ bool check_topology(int ninputs, int noutputs);
+
+ int general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif
diff --git a/gr-digital/include/digital_pn_correlator_cc.h b/gr-digital/include/digital_pn_correlator_cc.h
new file mode 100644
index 000000000..87cc2ff93
--- /dev/null
+++ b/gr-digital/include/digital_pn_correlator_cc.h
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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.
+ */
+
+#ifndef INCLUDED_GR_PN_CORRELATOR_CC_H
+#define INCLUDED_GR_PN_CORRELATOR_CC_H
+
+#include <digital_api.h>
+#include <gr_sync_decimator.h>
+#include <gri_glfsr.h>
+
+class digital_pn_correlator_cc;
+typedef boost::shared_ptr<digital_pn_correlator_cc> digital_pn_correlator_cc_sptr;
+
+DIGITAL_API digital_pn_correlator_cc_sptr
+digital_make_pn_correlator_cc(int degree, int mask=0, int seed=1);
+/*!
+ * \brief PN code sequential search correlator
+ *
+ * \ingroup sync_blk
+ *
+ * Receives complex baseband signal, outputs complex correlation
+ * against reference PN code, one sample per PN code period. The PN
+ * sequence is generated using a GLFSR.
+ *
+ * \param degree Degree of shift register must be in [1, 32]. If mask
+ * is 0, the degree determines a default mask (see
+ * digital_impl_glfsr.cc for the mapping).
+ * \param repeat Set to repeat sequence.
+ * \param mask Allows a user-defined bit mask for indexes of the shift
+ * register to feed back.
+ * \param seed Initial setting for values in shift register.
+ */
+class DIGITAL_API digital_pn_correlator_cc : public gr_sync_decimator
+{
+ friend DIGITAL_API digital_pn_correlator_cc_sptr
+ digital_make_pn_correlator_cc(int degree, int mask, int seed);
+
+ int d_len;
+ float d_pn;
+ gri_glfsr *d_reference;
+
+ protected:
+ digital_pn_correlator_cc(int degree, int mask, int seed);
+
+ public:
+ virtual int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ ~digital_pn_correlator_cc();
+};
+
+#endif /* INCLUDED_GR_PN_CORRELATOR_CC_H */
diff --git a/gr-digital/include/digital_probe_density_b.h b/gr-digital/include/digital_probe_density_b.h
new file mode 100644
index 000000000..271ad2a07
--- /dev/null
+++ b/gr-digital/include/digital_probe_density_b.h
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2012 Free Software Foundation, Inc.
+ *
+ * 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.
+ */
+#ifndef INCLUDED_GR_PROBE_DENSITY_B_H
+#define INCLUDED_GR_PROBE_DENSITY_B_H
+
+#include <digital_api.h>
+#include <gr_sync_block.h>
+
+class digital_probe_density_b;
+
+typedef boost::shared_ptr<digital_probe_density_b> digital_probe_density_b_sptr;
+
+DIGITAL_API digital_probe_density_b_sptr
+digital_make_probe_density_b(double alpha);
+
+/*!
+ * This block maintains a running average of the input stream and
+ * makes it available as an accessor function. The input stream
+ * is type unsigned char.
+ *
+ * If you send this block a stream of unpacked bytes, it will tell
+ * you what the bit density is.
+ *
+ * \param alpha Average filter constant
+ *
+ */
+
+class DIGITAL_API digital_probe_density_b : public gr_sync_block
+{
+private:
+ friend DIGITAL_API digital_probe_density_b_sptr
+ digital_make_probe_density_b(double alpha);
+
+ double d_alpha;
+ double d_beta;
+ double d_density;
+
+ digital_probe_density_b(double alpha);
+
+public:
+ ~digital_probe_density_b();
+
+ /*!
+ * \brief Returns the current density value
+ */
+ double density() const { return d_density; }
+
+ /*!
+ * \brief Set the average filter constant
+ */
+ void set_alpha(double alpha);
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_PROBE_DENSITY_B_H */
diff --git a/gr-digital/include/digital_scrambler_bb.h b/gr-digital/include/digital_scrambler_bb.h
new file mode 100644
index 000000000..d6f08dcc8
--- /dev/null
+++ b/gr-digital/include/digital_scrambler_bb.h
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,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.
+ */
+#ifndef INCLUDED_GR_SCRAMBLER_BB_H
+#define INCLUDED_GR_SCRAMBLER_BB_H
+
+#include <digital_api.h>
+#include <gr_sync_block.h>
+#include "gri_lfsr.h"
+
+class digital_scrambler_bb;
+typedef boost::shared_ptr<digital_scrambler_bb> digital_scrambler_bb_sptr;
+
+DIGITAL_API digital_scrambler_bb_sptr
+digital_make_scrambler_bb(int mask, int seed, int len);
+
+/*!
+ * Scramble an input stream using an LFSR. This block works on the LSB only
+ * of the input data stream, i.e., on an "unpacked binary" stream, and
+ * produces the same format on its output.
+ *
+ * \param mask Polynomial mask for LFSR
+ * \param seed Initial shift register contents
+ * \param len Shift register length
+ *
+ * \ingroup coding_blk
+ */
+
+class DIGITAL_API digital_scrambler_bb : public gr_sync_block
+{
+ friend DIGITAL_API digital_scrambler_bb_sptr
+ digital_make_scrambler_bb(int mask, int seed, int len);
+
+ gri_lfsr d_lfsr;
+
+ digital_scrambler_bb(int mask, int seed, int len);
+
+public:
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+#endif /* INCLUDED_GR_SCRAMBLER_BB_H */
diff --git a/gr-digital/include/digital_simple_framer.h b/gr-digital/include/digital_simple_framer.h
new file mode 100644
index 000000000..b622ae5dd
--- /dev/null
+++ b/gr-digital/include/digital_simple_framer.h
@@ -0,0 +1,66 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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.
+ */
+
+#ifndef INCLUDED_GR_SIMPLE_FRAMER_H
+#define INCLUDED_GR_SIMPLE_FRAMER_H
+
+#include <digital_api.h>
+#include <gr_block.h>
+
+class digital_simple_framer;
+typedef boost::shared_ptr<digital_simple_framer> digital_simple_framer_sptr;
+
+DIGITAL_API digital_simple_framer_sptr digital_make_simple_framer(int payload_bytesize);
+
+/*!
+ * \brief add sync field, seq number and command field to payload
+ * \ingroup sync_blk
+ *
+ * Takes in enough samples to create a full output frame. The frame is
+ * prepended with the GRSF_SYNC (defind in
+ * digital_simple_framer_sync.h) and an 8-bit sequence number.
+ *
+ * \param payload_bytesize The size of the payload in bytes.
+ */
+class DIGITAL_API digital_simple_framer : public gr_block
+{
+ int d_seqno;
+ int d_payload_bytesize;
+ int d_input_block_size; // bytes
+ int d_output_block_size; // bytes
+
+ friend DIGITAL_API digital_simple_framer_sptr
+ digital_make_simple_framer(int payload_bytesize);
+ digital_simple_framer(int payload_bytesize);
+
+ public:
+ void forecast(int noutput_items,
+ gr_vector_int &ninput_items_required);
+
+ int general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+};
+
+
+#endif /* INCLUDED_GR_SIMPLE_FRAMER_H */
diff --git a/gr-digital/include/digital_simple_framer_sync.h b/gr-digital/include/digital_simple_framer_sync.h
new file mode 100644
index 000000000..412003582
--- /dev/null
+++ b/gr-digital/include/digital_simple_framer_sync.h
@@ -0,0 +1,51 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005,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.
+ */
+
+#ifndef INCLUDED_GR_SIMPLE_FRAMER_SYNC_H
+#define INCLUDED_GR_SIMPLE_FRAMER_SYNC_H
+
+/*!
+ * \brief Here are a couple of maximum length sequences (m-sequences)
+ * that were generated by the the "mseq" matlab/octave code downloaded
+ * from: <a href="http://www.mathworks.com/matlabcentral/fileexchange/990">http://www.mathworks.com/matlabcentral/fileexchange/990</a>
+ *
+ * <pre>
+ * 31-bit m-sequence:
+ * 0110100100001010111011000111110
+ * 0x690AEC76 (padded on right with a zero)
+ *
+ * 63-bit m-sequence:
+ * 101011001101110110100100111000101111001010001100001000001111110
+ * 0xACDDA4E2F28C20FC (padded on right with a zero)
+ * </pre>
+ */
+
+static const unsigned long long GRSF_SYNC = 0xacdda4e2f28c20fcULL;
+
+static const int GRSF_BITS_PER_BYTE = 8;
+static const int GRSF_SYNC_OVERHEAD = sizeof(GRSF_SYNC);
+static const int GRSF_PAYLOAD_OVERHEAD = 1; // 1 byte seqno
+static const int GRSF_TAIL_PAD = 1; // one byte trailing padding
+static const int GRSF_OVERHEAD = GRSF_SYNC_OVERHEAD + GRSF_PAYLOAD_OVERHEAD + GRSF_TAIL_PAD;
+
+
+#endif /* INCLUDED_GR_SIMPLE_FRAMER_SYNC_H */
diff --git a/gr-digital/lib/CMakeLists.txt b/gr-digital/lib/CMakeLists.txt
index 779972ff3..bd4f1a500 100644
--- a/gr-digital/lib/CMakeLists.txt
+++ b/gr-digital/lib/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright 2011 Free Software Foundation, Inc.
+# Copyright 2011,2012 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -23,29 +23,102 @@
include_directories(
${GNURADIO_CORE_INCLUDE_DIRS}
${GR_DIGITAL_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_BINARY_DIR}/../include
)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
+
+########################################################################
+# generate helper scripts to expand templated files
+########################################################################
+include(GrPython)
+
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py "
+#!${PYTHON_EXECUTABLE}
+
+import sys, os, re
+sys.path.append('${GR_CORE_PYTHONPATH}')
+os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
+os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
+
+if __name__ == '__main__':
+ import build_utils
+ root, inp = sys.argv[1:3]
+ for sig in sys.argv[3:]:
+ name = re.sub ('X+', sig, root)
+ d = build_utils.standard_dict(name, sig, 'digital')
+ build_utils.expand_template(d, inp)
+
+")
+
+macro(expand_cc root)
+ #make a list of all the generated files
+ unset(expanded_files_cc)
+ unset(expanded_files_h)
+ foreach(sig ${ARGN})
+ string(REGEX REPLACE "X+" ${sig} name ${root})
+ list(APPEND expanded_files_cc ${CMAKE_CURRENT_BINARY_DIR}/${name}.cc)
+ list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/../include/${name}.h)
+ endforeach(sig)
+
+ #create a command to generate the files
+ add_custom_command(
+ OUTPUT ${expanded_files_cc}
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.cc.t
+ COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
+ ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
+ ${root} ${root}.cc.t ${ARGN}
+ )
+
+ #make source files depends on headers to force generation
+ set_source_files_properties(${expanded_files_cc}
+ PROPERTIES OBJECT_DEPENDS "${expanded_files_h}"
+ )
+
+ #install rules for the generated cc files
+ list(APPEND generated_sources ${expanded_files_cc})
+endmacro(expand_cc)
+
+########################################################################
+# Invoke macro to generate various sources
+########################################################################
+expand_cc(digital_chunks_to_symbols_XX bf bc sf sc if ic)
+
########################################################################
# Setup library
########################################################################
list(APPEND gr_digital_sources
+ ${generated_sources}
+ digital_impl_glfsr.cc
digital_impl_mpsk_snr_est.cc
+ digital_additive_scrambler_bb.cc
digital_binary_slicer_fb.cc
+ digital_bytes_to_syms.cc
digital_clock_recovery_mm_cc.cc
digital_clock_recovery_mm_ff.cc
+ digital_cma_equalizer_cc.cc
digital_constellation.cc
digital_constellation_receiver_cb.cc
digital_constellation_decoder_cb.cc
digital_correlate_access_code_bb.cc
+ digital_correlate_access_code_tag_bb.cc
digital_costas_loop_cc.cc
- digital_cma_equalizer_cc.cc
+ digital_cpmmod_bc.cc
digital_crc32.cc
+ digital_descrambler_bb.cc
+ digital_diff_decoder_bb.cc
+ digital_diff_encoder_bb.cc
+ digital_diff_phasor_cc.cc
digital_fll_band_edge_cc.cc
+ digital_framer_sink_1.cc
+ digital_glfsr_source_b.cc
+ digital_glfsr_source_f.cc
+ digital_gmskmod_bc.cc
digital_lms_dd_equalizer_cc.cc
digital_kurtotic_equalizer_cc.cc
+ digital_map_bb.cc
digital_mpsk_receiver_cc.cc
digital_mpsk_snr_est_cc.cc
digital_ofdm_cyclic_prefixer.cc
@@ -54,9 +127,14 @@ list(APPEND gr_digital_sources
digital_ofdm_insert_preamble.cc
digital_ofdm_mapper_bcv.cc
digital_ofdm_sampler.cc
+ digital_packet_sink.cc
+ digital_pfb_clock_sync_ccf.cc
+ digital_pfb_clock_sync_fff.cc
+ digital_pn_correlator_cc.cc
+ digital_probe_density_b.cc
digital_probe_mpsk_snr_est_c.cc
- digital_gmskmod_bc.cc
- digital_cpmmod_bc.cc
+ digital_scrambler_bb.cc
+ digital_simple_framer.cc
)
list(APPEND digital_libs
@@ -67,3 +145,5 @@ list(APPEND digital_libs
add_library(gnuradio-digital SHARED ${gr_digital_sources})
target_link_libraries(gnuradio-digital ${digital_libs})
GR_LIBRARY_FOO(gnuradio-digital RUNTIME_COMPONENT "digital_runtime" DEVEL_COMPONENT "digital_devel")
+
+add_dependencies(gnuradio-digital digital_generated_includes digital_generated_swigs)
diff --git a/gr-digital/lib/digital_additive_scrambler_bb.cc b/gr-digital/lib/digital_additive_scrambler_bb.cc
new file mode 100644
index 000000000..a8affaa78
--- /dev/null
+++ b/gr-digital/lib/digital_additive_scrambler_bb.cc
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/*
+ * 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 GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <digital_additive_scrambler_bb.h>
+#include <gr_io_signature.h>
+
+digital_additive_scrambler_bb_sptr
+digital_make_additive_scrambler_bb(int mask, int seed, int len, int count)
+{
+ return gnuradio::get_initial_sptr(new digital_additive_scrambler_bb
+ (mask, seed, len, count));
+}
+
+digital_additive_scrambler_bb::digital_additive_scrambler_bb(int mask,
+ int seed,
+ int len,
+ int count)
+ : gr_sync_block("additive_scrambler_bb",
+ gr_make_io_signature (1, 1, sizeof (unsigned char)),
+ gr_make_io_signature (1, 1, sizeof (unsigned char))),
+ d_lfsr(mask, seed, len),
+ d_count(count),
+ d_bits(0)
+{
+}
+
+int
+digital_additive_scrambler_bb::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i++) {
+ out[i] = in[i]^d_lfsr.next_bit();
+ if (d_count > 0) {
+ if (++d_bits == d_count) {
+ d_lfsr.reset();
+ d_bits = 0;
+ }
+ }
+ }
+
+ return noutput_items;
+}
diff --git a/gr-digital/lib/digital_bytes_to_syms.cc b/gr-digital/lib/digital_bytes_to_syms.cc
new file mode 100644
index 000000000..f8bd82d5b
--- /dev/null
+++ b/gr-digital/lib/digital_bytes_to_syms.cc
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <digital_bytes_to_syms.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+
+static const int BITS_PER_BYTE = 8;
+
+digital_bytes_to_syms_sptr
+digital_make_bytes_to_syms ()
+{
+ return gnuradio::get_initial_sptr(new digital_bytes_to_syms ());
+}
+
+digital_bytes_to_syms::digital_bytes_to_syms ()
+ : gr_sync_interpolator ("bytes_to_syms",
+ gr_make_io_signature (1, 1, sizeof (unsigned char)),
+ gr_make_io_signature (1, 1, sizeof (float)),
+ BITS_PER_BYTE)
+{
+}
+
+int
+digital_bytes_to_syms::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (unsigned char *) input_items[0];
+ float *out = (float *) output_items[0];
+
+ assert (noutput_items % BITS_PER_BYTE == 0);
+
+ for (int i = 0; i < noutput_items / BITS_PER_BYTE; i++) {
+ int x = in[i];
+
+ *out++ = (((x >> 7) & 0x1) << 1) - 1;
+ *out++ = (((x >> 6) & 0x1) << 1) - 1;
+ *out++ = (((x >> 5) & 0x1) << 1) - 1;
+ *out++ = (((x >> 4) & 0x1) << 1) - 1;
+ *out++ = (((x >> 3) & 0x1) << 1) - 1;
+ *out++ = (((x >> 2) & 0x1) << 1) - 1;
+ *out++ = (((x >> 1) & 0x1) << 1) - 1;
+ *out++ = (((x >> 0) & 0x1) << 1) - 1;
+ }
+
+ return noutput_items;
+}
+
+
+
diff --git a/gr-digital/lib/digital_chunks_to_symbols_XX.cc.t b/gr-digital/lib/digital_chunks_to_symbols_XX.cc.t
new file mode 100644
index 000000000..399a474a6
--- /dev/null
+++ b/gr-digital/lib/digital_chunks_to_symbols_XX.cc.t
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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.
+ */
+
+// @WARNING@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <@NAME@.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <iostream>
+#include <string.h>
+
+@SPTR_NAME@
+digital_make_@BASE_NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D)
+{
+ return gnuradio::get_initial_sptr (new @NAME@ (symbol_table,D));
+}
+
+@NAME@::@NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D)
+ : gr_sync_interpolator ("@BASE_NAME@",
+ gr_make_io_signature (1, -1, sizeof (@I_TYPE@)),
+ gr_make_io_signature (1, -1, sizeof (@O_TYPE@)),
+ D),
+ d_D (D),
+ d_symbol_table (symbol_table)
+{
+}
+
+int
+@NAME@::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ assert (noutput_items % d_D == 0);
+ assert (input_items.size() == output_items.size());
+ int nstreams = input_items.size();
+
+ for (int m=0;m<nstreams;m++) {
+ const @I_TYPE@ *in = (@I_TYPE@ *) input_items[m];
+ @O_TYPE@ *out = (@O_TYPE@ *) output_items[m];
+
+ // per stream processing
+ for (int i = 0; i < noutput_items / d_D; i++){
+ assert (((unsigned int)in[i]*d_D+d_D) <= d_symbol_table.size());
+ memcpy(out, &d_symbol_table[(unsigned int)in[i]*d_D], d_D*sizeof(@O_TYPE@));
+ out+=d_D;
+ }
+ // end of per stream processing
+
+ }
+ return noutput_items;
+}
diff --git a/gr-digital/lib/digital_correlate_access_code_tag_bb.cc b/gr-digital/lib/digital_correlate_access_code_tag_bb.cc
new file mode 100644
index 000000000..95f06534e
--- /dev/null
+++ b/gr-digital/lib/digital_correlate_access_code_tag_bb.cc
@@ -0,0 +1,131 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <digital_correlate_access_code_tag_bb.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <gr_count_bits.h>
+#include <cstdio>
+#include <iostream>
+
+#define VERBOSE 0
+
+
+digital_correlate_access_code_tag_bb_sptr
+digital_make_correlate_access_code_tag_bb (const std::string &access_code,
+ int threshold,
+ const std::string &tag_name)
+{
+ return gnuradio::get_initial_sptr(new digital_correlate_access_code_tag_bb
+ (access_code, threshold, tag_name));
+}
+
+
+digital_correlate_access_code_tag_bb::digital_correlate_access_code_tag_bb (
+ const std::string &access_code, int threshold, const std::string &tag_name)
+ : gr_sync_block ("correlate_access_code_tag_bb",
+ gr_make_io_signature (1, 1, sizeof(char)),
+ gr_make_io_signature (1, 1, sizeof(char))),
+ d_data_reg(0), d_mask(0),
+ d_threshold(threshold), d_len(0)
+{
+ if (!set_access_code(access_code)) {
+ fprintf(stderr, "digital_correlate_access_code_tag_bb: access_code is > 64 bits\n");
+ throw std::out_of_range ("access_code is > 64 bits");
+ }
+
+ std::stringstream str;
+ str << name() << unique_id();
+ d_me = pmt::pmt_string_to_symbol(str.str());
+ d_key = pmt::pmt_string_to_symbol(tag_name);
+}
+
+digital_correlate_access_code_tag_bb::~digital_correlate_access_code_tag_bb ()
+{
+}
+
+bool
+digital_correlate_access_code_tag_bb::set_access_code(
+ const std::string &access_code)
+{
+ d_len = access_code.length(); // # of bytes in string
+ if (d_len > 64)
+ return false;
+
+ // set len top bits to 1.
+ d_mask = ((~0ULL) >> (64 - d_len)) << (64 - d_len);
+
+ d_access_code = 0;
+ for (unsigned i=0; i < 64; i++){
+ d_access_code <<= 1;
+ if (i < d_len)
+ d_access_code |= access_code[i] & 1; // look at LSB only
+ }
+
+ return true;
+}
+
+int
+digital_correlate_access_code_tag_bb::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+
+ uint64_t abs_out_sample_cnt = nitems_written(0);
+
+ for (int i = 0; i < noutput_items; i++){
+
+ out[i] = in[i];
+
+ // compute hamming distance between desired access code and current data
+ unsigned long long wrong_bits = 0;
+ unsigned int nwrong = d_threshold+1;
+ int new_flag = 0;
+
+ wrong_bits = (d_data_reg ^ d_access_code) & d_mask;
+ nwrong = gr_count_bits64(wrong_bits);
+
+ // test for access code with up to threshold errors
+ new_flag = (nwrong <= d_threshold);
+
+ // shift in new data and new flag
+ d_data_reg = (d_data_reg << 1) | (in[i] & 0x1);
+ if (new_flag) {
+ if(VERBOSE) std::cout << "writing tag at sample " << abs_out_sample_cnt + i << std::endl;
+ add_item_tag(0, //stream ID
+ abs_out_sample_cnt + i - 64 + d_len, //sample
+ d_key, //frame info
+ pmt::pmt_t(), //data (unused)
+ d_me //block src id
+ );
+ }
+ }
+
+ return noutput_items;
+}
+
diff --git a/gr-digital/lib/digital_descrambler_bb.cc b/gr-digital/lib/digital_descrambler_bb.cc
new file mode 100644
index 000000000..68cba7145
--- /dev/null
+++ b/gr-digital/lib/digital_descrambler_bb.cc
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * 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 GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <digital_descrambler_bb.h>
+#include <gr_io_signature.h>
+
+digital_descrambler_bb_sptr
+digital_make_descrambler_bb(int mask, int seed, int len)
+{
+ return gnuradio::get_initial_sptr(new digital_descrambler_bb(mask, seed, len));
+}
+
+digital_descrambler_bb::digital_descrambler_bb(int mask, int seed, int len)
+ : gr_sync_block("descrambler_bb",
+ gr_make_io_signature (1, 1, sizeof (unsigned char)),
+ gr_make_io_signature (1, 1, sizeof (unsigned char))),
+ d_lfsr(mask, seed, len)
+{
+}
+
+int
+digital_descrambler_bb::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i++)
+ out[i] = d_lfsr.next_bit_descramble(in[i]);
+
+ return noutput_items;
+}
diff --git a/gr-digital/lib/digital_diff_decoder_bb.cc b/gr-digital/lib/digital_diff_decoder_bb.cc
new file mode 100644
index 000000000..7b8e8726a
--- /dev/null
+++ b/gr-digital/lib/digital_diff_decoder_bb.cc
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <digital_diff_decoder_bb.h>
+#include <gr_io_signature.h>
+
+digital_diff_decoder_bb_sptr
+digital_make_diff_decoder_bb (unsigned int modulus)
+{
+ return gnuradio::get_initial_sptr(new digital_diff_decoder_bb(modulus));
+}
+
+digital_diff_decoder_bb::digital_diff_decoder_bb (unsigned int modulus)
+ : gr_sync_block ("diff_decoder_bb",
+ gr_make_io_signature (1, 1, sizeof (unsigned char)),
+ gr_make_io_signature (1, 1, sizeof (unsigned char))),
+ d_modulus(modulus)
+{
+ set_history(2); // need to look at two inputs
+}
+
+int
+digital_diff_decoder_bb::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+ in += 1; // ensure that in[-1] is valid
+
+ unsigned modulus = d_modulus;
+
+ for (int i = 0; i < noutput_items; i++) {
+ out[i] = (in[i] - in[i-1]) % modulus;
+ }
+
+ return noutput_items;
+}
diff --git a/gr-digital/lib/digital_diff_encoder_bb.cc b/gr-digital/lib/digital_diff_encoder_bb.cc
new file mode 100644
index 000000000..bfbaba98f
--- /dev/null
+++ b/gr-digital/lib/digital_diff_encoder_bb.cc
@@ -0,0 +1,62 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <digital_diff_encoder_bb.h>
+#include <gr_io_signature.h>
+
+digital_diff_encoder_bb_sptr
+digital_make_diff_encoder_bb (unsigned int modulus)
+{
+ return gnuradio::get_initial_sptr(new digital_diff_encoder_bb(modulus));
+}
+
+digital_diff_encoder_bb::digital_diff_encoder_bb (unsigned int modulus)
+ : gr_sync_block ("diff_encoder_bb",
+ gr_make_io_signature (1, 1, sizeof (unsigned char)),
+ gr_make_io_signature (1, 1, sizeof (unsigned char))),
+ d_last_out(0), d_modulus(modulus)
+{
+}
+
+int
+digital_diff_encoder_bb::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+
+ unsigned last_out = d_last_out;
+ unsigned modulus = d_modulus;
+
+ for (int i = 0; i < noutput_items; i++) {
+ out[i] = (in[i] + last_out) % modulus;
+ last_out = out[i];
+ }
+
+ d_last_out = last_out;
+ return noutput_items;
+}
diff --git a/gr-digital/lib/digital_diff_phasor_cc.cc b/gr-digital/lib/digital_diff_phasor_cc.cc
new file mode 100644
index 000000000..8313a4de8
--- /dev/null
+++ b/gr-digital/lib/digital_diff_phasor_cc.cc
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <digital_diff_phasor_cc.h>
+#include <gr_io_signature.h>
+
+digital_diff_phasor_cc_sptr
+digital_make_diff_phasor_cc ()
+{
+ return gnuradio::get_initial_sptr(new digital_diff_phasor_cc());
+}
+
+digital_diff_phasor_cc::digital_diff_phasor_cc ()
+ : gr_sync_block ("diff_phasor_cc",
+ gr_make_io_signature (1, 1, sizeof (gr_complex)),
+ gr_make_io_signature (1, 1, sizeof (gr_complex)))
+{
+ set_history(2);
+}
+
+
+digital_diff_phasor_cc::~digital_diff_phasor_cc(){}
+
+int
+digital_diff_phasor_cc::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gr_complex const *in = (const gr_complex *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+ in += 1; // ensure that i - 1 is valid.
+
+ for(int i = 0; i < noutput_items; i++) {
+ out[i] = in[i] * conj(in[i-1]);
+ }
+
+ return noutput_items;
+}
diff --git a/gr-digital/lib/digital_framer_sink_1.cc b/gr-digital/lib/digital_framer_sink_1.cc
new file mode 100644
index 000000000..ba1c5bd50
--- /dev/null
+++ b/gr-digital/lib/digital_framer_sink_1.cc
@@ -0,0 +1,192 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <digital_framer_sink_1.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <stdexcept>
+#include <string.h>
+
+#define VERBOSE 0
+
+inline void
+digital_framer_sink_1::enter_search()
+{
+ if (VERBOSE)
+ fprintf(stderr, "@ enter_search\n");
+
+ d_state = STATE_SYNC_SEARCH;
+}
+
+inline void
+digital_framer_sink_1::enter_have_sync()
+{
+ if (VERBOSE)
+ fprintf(stderr, "@ enter_have_sync\n");
+
+ d_state = STATE_HAVE_SYNC;
+ d_header = 0;
+ d_headerbitlen_cnt = 0;
+}
+
+inline void
+digital_framer_sink_1::enter_have_header(int payload_len,
+ int whitener_offset)
+{
+ if (VERBOSE)
+ fprintf(stderr, "@ enter_have_header (payload_len = %d) (offset = %d)\n",
+ payload_len, whitener_offset);
+
+ d_state = STATE_HAVE_HEADER;
+ d_packetlen = payload_len;
+ d_packet_whitener_offset = whitener_offset;
+ d_packetlen_cnt = 0;
+ d_packet_byte = 0;
+ d_packet_byte_index = 0;
+}
+
+digital_framer_sink_1_sptr
+digital_make_framer_sink_1(gr_msg_queue_sptr target_queue)
+{
+ return gnuradio::get_initial_sptr(new digital_framer_sink_1(target_queue));
+}
+
+
+digital_framer_sink_1::digital_framer_sink_1(gr_msg_queue_sptr target_queue)
+ : gr_sync_block ("framer_sink_1",
+ gr_make_io_signature (1, 1, sizeof(unsigned char)),
+ gr_make_io_signature (0, 0, 0)),
+ d_target_queue(target_queue)
+{
+ enter_search();
+}
+
+digital_framer_sink_1::~digital_framer_sink_1 ()
+{
+}
+
+int
+digital_framer_sink_1::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ int count=0;
+
+ if (VERBOSE)
+ fprintf(stderr,">>> Entering state machine\n");
+
+ while (count < noutput_items){
+ switch(d_state) {
+
+ case STATE_SYNC_SEARCH: // Look for flag indicating beginning of pkt
+ if (VERBOSE)
+ fprintf(stderr,"SYNC Search, noutput=%d\n", noutput_items);
+
+ while (count < noutput_items) {
+ if (in[count] & 0x2){ // Found it, set up for header decode
+ enter_have_sync();
+ break;
+ }
+ count++;
+ }
+ break;
+
+ case STATE_HAVE_SYNC:
+ if (VERBOSE)
+ fprintf(stderr,"Header Search bitcnt=%d, header=0x%08x\n",
+ d_headerbitlen_cnt, d_header);
+
+ while (count < noutput_items) { // Shift bits one at a time into header
+ d_header = (d_header << 1) | (in[count++] & 0x1);
+ if (++d_headerbitlen_cnt == HEADERBITLEN) {
+
+ if (VERBOSE)
+ fprintf(stderr, "got header: 0x%08x\n", d_header);
+
+ // we have a full header, check to see if it has been received properly
+ if (header_ok()){
+ int payload_len;
+ int whitener_offset;
+ header_payload(&payload_len, &whitener_offset);
+ enter_have_header(payload_len, whitener_offset);
+
+ if (d_packetlen == 0){ // check for zero-length payload
+ // build a zero-length message
+ // NOTE: passing header field as arg1 is not scalable
+ gr_message_sptr msg =
+ gr_make_message(0, d_packet_whitener_offset, 0, 0);
+
+ d_target_queue->insert_tail(msg); // send it
+ msg.reset(); // free it up
+
+ enter_search();
+ }
+ }
+ else
+ enter_search(); // bad header
+ break; // we're in a new state
+ }
+ }
+ break;
+
+ case STATE_HAVE_HEADER:
+ if (VERBOSE)
+ fprintf(stderr,"Packet Build\n");
+
+ while (count < noutput_items) { // shift bits into bytes of packet one at a time
+ d_packet_byte = (d_packet_byte << 1) | (in[count++] & 0x1);
+ if (d_packet_byte_index++ == 7) { // byte is full so move to next byte
+ d_packet[d_packetlen_cnt++] = d_packet_byte;
+ d_packet_byte_index = 0;
+
+ if (d_packetlen_cnt == d_packetlen){ // packet is filled
+
+ // build a message
+ // NOTE: passing header field as arg1 is not scalable
+ gr_message_sptr msg =
+ gr_make_message(0, d_packet_whitener_offset, 0, d_packetlen_cnt);
+ memcpy(msg->msg(), d_packet, d_packetlen_cnt);
+
+ d_target_queue->insert_tail(msg); // send it
+ msg.reset(); // free it up
+
+ enter_search();
+ break;
+ }
+ }
+ }
+ break;
+
+ default:
+ assert(0);
+
+ } // switch
+
+ } // while
+
+ return noutput_items;
+}
diff --git a/gr-digital/lib/digital_glfsr_source_b.cc b/gr-digital/lib/digital_glfsr_source_b.cc
new file mode 100644
index 000000000..e557e475a
--- /dev/null
+++ b/gr-digital/lib/digital_glfsr_source_b.cc
@@ -0,0 +1,86 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 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.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <digital_glfsr_source_b.h>
+#include <gri_glfsr.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+digital_glfsr_source_b_sptr
+digital_make_glfsr_source_b(int degree, bool repeat, int mask, int seed)
+{
+ return gnuradio::get_initial_sptr(new digital_glfsr_source_b
+ (degree, repeat, mask, seed));
+}
+
+digital_glfsr_source_b::digital_glfsr_source_b(int degree, bool repeat,
+ int mask, int seed)
+ : gr_sync_block ("glfsr_source_b",
+ gr_make_io_signature (0, 0, 0),
+ gr_make_io_signature (1, 1, sizeof(unsigned char))),
+ d_repeat(repeat),
+ d_index(0)
+{
+ if (degree < 1 || degree > 32)
+ throw std::runtime_error("digital_glfsr_source_b: degree must be between 1 and 32 inclusive");
+ d_length = (unsigned int)((1ULL << degree)-1);
+
+ if (mask == 0)
+ mask = gri_glfsr::glfsr_mask(degree);
+ d_glfsr = new gri_glfsr(mask, seed);
+}
+
+digital_glfsr_source_b::~digital_glfsr_source_b()
+{
+ delete d_glfsr;
+}
+
+int
+digital_glfsr_source_b::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ char *out = (char *) output_items[0];
+ if ((d_index > d_length) && d_repeat == false)
+ return -1; /* once through the sequence */
+
+ int i;
+ for (i = 0; i < noutput_items; i++) {
+ out[i] = d_glfsr->next_bit();
+ d_index++;
+ if (d_index > d_length && d_repeat == false)
+ break;
+ }
+
+ return i;
+}
+
+int
+digital_glfsr_source_b::mask() const
+{
+ return d_glfsr->mask();
+}
diff --git a/gr-digital/lib/digital_glfsr_source_f.cc b/gr-digital/lib/digital_glfsr_source_f.cc
new file mode 100644
index 000000000..5a7736ef8
--- /dev/null
+++ b/gr-digital/lib/digital_glfsr_source_f.cc
@@ -0,0 +1,86 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 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.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <digital_glfsr_source_f.h>
+#include <gri_glfsr.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+
+digital_glfsr_source_f_sptr
+digital_make_glfsr_source_f(int degree, bool repeat, int mask, int seed)
+{
+ return gnuradio::get_initial_sptr(new digital_glfsr_source_f
+ (degree, repeat, mask, seed));
+}
+
+digital_glfsr_source_f::digital_glfsr_source_f(int degree, bool repeat,
+ int mask, int seed)
+ : gr_sync_block ("glfsr_source_f",
+ gr_make_io_signature (0, 0, 0),
+ gr_make_io_signature (1, 1, sizeof(float))),
+ d_repeat(repeat),
+ d_index(0)
+{
+ if (degree < 1 || degree > 32)
+ throw std::runtime_error("digital_glfsr_source_f: degree must be between 1 and 32 inclusive");
+ d_length = (unsigned int)((1ULL << degree)-1);
+
+ if (mask == 0)
+ mask = gri_glfsr::glfsr_mask(degree);
+ d_glfsr = new gri_glfsr(mask, seed);
+}
+
+digital_glfsr_source_f::~digital_glfsr_source_f()
+{
+ delete d_glfsr;
+}
+
+int
+digital_glfsr_source_f::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ float *out = (float *) output_items[0];
+ if ((d_index > d_length) && d_repeat == false)
+ return -1; /* once through the sequence */
+
+ int i;
+ for (i = 0; i < noutput_items; i++) {
+ out[i] = (float)d_glfsr->next_bit()*2.0-1.0;
+ d_index++;
+ if (d_index > d_length && d_repeat == false)
+ break;
+ }
+
+ return i;
+}
+
+int
+digital_glfsr_source_f::mask() const
+{
+ return d_glfsr->mask();
+}
diff --git a/gr-digital/lib/digital_impl_glfsr.cc b/gr-digital/lib/digital_impl_glfsr.cc
new file mode 100644
index 000000000..342980e53
--- /dev/null
+++ b/gr-digital/lib/digital_impl_glfsr.cc
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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 <digital_impl_glfsr.h>
+#include <stdexcept>
+
+static int s_polynomial_masks[] = {
+ 0x00000000,
+ 0x00000001, // x^1 + 1
+ 0x00000003, // x^2 + x^1 + 1
+ 0x00000005, // x^3 + x^1 + 1
+ 0x00000009, // x^4 + x^1 + 1
+ 0x00000012, // x^5 + x^2 + 1
+ 0x00000021, // x^6 + x^1 + 1
+ 0x00000041, // x^7 + x^1 + 1
+ 0x0000008E, // x^8 + x^4 + x^3 + x^2 + 1
+ 0x00000108, // x^9 + x^4 + 1
+ 0x00000204, // x^10 + x^4 + 1
+ 0x00000402, // x^11 + x^2 + 1
+ 0x00000829, // x^12 + x^6 + x^4 + x^1 + 1
+ 0x0000100D, // x^13 + x^4 + x^3 + x^1 + 1
+ 0x00002015, // x^14 + x^5 + x^3 + x^1 + 1
+ 0x00004001, // x^15 + x^1 + 1
+ 0x00008016, // x^16 + x^5 + x^3 + x^2 + 1
+ 0x00010004, // x^17 + x^3 + 1
+ 0x00020013, // x^18 + x^5 + x^2 + x^1 + 1
+ 0x00040013, // x^19 + x^5 + x^2 + x^1 + 1
+ 0x00080004, // x^20 + x^3 + 1
+ 0x00100002, // x^21 + x^2 + 1
+ 0x00200001, // x^22 + x^1 + 1
+ 0x00400010, // x^23 + x^5 + 1
+ 0x0080000D, // x^24 + x^4 + x^3 + x^1 + 1
+ 0x01000004, // x^25 + x^3 + 1
+ 0x02000023, // x^26 + x^6 + x^2 + x^1 + 1
+ 0x04000013, // x^27 + x^5 + x^2 + x^1 + 1
+ 0x08000004, // x^28 + x^3 + 1
+ 0x10000002, // x^29 + x^2 + 1
+ 0x20000029, // x^30 + x^4 + x^1 + 1
+ 0x40000004, // x^31 + x^3 + 1
+ 0x80000057 // x^32 + x^7 + x^5 + x^3 + x^2 + x^1 + 1
+};
+
+int digital_impl_glfsr::glfsr_mask(int degree)
+{
+ if (degree < 1 || degree > 32)
+ throw std::runtime_error("digital_impl_glfsr::glfsr_mask(): degree must be between 1 and 32 inclusive");
+ return s_polynomial_masks[degree];
+}
diff --git a/gr-digital/lib/digital_map_bb.cc b/gr-digital/lib/digital_map_bb.cc
new file mode 100644
index 000000000..1d8444a40
--- /dev/null
+++ b/gr-digital/lib/digital_map_bb.cc
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <digital_map_bb.h>
+#include <gr_io_signature.h>
+
+digital_map_bb_sptr
+digital_make_map_bb (const std::vector<int> &map)
+{
+ return gnuradio::get_initial_sptr(new digital_map_bb (map));
+}
+
+digital_map_bb::digital_map_bb (const std::vector<int> &map)
+ : gr_sync_block ("map_bb",
+ gr_make_io_signature (1, 1, sizeof (unsigned char)),
+ gr_make_io_signature (1, 1, sizeof (unsigned char)))
+{
+ for (int i = 0; i < 0x100; i++)
+ d_map[i] = i;
+
+ unsigned int size = std::min((size_t) 0x100, map.size());
+ for (unsigned int i = 0; i < size; i++)
+ d_map[i] = map[i];
+}
+
+int
+digital_map_bb::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i++)
+ out[i] = d_map[in[i]];
+
+ return noutput_items;
+}
diff --git a/gr-digital/lib/digital_packet_sink.cc b/gr-digital/lib/digital_packet_sink.cc
new file mode 100644
index 000000000..92521376f
--- /dev/null
+++ b/gr-digital/lib/digital_packet_sink.cc
@@ -0,0 +1,207 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <digital_packet_sink.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdexcept>
+#include <gr_count_bits.h>
+#include <string.h>
+
+#define VERBOSE 0
+
+static const int DEFAULT_THRESHOLD = 12; // detect access code with up to DEFAULT_THRESHOLD bits wrong
+
+inline void
+digital_packet_sink::enter_search()
+{
+ if (VERBOSE)
+ fprintf(stderr, "@ enter_search\n");
+
+ d_state = STATE_SYNC_SEARCH;
+ d_shift_reg = 0;
+}
+
+inline void
+digital_packet_sink::enter_have_sync()
+{
+ if (VERBOSE)
+ fprintf(stderr, "@ enter_have_sync\n");
+
+ d_state = STATE_HAVE_SYNC;
+ d_header = 0;
+ d_headerbitlen_cnt = 0;
+}
+
+inline void
+digital_packet_sink::enter_have_header(int payload_len)
+{
+ if (VERBOSE)
+ fprintf(stderr, "@ enter_have_header (payload_len = %d)\n", payload_len);
+
+ d_state = STATE_HAVE_HEADER;
+ d_packetlen = payload_len;
+ d_packetlen_cnt = 0;
+ d_packet_byte = 0;
+ d_packet_byte_index = 0;
+}
+
+digital_packet_sink_sptr
+digital_make_packet_sink (const std::vector<unsigned char>& sync_vector,
+ gr_msg_queue_sptr target_queue, int threshold)
+{
+ return gnuradio::get_initial_sptr(new digital_packet_sink (sync_vector, target_queue, threshold));
+}
+
+
+digital_packet_sink::digital_packet_sink (const std::vector<unsigned char>& sync_vector,
+ gr_msg_queue_sptr target_queue, int threshold)
+ : gr_sync_block ("packet_sink",
+ gr_make_io_signature (1, 1, sizeof(float)),
+ gr_make_io_signature (0, 0, 0)),
+ d_target_queue(target_queue), d_threshold(threshold == -1 ? DEFAULT_THRESHOLD : threshold)
+{
+ d_sync_vector = 0;
+ for(int i=0;i<8;i++){
+ d_sync_vector <<= 8;
+ d_sync_vector |= sync_vector[i];
+ }
+
+ enter_search();
+}
+
+digital_packet_sink::~digital_packet_sink ()
+{
+}
+
+int
+digital_packet_sink::work (int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ float *inbuf = (float *) input_items[0];
+ int count=0;
+
+ if (VERBOSE)
+ fprintf(stderr,">>> Entering state machine\n"),fflush(stderr);
+
+ while (count<noutput_items) {
+ switch(d_state) {
+
+ case STATE_SYNC_SEARCH: // Look for sync vector
+ if (VERBOSE)
+ fprintf(stderr,"SYNC Search, noutput=%d\n",noutput_items),fflush(stderr);
+
+ while (count < noutput_items) {
+ if(slice(inbuf[count++]))
+ d_shift_reg = (d_shift_reg << 1) | 1;
+ else
+ d_shift_reg = d_shift_reg << 1;
+
+ // Compute popcnt of putative sync vector
+ if(gr_count_bits64 (d_shift_reg ^ d_sync_vector) <= d_threshold) {
+ // Found it, set up for header decode
+ enter_have_sync();
+ break;
+ }
+ }
+ break;
+
+ case STATE_HAVE_SYNC:
+ if (VERBOSE)
+ fprintf(stderr,"Header Search bitcnt=%d, header=0x%08x\n", d_headerbitlen_cnt, d_header),
+ fflush(stderr);
+
+ while (count < noutput_items) { // Shift bits one at a time into header
+ if(slice(inbuf[count++]))
+ d_header = (d_header << 1) | 1;
+ else
+ d_header = d_header << 1;
+
+ if (++d_headerbitlen_cnt == HEADERBITLEN) {
+
+ if (VERBOSE)
+ fprintf(stderr, "got header: 0x%08x\n", d_header);
+
+ // we have a full header, check to see if it has been received properly
+ if (header_ok()){
+ int payload_len = header_payload_len();
+ if (payload_len <= MAX_PKT_LEN) // reasonable?
+ enter_have_header(payload_len); // yes.
+ else
+ enter_search(); // no.
+ }
+ else
+ enter_search(); // no.
+ break; // we're in a new state
+ }
+ }
+ break;
+
+ case STATE_HAVE_HEADER:
+ if (VERBOSE)
+ fprintf(stderr,"Packet Build\n"),fflush(stderr);
+
+ while (count < noutput_items) { // shift bits into bytes of packet one at a time
+ if(slice(inbuf[count++]))
+ d_packet_byte = (d_packet_byte << 1) | 1;
+ else
+ d_packet_byte = d_packet_byte << 1;
+
+ if (d_packet_byte_index++ == 7) { // byte is full so move to next byte
+ d_packet[d_packetlen_cnt++] = d_packet_byte;
+ d_packet_byte_index = 0;
+
+ if (d_packetlen_cnt == d_packetlen){ // packet is filled
+
+ // build a message
+ gr_message_sptr msg = gr_make_message(0, 0, 0, d_packetlen_cnt);
+ memcpy(msg->msg(), d_packet, d_packetlen_cnt);
+
+ d_target_queue->insert_tail(msg); // send it
+ msg.reset(); // free it up
+
+ enter_search();
+ break;
+ }
+ }
+ }
+ break;
+
+ default:
+ assert(0);
+
+ } // switch
+
+ } // while
+
+ return noutput_items;
+}
+
diff --git a/gr-digital/lib/digital_pfb_clock_sync_ccf.cc b/gr-digital/lib/digital_pfb_clock_sync_ccf.cc
new file mode 100644
index 000000000..1a2d5970b
--- /dev/null
+++ b/gr-digital/lib/digital_pfb_clock_sync_ccf.cc
@@ -0,0 +1,440 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009-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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cstdio>
+#include <cmath>
+
+#include <digital_pfb_clock_sync_ccf.h>
+#include <gr_fir_ccf.h>
+#include <gr_fir_util.h>
+#include <gr_io_signature.h>
+#include <gr_math.h>
+
+digital_pfb_clock_sync_ccf_sptr
+digital_make_pfb_clock_sync_ccf(double sps, float loop_bw,
+ const std::vector<float> &taps,
+ unsigned int filter_size,
+ float init_phase,
+ float max_rate_deviation,
+ int osps)
+{
+ return gnuradio::get_initial_sptr(new digital_pfb_clock_sync_ccf
+ (sps, loop_bw, taps,
+ filter_size,
+ init_phase,
+ max_rate_deviation,
+ osps));
+}
+
+static int ios[] = {sizeof(gr_complex), sizeof(float), sizeof(float), sizeof(float)};
+static std::vector<int> iosig(ios, ios+sizeof(ios)/sizeof(int));
+digital_pfb_clock_sync_ccf::digital_pfb_clock_sync_ccf (double sps, float loop_bw,
+ const std::vector<float> &taps,
+ unsigned int filter_size,
+ float init_phase,
+ float max_rate_deviation,
+ int osps)
+ : gr_block ("pfb_clock_sync_ccf",
+ gr_make_io_signature (1, 1, sizeof(gr_complex)),
+ gr_make_io_signaturev (1, 4, iosig)),
+ d_updated (false), d_nfilters(filter_size),
+ d_max_dev(max_rate_deviation),
+ d_osps(osps), d_error(0), d_out_idx(0)
+{
+ d_nfilters = filter_size;
+ d_sps = floor(sps);
+
+ // Set the damping factor for a critically damped system
+ d_damping = sqrtf(2.0f)/2.0f;
+
+ // Set the bandwidth, which will then call update_gains()
+ set_loop_bandwidth(loop_bw);
+
+ // Store the last filter between calls to work
+ // The accumulator keeps track of overflow to increment the stride correctly.
+ // set it here to the fractional difference based on the initial phaes
+ d_k = init_phase;
+ d_rate = (sps-floor(sps))*(double)d_nfilters;
+ d_rate_i = (int)floor(d_rate);
+ d_rate_f = d_rate - (float)d_rate_i;
+ d_filtnum = (int)floor(d_k);
+
+ d_filters = std::vector<gr_fir_ccf*>(d_nfilters);
+ d_diff_filters = std::vector<gr_fir_ccf*>(d_nfilters);
+
+ // Create an FIR filter for each channel and zero out the taps
+ std::vector<float> vtaps(0, d_nfilters);
+ for(int i = 0; i < d_nfilters; i++) {
+ d_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps);
+ d_diff_filters[i] = gr_fir_util::create_gr_fir_ccf(vtaps);
+ }
+
+ // Now, actually set the filters' taps
+ std::vector<float> dtaps;
+ create_diff_taps(taps, dtaps);
+ set_taps(taps, d_taps, d_filters);
+ set_taps(dtaps, d_dtaps, d_diff_filters);
+}
+
+digital_pfb_clock_sync_ccf::~digital_pfb_clock_sync_ccf ()
+{
+ for(int i = 0; i < d_nfilters; i++) {
+ delete d_filters[i];
+ delete d_diff_filters[i];
+ }
+}
+
+bool
+digital_pfb_clock_sync_ccf::check_topology(int ninputs, int noutputs)
+{
+ return noutputs == 1 || noutputs == 4;
+}
+
+
+
+/*******************************************************************
+ SET FUNCTIONS
+*******************************************************************/
+
+
+void
+digital_pfb_clock_sync_ccf::set_loop_bandwidth(float bw)
+{
+ if(bw < 0) {
+ throw std::out_of_range ("digital_pfb_clock_sync_cc: invalid bandwidth. Must be >= 0.");
+ }
+
+ d_loop_bw = bw;
+ update_gains();
+}
+
+void
+digital_pfb_clock_sync_ccf::set_damping_factor(float df)
+{
+ if(df < 0 || df > 1.0) {
+ throw std::out_of_range ("digital_pfb_clock_sync_cc: invalid damping factor. Must be in [0,1].");
+ }
+
+ d_damping = df;
+ update_gains();
+}
+
+void
+digital_pfb_clock_sync_ccf::set_alpha(float alpha)
+{
+ if(alpha < 0 || alpha > 1.0) {
+ throw std::out_of_range ("digital_pfb_clock_sync_cc: invalid alpha. Must be in [0,1].");
+ }
+ d_alpha = alpha;
+}
+
+void
+digital_pfb_clock_sync_ccf::set_beta(float beta)
+{
+ if(beta < 0 || beta > 1.0) {
+ throw std::out_of_range ("digital_pfb_clock_sync_cc: invalid beta. Must be in [0,1].");
+ }
+ d_beta = beta;
+}
+
+/*******************************************************************
+ GET FUNCTIONS
+*******************************************************************/
+
+
+float
+digital_pfb_clock_sync_ccf::get_loop_bandwidth() const
+{
+ return d_loop_bw;
+}
+
+float
+digital_pfb_clock_sync_ccf::get_damping_factor() const
+{
+ return d_damping;
+}
+
+float
+digital_pfb_clock_sync_ccf::get_alpha() const
+{
+ return d_alpha;
+}
+
+float
+digital_pfb_clock_sync_ccf::get_beta() const
+{
+ return d_beta;
+}
+
+float
+digital_pfb_clock_sync_ccf::get_clock_rate() const
+{
+ return d_rate_f;
+}
+
+/*******************************************************************
+*******************************************************************/
+
+void
+digital_pfb_clock_sync_ccf::update_gains()
+{
+ float denom = (1.0 + 2.0*d_damping*d_loop_bw + d_loop_bw*d_loop_bw);
+ d_alpha = (4*d_damping*d_loop_bw) / denom;
+ d_beta = (4*d_loop_bw*d_loop_bw) / denom;
+}
+
+
+void
+digital_pfb_clock_sync_ccf::set_taps (const std::vector<float> &newtaps,
+ std::vector< std::vector<float> > &ourtaps,
+ std::vector<gr_fir_ccf*> &ourfilter)
+{
+ int i,j;
+
+ unsigned int ntaps = newtaps.size();
+ d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_nfilters);
+
+ // Create d_numchan vectors to store each channel's taps
+ ourtaps.resize(d_nfilters);
+
+ // Make a vector of the taps plus fill it out with 0's to fill
+ // each polyphase filter with exactly d_taps_per_filter
+ std::vector<float> tmp_taps;
+ tmp_taps = newtaps;
+ while((float)(tmp_taps.size()) < d_nfilters*d_taps_per_filter) {
+ tmp_taps.push_back(0.0);
+ }
+
+ // Partition the filter
+ for(i = 0; i < d_nfilters; i++) {
+ // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+ ourtaps[i] = std::vector<float>(d_taps_per_filter, 0);
+ for(j = 0; j < d_taps_per_filter; j++) {
+ ourtaps[i][j] = tmp_taps[i + j*d_nfilters];
+ }
+
+ // Build a filter for each channel and add it's taps to it
+ ourfilter[i]->set_taps(ourtaps[i]);
+ }
+
+ // Set the history to ensure enough input items for each filter
+ set_history (d_taps_per_filter + d_sps);
+
+ // Make sure there is enough output space for d_osps outputs/input.
+ set_output_multiple(d_osps);
+
+ d_updated = true;
+}
+
+void
+digital_pfb_clock_sync_ccf::create_diff_taps(const std::vector<float> &newtaps,
+ std::vector<float> &difftaps)
+{
+ std::vector<float> diff_filter(3);
+ diff_filter[0] = -1;
+ diff_filter[1] = 0;
+ diff_filter[2] = 1;
+
+ float pwr = 0;
+ difftaps.push_back(0);
+ for(unsigned int i = 0; i < newtaps.size()-2; i++) {
+ float tap = 0;
+ for(int j = 0; j < 3; j++) {
+ tap += diff_filter[j]*newtaps[i+j];
+ pwr += fabsf(tap);
+ }
+ difftaps.push_back(tap);
+ }
+ difftaps.push_back(0);
+
+ for(unsigned int i = 0; i < difftaps.size(); i++) {
+ difftaps[i] *= pwr;
+ }
+}
+
+std::string
+digital_pfb_clock_sync_ccf::get_taps_as_string()
+{
+ int i, j;
+ std::stringstream str;
+ str.precision(4);
+ str.setf(std::ios::scientific);
+
+ str << "[ ";
+ for(i = 0; i < d_nfilters; i++) {
+ str << "[" << d_taps[i][0] << ", ";
+ for(j = 1; j < d_taps_per_filter-1; j++) {
+ str << d_taps[i][j] << ", ";
+ }
+ str << d_taps[i][j] << "],";
+ }
+ str << " ]" << std::endl;
+
+ return str.str();
+}
+
+std::string
+digital_pfb_clock_sync_ccf::get_diff_taps_as_string()
+{
+ int i, j;
+ std::stringstream str;
+ str.precision(4);
+ str.setf(std::ios::scientific);
+
+ str << "[ ";
+ for(i = 0; i < d_nfilters; i++) {
+ str << "[" << d_dtaps[i][0] << ", ";
+ for(j = 1; j < d_taps_per_filter-1; j++) {
+ str << d_dtaps[i][j] << ", ";
+ }
+ str << d_dtaps[i][j] << "],";
+ }
+ str << " ]" << std::endl;
+
+ return str.str();
+}
+
+std::vector< std::vector<float> >
+digital_pfb_clock_sync_ccf::get_taps()
+{
+ return d_taps;
+}
+
+std::vector< std::vector<float> >
+digital_pfb_clock_sync_ccf::get_diff_taps()
+{
+ return d_dtaps;
+}
+
+std::vector<float>
+digital_pfb_clock_sync_ccf::get_channel_taps(int channel)
+{
+ std::vector<float> taps;
+ for(int i = 0; i < d_taps_per_filter; i++) {
+ taps.push_back(d_taps[channel][i]);
+ }
+ return taps;
+}
+
+std::vector<float>
+digital_pfb_clock_sync_ccf::get_diff_channel_taps(int channel)
+{
+ std::vector<float> taps;
+ for(int i = 0; i < d_taps_per_filter; i++) {
+ taps.push_back(d_dtaps[channel][i]);
+ }
+ return taps;
+}
+
+
+int
+digital_pfb_clock_sync_ccf::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ gr_complex *in = (gr_complex *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ float *err = NULL, *outrate = NULL, *outk = NULL;
+ if(output_items.size() == 4) {
+ err = (float *) output_items[1];
+ outrate = (float*)output_items[2];
+ outk = (float*)output_items[3];
+ }
+
+ if (d_updated) {
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ // We need this many to process one output
+ int nrequired = ninput_items[0] - d_taps_per_filter - d_osps;
+
+ int i = 0, count = 0;
+ float error_r, error_i;
+
+ // produce output as long as we can and there are enough input samples
+ while((i < noutput_items) && (count < nrequired)) {
+ while(d_out_idx < d_osps) {
+ d_filtnum = (int)floor(d_k);
+
+ // Keep the current filter number in [0, d_nfilters]
+ // If we've run beyond the last filter, wrap around and go to next sample
+ // If we've go below 0, wrap around and go to previous sample
+ while(d_filtnum >= d_nfilters) {
+ d_k -= d_nfilters;
+ d_filtnum -= d_nfilters;
+ count += 1;
+ }
+ while(d_filtnum < 0) {
+ d_k += d_nfilters;
+ d_filtnum += d_nfilters;
+ count -= 1;
+ }
+
+ out[i+d_out_idx] = d_filters[d_filtnum]->filter(&in[count+d_out_idx]);
+ d_k = d_k + d_rate_i + d_rate_f; // update phase
+ d_out_idx++;
+
+ if(output_items.size() == 4) {
+ err[i] = d_error;
+ outrate[i] = d_rate_f;
+ outk[i] = d_k;
+ }
+
+ // We've run out of output items we can create; return now.
+ if(i+d_out_idx >= noutput_items) {
+ consume_each(count);
+ return i;
+ }
+ }
+
+ // reset here; if we didn't complete a full osps samples last time,
+ // the early return would take care of it.
+ d_out_idx = 0;
+
+ // Update the phase and rate estimates for this symbol
+ gr_complex diff = d_diff_filters[d_filtnum]->filter(&in[count]);
+ error_r = out[i].real() * diff.real();
+ error_i = out[i].imag() * diff.imag();
+ d_error = (error_i + error_r) / 2.0; // average error from I&Q channel
+
+ // Run the control loop to update the current phase (k) and
+ // tracking rate estimates based on the error value
+ d_rate_f = d_rate_f + d_beta*d_error;
+ d_k = d_k + d_alpha*d_error;
+
+ // Keep our rate within a good range
+ d_rate_f = gr_branchless_clip(d_rate_f, d_max_dev);
+
+ i+=d_osps;
+ count += (int)floor(d_sps);
+ }
+
+ consume_each(count);
+ return i;
+}
diff --git a/gr-digital/lib/digital_pfb_clock_sync_fff.cc b/gr-digital/lib/digital_pfb_clock_sync_fff.cc
new file mode 100644
index 000000000..0e7d2a52d
--- /dev/null
+++ b/gr-digital/lib/digital_pfb_clock_sync_fff.cc
@@ -0,0 +1,434 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cstdio>
+#include <cmath>
+
+#include <digital_pfb_clock_sync_fff.h>
+#include <gr_fir_fff.h>
+#include <gr_fir_util.h>
+#include <gr_io_signature.h>
+#include <gr_math.h>
+
+digital_pfb_clock_sync_fff_sptr
+digital_make_pfb_clock_sync_fff(double sps, float gain,
+ const std::vector<float> &taps,
+ unsigned int filter_size,
+ float init_phase,
+ float max_rate_deviation,
+ int osps)
+{
+ return gnuradio::get_initial_sptr(new digital_pfb_clock_sync_fff
+ (sps, gain, taps,
+ filter_size,
+ init_phase,
+ max_rate_deviation,
+ osps));
+}
+
+static int ios[] = {sizeof(float), sizeof(float), sizeof(float), sizeof(float)};
+static std::vector<int> iosig(ios, ios+sizeof(ios)/sizeof(int));
+digital_pfb_clock_sync_fff::digital_pfb_clock_sync_fff (double sps, float loop_bw,
+ const std::vector<float> &taps,
+ unsigned int filter_size,
+ float init_phase,
+ float max_rate_deviation,
+ int osps)
+ : gr_block ("pfb_clock_sync_fff",
+ gr_make_io_signature (1, 1, sizeof(float)),
+ gr_make_io_signaturev (1, 4, iosig)),
+ d_updated (false), d_nfilters(filter_size),
+ d_max_dev(max_rate_deviation),
+ d_osps(osps), d_error(0), d_out_idx(0)
+{
+ d_nfilters = filter_size;
+ d_sps = floor(sps);
+
+ // Set the damping factor for a critically damped system
+ d_damping = sqrtf(2.0f)/2.0f;
+
+ // Set the bandwidth, which will then call update_gains()
+ set_loop_bandwidth(loop_bw);
+
+ // Store the last filter between calls to work
+ // The accumulator keeps track of overflow to increment the stride correctly.
+ // set it here to the fractional difference based on the initial phaes
+ d_k = init_phase;
+ d_rate = (sps-floor(sps))*(double)d_nfilters;
+ d_rate_i = (int)floor(d_rate);
+ d_rate_f = d_rate - (float)d_rate_i;
+ d_filtnum = (int)floor(d_k);
+
+ d_filters = std::vector<gr_fir_fff*>(d_nfilters);
+ d_diff_filters = std::vector<gr_fir_fff*>(d_nfilters);
+
+ // Create an FIR filter for each channel and zero out the taps
+ std::vector<float> vtaps(0, d_nfilters);
+ for(int i = 0; i < d_nfilters; i++) {
+ d_filters[i] = gr_fir_util::create_gr_fir_fff(vtaps);
+ d_diff_filters[i] = gr_fir_util::create_gr_fir_fff(vtaps);
+ }
+
+ // Now, actually set the filters' taps
+ std::vector<float> dtaps;
+ create_diff_taps(taps, dtaps);
+ set_taps(taps, d_taps, d_filters);
+ set_taps(dtaps, d_dtaps, d_diff_filters);
+}
+
+digital_pfb_clock_sync_fff::~digital_pfb_clock_sync_fff ()
+{
+ for(int i = 0; i < d_nfilters; i++) {
+ delete d_filters[i];
+ delete d_diff_filters[i];
+ }
+}
+
+bool
+digital_pfb_clock_sync_fff::check_topology(int ninputs, int noutputs)
+{
+ return noutputs == 1 || noutputs == 4;
+}
+
+/*******************************************************************
+ SET FUNCTIONS
+*******************************************************************/
+
+
+void
+digital_pfb_clock_sync_fff::set_loop_bandwidth(float bw)
+{
+ if(bw < 0) {
+ throw std::out_of_range ("digital_pfb_clock_sync_fff: invalid bandwidth. Must be >= 0.");
+ }
+
+ d_loop_bw = bw;
+ update_gains();
+}
+
+void
+digital_pfb_clock_sync_fff::set_damping_factor(float df)
+{
+ if(df < 0 || df > 1.0) {
+ throw std::out_of_range ("digital_pfb_clock_sync_fff: invalid damping factor. Must be in [0,1].");
+ }
+
+ d_damping = df;
+ update_gains();
+}
+
+void
+digital_pfb_clock_sync_fff::set_alpha(float alpha)
+{
+ if(alpha < 0 || alpha > 1.0) {
+ throw std::out_of_range ("digital_pfb_clock_sync_fff: invalid alpha. Must be in [0,1].");
+ }
+ d_alpha = alpha;
+}
+
+void
+digital_pfb_clock_sync_fff::set_beta(float beta)
+{
+ if(beta < 0 || beta > 1.0) {
+ throw std::out_of_range ("digital_pfb_clock_sync_fff: invalid beta. Must be in [0,1].");
+ }
+ d_beta = beta;
+}
+
+/*******************************************************************
+ GET FUNCTIONS
+*******************************************************************/
+
+
+float
+digital_pfb_clock_sync_fff::get_loop_bandwidth() const
+{
+ return d_loop_bw;
+}
+
+float
+digital_pfb_clock_sync_fff::get_damping_factor() const
+{
+ return d_damping;
+}
+
+float
+digital_pfb_clock_sync_fff::get_alpha() const
+{
+ return d_alpha;
+}
+
+float
+digital_pfb_clock_sync_fff::get_beta() const
+{
+ return d_beta;
+}
+
+float
+digital_pfb_clock_sync_fff::get_clock_rate() const
+{
+ return d_rate_f;
+}
+
+/*******************************************************************
+*******************************************************************/
+
+void
+digital_pfb_clock_sync_fff::update_gains()
+{
+ float denom = (1.0 + 2.0*d_damping*d_loop_bw + d_loop_bw*d_loop_bw);
+ d_alpha = (4*d_damping*d_loop_bw) / denom;
+ d_beta = (4*d_loop_bw*d_loop_bw) / denom;
+}
+
+
+void
+digital_pfb_clock_sync_fff::set_taps (const std::vector<float> &newtaps,
+ std::vector< std::vector<float> > &ourtaps,
+ std::vector<gr_fir_fff*> &ourfilter)
+{
+ int i,j;
+
+ unsigned int ntaps = newtaps.size();
+ d_taps_per_filter = (unsigned int)ceil((double)ntaps/(double)d_nfilters);
+
+ // Create d_numchan vectors to store each channel's taps
+ ourtaps.resize(d_nfilters);
+
+ // Make a vector of the taps plus fill it out with 0's to fill
+ // each polyphase filter with exactly d_taps_per_filter
+ std::vector<float> tmp_taps;
+ tmp_taps = newtaps;
+ while((float)(tmp_taps.size()) < d_nfilters*d_taps_per_filter) {
+ tmp_taps.push_back(0.0);
+ }
+
+ // Partition the filter
+ for(i = 0; i < d_nfilters; i++) {
+ // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out
+ ourtaps[i] = std::vector<float>(d_taps_per_filter, 0);
+ for(j = 0; j < d_taps_per_filter; j++) {
+ ourtaps[i][j] = tmp_taps[i + j*d_nfilters];
+ }
+
+ // Build a filter for each channel and add it's taps to it
+ ourfilter[i]->set_taps(ourtaps[i]);
+ }
+
+ // Set the history to ensure enough input items for each filter
+ set_history (d_taps_per_filter + d_sps);
+
+ // Make sure there is enough output space for d_osps outputs/input.
+ set_output_multiple(d_osps);
+
+ d_updated = true;
+}
+
+void
+digital_pfb_clock_sync_fff::create_diff_taps(const std::vector<float> &newtaps,
+ std::vector<float> &difftaps)
+{
+ std::vector<float> diff_filter(3);
+ diff_filter[0] = -1;
+ diff_filter[1] = 0;
+ diff_filter[2] = 1;
+
+ float pwr = 0;
+ difftaps.push_back(0);
+ for(unsigned int i = 0; i < newtaps.size()-2; i++) {
+ float tap = 0;
+ for(int j = 0; j < 3; j++) {
+ tap += diff_filter[j]*newtaps[i+j];
+ pwr += fabsf(tap);
+ }
+ difftaps.push_back(tap);
+ }
+ difftaps.push_back(0);
+
+ for(unsigned int i = 0; i < difftaps.size(); i++) {
+ difftaps[i] *= pwr;
+ }
+}
+
+std::string
+digital_pfb_clock_sync_fff::get_taps_as_string()
+{
+ int i, j;
+ std::stringstream str;
+ str.precision(4);
+ str.setf(std::ios::scientific);
+
+ str << "[ ";
+ for(i = 0; i < d_nfilters; i++) {
+ str << "[" << d_taps[i][0] << ", ";
+ for(j = 1; j < d_taps_per_filter-1; j++) {
+ str << d_taps[i][j] << ", ";
+ }
+ str << d_taps[i][j] << "],";
+ }
+ str << " ]" << std::endl;
+
+ return str.str();
+}
+
+std::string
+digital_pfb_clock_sync_fff::get_diff_taps_as_string()
+{
+ int i, j;
+ std::stringstream str;
+ str.precision(4);
+ str.setf(std::ios::scientific);
+
+ str << "[ ";
+ for(i = 0; i < d_nfilters; i++) {
+ str << "[" << d_dtaps[i][0] << ", ";
+ for(j = 1; j < d_taps_per_filter-1; j++) {
+ str << d_dtaps[i][j] << ", ";
+ }
+ str << d_dtaps[i][j] << "],";
+ }
+ str << " ]" << std::endl;
+
+ return str.str();
+}
+
+std::vector< std::vector<float> >
+digital_pfb_clock_sync_fff::get_taps()
+{
+ return d_taps;
+}
+
+std::vector< std::vector<float> >
+digital_pfb_clock_sync_fff::get_diff_taps()
+{
+ return d_dtaps;
+}
+
+std::vector<float>
+digital_pfb_clock_sync_fff::get_channel_taps(int channel)
+{
+ std::vector<float> taps;
+ for(int i = 0; i < d_taps_per_filter; i++) {
+ taps.push_back(d_taps[channel][i]);
+ }
+ return taps;
+}
+
+std::vector<float>
+digital_pfb_clock_sync_fff::get_diff_channel_taps(int channel)
+{
+ std::vector<float> taps;
+ for(int i = 0; i < d_taps_per_filter; i++) {
+ taps.push_back(d_dtaps[channel][i]);
+ }
+ return taps;
+}
+
+int
+digital_pfb_clock_sync_fff::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ float *in = (float *) input_items[0];
+ float *out = (float *) output_items[0];
+
+ float *err = NULL, *outrate = NULL, *outk = NULL;
+ if(output_items.size() == 4) {
+ err = (float *) output_items[1];
+ outrate = (float*)output_items[2];
+ outk = (float*)output_items[3];
+ }
+
+ if (d_updated) {
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ // We need this many to process one output
+ int nrequired = ninput_items[0] - d_taps_per_filter - d_osps;
+
+ int i = 0, count = 0;
+
+ // produce output as long as we can and there are enough input samples
+ while((i < noutput_items) && (count < nrequired)) {
+ while(d_out_idx < d_osps) {
+ d_filtnum = (int)floor(d_k);
+
+ // Keep the current filter number in [0, d_nfilters]
+ // If we've run beyond the last filter, wrap around and go to next sample
+ // If we've go below 0, wrap around and go to previous sample
+ while(d_filtnum >= d_nfilters) {
+ d_k -= d_nfilters;
+ d_filtnum -= d_nfilters;
+ count += 1;
+ }
+ while(d_filtnum < 0) {
+ d_k += d_nfilters;
+ d_filtnum += d_nfilters;
+ count -= 1;
+ }
+
+ out[i+d_out_idx] = d_filters[d_filtnum]->filter(&in[count+d_out_idx]);
+ d_k = d_k + d_rate_i + d_rate_f; // update phase
+ d_out_idx++;
+
+ if(output_items.size() == 4) {
+ err[i] = d_error;
+ outrate[i] = d_rate_f;
+ outk[i] = d_k;
+ }
+
+ // We've run out of output items we can create; return now.
+ if(i+d_out_idx >= noutput_items) {
+ consume_each(count);
+ return i;
+ }
+ }
+
+ // reset here; if we didn't complete a full osps samples last time,
+ // the early return would take care of it.
+ d_out_idx = 0;
+
+ // Update the phase and rate estimates for this symbol
+ float diff = d_diff_filters[d_filtnum]->filter(&in[count]);
+ d_error = out[i] * diff;
+
+ // Run the control loop to update the current phase (k) and
+ // tracking rate estimates based on the error value
+ d_rate_f = d_rate_f + d_beta*d_error;
+ d_k = d_k + d_alpha*d_error;
+
+ // Keep our rate within a good range
+ d_rate_f = gr_branchless_clip(d_rate_f, d_max_dev);
+
+ i+=d_osps;
+ count += (int)floor(d_sps);
+ }
+
+ consume_each(count);
+ return i;
+}
diff --git a/gr-digital/lib/digital_pn_correlator_cc.cc b/gr-digital/lib/digital_pn_correlator_cc.cc
new file mode 100644
index 000000000..43a3ddbd1
--- /dev/null
+++ b/gr-digital/lib/digital_pn_correlator_cc.cc
@@ -0,0 +1,80 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <digital_pn_correlator_cc.h>
+#include <gr_io_signature.h>
+
+digital_pn_correlator_cc_sptr
+digital_make_pn_correlator_cc(int degree, int mask, int seed)
+{
+ return gnuradio::get_initial_sptr(new digital_pn_correlator_cc
+ (degree, mask, seed));
+}
+
+digital_pn_correlator_cc::digital_pn_correlator_cc(int degree,
+ int mask,
+ int seed)
+ : gr_sync_decimator ("pn_correlator_cc",
+ gr_make_io_signature (1, 1, sizeof(gr_complex)),
+ gr_make_io_signature (1, 1, sizeof(gr_complex)),
+ (unsigned int)((1ULL << degree)-1)) // PN code length
+{
+ d_len = (unsigned int)((1ULL << degree)-1);
+ if (mask == 0)
+ mask = gri_glfsr::glfsr_mask(degree);
+ d_reference = new gri_glfsr(mask, seed);
+ for (int i = 0; i < d_len; i++) // initialize to last value in sequence
+ d_pn = 2.0*d_reference->next_bit()-1.0;
+}
+
+digital_pn_correlator_cc::~digital_pn_correlator_cc()
+{
+ delete d_reference;
+}
+
+int
+digital_pn_correlator_cc::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const gr_complex *in = (const gr_complex *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+ gr_complex sum;
+
+ for (int i = 0; i < noutput_items; i++) {
+ sum = 0.0;
+
+ for (int j = 0; j < d_len; j++) {
+ if (j != 0) // retard PN generator one sample per period
+ d_pn = 2.0*d_reference->next_bit()-1.0; // no conditionals
+ sum += *in++ * d_pn;
+ }
+
+ *out++ = sum*gr_complex(1.0/d_len, 0.0);
+ }
+
+ return noutput_items;
+}
diff --git a/gr-digital/lib/digital_probe_density_b.cc b/gr-digital/lib/digital_probe_density_b.cc
new file mode 100644
index 000000000..6b83d2ddb
--- /dev/null
+++ b/gr-digital/lib/digital_probe_density_b.cc
@@ -0,0 +1,68 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2010,2012 Free Software Foundation, Inc.
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <digital_probe_density_b.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+digital_probe_density_b_sptr
+digital_make_probe_density_b(double alpha)
+{
+ return gnuradio::get_initial_sptr(new digital_probe_density_b(alpha));
+}
+
+digital_probe_density_b::digital_probe_density_b(double alpha)
+ : gr_sync_block("density_b",
+ gr_make_io_signature(1, 1, sizeof(char)),
+ gr_make_io_signature(0, 0, 0))
+{
+ set_alpha(alpha);
+ d_density = 1.0;
+}
+
+digital_probe_density_b::~digital_probe_density_b()
+{
+}
+
+int
+digital_probe_density_b::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const char *in = (const char *)input_items[0];
+
+ for (int i = 0; i < noutput_items; i++)
+ d_density = d_alpha*(double)in[i] + d_beta*d_density;
+
+ return noutput_items;
+}
+
+void
+digital_probe_density_b::set_alpha(double alpha)
+{
+ d_alpha = alpha;
+ d_beta = 1.0-d_alpha;
+}
+
diff --git a/gr-digital/lib/digital_scrambler_bb.cc b/gr-digital/lib/digital_scrambler_bb.cc
new file mode 100644
index 000000000..c81b09d8c
--- /dev/null
+++ b/gr-digital/lib/digital_scrambler_bb.cc
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * 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 GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <digital_scrambler_bb.h>
+#include <gr_io_signature.h>
+
+digital_scrambler_bb_sptr
+digital_make_scrambler_bb(int mask, int seed, int len)
+{
+ return gnuradio::get_initial_sptr(new digital_scrambler_bb
+ (mask, seed, len));
+}
+
+digital_scrambler_bb::digital_scrambler_bb(int mask, int seed, int len)
+ : gr_sync_block("scrambler_bb",
+ gr_make_io_signature (1, 1, sizeof (unsigned char)),
+ gr_make_io_signature (1, 1, sizeof (unsigned char))),
+ d_lfsr(mask, seed, len)
+{
+}
+
+int
+digital_scrambler_bb::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+
+ for (int i = 0; i < noutput_items; i++)
+ out[i] = d_lfsr.next_bit_scramble(in[i]);
+
+ return noutput_items;
+}
diff --git a/gr-digital/lib/digital_simple_framer.cc b/gr-digital/lib/digital_simple_framer.cc
new file mode 100644
index 000000000..5c194543c
--- /dev/null
+++ b/gr-digital/lib/digital_simple_framer.cc
@@ -0,0 +1,102 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <digital_simple_framer.h>
+#include <digital_simple_framer_sync.h>
+#include <gr_io_signature.h>
+#include <assert.h>
+#include <stdexcept>
+#include <string.h>
+
+
+digital_simple_framer_sptr
+digital_make_simple_framer (int payload_bytesize)
+{
+ return gnuradio::get_initial_sptr(new digital_simple_framer
+ (payload_bytesize));
+}
+
+digital_simple_framer::digital_simple_framer (int payload_bytesize)
+ : gr_block ("simple_framer",
+ gr_make_io_signature (1, 1, sizeof (unsigned char)),
+ gr_make_io_signature (1, 1, sizeof (unsigned char))),
+ d_seqno (0), d_payload_bytesize (payload_bytesize),
+ d_input_block_size (payload_bytesize),
+ d_output_block_size (payload_bytesize + GRSF_OVERHEAD)
+{
+ set_output_multiple (d_output_block_size);
+}
+
+void
+digital_simple_framer::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+ assert (noutput_items % d_output_block_size == 0);
+
+ int nblocks = noutput_items / d_output_block_size;
+ int input_required = nblocks * d_input_block_size;
+
+ unsigned ninputs = ninput_items_required.size();
+ for (unsigned int i = 0; i < ninputs; i++)
+ ninput_items_required[i] = input_required;
+}
+
+int
+digital_simple_framer::general_work (int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+{
+ const unsigned char *in = (const unsigned char *) input_items[0];
+ unsigned char *out = (unsigned char *) output_items[0];
+
+ int n = 0;
+ int nblocks = 0;
+
+ memset (out, 0x55, noutput_items);
+
+ while (n < noutput_items) {
+ out[0] = (GRSF_SYNC >> 56) & 0xff;
+ out[1] = (GRSF_SYNC >> 48) & 0xff;
+ out[2] = (GRSF_SYNC >> 40) & 0xff;
+ out[3] = (GRSF_SYNC >> 32) & 0xff;
+ out[4] = (GRSF_SYNC >> 24) & 0xff;
+ out[5] = (GRSF_SYNC >> 16) & 0xff;
+ out[6] = (GRSF_SYNC >> 8) & 0xff;
+ out[7] = (GRSF_SYNC >> 0) & 0xff;
+ out[8] = d_seqno++;
+
+ memcpy (&out[9], in, d_input_block_size);
+ in += d_input_block_size;
+ out += d_output_block_size;
+ n += d_output_block_size;
+ nblocks++;
+ }
+
+ assert (n == noutput_items);
+
+ consume_each (nblocks * d_input_block_size);
+ return n;
+}
diff --git a/gr-digital/python/generic_mod_demod.py b/gr-digital/python/generic_mod_demod.py
index ae876e108..a6c4f3445 100644
--- a/gr-digital/python/generic_mod_demod.py
+++ b/gr-digital/python/generic_mod_demod.py
@@ -28,7 +28,7 @@ Generic modulation and demodulation.
from gnuradio import gr
from modulation_utils import extract_kwargs_from_options_for_class
from utils import mod_codes
-import digital_swig
+import digital_swig as digital
import math
# default values (used in __init__ and add_options)
@@ -121,12 +121,12 @@ class generic_mod(gr.hier_block2):
gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST)
if gray_coded == True:
- self.symbol_mapper = gr.map_bb(self._constellation.pre_diff_code())
+ self.symbol_mapper = digital.map_bb(self._constellation.pre_diff_code())
if differential:
- self.diffenc = gr.diff_encoder_bb(arity)
+ self.diffenc = digital.diff_encoder_bb(arity)
- self.chunks2symbols = gr.chunks_to_symbols_bc(self._constellation.points())
+ self.chunks2symbols = digital.chunks_to_symbols_bc(self._constellation.points())
# pulse shaping filter
nfilts = 32
@@ -269,28 +269,28 @@ class generic_demod(gr.hier_block2):
# Frequency correction
fll_ntaps = 55
- self.freq_recov = digital_swig.fll_band_edge_cc(self._samples_per_symbol, self._excess_bw,
- fll_ntaps, self._freq_bw)
+ self.freq_recov = digital.fll_band_edge_cc(self._samples_per_symbol, self._excess_bw,
+ fll_ntaps, self._freq_bw)
# symbol timing recovery with RRC data filter
taps = gr.firdes.root_raised_cosine(nfilts, nfilts*self._samples_per_symbol,
1.0, self._excess_bw, ntaps)
- self.time_recov = gr.pfb_clock_sync_ccf(self._samples_per_symbol,
- self._timing_bw, taps,
- nfilts, nfilts//2, self._timing_max_dev)
+ self.time_recov = digital.pfb_clock_sync_ccf(self._samples_per_symbol,
+ self._timing_bw, taps,
+ nfilts, nfilts//2, self._timing_max_dev)
fmin = -0.25
fmax = 0.25
- self.receiver = digital_swig.constellation_receiver_cb(
+ self.receiver = digital.constellation_receiver_cb(
self._constellation, self._phase_bw,
fmin, fmax)
# Do differential decoding based on phase change of symbols
if differential:
- self.diffdec = gr.diff_decoder_bb(arity)
+ self.diffdec = digital.diff_decoder_bb(arity)
if gray_coded:
- self.symbol_mapper = gr.map_bb(
+ self.symbol_mapper = digital.map_bb(
mod_codes.invert_code(self._constellation.pre_diff_code()))
# unpack the k bit vector into a stream of bits
diff --git a/gr-digital/python/qa_bytes_to_syms.py b/gr-digital/python/qa_bytes_to_syms.py
new file mode 100755
index 000000000..75475a95b
--- /dev/null
+++ b/gr-digital/python/qa_bytes_to_syms.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,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
+import digital_swig as digital
+import math
+
+class test_bytes_to_syms (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_bytes_to_syms_001 (self):
+ src_data = (0x01, 0x80, 0x03)
+ expected_result = (-1, -1, -1, -1, -1, -1, -1, +1,
+ +1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, +1, +1)
+ src = gr.vector_source_b (src_data)
+ op = digital.bytes_to_syms ()
+ dst = gr.vector_sink_f ()
+ self.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.run ()
+ result_data = dst.data ()
+ self.assertEqual (expected_result, result_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_bytes_to_syms, "test_bytes_to_syms.xml")
+
diff --git a/gr-digital/python/qa_chunks_to_symbols.py b/gr-digital/python/qa_chunks_to_symbols.py
new file mode 100755
index 000000000..63af10d8f
--- /dev/null
+++ b/gr-digital/python/qa_chunks_to_symbols.py
@@ -0,0 +1,140 @@
+#!/usr/bin/env python
+#
+# 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.
+#
+
+from gnuradio import gr, gr_unittest
+import digital_swig as digital
+
+class test_chunks_to_symbols(gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_bc_001(self):
+ const = [ 1+0j, 0+1j,
+ -1+0j, 0-1j]
+ src_data = (0, 1, 2, 3, 3, 2, 1, 0)
+ expected_result = (1+0j, 0+1j, -1+0j, 0-1j,
+ 0-1j, -1+0j, 0+1j, 1+0j)
+
+ src = gr.vector_source_b(src_data)
+ op = digital.chunks_to_symbols_bc(const)
+
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op)
+ self.tb.connect(op, dst)
+ self.tb.run()
+
+ actual_result = dst.data()
+ self.assertEqual(expected_result, actual_result)
+
+ def test_bf_002(self):
+ const = [-3, -1, 1, 3]
+ src_data = (0, 1, 2, 3, 3, 2, 1, 0)
+ expected_result = (-3, -1, 1, 3,
+ 3, 1, -1, -3)
+
+ src = gr.vector_source_b(src_data)
+ op = digital.chunks_to_symbols_bf(const)
+
+ dst = gr.vector_sink_f()
+ self.tb.connect(src, op)
+ self.tb.connect(op, dst)
+ self.tb.run()
+
+ actual_result = dst.data()
+ self.assertEqual(expected_result, actual_result)
+
+ def test_ic_003(self):
+ const = [ 1+0j, 0+1j,
+ -1+0j, 0-1j]
+ src_data = (0, 1, 2, 3, 3, 2, 1, 0)
+ expected_result = (1+0j, 0+1j, -1+0j, 0-1j,
+ 0-1j, -1+0j, 0+1j, 1+0j)
+
+ src = gr.vector_source_i(src_data)
+ op = digital.chunks_to_symbols_ic(const)
+
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op)
+ self.tb.connect(op, dst)
+ self.tb.run()
+
+ actual_result = dst.data()
+ self.assertEqual(expected_result, actual_result)
+
+ def test_if_004(self):
+ const = [-3, -1, 1, 3]
+ src_data = (0, 1, 2, 3, 3, 2, 1, 0)
+ expected_result = (-3, -1, 1, 3,
+ 3, 1, -1, -3)
+
+ src = gr.vector_source_i(src_data)
+ op = digital.chunks_to_symbols_if(const)
+
+ dst = gr.vector_sink_f()
+ self.tb.connect(src, op)
+ self.tb.connect(op, dst)
+ self.tb.run()
+
+ actual_result = dst.data()
+ self.assertEqual(expected_result, actual_result)
+
+ def test_sc_005(self):
+ const = [ 1+0j, 0+1j,
+ -1+0j, 0-1j]
+ src_data = (0, 1, 2, 3, 3, 2, 1, 0)
+ expected_result = (1+0j, 0+1j, -1+0j, 0-1j,
+ 0-1j, -1+0j, 0+1j, 1+0j)
+
+ src = gr.vector_source_s(src_data)
+ op = digital.chunks_to_symbols_sc(const)
+
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, op)
+ self.tb.connect(op, dst)
+ self.tb.run()
+
+ actual_result = dst.data()
+ self.assertEqual(expected_result, actual_result)
+
+ def test_sf_006(self):
+ const = [-3, -1, 1, 3]
+ src_data = (0, 1, 2, 3, 3, 2, 1, 0)
+ expected_result = (-3, -1, 1, 3,
+ 3, 1, -1, -3)
+
+ src = gr.vector_source_s(src_data)
+ op = digital.chunks_to_symbols_sf(const)
+
+ dst = gr.vector_sink_f()
+ self.tb.connect(src, op)
+ self.tb.connect(op, dst)
+ self.tb.run()
+
+ actual_result = dst.data()
+ self.assertEqual(expected_result, actual_result)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_chunks_to_symbols, "test_chunks_to_symbols.xml")
diff --git a/gr-digital/python/qa_correlate_access_code.py b/gr-digital/python/qa_correlate_access_code.py
index 6b6f25051..96246dcfb 100755
--- a/gr-digital/python/qa_correlate_access_code.py
+++ b/gr-digital/python/qa_correlate_access_code.py
@@ -21,7 +21,7 @@
#
from gnuradio import gr, gr_unittest
-import digital_swig
+import digital_swig as digital
import math
default_access_code = '\xAC\xDD\xA4\xE2\xF2\x8C\x20\xFC'
@@ -53,7 +53,7 @@ class test_correlate_access_code(gr_unittest.TestCase):
src_data = (1, 0, 1, 1, 1, 1, 0, 1, 1) + pad + (0,) * 7
expected_result = pad + (1, 0, 1, 1, 3, 1, 0, 1, 1, 2) + (0,) * 6
src = gr.vector_source_b (src_data)
- op = digital_swig.correlate_access_code_bb("1011", 0)
+ op = digital.correlate_access_code_bb("1011", 0)
dst = gr.vector_sink_b ()
self.tb.connect (src, op, dst)
self.tb.run ()
@@ -70,13 +70,28 @@ class test_correlate_access_code(gr_unittest.TestCase):
src_data = code + (1, 0, 1, 1) + pad
expected_result = pad + code + (3, 0, 1, 1)
src = gr.vector_source_b (src_data)
- op = digital_swig.correlate_access_code_bb(access_code, 0)
+ op = digital.correlate_access_code_bb(access_code, 0)
dst = gr.vector_sink_b ()
self.tb.connect (src, op, dst)
self.tb.run ()
result_data = dst.data ()
self.assertEqual (expected_result, result_data)
+ def test_003(self):
+ code = tuple(string_to_1_0_list(default_access_code))
+ access_code = to_1_0_string(code)
+ pad = (0,) * 64
+ #print code
+ #print access_code
+ src_data = code + (1, 0, 1, 1) + pad
+ expected_result = code + (1, 0, 1, 1) + pad
+ src = gr.vector_source_b (src_data)
+ op = digital.correlate_access_code_tag_bb(access_code, 0, "test")
+ dst = gr.vector_sink_b ()
+ self.tb.connect (src, op, dst)
+ self.tb.run ()
+ result_data = dst.data ()
+ self.assertEqual (expected_result, result_data)
if __name__ == '__main__':
diff --git a/gr-digital/python/qa_diff_encoder.py b/gr-digital/python/qa_diff_encoder.py
new file mode 100755
index 000000000..e4f5470af
--- /dev/null
+++ b/gr-digital/python/qa_diff_encoder.py
@@ -0,0 +1,87 @@
+#!/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
+import digital_swig as digital
+import math
+import random
+
+def make_random_int_tuple(L, min, max):
+ result = []
+ for x in range(L):
+ result.append(random.randint(min, max))
+ return tuple(result)
+
+
+class test_diff_encoder (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_diff_encdec_000(self):
+ random.seed(0)
+ modulus = 2
+ src_data = make_random_int_tuple(1000, 0, modulus-1)
+ expected_result = src_data
+ src = gr.vector_source_b(src_data)
+ enc = digital.diff_encoder_bb(modulus)
+ dec = digital.diff_decoder_bb(modulus)
+ dst = gr.vector_sink_b()
+ self.tb.connect(src, enc, dec, dst)
+ self.tb.run() # run the graph and wait for it to finish
+ actual_result = dst.data() # fetch the contents of the sink
+ self.assertEqual(expected_result, actual_result)
+
+ def test_diff_encdec_001(self):
+ random.seed(0)
+ modulus = 4
+ src_data = make_random_int_tuple(1000, 0, modulus-1)
+ expected_result = src_data
+ src = gr.vector_source_b(src_data)
+ enc = digital.diff_encoder_bb(modulus)
+ dec = digital.diff_decoder_bb(modulus)
+ dst = gr.vector_sink_b()
+ self.tb.connect(src, enc, dec, dst)
+ self.tb.run() # run the graph and wait for it to finish
+ actual_result = dst.data() # fetch the contents of the sink
+ self.assertEqual(expected_result, actual_result)
+
+ def test_diff_encdec_002(self):
+ random.seed(0)
+ modulus = 8
+ src_data = make_random_int_tuple(40000, 0, modulus-1)
+ expected_result = src_data
+ src = gr.vector_source_b(src_data)
+ enc = digital.diff_encoder_bb(modulus)
+ dec = digital.diff_decoder_bb(modulus)
+ dst = gr.vector_sink_b()
+ self.tb.connect(src, enc, dec, dst)
+ self.tb.run() # run the graph and wait for it to finish
+ actual_result = dst.data() # fetch the contents of the sink
+ self.assertEqual(expected_result, actual_result)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_diff_encoder, "test_diff_encoder.xml")
+
diff --git a/gr-digital/python/qa_diff_phasor_cc.py b/gr-digital/python/qa_diff_phasor_cc.py
new file mode 100755
index 000000000..3e7617fe4
--- /dev/null
+++ b/gr-digital/python/qa_diff_phasor_cc.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2007,2010 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
+import digital_swig as digital
+import math
+
+class test_diff_phasor (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_diff_phasor_cc (self):
+ src_data = (0+0j, 1+0j, -1+0j, 3+4j, -3-4j, -3+4j)
+ expected_result = (0+0j, 0+0j, -1+0j, -3-4j, -25+0j, -7-24j)
+ src = gr.vector_source_c (src_data)
+ op = digital.diff_phasor_cc ()
+ dst = gr.vector_sink_c ()
+ self.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.run () # run the graph and wait for it to finish
+ actual_result = dst.data () # fetch the contents of the sink
+ self.assertComplexTuplesAlmostEqual (expected_result, actual_result)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_diff_phasor, "test_diff_phasor.xml")
+
diff --git a/gr-digital/python/qa_framer_sink.py b/gr-digital/python/qa_framer_sink.py
new file mode 100755
index 000000000..bccc86dc7
--- /dev/null
+++ b/gr-digital/python/qa_framer_sink.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+#
+# 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.
+#
+
+from gnuradio import gr, gr_unittest
+import digital_swig as digital
+
+default_access_code = '\xAC\xDD\xA4\xE2\xF2\x8C\x20\xFC'
+
+def string_to_1_0_list(s):
+ r = []
+ for ch in s:
+ x = ord(ch)
+ for i in range(8):
+ t = (x >> i) & 0x1
+ r.append(t)
+ return r
+
+def to_1_0_string(L):
+ return ''.join(map(lambda x: chr(x + ord('0')), L))
+
+class test_framker_sink(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_001(self):
+
+ code = (1, 1, 0, 1)
+ access_code = to_1_0_string(code)
+ header = tuple(2*[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]) # len=1
+ pad = (0,) * 100
+ src_data = code + header + (0,1,0,0,0,0,0,1) + pad
+ expected_data = 'A'
+
+ rcvd_pktq = gr.msg_queue()
+
+ src = gr.vector_source_b(src_data)
+ correlator = digital.correlate_access_code_bb(access_code, 0)
+ framer_sink = digital.framer_sink_1(rcvd_pktq)
+ vsnk = gr.vector_sink_b()
+
+ self.tb.connect(src, correlator, framer_sink)
+ self.tb.connect(correlator, vsnk)
+ self.tb.run ()
+
+ result_data = rcvd_pktq.delete_head()
+ result_data = result_data.to_string()
+ self.assertEqual (expected_data, result_data)
+
+ def test_002(self):
+
+ code = tuple(string_to_1_0_list(default_access_code))
+ access_code = to_1_0_string(code)
+ header = tuple(2*[0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0]) # len=2
+ pad = (0,) * 100
+ src_data = code + header + (0,1,0,0,1,0,0,0) + (0,1,0,0,1,0,0,1) + pad
+ expected_data = 'HI'
+
+ rcvd_pktq = gr.msg_queue()
+
+ src = gr.vector_source_b(src_data)
+ correlator = digital.correlate_access_code_bb(access_code, 0)
+ framer_sink = digital.framer_sink_1(rcvd_pktq)
+ vsnk = gr.vector_sink_b()
+
+ self.tb.connect(src, correlator, framer_sink)
+ self.tb.connect(correlator, vsnk)
+ self.tb.run ()
+
+ result_data = rcvd_pktq.delete_head()
+ result_data = result_data.to_string()
+ self.assertEqual (expected_data, result_data)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_framker_sink, "test_framker_sink.xml")
+
diff --git a/gr-digital/python/qa_glfsr_source.py b/gr-digital/python/qa_glfsr_source.py
new file mode 100755
index 000000000..157520d7f
--- /dev/null
+++ b/gr-digital/python/qa_glfsr_source.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+#
+# Copyright 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
+import digital_swig as digital
+
+class test_glfsr_source(gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_000_make_b(self):
+ src = digital.glfsr_source_b(16)
+ self.assertEquals(src.mask(), 0x8016)
+ self.assertEquals(src.period(), 2**16-1)
+
+ def test_001_degree_b(self):
+ self.assertRaises(RuntimeError,
+ lambda: gr.glfsr_source_b(0))
+ self.assertRaises(RuntimeError,
+ lambda: gr.glfsr_source_b(33))
+
+ def test_002_correlation_b(self):
+ for degree in range(1,11): # Higher degrees take too long to correlate
+ src = digital.glfsr_source_b(degree, False)
+ b2f = digital.chunks_to_symbols_bf((-1.0,1.0), 1)
+ dst = gr.vector_sink_f()
+ del self.tb # Discard existing top block
+ self.tb = gr.top_block()
+ self.tb.connect(src, b2f, dst)
+ self.tb.run()
+ self.tb.disconnect_all()
+ actual_result = dst.data()
+ R = auto_correlate(actual_result)
+ self.assertEqual(R[0], float(len(R))) # Auto-correlation peak at origin
+ for i in range(len(R)-1):
+ self.assertEqual(R[i+1], -1.0) # Auto-correlation minimum everywhere else
+
+ def test_003_make_f(self):
+ src = digital.glfsr_source_f(16)
+ self.assertEquals(src.mask(), 0x8016)
+ self.assertEquals(src.period(), 2**16-1)
+
+ def test_004_degree_f(self):
+ self.assertRaises(RuntimeError,
+ lambda: gr.glfsr_source_f(0))
+ self.assertRaises(RuntimeError,
+ lambda: gr.glfsr_source_f(33))
+ def test_005_correlation_f(self):
+ for degree in range(1,11): # Higher degrees take too long to correlate
+ src = digital.glfsr_source_f(degree, False)
+ dst = gr.vector_sink_f()
+ del self.tb # Discard existing top block
+ self.tb = gr.top_block()
+ self.tb.connect(src, dst)
+ self.tb.run()
+
+ actual_result = dst.data()
+ R = auto_correlate(actual_result)
+ self.assertEqual(R[0], float(len(R))) # Auto-correlation peak at origin
+ for i in range(len(R)-1):
+ self.assertEqual(R[i+1], -1.0) # Auto-correlation minimum everywhere else
+
+def auto_correlate(data):
+ l = len(data)
+ R = [0,]*l
+ for lag in range(l):
+ for i in range(l):
+ R[lag] += data[i]*data[i-lag]
+ return R
+
+if __name__ == '__main__':
+ gr_unittest.run(test_glfsr_source, "test_glfsr_source.xml")
diff --git a/gr-digital/python/qa_map.py b/gr-digital/python/qa_map.py
new file mode 100755
index 000000000..3ad99a2c1
--- /dev/null
+++ b/gr-digital/python/qa_map.py
@@ -0,0 +1,60 @@
+#!/usr/bin/env python
+#
+# 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.
+#
+
+from gnuradio import gr, gr_unittest
+import digital_swig as digital
+
+class test_map(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def helper(self, symbols):
+ src_data = [0, 1, 2, 3, 0, 1, 2, 3]
+ expected_data = map(lambda x: symbols[x], src_data)
+ src = gr.vector_source_b (src_data)
+ op = digital.map_bb(symbols)
+ dst = gr.vector_sink_b ()
+ self.tb.connect (src, op, dst)
+ self.tb.run ()
+
+ result_data = list(dst.data())
+ self.assertEqual (expected_data, result_data)
+
+ def test_001(self):
+ symbols = [0, 0, 0, 0]
+ self.helper(symbols)
+
+ def test_002(self):
+ symbols = [3, 2, 1, 0]
+ self.helper(symbols)
+
+ def test_003(self):
+ symbols = [8-1, 32-1, 128, 256-1]
+ self.helper(symbols)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_map, "test_map.xml")
+
diff --git a/gr-digital/python/qa_pfb_clock_sync.py b/gr-digital/python/qa_pfb_clock_sync.py
new file mode 100755
index 000000000..06c8a60ba
--- /dev/null
+++ b/gr-digital/python/qa_pfb_clock_sync.py
@@ -0,0 +1,142 @@
+#!/usr/bin/env python
+#
+# Copyright 2011 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
+import digital_swig as digital
+import random, cmath
+
+class test_pfb_clock_sync(gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test01 (self):
+ # Test BPSK sync
+ excess_bw = 0.35
+
+ sps = 4
+ loop_bw = cmath.pi/100.0
+ nfilts = 32
+ init_phase = nfilts/2
+ max_rate_deviation = 1.5
+ osps = 1
+
+ ntaps = 11 * int(sps*nfilts)
+ taps = gr.firdes.root_raised_cosine(nfilts, nfilts*sps,
+ 1.0, excess_bw, ntaps)
+
+ self.test = digital.pfb_clock_sync_ccf(sps, loop_bw, taps,
+ nfilts, init_phase,
+ max_rate_deviation,
+ osps)
+
+ data = 1000*[complex(1,0), complex(-1,0)]
+ self.src = gr.vector_source_c(data, False)
+
+ # pulse shaping interpolation filter
+ rrc_taps = gr.firdes.root_raised_cosine(
+ nfilts, # gain
+ nfilts, # sampling rate based on 32 filters in resampler
+ 1.0, # symbol rate
+ excess_bw, # excess bandwidth (roll-off factor)
+ ntaps)
+ self.rrc_filter = gr.pfb_arb_resampler_ccf(sps, rrc_taps)
+
+ self.snk = gr.vector_sink_c()
+
+ self.tb.connect(self.src, self.rrc_filter, self.test, self.snk)
+ self.tb.run()
+
+ expected_result = 1000*[complex(-1,0), complex(1,0)]
+ dst_data = self.snk.data()
+
+ # Only compare last Ncmp samples
+ Ncmp = 100
+ len_e = len(expected_result)
+ len_d = len(dst_data)
+ expected_result = expected_result[len_e - Ncmp:]
+ dst_data = dst_data[len_d - Ncmp:]
+
+ #for e,d in zip(expected_result, dst_data):
+ # print e, d
+
+ self.assertComplexTuplesAlmostEqual (expected_result, dst_data, 1)
+
+
+ def test02 (self):
+ # Test real BPSK sync
+ excess_bw = 0.35
+
+ sps = 4
+ loop_bw = cmath.pi/100.0
+ nfilts = 32
+ init_phase = nfilts/2
+ max_rate_deviation = 1.5
+ osps = 1
+
+ ntaps = 11 * int(sps*nfilts)
+ taps = gr.firdes.root_raised_cosine(nfilts, nfilts*sps,
+ 1.0, excess_bw, ntaps)
+
+ self.test = digital.pfb_clock_sync_fff(sps, loop_bw, taps,
+ nfilts, init_phase,
+ max_rate_deviation,
+ osps)
+
+ data = 1000*[1, -1]
+ self.src = gr.vector_source_f(data, False)
+
+ # pulse shaping interpolation filter
+ rrc_taps = gr.firdes.root_raised_cosine(
+ nfilts, # gain
+ nfilts, # sampling rate based on 32 filters in resampler
+ 1.0, # symbol rate
+ excess_bw, # excess bandwidth (roll-off factor)
+ ntaps)
+ self.rrc_filter = gr.pfb_arb_resampler_fff(sps, rrc_taps)
+
+ self.snk = gr.vector_sink_f()
+
+ self.tb.connect(self.src, self.rrc_filter, self.test, self.snk)
+ self.tb.run()
+
+ expected_result = 1000*[-1, 1]
+ dst_data = self.snk.data()
+
+ # Only compare last Ncmp samples
+ Ncmp = 100
+ len_e = len(expected_result)
+ len_d = len(dst_data)
+ expected_result = expected_result[len_e - Ncmp:]
+ dst_data = dst_data[len_d - Ncmp:]
+
+ #for e,d in zip(expected_result, dst_data):
+ # print e, d
+
+ self.assertComplexTuplesAlmostEqual (expected_result, dst_data, 1)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_pfb_clock_sync, "test_pfb_clock_sync.xml")
diff --git a/volk/python/qa_square.py b/gr-digital/python/qa_pn_correlator_cc.py
index c74bc25ef..377bef5fe 100755
--- a/volk/python/qa_square.py
+++ b/gr-digital/python/qa_pn_correlator_cc.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2010 Free Software Foundation, Inc.
+# Copyright 2007,2010,2012 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -21,27 +21,31 @@
#
from gnuradio import gr, gr_unittest
-import volk_swig as volk
+import digital_swig as digital
-class qa_volk(gr_unittest.TestCase):
+class test_pn_correlator_cc(gr_unittest.TestCase):
def setUp(self):
- self.tb = gr.top_block()
+ self.tb = gr.top_block ()
def tearDown(self):
self.tb = None
- def test_001_square_ff(self):
- src_data = (-3, 4, -5.5, 2, 3)
- expected_result = (9, 16, 30.25, 4, 9)
- src = gr.vector_source_f(src_data)
- sqr = volk.square_ff()
- dst = gr.vector_sink_f()
- self.tb.connect(src, sqr)
- self.tb.connect(sqr, dst)
+ def test_000_make(self):
+ c = digital.pn_correlator_cc(10)
+
+ def test_001_correlate(self):
+ degree = 10
+ length = 2**degree-1
+ src = digital.glfsr_source_f(degree)
+ head = gr.head(gr.sizeof_float, length*length)
+ f2c = gr.float_to_complex()
+ corr = digital.pn_correlator_cc(degree)
+ dst = gr.vector_sink_c()
+ self.tb.connect(src, head, f2c, corr, dst)
self.tb.run()
- result_data = dst.data()
- self.assertFloatTuplesAlmostEqual(expected_result, result_data, 6)
+ data = dst.data()
+ self.assertEqual(data[-1], (1.0+0j))
if __name__ == '__main__':
- gr_unittest.main()
+ gr_unittest.run(test_pn_correlator_cc, "test_pn_correlator_cc.xml")
diff --git a/gr-digital/python/qa_probe_density.py b/gr-digital/python/qa_probe_density.py
new file mode 100755
index 000000000..c5b7e0e7c
--- /dev/null
+++ b/gr-digital/python/qa_probe_density.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+#
+# 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.
+#
+
+from gnuradio import gr, gr_unittest
+import digital_swig as digital
+
+class test_probe_density(gr_unittest.TestCase):
+
+ def setUp(self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_001(self):
+ src_data = [0, 1, 0, 1]
+ expected_data = 1
+ src = gr.vector_source_b (src_data)
+ op = digital.probe_density_b(1)
+ self.tb.connect (src, op)
+ self.tb.run ()
+
+ result_data = op.density()
+ self.assertEqual (expected_data, result_data)
+
+
+ def test_002(self):
+ src_data = [1, 1, 1, 1]
+ expected_data = 1
+ src = gr.vector_source_b (src_data)
+ op = digital.probe_density_b(0.01)
+ self.tb.connect (src, op)
+ self.tb.run ()
+
+ result_data = op.density()
+ self.assertEqual (expected_data, result_data)
+
+ def test_003(self):
+ src_data = [0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
+ expected_data = 0.95243
+ src = gr.vector_source_b (src_data)
+ op = digital.probe_density_b(0.01)
+ self.tb.connect (src, op)
+ self.tb.run ()
+
+ result_data = op.density()
+ print result_data
+ self.assertAlmostEqual (expected_data, result_data, 5)
+
+if __name__ == '__main__':
+ gr_unittest.run(test_probe_density, "test_probe_density.xml")
+
diff --git a/gr-digital/python/qa_scrambler.py b/gr-digital/python/qa_scrambler.py
new file mode 100755
index 000000000..f5bd61242
--- /dev/null
+++ b/gr-digital/python/qa_scrambler.py
@@ -0,0 +1,65 @@
+#!/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 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
+import digital_swig as digital
+
+class test_scrambler(gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block()
+
+ def tearDown(self):
+ self.tb = None
+
+ def test_scrambler_descrambler(self):
+ src_data = (1,)*1000
+ src = gr.vector_source_b(src_data, False)
+ scrambler = digital.scrambler_bb(0x8a, 0x7F, 7) # CCSDS 7-bit scrambler
+ descrambler = digital.descrambler_bb(0x8a, 0x7F, 7)
+ dst = gr.vector_sink_b()
+ self.tb.connect(src, scrambler, descrambler, dst)
+ self.tb.run()
+ self.assertEqual(tuple(src_data[:-8]), dst.data()[8:]) # skip garbage during synchronization
+
+ def test_additive_scrambler(self):
+ src_data = (1,)*1000
+ src = gr.vector_source_b(src_data, False)
+ scrambler = digital.additive_scrambler_bb(0x8a, 0x7f, 7)
+ descrambler = digital.additive_scrambler_bb(0x8a, 0x7f, 7)
+ dst = gr.vector_sink_b()
+ self.tb.connect(src, scrambler, descrambler, dst)
+ self.tb.run()
+ self.assertEqual(src_data, dst.data())
+
+ def test_additive_scrambler_reset(self):
+ src_data = (1,)*1000
+ src = gr.vector_source_b(src_data, False)
+ scrambler = digital.additive_scrambler_bb(0x8a, 0x7f, 7, 100)
+ descrambler = digital.additive_scrambler_bb(0x8a, 0x7f, 7, 100)
+ dst = gr.vector_sink_b()
+ self.tb.connect(src, scrambler, descrambler, dst)
+ self.tb.run()
+ self.assertEqual(src_data, dst.data())
+
+if __name__ == '__main__':
+ gr_unittest.run(test_scrambler, "test_scrambler.xml")
diff --git a/gr-digital/python/qa_simple_framer.py b/gr-digital/python/qa_simple_framer.py
new file mode 100755
index 000000000..09b2d329b
--- /dev/null
+++ b/gr-digital/python/qa_simple_framer.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,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
+import digital_swig as digital
+import math
+
+class test_simple_framer (gr_unittest.TestCase):
+
+ def setUp (self):
+ self.tb = gr.top_block ()
+
+ def tearDown (self):
+ self.tb = None
+
+ def test_simple_framer_001 (self):
+ src_data = (0x00, 0x11, 0x22, 0x33,
+ 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb,
+ 0xcc, 0xdd, 0xee, 0xff)
+
+ expected_result = (
+ 0xac, 0xdd, 0xa4, 0xe2, 0xf2, 0x8c, 0x20, 0xfc, 0x00, 0x00, 0x11, 0x22, 0x33, 0x55,
+ 0xac, 0xdd, 0xa4, 0xe2, 0xf2, 0x8c, 0x20, 0xfc, 0x01, 0x44, 0x55, 0x66, 0x77, 0x55,
+ 0xac, 0xdd, 0xa4, 0xe2, 0xf2, 0x8c, 0x20, 0xfc, 0x02, 0x88, 0x99, 0xaa, 0xbb, 0x55,
+ 0xac, 0xdd, 0xa4, 0xe2, 0xf2, 0x8c, 0x20, 0xfc, 0x03, 0xcc, 0xdd, 0xee, 0xff, 0x55)
+
+ src = gr.vector_source_b (src_data)
+ op = digital.simple_framer (4)
+ dst = gr.vector_sink_b ()
+ self.tb.connect (src, op)
+ self.tb.connect (op, dst)
+ self.tb.run ()
+ result_data = dst.data ()
+ self.assertEqual (expected_result, result_data)
+
+
+if __name__ == '__main__':
+ gr_unittest.run(test_simple_framer, "test_simple_framer.xml")
+
diff --git a/gr-digital/swig/CMakeLists.txt b/gr-digital/swig/CMakeLists.txt
index 6f2c2251a..0c129e181 100644
--- a/gr-digital/swig/CMakeLists.txt
+++ b/gr-digital/swig/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright 2011 Free Software Foundation, Inc.
+# Copyright 2011,2012 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -18,23 +18,107 @@
# Boston, MA 02110-1301, USA.
########################################################################
-# Setup swig generation
+# generate helper scripts to expand templated files
########################################################################
include(GrPython)
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py "
+#!${PYTHON_EXECUTABLE}
+
+import sys, os, re
+sys.path.append('${GR_CORE_PYTHONPATH}')
+os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
+os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
+
+if __name__ == '__main__':
+ import build_utils
+ root, inp = sys.argv[1:3]
+ for sig in sys.argv[3:]:
+ name = re.sub ('X+', sig, root)
+ d = build_utils.standard_dict(name, sig, 'digital')
+ build_utils.expand_template(d, inp)
+
+")
+
+macro(expand_i root)
+ # make a list of the .i generated files
+ unset(expanded_files_i)
+ foreach(sig ${ARGN})
+ string(REGEX REPLACE "X+" ${sig} name ${root})
+ list(APPEND expanded_files_i ${CMAKE_CURRENT_BINARY_DIR}/${name}.i)
+ endforeach(sig)
+
+ #create a command to generate the .i files
+ add_custom_command(
+ OUTPUT ${expanded_files_i}
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.i.t
+ COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
+ ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
+ ${root} ${root}.i.t ${ARGN}
+ )
+
+ # Lists of generated i files
+ list(APPEND generated_swigs ${expanded_files_i})
+endmacro(expand_i)
+
+
+########################################################################
+# Invoke macro to generate various sources
+########################################################################
+expand_i(digital_chunks_to_symbols_XX bf bc sf sc if ic)
+
+add_custom_target(digital_generated_swigs DEPENDS
+ ${generated_swigs}
+)
+
+########################################################################
+# Setup swig generation
+########################################################################
include(GrSwig)
-set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/digital_swig_doc.i)
-set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../include)
+########################################################################
+# Create the master gengen swig include files
+########################################################################
+set(generated_index ${CMAKE_CURRENT_BINARY_DIR}/digital_generated.i.in)
+file(WRITE ${generated_index} "
+//
+// This file is machine generated. All edits will be overwritten
+//
+")
+
+file(APPEND ${generated_index} "%include \"gnuradio.i\"\n\n")
+file(APPEND ${generated_index} "%{\n")
+
+foreach(swig_file ${generated_swigs})
+ get_filename_component(name ${swig_file} NAME_WE)
+ file(APPEND ${generated_index} "#include<${name}.h>\n")
+endforeach(swig_file)
+file(APPEND ${generated_index} "%}\n")
+
+foreach(swig_file ${generated_swigs})
+ get_filename_component(name ${swig_file} NAME)
+ file(APPEND ${generated_index} "%include<${name}>\n")
+endforeach(swig_file)
+
+execute_process(
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${generated_index} ${CMAKE_CURRENT_BINARY_DIR}/digital_generated.i
+)
set(GR_SWIG_INCLUDE_DIRS
${GR_DIGITAL_INCLUDE_DIRS}
${GNURADIO_CORE_SWIG_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}/../include
)
+# Setup swig docs to depend on includes and pull in from build directory
set(GR_SWIG_LIBRARIES gnuradio-digital)
-
+set(GR_SWIG_TARGET_DEPS digital_generated_includes)
+set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/digital_swig_doc.i)
+set(GR_SWIG_DOC_DIRS
+ ${CMAKE_CURRENT_SOURCE_DIR}/../include
+ ${CMAKE_CURRENT_BINARY_DIR}/../include)
GR_SWIG_MAKE(digital_swig digital_swig.i)
-
GR_SWIG_INSTALL(
TARGETS digital_swig
DESTINATION ${GR_PYTHON_DIR}/gnuradio/digital
@@ -45,19 +129,34 @@ install(
FILES
digital_swig.i
${CMAKE_CURRENT_BINARY_DIR}/digital_swig_doc.i
+ ${CMAKE_CURRENT_BINARY_DIR}/digital_generated.i
+ ${generated_swigs}
+ digital_additive_scrambler_bb.i
digital_binary_slicer_fb.i
+ digital_bytes_to_syms.i
digital_clock_recovery_mm_cc.i
digital_clock_recovery_mm_ff.i
+ digital_cma_equalizer_cc.i
digital_constellation.i
digital_constellation_receiver_cb.i
digital_constellation_decoder_cb.i
digital_correlate_access_code_bb.i
+ digital_correlate_access_code_tag_bb.i
digital_costas_loop_cc.i
- digital_cma_equalizer_cc.i
+ digital_cpmmod_bc.i
digital_crc32.i
+ digital_descrambler_bb.i
+ digital_diff_decoder_bb.i
+ digital_diff_encoder_bb.i
+ digital_diff_phasor_cc.i
digital_fll_band_edge_cc.i
+ digital_framer_sink_1.i
+ digital_glfsr_source_b.i
+ digital_glfsr_source_f.i
+ digital_gmskmod_bc.i
digital_lms_dd_equalizer_cc.i
digital_kurtotic_equalizer_cc.i
+ digital_map_bb.i
digital_mpsk_receiver_cc.i
digital_mpsk_snr_est_cc.i
digital_ofdm_cyclic_prefixer.i
@@ -66,9 +165,14 @@ install(
digital_ofdm_insert_preamble.i
digital_ofdm_mapper_bcv.i
digital_ofdm_sampler.i
+ digital_packet_sink.i
+ digital_pfb_clock_sync_ccf.i
+ digital_pfb_clock_sync_fff.i
+ digital_pn_correlator_cc.i
+ digital_probe_density_b.i
digital_probe_mpsk_snr_est_c.i
- digital_gmskmod_bc.i
- digital_cpmmod_bc.i
+ digital_scrambler_bb.i
+ digital_simple_framer.i
DESTINATION ${GR_INCLUDE_DIR}/gnuradio/swig
COMPONENT "digital_swig"
)
diff --git a/volk/python/volk_square_ff.i b/gr-digital/swig/digital_additive_scrambler_bb.i
index 5456c81fd..b063f0672 100644
--- a/volk/python/volk_square_ff.i
+++ b/gr-digital/swig/digital_additive_scrambler_bb.i
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2010 Free Software Foundation, Inc.
+ * Copyright 2008,2010,2012 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -14,24 +14,18 @@
* 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.
+ * 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.
*/
-/*
- * First arg is the package prefix.
- * Second arg is the name of the class minus the prefix.
- *
- * This does some behind-the-scenes magic so we can
- * access gr_example_square_ff from python as howto.square_ff
- */
-GR_SWIG_BLOCK_MAGIC(volk,square_ff);
+GR_SWIG_BLOCK_MAGIC(digital,additive_scrambler_bb);
-volk_square_ff_sptr volk_make_square_ff ();
+digital_additive_scrambler_bb_sptr
+digital_make_additive_scrambler_bb(int mask, int seed,
+ int len, int count=0);
-class volk_square_ff : public gr_sync_block
+class digital_additive_scrambler_bb : public gr_sync_block
{
-private:
- volk_square_ff();
};
diff --git a/gr-digital/swig/digital_bytes_to_syms.i b/gr-digital/swig/digital_bytes_to_syms.i
new file mode 100644
index 000000000..cf23f035c
--- /dev/null
+++ b/gr-digital/swig/digital_bytes_to_syms.i
@@ -0,0 +1,29 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(digital,bytes_to_syms);
+
+digital_bytes_to_syms_sptr digital_make_bytes_to_syms();
+
+class digital_bytes_to_syms : public gr_sync_interpolator
+{
+};
diff --git a/gr-digital/swig/digital_chunks_to_symbols_XX.i.t b/gr-digital/swig/digital_chunks_to_symbols_XX.i.t
new file mode 100644
index 000000000..a80ba2af1
--- /dev/null
+++ b/gr-digital/swig/digital_chunks_to_symbols_XX.i.t
@@ -0,0 +1,38 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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.
+ */
+
+// @WARNING@
+
+GR_SWIG_BLOCK_MAGIC(digital,@BASE_NAME@);
+
+@SPTR_NAME@ digital_make_@BASE_NAME@
+(const std::vector<@O_TYPE@> &symbol_table, const int D = 1);
+
+class @NAME@ : public gr_sync_interpolator
+{
+private:
+ @NAME@ (const std::vector<@O_TYPE@> &symbol_table, const int D = 1);
+
+public:
+ int D () const { return d_D; }
+ std::vector<@O_TYPE@> symbol_table () const { return d_symbol_table; }
+};
diff --git a/gr-digital/swig/digital_constellation_decoder_cb.i b/gr-digital/swig/digital_constellation_decoder_cb.i
index 53d3fe8e0..547f57ee6 100644
--- a/gr-digital/swig/digital_constellation_decoder_cb.i
+++ b/gr-digital/swig/digital_constellation_decoder_cb.i
@@ -31,7 +31,7 @@ class digital_constellation_decoder_cb : public gr_sync_block
digital_constellation_decoder_cb (digital_constellation_sptr constellation);
friend digital_constellation_decoder_cb_sptr
- gr_make_constellation_decoder_cb (digital_constellation_sptr constellation);
+ digital_make_constellation_decoder_cb (digital_constellation_sptr constellation);
public:
~digital_constellation_decoder_cb();
diff --git a/gr-digital/swig/digital_correlate_access_code_tag_bb.i b/gr-digital/swig/digital_correlate_access_code_tag_bb.i
new file mode 100644
index 000000000..03f20148a
--- /dev/null
+++ b/gr-digital/swig/digital_correlate_access_code_tag_bb.i
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(digital,correlate_access_code_tag_bb);
+
+digital_correlate_access_code_tag_bb_sptr
+digital_make_correlate_access_code_tag_bb(const std::string &access_code,
+ int threshold,
+ const std::string &tag_name)
+ throw(std::out_of_range);
+
+class digital_correlate_access_code_tag_bb : public gr_sync_block
+{
+ public:
+ bool set_access_code(const std::string &access_code);
+};
diff --git a/gr-digital/swig/digital_descrambler_bb.i b/gr-digital/swig/digital_descrambler_bb.i
new file mode 100644
index 000000000..59de806fb
--- /dev/null
+++ b/gr-digital/swig/digital_descrambler_bb.i
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(digital,descrambler_bb);
+
+digital_descrambler_bb_sptr
+digital_make_descrambler_bb(int mask, int seed, int len);
+
+class digital_descrambler_bb : public gr_sync_block
+{
+};
diff --git a/gr-digital/swig/digital_diff_decoder_bb.i b/gr-digital/swig/digital_diff_decoder_bb.i
new file mode 100644
index 000000000..f9741c771
--- /dev/null
+++ b/gr-digital/swig/digital_diff_decoder_bb.i
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(digital,diff_decoder_bb)
+
+digital_diff_decoder_bb_sptr
+digital_make_diff_decoder_bb(unsigned int modulus);
+
+class digital_diff_decoder_bb : public gr_sync_block
+{
+};
diff --git a/gr-digital/swig/digital_diff_encoder_bb.i b/gr-digital/swig/digital_diff_encoder_bb.i
new file mode 100644
index 000000000..45a4589bf
--- /dev/null
+++ b/gr-digital/swig/digital_diff_encoder_bb.i
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(digital,diff_encoder_bb)
+
+digital_diff_encoder_bb_sptr
+digital_make_diff_encoder_bb(unsigned int modulus);
+
+class digital_diff_encoder_bb : public gr_sync_block
+{
+};
diff --git a/gr-digital/swig/digital_diff_phasor_cc.i b/gr-digital/swig/digital_diff_phasor_cc.i
new file mode 100644
index 000000000..b1e20eb99
--- /dev/null
+++ b/gr-digital/swig/digital_diff_phasor_cc.i
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(digital,diff_phasor_cc)
+
+digital_diff_phasor_cc_sptr
+digital_make_diff_phasor_cc();
+
+class digital_diff_phasor_cc : public gr_sync_block
+{
+};
diff --git a/gr-digital/swig/digital_framer_sink_1.i b/gr-digital/swig/digital_framer_sink_1.i
new file mode 100644
index 000000000..a5c56560d
--- /dev/null
+++ b/gr-digital/swig/digital_framer_sink_1.i
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(digital,framer_sink_1);
+
+digital_framer_sink_1_sptr
+digital_make_framer_sink_1(gr_msg_queue_sptr target_queue);
+
+class digital_framer_sink_1 : public gr_sync_block
+{
+};
diff --git a/gr-digital/swig/digital_glfsr_source_b.i b/gr-digital/swig/digital_glfsr_source_b.i
new file mode 100644
index 000000000..b1c487209
--- /dev/null
+++ b/gr-digital/swig/digital_glfsr_source_b.i
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(digital,glfsr_source_b);
+
+digital_glfsr_source_b_sptr
+digital_make_glfsr_source_b(int degree, bool repeat=true,
+ int mask=0, int seed=1)
+ throw (std::runtime_error);
+
+class digital_glfsr_source_b : public gr_sync_block
+{
+public:
+ unsigned int period() const;
+ int mask() const;
+};
diff --git a/gr-digital/swig/digital_glfsr_source_f.i b/gr-digital/swig/digital_glfsr_source_f.i
new file mode 100644
index 000000000..4d94d8cd4
--- /dev/null
+++ b/gr-digital/swig/digital_glfsr_source_f.i
@@ -0,0 +1,35 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(digital,glfsr_source_f);
+
+digital_glfsr_source_f_sptr
+digital_make_glfsr_source_f(int degree, bool repeat=true,
+ int mask=0, int seed=1)
+ throw (std::runtime_error);
+
+class digital_glfsr_source_f : public gr_sync_block
+{
+public:
+ unsigned int period() const;
+ int mask() const;
+};
diff --git a/gr-digital/swig/digital_map_bb.i b/gr-digital/swig/digital_map_bb.i
new file mode 100644
index 000000000..50117d4f5
--- /dev/null
+++ b/gr-digital/swig/digital_map_bb.i
@@ -0,0 +1,31 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(digital,map_bb);
+
+digital_map_bb_sptr
+digital_make_map_bb(const std::vector<int> &map);
+
+class digital_map_bb : public gr_sync_block
+{
+};
+
diff --git a/gr-digital/swig/digital_packet_sink.i b/gr-digital/swig/digital_packet_sink.i
new file mode 100644
index 000000000..84f81f75c
--- /dev/null
+++ b/gr-digital/swig/digital_packet_sink.i
@@ -0,0 +1,34 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(digital,packet_sink)
+
+digital_packet_sink_sptr
+digital_make_packet_sink(const std::vector<unsigned char>& sync_vector,
+ gr_msg_queue_sptr target_queue,
+ int threshold = -1); // -1 -> use default
+
+class digital_packet_sink : public gr_sync_block
+{
+ public:
+ bool carrier_sensed() const;
+};
diff --git a/gr-digital/swig/digital_pfb_clock_sync_ccf.i b/gr-digital/swig/digital_pfb_clock_sync_ccf.i
new file mode 100644
index 000000000..dbba614cc
--- /dev/null
+++ b/gr-digital/swig/digital_pfb_clock_sync_ccf.i
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(digital,pfb_clock_sync_ccf);
+
+digital_pfb_clock_sync_ccf_sptr
+digital_make_pfb_clock_sync_ccf(double sps, float loop_bw,
+ const std::vector<float> &taps,
+ unsigned int filter_size=32,
+ float init_phase=0,
+ float max_rate_deviation=1.5,
+ int osps=1);
+
+class digital_pfb_clock_sync_ccf : public gr_block
+{
+ public:
+ void set_taps(const std::vector<float> &taps,
+ std::vector< std::vector<float> > &ourtaps,
+ std::vector<gr_fir_ccf*> &ourfilter);
+
+ std::vector< std::vector<float> > get_taps();
+ std::vector< std::vector<float> > get_diff_taps();
+ std::vector<float> get_channel_taps(int channel);
+ std::vector<float> get_diff_channel_taps(int channel);
+ std::string get_taps_as_string();
+ std::string get_diff_taps_as_string();
+
+ void set_loop_bandwidth(float bw);
+ void set_damping_factor(float df);
+ void set_alpha(float alpha);
+ void set_beta(float beta);
+ void set_max_rate_deviation(float m);
+
+ float get_loop_bandwidth() const;
+ float get_damping_factor() const;
+ float get_alpha() const;
+ float get_beta() const;
+ float get_clock_rate() const;
+};
diff --git a/gr-digital/swig/digital_pfb_clock_sync_fff.i b/gr-digital/swig/digital_pfb_clock_sync_fff.i
new file mode 100644
index 000000000..956495e5d
--- /dev/null
+++ b/gr-digital/swig/digital_pfb_clock_sync_fff.i
@@ -0,0 +1,58 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009,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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(digital,pfb_clock_sync_fff);
+
+digital_pfb_clock_sync_fff_sptr
+digital_make_pfb_clock_sync_fff(double sps, float loop_bw,
+ const std::vector<float> &taps,
+ unsigned int filter_size=32,
+ float init_phase=0,
+ float max_rate_deviation=1.5,
+ int osps=1);
+
+class digital_pfb_clock_sync_fff : public gr_block
+{
+ public:
+ void set_taps (const std::vector<float> &taps,
+ std::vector< std::vector<float> > &ourtaps,
+ std::vector<gr_fir_fff*> &ourfilter);
+
+ std::vector< std::vector<float> > get_taps();
+ std::vector< std::vector<float> > get_diff_taps();
+ std::vector<float> get_channel_taps(int channel);
+ std::vector<float> get_diff_channel_taps(int channel);
+ std::string get_taps_as_string();
+ std::string get_diff_taps_as_string();
+
+ void set_loop_bandwidth(float bw);
+ void set_damping_factor(float df);
+ void set_alpha(float alpha);
+ void set_beta(float beta);
+ void set_max_rate_deviation(float m);
+
+ float get_loop_bandwidth() const;
+ float get_damping_factor() const;
+ float get_alpha() const;
+ float get_beta() const;
+ float get_clock_rate() const;
+};
diff --git a/gr-digital/swig/digital_pn_correlator_cc.i b/gr-digital/swig/digital_pn_correlator_cc.i
new file mode 100644
index 000000000..11ccf12c2
--- /dev/null
+++ b/gr-digital/swig/digital_pn_correlator_cc.i
@@ -0,0 +1,32 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(digital,pn_correlator_cc)
+
+digital_pn_correlator_cc_sptr
+digital_make_pn_correlator_cc(int degree, int mask=0, int seed=1);
+
+class digital_pn_correlator_cc : public gr_sync_decimator
+{
+ protected:
+ digital_pn_correlator_cc();
+};
diff --git a/gr-digital/swig/digital_probe_density_b.i b/gr-digital/swig/digital_probe_density_b.i
new file mode 100644
index 000000000..b0c8a119a
--- /dev/null
+++ b/gr-digital/swig/digital_probe_density_b.i
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(digital,probe_density_b);
+
+digital_probe_density_b_sptr
+digital_make_probe_density_b(double alpha);
+
+class digital_probe_density_b : public gr_sync_block
+{
+public:
+ double density() const;
+ void set_alpha(double alpha);
+};
diff --git a/gr-digital/swig/digital_scrambler_bb.i b/gr-digital/swig/digital_scrambler_bb.i
new file mode 100644
index 000000000..ac9abef92
--- /dev/null
+++ b/gr-digital/swig/digital_scrambler_bb.i
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(digital,scrambler_bb);
+
+digital_scrambler_bb_sptr
+digital_make_scrambler_bb(int mask, int seed, int len);
+
+class digital_scrambler_bb : public gr_sync_block
+{
+};
diff --git a/gr-digital/swig/digital_simple_framer.i b/gr-digital/swig/digital_simple_framer.i
new file mode 100644
index 000000000..a376317c5
--- /dev/null
+++ b/gr-digital/swig/digital_simple_framer.i
@@ -0,0 +1,30 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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.
+ */
+
+GR_SWIG_BLOCK_MAGIC(digital,simple_framer);
+
+digital_simple_framer_sptr
+digital_make_simple_framer(int payload_bytesize);
+
+class digital_simple_framer : public gr_block
+{
+};
diff --git a/gr-digital/swig/digital_swig.i b/gr-digital/swig/digital_swig.i
index 4e9c660bc..191076d75 100644
--- a/gr-digital/swig/digital_swig.i
+++ b/gr-digital/swig/digital_swig.i
@@ -35,8 +35,13 @@ enum snr_est_type_t {
%include <gri_control_loop.i>
+// Bring in generated blocks
+%include "digital_generated.i"
+
%{
+#include "digital_additive_scrambler_bb.h"
#include "digital_binary_slicer_fb.h"
+#include "digital_bytes_to_syms.h"
#include "digital_clock_recovery_mm_cc.h"
#include "digital_clock_recovery_mm_ff.h"
#include "digital_cma_equalizer_cc.h"
@@ -44,11 +49,22 @@ enum snr_est_type_t {
#include "digital_constellation_decoder_cb.h"
#include "digital_constellation_receiver_cb.h"
#include "digital_correlate_access_code_bb.h"
+#include "digital_correlate_access_code_tag_bb.h"
#include "digital_costas_loop_cc.h"
+#include "digital_cpmmod_bc.h"
#include "digital_crc32.h"
+#include "digital_descrambler_bb.h"
+#include "digital_diff_decoder_bb.h"
+#include "digital_diff_encoder_bb.h"
+#include "digital_diff_phasor_cc.h"
#include "digital_fll_band_edge_cc.h"
+#include "digital_framer_sink_1.h"
+#include "digital_glfsr_source_b.h"
+#include "digital_glfsr_source_f.h"
+#include "digital_gmskmod_bc.h"
#include "digital_kurtotic_equalizer_cc.h"
#include "digital_lms_dd_equalizer_cc.h"
+#include "digital_map_bb.h"
#include "digital_mpsk_receiver_cc.h"
#include "digital_mpsk_snr_est_cc.h"
#include "digital_ofdm_cyclic_prefixer.h"
@@ -57,11 +73,18 @@ enum snr_est_type_t {
#include "digital_ofdm_insert_preamble.h"
#include "digital_ofdm_mapper_bcv.h"
#include "digital_ofdm_sampler.h"
+#include "digital_packet_sink.h"
+#include "digital_pfb_clock_sync_ccf.h"
+#include "digital_pfb_clock_sync_fff.h"
+#include "digital_pn_correlator_cc.h"
+#include "digital_probe_density_b.h"
#include "digital_probe_mpsk_snr_est_c.h"
-#include "digital_cpmmod_bc.h"
-#include "digital_gmskmod_bc.h"
+#include "digital_scrambler_bb.h"
+#include "digital_simple_framer.h"
%}
+%include "digital_additive_scrambler_bb.i"
+%include "digital_bytes_to_syms.i"
%include "digital_binary_slicer_fb.i"
%include "digital_clock_recovery_mm_cc.i"
%include "digital_clock_recovery_mm_ff.i"
@@ -70,11 +93,22 @@ enum snr_est_type_t {
%include "digital_constellation_decoder_cb.i"
%include "digital_constellation_receiver_cb.i"
%include "digital_correlate_access_code_bb.i"
+%include "digital_correlate_access_code_tag_bb.i"
%include "digital_costas_loop_cc.i"
+%include "digital_cpmmod_bc.i"
%include "digital_crc32.i"
+%include "digital_descrambler_bb.i"
+%include "digital_diff_decoder_bb.i"
+%include "digital_diff_encoder_bb.i"
+%include "digital_diff_phasor_cc.i"
%include "digital_fll_band_edge_cc.i"
+%include "digital_framer_sink_1.i"
+%include "digital_glfsr_source_b.i"
+%include "digital_glfsr_source_f.i"
+%include "digital_gmskmod_bc.i"
%include "digital_kurtotic_equalizer_cc.i"
%include "digital_lms_dd_equalizer_cc.i"
+%include "digital_map_bb.i"
%include "digital_mpsk_receiver_cc.i"
%include "digital_mpsk_snr_est_cc.i"
%include "digital_ofdm_cyclic_prefixer.i"
@@ -83,6 +117,11 @@ enum snr_est_type_t {
%include "digital_ofdm_insert_preamble.i"
%include "digital_ofdm_mapper_bcv.i"
%include "digital_ofdm_sampler.i"
+%include "digital_packet_sink.i"
+%include "digital_pfb_clock_sync_ccf.i"
+%include "digital_pfb_clock_sync_fff.i"
+%include "digital_pn_correlator_cc.i"
+%include "digital_probe_density_b.i"
%include "digital_probe_mpsk_snr_est_c.i"
-%include "digital_cpmmod_bc.i"
-%include "digital_gmskmod_bc.i"
+%include "digital_scrambler_bb.i"
+%include "digital_simple_framer.i"
diff --git a/gr-fft/CMakeLists.txt b/gr-fft/CMakeLists.txt
new file mode 100644
index 000000000..7d76dc7f9
--- /dev/null
+++ b/gr-fft/CMakeLists.txt
@@ -0,0 +1,111 @@
+# 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.
+
+########################################################################
+# Setup dependencies
+########################################################################
+include(GrBoost)
+
+find_package(FFTW3f)
+
+########################################################################
+# Register component
+########################################################################
+include(GrComponent)
+
+GR_REGISTER_COMPONENT("gr-fft" ENABLE_GR_FFT
+ ENABLE_GRUEL
+ ENABLE_VOLK
+ Boost_FOUND
+ ENABLE_GR_CORE
+ FFTW3F_FOUND
+)
+
+GR_SET_GLOBAL(GR_FFT_INCLUDE_DIRS
+ ${CMAKE_CURRENT_SOURCE_DIR}/lib
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+)
+
+########################################################################
+# Begin conditional configuration
+########################################################################
+if(ENABLE_GR_FFT)
+
+########################################################################
+# Setup CPack components
+########################################################################
+include(GrPackage)
+CPACK_SET(CPACK_COMPONENT_GROUP_FFT_DESCRIPTION "GNU Radio FFT Blocks")
+
+CPACK_COMPONENT("fft_runtime"
+ GROUP "FFT"
+ DISPLAY_NAME "Runtime"
+ DESCRIPTION "Runtime"
+ DEPENDS "core_runtime"
+)
+
+CPACK_COMPONENT("fft_devel"
+ GROUP "FFT"
+ DISPLAY_NAME "Development"
+ DESCRIPTION "C++ headers, package config, import libraries"
+ DEPENDS "core_devel"
+)
+
+CPACK_COMPONENT("fft_python"
+ GROUP "FFT"
+ DISPLAY_NAME "Python"
+ DESCRIPTION "Python modules for runtime; GRC xml files"
+ DEPENDS "core_python;fft_runtime"
+)
+
+CPACK_COMPONENT("fft_swig"
+ GROUP "FFT"
+ DISPLAY_NAME "SWIG"
+ DESCRIPTION "SWIG development .i files"
+ DEPENDS "core_swig;fft_python;fft_devel"
+)
+
+########################################################################
+# Add subdirectories
+########################################################################
+add_subdirectory(include/fft)
+add_subdirectory(lib)
+if(ENABLE_PYTHON)
+ add_subdirectory(swig)
+ add_subdirectory(python)
+ add_subdirectory(grc)
+endif(ENABLE_PYTHON)
+#add_subdirectory(examples)
+add_subdirectory(doc)
+
+########################################################################
+# Create Pkg Config File
+########################################################################
+configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/gnuradio-fft.pc.in
+ ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-fft.pc
+@ONLY)
+
+install(
+ FILES ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-fft.pc
+ DESTINATION ${GR_LIBRARY_DIR}/pkgconfig
+ COMPONENT "fft_devel"
+)
+
+endif(ENABLE_GR_FFT)
diff --git a/gr-fft/doc/CMakeLists.txt b/gr-fft/doc/CMakeLists.txt
new file mode 100644
index 000000000..96c42f030
--- /dev/null
+++ b/gr-fft/doc/CMakeLists.txt
@@ -0,0 +1,23 @@
+# 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.
+
+install(
+ FILES README.fft
+ DESTINATION ${GR_PKG_DOC_DIR}
+)
diff --git a/gr-fft/doc/README.fft b/gr-fft/doc/README.fft
new file mode 100644
index 000000000..3ea9e81f8
--- /dev/null
+++ b/gr-fft/doc/README.fft
@@ -0,0 +1,13 @@
+This is the gr-fft package. It contains signal processing blocks to
+perform FFTs and FFT-related functionality.
+
+The Python namespace is in gnuradio.fft, which would be normally
+imported as:
+
+ from gnuradio import fft
+
+See the Doxygen documentation for details about the blocks available
+in this package. A quick listing of the details can be found in Python
+after importing by using:
+
+ help(fft)
diff --git a/gr-fft/doc/fft.dox b/gr-fft/doc/fft.dox
new file mode 100644
index 000000000..5bf612d84
--- /dev/null
+++ b/gr-fft/doc/fft.dox
@@ -0,0 +1,29 @@
+/*! \page page_fft FFT Signal Processing Blocks
+
+\section Introduction
+
+This is the gr-fft package. It contains signal processing blocks to
+perform FFTs and FFT-related functionality.
+
+The Python namespace is in gnuradio.fft, which would be normally
+imported as:
+
+\code
+ from gnuradio import fft
+\endcode
+
+See the Doxygen documentation for details about the blocks available
+in this package. A quick listing of the details can be found in Python
+after importing by using:
+
+\code
+ help(fft)
+\endcode
+
+\section Dependencies
+
+The FFT blocks require the following dependencies.
+
+\li fftw3f (>= 3.0) http://www.fftw.org/download.html
+
+*/
diff --git a/gr-fft/gnuradio-fft.pc.in b/gr-fft/gnuradio-fft.pc.in
new file mode 100644
index 000000000..eb4ddfd9f
--- /dev/null
+++ b/gr-fft/gnuradio-fft.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gnuradio-fft
+Description: GNU Radio's FFT signal processing blocks
+Requires: gnuradio-core
+Version: @LIBVER@
+Libs: -L${libdir} -lgnuradio-fft
+Cflags: -I${includedir}
diff --git a/gr-fft/grc/CMakeLists.txt b/gr-fft/grc/CMakeLists.txt
new file mode 100644
index 000000000..632a9aaad
--- /dev/null
+++ b/gr-fft/grc/CMakeLists.txt
@@ -0,0 +1,26 @@
+# 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.
+
+install(FILES
+ fft_block_tree.xml
+ fft_vxx.xml
+ goertzel_fc.xml
+ DESTINATION ${GRC_BLOCKS_DIR}
+ COMPONENT "fft_python"
+)
diff --git a/gr-fft/grc/fft_block_tree.xml b/gr-fft/grc/fft_block_tree.xml
new file mode 100644
index 000000000..3bda77eae
--- /dev/null
+++ b/gr-fft/grc/fft_block_tree.xml
@@ -0,0 +1,36 @@
+<?xml version="1.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.
+-->
+
+<!--
+###################################################
+##Block Tree for GR FFT blocks.
+###################################################
+ -->
+<cat>
+ <name></name> <!-- Blank for Root Name -->
+ <cat>
+ <name>FFT</name>
+ <block>fft_vxx</block>
+ <block>goertzel_fc</block>
+ </cat>
+</cat>
diff --git a/gr-fft/grc/fft_vxx.xml b/gr-fft/grc/fft_vxx.xml
new file mode 100644
index 000000000..69f12ace7
--- /dev/null
+++ b/gr-fft/grc/fft_vxx.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##FFT
+###################################################
+ -->
+<block>
+ <name>FFT</name>
+ <key>fft_vxx</key>
+ <import>from gnuradio import fft</import>
+ <import>from gnuradio import window</import>
+ <make>#if $type() == "complex"
+fft.fft_vcc($fft_size, $forward, $window, $shift, $nthreads)
+#else
+fft.fft_vfc($fft_size, $forward, $window, $nthreads)
+#end if</make>
+ <callback>set_nthreads($nthreads)</callback>
+ <param>
+ <name>Input Type</name>
+ <key>type</key>
+ <type>enum</type>
+ <option>
+ <name>Complex</name>
+ <key>complex</key>
+ <opt>hide_shift:</opt>
+ </option>
+ <option>
+ <name>Float</name>
+ <key>float</key>
+ <opt>hide_shift:all</opt>
+ </option>
+ </param>
+ <param>
+ <name>FFT Size</name>
+ <key>fft_size</key>
+ <value>1024</value>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Forward/Reverse</name>
+ <key>forward</key>
+ <type>enum</type>
+ <option>
+ <name>Forward</name>
+ <key>True</key>
+ </option>
+ <option>
+ <name>Reverse</name>
+ <key>False</key>
+ </option>
+ </param>
+ <param>
+ <name>Window</name>
+ <key>window</key>
+ <value>window.blackmanharris(1024)</value>
+ <type>real_vector</type>
+ </param>
+ <param>
+ <name>Shift</name>
+ <key>shift</key>
+ <type>enum</type>
+ <hide>$type.hide_shift</hide>
+ <option>
+ <name>Yes</name>
+ <key>True</key>
+ </option>
+ <option>
+ <name>No</name>
+ <key>False</key>
+ </option>
+ </param>
+ <param>
+ <name>Num. Threads</name>
+ <key>nthreads</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>$type</type>
+ <vlen>$fft_size</vlen>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>complex</type>
+ <vlen>$fft_size</vlen>
+ </source>
+</block>
diff --git a/gr-fft/grc/goertzel_fc.xml b/gr-fft/grc/goertzel_fc.xml
new file mode 100644
index 000000000..371284358
--- /dev/null
+++ b/gr-fft/grc/goertzel_fc.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Goertzel
+###################################################
+ -->
+<block>
+ <name>Goertzel</name>
+ <key>goertzel_fc</key>
+ <import>from gnuradio import fft</import>
+ <make>fft.goertzel_fc($rate, $len, $freq)</make>
+ <callback>set_freq($freq)</callback>
+ <callback>set_rate($rate)</callback>
+ <param>
+ <name>Rate</name>
+ <key>rate</key>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Length</name>
+ <key>len</key>
+ <type>int</type>
+ </param>
+ <param>
+ <name>Frequency</name>
+ <key>freq</key>
+ <type>real</type>
+ </param>
+ <sink>
+ <name>in</name>
+ <type>float</type>
+ </sink>
+ <source>
+ <name>out</name>
+ <type>complex</type>
+ </source>
+</block>
diff --git a/gr-fft/include/fft/CMakeLists.txt b/gr-fft/include/fft/CMakeLists.txt
new file mode 100644
index 000000000..bce3da674
--- /dev/null
+++ b/gr-fft/include/fft/CMakeLists.txt
@@ -0,0 +1,33 @@
+# 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.
+
+########################################################################
+# Install header files
+########################################################################
+install(FILES
+ api.h
+ fft.h
+ fft_vcc.h
+ fft_vfc.h
+ goertzel.h
+ goertzel_fc.h
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio/fft
+ COMPONENT "fft_devel"
+)
+
diff --git a/gr-fft/include/fft/api.h b/gr-fft/include/fft/api.h
new file mode 100644
index 000000000..eef456373
--- /dev/null
+++ b/gr-fft/include/fft/api.h
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+#ifndef INCLUDED_FFT_API_H
+#define INCLUDED_FFT_API_H
+
+#include <gruel/attributes.h>
+
+#ifdef gnuradio_fft_EXPORTS
+# define FFT_API __GR_ATTR_EXPORT
+#else
+# define FFT_API __GR_ATTR_IMPORT
+#endif
+
+#endif /* INCLUDED_FFT_API_H */
diff --git a/gr-fft/include/fft/fft.h b/gr-fft/include/fft/fft.h
new file mode 100644
index 000000000..5cc2e21e8
--- /dev/null
+++ b/gr-fft/include/fft/fft.h
@@ -0,0 +1,195 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2008,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.
+ */
+
+#ifndef _FFT_FFT_H_
+#define _FFT_FFT_H_
+
+/*
+ * Wrappers for FFTW single precision 1d dft
+ */
+
+#include <fft/api.h>
+#include <gr_complex.h>
+#include <boost/thread.hpp>
+
+namespace gr {
+ namespace fft {
+
+
+ /*! \brief Helper function for allocating complex fft buffers
+ */
+ gr_complex* malloc_complex(int size);
+
+ /*! \brief Helper function for allocating float fft buffers
+ */
+ float* malloc_float(int size);
+
+ /*! \brief Helper function for freeing fft buffers
+ */
+ void free(void *b);
+
+ /*!
+ * \brief Export reference to planner mutex for those apps that
+ * want to use FFTW w/o using the fft_impl_fftw* classes.
+ */
+ class FFT_API planner {
+ public:
+ typedef boost::mutex::scoped_lock scoped_lock;
+ /*!
+ * Return reference to planner mutex
+ */
+ static boost::mutex &mutex();
+ };
+
+ /*!
+ * \brief FFT: complex in, complex out
+ * \ingroup misc
+ */
+ class FFT_API fft_complex {
+ int d_fft_size;
+ int d_nthreads;
+ gr_complex *d_inbuf;
+ gr_complex *d_outbuf;
+ void *d_plan;
+
+ public:
+ fft_complex(int fft_size, bool forward = true, int nthreads=1);
+ virtual ~fft_complex();
+
+ /*
+ * These return pointers to buffers owned by fft_impl_fft_complex
+ * into which input and output take place. It's done this way in
+ * order to ensure optimal alignment for SIMD instructions.
+ */
+ gr_complex *get_inbuf() const { return d_inbuf; }
+ gr_complex *get_outbuf() const { return d_outbuf; }
+
+ int inbuf_length() const { return d_fft_size; }
+ int outbuf_length() const { return d_fft_size; }
+
+ /*!
+ * Set the number of threads to use for caclulation.
+ */
+ void set_nthreads(int n);
+
+ /*!
+ * Get the number of threads being used by FFTW
+ */
+ int nthreads() const { return d_nthreads; }
+
+ /*!
+ * compute FFT. The input comes from inbuf, the output is placed in
+ * outbuf.
+ */
+ void execute();
+ };
+
+ /*!
+ * \brief FFT: real in, complex out
+ * \ingroup misc
+ */
+ class FFT_API fft_real_fwd {
+ int d_fft_size;
+ int d_nthreads;
+ float *d_inbuf;
+ gr_complex *d_outbuf;
+ void *d_plan;
+
+ public:
+ fft_real_fwd (int fft_size, int nthreads=1);
+ virtual ~fft_real_fwd ();
+
+ /*
+ * These return pointers to buffers owned by fft_impl_fft_real_fwd
+ * into which input and output take place. It's done this way in
+ * order to ensure optimal alignment for SIMD instructions.
+ */
+ float *get_inbuf() const { return d_inbuf; }
+ gr_complex *get_outbuf() const { return d_outbuf; }
+
+ int inbuf_length() const { return d_fft_size; }
+ int outbuf_length() const { return d_fft_size / 2 + 1; }
+
+ /*!
+ * Set the number of threads to use for caclulation.
+ */
+ void set_nthreads(int n);
+
+ /*!
+ * Get the number of threads being used by FFTW
+ */
+ int nthreads() const { return d_nthreads; }
+
+ /*!
+ * compute FFT. The input comes from inbuf, the output is placed in
+ * outbuf.
+ */
+ void execute();
+ };
+
+ /*!
+ * \brief FFT: complex in, float out
+ * \ingroup misc
+ */
+ class FFT_API fft_real_rev {
+ int d_fft_size;
+ int d_nthreads;
+ gr_complex *d_inbuf;
+ float *d_outbuf;
+ void *d_plan;
+
+ public:
+ fft_real_rev(int fft_size, int nthreads=1);
+ virtual ~fft_real_rev();
+
+ /*
+ * These return pointers to buffers owned by fft_impl_fft_real_rev
+ * into which input and output take place. It's done this way in
+ * order to ensure optimal alignment for SIMD instructions.
+ */
+ gr_complex *get_inbuf() const { return d_inbuf; }
+ float *get_outbuf() const { return d_outbuf; }
+
+ int inbuf_length() const { return d_fft_size / 2 + 1; }
+ int outbuf_length() const { return d_fft_size; }
+
+ /*!
+ * Set the number of threads to use for caclulation.
+ */
+ void set_nthreads(int n);
+
+ /*!
+ * Get the number of threads being used by FFTW
+ */
+ int nthreads() const { return d_nthreads; }
+
+ /*!
+ * compute FFT. The input comes from inbuf, the output is placed in
+ * outbuf.
+ */
+ void execute();
+ };
+
+ } /* namespace fft */
+} /*namespace gr */
+
+#endif /* _FFT_FFT_H_ */
diff --git a/gr-fft/include/fft/fft_vcc.h b/gr-fft/include/fft/fft_vcc.h
new file mode 100644
index 000000000..561ae858d
--- /dev/null
+++ b/gr-fft/include/fft/fft_vcc.h
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007,2008,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.
+ */
+
+#ifndef INCLUDED_FFT_FFT_VCC_H
+#define INCLUDED_FFT_FFT_VCC_H
+
+#include <fft/api.h>
+#include <gr_sync_block.h>
+
+namespace gr {
+ namespace fft {
+
+ class FFT_API fft_vcc : virtual public gr_sync_block
+ {
+ public:
+
+ // gr::fft::fft_vcc::sptr
+ typedef boost::shared_ptr<fft_vcc> sptr;
+
+ /*!
+ * \brief Compute forward or reverse FFT. complex vector in / complex vector out.
+ * \ingroup dft_blk
+ */
+ static FFT_API sptr make(int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift=false, int nthreads=1);
+
+ virtual void set_nthreads(int n) = 0;
+
+ virtual int nthreads() const = 0;
+
+ virtual bool set_window(const std::vector<float> &window) = 0;
+ };
+
+ } /* namespace fft */
+} /* namespace gr */
+
+#endif /* INCLUDED_FFT_FFT_VCC_H */
diff --git a/gr-fft/include/fft/fft_vfc.h b/gr-fft/include/fft/fft_vfc.h
new file mode 100644
index 000000000..fc48ceefe
--- /dev/null
+++ b/gr-fft/include/fft/fft_vfc.h
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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.
+ */
+
+#ifndef INCLUDED_FFT_FFT_VFC_H
+#define INCLUDED_FFT_FFT_VFC_H
+
+#include <fft/api.h>
+#include <gr_sync_block.h>
+
+namespace gr {
+ namespace fft {
+
+ class FFT_API fft_vfc : virtual public gr_sync_block
+ {
+ public:
+
+ // gr::fft::fft_vfc::sptr
+ typedef boost::shared_ptr<fft_vfc> sptr;
+
+ /*!
+ * \brief Compute forward or reverse FFT. float vector in / complex vector out.
+ * \ingroup dft_blk
+ */
+ static FFT_API sptr make(int fft_size, bool forward,
+ const std::vector<float> &window,
+ int nthreads=1);
+
+ virtual void set_nthreads(int n) = 0;
+
+ virtual int nthreads() const = 0;
+
+ virtual bool set_window(const std::vector<float> &window) = 0;
+ };
+
+ } /* namespace fft */
+} /* namespace gr */
+
+#endif /* INCLUDED_FFT_FFT_VFC_H */
diff --git a/gr-fft/include/fft/goertzel.h b/gr-fft/include/fft/goertzel.h
new file mode 100644
index 000000000..ff37355e6
--- /dev/null
+++ b/gr-fft/include/fft/goertzel.h
@@ -0,0 +1,64 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2011,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.
+ */
+
+#ifndef INCLUDED_FFT_IMPL_GOERTZEL_H
+#define INCLUDED_FFT_IMPL_GOERTZEL_H
+
+#include <fft/api.h>
+#include <gr_types.h>
+
+namespace gr {
+ namespace fft {
+
+ /*!
+ * \brief Implements Goertzel single-bin DFT calculation
+ * \ingroup misc
+ */
+ class FFT_API goertzel
+ {
+ public:
+ goertzel(){}
+ goertzel(int rate, int len, float freq);
+
+ void set_params(int rate, int len, float freq);
+
+ // Process a input array
+ gr_complex batch(float *in);
+
+ // Process sample by sample
+ void input(const float &in);
+ gr_complex output();
+ bool ready() const { return d_processed == d_len; }
+
+ private:
+ float d_d1;
+ float d_d2;
+ float d_wr;
+ float d_wi;
+ int d_len;
+ int d_processed;
+ };
+
+ } /* namespace fft */
+} /* namespace gr */
+
+#endif /* INCLUDED_FFT_IMPL_GOERTZEL_H */
diff --git a/gr-fft/include/fft/goertzel_fc.h b/gr-fft/include/fft/goertzel_fc.h
new file mode 100644
index 000000000..4d3fa8dcf
--- /dev/null
+++ b/gr-fft/include/fft/goertzel_fc.h
@@ -0,0 +1,57 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2011,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.
+ */
+
+#ifndef INCLUDED_FFT_GOERTZEL_FC_H
+#define INCLUDED_FFT_GOERTZEL_FC_H
+
+#include <fft/api.h>
+#include <gr_sync_decimator.h>
+
+namespace gr {
+ namespace fft {
+
+ class FFT_API goertzel_fc : virtual public gr_sync_decimator
+ {
+ public:
+
+ // gr::fft::goertzel_fc::sptr
+ typedef boost::shared_ptr<goertzel_fc> sptr;
+
+ /*!
+ * \brief Goertzel single-bin DFT calculation.
+ * \ingroup dft_blk
+ */
+ static FFT_API sptr make(int rate, int len, float freq);
+
+ virtual void set_freq (float freq) = 0;
+
+ virtual void set_rate (int rate) = 0;
+
+ virtual float freq() = 0;
+
+ virtual int rate() = 0;
+ };
+
+ } /* namespace fft */
+} /* namespace gr */
+
+#endif /* INCLUDED_FFT_GOERTZEL_FC_H */
diff --git a/gr-fft/lib/CMakeLists.txt b/gr-fft/lib/CMakeLists.txt
new file mode 100644
index 000000000..e2f17a183
--- /dev/null
+++ b/gr-fft/lib/CMakeLists.txt
@@ -0,0 +1,59 @@
+# 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.
+
+########################################################################
+# Setup the include and linker paths
+########################################################################
+include_directories(
+ ${GNURADIO_CORE_INCLUDE_DIRS}
+ ${GR_FFT_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+include_directories(${FFT_INCLUDE_DIRS})
+link_directories(${FFT_LIBRARY_DIRS})
+
+include_directories(${Boost_INCLUDE_DIRS})
+link_directories(${Boost_LIBRARY_DIRS})
+
+include_directories(${FFTW3F_INCLUDE_DIRS})
+link_directories(${FFTW3F_LIBRARY_DIRS})
+
+########################################################################
+# Setup library
+########################################################################
+list(APPEND fft_sources
+ fft.cc
+ fft_vcc_fftw.cc
+ fft_vfc_fftw.cc
+ goertzel_fc_impl.cc
+ goertzel.cc
+)
+
+list(APPEND fft_libs
+ gnuradio-core
+ ${Boost_LIBRARIES}
+ ${FFT_LIBRARIES}
+ ${FFTW3F_LIBRARIES}
+)
+
+add_library(gnuradio-fft SHARED ${fft_sources})
+target_link_libraries(gnuradio-fft ${fft_libs})
+GR_LIBRARY_FOO(gnuradio-fft RUNTIME_COMPONENT "fft_runtime" DEVEL_COMPONENT "fft_devel")
diff --git a/gr-fft/lib/fft.cc b/gr-fft/lib/fft.cc
new file mode 100644
index 000000000..6074236e1
--- /dev/null
+++ b/gr-fft/lib/fft.cc
@@ -0,0 +1,338 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2008,2011,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 <fft/fft.h>
+#include <gr_sys_paths.h>
+#include <fftw3.h>
+
+#ifdef _MSC_VER //http://www.fftw.org/install/windows.html#DLLwisdom
+static void my_fftw_write_char(char c, void *f) { fputc(c, (FILE *) f); }
+#define fftw_export_wisdom_to_file(f) fftw_export_wisdom(my_fftw_write_char, (void*) (f))
+#define fftwf_export_wisdom_to_file(f) fftwf_export_wisdom(my_fftw_write_char, (void*) (f))
+#define fftwl_export_wisdom_to_file(f) fftwl_export_wisdom(my_fftw_write_char, (void*) (f))
+
+static int my_fftw_read_char(void *f) { return fgetc((FILE *) f); }
+#define fftw_import_wisdom_from_file(f) fftw_import_wisdom(my_fftw_read_char, (void*) (f))
+#define fftwf_import_wisdom_from_file(f) fftwf_import_wisdom(my_fftw_read_char, (void*) (f))
+#define fftwl_import_wisdom_from_file(f) fftwl_import_wisdom(my_fftw_read_char, (void*) (f))
+#endif //_MSC_VER
+
+#include <gr_complex.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <cassert>
+#include <stdexcept>
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+namespace fs = boost::filesystem;
+
+namespace gr {
+ namespace fft {
+
+ gr_complex *
+ malloc_complex(int size)
+ {
+ return (gr_complex*)fftwf_malloc(sizeof(gr_complex)*size);
+ }
+
+ float *
+ malloc_float(int size)
+ {
+ return (float*)fftwf_malloc(sizeof(float)*size);
+ }
+
+ void
+ free(void *b)
+ {
+ fftwf_free(b);
+ }
+
+ boost::mutex &
+ planner::mutex()
+ {
+ static boost::mutex s_planning_mutex;
+
+ return s_planning_mutex;
+ }
+
+ static const char *
+ wisdom_filename()
+ {
+ static fs::path path;
+ path = fs::path(gr_appdata_path()) / ".gr_fftw_wisdom";
+ return path.string().c_str();
+ }
+
+ static void
+ import_wisdom()
+ {
+ const char *filename = wisdom_filename ();
+ FILE *fp = fopen (filename, "r");
+ if (fp != 0){
+ int r = fftwf_import_wisdom_from_file (fp);
+ fclose (fp);
+ if (!r){
+ fprintf (stderr, "gr::fft: can't import wisdom from %s\n", filename);
+ }
+ }
+ }
+
+ static void
+ config_threading(int nthreads)
+ {
+ static int fftw_threads_inited = 0;
+
+#ifdef FFTW3F_THREADS
+ if (fftw_threads_inited == 0)
+ {
+ fftw_threads_inited = 1;
+ fftwf_init_threads();
+ }
+
+ fftwf_plan_with_nthreads(nthreads);
+#endif
+ }
+
+ static void
+ export_wisdom()
+ {
+ const char *filename = wisdom_filename ();
+ FILE *fp = fopen (filename, "w");
+ if (fp != 0){
+ fftwf_export_wisdom_to_file (fp);
+ fclose (fp);
+ }
+ else {
+ fprintf (stderr, "fft_impl_fftw: ");
+ perror (filename);
+ }
+ }
+
+// ----------------------------------------------------------------
+
+ fft_complex::fft_complex(int fft_size, bool forward, int nthreads)
+ {
+ // Hold global mutex during plan construction and destruction.
+ planner::scoped_lock lock(planner::mutex());
+
+ assert (sizeof (fftwf_complex) == sizeof (gr_complex));
+
+ if (fft_size <= 0)
+ throw std::out_of_range ("fft_impl_fftw: invalid fft_size");
+
+ d_fft_size = fft_size;
+ d_inbuf = (gr_complex *) fftwf_malloc (sizeof (gr_complex) * inbuf_length ());
+ if (d_inbuf == 0)
+ throw std::runtime_error ("fftwf_malloc");
+
+ d_outbuf = (gr_complex *) fftwf_malloc (sizeof (gr_complex) * outbuf_length ());
+ if (d_outbuf == 0){
+ fftwf_free (d_inbuf);
+ throw std::runtime_error ("fftwf_malloc");
+ }
+
+ d_nthreads = nthreads;
+ config_threading(nthreads);
+ import_wisdom(); // load prior wisdom from disk
+
+ d_plan = fftwf_plan_dft_1d (fft_size,
+ reinterpret_cast<fftwf_complex *>(d_inbuf),
+ reinterpret_cast<fftwf_complex *>(d_outbuf),
+ forward ? FFTW_FORWARD : FFTW_BACKWARD,
+ FFTW_MEASURE);
+
+ if (d_plan == NULL) {
+ fprintf(stderr, "gr::fft: error creating plan\n");
+ throw std::runtime_error ("fftwf_plan_dft_1d failed");
+ }
+ export_wisdom(); // store new wisdom to disk
+ }
+
+ fft_complex::~fft_complex()
+ {
+ // Hold global mutex during plan construction and destruction.
+ planner::scoped_lock lock(planner::mutex());
+
+ fftwf_destroy_plan ((fftwf_plan) d_plan);
+ fftwf_free (d_inbuf);
+ fftwf_free (d_outbuf);
+ }
+
+ void
+ fft_complex::set_nthreads(int n)
+ {
+ if (n <= 0)
+ throw std::out_of_range ("gr::fft: invalid number of threads");
+ d_nthreads = n;
+
+#ifdef FFTW3F_THREADS
+ fftwf_plan_with_nthreads(d_nthreads);
+#endif
+ }
+
+ void
+ fft_complex::execute()
+ {
+ fftwf_execute((fftwf_plan) d_plan);
+ }
+
+// ----------------------------------------------------------------
+
+ fft_real_fwd::fft_real_fwd (int fft_size, int nthreads)
+ {
+ // Hold global mutex during plan construction and destruction.
+ planner::scoped_lock lock(planner::mutex());
+
+ assert (sizeof (fftwf_complex) == sizeof (gr_complex));
+
+ if (fft_size <= 0)
+ throw std::out_of_range ("gr::fft: invalid fft_size");
+
+ d_fft_size = fft_size;
+ d_inbuf = (float *) fftwf_malloc (sizeof (float) * inbuf_length ());
+ if (d_inbuf == 0)
+ throw std::runtime_error ("fftwf_malloc");
+
+ d_outbuf = (gr_complex *) fftwf_malloc (sizeof (gr_complex) * outbuf_length ());
+ if (d_outbuf == 0){
+ fftwf_free (d_inbuf);
+ throw std::runtime_error ("fftwf_malloc");
+ }
+
+ d_nthreads = nthreads;
+ config_threading(nthreads);
+ import_wisdom(); // load prior wisdom from disk
+
+ d_plan = fftwf_plan_dft_r2c_1d (fft_size,
+ d_inbuf,
+ reinterpret_cast<fftwf_complex *>(d_outbuf),
+ FFTW_MEASURE);
+
+ if (d_plan == NULL) {
+ fprintf(stderr, "gr::fft::fft_real_fwd: error creating plan\n");
+ throw std::runtime_error ("fftwf_plan_dft_r2c_1d failed");
+ }
+ export_wisdom(); // store new wisdom to disk
+ }
+
+ fft_real_fwd::~fft_real_fwd()
+ {
+ // Hold global mutex during plan construction and destruction.
+ planner::scoped_lock lock(planner::mutex());
+
+ fftwf_destroy_plan ((fftwf_plan) d_plan);
+ fftwf_free (d_inbuf);
+ fftwf_free (d_outbuf);
+ }
+
+ void
+ fft_real_fwd::set_nthreads(int n)
+ {
+ if (n <= 0)
+ throw std::out_of_range ("gr::fft::fft_real_fwd::set_nthreads: invalid number of threads");
+ d_nthreads = n;
+
+#ifdef FFTW3F_THREADS
+ fftwf_plan_with_nthreads(d_nthreads);
+#endif
+ }
+
+ void
+ fft_real_fwd::execute()
+ {
+ fftwf_execute ((fftwf_plan) d_plan);
+ }
+
+ // ----------------------------------------------------------------
+
+ fft_real_rev::fft_real_rev(int fft_size, int nthreads)
+ {
+ // Hold global mutex during plan construction and destruction.
+ planner::scoped_lock lock(planner::mutex());
+
+ assert (sizeof (fftwf_complex) == sizeof (gr_complex));
+
+ if (fft_size <= 0)
+ throw std::out_of_range ("gr::fft::fft_real_rev: invalid fft_size");
+
+ d_fft_size = fft_size;
+ d_inbuf = (gr_complex *) fftwf_malloc (sizeof (gr_complex) * inbuf_length ());
+ if (d_inbuf == 0)
+ throw std::runtime_error ("fftwf_malloc");
+
+ d_outbuf = (float *) fftwf_malloc (sizeof (float) * outbuf_length ());
+ if (d_outbuf == 0){
+ fftwf_free (d_inbuf);
+ throw std::runtime_error ("fftwf_malloc");
+ }
+
+ d_nthreads = nthreads;
+ config_threading(nthreads);
+ import_wisdom(); // load prior wisdom from disk
+
+ // FIXME If there's ever a chance that the planning functions
+ // will be called in multiple threads, we've got to ensure single
+ // threaded access. They are not thread-safe.
+ d_plan = fftwf_plan_dft_c2r_1d (fft_size,
+ reinterpret_cast<fftwf_complex *>(d_inbuf),
+ d_outbuf,
+ FFTW_MEASURE);
+
+ if (d_plan == NULL) {
+ fprintf(stderr, "gr::fft::fft_real_rev: error creating plan\n");
+ throw std::runtime_error ("fftwf_plan_dft_c2r_1d failed");
+ }
+ export_wisdom (); // store new wisdom to disk
+ }
+
+ fft_real_rev::~fft_real_rev ()
+ {
+ // Hold global mutex during plan construction and destruction.
+ planner::scoped_lock lock(planner::mutex());
+
+ fftwf_destroy_plan ((fftwf_plan) d_plan);
+ fftwf_free (d_inbuf);
+ fftwf_free (d_outbuf);
+ }
+
+ void
+ fft_real_rev::set_nthreads(int n)
+ {
+ if (n <= 0)
+ throw std::out_of_range ("gr::fft::fft_real_rev::set_nthreads: invalid number of threads");
+ d_nthreads = n;
+
+#ifdef FFTW3F_THREADS
+ fftwf_plan_with_nthreads(d_nthreads);
+#endif
+ }
+
+ void
+ fft_real_rev::execute ()
+ {
+ fftwf_execute ((fftwf_plan) d_plan);
+ }
+
+ } /* namespace fft */
+} /* namespace gr */
diff --git a/gr-fft/lib/fft_vcc_fftw.cc b/gr-fft/lib/fft_vcc_fftw.cc
new file mode 100644
index 000000000..ebcd5ec53
--- /dev/null
+++ b/gr-fft/lib/fft_vcc_fftw.cc
@@ -0,0 +1,147 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007,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 GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "fft_vcc_fftw.h"
+#include <gr_io_signature.h>
+#include <math.h>
+#include <string.h>
+
+namespace gr {
+ namespace fft {
+
+ fft_vcc::sptr fft_vcc::make(int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift, int nthreads)
+ {
+ return gnuradio::get_initial_sptr(new fft_vcc_fftw
+ (fft_size, forward, window,
+ shift, nthreads));
+ }
+
+ fft_vcc_fftw::fft_vcc_fftw(int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift, int nthreads)
+ : gr_sync_block("fft_vcc_fftw",
+ gr_make_io_signature(1, 1, fft_size * sizeof(gr_complex)),
+ gr_make_io_signature(1, 1, fft_size * sizeof(gr_complex))),
+ d_fft_size(fft_size), d_forward(forward), d_shift(shift)
+ {
+ d_fft = new fft_complex(d_fft_size, forward, nthreads);
+ }
+
+ fft_vcc_fftw::~fft_vcc_fftw()
+ {
+ delete d_fft;
+ }
+
+ void
+ fft_vcc_fftw::set_nthreads(int n)
+ {
+ d_fft->set_nthreads(n);
+ }
+
+ int
+ fft_vcc_fftw::nthreads() const
+ {
+ return d_fft->nthreads();
+ }
+
+ bool
+ fft_vcc_fftw::set_window(const std::vector<float> &window)
+ {
+ if(window.size()==0 || window.size()==d_fft_size) {
+ d_window=window;
+ return true;
+ }
+ else
+ return false;
+ }
+
+ int
+ fft_vcc_fftw::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const gr_complex *in = (const gr_complex *) input_items[0];
+ gr_complex *out = (gr_complex *) output_items[0];
+
+ unsigned int input_data_size = input_signature()->sizeof_stream_item (0);
+ unsigned int output_data_size = output_signature()->sizeof_stream_item (0);
+
+ int count = 0;
+
+ while(count++ < noutput_items) {
+
+ // copy input into optimally aligned buffer
+ if(d_window.size()) {
+ gr_complex *dst = d_fft->get_inbuf();
+ if(!d_forward && d_shift) {
+ unsigned int offset = (!d_forward && d_shift)?(d_fft_size/2):0;
+ int fft_m_offset = d_fft_size - offset;
+ for(unsigned int i = 0; i < offset; i++) // apply window
+ dst[i+fft_m_offset] = in[i] * d_window[i];
+ for(unsigned int i = offset; i < d_fft_size; i++) // apply window
+ dst[i-offset] = in[i] * d_window[i];
+ }
+ else {
+ for(unsigned int i = 0; i < d_fft_size; i++) // apply window
+ dst[i] = in[i] * d_window[i];
+ }
+ }
+ else {
+ if(!d_forward && d_shift) { // apply an ifft shift on the data
+ gr_complex *dst = d_fft->get_inbuf();
+ unsigned int len = (unsigned int)(floor(d_fft_size/2.0)); // half length of complex array
+ memcpy(&dst[0], &in[len], sizeof(gr_complex)*(d_fft_size - len));
+ memcpy(&dst[d_fft_size - len], &in[0], sizeof(gr_complex)*len);
+ }
+ else {
+ memcpy(d_fft->get_inbuf(), in, input_data_size);
+ }
+ }
+
+ // compute the fft
+ d_fft->execute();
+
+ // copy result to our output
+ if(d_forward && d_shift) { // apply a fft shift on the data
+ unsigned int len = (unsigned int)(ceil(d_fft_size/2.0));
+ memcpy(&out[0], &d_fft->get_outbuf()[len], sizeof(gr_complex)*(d_fft_size - len));
+ memcpy(&out[d_fft_size - len], &d_fft->get_outbuf()[0], sizeof(gr_complex)*len);
+ }
+ else {
+ memcpy (out, d_fft->get_outbuf (), output_data_size);
+ }
+
+ in += d_fft_size;
+ out += d_fft_size;
+ }
+
+ return noutput_items;
+ }
+
+ } /* namespace fft */
+} /* namespace gr */
diff --git a/gr-fft/lib/fft_vcc_fftw.h b/gr-fft/lib/fft_vcc_fftw.h
new file mode 100644
index 000000000..ea15dd07b
--- /dev/null
+++ b/gr-fft/lib/fft_vcc_fftw.h
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007,2008,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.
+ */
+
+#ifndef INCLUDED_FFT_FFT_VCC_FFTW_IMPL_H
+#define INCLUDED_FFT_FFT_VCC_FFTW_IMPL_H
+
+#include <fft/fft_vcc.h>
+#include <fft/fft.h>
+
+namespace gr {
+ namespace fft {
+
+ class FFT_API fft_vcc_fftw : public fft_vcc
+ {
+ private:
+ fft_complex *d_fft;
+ unsigned int d_fft_size;
+ std::vector<float> d_window;
+ bool d_forward;
+ bool d_shift;
+
+ public:
+ fft_vcc_fftw(int fft_size, bool forward,
+ const std::vector<float> &window,
+ bool shift, int nthreads=1);
+
+ ~fft_vcc_fftw();
+
+ void set_nthreads(int n);
+ int nthreads() const;
+ bool set_window(const std::vector<float> &window);
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace fft */
+} /* namespace gr */
+
+#endif /* INCLUDED_FFT_FFT_VCC_FFTW_IMPL_H */
diff --git a/gr-fft/lib/fft_vfc_fftw.cc b/gr-fft/lib/fft_vfc_fftw.cc
new file mode 100644
index 000000000..8f9b127e5
--- /dev/null
+++ b/gr-fft/lib/fft_vfc_fftw.cc
@@ -0,0 +1,124 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007,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 GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "fft_vfc_fftw.h"
+#include <gr_io_signature.h>
+#include <math.h>
+#include <string.h>
+
+namespace gr {
+ namespace fft {
+
+ fft_vfc::sptr fft_vfc::make(int fft_size, bool forward,
+ const std::vector<float> &window,
+ int nthreads)
+ {
+ return gnuradio::get_initial_sptr(new fft_vfc_fftw
+ (fft_size, forward, window,
+ nthreads));
+ }
+
+ fft_vfc_fftw::fft_vfc_fftw(int fft_size, bool forward,
+ const std::vector<float> &window,
+ int nthreads)
+ : gr_sync_block("fft_vfc_fftw",
+ gr_make_io_signature(1, 1, fft_size * sizeof(gr_complex)),
+ gr_make_io_signature(1, 1, fft_size * sizeof(gr_complex))),
+ d_fft_size(fft_size), d_forward(forward)
+ {
+ d_fft = new fft_complex(d_fft_size, forward, nthreads);
+ }
+
+ fft_vfc_fftw::~fft_vfc_fftw()
+ {
+ delete d_fft;
+ }
+
+ void
+ fft_vfc_fftw::set_nthreads(int n)
+ {
+ d_fft->set_nthreads(n);
+ }
+
+ int
+ fft_vfc_fftw::nthreads() const
+ {
+ return d_fft->nthreads();
+ }
+
+ bool
+ fft_vfc_fftw::set_window(const std::vector<float> &window)
+ {
+ if(window.size()==0 || window.size()==d_fft_size) {
+ d_window=window;
+ return true;
+ }
+ else
+ return false;
+ }
+
+ int
+ fft_vfc_fftw::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const float *in = (const float *)input_items[0];
+ gr_complex *out = (gr_complex *)output_items[0];
+
+ unsigned int output_data_size = output_signature()->sizeof_stream_item (0);
+
+ int count = 0;
+
+ while(count++ < noutput_items) {
+
+ // copy input into optimally aligned buffer
+ if(d_window.size()) {
+ gr_complex *dst = d_fft->get_inbuf();
+ for(unsigned int i = 0; i < d_fft_size; i++) // apply window
+ dst[i] = in[i] * d_window[i];
+ }
+ else {
+ gr_complex *dst = d_fft->get_inbuf();
+ for(unsigned int i = 0; i < d_fft_size; i++) // float to complex conversion
+ dst[i] = in[i];
+ }
+
+ // compute the fft
+ d_fft->execute();
+
+ // copy result to output stream
+ memcpy(out, d_fft->get_outbuf(), output_data_size);
+
+ in += d_fft_size;
+ out += d_fft_size;
+ }
+
+ return noutput_items;
+ }
+
+ } /* namespace fft */
+} /* namespace gr */
+
diff --git a/gr-fft/lib/fft_vfc_fftw.h b/gr-fft/lib/fft_vfc_fftw.h
new file mode 100644
index 000000000..1b6f78ba6
--- /dev/null
+++ b/gr-fft/lib/fft_vfc_fftw.h
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007,2008,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.
+ */
+
+#ifndef INCLUDED_FFT_FFT_VFC_FFTW_IMPL_H
+#define INCLUDED_FFT_FFT_VFC_FFTW_IMPL_H
+
+#include <fft/fft_vfc.h>
+#include <fft/fft.h>
+
+namespace gr {
+ namespace fft {
+
+ class FFT_API fft_vfc_fftw : public fft_vfc
+ {
+ private:
+ fft_complex *d_fft;
+ unsigned int d_fft_size;
+ std::vector<float> d_window;
+ bool d_forward;
+
+ public:
+ fft_vfc_fftw(int fft_size, bool forward,
+ const std::vector<float> &window,
+ int nthreads=1);
+
+ ~fft_vfc_fftw();
+
+ void set_nthreads(int n);
+ int nthreads() const;
+ bool set_window(const std::vector<float> &window);
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace fft */
+} /* namespace gr */
+
+#endif /* INCLUDED_FFT_FFT_VFC_FFTW_IMPL_H */
diff --git a/gr-fft/lib/goertzel.cc b/gr-fft/lib/goertzel.cc
new file mode 100644
index 000000000..4bcd5ee19
--- /dev/null
+++ b/gr-fft/lib/goertzel.cc
@@ -0,0 +1,84 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2011,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cmath>
+#include <fft/goertzel.h>
+
+namespace gr {
+ namespace fft {
+
+ goertzel::goertzel(int rate, int len, float freq)
+ {
+ set_params(rate, len, freq);
+ }
+
+ void
+ goertzel::set_params(int rate, int len, float freq)
+ {
+ d_d1 = 0.0;
+ d_d2 = 0.0;
+
+ float w = 2.0*M_PI*freq/rate;
+ d_wr = 2.0*std::cos(w);
+ d_wi = std::sin(w);
+ d_len = len;
+ d_processed = 0;
+ }
+
+ gr_complex
+ goertzel::batch(float *in)
+ {
+ d_d1 = 0.0;
+ d_d2 = 0.0;
+
+ for(int i = 0; i < d_len; i++)
+ input(in[i]);
+
+ return output();
+ }
+
+ void
+ goertzel::input(const float &input)
+ {
+ float y = input + d_wr*d_d1 - d_d2;
+ d_d2 = d_d1;
+ d_d1 = y;
+ d_processed++;
+ }
+
+ gr_complex
+ goertzel::output()
+ {
+ gr_complex out((0.5*d_wr*d_d1-d_d2)/d_len, (d_wi*d_d1)/d_len);
+ d_d1 = 0.0;
+ d_d2 = 0.0;
+ d_processed = 0;
+ return out;
+ }
+
+ } /* namespace fft */
+}/* namespace gr */
+
diff --git a/gr-fft/lib/goertzel_fc_impl.cc b/gr-fft/lib/goertzel_fc_impl.cc
new file mode 100644
index 000000000..ee214f24d
--- /dev/null
+++ b/gr-fft/lib/goertzel_fc_impl.cc
@@ -0,0 +1,85 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "goertzel_fc_impl.h"
+#include <gr_io_signature.h>
+
+namespace gr {
+ namespace fft {
+
+ goertzel_fc::sptr goertzel_fc::make(int rate, int len, float freq)
+ {
+ return gnuradio::get_initial_sptr(new goertzel_fc_impl(rate, len, freq));
+ }
+
+ goertzel_fc_impl::goertzel_fc_impl(int rate, int len, float freq)
+ : gr_sync_decimator("goertzel_fc",
+ gr_make_io_signature (1, 1, sizeof(float)),
+ gr_make_io_signature (1, 1, sizeof(gr_complex)),
+ len),
+ d_goertzel(rate, len, freq)
+ {
+ d_len = len;
+ d_rate = rate;
+ d_freq = freq;
+ }
+
+ goertzel_fc_impl::~goertzel_fc_impl()
+ {
+ }
+
+ void
+ goertzel_fc_impl::set_freq(float freq)
+ {
+ d_freq = freq;
+ d_goertzel.set_params(d_rate, d_len, d_freq);
+ }
+
+ void
+ goertzel_fc_impl::set_rate(int rate)
+ {
+ d_rate = rate;
+ d_goertzel.set_params(d_rate, d_len, d_freq);
+ }
+
+ int
+ goertzel_fc_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ float *in = (float *)input_items[0];
+ gr_complex *out = (gr_complex *)output_items[0];
+
+ for(int i = 0; i < noutput_items; i++) {
+ *out++ = d_goertzel.batch(in);
+ in += d_len;
+ }
+
+ return noutput_items;
+ }
+
+ } /* namespace fft */
+} /* namespace gr */
diff --git a/gr-fft/lib/goertzel_fc_impl.h b/gr-fft/lib/goertzel_fc_impl.h
new file mode 100644
index 000000000..426bc71f6
--- /dev/null
+++ b/gr-fft/lib/goertzel_fc_impl.h
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2011,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.
+ */
+
+#ifndef INCLUDED_FFT_GOERTZEL_FC_IMPL_H
+#define INCLUDED_FFT_GOERTZEL_FC_IMPL_H
+
+#include <fft/goertzel_fc.h>
+#include <fft/goertzel.h>
+
+namespace gr {
+ namespace fft {
+
+ class FFT_API goertzel_fc_impl : public goertzel_fc
+ {
+ private:
+ goertzel d_goertzel;
+ int d_len;
+ float d_freq;
+ int d_rate;
+
+ public:
+ goertzel_fc_impl(int rate, int len, float freq);
+
+ ~goertzel_fc_impl();
+
+ void set_freq(float freq);
+ void set_rate(int rate);
+
+ float freq() { return d_freq; }
+ int rate() { return d_rate; }
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace fft */
+} /* namespace gr */
+
+#endif /* INCLUDED_FFT_GOERTZEL_FC_IMPL_H */
+
diff --git a/gr-fft/python/CMakeLists.txt b/gr-fft/python/CMakeLists.txt
new file mode 100644
index 000000000..16c29e599
--- /dev/null
+++ b/gr-fft/python/CMakeLists.txt
@@ -0,0 +1,47 @@
+# 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
+ DESTINATION ${GR_PYTHON_DIR}/gnuradio/fft
+ COMPONENT "fft_python"
+)
+
+########################################################################
+# Handle the unit tests
+########################################################################
+if(ENABLE_TESTING)
+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)
+ set(GR_TEST_PYTHON_DIRS
+ ${CMAKE_BINARY_DIR}/gnuradio-core/src/python
+ ${CMAKE_BINARY_DIR}/gnuradio-core/src/lib/swig
+ ${CMAKE_BINARY_DIR}/gr-fft/python
+ ${CMAKE_BINARY_DIR}/gr-fft/swig
+ )
+ set(GR_TEST_TARGET_DEPS gruel gnuradio-core gnuradio-fft)
+ GR_ADD_TEST(${py_qa_test_name} ${PYTHON_EXECUTABLE} ${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
new file mode 100644
index 000000000..0fa643e35
--- /dev/null
+++ b/gr-fft/python/__init__.py
@@ -0,0 +1,28 @@
+#
+# 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 *
+
diff --git a/gr-fft/python/qa_fft.py b/gr-fft/python/qa_fft.py
new file mode 100755
index 000000000..1c45ac148
--- /dev/null
+++ b/gr-fft/python/qa_fft.py
@@ -0,0 +1,213 @@
+#!/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 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 = gr.stream_to_vector(gr.sizeof_gr_complex, fft_size)
+ op = fft.fft_vcc(fft_size, True, [], False)
+ v2s = gr.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 = gr.stream_to_vector(gr.sizeof_gr_complex, fft_size)
+ op = fft.fft_vcc(fft_size, False, [], False)
+ v2s = gr.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 = gr.stream_to_vector(gr.sizeof_gr_complex, fft_size)
+ op = fft.fft_vcc(fft_size, False, [], False, nthreads)
+ v2s = gr.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
new file mode 100755
index 000000000..27f9d370e
--- /dev/null
+++ b/gr-fft/python/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/swig/CMakeLists.txt b/gr-fft/swig/CMakeLists.txt
new file mode 100644
index 000000000..63f5dfb0e
--- /dev/null
+++ b/gr-fft/swig/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.
+
+########################################################################
+# Setup swig generation
+########################################################################
+include(GrPython)
+include(GrSwig)
+
+set(GR_SWIG_INCLUDE_DIRS
+ ${GR_FFT_INCLUDE_DIRS}
+ ${GNURADIO_CORE_SWIG_INCLUDE_DIRS}
+ ${FFTW3F_INCLUDE_DIRS}
+)
+
+set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/fft_swig_doc.i)
+set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../lib)
+
+set(GR_SWIG_LIBRARIES gnuradio-fft)
+
+GR_SWIG_MAKE(fft_swig fft_swig.i)
+
+GR_SWIG_INSTALL(
+ TARGETS fft_swig
+ DESTINATION ${GR_PYTHON_DIR}/gnuradio/fft
+ COMPONENT "fft_python"
+)
+
+install(
+ FILES
+ fft_swig.i
+ ${CMAKE_CURRENT_BINARY_DIR}/fft_swig_doc.i
+ DESTINATION ${GR_INCLUDE_DIR}/gnuradio/swig
+ COMPONENT "fft_swig"
+)
diff --git a/gr-fft/swig/fft_swig.i b/gr-fft/swig/fft_swig.i
new file mode 100644
index 000000000..07fab34d4
--- /dev/null
+++ b/gr-fft/swig/fft_swig.i
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * 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.
+ */
+
+#define FFT_API
+
+%include "gnuradio.i"
+
+//load generated python docstrings
+%include "fft_swig_doc.i"
+
+%{
+#include "fft/fft_vcc.h"
+#include "fft/fft_vfc.h"
+#include "fft/goertzel_fc.h"
+%}
+
+%include "fft/fft_vcc.h"
+%include "fft/fft_vfc.h"
+%include "fft/goertzel_fc.h"
+
+GR_SWIG_BLOCK_MAGIC2(fft, fft_vcc);
+GR_SWIG_BLOCK_MAGIC2(fft, fft_vfc);
+GR_SWIG_BLOCK_MAGIC2(fft, goertzel_fc);
diff --git a/gr-uhd/apps/uhd_fft b/gr-uhd/apps/uhd_fft
index 8bb5e0d2b..7af2c5326 100755
--- a/gr-uhd/apps/uhd_fft
+++ b/gr-uhd/apps/uhd_fft
@@ -196,18 +196,18 @@ class app_top_block(stdgui2.std_top_block):
callback=self.set_gain)
try:
- mboard_id = self.u.get_usrp_info().get("mboard_id").split(" ")[0]
+ mboard_id = self.u.get_usrp_info().get("mboard_id")
mboard_serial = self.u.get_usrp_info().get("mboard_serial")
if mboard_serial == "":
mboard_serial = "no serial"
- dboard_id = self.u.get_usrp_info().get("rx_id").split(" ")[0].split(",")[0]
+ dboard_subdev_name = self.u.get_usrp_info().get("rx_subdev_name")
dboard_serial = self.u.get_usrp_info().get("rx_serial")
if dboard_serial == "":
dboard_serial = "no serial"
subdev = self.u.get_subdev_spec()
antenna = self.u.get_antenna()
- usrp_config_val = "%s (%s), %s (%s, %s, %s)" % (mboard_id, mboard_serial, dboard_id, dboard_serial, subdev, antenna)
+ usrp_config_val = "%s (%s), %s (%s, %s, %s)" % (mboard_id, mboard_serial, dboard_subdev_name, dboard_serial, subdev, antenna)
except:
usrp_config_val = "Not implemented in this version."
diff --git a/gr-uhd/apps/uhd_siggen_base.py b/gr-uhd/apps/uhd_siggen_base.py
index 5fa881e42..8c69da1cc 100644
--- a/gr-uhd/apps/uhd_siggen_base.py
+++ b/gr-uhd/apps/uhd_siggen_base.py
@@ -110,11 +110,11 @@ class top_block(gr.top_block, pubsub):
# Setup USRP Configuration value
try:
usrp_info = self._u.get_usrp_info()
- mboard_id = usrp_info.get("mboard_id").split(" ")[0]
+ mboard_id = usrp_info.get("mboard_id")
mboard_serial = usrp_info.get("mboard_serial")
if mboard_serial == "":
mboard_serial = "no serial"
- dboard_id = usrp_info.get("tx_id").split(" ")[0].split(",")[0]
+ dboard_subdev_name = usrp_info.get("tx_subdev_name")
dboard_serial = usrp_info.get("tx_serial")
if dboard_serial == "":
dboard_serial = "no serial"
@@ -122,7 +122,7 @@ class top_block(gr.top_block, pubsub):
antenna = self._u.get_antenna()
desc_key_str = "Motherboard: %s [%s]\n" % (mboard_id, mboard_serial)
- desc_key_str += "Daughterboard: %s [%s]\n" % (dboard_id, dboard_serial)
+ desc_key_str += "Daughterboard: %s [%s]\n" % (dboard_subdev_name, dboard_serial)
desc_key_str += "Subdev: %s\n" % subdev
desc_key_str += "Antenna: %s" % antenna
except:
diff --git a/gr-wxgui/grc/top_block_gui.py b/gr-wxgui/grc/top_block_gui.py
index 333ccf1c1..479f55a30 100644
--- a/gr-wxgui/grc/top_block_gui.py
+++ b/gr-wxgui/grc/top_block_gui.py
@@ -48,7 +48,7 @@ class top_block_gui(gr.top_block):
def SetIcon(self, *args, **kwargs): self._frame.SetIcon(*args, **kwargs)
- def Run(self, start=True):
+ def Run(self, start=True, max_nouts=0):
"""
Setup the wx gui elements.
Start the gr top block.
@@ -69,6 +69,10 @@ class top_block_gui(gr.top_block):
self._frame.Show(True)
self._app.SetTopWindow(self._frame)
#start flow graph
- if start: self.start()
+ if start:
+ if max_nouts != 0:
+ self.start(max_nouts)
+ else:
+ self.start()
#blocking main loop
self._app.MainLoop()
diff --git a/grc/blocks/options.xml b/grc/blocks/options.xml
index b27ea900c..1cf0b7707 100644
--- a/grc/blocks/options.xml
+++ b/grc/blocks/options.xml
@@ -125,6 +125,19 @@ else: self.stop(); self.wait()</callback>
</option>
</param>
<param>
+ <name>Max Number of Output</name>
+ <key>max_nouts</key>
+ <value>0</value>
+ <type>int</type>
+ <hide>#if $generate_options() == 'hb'
+all#slurp
+#elif $max_nouts()
+none#slurp
+#else
+part#slurp
+#end if</hide>
+ </param>
+ <param>
<name>Realtime Scheduling</name>
<key>realtime_scheduling</key>
<value></value>
@@ -169,5 +182,9 @@ For example, an id of my_block will generate the file my_block.py and class my_b
The category parameter determines the placement of the block in the block selection window. \
The category only applies when creating hier blocks. \
To put hier blocks into the root category, enter / for the category.
+
+The Max Number of Output is the maximum number of output items allowed for any block \
+in the flowgraph; to disable this set the max_nouts equal to 0.\
+Use this to adjust the maximum latency a flowgraph can exhibit.
</doc>
</block>
diff --git a/grc/python/flow_graph.tmpl b/grc/python/flow_graph.tmpl
index 0878be4ba..17feb01f6 100644
--- a/grc/python/flow_graph.tmpl
+++ b/grc/python/flow_graph.tmpl
@@ -244,12 +244,20 @@ if __name__ == '__main__':
#end if
#if $generate_options == 'wx_gui'
tb = $(class_name)($(', '.join($params_eq_list)))
+ #if $flow_graph.get_option('max_nouts')
+ tb.Run($flow_graph.get_option('run'), $flow_graph.get_option('max_nouts'))
+ #else
tb.Run($flow_graph.get_option('run'))
+ #end if
#elif $generate_options == 'qt_gui'
qapp = Qt.QApplication(sys.argv)
tb = $(class_name)($(', '.join($params_eq_list)))
#if $flow_graph.get_option('run')
+ #if $flow_graph.get_option('max_nouts')
+ tb.start($flow_graph.get_option('max_nouts'))
+ #else
tb.start()
+ #end if
#end if
tb.show()
qapp.exec_()
@@ -258,11 +266,19 @@ if __name__ == '__main__':
tb = $(class_name)($(', '.join($params_eq_list)))
#set $run_options = $flow_graph.get_option('run_options')
#if $run_options == 'prompt'
+ #if $flow_graph.get_option('max_nouts')
+ tb.start($flow_graph.get_option('max_nouts'))
+ #else
tb.start()
+ #end if
raw_input('Press Enter to quit: ')
tb.stop()
#elif $run_options == 'run'
+ #if $flow_graph.get_option('max_nouts')
+ tb.run($flow_graph.get_option('max_nouts'))
+ #else
tb.run()
+ #end if
#end if
#end if
#end if
diff --git a/volk/CMakeLists.txt b/volk/CMakeLists.txt
index fdde308ad..68385f974 100644
--- a/volk/CMakeLists.txt
+++ b/volk/CMakeLists.txt
@@ -54,10 +54,30 @@ SET(CROSSCOMPILE_MULTILIB ${CROSSCOMPILE_MULTILIB} CACHE STRING "Define \"true\"
########################################################################
# Dependencies setup
########################################################################
-find_package(PythonInterp REQUIRED PYTHON_EXECUTABLE)
+include(GrPython) #sets PYTHON_EXECUTABLE and PYTHON_DASH_B
+GR_PYTHON_CHECK_MODULE("python >= 2.5" sys "sys.version.split()[0] >= '2.5'" PYTHON_MIN_VER_FOUND)
+GR_PYTHON_CHECK_MODULE("Cheetah >= 2.0.0" Cheetah "Cheetah.Version >= '2.0.0'" CHEETAH_FOUND)
+
+if(NOT PYTHON_MIN_VER_FOUND)
+ message(FATAL_ERROR "Python 2.5 or greater required to build VOLK")
+endif()
+
+if(NOT CHEETAH_FOUND)
+ message(FATAL_ERROR "Cheetah templates required to build VOLK")
+endif()
+
+set(Boost_ADDITIONAL_VERSIONS
+ "1.35.0" "1.35" "1.36.0" "1.36" "1.37.0" "1.37" "1.38.0" "1.38" "1.39.0" "1.39"
+ "1.40.0" "1.40" "1.41.0" "1.41" "1.42.0" "1.42" "1.43.0" "1.43" "1.44.0" "1.44"
+ "1.45.0" "1.45" "1.46.0" "1.46" "1.47.0" "1.47" "1.48.0" "1.48" "1.49.0" "1.49"
+ "1.50.0" "1.50" "1.51.0" "1.51" "1.52.0" "1.52" "1.53.0" "1.53" "1.54.0" "1.54"
+ "1.55.0" "1.55" "1.56.0" "1.56" "1.57.0" "1.57" "1.58.0" "1.58" "1.59.0" "1.59"
+ "1.60.0" "1.60" "1.61.0" "1.61" "1.62.0" "1.62" "1.63.0" "1.63" "1.64.0" "1.64"
+ "1.65.0" "1.65" "1.66.0" "1.66" "1.67.0" "1.67" "1.68.0" "1.68" "1.69.0" "1.69"
+)
find_package(Boost COMPONENTS unit_test_framework)
-find_package(ORC)
+find_package(ORC)
########################################################################
# Setup the package config file
diff --git a/volk/apps/CMakeLists.txt b/volk/apps/CMakeLists.txt
index 14291e5e3..175105a5a 100644
--- a/volk/apps/CMakeLists.txt
+++ b/volk/apps/CMakeLists.txt
@@ -1,5 +1,5 @@
#
-# Copyright 2011 Free Software Foundation, Inc.
+# Copyright 2011-2012 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -43,9 +43,8 @@ add_executable(volk_profile
target_link_libraries(volk_profile volk ${Boost_LIBRARIES})
install(
- PROGRAMS
- ${CMAKE_BINARY_DIR}/apps/volk_profile
- DESTINATION ${GR_RUNTIME_DIR}
+ TARGETS volk_profile
+ DESTINATION bin
COMPONENT "volk"
)
diff --git a/volk/cmake/GrPython.cmake b/volk/cmake/GrPython.cmake
new file mode 100644
index 000000000..eff9cbcdc
--- /dev/null
+++ b/volk/cmake/GrPython.cmake
@@ -0,0 +1,233 @@
+# Copyright 2010-2011 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.
+
+if(DEFINED __INCLUDED_GR_PYTHON_CMAKE)
+ return()
+endif()
+set(__INCLUDED_GR_PYTHON_CMAKE TRUE)
+
+########################################################################
+# Setup the python interpreter:
+# This allows the user to specify a specific interpreter,
+# or finds the interpreter via the built-in cmake module.
+########################################################################
+#this allows the user to override PYTHON_EXECUTABLE
+if(PYTHON_EXECUTABLE)
+
+ set(PYTHONINTERP_FOUND TRUE)
+
+#otherwise if not set, try to automatically find it
+else(PYTHON_EXECUTABLE)
+
+ #use the built-in find script
+ find_package(PythonInterp)
+
+ #and if that fails use the find program routine
+ if(NOT PYTHONINTERP_FOUND)
+ find_program(PYTHON_EXECUTABLE NAMES python python2.7 python2.6 python2.5)
+ if(PYTHON_EXECUTABLE)
+ set(PYTHONINTERP_FOUND TRUE)
+ endif(PYTHON_EXECUTABLE)
+ endif(NOT PYTHONINTERP_FOUND)
+
+endif(PYTHON_EXECUTABLE)
+
+#make the path to the executable appear in the cmake gui
+set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter")
+
+#make sure we can use -B with python (introduced in 2.6)
+if(PYTHON_EXECUTABLE)
+ execute_process(
+ COMMAND ${PYTHON_EXECUTABLE} -B -c ""
+ OUTPUT_QUIET ERROR_QUIET
+ RESULT_VARIABLE PYTHON_HAS_DASH_B_RESULT
+ )
+ if(PYTHON_HAS_DASH_B_RESULT EQUAL 0)
+ set(PYTHON_DASH_B "-B")
+ endif()
+endif(PYTHON_EXECUTABLE)
+
+########################################################################
+# Check for the existence of a python module:
+# - desc a string description of the check
+# - mod the name of the module to import
+# - cmd an additional command to run
+# - have the result variable to set
+########################################################################
+macro(GR_PYTHON_CHECK_MODULE desc mod cmd have)
+ message(STATUS "")
+ message(STATUS "Python checking for ${desc}")
+ execute_process(
+ COMMAND ${PYTHON_EXECUTABLE} -c "
+#########################################
+try: import ${mod}
+except:
+ try: ${mod}
+ except: exit(-1)
+try: assert ${cmd}
+except: exit(-1)
+#########################################"
+ RESULT_VARIABLE ${have}
+ )
+ if(${have} EQUAL 0)
+ message(STATUS "Python checking for ${desc} - found")
+ set(${have} TRUE)
+ else(${have} EQUAL 0)
+ message(STATUS "Python checking for ${desc} - not found")
+ set(${have} FALSE)
+ endif(${have} EQUAL 0)
+endmacro(GR_PYTHON_CHECK_MODULE)
+
+########################################################################
+# Sets the python installation directory GR_PYTHON_DIR
+########################################################################
+execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "
+from distutils import sysconfig
+print sysconfig.get_python_lib(plat_specific=True, prefix='')
+" OUTPUT_VARIABLE GR_PYTHON_DIR OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+file(TO_CMAKE_PATH ${GR_PYTHON_DIR} GR_PYTHON_DIR)
+
+########################################################################
+# Create an always-built target with a unique name
+# Usage: GR_UNIQUE_TARGET(<description> <dependencies list>)
+########################################################################
+function(GR_UNIQUE_TARGET desc)
+ file(RELATIVE_PATH reldir ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
+ execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib
+unique = hashlib.md5('${reldir}${ARGN}').hexdigest()[:5]
+print(re.sub('\\W', '_', '${desc} ${reldir} ' + unique))"
+ OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE)
+ add_custom_target(${_target} ALL DEPENDS ${ARGN})
+endfunction(GR_UNIQUE_TARGET)
+
+########################################################################
+# Install python sources (also builds and installs byte-compiled python)
+########################################################################
+function(GR_PYTHON_INSTALL)
+ include(CMakeParseArgumentsCopy)
+ CMAKE_PARSE_ARGUMENTS(GR_PYTHON_INSTALL "" "DESTINATION;COMPONENT" "FILES;PROGRAMS" ${ARGN})
+
+ ####################################################################
+ if(GR_PYTHON_INSTALL_FILES)
+ ####################################################################
+ install(${ARGN}) #installs regular python files
+
+ #create a list of all generated files
+ unset(pysrcfiles)
+ unset(pycfiles)
+ unset(pyofiles)
+ foreach(pyfile ${GR_PYTHON_INSTALL_FILES})
+ get_filename_component(pyfile ${pyfile} ABSOLUTE)
+ list(APPEND pysrcfiles ${pyfile})
+
+ #determine if this file is in the source or binary directory
+ file(RELATIVE_PATH source_rel_path ${CMAKE_CURRENT_SOURCE_DIR} ${pyfile})
+ string(LENGTH "${source_rel_path}" source_rel_path_len)
+ file(RELATIVE_PATH binary_rel_path ${CMAKE_CURRENT_BINARY_DIR} ${pyfile})
+ string(LENGTH "${binary_rel_path}" binary_rel_path_len)
+
+ #and set the generated path appropriately
+ if(${source_rel_path_len} GREATER ${binary_rel_path_len})
+ set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${binary_rel_path})
+ else()
+ set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${source_rel_path})
+ endif()
+ list(APPEND pycfiles ${pygenfile}c)
+ list(APPEND pyofiles ${pygenfile}o)
+
+ #ensure generation path exists
+ get_filename_component(pygen_path ${pygenfile} PATH)
+ file(MAKE_DIRECTORY ${pygen_path})
+
+ endforeach(pyfile)
+
+ #the command to generate the pyc files
+ add_custom_command(
+ DEPENDS ${pysrcfiles} OUTPUT ${pycfiles}
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pycfiles}
+ )
+
+ #the command to generate the pyo files
+ add_custom_command(
+ DEPENDS ${pysrcfiles} OUTPUT ${pyofiles}
+ COMMAND ${PYTHON_EXECUTABLE} -O ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pyofiles}
+ )
+
+ #create install rule and add generated files to target list
+ set(python_install_gen_targets ${pycfiles} ${pyofiles})
+ install(FILES ${python_install_gen_targets}
+ DESTINATION ${GR_PYTHON_INSTALL_DESTINATION}
+ COMPONENT ${GR_PYTHON_INSTALL_COMPONENT}
+ )
+
+
+ ####################################################################
+ elseif(GR_PYTHON_INSTALL_PROGRAMS)
+ ####################################################################
+ file(TO_NATIVE_PATH ${PYTHON_EXECUTABLE} pyexe_native)
+
+ if (CMAKE_CROSSCOMPILING)
+ set(pyexe_native /usr/bin/env python)
+ endif()
+
+ foreach(pyfile ${GR_PYTHON_INSTALL_PROGRAMS})
+ get_filename_component(pyfile_name ${pyfile} NAME)
+ get_filename_component(pyfile ${pyfile} ABSOLUTE)
+ string(REPLACE "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" pyexefile "${pyfile}.exe")
+ list(APPEND python_install_gen_targets ${pyexefile})
+
+ get_filename_component(pyexefile_path ${pyexefile} PATH)
+ file(MAKE_DIRECTORY ${pyexefile_path})
+
+ add_custom_command(
+ OUTPUT ${pyexefile} DEPENDS ${pyfile}
+ COMMAND ${PYTHON_EXECUTABLE} -c
+ \"open('${pyexefile}', 'w').write('\#!${pyexe_native}\\n'+open('${pyfile}').read())\"
+ COMMENT "Shebangin ${pyfile_name}"
+ )
+
+ #on windows, python files need an extension to execute
+ get_filename_component(pyfile_ext ${pyfile} EXT)
+ if(WIN32 AND NOT pyfile_ext)
+ set(pyfile_name "${pyfile_name}.py")
+ endif()
+
+ install(PROGRAMS ${pyexefile} RENAME ${pyfile_name}
+ DESTINATION ${GR_PYTHON_INSTALL_DESTINATION}
+ COMPONENT ${GR_PYTHON_INSTALL_COMPONENT}
+ )
+ endforeach(pyfile)
+
+ endif()
+
+ GR_UNIQUE_TARGET("pygen" ${python_install_gen_targets})
+
+endfunction(GR_PYTHON_INSTALL)
+
+########################################################################
+# Write the python helper script that generates byte code files
+########################################################################
+file(WRITE ${CMAKE_BINARY_DIR}/python_compile_helper.py "
+import sys, py_compile
+files = sys.argv[1:]
+srcs, gens = files[:len(files)/2], files[len(files)/2:]
+for src, gen in zip(srcs, gens):
+ py_compile.compile(file=src, cfile=gen, doraise=True)
+")
diff --git a/volk/cmake/msvc/config.h b/volk/cmake/msvc/config.h
new file mode 100644
index 000000000..43792c783
--- /dev/null
+++ b/volk/cmake/msvc/config.h
@@ -0,0 +1,58 @@
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_CONFIG_H_ // [
+#define _MSC_CONFIG_H_
+
+////////////////////////////////////////////////////////////////////////
+// enable inline functions for C code
+////////////////////////////////////////////////////////////////////////
+#ifndef __cplusplus
+# define inline __inline
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// signed size_t
+////////////////////////////////////////////////////////////////////////
+#include <stddef.h>
+typedef ptrdiff_t ssize_t;
+
+////////////////////////////////////////////////////////////////////////
+// rint functions
+////////////////////////////////////////////////////////////////////////
+#include <math.h>
+static inline long lrint(double x){return (long)(x > 0.0 ? x + 0.5 : x - 0.5);}
+static inline long lrintf(float x){return (long)(x > 0.0f ? x + 0.5f : x - 0.5f);}
+static inline long long llrint(double x){return (long long)(x > 0.0 ? x + 0.5 : x - 0.5);}
+static inline long long llrintf(float x){return (long long)(x > 0.0f ? x + 0.5f : x - 0.5f);}
+static inline double rint(double x){return (x > 0.0)? floor(x + 0.5) : ceil(x - 0.5);}
+static inline float rintf(float x){return (x > 0.0f)? floorf(x + 0.5f) : ceilf(x - 0.5f);}
+
+////////////////////////////////////////////////////////////////////////
+// math constants
+////////////////////////////////////////////////////////////////////////
+#define INFINITY HUGE_VAL
+
+# define M_E 2.7182818284590452354 /* e */
+# define M_LOG2E 1.4426950408889634074 /* log_2 e */
+# define M_LOG10E 0.43429448190325182765 /* log_10 e */
+# define M_LN2 0.69314718055994530942 /* log_e 2 */
+# define M_LN10 2.30258509299404568402 /* log_e 10 */
+# define M_PI 3.14159265358979323846 /* pi */
+# define M_PI_2 1.57079632679489661923 /* pi/2 */
+# define M_PI_4 0.78539816339744830962 /* pi/4 */
+# define M_1_PI 0.31830988618379067154 /* 1/pi */
+# define M_2_PI 0.63661977236758134308 /* 2/pi */
+# define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */
+# define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
+# define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
+
+////////////////////////////////////////////////////////////////////////
+// random and srandom
+////////////////////////////////////////////////////////////////////////
+#include <stdlib.h>
+static inline long int random (void) { return rand(); }
+static inline void srandom (unsigned int seed) { srand(seed); }
+
+#endif // _MSC_CONFIG_H_ ]
diff --git a/volk/msvc/inttypes.h b/volk/cmake/msvc/inttypes.h
index 0a1b60fc1..0a1b60fc1 100644
--- a/volk/msvc/inttypes.h
+++ b/volk/cmake/msvc/inttypes.h
diff --git a/volk/msvc/stdint.h b/volk/cmake/msvc/stdint.h
index 108bc8982..108bc8982 100644
--- a/volk/msvc/stdint.h
+++ b/volk/cmake/msvc/stdint.h
diff --git a/volk/gen/archs.xml b/volk/gen/archs.xml
index 59cc81cc5..2c9ab41a5 100644
--- a/volk/gen/archs.xml
+++ b/volk/gen/archs.xml
@@ -1,155 +1,183 @@
<!-- archs appear in order of significance for blind, de-facto version ordering -->
<grammar>
-<arch name="generic" type="all"> <!-- name and type are both required-->
- <flag>none</flag> <!-- flag is the only required field-->
+<arch name="generic"> <!-- name is required-->
</arch>
-<arch name="altivec" type="powerpc">
- <flag>maltivec</flag>
+<arch name="altivec">
+ <flag compiler="gnu">-maltivec</flag>
<alignment>16</alignment>
+ <check name="has_ppc"></check>
</arch>
-<arch name="neon" type="arm">
- <flag>mfpu=neon,mfloat-abi=softfp,funsafe-math-optimizations</flag>
+<arch name="neon">
+ <flag compiler="gnu">-mfpu=neon</flag>
+ <flag compiler="gnu">-mfloat-abi=softfp</flag>
+ <flag compiler="gnu">-funsafe-math-optimizations</flag>
<alignment>16</alignment>
+ <check name="has_neon"></check>
</arch>
-<arch name="32" type="x86" no_test="true" >
- <flag>m32</flag>
- <overrule>MD_SUBCPU</overrule>
- <overrule_val>x86_64</overrule_val>
+<arch name="32">
+ <flag compiler="gnu">-m32</flag>
</arch>
-<arch name="64" type="x86">
- <op>0x80000001</op>
- <reg>d</reg>
- <shift>29</shift>
- <flag>m64</flag>
- <val>1</val>
- <overrule>MD_SUBCPU</overrule>
- <overrule_val>x86</overrule_val>
+<arch name="64">
+ <check name="check_extended_cpuid">
+ <param>0x80000001</param>
+ </check>
+ <check name="cpuid_x86_bit"> <!-- checks to see if a bit is set -->
+ <param>3</param> <!-- eax, ebx, ecx, [edx] -->
+ <param>0x80000001</param> <!-- cpuid operation -->
+ <param>29</param> <!-- bit shift -->
+ </check>
+ <flag compiler="gnu">-m64</flag>
</arch>
-<arch name="3dnow" type="x86">
- <op>0x80000001</op>
- <reg>d</reg>
- <shift>31</shift>
- <flag>m3dnow</flag>
- <val>1</val>
+<arch name="3dnow">
+ <check name="cpuid_x86_bit">
+ <param>3</param>
+ <param>0x80000001</param>
+ <param>31</param>
+ </check>
+ <flag compiler="gnu">-m3dnow</flag>
<alignment>8</alignment>
</arch>
-<arch name="abm" type="x86">
- <val>1</val>
- <op>0x80000001</op>
- <reg>d</reg>
- <shift>5</shift>
- <flag>msse4.2</flag>
+<arch name="abm">
+ <check name="cpuid_x86_bit">
+ <param>3</param>
+ <param>0x80000001</param>
+ <param>5</param>
+ </check>
+ <flag compiler="gnu">-msse4.2</flag>
<alignment>16</alignment>
</arch>
-<arch name="popcount" type="x86">
- <val>1</val>
- <op>1</op>
- <reg>c</reg>
- <shift>23</shift>
- <flag>mpopcnt</flag>
-</arch>
-
-<arch name="mmx" type="x86">
- <val>1</val>
- <op>1</op>
- <reg>d</reg>
- <shift>23</shift>
- <flag>mmmx</flag>
+<arch name="popcount">
+ <check name="cpuid_x86_bit">
+ <param>2</param>
+ <param>0x00000001</param>
+ <param>23</param>
+ </check>
+ <flag compiler="gnu">-mpopcnt</flag>
+ <flag compiler="msvc">/arch:AVX</flag>
+</arch>
+
+<arch name="mmx">
+ <check name="cpuid_x86_bit">
+ <param>3</param>
+ <param>0x00000001</param>
+ <param>23</param>
+ </check>
+ <flag compiler="gnu">-mmmx</flag>
+ <flag compiler="msvc">/arch:SSE</flag>
<alignment>8</alignment>
</arch>
-
-<arch name="sse" type="x86">
- <val>1</val>
- <op>1</op>
- <reg>d</reg>
- <shift>25</shift>
- <flag>msse</flag>
+<arch name="sse">
+ <check name="cpuid_x86_bit">
+ <param>3</param>
+ <param>0x00000001</param>
+ <param>25</param>
+ </check>
+ <flag compiler="gnu">-msse</flag>
+ <flag compiler="msvc">/arch:SSE</flag>
<environment>_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);</environment>
<include>xmmintrin.h</include>
<alignment>16</alignment>
</arch>
-
-<arch name="sse2" type="x86">
- <val>1</val>
- <op>1</op>
- <reg>d</reg>
- <shift>26</shift>
- <flag>msse2</flag>
+<arch name="sse2">
+ <check name="cpuid_x86_bit">
+ <param>3</param>
+ <param>0x00000001</param>
+ <param>26</param>
+ </check>
+ <flag compiler="gnu">-msse2</flag>
+ <flag compiler="msvc">/arch:SSE2</flag>
<alignment>16</alignment>
</arch>
-<arch name="orc" type="all">
- <flag>lorc-0.4</flag>
- <overrule>LV_HAVE_ORC</overrule>
- <overrule_val>no</overrule_val>
+<arch name="orc">
</arch>
-<arch name="sse3" type="x86">
- <val>1</val>
- <op>1</op>
- <reg>c</reg>
- <shift>0</shift>
- <flag>msse3</flag>
+<!-- it's here for overrule stuff. -->
+<arch name="norc">
+</arch>
+
+<arch name="sse3">
+ <check name="cpuid_x86_bit">
+ <param>2</param>
+ <param>0x00000001</param>
+ <param>0</param>
+ </check>
+ <flag compiler="gnu">-msse3</flag>
+ <flag compiler="msvc">/arch:AVX</flag>
<environment>_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);</environment>
<include>pmmintrin.h</include>
<alignment>16</alignment>
</arch>
-<arch name="ssse3" type="x86">
- <val>1</val>
- <op>1</op>
- <reg>c</reg>
- <shift>9</shift>
- <flag>mssse3</flag>
+<arch name="ssse3">
+ <check name="cpuid_x86_bit">
+ <param>2</param>
+ <param>0x00000001</param>
+ <param>9</param>
+ </check>
+ <flag compiler="gnu">-mssse3</flag>
+ <flag compiler="msvc">/arch:AVX</flag>
<alignment>16</alignment>
</arch>
-<arch name="sse4_a" type="x86">
- <val>1</val>
- <op>0x80000001</op>
- <reg>c</reg>
- <shift>6</shift>
- <flag>msse4a</flag>
+<arch name="sse4_a">
+ <check name="cpuid_x86_bit">
+ <param>2</param>
+ <param>0x80000001</param>
+ <param>6</param>
+ </check>
+ <flag compiler="gnu">-msse4a</flag>
<alignment>16</alignment>
</arch>
-
-<arch name="sse4_1" type="x86">
- <val>1</val>
- <op>1</op>
- <reg>c</reg>
- <shift>19</shift>
- <flag>msse4.1</flag>
+<arch name="sse4_1">
+ <check name="cpuid_x86_bit">
+ <param>2</param>
+ <param>0x00000001</param>
+ <param>19</param>
+ </check>
+ <flag compiler="gnu">-msse4.1</flag>
+ <flag compiler="msvc">/arch:AVX</flag>
<alignment>16</alignment>
</arch>
-<arch name="sse4_2" type="x86">
- <val>1</val>
- <op>1</op>
- <reg>c</reg>
- <shift>20</shift>
- <flag>msse4.2</flag>
+<arch name="sse4_2">
+ <check name="cpuid_x86_bit">
+ <param>2</param>
+ <param>0x00000001</param>
+ <param>20</param>
+ </check>
+ <flag compiler="gnu">-msse4.2</flag>
+ <flag compiler="msvc">/arch:AVX</flag>
<alignment>16</alignment>
</arch>
-<arch name="avx" type="x86">
- <val>1</val>
- <op>1</op>
- <reg>c</reg>
- <shift>28</shift>
- <flag>mavx</flag>
- <check>xgetbv</check>
- <checkval>7</checkval>
+<arch name="avx">
+ <check name="cpuid_x86_bit">
+ <param>2</param>
+ <param>0x00000001</param>
+ <param>28</param>
+ </check>
+ <!-- check to make sure that xgetbv is enabled in OS -->
+ <check name="cpuid_x86_bit">
+ <param>2</param>
+ <param>0x00000001</param>
+ <param>27</param>
+ </check>
+ <!-- check to see that the OS has enabled AVX -->
+ <check name="get_avx_enabled"></check>
+ <flag compiler="gnu">-mavx</flag>
+ <flag compiler="msvc">/arch:AVX</flag>
<alignment>32</alignment>
</arch>
diff --git a/volk/gen/compilers.xml b/volk/gen/compilers.xml
deleted file mode 100644
index 005eda2aa..000000000
--- a/volk/gen/compilers.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!-- compilers remap gcc-specific information from archs.xml to specific compiler cases-->
-<grammar>
-
-<compiler name="MSVC">
- <!-- remap the following flags to SSE -->
- <remap name="mmmx">arch:SSE</remap>
- <remap name="msse">arch:SSE</remap>
-
- <!-- remap the following flags to SSE2 -->
- <remap name="msse2">arch:SSE2</remap>
-
- <!-- remap the following flags to AVX -->
- <remap name="msse3">arch:AVX</remap>
- <remap name="mssse3">arch:AVX</remap>
- <remap name="msse4.1">arch:AVX</remap>
- <remap name="msse4.2">arch:AVX</remap>
- <remap name="mpopcnt">arch:AVX</remap>
- <remap name="mavx">arch:AVX</remap>
-
- <prefix>/</prefix>
-</compiler>
-
-<compiler name="GNU">
- <prefix>-</prefix>
-</compiler>
-
-
-
-
-</grammar>
diff --git a/volk/gen/machines.xml b/volk/gen/machines.xml
index 9c19c91c6..8e3c9c8c2 100644
--- a/volk/gen/machines.xml
+++ b/volk/gen/machines.xml
@@ -1,64 +1,51 @@
<grammar>
<machine name="generic">
-<archs>generic</archs>
+<archs>generic orc|</archs>
</machine>
<!--
<machine name="mmx">
-<archs>generic 32|64 mmx</archs>
+<archs>generic 32|64 mmx orc|</archs>
</machine>
<machine name="sse">
-<archs>generic 32|64 mmx sse</archs>
+<archs>generic 32|64| mmx sse orc|</archs>
</machine>
-->
-<!--
-Create an SSE2 and AVX only machine (without 64/32 inline assembly support).
-This machine is intended to support the MSVC compiler on x86/amd64.
-The MSVC compiler has intrinsic support for SSE, SSE2, AVX
-however it does not support the gcc style inline assembly.
--->
-
<machine name="neon">
-<archs>generic neon</archs>
-</machine>
-
-<machine name="sse2_only">
-<archs>generic mmx sse sse2</archs>
+<archs>generic neon orc|</archs>
</machine>
+<!-- trailing | bar means generate without either for MSVC -->
<machine name="sse2">
-<archs>generic 32|64 mmx sse sse2</archs>
+<archs>generic 32|64| mmx sse sse2 orc|</archs>
</machine>
<machine name="sse3">
-<archs>generic 32|64 mmx sse sse2 sse3</archs>
+<archs>generic 32|64 mmx sse sse2 sse3 orc|</archs>
</machine>
<machine name="ssse3">
-<archs>generic 32|64 mmx sse sse2 sse3 ssse3</archs>
+<archs>generic 32|64 mmx sse sse2 sse3 ssse3 orc|</archs>
</machine>
<machine name="sse4_a">
-<archs>generic 32|64 mmx sse sse2 sse3 sse4_a popcount</archs>
+<archs>generic 32|64 mmx sse sse2 sse3 sse4_a popcount orc|</archs>
</machine>
<machine name="sse4_1">
-<archs>generic 32|64 mmx sse sse2 sse3 ssse3 sse4_1</archs>
+<archs>generic 32|64 mmx sse sse2 sse3 ssse3 sse4_1 orc|</archs>
</machine>
<machine name="sse4_2">
-<archs>generic 32|64 mmx sse sse2 sse3 ssse3 sse4_1 sse4_2 popcount</archs>
+<archs>generic 32|64 mmx sse sse2 sse3 ssse3 sse4_1 sse4_2 popcount orc|</archs>
</machine>
+<!-- trailing | bar means generate without either for MSVC -->
<machine name="avx">
-<archs>generic 32|64 mmx sse sse2 sse3 ssse3 sse4_1 sse4_2 popcount avx</archs>
-</machine>
-
-<machine name="avx_only">
-<archs>generic mmx sse sse2 sse3 ssse3 sse4_1 sse4_2 popcount avx</archs>
+<archs>generic 32|64| mmx sse sse2 sse3 ssse3 sse4_1 sse4_2 popcount avx orc|</archs>
</machine>
<machine name="altivec">
diff --git a/volk/gen/make_c.py b/volk/gen/make_c.py
deleted file mode 100644
index 233cb85c2..000000000
--- a/volk/gen/make_c.py
+++ /dev/null
@@ -1,88 +0,0 @@
-#
-# Copyright 2010-2011 Free Software Foundation, Inc.
-#
-# This program 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 of the License, or
-# (at your option) any later version.
-#
-# This program 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, see <http://www.gnu.org/licenses/>.
-#
-
-from volk_regexp import *
-import string
-
-#ok todo list:
-#put n_archs into the info struct so it doesn't have to be arch_defs[0].
-
-def make_c(machines, archs, functions, arched_arglist, my_arglist):
- tempstring = r"""
-// This file is automatically generated by make_c.py.
-// Do not edit this file.
-"""
- tempstring += """
-#include <volk/volk_common.h>
-#include "volk_machines.h"
-#include <volk/volk_typedefs.h>
-#include <volk/volk_cpu.h>
-#include "volk_rank_archs.h"
-#include <volk/volk.h>
-#include <stdio.h>
-#include <string.h>
-
-"""
-
-#OK here's the deal. the .h prototypes the functions. the .c impls them as fptrs, can use p_whatever.
-#also .c impls the get_machine call
-#also .c impls the default call for each fn
-
-#here do static fn get arch
- tempstring += r"""
-struct volk_machine *get_machine(void) {
- extern struct volk_machine *volk_machines[];
- extern unsigned int n_volk_machines;
- static struct volk_machine *machine = NULL;
-
- if(machine != NULL) return machine;
- else {
- unsigned int max_score = 0;
- unsigned int i;
- for(i=0; i<n_volk_machines; i++) {
- if(!(volk_machines[i]->caps & (~volk_get_lvarch()))) {
- if(volk_machines[i]->caps > max_score) {
- max_score = volk_machines[i]->caps;
- machine = volk_machines[i];
- }
- }
- }
- printf("Using Volk machine: %s\n", machine->name);
- return machine;
- }
-}
-
-unsigned int volk_get_alignment(void) {
- return get_machine()->alignment;
-}
-
-"""
-
- for i in range(len(functions)):
- tempstring += "void get_" + functions[i] + replace_arch.sub("", arched_arglist[i]) + "\n"
- tempstring += " %s = get_machine()->%s_archs[volk_rank_archs(get_machine()->%s_indices, get_machine()->%s_arch_defs, get_machine()->%s_n_archs, get_machine()->%s_name, volk_get_lvarch())];\n" % (functions[i], functions[i], functions[i], functions[i], functions[i], functions[i])
- tempstring += " %s(%s);\n}\n\n" % (functions[i], my_arglist[i])
- tempstring += replace_volk.sub("p", functions[i]) + " " + functions[i] + " = &get_" + functions[i] + ";\n\n"
- tempstring += "void %s_manual%s\n" % (functions[i], arched_arglist[i])
- tempstring += " get_machine()->%s_archs[get_index(get_machine()->%s_indices, get_machine()->%s_n_archs, arch)](%s);\n}\n" % (functions[i], functions[i], functions[i], my_arglist[i])
- tempstring += "struct volk_func_desc %s_get_func_desc(void) {\n" % (functions[i])
- tempstring += " struct volk_func_desc desc = {get_machine()->%s_indices, get_machine()->%s_arch_defs, get_machine()->%s_n_archs};\n" % (functions[i], functions[i], functions[i])
- tempstring += " return desc;\n}\n"
-
- return tempstring
-
-
diff --git a/volk/gen/make_config_fixed.py b/volk/gen/make_config_fixed.py
deleted file mode 100644
index 96f20b6b2..000000000
--- a/volk/gen/make_config_fixed.py
+++ /dev/null
@@ -1,21 +0,0 @@
-from xml.dom import minidom
-
-def make_config_fixed(dom) :
- tempstring = "";
- tempstring = tempstring +'/*this file is auto generated by volk_register.py*/';
- tempstring = tempstring + '\n#ifndef INCLUDED_VOLK_CONFIG_FIXED_H';
- tempstring = tempstring + '\n#define INCLUDED_VOLK_CONFIG_FIXED_H';
- tempstring = tempstring + '\n\n';
- enum_counter = 0;
- for domarch in dom:
- arch = str(domarch.attributes["name"].value);
- tempstring = tempstring + '#define LV_' + arch.swapcase() + " " + str(enum_counter) + '\n';
- enum_counter = enum_counter + 1;
- tempstring = tempstring + '\n\n';
-
- tempstring = tempstring + "#endif /*INCLUDED_VOLK_CONFIG_FIXED*/\n"
-
- return tempstring;
-
-
-
diff --git a/volk/gen/make_config_in.py b/volk/gen/make_config_in.py
deleted file mode 100644
index d29680af2..000000000
--- a/volk/gen/make_config_in.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from xml.dom import minidom
-
-def make_config_in(dom) :
- tempstring = "";
- tempstring = tempstring +'/*this file is auto generated by volk_register.py*/';
- tempstring = tempstring + '\n\n';
-
- for domarch in dom:
- arch = str(domarch.attributes["name"].value);
- tempstring = tempstring + '#undef LV_HAVE_' + arch.swapcase() + '\n';
- tempstring = tempstring + '\n';
-
- return tempstring
diff --git a/volk/gen/make_cpuid_c.py b/volk/gen/make_cpuid_c.py
deleted file mode 100644
index 005fc2b19..000000000
--- a/volk/gen/make_cpuid_c.py
+++ /dev/null
@@ -1,283 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2011 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 xml.dom import minidom
-
-HEADER_TEMPL = """\
-/*this file is auto_generated by volk_register.py*/
-
-#include <volk/volk_cpu.h>
-#include <volk/volk_config_fixed.h>
-
-struct VOLK_CPU volk_cpu;
-
-#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)
-# define VOLK_CPU_x86
-#endif
-
-#if defined(VOLK_CPU_x86)
-
-//implement get cpuid for gcc compilers using a copy of cpuid.h
-#if defined(__GNUC__)
-#include <gcc_x86_cpuid.h>
-#define cpuid_x86(op, r) __get_cpuid(op, (unsigned int *)r+0, (unsigned int *)r+1, (unsigned int *)r+2, (unsigned int *)r+3)
-
- /* Return Intel AVX extended CPU capabilities register.
- * This function will bomb on non-AVX-capable machines, so
- * check for AVX capability before executing.
- */
- #if __GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 4
- static inline unsigned long long _xgetbv(unsigned int index){
- unsigned int eax, edx;
- __asm__ __volatile__("xgetbv" : "=a"(eax), "=d"(edx) : "c"(index));
- return ((unsigned long long)edx << 32) | eax;
- }
- #define __xgetbv() _xgetbv(0)
- #else
- #define __xgetbv() 0
- #endif
-
-//implement get cpuid for MSVC compilers using __cpuid intrinsic
-#elif defined(_MSC_VER)
-#include <intrin.h>
-#define cpuid_x86(op, r) __cpuid(r, op)
-
- #if defined(_XCR_XFEATURE_ENABLED_MASK)
- #define __xgetbv() _xgetbv(_XCR_XFEATURE_ENABLED_MASK)
- #else
- #define __xgetbv() 0
- #endif
-
-#else
-#error "A get cpuid for volk is not available on this compiler..."
-#endif
-
-static inline unsigned int cpuid_eax(unsigned int op) {
- int regs[4];
- cpuid_x86 (op, regs);
- return regs[0];
-}
-
-static inline unsigned int cpuid_ebx(unsigned int op) {
- int regs[4];
- cpuid_x86 (op, regs);
- return regs[1];
-}
-
-static inline unsigned int cpuid_ecx(unsigned int op) {
- int regs[4];
- cpuid_x86 (op, regs);
- return regs[2];
-}
-
-static inline unsigned int cpuid_edx(unsigned int op) {
- int regs[4];
- cpuid_x86 (op, regs);
- return regs[3];
-}
-
-static inline unsigned int xgetbv(void) {
- //check to make sure that xgetbv is enabled in OS
- int xgetbv_enabled = cpuid_ecx(1) >> 27 & 0x01;
- if(xgetbv_enabled == 0) return 0;
- return __xgetbv();
-}
-#endif
-
-"""
-
-def make_cpuid_c(dom) :
- tempstring = HEADER_TEMPL;
-
- for domarch in dom:
- if str(domarch.attributes["type"].value) == "x86":
- if "no_test" in domarch.attributes.keys():
- no_test = str(domarch.attributes["no_test"].value);
- if no_test == "true":
- no_test = True;
- else:
- no_test = False;
- else:
- no_test = False;
- arch = str(domarch.attributes["name"].value)
- op = domarch.getElementsByTagName("op")
- if op:
- op = str(op[0].firstChild.data)
- reg = domarch.getElementsByTagName("reg")
- if reg:
- reg = str(reg[0].firstChild.data)
- shift = domarch.getElementsByTagName("shift")
- if shift:
- shift = str(shift[0].firstChild.data)
- val = domarch.getElementsByTagName("val")
- if val:
- val = str(val[0].firstChild.data)
- check = domarch.getElementsByTagName("check")
- if check:
- check = str(check[0].firstChild.data)
- checkval = domarch.getElementsByTagName("checkval")
- if checkval:
- checkval = str(checkval[0].firstChild.data)
-
- if no_test:
- tempstring = tempstring + """\
-int i_can_has_%s () {
-#if defined(VOLK_CPU_x86)
- return 1;
-#else
- return 0;
-#endif
-}
-
-""" % (arch)
-
- elif op == "1":
- tempstring = tempstring + """\
-int i_can_has_%s () {
-#if defined(VOLK_CPU_x86)
- unsigned int e%sx = cpuid_e%sx (%s);
- int hwcap = (((e%sx >> %s) & 1) == %s);
-""" % (arch, reg, reg, op, reg, shift, val)
-
- if check and checkval:
- tempstring += """\
- if (hwcap == 0) return 0;
- hwcap &= (%s() == %s);
-""" % (check, checkval)
-
- tempstring += """\
- return hwcap;
-#else
- return 0;
-#endif
-}
-
-"""
-
- elif op == "0x80000001":
- tempstring = tempstring + """\
-int i_can_has_%s () {
-#if defined(VOLK_CPU_x86)
- unsigned int extended_fct_count = cpuid_eax(0x80000000);
- if (extended_fct_count < 0x80000001)
- return %s^1;
- unsigned int extended_features = cpuid_e%sx (%s);
- return ((extended_features >> %s) & 1) == %s;
-#else
- return 0;
-#endif
-}
-
-""" % (arch, val, reg, op, shift, val)
-
- elif str(domarch.attributes["type"].value) == "powerpc":
- arch = str(domarch.attributes["name"].value);
- tempstring = tempstring + """\
-int i_can_has_%s () {
-#ifdef __PPC__
- return 1;
-#else
- return 0;
-#endif
-}
-
-""" % (arch)
-
- elif str(domarch.attributes["type"].value) == "arm":
- arch = str(domarch.attributes["name"].value);
- tempstring = tempstring + """\
-#if defined(__arm__) && defined(__linux__)
-#include <asm/hwcap.h>
-#include <linux/auxvec.h>
-#include <stdio.h>
-#define LOOK_FOR_NEON
-#endif
-
-int i_can_has_%s () {
-//it's linux-specific, but if you're compiling libvolk for NEON
-//on Windows you have other problems
-
-#ifdef LOOK_FOR_NEON
- FILE *auxvec_f;
- unsigned long auxvec[2];
- unsigned int found_neon = 0;
- auxvec_f = fopen("/proc/self/auxv", "rb");
- if(!auxvec_f) return 0;
-
- //so auxv is basically 32b of ID and 32b of value
- //so it goes like this
- while(!found_neon && auxvec_f) {
- fread(auxvec, sizeof(unsigned long), 2, auxvec_f);
- if((auxvec[0] == AT_HWCAP) && (auxvec[1] & HWCAP_NEON))
- found_neon = 1;
- }
-
- fclose(auxvec_f);
- return found_neon;
-
-#else
- return 0;
-#endif
-}
-
-""" % (arch)
-
- elif str(domarch.attributes["type"].value) == "all":
- arch = str(domarch.attributes["name"].value);
- tempstring = tempstring + """\
-int i_can_has_%s () {
- return 1;
-}
-
-""" % (arch)
- else:
- arch = str(domarch.attributes["name"].value);
- tempstring = tempstring + """\
-int i_can_has_%s () {
- return 0;
-}
-
-""" % (arch)
-
- tempstring = tempstring + "void volk_cpu_init() {\n";
- for domarch in dom:
- arch = str(domarch.attributes["name"].value);
- tempstring = tempstring + " volk_cpu.has_" + arch + " = &i_can_has_" + arch + ";\n"
- tempstring = tempstring + "}\n\n"
-
- tempstring = tempstring + "unsigned int volk_get_lvarch() {\n";
- tempstring = tempstring + " unsigned int retval = 0;\n"
- tempstring = tempstring + " volk_cpu_init();\n"
- for domarch in dom:
- arch = str(domarch.attributes["name"].value);
- tempstring = tempstring + " retval += volk_cpu.has_" + arch + "() << LV_" + arch.swapcase() + ";\n"
- tempstring = tempstring + " return retval;\n"
- tempstring = tempstring + "}\n\n"
-
- return tempstring;
-
-
-
-
-
-
-
diff --git a/volk/gen/make_cpuid_h.py b/volk/gen/make_cpuid_h.py
deleted file mode 100644
index 1aa783781..000000000
--- a/volk/gen/make_cpuid_h.py
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2011 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 xml.dom import minidom
-
-def make_cpuid_h(dom) :
- tempstring = "";
- tempstring = tempstring +'/*this file is auto generated by volk_register.py*/';
- tempstring = tempstring +'\n#ifndef INCLUDED_VOLK_CPU_H';
- tempstring = tempstring +'\n#define INCLUDED_VOLK_CPU_H\n\n';
- tempstring = tempstring + "#include <volk/volk_common.h>\n\n";
- tempstring = tempstring + '__VOLK_DECL_BEGIN\n';
- tempstring = tempstring + '\n'
-
- tempstring = tempstring + "struct VOLK_CPU {\n"
- for domarch in dom:
- arch = str(domarch.attributes["name"].value);
- tempstring = tempstring + " int (*has_" + arch + ") ();\n";
- tempstring = tempstring + "};\n\n";
- tempstring = tempstring + "extern struct VOLK_CPU volk_cpu;\n\n";
-
- tempstring = tempstring + "void volk_cpu_init ();\n"
- tempstring = tempstring + "unsigned int volk_get_lvarch ();\n"
-
- tempstring = tempstring + "\n";
- tempstring = tempstring + "__VOLK_DECL_END\n";
- tempstring = tempstring + "#endif /*INCLUDED_VOLK_CPU_H*/\n"
-
- return tempstring;
diff --git a/volk/gen/make_each_machine_c.py b/volk/gen/make_each_machine_c.py
deleted file mode 100644
index 535578859..000000000
--- a/volk/gen/make_each_machine_c.py
+++ /dev/null
@@ -1,90 +0,0 @@
-#
-# Copyright 2010-2011 Free Software Foundation, Inc.
-#
-# This program 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 of the License, or
-# (at your option) any later version.
-#
-# This program 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, see <http://www.gnu.org/licenses/>.
-#
-
-from volk_regexp import *
-import string
-
-def _make_each_machine_struct(machine_name, archs, functions, fcountlist, taglist, alignment):
-
- #make the machine fcountlist and taglist a subset given the archs list
- machine_fcountlists = list()
- machine_taglists = list()
- for i in range(len(fcountlist)):
- machine_fcountlist = list()
- machine_taglist = list()
- for j in range(len(fcountlist[i])):
- if len(set(archs).intersection(map(str.lower, fcountlist[i][j]))) == len(fcountlist[i][j]):
- machine_fcountlist.append(fcountlist[i][j])
- machine_taglist.append(taglist[i][j])
- machine_fcountlists.append(machine_fcountlist)
- machine_taglists.append(machine_taglist)
-
- #create the volk machine struct for this machine file
- tempstring = ""
- tempstring += "struct volk_machine volk_machine_" + machine_name + " = {\n"
- tempstring += " " + ' | '.join(["(1 << LV_" + arch.swapcase() + ")" for arch in archs]) + ",\n"
- tempstring += " \"%s\",\n"%machine_name
- tempstring += " %s,\n"%alignment
-
- #fill in the description for each function
- for i in range(len(functions)):
- tempstring += " \"%s\",\n"%functions[i]
- tempstring += " {%s},\n"%(', '.join(['"%s"'%tag for tag in machine_taglists[i]]))
- tempstring += " {%s},\n"%(', '.join([' | '.join(['(1 << LV_%s)'%fc for fc in fcount]) for fcount in machine_fcountlists[i]]))
- tempstring += " {%s},\n"%(', '.join(['%s_%s'%(functions[i], tag) for tag in machine_taglists[i]]))
- tempstring += " %d,\n"%len(machine_taglists[i])
-
- tempstring = strip_trailing(tempstring, ",")
- tempstring += "};\n"
- return tempstring
-
-def make_each_machine_c(machine_name, archs, functions, fcountlist, taglist, alignment):
- tempstring = r"""
-// This file is automatically generated by make_each_machine_c.py.
-// Do not edit this file.
-"""
- for arch in archs:
- tempstring += "#define LV_HAVE_" + arch.swapcase() + " 1\n"
-
- tempstring += """
-#include <volk/volk_common.h>
-#include "volk_machines.h"
-#include <volk/volk_config_fixed.h>
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-"""
- for func in functions:
- tempstring += "#include <volk/" + func + ".h>\n"
- tempstring += "\n\n"
-
- tempstring += """
-#ifdef LV_HAVE_ORC
-%s
-#else
-%s
-#endif
-"""%(
- _make_each_machine_struct(machine_name, archs+["orc"], functions, fcountlist, taglist, alignment),
- _make_each_machine_struct(machine_name, archs, functions, fcountlist, taglist, alignment)
-)
-
- return tempstring
-
-
diff --git a/volk/gen/make_environment_init_c.py b/volk/gen/make_environment_init_c.py
deleted file mode 100644
index 6186162ee..000000000
--- a/volk/gen/make_environment_init_c.py
+++ /dev/null
@@ -1,32 +0,0 @@
-from xml.dom import minidom
-
-def make_environment_init_c(dom) :
- tempstring = "";
- tempstring = tempstring + "/*this file is auto_generated by volk_register.py*/\n\n";
- tempstring = tempstring + "#include<volk/volk_environment_init.h>\n"
- for domarch in dom:
- arch = str(domarch.attributes["name"].value);
- incs = domarch.getElementsByTagName("include");
- for inc in incs:
- my_inc = str(inc.firstChild.data);
- tempstring = tempstring + "#ifdef LV_HAVE_" + arch.swapcase() + "\n";
- tempstring = tempstring + "#include<" + my_inc + ">\n";
- tempstring = tempstring + "#endif\n"
- tempstring = tempstring + '\n\n';
- tempstring = tempstring + "void volk_environment_init(){\n"
-
- for domarch in dom:
- arch = str(domarch.attributes["name"].value);
- envs = domarch.getElementsByTagName("environment");
- for env in envs:
- cmd = str(env.firstChild.data);
- tempstring = tempstring + "#ifdef LV_HAVE_" + arch.swapcase() + "\n";
- tempstring = tempstring + " " + cmd + "\n";
- tempstring = tempstring + "#endif\n"
-
- tempstring = tempstring + "}\n";
- return tempstring;
-
-
-
-
diff --git a/volk/gen/make_environment_init_h.py b/volk/gen/make_environment_init_h.py
deleted file mode 100644
index 0b0f35d61..000000000
--- a/volk/gen/make_environment_init_h.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from xml.dom import minidom
-
-def make_environment_init_h() :
- tempstring = "";
- tempstring = tempstring + "/*this file is auto_generated by volk_register.py*/\n\n";
- tempstring = tempstring + "#ifndef INCLUDE_LIBVECTOR_ENVIRONMENT_INIT_H\n";
- tempstring = tempstring + "#define INCLUDE_LIBVECTOR_ENVIRONMENT_INIT_H\n";
- tempstring = tempstring + "\n";
- tempstring = tempstring + "#include <volk/volk_common.h>\n\n";
- tempstring = tempstring + "__VOLK_DECL_BEGIN\n";
- tempstring = tempstring + "void volk_environment_init();\n";
- tempstring = tempstring + "__VOLK_DECL_END\n";
- tempstring = tempstring + "#endif\n"
- return tempstring;
-
-
-
-
diff --git a/volk/gen/make_h.py b/volk/gen/make_h.py
deleted file mode 100644
index cf8987c39..000000000
--- a/volk/gen/make_h.py
+++ /dev/null
@@ -1,38 +0,0 @@
-from xml.dom import minidom
-from volk_regexp import *
-
-def make_h(funclist, arched_arglist) :
- tempstring = "";
- tempstring = tempstring + '/*this file is auto generated by make_h.py*/\n';
-
- tempstring = tempstring + '\n#ifndef INCLUDED_VOLK_RUNTIME';
- tempstring = tempstring + '\n#define INCLUDED_VOLK_RUNTIME';
- tempstring = tempstring + '\n\n#include<volk/volk_typedefs.h>\n';
- tempstring = tempstring + '#include<volk/volk_config_fixed.h>\n';
- tempstring = tempstring + '#include<volk/volk_common.h>\n';
- tempstring = tempstring + '#include<volk/volk_complex.h>\n';
- tempstring = tempstring + '__VOLK_DECL_BEGIN\n';
-
- tempstring = tempstring + '\n';
-
- tempstring += """
-struct volk_func_desc {
- const char **indices;
- const int *arch_defs;
- const int n_archs;
-};
-
-VOLK_API unsigned int volk_get_alignment(void);
-
-"""
- for i in range(len(funclist)):
- tempstring += "extern VOLK_API " + replace_volk.sub("p", funclist[i]) + " " + funclist[i] + ";\n"
- tempstring += "extern VOLK_API void %s_manual%s;\n" % (funclist[i], arched_arglist[i])
- tempstring = strip_trailing(tempstring, " {")
- tempstring += "extern VOLK_API struct volk_func_desc %s_get_func_desc(void);\n" % (funclist[i])
-
- tempstring = tempstring + '__VOLK_DECL_END\n';
- tempstring = tempstring + "#endif /*INCLUDED_VOLK_RUNTIME*/\n";
-
- return tempstring;
-
diff --git a/volk/gen/make_machines_c.py b/volk/gen/make_machines_c.py
deleted file mode 100644
index f19da4ae4..000000000
--- a/volk/gen/make_machines_c.py
+++ /dev/null
@@ -1,41 +0,0 @@
-#
-# Copyright 2010-2011 Free Software Foundation, Inc.
-#
-# This program 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 of the License, or
-# (at your option) any later version.
-#
-# This program 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, see <http://www.gnu.org/licenses/>.
-#
-
-from volk_regexp import *
-
-def make_machines_c(machines):
- tempstring = r"""
-// This file is automatically generated by make_machines_c.py.
-// Do not edit this file.
-
-#include <volk/volk_common.h>
-#include <volk/volk_typedefs.h>
-#include "volk_machines.h"
-
-struct volk_machine *volk_machines[] = {
-"""
- for machine in machines:
- tempstring += """#if LV_MACHINE_""" + machine.swapcase() + "\n"
- tempstring += "&volk_machine_" + machine
- tempstring += ","
- tempstring += "\n#endif\n"
-
- tempstring += r"""
-};
-unsigned int n_volk_machines = sizeof(volk_machines)/sizeof(*volk_machines);
-"""
- return tempstring
diff --git a/volk/gen/make_machines_h.py b/volk/gen/make_machines_h.py
deleted file mode 100644
index d2374120b..000000000
--- a/volk/gen/make_machines_h.py
+++ /dev/null
@@ -1,59 +0,0 @@
-#
-# Copyright 2010-2011 Free Software Foundation, Inc.
-#
-# This program 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 of the License, or
-# (at your option) any later version.
-#
-# This program 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, see <http://www.gnu.org/licenses/>.
-#
-
-from volk_regexp import *
-
-def make_machines_h(functions, machines, archs):
- tempstring = r"""
-// This file is automatically generated by make_machines_h.py.
-// Do not edit this file.
-
-#ifndef INCLUDED_LIBVOLK_MACHINES_H
-#define INCLUDED_LIBVOLK_MACHINES_H
-
-#include <volk/volk_common.h>
-#include <volk/volk_typedefs.h>
-
-__VOLK_DECL_BEGIN
-
-struct volk_machine {
- const unsigned int caps; //capabilities (i.e., archs compiled into this machine, in the volk_get_lvarch format)
- const char *name;
- const unsigned int alignment; //the maximum byte alignment required for functions in this library
-"""
- for function in functions:
- tempstring += " const char *%s_name;\n"%function
- tempstring += " const char *%s_indices[%d];\n"%(function, len(archs))
- tempstring += " const int %s_arch_defs[%d];\n"%(function, len(archs))
- tempstring += " const %s %s_archs[%d];\n"%(replace_volk.sub("p", function), function, len(archs))
- tempstring += " const int %s_n_archs;\n"%function
-
- tempstring += r"""};
-
-"""
- for machine in machines:
- tempstring += """#if LV_MACHINE_""" + machine.swapcase() + "\n"
- tempstring += "extern struct volk_machine volk_machine_" + machine + ";\n"
- tempstring += """#endif\n"""
-
- tempstring += r"""
-
-__VOLK_DECL_END
-
-#endif //INCLUDED_LIBVOLK_MACHINES_H"""
-
- return tempstring
diff --git a/volk/gen/make_makefile_am.py b/volk/gen/make_makefile_am.py
deleted file mode 100644
index 880ce4094..000000000
--- a/volk/gen/make_makefile_am.py
+++ /dev/null
@@ -1,123 +0,0 @@
-#
-# Copyright 2010-2011 Free Software Foundation, Inc.
-#
-# This program 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 of the License, or
-# (at your option) any later version.
-#
-# This program 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, see <http://www.gnu.org/licenses/>.
-#
-
-from xml.dom import minidom
-
-def make_makefile_am(dom, machines, archflags_dict):
- tempstring = r"""
-# This file is automatically generated by make_makefile_am.py.
-# Do not edit this file.
-
-include $(top_srcdir)/Makefile.common
-
-AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) \
- -I$(top_gendir)/include \
- -I$(top_srcdir)/include \
- -Dvolk_EXPORTS \
- -fvisibility=hidden \
- $(WITH_INCLUDES)
-
-lib_LTLIBRARIES = \
- libvolk.la
-
-EXTRA_DIST = \
- volk_rank_archs.h \
- gcc_x86_cpuid.h
-
-# ----------------------------------------------------------------
-# The main library
-# ----------------------------------------------------------------
-
-libvolk_la_SOURCES = \
- $(platform_CODE) \
- $(top_gendir)/lib/volk.c \
- $(top_gendir)/lib/volk_cpu.c \
- volk_rank_archs.c \
- volk_prefs.c \
- $(top_gendir)/lib/volk_machines.c
-
-if LV_HAVE_ORC
-volk_orc_CFLAGS = -DLV_HAVE_ORC=1
-volk_orc_LDFLAGS = $(ORC_LDFLAGS) -lorc-0.4
-volk_orc_LIBADD = ../orc/libvolk_orc.la
-else
-volk_orc_CFLAGS =
-volk_orc_LDFLAGS =
-volk_orc_LIBADD =
-endif
-
-libvolk_la_CPPFLAGS = $(AM_CPPFLAGS) $(volk_orc_CFLAGS)
-libvolk_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0 $(volk_orc_LDFLAGS)
-libvolk_la_LIBADD = $(volk_orc_LIBADD)
-
-noinst_LTLIBRARIES =
-
-"""
-
- #here be dragons
- for machine_name in machines:
- tempstring += "if LV_MACHINE_" + machine_name.swapcase() + "\n"
- tempstring += "libvolk_" + machine_name + "_la_SOURCES = $(top_gendir)/lib/volk_machine_" + machine_name + ".c\n"
- tempstring += "libvolk_" + machine_name + "_la_CPPFLAGS = -I$(top_srcdir)/include -I$(top_gendir)/include $(volk_orc_CFLAGS) "
- for arch in machines[machine_name]:
- if archflags_dict[arch] != "none":
- tempstring += "-" + archflags_dict[arch] + " "
-
- tempstring += "\nnoinst_LTLIBRARIES += libvolk_" + machine_name + ".la "
- tempstring += "\nlibvolk_la_LIBADD += libvolk_" + machine_name + ".la\n"
- tempstring += "libvolk_la_CPPFLAGS += -DLV_MACHINE_" + machine_name.swapcase() + " \n"
- tempstring += "endif\n"
-
-
- tempstring += r"""
-
-# ----------------------------------------------------------------
-# The QA library. Note libvolk.la in LIBADD
-# ----------------------------------------------------------------
-#libvolk_qa_la_SOURCES = \
-# qa_utils.cc
-
-#libvolk_qa_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0 -lboost
-
-#libvolk_qa_la_LIBADD = \
-# libvolk.la \
-# libvolk_runtime.la
-
-# ----------------------------------------------------------------
-# headers that don't get installed
-# ----------------------------------------------------------------
-noinst_HEADERS = \
- $(top_gendir)/lib/volk_init.h \
- $(top_gendir)/lib/volk_machines.h \
- $(top_gendir)/lib/volk_environment_init.h \
- qa_utils.h
-
-# ----------------------------------------------------------------
-# Our test program
-# ----------------------------------------------------------------
-noinst_PROGRAMS = \
- testqa
-
-testqa_SOURCES = testqa.cc qa_utils.cc
-testqa_CPPFLAGS = -DBOOST_TEST_DYN_LINK -DBOOST_TEST_MAIN $(AM_CPPFLAGS)
-testqa_LDFLAGS = $(BOOST_UNIT_TEST_FRAMEWORK_LIB)
-testqa_LDADD = \
- libvolk.la
-"""
-
-
- return tempstring
diff --git a/volk/gen/make_proccpu_sim.py b/volk/gen/make_proccpu_sim.py
deleted file mode 100644
index e2c8123e5..000000000
--- a/volk/gen/make_proccpu_sim.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2011 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 xml.dom import minidom
-
-def make_proccpu_sim(dom) :
- tempstring = "";
- tempstring = tempstring + "/*this file is auto_generated by volk_register.py*/\n\n";
- tempstring = tempstring + "#include <volk/volk_cpu.h>\n"
- tempstring = tempstring + "#include <stdio.h>\n"
- tempstring = tempstring + "\n\n"
-
- tempstring = tempstring + "void test_append(char* buf, int val, char* newkey){\n";
- tempstring = tempstring + " if(val==1){\n";
- tempstring = tempstring + " sprintf(buf, \"%s %s\", buf, newkey);\n";
- tempstring = tempstring + " }\n";
- tempstring = tempstring + "}\n";
- tempstring = tempstring + "\n\n";
-
- tempstring = tempstring + "int main() {\n";
- tempstring = tempstring + " volk_cpu_init();\n";
- tempstring = tempstring + " char buf[2048];\n";
- for domarch in dom:
- arch = str(domarch.attributes["name"].value);
- tempstring = tempstring + " test_append(buf, volk_cpu.has_" + arch + "(), \"" + arch + "\");\n"
- tempstring = tempstring + " printf(\"%s\\n\", buf);\n"
- tempstring = tempstring + "}\n"
- return tempstring;
diff --git a/volk/gen/make_set_simd.py b/volk/gen/make_set_simd.py
deleted file mode 100644
index 8334487d7..000000000
--- a/volk/gen/make_set_simd.py
+++ /dev/null
@@ -1,166 +0,0 @@
-#
-# Copyright 2010 Free Software Foundation, Inc.
-#
-# This program 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 of the License, or
-# (at your option) any later version.
-#
-# This program 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, see <http://www.gnu.org/licenses/>.
-#
-
-from xml.dom import minidom
-
-def make_set_simd(dom, machines) :
- tempstring = "";
- tempstring = tempstring +'dnl this file is auto generated by volk_register.py\n\n';
-
- tempstring = tempstring +'\ndnl define arch checks\n';
- for domarch in dom:
- if str(domarch.attributes["type"].value) != "all":
- arch = str(domarch.attributes["name"].value);
- flag = domarch.getElementsByTagName("flag");
- flag = str(flag[0].firstChild.data);
- tempstring = tempstring + "AC_DEFUN([_TRY_ADD_" + arch.swapcase() + "],\n";
- tempstring = tempstring + "[\n";
- tempstring = tempstring + " LF_CHECK_CC_FLAG([-" + flag + "])\n";
- tempstring = tempstring + " LF_CHECK_CXX_FLAG([-" + flag + "])\n";
- tempstring = tempstring + "])\n";
-
- tempstring = tempstring +'\ndnl main set_simd_flags\n';
- tempstring = tempstring + "AC_DEFUN([LV_SET_SIMD_FLAGS],\n";
- tempstring = tempstring + "[\n";
- #tempstring = tempstring + " AC_REQUIRE([GR_SET_MD_CPU])\n";
- tempstring = tempstring + " AC_SUBST(LV_CXXFLAGS)\n";
- tempstring = tempstring + " indCC=no\n";
- tempstring = tempstring + " indCXX=no\n";
- tempstring = tempstring + " indLV_ARCH=no\n";
- tempstring = tempstring + " AC_ARG_WITH(lv_arch,\n";
- tempstring = tempstring + " AC_HELP_STRING([--with-lv_arch=ARCH],[set volk hardware speedups as space separated string with elements from the following list(";
-
- for domarch in dom:
- arch = str(domarch.attributes["name"].value);
- tempstring = tempstring + arch + ", "
- tempstring = tempstring[0:len(tempstring) - 2];
-
- tempstring = tempstring + ")]),\n";
- tempstring = tempstring + " [cf_with_lv_arch=\"$withval\"],\n";
- tempstring = tempstring + " [cf_with_lv_arch=\"\"])\n";
- if str(domarch.attributes["type"].value) == "all":
- arch = str(domarch.attributes["name"].value);
- tempstring = tempstring + " AC_DEFINE(LV_MAKE_" + arch.swapcase() + ", 1, [always set "+ arch + "!])\n";
- tempstring = tempstring + " ADDONS=\"\"\n";
- tempstring = tempstring + " BUILT_ARCHS=\"\"\n";
- #tempstring = tempstring + " _MAKE_FAKE_PROCCPU\n";
- tempstring = tempstring + " OVERRULE_FLAG=\"no\"\n";
- tempstring = tempstring + " if test -z \"$cf_with_lv_arch\"; then\n";
- tempstring = tempstring + " cf_with_lv_arch=\"";
- for domarch in dom:
- arch = str(domarch.attributes["name"].value);
- tempstring = tempstring + arch + " ";
- tempstring = tempstring[0:-1] + "\"\n";
- tempstring = tempstring + " OVERRULE_FLAG=\"yes\"\n";
- tempstring = tempstring + " fi\n";
-
- tempstring = tempstring +'\ndnl init LV_MAKE_XXX and then try to add archs\n';
- for domarch in dom:
- if str(domarch.attributes["type"].value) != "all":
- arch = str(domarch.attributes["name"].value);
- tempstring = tempstring + " LV_MAKE_" + arch.swapcase() + "=no\n";
-
- for domarch in dom:
- arch = str(domarch.attributes["name"].value);
- atype = str(domarch.attributes["type"].value);
- if atype != "all":
- tempstring = tempstring + " _TRY_ADD_" + arch.swapcase() + "\n";
-
- for domarch in dom:
- arch = str(domarch.attributes["name"].value);
- atype = str(domarch.attributes["type"].value);
- tempstring = tempstring +'\ndnl add in flags for arch ' + arch + '\n';
- overrule = domarch.getElementsByTagName("overrule");
- if overrule:
- overrule = str(overrule[0].firstChild.data);
- else:
- overrule = "";
- overrule_val = domarch.getElementsByTagName("overrule_val");
- if overrule_val:
- overrule_val = str(overrule_val[0].firstChild.data);
- else:
- overrule_val = "";
- flag = domarch.getElementsByTagName("flag");
- flag = str(flag[0].firstChild.data);
- if atype != "all":
- tempstring = tempstring + " for i in $lf_CXXFLAGS\n"
- tempstring = tempstring + " do\n"
- tempstring = tempstring + " if test \"X$i\" = X-" + flag +"; then\n";
- tempstring = tempstring + " indCXX=yes\n";
- tempstring = tempstring + " fi\n"
- tempstring = tempstring + " done\n"
- tempstring = tempstring + " for i in $lf_CFLAGS\n"
- tempstring = tempstring + " do\n"
- tempstring = tempstring + " if test \"X$i\" = X-" + flag +"; then\n";
- tempstring = tempstring + " indCC=yes\n";
- tempstring = tempstring + " fi\n"
- tempstring = tempstring + " done\n"
- tempstring = tempstring + " for i in $cf_with_lv_arch\n"
- tempstring = tempstring + " do\n"
- tempstring = tempstring + " if test \"X$i\" = X" + arch + "; then\n";
- tempstring = tempstring + " indLV_ARCH=yes\n"
- tempstring = tempstring + " fi\n"
- tempstring = tempstring + " done\n"
- tempstring = tempstring + " if test -n \"" + overrule + "\" && test \"$" + overrule + "\" == \"" + overrule_val + "\" && test \"$OVERRULE_FLAG\" == \"yes\" && test \"$indLV_ARCH\" == \"yes\"; then\n"
- tempstring = tempstring + " indLV_ARCH=no\n"
- tempstring = tempstring + " fi\n"
-
- tempstring = tempstring + " if test \"$indCC\" == \"yes\" && test \"$indCXX\" == \"yes\" && test \"$indLV_ARCH\" == \"yes\"; then\n"
-
- #tempstring = tempstring + " ADDONS=\"${ADDONS} -" + flag + "\"\n";
- tempstring = tempstring + " BUILT_ARCHS=\"${BUILT_ARCHS} " + arch + "\"\n";
- tempstring = tempstring + " LV_MAKE_" + arch.swapcase() + "=yes\n";
- tempstring = tempstring + " fi\n"
- tempstring = tempstring + " indCC=no\n"
- tempstring = tempstring + " indCXX=no\n"
- tempstring = tempstring + " indLV_ARCH=no\n"
- else:
- tempstring = tempstring + " for i in $cf_with_lv_arch\n"
- tempstring = tempstring + " do\n"
- tempstring = tempstring + " if test \"X$i\" = X" + arch + "; then\n";
- tempstring = tempstring + " indLV_ARCH=yes\n"
- tempstring = tempstring + " fi\n"
- tempstring = tempstring + " done\n"
- tempstring = tempstring + " if test -n \"" + overrule + "\" && test \"$" + overrule + "\" == \"" + overrule_val + "\" && test \"$OVERRULE_FLAG\" == \"yes\" && test \"$indLV_ARCH\" == \"yes\"; then\n"
- tempstring = tempstring + " indLV_ARCH=no\n"
- tempstring = tempstring + " fi\n"
- tempstring = tempstring + " if test \"$indLV_ARCH\" == \"yes\"; then\n"
- tempstring = tempstring + " LV_MAKE_" + arch.swapcase() + "=yes\n";
- tempstring = tempstring + " BUILT_ARCHS=\"${BUILT_ARCHS} " + arch + "\"\n";
- tempstring = tempstring + " fi\n"
- tempstring = tempstring + " indLV_ARCH=no\n"
-
-
- for domarch in dom:
- arch = str(domarch.attributes["name"].value);
- tempstring = tempstring + " AM_CONDITIONAL(LV_MAKE_" + arch.swapcase() + ", test \"$LV_MAKE_" + arch.swapcase() + "\" == \"yes\")\n";
-
- tempstring += "\n"
- #now we can define the machines we're compiling
- for machine_name in machines:
- tempstring += " AM_CONDITIONAL(LV_MACHINE_" + machine_name.swapcase() + ", "
- marchlist = machines[machine_name]
- for march in marchlist:
- tempstring += "test \"$LV_MAKE_" + march.swapcase() + "\" == \"yes\" && "
-
- tempstring += "test true)\n" #just so we don't have to detect the last one in the group, i know
- tempstring = tempstring + " LV_CXXFLAGS=\"${LV_CXXFLAGS} ${ADDONS}\"\n"
- tempstring = tempstring + "])\n"
-
- return tempstring;
-
-
diff --git a/volk/gen/make_typedefs.py b/volk/gen/make_typedefs.py
deleted file mode 100644
index 09221d2ef..000000000
--- a/volk/gen/make_typedefs.py
+++ /dev/null
@@ -1,23 +0,0 @@
-from xml.dom import minidom
-import string
-from volk_regexp import *
-
-
-
-def make_typedefs(funclist, retlist, my_argtypelist) :
- tempstring = "";
- tempstring = tempstring + '/*this file is auto generated by volk_register.py*/';
- tempstring = tempstring + '/*this file is auto generated by volk_register.py*/';
- tempstring = tempstring + '\n#ifndef INCLUDED_VOLK_TYPEDEFS';
- tempstring = tempstring + '\n#define INCLUDED_VOLK_TYPEDEFS\n';
- tempstring = tempstring + '\n\n#include<inttypes.h>\n';
- tempstring = tempstring + '#include<volk/volk_complex.h>\n';
-
- tempstring = tempstring + '\n';
-
- for i in range(len(funclist)):
- tempstring = tempstring + "typedef " + retlist[i] +" (*" + replace_volk.sub("p", funclist[i]) + ")(" + my_argtypelist[i] + ");\n";
-
- tempstring = tempstring + "#endif /*INCLUDED_VOLK_TYPEDEFS*/\n";
-
- return tempstring;
diff --git a/volk/gen/volk_arch_defs.py b/volk/gen/volk_arch_defs.py
new file mode 100644
index 000000000..41154d5a7
--- /dev/null
+++ b/volk/gen/volk_arch_defs.py
@@ -0,0 +1,92 @@
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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, see <http://www.gnu.org/licenses/>.
+#
+
+archs = list()
+arch_dict = dict()
+
+#TODO enable this when we are ready
+create_unaligned_archs = False
+
+class arch_class:
+ def __init__(self, flags, checks, **kwargs):
+ for key, cast, failval in (
+ ('name', str, None),
+ ('environment', str, None),
+ ('include', str, None),
+ ('alignment', int, 1)
+ ):
+ try: setattr(self, key, cast(kwargs[key]))
+ except: setattr(self, key, failval)
+ self.checks = checks
+ assert(self.name)
+ self._flags = flags
+
+ def is_supported(self, compiler):
+ if not self._flags.keys(): return True
+ return compiler in self._flags.keys()
+
+ def get_flags(self, compiler):
+ try: return self._flags[compiler]
+ except KeyError: return list()
+
+ def __repr__(self): return self.name
+
+def register_arch(**kwargs):
+ arch = arch_class(**kwargs)
+ archs.append(arch)
+ arch_dict[arch.name] = arch
+ if arch.alignment > 1 and create_unaligned_archs:
+ kwargs['name'] += '_u'
+ kwargs['alignment'] = 1
+ register_arch(**kwargs)
+
+########################################################################
+# register the arches
+########################################################################
+#TODO skip the XML and put it here
+from xml.dom import minidom
+import os
+gendir = os.path.dirname(__file__)
+archs_xml = minidom.parse(os.path.join(gendir, 'archs.xml')).getElementsByTagName('arch')
+for arch_xml in archs_xml:
+ kwargs = dict()
+ for attr in arch_xml.attributes.keys():
+ kwargs[attr] = arch_xml.attributes[attr].value
+ for node in arch_xml.childNodes:
+ try:
+ name = node.tagName
+ val = arch_xml.getElementsByTagName(name)[0].firstChild.data
+ kwargs[name] = val
+ except: pass
+ checks = list()
+ for check_xml in arch_xml.getElementsByTagName("check"):
+ name = check_xml.attributes["name"].value
+ params = list()
+ for param_xml in check_xml.getElementsByTagName("param"):
+ params.append(param_xml.firstChild.data)
+ checks.append([name, params])
+ flags = dict()
+ for flag_xml in arch_xml.getElementsByTagName("flag"):
+ name = flag_xml.attributes["compiler"].value
+ if not flags.has_key(name): flags[name] = list()
+ flags[name].append(flag_xml.firstChild.data)
+ #force kwargs keys to be of type str, not unicode for py25
+ kwargs = dict((str(k), v) for k, v in kwargs.iteritems())
+ register_arch(flags=flags, checks=checks, **kwargs)
+
+if __name__ == '__main__':
+ print archs
diff --git a/volk/gen/volk_compile_utils.py b/volk/gen/volk_compile_utils.py
new file mode 100644
index 000000000..cf1357375
--- /dev/null
+++ b/volk/gen/volk_compile_utils.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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, see <http://www.gnu.org/licenses/>.
+#
+
+import optparse
+import volk_arch_defs
+import volk_machine_defs
+
+def do_arch_flags_list(compiler):
+ output = list()
+ for arch in volk_arch_defs.archs:
+ if not arch.is_supported(compiler): continue
+ fields = [arch.name] + arch.get_flags(compiler)
+ output.append(','.join(fields))
+ print ';'.join(output)
+
+def do_machines_list(arch_names):
+ output = list()
+ for machine in volk_machine_defs.machines:
+ machine_arch_set = set(machine.arch_names)
+ if set(arch_names).intersection(machine_arch_set) == machine_arch_set:
+ output.append(machine.name)
+ print ';'.join(output)
+
+def do_machine_flags_list(compiler, machine_name):
+ output = list()
+ machine = volk_machine_defs.machine_dict[machine_name]
+ for arch in machine.archs:
+ output.extend(arch.get_flags(compiler))
+ print ' '.join(output)
+
+def main():
+ parser = optparse.OptionParser()
+ parser.add_option('--mode', type='string')
+ parser.add_option('--compiler', type='string')
+ parser.add_option('--archs', type='string')
+ parser.add_option('--machine', type='string')
+ (opts, args) = parser.parse_args()
+
+ if opts.mode == 'arch_flags': return do_arch_flags_list(opts.compiler.lower())
+ if opts.mode == 'machines': return do_machines_list(opts.archs.split(';'))
+ if opts.mode == 'machine_flags': return do_machine_flags_list(opts.compiler.lower(), opts.machine)
+
+if __name__ == '__main__': main()
diff --git a/volk/gen/volk_kernel_defs.py b/volk/gen/volk_kernel_defs.py
new file mode 100644
index 000000000..52cdb684c
--- /dev/null
+++ b/volk/gen/volk_kernel_defs.py
@@ -0,0 +1,224 @@
+#
+# Copyright 2011-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.
+#
+
+import os
+import re
+import sys
+import glob
+
+from volk_arch_defs import archs
+
+remove_after_underscore = re.compile("_.*");
+space_remove = re.compile(" ");
+leading_space_remove = re.compile("^ *");
+replace_arch = re.compile(", const char\* arch");
+replace_bracket = re.compile(" {");
+replace_volk = re.compile("volk");
+
+def strip_trailing(tostrip, stripstr):
+ lindex = tostrip.rfind(stripstr)
+ tostrip = tostrip[0:lindex] + tostrip[lindex:len(tostrip)].replace(stripstr, "");
+ return tostrip
+
+srcdir = os.path.dirname(os.path.dirname(__file__))
+hdr_files = glob.glob(os.path.join(srcdir, "include/volk/*.h"))
+
+datatypes = [];
+functions = [];
+
+for line in hdr_files:
+ subline = re.search(".*_(a|u)\.h.*", os.path.basename(line))
+ if subline:
+ subsubline = re.search("(?<=volk_).*", subline.group(0));
+ if subsubline:
+ dtype = remove_after_underscore.sub("", subsubline.group(0));
+ subdtype = re.search("[0-9]+[A-z]+", dtype);
+ if subdtype:
+ datatypes.append(subdtype.group(0));
+
+
+datatypes = set(datatypes);
+
+for line in hdr_files:
+ for dt in datatypes:
+ if dt in line:
+ subline = re.search("(volk_" + dt +"_.*(a|u).*\.h)", line);
+ if subline:
+
+ subsubline = re.search(".+(?=\.h)", subline.group(0));
+ functions.append(subsubline.group(0));
+
+archs_or = "("
+for arch in archs:
+ archs_or = archs_or + arch.name.upper() + "|";
+archs_or = archs_or[0:len(archs_or)-1];
+archs_or = archs_or + ")";
+
+taglist = [];
+fcountlist = [];
+arched_arglist = [];
+retlist = [];
+my_arglist = [];
+my_argtypelist = [];
+for func in functions:
+ tags = [];
+ fcount = [];
+ infile_source = open(os.path.join(srcdir, 'include', 'volk', func + ".h"))
+ begun_name = 0;
+ begun_paren = 0;
+ sourcefile = infile_source.readlines();
+ infile_source.close();
+ for line in sourcefile:
+#FIXME: make it work for multiple #if define()s
+ archline = re.search("^\#if.*?LV_HAVE_" + archs_or + ".*", line);
+ if archline:
+ arch = archline.group(0);
+ archline = re.findall(archs_or + "(?=( |\n|&))", line);
+ if archline:
+ archsublist = [];
+ for tup in archline:
+ archsublist.append(tup[0]);
+ fcount.append(archsublist);
+ testline = re.search("static inline.*?" + func, line);
+ if (not testline):
+ continue
+ tagline = re.search(func + "_.+", line);
+ if tagline:
+ tag = re.search("(?<=" + func + "_)\w+(?= *\()",line);
+ if tag:
+ tag = re.search("\w+", tag.group(0));
+ if tag:
+ tags.append(tag.group(0));
+
+
+ if begun_name == 0:
+ retline = re.search(".+(?=" + func + ")", line);
+ if retline:
+ ret = retline.group(0);
+
+
+
+
+ subline = re.search(func + ".*", line);
+ if subline:
+ subsubline = re.search("\(.*?\)", subline.group(0));
+ if subsubline:
+ args = subsubline.group(0);
+
+ else:
+ begun_name = 1;
+ subsubline = re.search("\(.*", subline.group(0));
+ if subsubline:
+ args = subsubline.group(0);
+ begun_paren = 1;
+ else:
+ if begun_paren == 1:
+ subline = re.search(".*?\)", line);
+ if subline:
+ args = args + subline.group(0);
+ begun_name = 0;
+ begun_paren = 0;
+ else:
+ subline = re.search(".*", line);
+ args = args + subline.group(0);
+ else:
+ subline = re.search("\(.*?\)", line);
+ if subline:
+ args = subline.group(0);
+ begun_name = 0;
+ else:
+ subline = re.search("\(.*", line);
+ if subline:
+ args = subline.group(0);
+ begun_paren = 1;
+
+ replace = re.compile("static ");
+ ret = replace.sub("", ret);
+ replace = re.compile("inline ");
+ ret = replace.sub("", ret);
+ arched_args = args[args.find('(')+1:args.find(')')]
+
+ remove = re.compile('\)|\(|{');
+ rargs = remove.sub("", args);
+ sargs = rargs.split(',');
+
+
+
+ margs = [];
+ atypes = [];
+ for arg in sargs:
+ temp = arg.split(" ");
+ margs.append(temp[-1]);
+ replace = re.compile(" " + temp[-1]);
+ atypes.append(replace.sub("", arg));
+
+
+ my_args = ""
+ arg_types = ""
+ for arg in range(0, len(margs) - 1):
+ this_arg = leading_space_remove.sub("", margs[arg]);
+ my_args = my_args + this_arg + ", ";
+ this_type = leading_space_remove.sub("", atypes[arg]);
+ arg_types = arg_types + this_type + ", ";
+
+ this_arg = leading_space_remove.sub("", margs[-1]);
+ my_args = my_args + this_arg;
+ this_type = leading_space_remove.sub("", atypes[-1]);
+ arg_types = arg_types + this_type;
+ my_argtypelist.append(arg_types);
+
+ if(ret[-1] != ' '):
+ ret = ret + ' ';
+
+ arched_arglist.append(arched_args); #!!!!!!!!!!!
+ my_arglist.append(my_args) #!!!!!!!!!!!!!!!!!
+ retlist.append(ret);
+ fcountlist.append(fcount);
+ taglist.append(tags);
+
+class kernel_class:
+ def __init__(self, index):
+ self.name = functions[index]
+ self.pname = self.name.replace('volk_', 'p_')
+ self.rettype = retlist[index]
+ self.arglist_defs = my_argtypelist[index]
+ self.arglist_namedefs = arched_arglist[index]
+ self.arglist_names = my_arglist[index]
+ self._tagdeps = fcountlist[index]
+ self._taglist = taglist[index]
+
+ def get_tags(self, archs):
+ def is_in(x): return x.lower() in archs
+ taglist = list()
+ tagdeps = list()
+ for i in range(len(self._tagdeps)):
+ if all(map(is_in, self._tagdeps[i])):
+ taglist.append(self._taglist[i])
+ tagdeps.append(self._tagdeps[i])
+ return taglist, tagdeps
+
+ def __repr__(self):
+ return self.name
+
+kernels = map(kernel_class, range(len(retlist)))
+
+if __name__ == '__main__':
+ print kernels
diff --git a/volk/gen/volk_machine_defs.py b/volk/gen/volk_machine_defs.py
new file mode 100644
index 000000000..d1a856981
--- /dev/null
+++ b/volk/gen/volk_machine_defs.py
@@ -0,0 +1,78 @@
+#
+# Copyright 2012 Free Software Foundation, Inc.
+#
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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, see <http://www.gnu.org/licenses/>.
+#
+
+from volk_arch_defs import arch_dict
+
+machines = list()
+machine_dict = dict()
+
+class machine_class:
+ def __init__(self, name, archs):
+ self.name = name
+ self.archs = list()
+ self.arch_names = list()
+ for arch_name in archs:
+ if not arch_name: continue
+ arch = arch_dict[arch_name]
+ self.archs.append(arch)
+ self.arch_names.append(arch_name)
+ arch_name += '_u'
+ if arch.alignment > 1 and arch_dict.has_key(arch_name):
+ arch = arch_dict[arch_name]
+ self.archs.append(arch)
+ self.alignment = max(map(lambda a: a.alignment, self.archs))
+
+ def __repr__(self): return self.name
+
+def register_machine(name, archs):
+ for i, arch_name in enumerate(archs):
+ if '|' in arch_name: #handle special arch names with the '|'
+ for arch_sub in arch_name.split('|'):
+ if arch_sub:
+ register_machine(name+'_'+arch_sub, archs[:i] + [arch_sub] + archs[i+1:])
+ else:
+ register_machine(name, archs[:i] + archs[i+1:])
+ return
+ machine = machine_class(name=name, archs=archs)
+ machines.append(machine)
+ machine_dict[machine.name] = machine
+
+########################################################################
+# register the machines
+########################################################################
+#TODO skip the XML and put it here
+from xml.dom import minidom
+import os
+gendir = os.path.dirname(__file__)
+machines_xml = minidom.parse(os.path.join(gendir, 'machines.xml')).getElementsByTagName('machine')
+for machine_xml in machines_xml:
+ kwargs = dict()
+ for attr in machine_xml.attributes.keys():
+ kwargs[attr] = machine_xml.attributes[attr].value
+ for node in machine_xml.childNodes:
+ try:
+ name = node.tagName
+ val = machine_xml.getElementsByTagName(name)[0].firstChild.data
+ kwargs[name] = val
+ except: pass
+ kwargs['archs'] = kwargs['archs'].split()
+ #force kwargs keys to be of type str, not unicode for py25
+ kwargs = dict((str(k), v) for k, v in kwargs.iteritems())
+ register_machine(**kwargs)
+
+if __name__ == '__main__':
+ print machines
diff --git a/volk/gen/volk_regexp.py b/volk/gen/volk_regexp.py
deleted file mode 100644
index eb4ceb54b..000000000
--- a/volk/gen/volk_regexp.py
+++ /dev/null
@@ -1,13 +0,0 @@
-import re
-
-remove_after_underscore = re.compile("_.*");
-space_remove = re.compile(" ");
-leading_space_remove = re.compile("^ *");
-replace_arch = re.compile(", const char\* arch");
-replace_bracket = re.compile(" {");
-replace_volk = re.compile("volk");
-
-def strip_trailing(tostrip, stripstr):
- lindex = tostrip.rfind(stripstr)
- tostrip = tostrip[0:lindex] + tostrip[lindex:len(tostrip)].replace(stripstr, "");
- return tostrip
diff --git a/volk/gen/volk_register.py b/volk/gen/volk_register.py
deleted file mode 100644
index 3a237c5ca..000000000
--- a/volk/gen/volk_register.py
+++ /dev/null
@@ -1,303 +0,0 @@
-#! /usr/bin/env python
-
-import sys
-import os
-import re
-import glob
-from xml.dom import minidom
-from volk_regexp import *
-from make_cpuid_c import make_cpuid_c
-from make_cpuid_h import make_cpuid_h
-from make_set_simd import make_set_simd
-from make_config_fixed import make_config_fixed
-from make_typedefs import make_typedefs
-from make_environment_init_c import make_environment_init_c
-from make_environment_init_h import make_environment_init_h
-from make_makefile_am import make_makefile_am
-from make_machines_h import make_machines_h
-from make_machines_c import make_machines_c
-from make_each_machine_c import make_each_machine_c
-from make_c import make_c
-from make_h import make_h
-import copy
-
-#set srcdir and gendir
-srcdir = os.path.dirname(os.path.dirname(__file__))
-try: gendir = sys.argv[1]
-except: gendir = os.path.dirname(__file__)
-
-#ensure directories exist
-for dir in (
- (os.path.join(gendir, 'include', 'volk')),
- (os.path.join(gendir, 'lib')),
- (os.path.join(gendir, 'config'))
-):
- if not os.path.exists(dir): os.makedirs(dir)
-
-outfile_set_simd = open(os.path.join(gendir, "config/lv_set_simd_flags.m4"), "w")
-outfile_h = open(os.path.join(gendir, "include/volk/volk.h"), "w")
-outfile_c = open(os.path.join(gendir, "lib/volk.c"), "w")
-outfile_typedefs = open(os.path.join(gendir, "include/volk/volk_typedefs.h"), "w")
-outfile_init_h = open(os.path.join(gendir, "lib/volk_init.h"), "w")
-outfile_cpu_h = open(os.path.join(gendir, "include/volk/volk_cpu.h"), "w")
-outfile_cpu_c = open(os.path.join(gendir, "lib/volk_cpu.c"), "w")
-#outfile_config_in = open(os.path.join(gendir, "include/volk/volk_config.h.in"), "w")
-outfile_config_fixed = open(os.path.join(gendir, "include/volk/volk_config_fixed.h"), "w")
-outfile_environment_c = open(os.path.join(gendir, "lib/volk_environment_init.c"), "w")
-outfile_environment_h = open(os.path.join(gendir, "lib/volk_environment_init.h"), "w")
-outfile_makefile_am = open(os.path.join(gendir, "lib/Makefile.am"), "w")
-outfile_machines_h = open(os.path.join(gendir, "lib/volk_machines.h"), "w")
-outfile_machines_c = open(os.path.join(gendir, "lib/volk_machines.c"), "w")
-hdr_files = glob.glob(os.path.join(srcdir, "include/volk/*.h"))
-
-datatypes = [];
-functions = [];
-
-for line in hdr_files:
- subline = re.search(".*_(a|u)\.h.*", os.path.basename(line))
- if subline:
- subsubline = re.search("(?<=volk_).*", subline.group(0));
- if subsubline:
- dtype = remove_after_underscore.sub("", subsubline.group(0));
- subdtype = re.search("[0-9]+[A-z]+", dtype);
- if subdtype:
- datatypes.append(subdtype.group(0));
-
-
-datatypes = set(datatypes);
-
-for line in hdr_files:
- for dt in datatypes:
- if dt in line:
- subline = re.search("(volk_" + dt +"_.*(a|u).*\.h)", line);
- if subline:
-
- subsubline = re.search(".+(?=\.h)", subline.group(0));
- functions.append(subsubline.group(0));
-
-archs = [];
-afile = minidom.parse(os.path.join(srcdir, "gen/archs.xml"))
-filearchs = afile.getElementsByTagName("arch");
-for filearch in filearchs:
- archs.append(str(filearch.attributes["name"].value));
-
-for arch in archs:
- a_var = re.search("^\$", arch);
- if a_var:
- archs.remove(arch);
-
-#strip out mutex archs
-
-archflags_dict = {}
-for filearch in filearchs:
- archflags_dict[str(filearch.attributes["name"].value)] = str(filearch.getElementsByTagName("flag")[0].firstChild.data)
-
-archalign_dict = {}
-for filearch in filearchs:
- alignelem = filearch.getElementsByTagName("alignment")
- if(alignelem):
- archalign_dict[str(filearch.attributes["name"].value)] = int(alignelem[0].firstChild.data)
-
-archs_or = "("
-for arch in archs:
- archs_or = archs_or + arch.upper() + "|";
-archs_or = archs_or[0:len(archs_or)-1];
-archs_or = archs_or + ")";
-
-#get machine list and parse to a list of machines, each with a list of archs (none of this DOM crap)
-machine_str_dict = {}
-mfile = minidom.parse(os.path.join(srcdir, "gen/machines.xml"))
-filemachines = mfile.getElementsByTagName("machine")
-
-for filemachine in filemachines:
- machine_str_dict[str(filemachine.attributes["name"].value)] = str(filemachine.getElementsByTagName("archs")[0].firstChild.data).split()
-
-#all right now you have a dict of arch lists
-#next we expand it
-#this is an expanded list accounting for the OR syntax
-#TODO: make this work for multiple "|" machines
-machines = {}
-already_done = False
-for machine_name in machine_str_dict:
- already_done = False
- marchlist = machine_str_dict[machine_name]
- for march in marchlist:
- or_marchs = march.split("|")
- if len(or_marchs) > 1:
- marchlist.remove(march)
- for or_march in or_marchs:
- tempmarchlist = copy.deepcopy(marchlist)
- tempmarchlist.append(or_march)
- machines[machine_name + "_" + or_march] = tempmarchlist
- already_done = True
-
- if not already_done:
- machines[machine_name] = marchlist
-
-#get the maximum alignment for all archs in a machine
-machine_alignment_dict = {}
-for machine in machines:
- machine_alignment_dict[machine] = max((archalign_dict.get(k, 1)) for k in machines[machine])
-
-#for machine in machine_alignment_dict:
-# print machine + ": %d" % machine_alignment_dict[machine]
-
-taglist = [];
-fcountlist = [];
-arched_arglist = [];
-retlist = [];
-my_arglist = [];
-my_argtypelist = [];
-for func in functions:
- tags = [];
- fcount = [];
- infile_source = open(os.path.join(srcdir, 'include', 'volk', func + ".h"))
- begun_name = 0;
- begun_paren = 0;
- sourcefile = infile_source.readlines();
- infile_source.close();
- for line in sourcefile:
-#FIXME: make it work for multiple #if define()s
- archline = re.search("^\#if.*?LV_HAVE_" + archs_or + ".*", line);
- if archline:
- arch = archline.group(0);
- archline = re.findall(archs_or + "(?=( |\n|&))", line);
- if archline:
- archsublist = [];
- for tup in archline:
- archsublist.append(tup[0]);
- fcount.append(archsublist);
- testline = re.search("static inline.*?" + func, line);
- if (not testline):
- continue
- tagline = re.search(func + "_.+", line);
- if tagline:
- tag = re.search("(?<=" + func + "_)\w+(?= *\()",line);
- if tag:
- tag = re.search("\w+", tag.group(0));
- if tag:
- tags.append(tag.group(0));
-
-
- if begun_name == 0:
- retline = re.search(".+(?=" + func + ")", line);
- if retline:
- ret = retline.group(0);
-
-
-
-
- subline = re.search(func + ".*", line);
- if subline:
- subsubline = re.search("\(.*?\)", subline.group(0));
- if subsubline:
- args = subsubline.group(0);
-
- else:
- begun_name = 1;
- subsubline = re.search("\(.*", subline.group(0));
- if subsubline:
- args = subsubline.group(0);
- begun_paren = 1;
- else:
- if begun_paren == 1:
- subline = re.search(".*?\)", line);
- if subline:
- args = args + subline.group(0);
- begun_name = 0;
- begun_paren = 0;
- else:
- subline = re.search(".*", line);
- args = args + subline.group(0);
- else:
- subline = re.search("\(.*?\)", line);
- if subline:
- args = subline.group(0);
- begun_name = 0;
- else:
- subline = re.search("\(.*", line);
- if subline:
- args = subline.group(0);
- begun_paren = 1;
-
- replace = re.compile("static ");
- ret = replace.sub("", ret);
- replace = re.compile("inline ");
- ret = replace.sub("", ret);
- replace = re.compile("\)");
- arched_args = replace.sub(", const char* arch) {", args);
-
- remove = re.compile('\)|\(|{');
- rargs = remove.sub("", args);
- sargs = rargs.split(',');
-
-
-
- margs = [];
- atypes = [];
- for arg in sargs:
- temp = arg.split(" ");
- margs.append(temp[-1]);
- replace = re.compile(" " + temp[-1]);
- atypes.append(replace.sub("", arg));
-
-
- my_args = ""
- arg_types = ""
- for arg in range(0, len(margs) - 1):
- this_arg = leading_space_remove.sub("", margs[arg]);
- my_args = my_args + this_arg + ", ";
- this_type = leading_space_remove.sub("", atypes[arg]);
- arg_types = arg_types + this_type + ", ";
-
- this_arg = leading_space_remove.sub("", margs[-1]);
- my_args = my_args + this_arg;
- this_type = leading_space_remove.sub("", atypes[-1]);
- arg_types = arg_types + this_type;
- my_argtypelist.append(arg_types);
-
- if(ret[-1] != ' '):
- ret = ret + ' ';
-
- arched_arglist.append(arched_args); #!!!!!!!!!!!
- my_arglist.append(my_args) #!!!!!!!!!!!!!!!!!
- retlist.append(ret);
- fcountlist.append(fcount);
- taglist.append(tags);
-
-
-outfile_cpu_h.write(make_cpuid_h(filearchs));
-outfile_cpu_h.close();
-
-outfile_cpu_c.write(make_cpuid_c(filearchs));
-outfile_cpu_c.close();
-
-outfile_set_simd.write(make_set_simd(filearchs, machines));
-outfile_set_simd.close();
-
-outfile_config_fixed.write(make_config_fixed(filearchs));
-outfile_config_fixed.close();
-
-outfile_typedefs.write(make_typedefs(functions, retlist, my_argtypelist));
-outfile_typedefs.close();
-
-outfile_makefile_am.write(make_makefile_am(filearchs, machines, archflags_dict))
-outfile_makefile_am.close()
-
-outfile_machines_h.write(make_machines_h(functions, machines, archs))
-outfile_machines_h.close()
-
-outfile_machines_c.write(make_machines_c(machines))
-outfile_machines_c.close()
-
-outfile_c.write(make_c(machines, archs, functions, arched_arglist, my_arglist))
-outfile_c.close()
-
-outfile_h.write(make_h(functions, arched_arglist))
-outfile_h.close()
-
-for machine in machines:
- machine_c_filename = os.path.join(gendir, "lib/volk_machine_" + machine + ".c")
- outfile_machine_c = open(machine_c_filename, "w")
- outfile_machine_c.write(make_each_machine_c(machine, machines[machine], functions, fcountlist, taglist, machine_alignment_dict[machine]))
- outfile_machine_c.close()
diff --git a/volk/gen/volk_tmpl_utils.py b/volk/gen/volk_tmpl_utils.py
new file mode 100644
index 000000000..6c08a8213
--- /dev/null
+++ b/volk/gen/volk_tmpl_utils.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python
+#
+# 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.
+#
+
+import os
+import re
+import sys
+import optparse
+import volk_arch_defs
+import volk_machine_defs
+import volk_kernel_defs
+from Cheetah import Template
+
+def __escape_pre_processor(code):
+ out = list()
+ for line in code.splitlines():
+ m = re.match('^(\s*)#(\s*)(\w+)(.*)$', line)
+ if m:
+ p0, p1, fcn, stuff = m.groups()
+ conly = fcn in ('include', 'define', 'ifdef', 'ifndef', 'endif', 'elif', 'pragma')
+ both = fcn in ('if', 'else')
+ istmpl = '$' in stuff
+ if 'defined' in stuff: istmpl = False
+ if conly or (both and not istmpl):
+ line = '%s\\#%s%s%s'%(p0, p1, fcn, stuff)
+ out.append(line)
+ return '\n'.join(out)
+
+def __parse_tmpl(_tmpl, **kwargs):
+ defs = {
+ 'archs': volk_arch_defs.archs,
+ 'arch_dict': volk_arch_defs.arch_dict,
+ 'machines': volk_machine_defs.machines,
+ 'machine_dict': volk_machine_defs.machine_dict,
+ 'kernels': volk_kernel_defs.kernels,
+ }
+ defs.update(kwargs)
+ _tmpl = __escape_pre_processor(_tmpl)
+ _tmpl = """
+
+/* this file was generated by volk template utils, do not edit! */
+
+""" + _tmpl
+ return str(Template.Template(_tmpl, defs))
+
+def main():
+ parser = optparse.OptionParser()
+ parser.add_option('--input', type='string')
+ parser.add_option('--output', type='string')
+ (opts, args) = parser.parse_args()
+
+ output = __parse_tmpl(open(opts.input).read(), args=args)
+ if opts.output: open(opts.output, 'w').write(output)
+ else: print output
+
+if __name__ == '__main__': main()
diff --git a/volk/lib/CMakeLists.txt b/volk/lib/CMakeLists.txt
index b491f94bb..8288786c9 100644
--- a/volk/lib/CMakeLists.txt
+++ b/volk/lib/CMakeLists.txt
@@ -1,5 +1,5 @@
#
-# Copyright 2011 Free Software Foundation, Inc.
+# Copyright 2011-2012 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -16,6 +16,31 @@
#
########################################################################
+# header file detection
+########################################################################
+include(CheckIncludeFile)
+CHECK_INCLUDE_FILE(cpuid.h HAVE_CPUID_H)
+if(HAVE_CPUID_H)
+ add_definitions(-DHAVE_CPUID_H)
+endif()
+
+CHECK_INCLUDE_FILE(intrin.h HAVE_INTRIN_H)
+if(HAVE_INTRIN_H)
+ add_definitions(-DHAVE_INTRIN_H)
+endif()
+
+CHECK_INCLUDE_FILE(fenv.h HAVE_FENV_H)
+if(HAVE_FENV_H)
+ add_definitions(-DHAVE_FENV_H)
+endif()
+
+CHECK_INCLUDE_FILE(dlfcn.h HAVE_DLFCN_H)
+if(HAVE_DLFCN_H)
+ add_definitions(-DHAVE_DLFCN_H)
+ list(APPEND volk_libraries ${CMAKE_DL_LIBS})
+endif()
+
+########################################################################
# Setup the compiler name
########################################################################
set(COMPILER_NAME ${CMAKE_C_COMPILER_ID})
@@ -23,235 +48,183 @@ if(MSVC) #its not set otherwise
set(COMPILER_NAME MSVC)
endif()
+message(STATUS "Compiler name: ${COMPILER_NAME}")
+
if(NOT DEFINED COMPILER_NAME)
message(FATAL_ERROR "COMPILER_NAME undefined. Volk build may not support this compiler.")
endif()
########################################################################
-# Parse the arches xml file:
-# Test each arch to see if the compiler supports the flag.
-# If the test passes append the arch to the available list.
+# detect x86 flavor of CPU
########################################################################
-#extract the compiler lines from the xml file using abusive python
-
-
-
-execute_process(
- COMMAND ${PYTHON_EXECUTABLE} -c
- "from xml.dom import minidom; print ';'.join(map(lambda b: ','.join([','.join([b.attributes['name'].value,item.attributes['name'].value,item.firstChild.data]) for item in b.getElementsByTagName('remap')]), minidom.parse('${CMAKE_SOURCE_DIR}/gen/compilers.xml').getElementsByTagName('compiler')))"
-
- OUTPUT_VARIABLE compiler_lines OUTPUT_STRIP_TRAILING_WHITESPACE
-)
-
-foreach(thing ${compiler_lines})
- string(REGEX REPLACE "," ";" thing_list ${thing})
- list(FIND thing_list ${COMPILER_NAME} check_val)
- if(NOT ("${check_val}" STREQUAL "-1"))
- string(REGEX REPLACE "${COMPILER_NAME}," ";" filter_string ${thing})
- endif()
-endforeach()
-
+if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "^(i.86|x86|x86_64|amd64)$")
+ message(STATUS "x86* CPU detected")
+ set(CPU_IS_x86 TRUE)
+endif()
-#extract compiler prefixes from the xml file using abusive python
+########################################################################
+# determine passing architectures based on compile flag tests
+########################################################################
execute_process(
- COMMAND ${PYTHON_EXECUTABLE} -c
- "from xml.dom import minidom; print ';'.join(map(lambda b: ','.join([','.join([b.attributes['name'].value,item.firstChild.data]) for item in b.getElementsByTagName('prefix')]), minidom.parse('${CMAKE_SOURCE_DIR}/gen/compilers.xml').getElementsByTagName('compiler')))"
-
- OUTPUT_VARIABLE compiler_prefixes OUTPUT_STRIP_TRAILING_WHITESPACE
+ COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
+ ${CMAKE_SOURCE_DIR}/gen/volk_compile_utils.py
+ --mode "arch_flags" --compiler "${COMPILER_NAME}"
+ OUTPUT_VARIABLE arch_flag_lines OUTPUT_STRIP_TRAILING_WHITESPACE
)
-foreach(thing ${compiler_prefixes})
- string(REGEX REPLACE "," ";" thing_list ${thing})
- list(FIND thing_list ${COMPILER_NAME} check_val)
- if(NOT ("${check_val}" STREQUAL "-1"))
- list(GET thing_list "1" prefix)
+macro(check_arch arch_name)
+ set(flags ${ARGN})
+ set(have_${arch_name} TRUE)
+ foreach(flag ${flags})
+ include(CheckCXXCompilerFlag)
+ set(have_flag have${flag})
+ execute_process( #make the have_flag have nice alphanum chars (just for looks/not necessary)
+ COMMAND ${PYTHON_EXECUTABLE} -c "import re; print(re.sub('\\W', '_', '${have_flag}'))"
+ OUTPUT_VARIABLE have_flag OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ CHECK_CXX_COMPILER_FLAG(${flag} ${have_flag})
+ if (NOT ${have_flag})
+ set(have_${arch_name} FALSE)
+ endif()
+ endforeach(flag)
+ if (have_${arch_name})
+ list(APPEND available_archs ${arch_name})
endif()
-endforeach()
-
-
-
-
-#extract the arch lines from the xml file using abusive python
-execute_process(
- COMMAND ${PYTHON_EXECUTABLE} -c
- "from xml.dom import minidom; print ';'.join(map(lambda a: '%s %s %s %s'%(a.attributes['name'].value,a.getElementsByTagName('flag')[0].firstChild.data,a.getElementsByTagName('overrule')[0].firstChild.data,a.getElementsByTagName('overrule_val')[0].firstChild.data) if (len(a.getElementsByTagName('overrule'))) else '%s %s %s %s'%(a.attributes['name'].value,a.getElementsByTagName('flag')[0].firstChild.data,'no_overrule', 'no_overrule_val'), minidom.parse('${CMAKE_SOURCE_DIR}/gen/archs.xml').getElementsByTagName('arch')))"
-
- OUTPUT_VARIABLE arch_lines OUTPUT_STRIP_TRAILING_WHITESPACE
-)
+endmacro(check_arch)
+foreach(line ${arch_flag_lines})
+ string(REGEX REPLACE "," ";" arch_flags ${line})
+ check_arch(${arch_flags})
+endforeach(line)
+macro(OVERRULE_ARCH arch reason)
+ message(STATUS "${reason}, Overruled arch ${arch}")
+ list(REMOVE_ITEM available_archs ${arch})
+endmacro(OVERRULE_ARCH)
-
-#set the various overrule values (see archs.xml)
-#a lot of this is translating between automake and cmake
-if(NOT "${CROSSCOMPILE_MULTILIB}" STREQUAL "true")
- set(MD_SUBCPU ${CMAKE_SYSTEM_PROCESSOR})
- #detect 32 or 64 bit compiler
- if(MD_SUBCPU MATCHES "^(i.86|x86|x86_64|amd64)$")
- include(CheckTypeSize)
- check_type_size("void*" SIZEOF_VOID_P BUILTIN_TYPES_ONLY)
- if (${SIZEOF_VOID_P} EQUAL 8)
- set(MD_SUBCPU x86_64)
- else()
- set(MD_SUBCPU x86)
- endif()
+########################################################################
+# eliminate AVX on GCC < 4.4
+# even though it accepts -mavx, as won't assemble xgetbv, which we need
+########################################################################
+if(CPU_IS_x86 AND COMPILER_NAME MATCHES "GNU")
+ execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
+ OUTPUT_VARIABLE GCC_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if(GCC_VERSION VERSION_LESS "4.4")
+ OVERRULE_ARCH(avx "GCC missing xgetbv")
endif()
endif()
-if(NOT "${ORC_FOUND}" STREQUAL "TRUE")
- set(LV_HAVE_ORC "no")
-endif()
-
+########################################################################
+# implement overruling in the ORC case,
+# since ORC always passes flag detection
+########################################################################
+if(NOT ORC_FOUND)
+ OVERRULE_ARCH(orc "ORC support not found")
+endif()
-
-
-
-macro(compiler_filter name flag)
- set(filtered_flag ${flag})
- foreach(thing ${filter_string})
- string(REGEX REPLACE "," ";" flagmap ${thing})
- list(GET flagmap "0" key)
- list(GET flagmap "1" val)
- string(REGEX MATCH "^${key}$" found ${flag})
- if("${found}" STREQUAL "${key}")
- string(REGEX REPLACE "^${key}$" "${val}" filtered_flag ${flag})
- endif()
- endforeach()
- set(${name}_flag "${prefix}${filtered_flag}")
-endmacro()
-
-
-
-
-
-
-
-macro(handle_arch name flag overrule overrule_val)
-
- #handle overrule
- if("${${overrule}}" STREQUAL "${overrule_val}")
- set(have_${name} FALSE)
- message(STATUS "${name} overruled")
- #handle special case for none flag
- elseif(${flag} STREQUAL "none")
- set(have_${name} TRUE)
- #otherwise test the flag(s) against the compiler
- else()
- include(CheckCXXCompilerFlag)
- string(REGEX REPLACE "," ";" flag_list ${flag})
- set(have_${name} 1)
- foreach(thing ${flag_list})
- compiler_filter(${name} ${thing})
- CHECK_CXX_COMPILER_FLAG(${${name}_flag} have_${thing})
- if(NOT (${have_${name}} AND ("${have_${thing}}" STREQUAL "1")))
- set(have_${name} 0)
- endif()
- endforeach()
+########################################################################
+# implement overruling in the non-multilib case
+# this makes things work when both -m32 and -m64 pass
+########################################################################
+if(NOT CROSSCOMPILE_MULTILIB AND CPU_IS_x86)
+ include(CheckTypeSize)
+ check_type_size("void*[8]" SIZEOF_CPU BUILTIN_TYPES_ONLY)
+ if (${SIZEOF_CPU} EQUAL 64)
+ OVERRULE_ARCH(32 "CPU width is 64 bits")
endif()
-
- if(have_${name})
- list(APPEND available_arches ${name})
+ if (${SIZEOF_CPU} EQUAL 32)
+ OVERRULE_ARCH(64 "CPU width is 32 bits")
endif()
+endif()
-endmacro(handle_arch)
-
-#create a list of available arches
-foreach(arch_line ${arch_lines})
- string(REPLACE " " ";" args "${arch_line}")
- handle_arch(${args})
-endforeach(arch_line)
-
-message(STATUS "Available arches: ${available_arches}")
+########################################################################
+# done overrules! print the result
+########################################################################
+message(STATUS "Available architectures: ${available_archs}")
########################################################################
-# Parse the machines xml file:
-# Test each machine to see if its arch dependencies are supported.
-# Build a list of supported machines and the machine definitions.
+# determine available machines given the available architectures
########################################################################
-#extract the machine lines from the xml file using crazy python
execute_process(
- COMMAND ${PYTHON_EXECUTABLE} -c
- "from xml.dom import minidom; print ';'.join(map(lambda a: '%s %s'%(a.attributes['name'].value,a.getElementsByTagName('archs')[0].firstChild.data),minidom.parse('${CMAKE_SOURCE_DIR}/gen/machines.xml').getElementsByTagName('machine')))"
- OUTPUT_VARIABLE machine_lines OUTPUT_STRIP_TRAILING_WHITESPACE
+ COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
+ ${CMAKE_SOURCE_DIR}/gen/volk_compile_utils.py
+ --mode "machines" --archs "${available_archs}"
+ OUTPUT_VARIABLE available_machines OUTPUT_STRIP_TRAILING_WHITESPACE
)
-macro(handle_machine1 name)
- unset(machine_flags)
- string(TOUPPER LV_MACHINE_${name} machine_def)
-
- #check if all the arches are supported
- foreach(arch ${ARGN})
- set(is_match ${have_${arch}})
- if(NOT is_match)
- set(is_match FALSE)
- break()
- endif(NOT is_match)
- set(machine_flags "${machine_flags} ${${arch}_flag}")
- endforeach(arch)
-
- string(REGEX REPLACE "^[ \t]+" "" machine_flags "${machine_flags}")
-
- if(is_match)
- #this is a match, append the source and set its flags
- set(machine_source ${CMAKE_CURRENT_BINARY_DIR}/volk_machine_${name}.c)
- set_source_files_properties(${machine_source} PROPERTIES COMPILE_FLAGS "${machine_flags}")
- list(APPEND machine_sources ${machine_source})
- list(APPEND machine_defs ${machine_def})
- list(APPEND available_machines ${name})
- endif()
-endmacro(handle_machine1)
-
-macro(handle_machine name)
- set(arches ${ARGN})
- list(FIND arches "32|64" index)
- if(${index} EQUAL -1)
- handle_machine1(${name} ${arches})
- else()
- list(REMOVE_ITEM arches "32|64")
- handle_machine1(${name}_32 32 ${arches})
- handle_machine1(${name}_64 64 ${arches})
- endif()
-endmacro(handle_machine)
-
-#setup the available machines
-foreach(machine_line ${machine_lines})
- string(REPLACE " " ";" args "${machine_line}")
- handle_machine(${args})
-endforeach(machine_line)
+########################################################################
+# Implement machine overruling for redundant machines:
+# A machine is redundant when expansion rules occur,
+# and the arch superset passes configuration checks.
+# When this occurs, eliminate the redundant machines
+# to avoid unnecessary compilation of subset machines.
+########################################################################
+foreach(arch orc 64 32)
+ foreach(machine_name ${available_machines})
+ string(REPLACE "_${arch}" "" machine_name_no_arch ${machine_name})
+ if (${machine_name} STREQUAL ${machine_name_no_arch})
+ else()
+ list(REMOVE_ITEM available_machines ${machine_name_no_arch})
+ endif()
+ endforeach(machine_name)
+endforeach(arch)
+########################################################################
+# done overrules! print the result
+########################################################################
message(STATUS "Available machines: ${available_machines}")
########################################################################
# Create rules to run the volk generator
########################################################################
-#list of the generated sources
-set(volk_gen_sources
- ${CMAKE_BINARY_DIR}/include/volk/volk.h
- ${CMAKE_BINARY_DIR}/lib/volk.c
- ${CMAKE_BINARY_DIR}/lib/volk_init.h
- ${CMAKE_BINARY_DIR}/include/volk/volk_typedefs.h
- ${CMAKE_BINARY_DIR}/include/volk/volk_cpu.h
- ${CMAKE_BINARY_DIR}/lib/volk_cpu.c
- ${CMAKE_BINARY_DIR}/include/volk/volk_config_fixed.h
- ${CMAKE_BINARY_DIR}/lib/volk_environment_init.c
- ${CMAKE_BINARY_DIR}/lib/volk_environment_init.h
- ${CMAKE_BINARY_DIR}/lib/volk_machines.h
- ${CMAKE_BINARY_DIR}/lib/volk_machines.c
- ${machine_sources}
-)
#dependencies are all python, xml, and header implementation files
file(GLOB xml_files ${CMAKE_SOURCE_DIR}/gen/*.xml)
file(GLOB py_files ${CMAKE_SOURCE_DIR}/gen/*.py)
file(GLOB h_files ${CMAKE_SOURCE_DIR}/include/volk/*.h)
-add_custom_command(
- OUTPUT ${volk_gen_sources}
- DEPENDS ${xml_files} ${py_files} ${h_files}
- COMMAND ${PYTHON_EXECUTABLE} -B
- ${CMAKE_SOURCE_DIR}/gen/volk_register.py
- ${CMAKE_BINARY_DIR}
-)
+macro(gen_template tmpl output)
+ list(APPEND volk_gen_sources ${output})
+ add_custom_command(
+ OUTPUT ${output}
+ DEPENDS ${xml_files} ${py_files} ${h_files} ${tmpl}
+ COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
+ ${CMAKE_SOURCE_DIR}/gen/volk_tmpl_utils.py
+ --input ${tmpl} --output ${output} ${ARGN}
+ )
+endmacro(gen_template)
+
+make_directory(${CMAKE_BINARY_DIR}/include/volk)
+
+gen_template(${CMAKE_SOURCE_DIR}/tmpl/volk.tmpl.h ${CMAKE_BINARY_DIR}/include/volk/volk.h)
+gen_template(${CMAKE_SOURCE_DIR}/tmpl/volk.tmpl.c ${CMAKE_BINARY_DIR}/lib/volk.c)
+gen_template(${CMAKE_SOURCE_DIR}/tmpl/volk_typedefs.tmpl.h ${CMAKE_BINARY_DIR}/include/volk/volk_typedefs.h)
+gen_template(${CMAKE_SOURCE_DIR}/tmpl/volk_cpu.tmpl.h ${CMAKE_BINARY_DIR}/include/volk/volk_cpu.h)
+gen_template(${CMAKE_SOURCE_DIR}/tmpl/volk_cpu.tmpl.c ${CMAKE_BINARY_DIR}/lib/volk_cpu.c)
+gen_template(${CMAKE_SOURCE_DIR}/tmpl/volk_config_fixed.tmpl.h ${CMAKE_BINARY_DIR}/include/volk/volk_config_fixed.h)
+gen_template(${CMAKE_SOURCE_DIR}/tmpl/volk_machines.tmpl.h ${CMAKE_BINARY_DIR}/lib/volk_machines.h)
+gen_template(${CMAKE_SOURCE_DIR}/tmpl/volk_machines.tmpl.c ${CMAKE_BINARY_DIR}/lib/volk_machines.c)
+
+foreach(machine_name ${available_machines})
+ #generate machine source
+ set(machine_source ${CMAKE_CURRENT_BINARY_DIR}/volk_machine_${machine_name}.c)
+ gen_template(${CMAKE_SOURCE_DIR}/tmpl/volk_machine_xxx.tmpl.c ${machine_source} ${machine_name})
+
+ #determine machine flags
+ execute_process(
+ COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
+ ${CMAKE_SOURCE_DIR}/gen/volk_compile_utils.py
+ --mode "machine_flags" --machine "${machine_name}" --compiler "${COMPILER_NAME}"
+ OUTPUT_VARIABLE ${machine_name}_flags OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ if(${machine_name}_flags)
+ set_source_files_properties(${machine_source} PROPERTIES COMPILE_FLAGS "${${machine_name}_flags}")
+ endif()
+
+ #add to available machine defs
+ string(TOUPPER LV_MACHINE_${machine_name} machine_def)
+ list(APPEND machine_defs ${machine_def})
+endforeach(machine_name)
########################################################################
# Set local include directories first
@@ -270,7 +243,7 @@ if(ORC_FOUND)
#setup orc library usage
include_directories(${ORC_INCLUDE_DIRS})
link_directories(${ORC_LIBRARY_DIRS})
- add_definitions(-DLV_HAVE_ORC)
+ list(APPEND volk_libraries ${ORC_LIBRARIES})
#setup orc functions
file(GLOB orc_files ${CMAKE_SOURCE_DIR}/orc/*.orc)
@@ -313,16 +286,15 @@ PROPERTIES COMPILE_DEFINITIONS "${machine_defs}")
if(MSVC)
#add compatibility includes for stdint types
- include_directories(${CMAKE_SOURCE_DIR}/msvc)
+ include_directories(${CMAKE_SOURCE_DIR}/cmake/msvc)
+ add_definitions(-DHAVE_CONFIG_H)
#compile the sources as C++ due to the lack of complex.h under MSVC
set_source_files_properties(${volk_sources} PROPERTIES LANGUAGE CXX)
endif()
#create the volk runtime library
add_library(volk SHARED ${volk_sources})
-if(ORC_FOUND)
- target_link_libraries(volk ${ORC_LIBRARIES})
-endif(ORC_FOUND)
+target_link_libraries(volk ${volk_libraries})
set_target_properties(volk PROPERTIES SOVERSION ${LIBVER})
set_target_properties(volk PROPERTIES DEFINE_SYMBOL "volk_EXPORTS")
diff --git a/volk/lib/gcc_x86_cpuid.h b/volk/lib/gcc_x86_cpuid.h
index e0254f192..3c3f47b00 100644
--- a/volk/lib/gcc_x86_cpuid.h
+++ b/volk/lib/gcc_x86_cpuid.h
@@ -5,16 +5,16 @@
* 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 file 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.
- *
+ *
* Under Section 7 of GPL version 3, you are granted additional
* permissions described in the GCC Runtime Library Exception, version
* 3.1, as published by the Free Software Foundation.
- *
+ *
* You should have received a copy of the GNU General Public License and
* a copy of the GCC Runtime Library Exception along with this program;
* see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
diff --git a/volk/lib/testqa.cc b/volk/lib/testqa.cc
index 593087f85..d0204fc01 100644
--- a/volk/lib/testqa.cc
+++ b/volk/lib/testqa.cc
@@ -55,7 +55,7 @@ VOLK_RUN_TESTS(volk_32f_x2_dot_prod_32f_a, 1e-4, 0, 204600, 1);
VOLK_RUN_TESTS(volk_32f_x2_dot_prod_32f_u, 1e-4, 0, 204600, 1);
//VOLK_RUN_TESTS(volk_32f_s32f_32f_fm_detect_32f_a, 1e-4, 2046, 10000);
VOLK_RUN_TESTS(volk_32f_index_max_16u_a, 3, 0, 20460, 1);
-VOLK_RUN_TESTS(volk_32f_x2_s32f_interleave_16ic_a, 1, 32768, 20460, 1);
+VOLK_RUN_TESTS(volk_32f_x2_s32f_interleave_16ic_a, 1, 32767, 20460, 1);
VOLK_RUN_TESTS(volk_32f_x2_interleave_32fc_a, 0, 0, 20460, 1);
VOLK_RUN_TESTS(volk_32f_x2_max_32f_a, 1e-4, 0, 20460, 1);
VOLK_RUN_TESTS(volk_32f_x2_min_32f_a, 1e-4, 0, 20460, 1);
diff --git a/volk/libvector_replace.sh b/volk/libvector_replace.sh
deleted file mode 100755
index e1940c00f..000000000
--- a/volk/libvector_replace.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/bash
-
-cd $1
-files=`ls`
-for file in $files
-do
- sed 's/libvector/volk/g' < $file > tempfile
- sed 's/LIBVECTOR/VOLK/g' < tempfile > $file
-done
-for file in $files
-do
- echo $file > tempfile
- newfile=`sed 's/libvector/volk/g' < tempfile`
- if (test "$file" != "$newfile"); then
- mv $file $newfile
- echo "changed $file to $newfile"
- fi
-done
diff --git a/volk/python/__init__.py b/volk/python/__init__.py
deleted file mode 100644
index 7c9c4a0c6..000000000
--- a/volk/python/__init__.py
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# Copyright 2010 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.
-#
-
-# The presence of this file turns this directory into a Python package
-
-# ----------------------------------------------------------------
-# Temporary workaround for ticket:181 (swig+python problem)
-import sys
-_RTLD_GLOBAL = 0
-try:
- from dl import RTLD_GLOBAL as _RTLD_GLOBAL
-except ImportError:
- try:
- from DLFCN import RTLD_GLOBAL as _RTLD_GLOBAL
- except ImportError:
- pass
-
-if _RTLD_GLOBAL != 0:
- _dlopenflags = sys.getdlopenflags()
- sys.setdlopenflags(_dlopenflags|_RTLD_GLOBAL)
-# ----------------------------------------------------------------
-
-
-# import swig generated symbols into the volk namespace
-from volk_swig import *
-
-# import any pure python here
-# from volk_foo import bar
-# from volk_baz import *
-
-
-# ----------------------------------------------------------------
-# Tail of workaround
-if _RTLD_GLOBAL != 0:
- sys.setdlopenflags(_dlopenflags) # Restore original flags
-# ----------------------------------------------------------------
diff --git a/volk/python/volk.i b/volk/python/volk.i
deleted file mode 100644
index d678a9120..000000000
--- a/volk/python/volk.i
+++ /dev/null
@@ -1,47 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2010 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.
- */
-
-%feature("autodoc", "1"); // generate python docstrings
-
-%include "exception.i"
-%import "gnuradio.i" // the common stuff
-
-%{
-#include "gnuradio_swig_bug_workaround.h" // mandatory bug fix
-#include <stdexcept>
-%}
-
-// ----------------------------------------------------------------
-
-/*
- * Gather all .i files in this directory together.
- */
-
-%{
-
-// The .h files
-#include <volk/volk_square_ff.h>
-
-%}
-
-// The .i files
-%include <volk_square_ff.i>
-
diff --git a/volk/tmpl/volk.tmpl.c b/volk/tmpl/volk.tmpl.c
new file mode 100644
index 000000000..c3a1544ff
--- /dev/null
+++ b/volk/tmpl/volk.tmpl.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2011-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 <volk/volk_common.h>
+#include "volk_machines.h"
+#include <volk/volk_typedefs.h>
+#include <volk/volk_cpu.h>
+#include "volk_rank_archs.h"
+#include <volk/volk.h>
+#include <stdio.h>
+#include <string.h>
+
+struct volk_machine *get_machine(void) {
+ extern struct volk_machine *volk_machines[];
+ extern unsigned int n_volk_machines;
+ static struct volk_machine *machine = NULL;
+
+ if(machine != NULL) return machine;
+ else {
+ unsigned int max_score = 0;
+ unsigned int i;
+ for(i=0; i<n_volk_machines; i++) {
+ if(!(volk_machines[i]->caps & (~volk_get_lvarch()))) {
+ if(volk_machines[i]->caps > max_score) {
+ max_score = volk_machines[i]->caps;
+ machine = volk_machines[i];
+ }
+ }
+ }
+ printf("Using Volk machine: %s\n", machine->name);
+ return machine;
+ }
+}
+
+unsigned int volk_get_alignment(void) {
+ return get_machine()->alignment;
+}
+
+#for $kern in $kernels
+
+void get_$(kern.name)($kern.arglist_namedefs) {
+ $kern.name = get_machine()->$(kern.name)_archs[volk_rank_archs(
+ get_machine()->$(kern.name)_indices,
+ get_machine()->$(kern.name)_arch_defs,
+ get_machine()->$(kern.name)_n_archs,
+ get_machine()->$(kern.name)_name,
+ volk_get_lvarch()
+ )];
+ $(kern.name)($kern.arglist_names);
+}
+
+$kern.pname $kern.name = &get_$(kern.name);
+
+void $(kern.name)_manual($kern.arglist_namedefs, const char* arch) {
+ const size_t index = get_index(
+ get_machine()->$(kern.name)_indices,
+ get_machine()->$(kern.name)_n_archs,
+ arch
+ );
+ get_machine()->$(kern.name)_archs[index](
+ $kern.arglist_names
+ );
+}
+
+struct volk_func_desc $(kern.name)_get_func_desc(void) {
+ struct volk_func_desc desc = {
+ get_machine()->$(kern.name)_indices,
+ get_machine()->$(kern.name)_arch_defs,
+ get_machine()->$(kern.name)_n_archs
+ };
+ return desc;
+}
+
+#end for
diff --git a/volk/tmpl/volk.tmpl.h b/volk/tmpl/volk.tmpl.h
new file mode 100644
index 000000000..161579e46
--- /dev/null
+++ b/volk/tmpl/volk.tmpl.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2011-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.
+ */
+
+#ifndef INCLUDED_VOLK_RUNTIME
+#define INCLUDED_VOLK_RUNTIME
+
+#include <volk/volk_typedefs.h>
+#include <volk/volk_config_fixed.h>
+#include <volk/volk_common.h>
+#include <volk/volk_complex.h>
+
+__VOLK_DECL_BEGIN
+
+struct volk_func_desc {
+ const char **indices;
+ const int *arch_defs;
+ const int n_archs;
+};
+
+VOLK_API unsigned int volk_get_alignment(void);
+
+#for $kern in $kernels
+extern VOLK_API $kern.pname $kern.name;
+extern VOLK_API void $(kern.name)_manual($kern.arglist_namedefs, const char* arch);
+extern VOLK_API struct volk_func_desc $(kern.name)_get_func_desc(void);
+#end for
+
+__VOLK_DECL_END
+
+#endif /*INCLUDED_VOLK_RUNTIME*/
diff --git a/volk/tmpl/volk_config_fixed.tmpl.h b/volk/tmpl/volk_config_fixed.tmpl.h
new file mode 100644
index 000000000..e1c01ae77
--- /dev/null
+++ b/volk/tmpl/volk_config_fixed.tmpl.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2011-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.
+ */
+
+#ifndef INCLUDED_VOLK_CONFIG_FIXED_H
+#define INCLUDED_VOLK_CONFIG_FIXED_H
+
+#for $i, $arch in enumerate($archs)
+#define LV_$(arch.name.upper()) $i
+#end for
+
+#endif /*INCLUDED_VOLK_CONFIG_FIXED*/
diff --git a/volk/tmpl/volk_cpu.tmpl.c b/volk/tmpl/volk_cpu.tmpl.c
new file mode 100644
index 000000000..81fc679cb
--- /dev/null
+++ b/volk/tmpl/volk_cpu.tmpl.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2011-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 <volk/volk_cpu.h>
+#include <volk/volk_config_fixed.h>
+#include <stdlib.h>
+
+struct VOLK_CPU volk_cpu;
+
+#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)
+ #define VOLK_CPU_x86
+#endif
+
+#if defined(VOLK_CPU_x86)
+
+//implement get cpuid for gcc compilers using a system or local copy of cpuid.h
+#if defined(__GNUC__)
+ #if defined(HAVE_CPUID_H)
+ #include <cpuid.h>
+ #else
+ #include "gcc_x86_cpuid.h"
+ #endif
+ #define cpuid_x86(op, r) __get_cpuid(op, (unsigned int *)r+0, (unsigned int *)r+1, (unsigned int *)r+2, (unsigned int *)r+3)
+
+ /* Return Intel AVX extended CPU capabilities register.
+ * This function will bomb on non-AVX-capable machines, so
+ * check for AVX capability before executing.
+ */
+ #if __GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 4
+ static inline unsigned long long _xgetbv(unsigned int index){
+ unsigned int eax, edx;
+ __asm__ __volatile__("xgetbv" : "=a"(eax), "=d"(edx) : "c"(index));
+ return ((unsigned long long)edx << 32) | eax;
+ }
+ #define __xgetbv() _xgetbv(0)
+ #else
+ #define __xgetbv() 0
+ #endif
+
+//implement get cpuid for MSVC compilers using __cpuid intrinsic
+#elif defined(_MSC_VER) && defined(HAVE_INTRIN_H)
+ #include <intrin.h>
+ #define cpuid_x86(op, r) __cpuid(((int*)r), op)
+
+ #if defined(_XCR_XFEATURE_ENABLED_MASK)
+ #define __xgetbv() _xgetbv(_XCR_XFEATURE_ENABLED_MASK)
+ #else
+ #define __xgetbv() 0
+ #endif
+
+#else
+ #error "A get cpuid for volk is not available on this compiler..."
+#endif //defined(__GNUC__)
+
+#endif //defined(VOLK_CPU_x86)
+
+static inline unsigned int cpuid_x86_bit(unsigned int reg, unsigned int op, unsigned int bit) {
+#if defined(VOLK_CPU_x86)
+ unsigned int regs[4];
+ cpuid_x86(op, regs);
+ return regs[reg] >> bit & 0x01;
+#else
+ return 0;
+#endif
+}
+
+static inline unsigned int check_extended_cpuid(unsigned int val) {
+#if defined(VOLK_CPU_x86)
+ unsigned int regs[4];
+ cpuid_x86(0x80000000, regs);
+ return regs[0] >= val;
+#else
+ return 0;
+#endif
+}
+
+static inline unsigned int get_avx_enabled(void) {
+#if defined(VOLK_CPU_x86)
+ return __xgetbv() & 0x6;
+#else
+ return 0;
+#endif
+}
+
+//neon detection is linux specific
+#if defined(__arm__) && defined(__linux__)
+ #include <asm/hwcap.h>
+ #include <linux/auxvec.h>
+ #include <stdio.h>
+ #define VOLK_CPU_ARM
+#endif
+
+static int has_neon(void){
+#if defined(VOLK_CPU_ARM)
+ FILE *auxvec_f;
+ unsigned long auxvec[2];
+ unsigned int found_neon = 0;
+ auxvec_f = fopen("/proc/self/auxv", "rb");
+ if(!auxvec_f) return 0;
+
+ //so auxv is basically 32b of ID and 32b of value
+ //so it goes like this
+ while(!found_neon && auxvec_f) {
+ fread(auxvec, sizeof(unsigned long), 2, auxvec_f);
+ if((auxvec[0] == AT_HWCAP) && (auxvec[1] & HWCAP_NEON))
+ found_neon = 1;
+ }
+
+ fclose(auxvec_f);
+ return found_neon;
+#else
+ return 0;
+#endif
+}
+
+static int has_ppc(void){
+#ifdef __PPC__
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+#for $arch in $archs
+static int i_can_has_$arch.name (void) {
+ #for $check, $params in $arch.checks
+ if ($(check)($(', '.join($params))) == 0) return 0;
+ #end for
+ return 1;
+}
+
+#end for
+
+#if defined(HAVE_FENV_H)
+ #include <fenv.h>
+ static inline void set_float_rounding(void){
+ fesetround(FE_TONEAREST);
+ }
+#elif defined(_MSC_VER)
+ #include <float.h>
+ static inline void set_float_rounding(void){
+ unsigned int cwrd;
+ _controlfp_s(&cwrd, 0, 0);
+ _controlfp_s(&cwrd, _RC_NEAR, _MCW_RC);
+ }
+#else
+ static inline void set_float_rounding(void){
+ //do nothing
+ }
+#endif
+
+void volk_cpu_init() {
+ #for $arch in $archs
+ volk_cpu.has_$arch.name = &i_can_has_$arch.name;
+ #end for
+ set_float_rounding();
+}
+
+unsigned int volk_get_lvarch() {
+ unsigned int retval = 0;
+ volk_cpu_init();
+ #for $arch in $archs
+ retval += volk_cpu.has_$(arch.name)() << LV_$(arch.name.upper());
+ #end for
+ return retval;
+}
diff --git a/volk/tmpl/volk_cpu.tmpl.h b/volk/tmpl/volk_cpu.tmpl.h
new file mode 100644
index 000000000..4d66512e1
--- /dev/null
+++ b/volk/tmpl/volk_cpu.tmpl.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2011-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.
+ */
+
+#ifndef INCLUDED_VOLK_CPU_H
+#define INCLUDED_VOLK_CPU_H
+
+#include <volk/volk_common.h>
+
+__VOLK_DECL_BEGIN
+
+struct VOLK_CPU {
+ #for $arch in $archs
+ int (*has_$arch.name) ();
+ #end for
+};
+
+extern struct VOLK_CPU volk_cpu;
+
+void volk_cpu_init ();
+unsigned int volk_get_lvarch ();
+
+__VOLK_DECL_END
+
+#endif /*INCLUDED_VOLK_CPU_H*/
diff --git a/volk/tmpl/volk_machine_xxx.tmpl.c b/volk/tmpl/volk_machine_xxx.tmpl.c
new file mode 100644
index 000000000..e405bd693
--- /dev/null
+++ b/volk/tmpl/volk_machine_xxx.tmpl.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2011-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.
+ */
+
+#set $this_machine = $machine_dict[$args[0]]
+#set $arch_names = $this_machine.arch_names
+
+#for $arch in $this_machine.archs
+#define LV_HAVE_$(arch.name.upper()) 1
+#end for
+
+#include <volk/volk_common.h>
+#include "volk_machines.h"
+#include <volk/volk_config_fixed.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#for $kern in $kernels
+#include <volk/$(kern.name).h>
+#end for
+
+########################################################################
+#def make_arch_have_list($archs)
+$(' | '.join(['(1 << LV_%s)'%a.name.upper() for a in $archs]))#slurp
+#end def
+
+########################################################################
+#def make_tag_str_list($tags)
+{$(', '.join(['"%s"'%a for a in $tags]))}#slurp
+#end def
+
+########################################################################
+#def make_tag_have_list($deps)
+{$(', '.join([' | '.join(['(1 << LV_%s)'%a.upper() for a in d]) for d in $deps]))}#slurp
+#end def
+
+########################################################################
+#def make_tag_kern_list($name, $tags)
+{$(', '.join(['%s_%s'%($name, a) for a in $tags]))}#slurp
+#end def
+
+struct volk_machine volk_machine_$(this_machine.name) = {
+ $make_arch_have_list($this_machine.archs),
+ "$this_machine.name",
+ $this_machine.alignment,
+ #for $kern in $kernels
+ #set $taglist, $tagdeps = $kern.get_tags($arch_names)
+ "$kern.name",
+ $make_tag_str_list($taglist),
+ $make_tag_have_list($tagdeps),
+ $make_tag_kern_list($kern.name, $taglist),
+ $(len($taglist)),
+ #end for
+};
diff --git a/volk/tmpl/volk_machines.tmpl.c b/volk/tmpl/volk_machines.tmpl.c
new file mode 100644
index 000000000..57dd03c98
--- /dev/null
+++ b/volk/tmpl/volk_machines.tmpl.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2011-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 <volk/volk_common.h>
+#include <volk/volk_typedefs.h>
+#include "volk_machines.h"
+
+struct volk_machine *volk_machines[] = {
+#for $machine in $machines
+#ifdef LV_MACHINE_$(machine.name.upper())
+&volk_machine_$(machine.name),
+#endif
+#end for
+};
+
+unsigned int n_volk_machines = sizeof(volk_machines)/sizeof(*volk_machines);
diff --git a/volk/tmpl/volk_machines.tmpl.h b/volk/tmpl/volk_machines.tmpl.h
new file mode 100644
index 000000000..b30e600ed
--- /dev/null
+++ b/volk/tmpl/volk_machines.tmpl.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2011-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.
+ */
+
+#ifndef INCLUDED_LIBVOLK_MACHINES_H
+#define INCLUDED_LIBVOLK_MACHINES_H
+
+#include <volk/volk_common.h>
+#include <volk/volk_typedefs.h>
+
+__VOLK_DECL_BEGIN
+
+struct volk_machine {
+ const unsigned int caps; //capabilities (i.e., archs compiled into this machine, in the volk_get_lvarch format)
+ const char *name;
+ const unsigned int alignment; //the maximum byte alignment required for functions in this library
+ #for $kern in $kernels
+ const char *$(kern.name)_name;
+ const char *$(kern.name)_indices[$(len($archs))];
+ const int $(kern.name)_arch_defs[$(len($archs))];
+ const $(kern.pname) $(kern.name)_archs[$(len($archs))];
+ const int $(kern.name)_n_archs;
+ #end for
+};
+
+#for $machine in $machines
+#ifdef LV_MACHINE_$(machine.name.upper())
+extern struct volk_machine volk_machine_$(machine.name);
+#endif
+#end for
+
+__VOLK_DECL_END
+
+#endif //INCLUDED_LIBVOLK_MACHINES_H
diff --git a/volk/tmpl/volk_typedefs.tmpl.h b/volk/tmpl/volk_typedefs.tmpl.h
new file mode 100644
index 000000000..52a87242f
--- /dev/null
+++ b/volk/tmpl/volk_typedefs.tmpl.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2011-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.
+ */
+
+#ifndef INCLUDED_VOLK_TYPEDEFS
+#define INCLUDED_VOLK_TYPEDEFS
+
+#include <inttypes.h>
+#include <volk/volk_complex.h>
+
+#for $kern in $kernels
+typedef $kern.rettype (*$(kern.pname))($kern.arglist_defs);
+#end for
+
+#endif /*INCLUDED_VOLK_TYPEDEFS*/