├── CMakeLists.txt ├── MANIFEST.md ├── apps └── CMakeLists.txt ├── cmake ├── Modules │ ├── CMakeParseArgumentsCopy.cmake │ ├── FindCppUnit.cmake │ ├── FindGnuradioRuntime.cmake │ ├── FindUHD.cmake │ ├── GrMiscUtils.cmake │ ├── GrPlatform.cmake │ ├── GrPython.cmake │ ├── GrSwig.cmake │ ├── GrTest.cmake │ ├── UseSWIG.cmake │ └── nwrConfig.cmake └── cmake_uninstall.cmake.in ├── docs ├── CMakeLists.txt ├── README.nwr ├── clock_loop.pdf ├── clock_loop.tex └── doxygen │ ├── CMakeLists.txt │ ├── Doxyfile.in │ ├── Doxyfile.swig_doc.in │ ├── doxyxml │ ├── __init__.py │ ├── base.py │ ├── doxyindex.py │ ├── generated │ │ ├── __init__.py │ │ ├── compound.py │ │ ├── compoundsuper.py │ │ ├── index.py │ │ └── indexsuper.py │ └── text.py │ ├── other │ ├── group_defs.dox │ └── main_page.dox │ └── swig_doc.py ├── examples ├── README ├── nwr_band_162487500Hz_250ksps_201611091145.c32.gz ├── nwr_fg.grc ├── nwr_file_prune.grc └── rtl_sdr_capture_convert.grc ├── grc ├── CMakeLists.txt ├── nwr_add_tag_value_ff.xml ├── nwr_burst_detect_and_tag.xml ├── nwr_correction_estimator_ff.xml ├── nwr_lms_da_equalizer_ff.xml ├── nwr_multiply_by_tag_value_ff.xml ├── nwr_pll_refout_cc.xml └── nwr_same_burst_decoder.xml ├── include └── nwr │ ├── CMakeLists.txt │ ├── add_tag_value_ff.h │ ├── api.h │ ├── burst_detect_and_tag.h │ ├── correction_estimator_ff.h │ ├── lms_da_equalizer_ff.h │ ├── multiply_by_tag_value_ff.h │ ├── pll_refout_cc.h │ └── same_burst_decoder.h ├── lib ├── CMakeLists.txt ├── add_tag_value_ff_impl.cc ├── add_tag_value_ff_impl.h ├── burst_detect_and_tag_impl.cc ├── burst_detect_and_tag_impl.h ├── correction_estimator_ff_impl.cc ├── correction_estimator_ff_impl.h ├── lms_da_equalizer_ff_impl.cc ├── lms_da_equalizer_ff_impl.h ├── multiply_by_tag_value_ff_impl.cc ├── multiply_by_tag_value_ff_impl.h ├── pll_refout_cc_impl.cc ├── pll_refout_cc_impl.h ├── qa_nwr.cc ├── qa_nwr.h ├── same_burst_decoder_impl.cc ├── same_burst_decoder_impl.h └── test_nwr.cc ├── python ├── CMakeLists.txt ├── __init__.py ├── build_utils.py ├── build_utils_codes.py ├── qa_add_tag_value_ff.py ├── qa_burst_detect_and_tag.py ├── qa_correction_estimator_ff.py ├── qa_lms_da_equalizer_ff.py ├── qa_multiply_by_tag_value_ff.py ├── qa_pll_refout_cc.py └── qa_same_burst_decoder.py └── swig ├── CMakeLists.txt └── nwr_swig.i /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011,2012,2014,2016 Free Software Foundation, Inc. 2 | # Copyright (C) 2016 Andy Walls 3 | # 4 | # This file was automatically generated by gr_modtool from GNU Radio 5 | # and subsequently hand edited by Andy Walls 6 | # 7 | # GNU Radio is free software; you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation; either version 3, or (at your option) 10 | # any later version. 11 | # 12 | # GNU Radio is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with GNU Radio; see the file COPYING. If not, write to 19 | # the Free Software Foundation, Inc., 51 Franklin Street, 20 | # Boston, MA 02110-1301, USA. 21 | 22 | ######################################################################## 23 | # Project setup 24 | ######################################################################## 25 | cmake_minimum_required(VERSION 2.6) 26 | project(gr-nwr CXX C) 27 | enable_testing() 28 | 29 | #install to PyBOMBS target prefix if defined 30 | if(DEFINED ENV{PYBOMBS_PREFIX}) 31 | set(CMAKE_INSTALL_PREFIX $ENV{PYBOMBS_PREFIX}) 32 | message(STATUS "PyBOMBS installed GNU Radio. Setting CMAKE_INSTALL_PREFIX to $ENV{PYBOMBS_PREFIX}") 33 | endif() 34 | 35 | #select the release build type by default to get optimization flags 36 | if(NOT CMAKE_BUILD_TYPE) 37 | set(CMAKE_BUILD_TYPE "Release") 38 | message(STATUS "Build type not specified: defaulting to release.") 39 | endif(NOT CMAKE_BUILD_TYPE) 40 | set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "") 41 | 42 | #make sure our local CMake Modules path comes first 43 | list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules) 44 | 45 | # Set the version information here 46 | set(VERSION_INFO_MAJOR_VERSION 1) 47 | set(VERSION_INFO_API_COMPAT 0) 48 | set(VERSION_INFO_MINOR_VERSION 0) 49 | set(VERSION_INFO_MAINT_VERSION git) 50 | 51 | ######################################################################## 52 | # Compiler specific setup 53 | ######################################################################## 54 | if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) 55 | #http://gcc.gnu.org/wiki/Visibility 56 | add_definitions(-fvisibility=hidden) 57 | endif() 58 | 59 | ######################################################################## 60 | # Find boost 61 | ######################################################################## 62 | if(UNIX AND EXISTS "/usr/lib64") 63 | list(APPEND BOOST_LIBRARYDIR "/usr/lib64") #fedora 64-bit fix 64 | endif(UNIX AND EXISTS "/usr/lib64") 65 | set(Boost_ADDITIONAL_VERSIONS 66 | "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" 67 | "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" 68 | "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" 69 | "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" 70 | "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" 71 | "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" 72 | "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" 73 | ) 74 | find_package(Boost "1.35" COMPONENTS filesystem system) 75 | 76 | if(NOT Boost_FOUND) 77 | message(FATAL_ERROR "Boost required to compile nwr") 78 | endif() 79 | 80 | ######################################################################## 81 | # Find UHD 82 | ######################################################################## 83 | find_package(UHD) 84 | 85 | if(NOT UHD_FOUND) 86 | message(FATAL_ERROR "UHD required to compile nwr") 87 | endif() 88 | 89 | ######################################################################## 90 | # Install directories 91 | ######################################################################## 92 | include(GrPlatform) #define LIB_SUFFIX 93 | set(GR_RUNTIME_DIR bin) 94 | set(GR_LIBRARY_DIR lib${LIB_SUFFIX}) 95 | set(GR_INCLUDE_DIR include/nwr) 96 | set(GR_DATA_DIR share) 97 | set(GR_PKG_DATA_DIR ${GR_DATA_DIR}/${CMAKE_PROJECT_NAME}) 98 | set(GR_DOC_DIR ${GR_DATA_DIR}/doc) 99 | set(GR_PKG_DOC_DIR ${GR_DOC_DIR}/${CMAKE_PROJECT_NAME}) 100 | set(GR_CONF_DIR etc) 101 | set(GR_PKG_CONF_DIR ${GR_CONF_DIR}/${CMAKE_PROJECT_NAME}/conf.d) 102 | set(GR_LIBEXEC_DIR libexec) 103 | set(GR_PKG_LIBEXEC_DIR ${GR_LIBEXEC_DIR}/${CMAKE_PROJECT_NAME}) 104 | set(GRC_BLOCKS_DIR ${GR_PKG_DATA_DIR}/grc/blocks) 105 | 106 | ######################################################################## 107 | # On Apple only, set install name and use rpath correctly, if not already set 108 | ######################################################################## 109 | if(APPLE) 110 | if(NOT CMAKE_INSTALL_NAME_DIR) 111 | set(CMAKE_INSTALL_NAME_DIR 112 | ${CMAKE_INSTALL_PREFIX}/${GR_LIBRARY_DIR} CACHE 113 | PATH "Library Install Name Destination Directory" FORCE) 114 | endif(NOT CMAKE_INSTALL_NAME_DIR) 115 | if(NOT CMAKE_INSTALL_RPATH) 116 | set(CMAKE_INSTALL_RPATH 117 | ${CMAKE_INSTALL_PREFIX}/${GR_LIBRARY_DIR} CACHE 118 | PATH "Library Install RPath" FORCE) 119 | endif(NOT CMAKE_INSTALL_RPATH) 120 | if(NOT CMAKE_BUILD_WITH_INSTALL_RPATH) 121 | set(CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE 122 | BOOL "Do Build Using Library Install RPath" FORCE) 123 | endif(NOT CMAKE_BUILD_WITH_INSTALL_RPATH) 124 | endif(APPLE) 125 | 126 | ######################################################################## 127 | # Find gnuradio build dependencies 128 | ######################################################################## 129 | find_package(CppUnit) 130 | find_package(Doxygen) 131 | 132 | # Search for GNU Radio and its components and versions. Add any 133 | # components required to the list of GR_REQUIRED_COMPONENTS (in all 134 | # caps such as FILTER or FFT) and change the version to the minimum 135 | # API compatible version required. 136 | set(GR_REQUIRED_COMPONENTS RUNTIME FILTER BLOCKS VOLK) 137 | find_package(Gnuradio "3.7.2" REQUIRED) 138 | list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules) 139 | include(GrVersion) 140 | 141 | if(NOT CPPUNIT_FOUND) 142 | message(FATAL_ERROR "CppUnit required to compile nwr") 143 | endif() 144 | 145 | ######################################################################## 146 | # Setup doxygen option 147 | ######################################################################## 148 | if(DOXYGEN_FOUND) 149 | option(ENABLE_DOXYGEN "Build docs using Doxygen" ON) 150 | else(DOXYGEN_FOUND) 151 | option(ENABLE_DOXYGEN "Build docs using Doxygen" OFF) 152 | endif(DOXYGEN_FOUND) 153 | 154 | ######################################################################## 155 | # Setup the include and linker paths 156 | ######################################################################## 157 | include_directories( 158 | ${CMAKE_SOURCE_DIR}/lib 159 | ${CMAKE_SOURCE_DIR}/include 160 | ${CMAKE_BINARY_DIR}/lib 161 | ${CMAKE_BINARY_DIR}/include 162 | ${Boost_INCLUDE_DIRS} 163 | ${UHD_INCLUDE_DIRS} 164 | ${CPPUNIT_INCLUDE_DIRS} 165 | ${GNURADIO_ALL_INCLUDE_DIRS} 166 | ) 167 | 168 | link_directories( 169 | ${Boost_LIBRARY_DIRS} 170 | ${UHD_LIBRARY_DIRS} 171 | ${CPPUNIT_LIBRARY_DIRS} 172 | ${GNURADIO_RUNTIME_LIBRARY_DIRS} 173 | ) 174 | 175 | # Set component parameters 176 | set(GR_NWR_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include CACHE INTERNAL "" FORCE) 177 | set(GR_NWR_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/swig CACHE INTERNAL "" FORCE) 178 | 179 | ######################################################################## 180 | # Create uninstall target 181 | ######################################################################## 182 | configure_file( 183 | ${CMAKE_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in 184 | ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake 185 | @ONLY) 186 | 187 | add_custom_target(uninstall 188 | ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake 189 | ) 190 | 191 | ######################################################################## 192 | # Add subdirectories 193 | ######################################################################## 194 | add_subdirectory(include/nwr) 195 | add_subdirectory(lib) 196 | add_subdirectory(swig) 197 | add_subdirectory(python) 198 | add_subdirectory(grc) 199 | add_subdirectory(apps) 200 | add_subdirectory(docs) 201 | 202 | ######################################################################## 203 | # Install cmake search helper for this library 204 | ######################################################################## 205 | if(NOT CMAKE_MODULES_DIR) 206 | set(CMAKE_MODULES_DIR lib${LIB_SUFFIX}/cmake) 207 | endif(NOT CMAKE_MODULES_DIR) 208 | 209 | install(FILES cmake/Modules/nwrConfig.cmake 210 | DESTINATION ${CMAKE_MODULES_DIR}/nwr 211 | ) 212 | -------------------------------------------------------------------------------- /MANIFEST.md: -------------------------------------------------------------------------------- 1 | title: The NWR OOT Module 2 | brief: NOAA Weather Radio receiver and SAME demodulator 3 | tags: # Tags are arbitrary, but look at CGRAN what other authors are using 4 | - sdr 5 | - NWR 6 | - WX 7 | - NOAA 8 | - weather 9 | - SAME 10 | - VHF 11 | - FM 12 | - AFSK 13 | author: 14 | - Andy Walls 15 | copyright_owner: 16 | - Andy Walls 17 | - Free Software Foundation 18 | - KitwarePublic Wiki authors (some content generated by gr_modtool) 19 | - Kitware Inc. (some content generated by gr_modtool) 20 | - Alexander Neundorf (some content generated by gr_modtool) 21 | - Mathieu Malaterre (some content generated by gr_modtool) 22 | - Alexander Neundorf (some content generated by gr_modtool) 23 | - John P. Chandler (praxis.f) 24 | license: Refer to license markings in the individual files. No grant of license for any unmarked files and/or files that do not state a license. 25 | repo: https://github.com/awalls-cx18/gr-nwr.git 26 | website: https://github.com/awalls-cx18/gr-nwr 27 | #icon: # Put a URL to a square image here that will be used as an icon on CGRAN 28 | --- 29 | gr-nwr provides an example NOAA Weather Radio receiver flowgraph for 30 | receiving and demodulating NWR audio and SAME digitial data from any 31 | single channel of WX1 through WX7 (162.400 - 162.550 MHz). 32 | A description of the NWR service can be found here: 33 | http://www.nws.noaa.gov/nwr 34 | 35 | NWR audio is narrowband FM with a 5 kHz deviation and the channels use 25 kHz 36 | channel spacing. The audio only goes to about 3 kHz and uses pre-emphasis. 37 | 38 | The SAME digital encoding is AFSK in the demodulated audio. SAME digitally 39 | encodes emergency weather warnings. These digital messages immediately 40 | precede the audio for the emergency weather warnings. 41 | Detailed specifications on SAME can be found here: 42 | http://www.nws.noaa.gov/nwr/info/nwrsame.html 43 | http://www.nws.noaa.gov/directives/sym/pd01017012curr.pdf 44 | 45 | ***WARNING*** 46 | DO NOT USE THIS IMPLEMENTATION FOR CRITICAL OR SAFETY OF LIFE PURPOSES. 47 | It's just a demonstration and comes with NO WARRANTIES. 48 | 49 | If you need reliable NWR warnings, buy a National Weather Serive approved 50 | radio from one of these manufacturers or resellers: 51 | http://www.nws.noaa.gov/nwr/info/nwrrcvr.html#consumers 52 | -------------------------------------------------------------------------------- /apps/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file was automatically generated by gr_modtool from GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | include(GrPython) 21 | 22 | GR_PYTHON_INSTALL( 23 | PROGRAMS 24 | DESTINATION bin 25 | ) 26 | -------------------------------------------------------------------------------- /cmake/Modules/CMakeParseArgumentsCopy.cmake: -------------------------------------------------------------------------------- 1 | # This file was automatically generated by gr_modtool from GNU Radio 2 | 3 | # CMAKE_PARSE_ARGUMENTS( args...) 4 | # 5 | # CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions for 6 | # parsing the arguments given to that macro or function. 7 | # It processes the arguments and defines a set of variables which hold the 8 | # values of the respective options. 9 | # 10 | # The argument contains all options for the respective macro, 11 | # i.e. keywords which can be used when calling the macro without any value 12 | # following, like e.g. the OPTIONAL keyword of the install() command. 13 | # 14 | # The argument contains all keywords for this macro 15 | # which are followed by one value, like e.g. DESTINATION keyword of the 16 | # install() command. 17 | # 18 | # The argument contains all keywords for this macro 19 | # which can be followed by more than one value, like e.g. the TARGETS or 20 | # FILES keywords of the install() command. 21 | # 22 | # When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the 23 | # keywords listed in , and 24 | # a variable composed of the given 25 | # followed by "_" and the name of the respective keyword. 26 | # These variables will then hold the respective value from the argument list. 27 | # For the keywords this will be TRUE or FALSE. 28 | # 29 | # All remaining arguments are collected in a variable 30 | # _UNPARSED_ARGUMENTS, this can be checked afterwards to see whether 31 | # your macro was called with unrecognized parameters. 32 | # 33 | # As an example here a my_install() macro, which takes similar arguments as the 34 | # real install() command: 35 | # 36 | # function(MY_INSTALL) 37 | # set(options OPTIONAL FAST) 38 | # set(oneValueArgs DESTINATION RENAME) 39 | # set(multiValueArgs TARGETS CONFIGURATIONS) 40 | # cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) 41 | # ... 42 | # 43 | # Assume my_install() has been called like this: 44 | # my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub) 45 | # 46 | # After the cmake_parse_arguments() call the macro will have set the following 47 | # variables: 48 | # MY_INSTALL_OPTIONAL = TRUE 49 | # MY_INSTALL_FAST = FALSE (this option was not used when calling my_install() 50 | # MY_INSTALL_DESTINATION = "bin" 51 | # MY_INSTALL_RENAME = "" (was not used) 52 | # MY_INSTALL_TARGETS = "foo;bar" 53 | # MY_INSTALL_CONFIGURATIONS = "" (was not used) 54 | # MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL" 55 | # 56 | # You can the continue and process these variables. 57 | # 58 | # Keywords terminate lists of values, e.g. if directly after a one_value_keyword 59 | # another recognized keyword follows, this is interpreted as the beginning of 60 | # the new option. 61 | # E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in 62 | # MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would 63 | # be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor. 64 | 65 | #============================================================================= 66 | # Copyright 2010 Alexander Neundorf 67 | # 68 | # Distributed under the OSI-approved BSD License (the "License"); 69 | # see accompanying file Copyright.txt for details. 70 | # 71 | # This software is distributed WITHOUT ANY WARRANTY; without even the 72 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 73 | # See the License for more information. 74 | #============================================================================= 75 | # (To distribute this file outside of CMake, substitute the full 76 | # License text for the above reference.) 77 | # 78 | # (The following is the full license text from 79 | # https://github.com/Kitware/CMake/blob/master/Copyright.txt 80 | # to be substituted for the above reference:) 81 | # 82 | # CMake - Cross Platform Makefile Generator 83 | # Copyright 2000-2016 Kitware, Inc. and Contributors 84 | # All rights reserved. 85 | # 86 | # Redistribution and use in source and binary forms, with or without 87 | # modification, are permitted provided that the following conditions 88 | # are met: 89 | # 90 | # * Redistributions of source code must retain the above copyright 91 | # notice, this list of conditions and the following disclaimer. 92 | # 93 | # * Redistributions in binary form must reproduce the above copyright 94 | # notice, this list of conditions and the following disclaimer in the 95 | # documentation and/or other materials provided with the distribution. 96 | # 97 | # * Neither the name of Kitware, Inc. nor the names of Contributors 98 | # may be used to endorse or promote products derived from this 99 | # software without specific prior written permission. 100 | # 101 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 102 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 103 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 104 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 105 | # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 106 | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 107 | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 108 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 109 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 110 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 111 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 112 | #============================================================================= 113 | 114 | 115 | if(__CMAKE_PARSE_ARGUMENTS_INCLUDED) 116 | return() 117 | endif() 118 | set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE) 119 | 120 | 121 | function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames) 122 | # first set all result variables to empty/FALSE 123 | foreach(arg_name ${_singleArgNames} ${_multiArgNames}) 124 | set(${prefix}_${arg_name}) 125 | endforeach(arg_name) 126 | 127 | foreach(option ${_optionNames}) 128 | set(${prefix}_${option} FALSE) 129 | endforeach(option) 130 | 131 | set(${prefix}_UNPARSED_ARGUMENTS) 132 | 133 | set(insideValues FALSE) 134 | set(currentArgName) 135 | 136 | # now iterate over all arguments and fill the result variables 137 | foreach(currentArg ${ARGN}) 138 | list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword 139 | list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword 140 | list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword 141 | 142 | if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1) 143 | if(insideValues) 144 | if("${insideValues}" STREQUAL "SINGLE") 145 | set(${prefix}_${currentArgName} ${currentArg}) 146 | set(insideValues FALSE) 147 | elseif("${insideValues}" STREQUAL "MULTI") 148 | list(APPEND ${prefix}_${currentArgName} ${currentArg}) 149 | endif() 150 | else(insideValues) 151 | list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg}) 152 | endif(insideValues) 153 | else() 154 | if(NOT ${optionIndex} EQUAL -1) 155 | set(${prefix}_${currentArg} TRUE) 156 | set(insideValues FALSE) 157 | elseif(NOT ${singleArgIndex} EQUAL -1) 158 | set(currentArgName ${currentArg}) 159 | set(${prefix}_${currentArgName}) 160 | set(insideValues "SINGLE") 161 | elseif(NOT ${multiArgIndex} EQUAL -1) 162 | set(currentArgName ${currentArg}) 163 | set(${prefix}_${currentArgName}) 164 | set(insideValues "MULTI") 165 | endif() 166 | endif() 167 | 168 | endforeach(currentArg) 169 | 170 | # propagate the result variables to the caller: 171 | foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames}) 172 | set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE) 173 | endforeach(arg_name) 174 | set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE) 175 | 176 | endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs) 177 | -------------------------------------------------------------------------------- /cmake/Modules/FindCppUnit.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2011-2013 Free Software Foundation, Inc. 2 | # 3 | # This file was automatically generated by gr_modtool from GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | INCLUDE(FindPkgConfig) 21 | PKG_CHECK_MODULES(PC_CPPUNIT "cppunit") 22 | 23 | FIND_PATH(CPPUNIT_INCLUDE_DIRS 24 | NAMES cppunit/TestCase.h 25 | HINTS ${PC_CPPUNIT_INCLUDE_DIR} 26 | ${CMAKE_INSTALL_PREFIX}/include 27 | PATHS 28 | /usr/local/include 29 | /usr/include 30 | ) 31 | 32 | FIND_LIBRARY(CPPUNIT_LIBRARIES 33 | NAMES cppunit 34 | HINTS ${PC_CPPUNIT_LIBDIR} 35 | ${CMAKE_INSTALL_PREFIX}/lib 36 | ${CMAKE_INSTALL_PREFIX}/lib64 37 | PATHS 38 | ${CPPUNIT_INCLUDE_DIRS}/../lib 39 | /usr/local/lib 40 | /usr/lib 41 | ) 42 | 43 | LIST(APPEND CPPUNIT_LIBRARIES ${CMAKE_DL_LIBS}) 44 | 45 | INCLUDE(FindPackageHandleStandardArgs) 46 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(CPPUNIT DEFAULT_MSG CPPUNIT_LIBRARIES CPPUNIT_INCLUDE_DIRS) 47 | MARK_AS_ADVANCED(CPPUNIT_LIBRARIES CPPUNIT_INCLUDE_DIRS) 48 | -------------------------------------------------------------------------------- /cmake/Modules/FindGnuradioRuntime.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2013 Free Software Foundation, Inc. 2 | # 3 | # This file was automatically generated by gr_modtool from GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | INCLUDE(FindPkgConfig) 21 | PKG_CHECK_MODULES(PC_GNURADIO_RUNTIME gnuradio-runtime) 22 | 23 | if(PC_GNURADIO_RUNTIME_FOUND) 24 | # look for include files 25 | FIND_PATH( 26 | GNURADIO_RUNTIME_INCLUDE_DIRS 27 | NAMES gnuradio/top_block.h 28 | HINTS $ENV{GNURADIO_RUNTIME_DIR}/include 29 | ${PC_GNURADIO_RUNTIME_INCLUDE_DIRS} 30 | ${CMAKE_INSTALL_PREFIX}/include 31 | PATHS /usr/local/include 32 | /usr/include 33 | ) 34 | 35 | # look for libs 36 | FIND_LIBRARY( 37 | GNURADIO_RUNTIME_LIBRARIES 38 | NAMES gnuradio-runtime 39 | HINTS $ENV{GNURADIO_RUNTIME_DIR}/lib 40 | ${PC_GNURADIO_RUNTIME_LIBDIR} 41 | ${CMAKE_INSTALL_PREFIX}/lib/ 42 | ${CMAKE_INSTALL_PREFIX}/lib64/ 43 | PATHS /usr/local/lib 44 | /usr/local/lib64 45 | /usr/lib 46 | /usr/lib64 47 | ) 48 | 49 | set(GNURADIO_RUNTIME_FOUND ${PC_GNURADIO_RUNTIME_FOUND}) 50 | endif(PC_GNURADIO_RUNTIME_FOUND) 51 | 52 | INCLUDE(FindPackageHandleStandardArgs) 53 | # do not check GNURADIO_RUNTIME_INCLUDE_DIRS, is not set when default include path us used. 54 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_RUNTIME DEFAULT_MSG GNURADIO_RUNTIME_LIBRARIES) 55 | MARK_AS_ADVANCED(GNURADIO_RUNTIME_LIBRARIES GNURADIO_RUNTIME_INCLUDE_DIRS) 56 | -------------------------------------------------------------------------------- /cmake/Modules/FindUHD.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2011-2014 Free Software Foundation, Inc. 2 | # 3 | # This file was copied from GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | ####################################################################### 21 | # Find the library for the USRP Hardware Driver 22 | ######################################################################## 23 | 24 | # make this file non-reentrant within the current context 25 | if(__INCLUDED_FIND_UHD_CMAKE) 26 | return() 27 | endif() 28 | set(__INCLUDED_FIND_UHD_CMAKE TRUE) 29 | 30 | # First check to see if UHD installed its own CMake files 31 | 32 | # save the current MODULE path 33 | set(SAVED_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}) 34 | 35 | # clear the current MODULE path; uses system paths only 36 | unset(CMAKE_MODULE_PATH) 37 | 38 | # try to find UHD via the provided parameters, 39 | # handle REQUIRED internally later 40 | unset(UHD_FOUND) 41 | 42 | # set that UHDConfig.cmake was not used. Have to use the ENV, since 43 | # UHDConfigVersion does not allow CACHE changes and UHDConfig might 44 | # not allow CACHE changes. 45 | set(ENV{UHD_CONFIG_USED} FALSE) 46 | set(ENV{UHD_CONFIG_VERSION_USED} FALSE) 47 | 48 | # was the version specified? 49 | unset(LOCAL_UHD_FIND_VERSION) 50 | if(UHD_FIND_VERSION) 51 | set(LOCAL_UHD_FIND_VERSION ${UHD_FIND_VERSION}) 52 | endif(UHD_FIND_VERSION) 53 | 54 | # was EXACT specified? 55 | unset(LOCAL_UHD_FIND_VERSION_EXACT) 56 | if(UHD_FIND_VERSION_EXACT) 57 | set(LOCAL_UHD_FIND_VERSION_EXACT "EXACT") 58 | endif(UHD_FIND_VERSION_EXACT) 59 | 60 | # try to find UHDConfig using the desired parameters; 61 | # UHDConfigVersion will catch a pass-through version bug ... 62 | find_package( 63 | UHD ${LOCAL_UHD_FIND_VERSION} 64 | ${LOCAL_UHD_FIND_VERSION_EXACT} QUIET 65 | ) 66 | 67 | # restore CMAKE_MODULE_PATH 68 | set(CMAKE_MODULE_PATH ${SAVED_CMAKE_MODULE_PATH}) 69 | 70 | # check if UHDConfig was used above 71 | if(NOT "$ENV{UHD_CONFIG_VERSION_USED}" STREQUAL "TRUE") 72 | 73 | # Not used; try the "old" method (not as robust) 74 | 75 | include(FindPkgConfig) 76 | pkg_check_modules(PC_UHD uhd) 77 | 78 | find_path( 79 | UHD_INCLUDE_DIRS 80 | NAMES uhd/config.hpp 81 | HINTS $ENV{UHD_DIR}/include 82 | ${PC_UHD_INCLUDEDIR} 83 | PATHS /usr/local/include 84 | /usr/include 85 | ) 86 | 87 | find_library( 88 | UHD_LIBRARIES 89 | NAMES uhd 90 | HINTS $ENV{UHD_DIR}/lib 91 | ${PC_UHD_LIBDIR} 92 | PATHS /usr/local/lib 93 | /usr/lib 94 | ) 95 | endif(NOT "$ENV{UHD_CONFIG_VERSION_USED}" STREQUAL "TRUE") 96 | 97 | if(UHD_LIBRARIES AND UHD_INCLUDE_DIRS) 98 | 99 | # if UHDConfig set UHD_FOUND==TRUE, then these have already been 100 | # done, but done quietly. It does not hurt to redo them here. 101 | 102 | include(FindPackageHandleStandardArgs) 103 | find_package_handle_standard_args(UHD DEFAULT_MSG UHD_LIBRARIES UHD_INCLUDE_DIRS) 104 | mark_as_advanced(UHD_LIBRARIES UHD_INCLUDE_DIRS) 105 | 106 | elseif(UHD_FIND_REQUIRED) 107 | if($ENV{UHD_CONFIG_VERSION_USED} AND NOT $ENV{UHD_CONFIG_USED}) 108 | message(FATAL_ERROR "The found UHD version ($ENV{UHD_PACKAGE_VERSION}) is not compatible with the version required (${UHD_FIND_VERSION}).") 109 | else() 110 | message(FATAL_ERROR "UHD is required, but was not found.") 111 | endif() 112 | endif() 113 | -------------------------------------------------------------------------------- /cmake/Modules/GrPlatform.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file was automatically generated by gr_modtool from GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | if(DEFINED __INCLUDED_GR_PLATFORM_CMAKE) 21 | return() 22 | endif() 23 | set(__INCLUDED_GR_PLATFORM_CMAKE TRUE) 24 | 25 | ######################################################################## 26 | # Setup additional defines for OS types 27 | ######################################################################## 28 | if(CMAKE_SYSTEM_NAME STREQUAL "Linux") 29 | set(LINUX TRUE) 30 | endif() 31 | 32 | if(NOT CMAKE_CROSSCOMPILING AND LINUX AND EXISTS "/etc/debian_version") 33 | set(DEBIAN TRUE) 34 | endif() 35 | 36 | if(NOT CMAKE_CROSSCOMPILING AND LINUX AND EXISTS "/etc/redhat-release") 37 | set(REDHAT TRUE) 38 | endif() 39 | 40 | if(NOT CMAKE_CROSSCOMPILING AND LINUX AND EXISTS "/etc/slackware-version") 41 | set(SLACKWARE TRUE) 42 | endif() 43 | 44 | ######################################################################## 45 | # when the library suffix should be 64 (applies to redhat linux family) 46 | ######################################################################## 47 | if (REDHAT OR SLACKWARE) 48 | set(LIB64_CONVENTION TRUE) 49 | endif() 50 | 51 | if(NOT DEFINED LIB_SUFFIX AND LIB64_CONVENTION AND CMAKE_SYSTEM_PROCESSOR MATCHES "64$") 52 | set(LIB_SUFFIX 64) 53 | endif() 54 | 55 | ######################################################################## 56 | # Detect /lib versus /lib64 57 | ######################################################################## 58 | if (CMAKE_INSTALL_LIBDIR MATCHES lib64) 59 | set(LIB_SUFFIX 64) 60 | endif() 61 | 62 | set(LIB_SUFFIX ${LIB_SUFFIX} CACHE STRING "lib directory suffix") 63 | -------------------------------------------------------------------------------- /cmake/Modules/GrPython.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2010-2011 Free Software Foundation, Inc. 2 | # 3 | # This file was automatically generated by gr_modtool from GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | if(DEFINED __INCLUDED_GR_PYTHON_CMAKE) 21 | return() 22 | endif() 23 | set(__INCLUDED_GR_PYTHON_CMAKE TRUE) 24 | 25 | ######################################################################## 26 | # Setup the python interpreter: 27 | # This allows the user to specify a specific interpreter, 28 | # or finds the interpreter via the built-in cmake module. 29 | ######################################################################## 30 | #this allows the user to override PYTHON_EXECUTABLE 31 | if(PYTHON_EXECUTABLE) 32 | 33 | set(PYTHONINTERP_FOUND TRUE) 34 | 35 | #otherwise if not set, try to automatically find it 36 | else(PYTHON_EXECUTABLE) 37 | 38 | #use the built-in find script 39 | find_package(PythonInterp 2) 40 | 41 | #and if that fails use the find program routine 42 | if(NOT PYTHONINTERP_FOUND) 43 | find_program(PYTHON_EXECUTABLE NAMES python python2 python2.7 python2.6 python2.5) 44 | if(PYTHON_EXECUTABLE) 45 | set(PYTHONINTERP_FOUND TRUE) 46 | endif(PYTHON_EXECUTABLE) 47 | endif(NOT PYTHONINTERP_FOUND) 48 | 49 | endif(PYTHON_EXECUTABLE) 50 | 51 | if (CMAKE_CROSSCOMPILING) 52 | set(QA_PYTHON_EXECUTABLE "/usr/bin/python") 53 | else (CMAKE_CROSSCOMPILING) 54 | set(QA_PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE}) 55 | endif(CMAKE_CROSSCOMPILING) 56 | 57 | #make the path to the executable appear in the cmake gui 58 | set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter") 59 | set(QA_PYTHON_EXECUTABLE ${QA_PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter for QA tests") 60 | 61 | #make sure we can use -B with python (introduced in 2.6) 62 | if(PYTHON_EXECUTABLE) 63 | execute_process( 64 | COMMAND ${PYTHON_EXECUTABLE} -B -c "" 65 | OUTPUT_QUIET ERROR_QUIET 66 | RESULT_VARIABLE PYTHON_HAS_DASH_B_RESULT 67 | ) 68 | if(PYTHON_HAS_DASH_B_RESULT EQUAL 0) 69 | set(PYTHON_DASH_B "-B") 70 | endif() 71 | endif(PYTHON_EXECUTABLE) 72 | 73 | ######################################################################## 74 | # Check for the existence of a python module: 75 | # - desc a string description of the check 76 | # - mod the name of the module to import 77 | # - cmd an additional command to run 78 | # - have the result variable to set 79 | ######################################################################## 80 | macro(GR_PYTHON_CHECK_MODULE desc mod cmd have) 81 | message(STATUS "") 82 | message(STATUS "Python checking for ${desc}") 83 | execute_process( 84 | COMMAND ${PYTHON_EXECUTABLE} -c " 85 | ######################################### 86 | try: 87 | import ${mod} 88 | assert ${cmd} 89 | except ImportError, AssertionError: exit(-1) 90 | except: pass 91 | #########################################" 92 | RESULT_VARIABLE ${have} 93 | ) 94 | if(${have} EQUAL 0) 95 | message(STATUS "Python checking for ${desc} - found") 96 | set(${have} TRUE) 97 | else(${have} EQUAL 0) 98 | message(STATUS "Python checking for ${desc} - not found") 99 | set(${have} FALSE) 100 | endif(${have} EQUAL 0) 101 | endmacro(GR_PYTHON_CHECK_MODULE) 102 | 103 | ######################################################################## 104 | # Sets the python installation directory GR_PYTHON_DIR 105 | ######################################################################## 106 | if(NOT DEFINED GR_PYTHON_DIR) 107 | execute_process(COMMAND ${PYTHON_EXECUTABLE} -c " 108 | from distutils import sysconfig 109 | print sysconfig.get_python_lib(plat_specific=True, prefix='') 110 | " OUTPUT_VARIABLE GR_PYTHON_DIR OUTPUT_STRIP_TRAILING_WHITESPACE 111 | ) 112 | endif() 113 | file(TO_CMAKE_PATH ${GR_PYTHON_DIR} GR_PYTHON_DIR) 114 | 115 | ######################################################################## 116 | # Create an always-built target with a unique name 117 | # Usage: GR_UNIQUE_TARGET( ) 118 | ######################################################################## 119 | function(GR_UNIQUE_TARGET desc) 120 | file(RELATIVE_PATH reldir ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}) 121 | execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib 122 | unique = hashlib.md5('${reldir}${ARGN}').hexdigest()[:5] 123 | print(re.sub('\\W', '_', '${desc} ${reldir} ' + unique))" 124 | OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE) 125 | add_custom_target(${_target} ALL DEPENDS ${ARGN}) 126 | endfunction(GR_UNIQUE_TARGET) 127 | 128 | ######################################################################## 129 | # Install python sources (also builds and installs byte-compiled python) 130 | ######################################################################## 131 | function(GR_PYTHON_INSTALL) 132 | include(CMakeParseArgumentsCopy) 133 | CMAKE_PARSE_ARGUMENTS(GR_PYTHON_INSTALL "" "DESTINATION;COMPONENT" "FILES;PROGRAMS" ${ARGN}) 134 | 135 | #################################################################### 136 | if(GR_PYTHON_INSTALL_FILES) 137 | #################################################################### 138 | install(${ARGN}) #installs regular python files 139 | 140 | #create a list of all generated files 141 | unset(pysrcfiles) 142 | unset(pycfiles) 143 | unset(pyofiles) 144 | foreach(pyfile ${GR_PYTHON_INSTALL_FILES}) 145 | get_filename_component(pyfile ${pyfile} ABSOLUTE) 146 | list(APPEND pysrcfiles ${pyfile}) 147 | 148 | #determine if this file is in the source or binary directory 149 | file(RELATIVE_PATH source_rel_path ${CMAKE_CURRENT_SOURCE_DIR} ${pyfile}) 150 | string(LENGTH "${source_rel_path}" source_rel_path_len) 151 | file(RELATIVE_PATH binary_rel_path ${CMAKE_CURRENT_BINARY_DIR} ${pyfile}) 152 | string(LENGTH "${binary_rel_path}" binary_rel_path_len) 153 | 154 | #and set the generated path appropriately 155 | if(${source_rel_path_len} GREATER ${binary_rel_path_len}) 156 | set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${binary_rel_path}) 157 | else() 158 | set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${source_rel_path}) 159 | endif() 160 | list(APPEND pycfiles ${pygenfile}c) 161 | list(APPEND pyofiles ${pygenfile}o) 162 | 163 | #ensure generation path exists 164 | get_filename_component(pygen_path ${pygenfile} PATH) 165 | file(MAKE_DIRECTORY ${pygen_path}) 166 | 167 | endforeach(pyfile) 168 | 169 | #the command to generate the pyc files 170 | add_custom_command( 171 | DEPENDS ${pysrcfiles} OUTPUT ${pycfiles} 172 | COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pycfiles} 173 | ) 174 | 175 | #the command to generate the pyo files 176 | add_custom_command( 177 | DEPENDS ${pysrcfiles} OUTPUT ${pyofiles} 178 | COMMAND ${PYTHON_EXECUTABLE} -O ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pyofiles} 179 | ) 180 | 181 | #create install rule and add generated files to target list 182 | set(python_install_gen_targets ${pycfiles} ${pyofiles}) 183 | install(FILES ${python_install_gen_targets} 184 | DESTINATION ${GR_PYTHON_INSTALL_DESTINATION} 185 | COMPONENT ${GR_PYTHON_INSTALL_COMPONENT} 186 | ) 187 | 188 | #################################################################### 189 | elseif(GR_PYTHON_INSTALL_PROGRAMS) 190 | #################################################################### 191 | file(TO_NATIVE_PATH ${PYTHON_EXECUTABLE} pyexe_native) 192 | 193 | if (CMAKE_CROSSCOMPILING) 194 | set(pyexe_native "/usr/bin/env python") 195 | endif() 196 | 197 | foreach(pyfile ${GR_PYTHON_INSTALL_PROGRAMS}) 198 | get_filename_component(pyfile_name ${pyfile} NAME) 199 | get_filename_component(pyfile ${pyfile} ABSOLUTE) 200 | string(REPLACE "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" pyexefile "${pyfile}.exe") 201 | list(APPEND python_install_gen_targets ${pyexefile}) 202 | 203 | get_filename_component(pyexefile_path ${pyexefile} PATH) 204 | file(MAKE_DIRECTORY ${pyexefile_path}) 205 | 206 | add_custom_command( 207 | OUTPUT ${pyexefile} DEPENDS ${pyfile} 208 | COMMAND ${PYTHON_EXECUTABLE} -c 209 | "import re; R=re.compile('^\#!.*$\\n',flags=re.MULTILINE); open('${pyexefile}','w').write('\#!${pyexe_native}\\n'+R.sub('',open('${pyfile}','r').read()))" 210 | COMMENT "Shebangin ${pyfile_name}" 211 | VERBATIM 212 | ) 213 | 214 | #on windows, python files need an extension to execute 215 | get_filename_component(pyfile_ext ${pyfile} EXT) 216 | if(WIN32 AND NOT pyfile_ext) 217 | set(pyfile_name "${pyfile_name}.py") 218 | endif() 219 | 220 | install(PROGRAMS ${pyexefile} RENAME ${pyfile_name} 221 | DESTINATION ${GR_PYTHON_INSTALL_DESTINATION} 222 | COMPONENT ${GR_PYTHON_INSTALL_COMPONENT} 223 | ) 224 | endforeach(pyfile) 225 | 226 | endif() 227 | 228 | GR_UNIQUE_TARGET("pygen" ${python_install_gen_targets}) 229 | 230 | endfunction(GR_PYTHON_INSTALL) 231 | 232 | ######################################################################## 233 | # Write the python helper script that generates byte code files 234 | ######################################################################## 235 | file(WRITE ${CMAKE_BINARY_DIR}/python_compile_helper.py " 236 | import sys, py_compile 237 | files = sys.argv[1:] 238 | srcs, gens = files[:len(files)/2], files[len(files)/2:] 239 | for src, gen in zip(srcs, gens): 240 | py_compile.compile(file=src, cfile=gen, doraise=True) 241 | ") 242 | -------------------------------------------------------------------------------- /cmake/Modules/GrSwig.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2010-2011 Free Software Foundation, Inc. 2 | # 3 | # This file was automatically generated by gr_modtool from GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | if(DEFINED __INCLUDED_GR_SWIG_CMAKE) 21 | return() 22 | endif() 23 | set(__INCLUDED_GR_SWIG_CMAKE TRUE) 24 | 25 | include(GrPython) 26 | 27 | ######################################################################## 28 | # Builds a swig documentation file to be generated into python docstrings 29 | # Usage: GR_SWIG_MAKE_DOCS(output_file input_path input_path....) 30 | # 31 | # Set the following variable to specify extra dependent targets: 32 | # - GR_SWIG_DOCS_SOURCE_DEPS 33 | # - GR_SWIG_DOCS_TARGET_DEPS 34 | ######################################################################## 35 | function(GR_SWIG_MAKE_DOCS output_file) 36 | if(ENABLE_DOXYGEN) 37 | 38 | #setup the input files variable list, quote formated 39 | set(input_files) 40 | unset(INPUT_PATHS) 41 | foreach(input_path ${ARGN}) 42 | if(IS_DIRECTORY ${input_path}) #when input path is a directory 43 | file(GLOB input_path_h_files ${input_path}/*.h) 44 | else() #otherwise its just a file, no glob 45 | set(input_path_h_files ${input_path}) 46 | endif() 47 | list(APPEND input_files ${input_path_h_files}) 48 | set(INPUT_PATHS "${INPUT_PATHS} \"${input_path}\"") 49 | endforeach(input_path) 50 | 51 | #determine the output directory 52 | get_filename_component(name ${output_file} NAME_WE) 53 | get_filename_component(OUTPUT_DIRECTORY ${output_file} PATH) 54 | set(OUTPUT_DIRECTORY ${OUTPUT_DIRECTORY}/${name}_swig_docs) 55 | make_directory(${OUTPUT_DIRECTORY}) 56 | 57 | #generate the Doxyfile used by doxygen 58 | configure_file( 59 | ${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile.swig_doc.in 60 | ${OUTPUT_DIRECTORY}/Doxyfile 61 | @ONLY) 62 | 63 | #Create a dummy custom command that depends on other targets 64 | include(GrMiscUtils) 65 | GR_GEN_TARGET_DEPS(_${name}_tag tag_deps ${GR_SWIG_DOCS_TARGET_DEPS}) 66 | 67 | #call doxygen on the Doxyfile + input headers 68 | add_custom_command( 69 | OUTPUT ${OUTPUT_DIRECTORY}/xml/index.xml 70 | DEPENDS ${input_files} ${GR_SWIG_DOCS_SOURCE_DEPS} ${tag_deps} 71 | COMMAND ${DOXYGEN_EXECUTABLE} ${OUTPUT_DIRECTORY}/Doxyfile 72 | COMMENT "Generating doxygen xml for ${name} docs" 73 | ) 74 | 75 | #call the swig_doc script on the xml files 76 | add_custom_command( 77 | OUTPUT ${output_file} 78 | DEPENDS ${input_files} ${stamp-file} ${OUTPUT_DIRECTORY}/xml/index.xml 79 | COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} 80 | ${CMAKE_SOURCE_DIR}/docs/doxygen/swig_doc.py 81 | ${OUTPUT_DIRECTORY}/xml 82 | ${output_file} 83 | COMMENT "Generating python docstrings for ${name}" 84 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs/doxygen 85 | ) 86 | 87 | else(ENABLE_DOXYGEN) 88 | file(WRITE ${output_file} "\n") #no doxygen -> empty file 89 | endif(ENABLE_DOXYGEN) 90 | endfunction(GR_SWIG_MAKE_DOCS) 91 | 92 | ######################################################################## 93 | # Build a swig target for the common gnuradio use case. Usage: 94 | # GR_SWIG_MAKE(target ifile ifile ifile...) 95 | # 96 | # Set the following variables before calling: 97 | # - GR_SWIG_FLAGS 98 | # - GR_SWIG_INCLUDE_DIRS 99 | # - GR_SWIG_LIBRARIES 100 | # - GR_SWIG_SOURCE_DEPS 101 | # - GR_SWIG_TARGET_DEPS 102 | # - GR_SWIG_DOC_FILE 103 | # - GR_SWIG_DOC_DIRS 104 | ######################################################################## 105 | macro(GR_SWIG_MAKE name) 106 | set(ifiles ${ARGN}) 107 | 108 | # Shimming this in here to take care of a SWIG bug with handling 109 | # vector and vector (on 32-bit machines) and 110 | # vector (on 64-bit machines). Use this to test 111 | # the size of size_t, then set SIZE_T_32 if it's a 32-bit machine 112 | # or not if it's 64-bit. The logic in gr_type.i handles the rest. 113 | INCLUDE(CheckTypeSize) 114 | CHECK_TYPE_SIZE("size_t" SIZEOF_SIZE_T) 115 | CHECK_TYPE_SIZE("unsigned int" SIZEOF_UINT) 116 | if(${SIZEOF_SIZE_T} EQUAL ${SIZEOF_UINT}) 117 | list(APPEND GR_SWIG_FLAGS -DSIZE_T_32) 118 | endif(${SIZEOF_SIZE_T} EQUAL ${SIZEOF_UINT}) 119 | 120 | #do swig doc generation if specified 121 | if(GR_SWIG_DOC_FILE) 122 | set(GR_SWIG_DOCS_SOURCE_DEPS ${GR_SWIG_SOURCE_DEPS}) 123 | list(APPEND GR_SWIG_DOCS_TARGET_DEPS ${GR_SWIG_TARGET_DEPS}) 124 | GR_SWIG_MAKE_DOCS(${GR_SWIG_DOC_FILE} ${GR_SWIG_DOC_DIRS}) 125 | add_custom_target(${name}_swig_doc DEPENDS ${GR_SWIG_DOC_FILE}) 126 | list(APPEND GR_SWIG_TARGET_DEPS ${name}_swig_doc ${GR_RUNTIME_SWIG_DOC_FILE}) 127 | endif() 128 | 129 | #append additional include directories 130 | find_package(PythonLibs 2) 131 | list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_PATH}) #deprecated name (now dirs) 132 | list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS}) 133 | 134 | #prepend local swig directories 135 | list(INSERT GR_SWIG_INCLUDE_DIRS 0 ${CMAKE_CURRENT_SOURCE_DIR}) 136 | list(INSERT GR_SWIG_INCLUDE_DIRS 0 ${CMAKE_CURRENT_BINARY_DIR}) 137 | 138 | #determine include dependencies for swig file 139 | execute_process( 140 | COMMAND ${PYTHON_EXECUTABLE} 141 | ${CMAKE_BINARY_DIR}/get_swig_deps.py 142 | "${ifiles}" "${GR_SWIG_INCLUDE_DIRS}" 143 | OUTPUT_STRIP_TRAILING_WHITESPACE 144 | OUTPUT_VARIABLE SWIG_MODULE_${name}_EXTRA_DEPS 145 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 146 | ) 147 | 148 | #Create a dummy custom command that depends on other targets 149 | include(GrMiscUtils) 150 | GR_GEN_TARGET_DEPS(_${name}_swig_tag tag_deps ${GR_SWIG_TARGET_DEPS}) 151 | set(tag_file ${CMAKE_CURRENT_BINARY_DIR}/${name}.tag) 152 | add_custom_command( 153 | OUTPUT ${tag_file} 154 | DEPENDS ${GR_SWIG_SOURCE_DEPS} ${tag_deps} 155 | COMMAND ${CMAKE_COMMAND} -E touch ${tag_file} 156 | ) 157 | 158 | #append the specified include directories 159 | include_directories(${GR_SWIG_INCLUDE_DIRS}) 160 | list(APPEND SWIG_MODULE_${name}_EXTRA_DEPS ${tag_file}) 161 | 162 | #setup the swig flags with flags and include directories 163 | set(CMAKE_SWIG_FLAGS -fvirtual -modern -keyword -w511 -module ${name} ${GR_SWIG_FLAGS}) 164 | foreach(dir ${GR_SWIG_INCLUDE_DIRS}) 165 | list(APPEND CMAKE_SWIG_FLAGS "-I${dir}") 166 | endforeach(dir) 167 | 168 | #set the C++ property on the swig .i file so it builds 169 | set_source_files_properties(${ifiles} PROPERTIES CPLUSPLUS ON) 170 | 171 | #setup the actual swig library target to be built 172 | include(UseSWIG) 173 | SWIG_ADD_MODULE(${name} python ${ifiles}) 174 | SWIG_LINK_LIBRARIES(${name} ${PYTHON_LIBRARIES} ${GR_SWIG_LIBRARIES}) 175 | if(${name} STREQUAL "runtime_swig") 176 | SET_TARGET_PROPERTIES(${SWIG_MODULE_runtime_swig_REAL_NAME} PROPERTIES DEFINE_SYMBOL "gnuradio_runtime_EXPORTS") 177 | endif(${name} STREQUAL "runtime_swig") 178 | 179 | endmacro(GR_SWIG_MAKE) 180 | 181 | ######################################################################## 182 | # Install swig targets generated by GR_SWIG_MAKE. Usage: 183 | # GR_SWIG_INSTALL( 184 | # TARGETS target target target... 185 | # [DESTINATION destination] 186 | # [COMPONENT component] 187 | # ) 188 | ######################################################################## 189 | macro(GR_SWIG_INSTALL) 190 | 191 | include(CMakeParseArgumentsCopy) 192 | CMAKE_PARSE_ARGUMENTS(GR_SWIG_INSTALL "" "DESTINATION;COMPONENT" "TARGETS" ${ARGN}) 193 | 194 | foreach(name ${GR_SWIG_INSTALL_TARGETS}) 195 | install(TARGETS ${SWIG_MODULE_${name}_REAL_NAME} 196 | DESTINATION ${GR_SWIG_INSTALL_DESTINATION} 197 | COMPONENT ${GR_SWIG_INSTALL_COMPONENT} 198 | ) 199 | 200 | include(GrPython) 201 | GR_PYTHON_INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${name}.py 202 | DESTINATION ${GR_SWIG_INSTALL_DESTINATION} 203 | COMPONENT ${GR_SWIG_INSTALL_COMPONENT} 204 | ) 205 | 206 | GR_LIBTOOL( 207 | TARGET ${SWIG_MODULE_${name}_REAL_NAME} 208 | DESTINATION ${GR_SWIG_INSTALL_DESTINATION} 209 | ) 210 | 211 | endforeach(name) 212 | 213 | endmacro(GR_SWIG_INSTALL) 214 | 215 | ######################################################################## 216 | # Generate a python file that can determine swig dependencies. 217 | # Used by the make macro above to determine extra dependencies. 218 | # When you build C++, CMake figures out the header dependencies. 219 | # This code essentially performs that logic for swig includes. 220 | ######################################################################## 221 | file(WRITE ${CMAKE_BINARY_DIR}/get_swig_deps.py " 222 | 223 | import os, sys, re 224 | 225 | i_include_matcher = re.compile('%(include|import)\\s*[<|\"](.*)[>|\"]') 226 | h_include_matcher = re.compile('#(include)\\s*[<|\"](.*)[>|\"]') 227 | include_dirs = sys.argv[2].split(';') 228 | 229 | def get_swig_incs(file_path): 230 | if file_path.endswith('.i'): matcher = i_include_matcher 231 | else: matcher = h_include_matcher 232 | file_contents = open(file_path, 'r').read() 233 | return matcher.findall(file_contents, re.MULTILINE) 234 | 235 | def get_swig_deps(file_path, level): 236 | deps = [file_path] 237 | if level == 0: return deps 238 | for keyword, inc_file in get_swig_incs(file_path): 239 | for inc_dir in include_dirs: 240 | inc_path = os.path.join(inc_dir, inc_file) 241 | if not os.path.exists(inc_path): continue 242 | deps.extend(get_swig_deps(inc_path, level-1)) 243 | break #found, we dont search in lower prio inc dirs 244 | return deps 245 | 246 | if __name__ == '__main__': 247 | ifiles = sys.argv[1].split(';') 248 | deps = sum([get_swig_deps(ifile, 3) for ifile in ifiles], []) 249 | #sys.stderr.write(';'.join(set(deps)) + '\\n\\n') 250 | print(';'.join(set(deps))) 251 | ") 252 | -------------------------------------------------------------------------------- /cmake/Modules/GrTest.cmake: -------------------------------------------------------------------------------- 1 | # Copyright 2010-2011 Free Software Foundation, Inc. 2 | # 3 | # This file was automatically generated by gr_modtool from GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | if(DEFINED __INCLUDED_GR_TEST_CMAKE) 21 | return() 22 | endif() 23 | set(__INCLUDED_GR_TEST_CMAKE TRUE) 24 | 25 | ######################################################################## 26 | # Add a unit test and setup the environment for a unit test. 27 | # Takes the same arguments as the ADD_TEST function. 28 | # 29 | # Before calling set the following variables: 30 | # GR_TEST_TARGET_DEPS - built targets for the library path 31 | # GR_TEST_LIBRARY_DIRS - directories for the library path 32 | # GR_TEST_PYTHON_DIRS - directories for the python path 33 | # GR_TEST_ENVIRONS - other environment key/value pairs 34 | ######################################################################## 35 | function(GR_ADD_TEST test_name) 36 | 37 | #Ensure that the build exe also appears in the PATH. 38 | list(APPEND GR_TEST_TARGET_DEPS ${ARGN}) 39 | 40 | #In the land of windows, all libraries must be in the PATH. 41 | #Since the dependent libraries are not yet installed, 42 | #we must manually set them in the PATH to run tests. 43 | #The following appends the path of a target dependency. 44 | foreach(target ${GR_TEST_TARGET_DEPS}) 45 | get_target_property(location ${target} LOCATION) 46 | if(location) 47 | get_filename_component(path ${location} PATH) 48 | string(REGEX REPLACE "\\$\\(.*\\)" ${CMAKE_BUILD_TYPE} path ${path}) 49 | list(APPEND GR_TEST_LIBRARY_DIRS ${path}) 50 | endif(location) 51 | endforeach(target) 52 | 53 | if(WIN32) 54 | #SWIG generates the python library files into a subdirectory. 55 | #Therefore, we must append this subdirectory into PYTHONPATH. 56 | #Only do this for the python directories matching the following: 57 | foreach(pydir ${GR_TEST_PYTHON_DIRS}) 58 | get_filename_component(name ${pydir} NAME) 59 | if(name MATCHES "^(swig|lib|src)$") 60 | list(APPEND GR_TEST_PYTHON_DIRS ${pydir}/${CMAKE_BUILD_TYPE}) 61 | endif() 62 | endforeach(pydir) 63 | endif(WIN32) 64 | 65 | file(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR} srcdir) 66 | file(TO_NATIVE_PATH "${GR_TEST_LIBRARY_DIRS}" libpath) #ok to use on dir list? 67 | file(TO_NATIVE_PATH "${GR_TEST_PYTHON_DIRS}" pypath) #ok to use on dir list? 68 | 69 | set(environs "VOLK_GENERIC=1" "GR_DONT_LOAD_PREFS=1" "srcdir=${srcdir}") 70 | list(APPEND environs ${GR_TEST_ENVIRONS}) 71 | 72 | #http://www.cmake.org/pipermail/cmake/2009-May/029464.html 73 | #Replaced this add test + set environs code with the shell script generation. 74 | #Its nicer to be able to manually run the shell script to diagnose problems. 75 | #ADD_TEST(${ARGV}) 76 | #SET_TESTS_PROPERTIES(${test_name} PROPERTIES ENVIRONMENT "${environs}") 77 | 78 | if(UNIX) 79 | set(LD_PATH_VAR "LD_LIBRARY_PATH") 80 | if(APPLE) 81 | set(LD_PATH_VAR "DYLD_LIBRARY_PATH") 82 | endif() 83 | 84 | set(binpath "${CMAKE_CURRENT_BINARY_DIR}:$PATH") 85 | list(APPEND libpath "$${LD_PATH_VAR}") 86 | list(APPEND pypath "$PYTHONPATH") 87 | 88 | #replace list separator with the path separator 89 | string(REPLACE ";" ":" libpath "${libpath}") 90 | string(REPLACE ";" ":" pypath "${pypath}") 91 | list(APPEND environs "PATH=${binpath}" "${LD_PATH_VAR}=${libpath}" "PYTHONPATH=${pypath}") 92 | 93 | #generate a bat file that sets the environment and runs the test 94 | if (CMAKE_CROSSCOMPILING) 95 | set(SHELL "/bin/sh") 96 | else(CMAKE_CROSSCOMPILING) 97 | find_program(SHELL sh) 98 | endif(CMAKE_CROSSCOMPILING) 99 | set(sh_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.sh) 100 | file(WRITE ${sh_file} "#!${SHELL}\n") 101 | #each line sets an environment variable 102 | foreach(environ ${environs}) 103 | file(APPEND ${sh_file} "export ${environ}\n") 104 | endforeach(environ) 105 | #load the command to run with its arguments 106 | foreach(arg ${ARGN}) 107 | file(APPEND ${sh_file} "${arg} ") 108 | endforeach(arg) 109 | file(APPEND ${sh_file} "\n") 110 | 111 | #make the shell file executable 112 | execute_process(COMMAND chmod +x ${sh_file}) 113 | 114 | add_test(${test_name} ${SHELL} ${sh_file}) 115 | 116 | endif(UNIX) 117 | 118 | if(WIN32) 119 | list(APPEND libpath ${DLL_PATHS} "%PATH%") 120 | list(APPEND pypath "%PYTHONPATH%") 121 | 122 | #replace list separator with the path separator (escaped) 123 | string(REPLACE ";" "\\;" libpath "${libpath}") 124 | string(REPLACE ";" "\\;" pypath "${pypath}") 125 | list(APPEND environs "PATH=${libpath}" "PYTHONPATH=${pypath}") 126 | 127 | #generate a bat file that sets the environment and runs the test 128 | set(bat_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.bat) 129 | file(WRITE ${bat_file} "@echo off\n") 130 | #each line sets an environment variable 131 | foreach(environ ${environs}) 132 | file(APPEND ${bat_file} "SET ${environ}\n") 133 | endforeach(environ) 134 | #load the command to run with its arguments 135 | foreach(arg ${ARGN}) 136 | file(APPEND ${bat_file} "${arg} ") 137 | endforeach(arg) 138 | file(APPEND ${bat_file} "\n") 139 | 140 | add_test(${test_name} ${bat_file}) 141 | endif(WIN32) 142 | 143 | endfunction(GR_ADD_TEST) 144 | -------------------------------------------------------------------------------- /cmake/Modules/nwrConfig.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016 Andy Walls 3 | # 4 | # This file was automatically generated by gr_modtool from GNU Radio 5 | # 6 | # This file was automatically generated from a template incorporating 7 | # data input by Andy Walls. 8 | # See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 9 | # 10 | INCLUDE(FindPkgConfig) 11 | PKG_CHECK_MODULES(PC_NWR nwr) 12 | 13 | FIND_PATH( 14 | NWR_INCLUDE_DIRS 15 | NAMES nwr/api.h 16 | HINTS $ENV{NWR_DIR}/include 17 | ${PC_NWR_INCLUDEDIR} 18 | PATHS ${CMAKE_INSTALL_PREFIX}/include 19 | /usr/local/include 20 | /usr/include 21 | ) 22 | 23 | FIND_LIBRARY( 24 | NWR_LIBRARIES 25 | NAMES gnuradio-nwr 26 | HINTS $ENV{NWR_DIR}/lib 27 | ${PC_NWR_LIBDIR} 28 | PATHS ${CMAKE_INSTALL_PREFIX}/lib 29 | ${CMAKE_INSTALL_PREFIX}/lib64 30 | /usr/local/lib 31 | /usr/local/lib64 32 | /usr/lib 33 | /usr/lib64 34 | ) 35 | 36 | INCLUDE(FindPackageHandleStandardArgs) 37 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(NWR DEFAULT_MSG NWR_LIBRARIES NWR_INCLUDE_DIRS) 38 | MARK_AS_ADVANCED(NWR_LIBRARIES NWR_INCLUDE_DIRS) 39 | 40 | -------------------------------------------------------------------------------- /cmake/cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | # This file was automatically generated by gr_modtool from GNU Radio 2 | # 3 | # Copyright (C) 2013 Free Software Foundation 4 | # https://github.com/gnuradio/gnuradio/blob/master/gr-utils/python/modtool/gr-newmod/cmake/cmake_uninstall.cmake.in 5 | # 6 | # Copyright (C) 2011 KitwarePublic Wiki Authors 7 | # http://www.vtk.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F 8 | # 9 | # Licensed under the Creative Commons Attribution 2.5 Generic license: 10 | # https://creativecommons.org/licenses/by/2.5/ 11 | # https://creativecommons.org/licenses/by/2.5/legalcode 12 | 13 | IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 14 | MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") 15 | ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 16 | 17 | FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) 18 | STRING(REGEX REPLACE "\n" ";" files "${files}") 19 | FOREACH(file ${files}) 20 | MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") 21 | IF(EXISTS "$ENV{DESTDIR}${file}") 22 | EXEC_PROGRAM( 23 | "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 24 | OUTPUT_VARIABLE rm_out 25 | RETURN_VALUE rm_retval 26 | ) 27 | IF(NOT "${rm_retval}" STREQUAL 0) 28 | MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") 29 | ENDIF(NOT "${rm_retval}" STREQUAL 0) 30 | ELSEIF(IS_SYMLINK "$ENV{DESTDIR}${file}") 31 | EXEC_PROGRAM( 32 | "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 33 | OUTPUT_VARIABLE rm_out 34 | RETURN_VALUE rm_retval 35 | ) 36 | IF(NOT "${rm_retval}" STREQUAL 0) 37 | MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") 38 | ENDIF(NOT "${rm_retval}" STREQUAL 0) 39 | ELSE(EXISTS "$ENV{DESTDIR}${file}") 40 | MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") 41 | ENDIF(EXISTS "$ENV{DESTDIR}${file}") 42 | ENDFOREACH(file) 43 | -------------------------------------------------------------------------------- /docs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file was automatically generated by gr_modtool from GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | ######################################################################## 21 | # Setup dependencies 22 | ######################################################################## 23 | find_package(Doxygen) 24 | 25 | ######################################################################## 26 | # Begin conditional configuration 27 | ######################################################################## 28 | if(ENABLE_DOXYGEN) 29 | 30 | ######################################################################## 31 | # Add subdirectories 32 | ######################################################################## 33 | add_subdirectory(doxygen) 34 | 35 | endif(ENABLE_DOXYGEN) 36 | -------------------------------------------------------------------------------- /docs/README.nwr: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016 Andy Walls 3 | # 4 | # This file was automatically generated by gr_modtool from GNU Radio 5 | # 6 | # This file was automatically generated from a template incorporating 7 | # data input by Andy Walls. 8 | # See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 9 | # 10 | 11 | This is the nwr-write-a-block package meant as a guide to building 12 | out-of-tree packages. To use the nwr blocks, the Python namespaces 13 | is in 'nwr', which is imported as: 14 | 15 | import nwr 16 | 17 | See the Doxygen documentation for details about the blocks available 18 | in this package. A quick listing of the details can be found in Python 19 | after importing by using: 20 | 21 | help(nwr) 22 | -------------------------------------------------------------------------------- /docs/clock_loop.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awalls-cx18/gr-nwr/9bdb8f3225e241a14c01267512fdd502a1aaab5b/docs/clock_loop.pdf -------------------------------------------------------------------------------- /docs/doxygen/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file was automatically generated by gr_modtool from GNU Radio 4 | # 5 | # GNU Radio is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 3, or (at your option) 8 | # any later version. 9 | # 10 | # GNU Radio is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with GNU Radio; see the file COPYING. If not, write to 17 | # the Free Software Foundation, Inc., 51 Franklin Street, 18 | # Boston, MA 02110-1301, USA. 19 | 20 | ######################################################################## 21 | # Create the doxygen configuration file 22 | ######################################################################## 23 | file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} top_srcdir) 24 | file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} top_builddir) 25 | file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} abs_top_srcdir) 26 | file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} abs_top_builddir) 27 | 28 | set(HAVE_DOT ${DOXYGEN_DOT_FOUND}) 29 | set(enable_html_docs YES) 30 | set(enable_latex_docs NO) 31 | set(enable_xml_docs YES) 32 | 33 | configure_file( 34 | ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in 35 | ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 36 | @ONLY) 37 | 38 | set(BUILT_DIRS ${CMAKE_CURRENT_BINARY_DIR}/xml ${CMAKE_CURRENT_BINARY_DIR}/html) 39 | 40 | ######################################################################## 41 | # Make and install doxygen docs 42 | ######################################################################## 43 | add_custom_command( 44 | OUTPUT ${BUILT_DIRS} 45 | COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 46 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 47 | COMMENT "Generating documentation with doxygen" 48 | ) 49 | 50 | add_custom_target(doxygen_target ALL DEPENDS ${BUILT_DIRS}) 51 | 52 | install(DIRECTORY ${BUILT_DIRS} DESTINATION ${GR_PKG_DOC_DIR}) 53 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Free Software Foundation, Inc. 3 | # 4 | # This file was automatically generated by gr_modtool from GNU Radio 5 | # 6 | # GNU Radio is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # GNU Radio is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with GNU Radio; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | """ 22 | Python interface to contents of doxygen xml documentation. 23 | 24 | Example use: 25 | See the contents of the example folder for the C++ and 26 | doxygen-generated xml used in this example. 27 | 28 | >>> # Parse the doxygen docs. 29 | >>> import os 30 | >>> this_dir = os.path.dirname(globals()['__file__']) 31 | >>> xml_path = this_dir + "/example/xml/" 32 | >>> di = DoxyIndex(xml_path) 33 | 34 | Get a list of all top-level objects. 35 | 36 | >>> print([mem.name() for mem in di.members()]) 37 | [u'Aadvark', u'aadvarky_enough', u'main'] 38 | 39 | Get all functions. 40 | 41 | >>> print([mem.name() for mem in di.in_category(DoxyFunction)]) 42 | [u'aadvarky_enough', u'main'] 43 | 44 | Check if an object is present. 45 | 46 | >>> di.has_member(u'Aadvark') 47 | True 48 | >>> di.has_member(u'Fish') 49 | False 50 | 51 | Get an item by name and check its properties. 52 | 53 | >>> aad = di.get_member(u'Aadvark') 54 | >>> print(aad.brief_description) 55 | Models the mammal Aadvark. 56 | >>> print(aad.detailed_description) 57 | Sadly the model is incomplete and cannot capture all aspects of an aadvark yet. 58 | 59 | This line is uninformative and is only to test line breaks in the comments. 60 | >>> [mem.name() for mem in aad.members()] 61 | [u'aadvarkness', u'print', u'Aadvark', u'get_aadvarkness'] 62 | >>> aad.get_member(u'print').brief_description 63 | u'Outputs the vital aadvark statistics.' 64 | 65 | """ 66 | 67 | from doxyindex import DoxyIndex, DoxyFunction, DoxyParam, DoxyClass, DoxyFile, DoxyNamespace, DoxyGroup, DoxyFriend, DoxyOther 68 | 69 | def _test(): 70 | import os 71 | this_dir = os.path.dirname(globals()['__file__']) 72 | xml_path = this_dir + "/example/xml/" 73 | di = DoxyIndex(xml_path) 74 | # Get the Aadvark class 75 | aad = di.get_member('Aadvark') 76 | aad.brief_description 77 | import doctest 78 | return doctest.testmod() 79 | 80 | if __name__ == "__main__": 81 | _test() 82 | 83 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/base.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Free Software Foundation, Inc. 3 | # 4 | # This file was automatically generated by gr_modtool from GNU Radio 5 | # 6 | # GNU Radio is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # GNU Radio is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with GNU Radio; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | """ 22 | A base class is created. 23 | 24 | Classes based upon this are used to make more user-friendly interfaces 25 | to the doxygen xml docs than the generated classes provide. 26 | """ 27 | 28 | import os 29 | import pdb 30 | 31 | from xml.parsers.expat import ExpatError 32 | 33 | from generated import compound 34 | 35 | 36 | class Base(object): 37 | 38 | class Duplicate(StandardError): 39 | pass 40 | 41 | class NoSuchMember(StandardError): 42 | pass 43 | 44 | class ParsingError(StandardError): 45 | pass 46 | 47 | def __init__(self, parse_data, top=None): 48 | self._parsed = False 49 | self._error = False 50 | self._parse_data = parse_data 51 | self._members = [] 52 | self._dict_members = {} 53 | self._in_category = {} 54 | self._data = {} 55 | if top is not None: 56 | self._xml_path = top._xml_path 57 | # Set up holder of references 58 | else: 59 | top = self 60 | self._refs = {} 61 | self._xml_path = parse_data 62 | self.top = top 63 | 64 | @classmethod 65 | def from_refid(cls, refid, top=None): 66 | """ Instantiate class from a refid rather than parsing object. """ 67 | # First check to see if its already been instantiated. 68 | if top is not None and refid in top._refs: 69 | return top._refs[refid] 70 | # Otherwise create a new instance and set refid. 71 | inst = cls(None, top=top) 72 | inst.refid = refid 73 | inst.add_ref(inst) 74 | return inst 75 | 76 | @classmethod 77 | def from_parse_data(cls, parse_data, top=None): 78 | refid = getattr(parse_data, 'refid', None) 79 | if refid is not None and top is not None and refid in top._refs: 80 | return top._refs[refid] 81 | inst = cls(parse_data, top=top) 82 | if refid is not None: 83 | inst.refid = refid 84 | inst.add_ref(inst) 85 | return inst 86 | 87 | def add_ref(self, obj): 88 | if hasattr(obj, 'refid'): 89 | self.top._refs[obj.refid] = obj 90 | 91 | mem_classes = [] 92 | 93 | def get_cls(self, mem): 94 | for cls in self.mem_classes: 95 | if cls.can_parse(mem): 96 | return cls 97 | raise StandardError(("Did not find a class for object '%s'." \ 98 | % (mem.get_name()))) 99 | 100 | def convert_mem(self, mem): 101 | try: 102 | cls = self.get_cls(mem) 103 | converted = cls.from_parse_data(mem, self.top) 104 | if converted is None: 105 | raise StandardError('No class matched this object.') 106 | self.add_ref(converted) 107 | return converted 108 | except StandardError, e: 109 | print e 110 | 111 | @classmethod 112 | def includes(cls, inst): 113 | return isinstance(inst, cls) 114 | 115 | @classmethod 116 | def can_parse(cls, obj): 117 | return False 118 | 119 | def _parse(self): 120 | self._parsed = True 121 | 122 | def _get_dict_members(self, cat=None): 123 | """ 124 | For given category a dictionary is returned mapping member names to 125 | members of that category. For names that are duplicated the name is 126 | mapped to None. 127 | """ 128 | self.confirm_no_error() 129 | if cat not in self._dict_members: 130 | new_dict = {} 131 | for mem in self.in_category(cat): 132 | if mem.name() not in new_dict: 133 | new_dict[mem.name()] = mem 134 | else: 135 | new_dict[mem.name()] = self.Duplicate 136 | self._dict_members[cat] = new_dict 137 | return self._dict_members[cat] 138 | 139 | def in_category(self, cat): 140 | self.confirm_no_error() 141 | if cat is None: 142 | return self._members 143 | if cat not in self._in_category: 144 | self._in_category[cat] = [mem for mem in self._members 145 | if cat.includes(mem)] 146 | return self._in_category[cat] 147 | 148 | def get_member(self, name, cat=None): 149 | self.confirm_no_error() 150 | # Check if it's in a namespace or class. 151 | bits = name.split('::') 152 | first = bits[0] 153 | rest = '::'.join(bits[1:]) 154 | member = self._get_dict_members(cat).get(first, self.NoSuchMember) 155 | # Raise any errors that are returned. 156 | if member in set([self.NoSuchMember, self.Duplicate]): 157 | raise member() 158 | if rest: 159 | return member.get_member(rest, cat=cat) 160 | return member 161 | 162 | def has_member(self, name, cat=None): 163 | try: 164 | mem = self.get_member(name, cat=cat) 165 | return True 166 | except self.NoSuchMember: 167 | return False 168 | 169 | def data(self): 170 | self.confirm_no_error() 171 | return self._data 172 | 173 | def members(self): 174 | self.confirm_no_error() 175 | return self._members 176 | 177 | def process_memberdefs(self): 178 | mdtss = [] 179 | for sec in self._retrieved_data.compounddef.sectiondef: 180 | mdtss += sec.memberdef 181 | # At the moment we lose all information associated with sections. 182 | # Sometimes a memberdef is in several sectiondef. 183 | # We make sure we don't get duplicates here. 184 | uniques = set([]) 185 | for mem in mdtss: 186 | converted = self.convert_mem(mem) 187 | pair = (mem.name, mem.__class__) 188 | if pair not in uniques: 189 | uniques.add(pair) 190 | self._members.append(converted) 191 | 192 | def retrieve_data(self): 193 | filename = os.path.join(self._xml_path, self.refid + '.xml') 194 | try: 195 | self._retrieved_data = compound.parse(filename) 196 | except ExpatError: 197 | print('Error in xml in file %s' % filename) 198 | self._error = True 199 | self._retrieved_data = None 200 | 201 | def check_parsed(self): 202 | if not self._parsed: 203 | self._parse() 204 | 205 | def confirm_no_error(self): 206 | self.check_parsed() 207 | if self._error: 208 | raise self.ParsingError() 209 | 210 | def error(self): 211 | self.check_parsed() 212 | return self._error 213 | 214 | def name(self): 215 | # first see if we can do it without processing. 216 | if self._parse_data is not None: 217 | return self._parse_data.name 218 | self.check_parsed() 219 | return self._retrieved_data.compounddef.name 220 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/doxyindex.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Free Software Foundation, Inc. 3 | # 4 | # This file was automatically generated by gr_modtool from GNU Radio 5 | # 6 | # GNU Radio is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # GNU Radio is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with GNU Radio; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | """ 22 | Classes providing more user-friendly interfaces to the doxygen xml 23 | docs than the generated classes provide. 24 | """ 25 | 26 | import os 27 | 28 | from generated import index 29 | from base import Base 30 | from text import description 31 | 32 | class DoxyIndex(Base): 33 | """ 34 | Parses a doxygen xml directory. 35 | """ 36 | 37 | __module__ = "gnuradio.utils.doxyxml" 38 | 39 | def _parse(self): 40 | if self._parsed: 41 | return 42 | super(DoxyIndex, self)._parse() 43 | self._root = index.parse(os.path.join(self._xml_path, 'index.xml')) 44 | for mem in self._root.compound: 45 | converted = self.convert_mem(mem) 46 | # For files and namespaces we want the contents to be 47 | # accessible directly from the parent rather than having 48 | # to go through the file object. 49 | if self.get_cls(mem) == DoxyFile: 50 | if mem.name.endswith('.h'): 51 | self._members += converted.members() 52 | self._members.append(converted) 53 | elif self.get_cls(mem) == DoxyNamespace: 54 | self._members += converted.members() 55 | self._members.append(converted) 56 | else: 57 | self._members.append(converted) 58 | 59 | 60 | def generate_swig_doc_i(self): 61 | """ 62 | %feature("docstring") gr_make_align_on_samplenumbers_ss::align_state " 63 | Wraps the C++: gr_align_on_samplenumbers_ss::align_state"; 64 | """ 65 | pass 66 | 67 | 68 | class DoxyCompMem(Base): 69 | 70 | 71 | kind = None 72 | 73 | def __init__(self, *args, **kwargs): 74 | super(DoxyCompMem, self).__init__(*args, **kwargs) 75 | 76 | @classmethod 77 | def can_parse(cls, obj): 78 | return obj.kind == cls.kind 79 | 80 | def set_descriptions(self, parse_data): 81 | bd = description(getattr(parse_data, 'briefdescription', None)) 82 | dd = description(getattr(parse_data, 'detaileddescription', None)) 83 | self._data['brief_description'] = bd 84 | self._data['detailed_description'] = dd 85 | 86 | def set_parameters(self, data): 87 | vs = [ddc.value for ddc in data.detaileddescription.content_] 88 | pls = [] 89 | for v in vs: 90 | if hasattr(v, 'parameterlist'): 91 | pls += v.parameterlist 92 | pis = [] 93 | for pl in pls: 94 | pis += pl.parameteritem 95 | dpis = [] 96 | for pi in pis: 97 | dpi = DoxyParameterItem(pi) 98 | dpi._parse() 99 | dpis.append(dpi) 100 | self._data['params'] = dpis 101 | 102 | 103 | class DoxyCompound(DoxyCompMem): 104 | pass 105 | 106 | class DoxyMember(DoxyCompMem): 107 | pass 108 | 109 | class DoxyFunction(DoxyMember): 110 | 111 | __module__ = "gnuradio.utils.doxyxml" 112 | 113 | kind = 'function' 114 | 115 | def _parse(self): 116 | if self._parsed: 117 | return 118 | super(DoxyFunction, self)._parse() 119 | self.set_descriptions(self._parse_data) 120 | self.set_parameters(self._parse_data) 121 | if not self._data['params']: 122 | # If the params weren't set by a comment then just grab the names. 123 | self._data['params'] = [] 124 | prms = self._parse_data.param 125 | for prm in prms: 126 | self._data['params'].append(DoxyParam(prm)) 127 | 128 | brief_description = property(lambda self: self.data()['brief_description']) 129 | detailed_description = property(lambda self: self.data()['detailed_description']) 130 | params = property(lambda self: self.data()['params']) 131 | 132 | Base.mem_classes.append(DoxyFunction) 133 | 134 | 135 | class DoxyParam(DoxyMember): 136 | 137 | __module__ = "gnuradio.utils.doxyxml" 138 | 139 | def _parse(self): 140 | if self._parsed: 141 | return 142 | super(DoxyParam, self)._parse() 143 | self.set_descriptions(self._parse_data) 144 | self._data['declname'] = self._parse_data.declname 145 | 146 | @property 147 | def description(self): 148 | descriptions = [] 149 | if self.brief_description: 150 | descriptions.append(self.brief_description) 151 | if self.detailed_description: 152 | descriptions.append(self.detailed_description) 153 | return '\n\n'.join(descriptions) 154 | 155 | brief_description = property(lambda self: self.data()['brief_description']) 156 | detailed_description = property(lambda self: self.data()['detailed_description']) 157 | name = property(lambda self: self.data()['declname']) 158 | 159 | class DoxyParameterItem(DoxyMember): 160 | """A different representation of a parameter in Doxygen.""" 161 | 162 | def _parse(self): 163 | if self._parsed: 164 | return 165 | super(DoxyParameterItem, self)._parse() 166 | names = [] 167 | for nl in self._parse_data.parameternamelist: 168 | for pn in nl.parametername: 169 | names.append(description(pn)) 170 | # Just take first name 171 | self._data['name'] = names[0] 172 | # Get description 173 | pd = description(self._parse_data.get_parameterdescription()) 174 | self._data['description'] = pd 175 | 176 | description = property(lambda self: self.data()['description']) 177 | name = property(lambda self: self.data()['name']) 178 | 179 | 180 | class DoxyClass(DoxyCompound): 181 | 182 | __module__ = "gnuradio.utils.doxyxml" 183 | 184 | kind = 'class' 185 | 186 | def _parse(self): 187 | if self._parsed: 188 | return 189 | super(DoxyClass, self)._parse() 190 | self.retrieve_data() 191 | if self._error: 192 | return 193 | self.set_descriptions(self._retrieved_data.compounddef) 194 | self.set_parameters(self._retrieved_data.compounddef) 195 | # Sectiondef.kind tells about whether private or public. 196 | # We just ignore this for now. 197 | self.process_memberdefs() 198 | 199 | brief_description = property(lambda self: self.data()['brief_description']) 200 | detailed_description = property(lambda self: self.data()['detailed_description']) 201 | params = property(lambda self: self.data()['params']) 202 | 203 | Base.mem_classes.append(DoxyClass) 204 | 205 | 206 | class DoxyFile(DoxyCompound): 207 | 208 | __module__ = "gnuradio.utils.doxyxml" 209 | 210 | kind = 'file' 211 | 212 | def _parse(self): 213 | if self._parsed: 214 | return 215 | super(DoxyFile, self)._parse() 216 | self.retrieve_data() 217 | self.set_descriptions(self._retrieved_data.compounddef) 218 | if self._error: 219 | return 220 | self.process_memberdefs() 221 | 222 | brief_description = property(lambda self: self.data()['brief_description']) 223 | detailed_description = property(lambda self: self.data()['detailed_description']) 224 | 225 | Base.mem_classes.append(DoxyFile) 226 | 227 | 228 | class DoxyNamespace(DoxyCompound): 229 | 230 | __module__ = "gnuradio.utils.doxyxml" 231 | 232 | kind = 'namespace' 233 | 234 | def _parse(self): 235 | if self._parsed: 236 | return 237 | super(DoxyNamespace, self)._parse() 238 | self.retrieve_data() 239 | self.set_descriptions(self._retrieved_data.compounddef) 240 | if self._error: 241 | return 242 | self.process_memberdefs() 243 | 244 | Base.mem_classes.append(DoxyNamespace) 245 | 246 | 247 | class DoxyGroup(DoxyCompound): 248 | 249 | __module__ = "gnuradio.utils.doxyxml" 250 | 251 | kind = 'group' 252 | 253 | def _parse(self): 254 | if self._parsed: 255 | return 256 | super(DoxyGroup, self)._parse() 257 | self.retrieve_data() 258 | if self._error: 259 | return 260 | cdef = self._retrieved_data.compounddef 261 | self._data['title'] = description(cdef.title) 262 | # Process inner groups 263 | grps = cdef.innergroup 264 | for grp in grps: 265 | converted = DoxyGroup.from_refid(grp.refid, top=self.top) 266 | self._members.append(converted) 267 | # Process inner classes 268 | klasses = cdef.innerclass 269 | for kls in klasses: 270 | converted = DoxyClass.from_refid(kls.refid, top=self.top) 271 | self._members.append(converted) 272 | # Process normal members 273 | self.process_memberdefs() 274 | 275 | title = property(lambda self: self.data()['title']) 276 | 277 | 278 | Base.mem_classes.append(DoxyGroup) 279 | 280 | 281 | class DoxyFriend(DoxyMember): 282 | 283 | __module__ = "gnuradio.utils.doxyxml" 284 | 285 | kind = 'friend' 286 | 287 | Base.mem_classes.append(DoxyFriend) 288 | 289 | 290 | class DoxyOther(Base): 291 | 292 | __module__ = "gnuradio.utils.doxyxml" 293 | 294 | kinds = set(['variable', 'struct', 'union', 'define', 'typedef', 'enum', 295 | 'dir', 'page', 'signal', 'slot', 'property']) 296 | 297 | @classmethod 298 | def can_parse(cls, obj): 299 | return obj.kind in cls.kinds 300 | 301 | Base.mem_classes.append(DoxyOther) 302 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/generated/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2011 Free Software Foundation, Inc. 3 | # 4 | # This file was automatically generated by gr_modtool from GNU Radio 5 | # This file was originally generated by generateDS.py 6 | # The xsd file was originally generated by doxgen 7 | # 8 | # GNU Radio is free software; you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation; either version 3, or (at your option) 11 | # any later version. 12 | # 13 | # GNU Radio is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with GNU Radio; see the file COPYING. If not, write to 20 | # the Free Software Foundation, Inc., 51 Franklin Street, 21 | # Boston, MA 02110-1301, USA. 22 | # 23 | 24 | """ 25 | Contains generated files produced by generateDS.py. 26 | 27 | These do the real work of parsing the doxygen xml files but the 28 | resultant classes are not very friendly to navigate so the rest of the 29 | doxyxml module processes them further. 30 | """ 31 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/generated/index.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # 4 | # Copyright 2011 Free Software Foundation, Inc. 5 | # 6 | # This file was automatically generated by gr_modtool from GNU Radio 7 | # This file was originally generated by generateDS.py 8 | # The xsd file was originally generated by doxgen 9 | # 10 | # GNU Radio is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 3, or (at your option) 13 | # any later version. 14 | # 15 | # GNU Radio is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | # 20 | # You should have received a copy of the GNU General Public License 21 | # along with GNU Radio; see the file COPYING. If not, write to 22 | # the Free Software Foundation, Inc., 51 Franklin Street, 23 | # Boston, MA 02110-1301, USA. 24 | # 25 | 26 | """ 27 | Generated Mon Feb 9 19:08:05 2009 by generateDS.py. 28 | """ 29 | 30 | from xml.dom import minidom 31 | 32 | import os 33 | import sys 34 | import compound 35 | 36 | import indexsuper as supermod 37 | 38 | class DoxygenTypeSub(supermod.DoxygenType): 39 | def __init__(self, version=None, compound=None): 40 | supermod.DoxygenType.__init__(self, version, compound) 41 | 42 | def find_compounds_and_members(self, details): 43 | """ 44 | Returns a list of all compounds and their members which match details 45 | """ 46 | 47 | results = [] 48 | for compound in self.compound: 49 | members = compound.find_members(details) 50 | if members: 51 | results.append([compound, members]) 52 | else: 53 | if details.match(compound): 54 | results.append([compound, []]) 55 | 56 | return results 57 | 58 | supermod.DoxygenType.subclass = DoxygenTypeSub 59 | # end class DoxygenTypeSub 60 | 61 | 62 | class CompoundTypeSub(supermod.CompoundType): 63 | def __init__(self, kind=None, refid=None, name='', member=None): 64 | supermod.CompoundType.__init__(self, kind, refid, name, member) 65 | 66 | def find_members(self, details): 67 | """ 68 | Returns a list of all members which match details 69 | """ 70 | 71 | results = [] 72 | 73 | for member in self.member: 74 | if details.match(member): 75 | results.append(member) 76 | 77 | return results 78 | 79 | supermod.CompoundType.subclass = CompoundTypeSub 80 | # end class CompoundTypeSub 81 | 82 | 83 | class MemberTypeSub(supermod.MemberType): 84 | 85 | def __init__(self, kind=None, refid=None, name=''): 86 | supermod.MemberType.__init__(self, kind, refid, name) 87 | 88 | supermod.MemberType.subclass = MemberTypeSub 89 | # end class MemberTypeSub 90 | 91 | 92 | def parse(inFilename): 93 | 94 | doc = minidom.parse(inFilename) 95 | rootNode = doc.documentElement 96 | rootObj = supermod.DoxygenType.factory() 97 | rootObj.build(rootNode) 98 | 99 | return rootObj 100 | 101 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/text.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Free Software Foundation, Inc. 3 | # 4 | # This file was automatically generated by gr_modtool from GNU Radio 5 | # 6 | # GNU Radio is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # GNU Radio is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with GNU Radio; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | """ 22 | Utilities for extracting text from generated classes. 23 | """ 24 | 25 | def is_string(txt): 26 | if isinstance(txt, str): 27 | return True 28 | try: 29 | if isinstance(txt, unicode): 30 | return True 31 | except NameError: 32 | pass 33 | return False 34 | 35 | def description(obj): 36 | if obj is None: 37 | return None 38 | return description_bit(obj).strip() 39 | 40 | def description_bit(obj): 41 | if hasattr(obj, 'content'): 42 | contents = [description_bit(item) for item in obj.content] 43 | result = ''.join(contents) 44 | elif hasattr(obj, 'content_'): 45 | contents = [description_bit(item) for item in obj.content_] 46 | result = ''.join(contents) 47 | elif hasattr(obj, 'value'): 48 | result = description_bit(obj.value) 49 | elif is_string(obj): 50 | return obj 51 | else: 52 | raise StandardError('Expecting a string or something with content, content_ or value attribute') 53 | # If this bit is a paragraph then add one some line breaks. 54 | if hasattr(obj, 'name') and obj.name == 'para': 55 | result += "\n\n" 56 | return result 57 | -------------------------------------------------------------------------------- /docs/doxygen/other/group_defs.dox: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Andy Walls 3 | * 4 | * This file was automatically generated by gr_modtool from GNU Radio 5 | * 6 | * This file was automatically generated from a template incorporating 7 | * data input by Andy Walls. 8 | * See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 9 | */ 10 | 11 | /*! 12 | * \defgroup block NWR C++ Signal Processing Blocks 13 | * \brief All C++ blocks that can be used from the NWR OOT GNU Radio 14 | * module are listed here or in the subcategories below. 15 | * 16 | */ 17 | 18 | -------------------------------------------------------------------------------- /docs/doxygen/other/main_page.dox: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Andy Walls 3 | * 4 | * This file was automatically generated by gr_modtool from GNU Radio 5 | * 6 | * This file was automatically generated from a template incorporating 7 | * data input by Andy Walls. 8 | * See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 9 | */ 10 | 11 | /*! \mainpage 12 | 13 | Welcome to the NWR Out of Tree GNU Radio Module Block 14 | 15 | This is the intro page for the Doxygen manual generated for the NWR 16 | block (docs/doxygen/other/main_page.dox). Edit it to add more detailed 17 | documentation about the new modules contained in this 18 | project. 19 | 20 | */ 21 | -------------------------------------------------------------------------------- /examples/README: -------------------------------------------------------------------------------- 1 | Copyright (C) 2016 Andy Walls 2 | 3 | Example flowgraphs and data files for NWR: 4 | 5 | 1. nwr_fg.grc 6 | The example flowgraph for NWR audio and SAME demodulation. 7 | 8 | 2. nwr_file_prune.grc 9 | A utility flowgraph for snipping out segments of a large I/Q capture file. 10 | 11 | 3. rtl_sdr_capture_convert.grc 12 | A utility flowgraph for converting a biased 8 bit integer I and Q capture 13 | file, generated by the rtl_sdr utility at its default sample_rate of 14 | 2.048 Msps, to a 32 bit float complex I and Q capture file with 15 | metadata headers, at a sample rate of 250 ksps, for playback with 16 | GNURadio's File Meta Source block. 17 | 18 | 4. nwr_band_162487500Hz_250ksps_201611091145.c32.gz 19 | A gzip compressed file containing 32 bit float complex I and Q and 20 | metadata headers. It is an approximately 1 minute 15 second capture 21 | of the NWR band stations on 9 Nov 2016 at about 11:45 a.m. EST. It 22 | captures a Required Weekly TEST of EAS with SAME data modulation and 23 | EAS tone from WXM57 Heathsville, VA on WX2 (162.400 MHz): 24 | http://www.nws.noaa.gov/nwr/coverage/site2.php?State=VA&Site=WXM57 25 | -------------------------------------------------------------------------------- /examples/nwr_band_162487500Hz_250ksps_201611091145.c32.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awalls-cx18/gr-nwr/9bdb8f3225e241a14c01267512fdd502a1aaab5b/examples/nwr_band_162487500Hz_250ksps_201611091145.c32.gz -------------------------------------------------------------------------------- /grc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016 Andy Walls 3 | # 4 | # This file was automatically generated by gr_modtool from GNU Radio 5 | # 6 | # This file was automatically generated from a template incorporating 7 | # data input by Andy Walls and subsequently hand edited by Andy Walls. 8 | # See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 9 | # 10 | 11 | install(FILES 12 | nwr_lms_da_equalizer_ff.xml 13 | nwr_burst_detect_and_tag.xml 14 | nwr_correction_estimator_ff.xml 15 | nwr_multiply_by_tag_value_ff.xml 16 | nwr_add_tag_value_ff.xml 17 | nwr_pll_refout_cc.xml 18 | nwr_same_burst_decoder.xml DESTINATION share/gnuradio/grc/blocks 19 | ) 20 | -------------------------------------------------------------------------------- /grc/nwr_add_tag_value_ff.xml: -------------------------------------------------------------------------------- 1 | 2 | 21 | 22 | 23 | Add Tag Value 24 | nwr_add_tag_value_ff 25 | [nwr] 26 | import nwr 27 | nwr.add_tag_value_ff($tagname, $vlen) 28 | 29 | 30 | Tag Name 31 | tagname 32 | string 33 | 34 | 35 | 36 | Vec Length 37 | vlen 38 | 1 39 | int 40 | 41 | 42 | 43 | in 44 | float 45 | 46 | 47 | 48 | out 49 | float 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /grc/nwr_burst_detect_and_tag.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Burst Detect and Tag 7 | nwr_burst_detect_and_tag 8 | [nwr] 9 | import nwr 10 | nwr.burst_detect_and_tag($type.size, $sample_rate, $thresh_db, $init_floor_est, $declare_dur, $max_dur, $sob_amp_frac, $sob_key, $eob_key, $eob_delay, $guard_interval) 11 | 12 | 13 | IO Type 14 | type 15 | enum 16 | 21 | 26 | 31 | 36 | 41 | 42 | 43 | 44 | Sample Rate 45 | sample_rate 46 | samp_rate 47 | float 48 | part 49 | 50 | 51 | 52 | Threshold (dB) 53 | thresh_db 54 | 0.0 55 | float 56 | 57 | 58 | 59 | Initial Floor Estimate 60 | init_floor_est 61 | 100e-6 62 | float 63 | 64 | 65 | 66 | Declaration Duration (s) 67 | declare_dur 68 | 1.920e-3*8.0*16.0 69 | float 70 | 71 | 72 | 73 | Maximum Duration (s) 74 | max_dur 75 | 1.920e-3*8.0*268.0 76 | float 77 | 78 | 79 | 80 | SOB Amplitude Fraction 81 | sob_amp_frac 82 | 0.2 83 | float 84 | 85 | 86 | 87 | Start Tag Name 88 | sob_key 89 | "rx_sob" 90 | string 91 | 92 | 93 | 94 | End Tag Name 95 | eob_key 96 | "rx_eob" 97 | string 98 | 99 | 100 | 101 | EOB Delay 102 | eob_delay 103 | 0.0 104 | float 105 | 106 | 107 | 108 | Burst Guard Interval 109 | guard_interval 110 | 0.9 111 | float 112 | 113 | 114 | 115 | in 116 | $type 117 | 118 | 119 | mag 120 | float 121 | 122 | 123 | floor_msg 124 | message 125 | 1 126 | 127 | 128 | 129 | out 130 | $type 131 | 132 | 133 | -------------------------------------------------------------------------------- /grc/nwr_correction_estimator_ff.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Correction Estimator 7 | nwr_correction_estimator_ff 8 | [nwr] 9 | import nwr 10 | nwr.correction_estimator_ff($inspection_length, $inspection_offset, $peak_ref, $trough_ref, $offset_corr_key, $scale_corr_key, $scale_eob_zero, $timing_win_start, $timing_win_end, $time_est_key, $clock_est_key, $sob_key, $eob_key) 11 | 12 | 13 | Inspection Length 14 | inspection_length 15 | 16 | int 17 | 18 | 19 | 20 | Inspection Offset 21 | inspection_offset 22 | 0 23 | int 24 | 25 | 26 | 27 | Expected Peak Level 28 | peak_ref 29 | 1.0 30 | float 31 | 32 | 33 | Expected Trough Level 34 | trough_ref 35 | -1.0 36 | float 37 | 38 | 39 | 40 | Offset Corr Tag Name 41 | offset_corr_key 42 | "offset_corr" 43 | string 44 | part 45 | 46 | 47 | Scale Corr Tag Name 48 | scale_corr_key 49 | "scale_corr" 50 | string 51 | part 52 | 53 | 54 | 55 | Scale Corr at End 56 | scale_eob_zero 57 | False 58 | bool 59 | 63 | 67 | 68 | 69 | 70 | Timing Est. Window Start 71 | timing_win_start 72 | -1 73 | int 74 | #if $timing_win_start() == -1 then 'part' else 'none' 75 | 76 | 77 | Timing Est. Window End 78 | timing_win_end 79 | -1 80 | int 81 | #if $timing_win_end() == -1 then 'part' else 'none' 82 | 83 | 84 | 85 | Timing Estimate Tag Name 86 | time_est_key 87 | "time_est" 88 | string 89 | part 90 | 91 | 92 | Clock Estimate Tag Name 93 | clock_est_key 94 | "clock_est" 95 | string 96 | part 97 | 98 | 99 | 100 | Start Tag Name 101 | sob_key 102 | "rx_sob" 103 | string 104 | part 105 | 106 | 107 | End Tag Name 108 | eob_key 109 | "rx_eob" 110 | string 111 | part 112 | 113 | 114 | 115 | in 116 | float 117 | 118 | 119 | 120 | out 121 | float 122 | 123 | 124 | -------------------------------------------------------------------------------- /grc/nwr_lms_da_equalizer_ff.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | LMS Data-Aided Equalizer 7 | nwr_lms_da_equalizer_ff 8 | [nwr] 9 | import nwr 10 | nwr.lms_da_equalizer_ff($training_samples, $sync_tag, $num_taps, $mu) 11 | set_gain($mu) 12 | 13 | Training samples 14 | training_samples 15 | float_vector 16 | 17 | 18 | Sync tag name 19 | sync_tag 20 | string 21 | 22 | 23 | Equalizer filter length 24 | num_taps 25 | 26 | int 27 | 28 | 29 | LMS DA update step gain 30 | mu 31 | float 32 | 33 | 34 | in 35 | float 36 | 37 | 38 | out 39 | float 40 | 41 | 42 | -------------------------------------------------------------------------------- /grc/nwr_multiply_by_tag_value_ff.xml: -------------------------------------------------------------------------------- 1 | 2 | 21 | 22 | 23 | Multiply by Tag Value 24 | nwr_multiply_by_tag_value_ff 25 | [nwr] 26 | import nwr 27 | nwr.multiply_by_tag_value_ff($tagname, $vlen) 28 | 29 | 30 | Tag Name 31 | tagname 32 | string 33 | 34 | 35 | 36 | Vec Length 37 | vlen 38 | 1 39 | int 40 | 41 | 42 | 43 | in 44 | float 45 | 46 | 47 | 48 | out 49 | float 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /grc/nwr_pll_refout_cc.xml: -------------------------------------------------------------------------------- 1 | 2 | 21 | 22 | PLL Ref Out 23 | nwr_pll_refout_cc 24 | [nwr] 25 | import nwr 26 | nwr.pll_refout_cc($w, $max_freq, $min_freq, $df, $alpha, $beta) 27 | set_loop_bandwidth($w) 28 | set_max_freq($max_freq) 29 | set_min_freq($min_freq) 30 | set_damping_factor($df) 31 | set_alpha($alpha) 32 | set_beta($beta) 33 | 34 | Loop Bandwidth 35 | w 36 | math.pi/100.0 37 | real 38 | #if ($w() >= 0.0) then 'none' else 'part'# 39 | 40 | 41 | Max Freq 42 | max_freq 43 | math.pi/(samp_rate/2.0)*f_max 44 | real 45 | 46 | 47 | Min Freq 48 | min_freq 49 | math.pi/(samp_rate/2.0)*f_min 50 | real 51 | 52 | 53 | Damping Factor 54 | df 55 | 1.0/math.sqrt(2.0) 56 | real 57 | #if ($df() >= 0.0) then 'none' else 'part'# 58 | 59 | 60 | Proportional Gain 61 | alpha 62 | -1.0 63 | real 64 | #if ($alpha() >= 0.0) then 'none' else 'part'# 65 | 66 | 67 | Integral Gain 68 | beta 69 | -1.0 70 | real 71 | #if ($beta() >= 0.0) then 'none' else 'part'# 72 | 73 | 74 | in 75 | complex 76 | 77 | 78 | out 79 | complex 80 | 81 | 82 | phase_error 83 | float 84 | 1 85 | 86 | 87 | phase_inc_inst 88 | float 89 | 1 90 | 91 | 92 | phase_inc_avg 93 | float 94 | 1 95 | 96 | 97 | -------------------------------------------------------------------------------- /grc/nwr_same_burst_decoder.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | SAME Burst Decoder 7 | nwr_same_burst_decoder 8 | [nwr] 9 | import nwr 10 | nwr.same_burst_decoder($sob_key, $eob_key) 11 | 12 | Start Tag Name 13 | sob_key 14 | "rx_sob" 15 | string 16 | 17 | 18 | End Tag Name 19 | eob_key 20 | "rx_eob" 21 | string 22 | 23 | 24 | 25 | in 26 | float 27 | 28 | 29 | 30 | printable 31 | message 32 | 1 33 | 34 | 35 | bytes 36 | message 37 | 1 38 | 39 | 40 | hard_bits 41 | message 42 | 1 43 | 44 | 45 | soft_bits 46 | message 47 | 1 48 | 49 | 50 | -------------------------------------------------------------------------------- /include/nwr/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016-2017 Andy Walls 3 | # 4 | # This file was automatically generated by gr_modtool from GNU Radio 5 | # 6 | # This file was automatically generated from a template incorporating 7 | # data input by Andy Walls and subsequently hand edited by Andy Walls. 8 | # See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 9 | # 10 | 11 | ######################################################################## 12 | # Install public header files 13 | ######################################################################## 14 | install(FILES 15 | api.h 16 | lms_da_equalizer_ff.h 17 | burst_detect_and_tag.h 18 | correction_estimator_ff.h 19 | multiply_by_tag_value_ff.h 20 | add_tag_value_ff.h 21 | pll_refout_cc.h 22 | same_burst_decoder.h DESTINATION include/nwr 23 | ) 24 | -------------------------------------------------------------------------------- /include/nwr/add_tag_value_ff.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2016 Free Software Foundation, Inc. 4 | * Copyright (C) 2016 Andy Walls 5 | * 6 | * This is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * This software is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this software; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | 22 | #ifndef INCLUDED_ADD_TAG_VALUE_FF_H 23 | #define INCLUDED_ADD_TAG_VALUE_FF_H 24 | 25 | #include 26 | #include 27 | 28 | namespace gr { 29 | namespace nwr { 30 | 31 | /*! 32 | * \brief output = input + float constant 33 | * \ingroup nwr 34 | * 35 | * \details 36 | * The float constant used by this block is found from a tag 37 | * with the name specified by \p tag_name. The tag must contain a 38 | * float or double PMT value that will be converted into a 39 | * float value. All input data is add to this 40 | * value until a new tag with an update value is found. The block 41 | * starts with a value of '0.0' for the additive constant. 42 | */ 43 | class NWR_API add_tag_value_ff : virtual public sync_block 44 | { 45 | public: 46 | // gr::nwr::add_tag_value_ff::sptr 47 | typedef boost::shared_ptr sptr; 48 | 49 | /*! 50 | * \brief Create an instance of add_tag_value_ff 51 | * \param tag_name Tag's key that it will use to get the 52 | * additive constant. 53 | * \param vlen Vector length of incoming stream 54 | */ 55 | static sptr make(const std::string& tag_name, 56 | size_t vlen=1); 57 | 58 | /*! 59 | * Get the current additive constant. 60 | * This block does not allow external setters. 61 | */ 62 | virtual float k() const = 0; 63 | }; 64 | 65 | } /* namespace nwr */ 66 | } /* namespace gr */ 67 | 68 | #endif /* INCLUDED_ADD_TAG_VALUE_FF_H */ 69 | -------------------------------------------------------------------------------- /include/nwr/api.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Andy Walls 3 | * 4 | * This file was automatically generated by gr_modtool from GNU Radio 5 | * 6 | * This file was automatically generated from a template incorporating 7 | * data input by Andy Walls. 8 | * See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 9 | */ 10 | 11 | #ifndef INCLUDED_NWR_API_H 12 | #define INCLUDED_NWR_API_H 13 | 14 | #include 15 | 16 | #ifdef gnuradio_nwr_EXPORTS 17 | # define NWR_API __GR_ATTR_EXPORT 18 | #else 19 | # define NWR_API __GR_ATTR_IMPORT 20 | #endif 21 | 22 | #endif /* INCLUDED_NWR_API_H */ 23 | -------------------------------------------------------------------------------- /include/nwr/burst_detect_and_tag.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright (C) 2016 Andy Walls 4 | * 5 | * This file was automatically generated by gr_modtool from GNU Radio 6 | * 7 | * This file was automatically generated from a template incorporating 8 | * data input by Andy Walls and subsequently hand edited by Andy Walls. 9 | * See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 10 | */ 11 | 12 | #ifndef INCLUDED_NWR_BURST_DETECT_AND_TAG_H 13 | #define INCLUDED_NWR_BURST_DETECT_AND_TAG_H 14 | 15 | #include 16 | #include 17 | 18 | namespace gr { 19 | namespace nwr { 20 | 21 | /*! 22 | * \brief Burst/Packet Energy Detector that Tags 23 | * \ingroup nwr 24 | * 25 | * \details 26 | * This block implements an Energy detector that marks the start 27 | * and end of bursts or packets, that cross a threshold for a minimum 28 | * amount of time. 29 | * 30 | * The items from the "in" are passed unmodified to "out", 31 | * except to mark the stream with user specified burst start and end 32 | * tags (e.g. "rx_sob" and "rx_eob"). 33 | * 34 | * The "mag" input should be a stream indicating the signal envelope 35 | * (either magnitude, magnitude^2, or something else) against which the 36 | * threshold comparisons will be made to declare the start or end of burst. 37 | * 38 | * The optional "floor_msg" input expects a message with a single PMT of 39 | * type double to provide an updated noise floor estimate, in units 40 | * consistent for comparison with items on the "mag" input. 41 | * 42 | */ 43 | class NWR_API burst_detect_and_tag : virtual public gr::sync_block 44 | { 45 | public: 46 | typedef boost::shared_ptr sptr; 47 | 48 | /*! 49 | * \brief Make a Burst/Packet Energy Detector that Tags 50 | * 51 | * \param item_size The size of an item passing from "in" to "out" 52 | * \param samp_rate The rate of items passing from "in" to "out" 53 | * \param thresh_db The threshold set point in dB above the noise floor 54 | * \param init_floor_est The initial noise floor estimate 55 | * \param declare_dur The minimum duration required to declare a burst 56 | * \param max_dur The maximum duration allowed for a burst 57 | * \param sob_amp_frac How high up the initial ramp to declare the start 58 | * \param sob_key Tag name for the start of burst marker 59 | * \param eob_key Tag name for the end of burst marker 60 | * \param eob_delay How long after burst falls below threshold to delay 61 | * the end of burst declaration 62 | * \param guard_interval Minimum delay before a new burst can be declared 63 | */ 64 | static sptr make(size_t item_size, 65 | float samp_rate, 66 | float thresh_db, 67 | float init_floor_est, 68 | float declare_dur, 69 | float max_dur, 70 | float sob_amp_frac = 0.0f, 71 | const std::string &sob_key = "rx_sob", 72 | const std::string &eob_key = "rx_eob", 73 | float eob_delay = 0.0, 74 | float guard_interval = 0.9); 75 | }; 76 | 77 | } // namespace nwr 78 | } // namespace gr 79 | 80 | #endif /* INCLUDED_NWR_BURST_DETECT_AND_TAG_H */ 81 | 82 | -------------------------------------------------------------------------------- /include/nwr/correction_estimator_ff.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright (C) 2016 Andy Walls 4 | * 5 | * This file was automatically generated by gr_modtool from GNU Radio 6 | * 7 | * This file was automatically generated from a template incorporating 8 | * data input by Andy Walls and later hand edited by Andy Walls. 9 | * See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 10 | */ 11 | 12 | #ifndef INCLUDED_NWR_CORRECTION_ESTIMATOR_FF_H 13 | #define INCLUDED_NWR_CORRECTION_ESTIMATOR_FF_H 14 | 15 | #include 16 | #include 17 | 18 | namespace gr { 19 | namespace nwr { 20 | 21 | /*! 22 | * \brief (Simple) Correction Estimator (float -> float) 23 | * \ingroup nwr 24 | * 25 | * \details 26 | * This block simplistically estimates offset and scaling corrections 27 | * for a burst of samples from the first N samples of a burst, 28 | * expected to be a preamble, and tags the beginning of the burst with 29 | * the estimated corrections. It also tags the end of the burst to 30 | * indicate the end of corrections (offset of 0.0 and scale of 1.0 or 31 | * optionally 0.0). 32 | */ 33 | class NWR_API correction_estimator_ff : virtual public gr::sync_block 34 | { 35 | public: 36 | typedef boost::shared_ptr sptr; 37 | 38 | /*! 39 | * \brief Make a simple correction estimator (float input/float output) 40 | * 41 | * \param inspection_length Number of samples to use for the estimates 42 | * \param inspection_offset Number of samples to skip before inspection 43 | * \param peak_ref Expected peak level 44 | * \param trough_ref Expected trough level 45 | * \param offset_corr_key Tag name to use for the offset correction 46 | * \param scale_corr_key Tag name to use for the scaling correction 47 | * \param scale_eob_zero Set scaling correction to 0.0 vs 1.0 at end 48 | * \param timing_win_start Relative sample when timing est process starts 49 | * \param timing_win_end Relative sample when timing est process ends 50 | * \param time_est_key Tag name to use for the symbol timing estimate 51 | * \param clock_est_key Tag name to use for the symbol clock estimate 52 | * \param sob_key Tag name that indicates the start of a burst 53 | * \param eob_key Tag name that indicates the end of a burst 54 | */ 55 | static sptr make(int inspection_length, 56 | int inspection_offset = 0, 57 | float peak_ref = 1.0f, 58 | float trough_ref = -1.0f, 59 | const std::string &offset_corr_key = "offset_corr", 60 | const std::string &scale_corr_key = "scale_corr", 61 | bool scale_eob_zero = false, 62 | int timing_win_start = -1, 63 | int timing_win_end = -1, 64 | const std::string &time_est_key = "time_est", 65 | const std::string &clock_est_key = "clock_est", 66 | const std::string &sob_key = "rx_sob", 67 | const std::string &eob_key = "rx_eob"); 68 | }; 69 | 70 | } // namespace nwr 71 | } // namespace gr 72 | 73 | #endif /* INCLUDED_NWR_CORRECTION_ESTIMATOR_FF_H */ 74 | 75 | -------------------------------------------------------------------------------- /include/nwr/lms_da_equalizer_ff.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright (C) 2016 Andy Walls 4 | * 5 | * This file was automatically generated by gr_modtool from GNU Radio 6 | * 7 | * This file was automatically generated from a template incorporating 8 | * data input by Andy Walls. 9 | * See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 10 | */ 11 | 12 | #ifndef INCLUDED_NWR_LMS_DA_EQUALIZER_FF_H 13 | #define INCLUDED_NWR_LMS_DA_EQUALIZER_FF_H 14 | 15 | #include 16 | #include 17 | 18 | namespace gr { 19 | namespace nwr { 20 | 21 | /*! 22 | * \brief Data-Aided LMS Feed-Forward Estimator Equalizer (float -> float) 23 | * \ingroup nwr 24 | * 25 | * \details 26 | * This block implements an equalizer using a data-aided LMS feed-forward 27 | * estimator. This block assumes it occurs *before* clock recovery. 28 | * 29 | * The "data" in "data-aided" is a sync word sample sequence, whose 30 | * position has already been marked with a tag by the corr_est block. 31 | * 32 | * The LMS algorithm used is from: 33 | * Moon, Todd K.; Stirling, Wynn C.; _Mathematical_Methods_and_Algorithms_ 34 | * for_Signal_Processing_; Prentice Hall, 2000, ISBN 0-201-36186-8 35 | */ 36 | class NWR_API lms_da_equalizer_ff : virtual public gr::sync_block 37 | { 38 | public: 39 | typedef boost::shared_ptr sptr; 40 | 41 | /*! 42 | * \brief Make a LMS data-aided equalizer (float input/float output) 43 | * 44 | * \param training_samples Training sequence samples 45 | * \param sync_tag Tag name to trigger retraining of the equalizer 46 | * \param num_taps Length of the equalization filter 47 | * \param mu LMS update step size (an error signal gain) 48 | * 49 | * In general, the LMS solution only converges when the mu is 50 | * less than 2.0/(num_taps * signal_power). So predictable 51 | * convergence requires an AGC before this block. Also shorter 52 | * equalizer filters are prefered to reduce processing load. 53 | * The smaller the mu, the slower the filter adaptation. 54 | */ 55 | 56 | static sptr make(const std::vector &training_samples, 57 | const std::string &sync_tag, 58 | unsigned int num_taps, 59 | float mu); 60 | 61 | virtual void set_taps(const std::vector &taps) = 0; 62 | virtual std::vector taps() const = 0; 63 | virtual float gain() const = 0; 64 | virtual void set_gain(float mu) = 0; 65 | 66 | }; 67 | 68 | } // namespace nwr 69 | } // namespace gr 70 | 71 | #endif /* INCLUDED_NWR_LMS_DA_EQUALIZER_FF_H */ 72 | 73 | -------------------------------------------------------------------------------- /include/nwr/multiply_by_tag_value_ff.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2016 Free Software Foundation, Inc. 4 | * Copyright (C) 2016 Andy Walls 5 | * 6 | * This is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * This software is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this software; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | 22 | #ifndef INCLUDED_MULTIPLY_BY_TAG_VALUE_FF_H 23 | #define INCLUDED_MULTIPLY_BY_TAG_VALUE_FF_H 24 | 25 | #include 26 | #include 27 | 28 | namespace gr { 29 | namespace nwr { 30 | 31 | /*! 32 | * \brief output = input * float constant 33 | * \ingroup nwr 34 | * 35 | * \details 36 | * The float constant used by this block is found from a tag 37 | * with the name specified by \p tag_name. The tag must contain a 38 | * float or double PMT value that will be converted into a 39 | * float value. All input data is multiplied by this 40 | * value until a new tag with an update value is found. The block 41 | * starts with a value of '1.0' for the multiplier constant. 42 | */ 43 | class NWR_API multiply_by_tag_value_ff : virtual public sync_block 44 | { 45 | public: 46 | // gr::nwr::multiply_by_tag_value_ff::sptr 47 | typedef boost::shared_ptr sptr; 48 | 49 | /*! 50 | * \brief Create an instance of multiply_by_tag_value_ff 51 | * \param tag_name Tag's key that it will use to get the 52 | * multiplicative constant. 53 | * \param vlen Vector length of incoming stream 54 | */ 55 | static sptr make(const std::string& tag_name, 56 | size_t vlen=1); 57 | 58 | /*! 59 | * Get the current multiplicative constant. 60 | * This block does not allow external setters. 61 | */ 62 | virtual float k() const = 0; 63 | }; 64 | 65 | } /* namespace nwr */ 66 | } /* namespace gr */ 67 | 68 | #endif /* INCLUDED_MULTIPLY_BY_TAG_VALUE_FF_H */ 69 | -------------------------------------------------------------------------------- /include/nwr/pll_refout_cc.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2004,2011,2012 Free Software Foundation, Inc. 4 | * Copyright (C) 2017 Andy Walls 5 | * 6 | * GNU Radio is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * GNU Radio is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | 22 | #ifndef INCLUDED_NWR_PLL_REFOUT_CC_H 23 | #define INCLUDED_NWR_PLL_REFOUT_CC_H 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | namespace gr { 31 | namespace nwr { 32 | 33 | /*! 34 | * \brief Implements a PLL which locks to the input frequency and outputs a carrier 35 | * \ingroup synchronizers_blk 36 | * 37 | * \details 38 | * Input stream 0: complex 39 | * Output stream 0: complex 40 | * 41 | * This PLL locks onto a [possibly noisy] reference carrier on the 42 | * input and outputs a clean version which is phase and frequency 43 | * aligned to it. 44 | * 45 | * All settings max_freq and min_freq are in terms of radians per 46 | * sample, NOT HERTZ. The loop bandwidth determins the lock range. 47 | */ 48 | class NWR_API pll_refout_cc 49 | : virtual public sync_block, 50 | virtual public blocks::control_loop 51 | { 52 | public: 53 | // gr::nwr::pll_refout_cc::sptr 54 | typedef boost::shared_ptr sptr; 55 | 56 | /* \brief Make PLL block that outputs the tracked carrier signal. 57 | * 58 | * \param loop_bw: control loop's bandwidth parameter. 59 | * \param max_freq: maximum (normalized) frequency PLL will lock to. 60 | * \param min_freq: minimum (normalized) frequency PLL will lock to. 61 | * \param df: damping factor, default is 1.0/sqrt(2.0) 62 | * \param alpha: PI filter proportional gain, overrides loop_bw & df. 63 | * \param beta: PI filter integral gain, overrides loop_bw & df. 64 | */ 65 | static sptr make(float loop_bw, float max_freq, float min_freq, 66 | float df = M_SQRT1_2, 67 | float alpha = -1.0f, float beta = -1.0f); 68 | }; 69 | 70 | } /* namespace nwr */ 71 | } /* namespace gr */ 72 | 73 | #endif /* INCLUDED_NWR_PLL_REFOUT_CC_H */ 74 | -------------------------------------------------------------------------------- /include/nwr/same_burst_decoder.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright (C) 2016 Andy Walls 4 | * 5 | * This file was automatically generated by gr_modtool from GNU Radio 6 | * 7 | * This file was automatically generated from a template incorporating 8 | * data input by Andy Walls and later hand edited by Andy Walls. 9 | * See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 10 | */ 11 | 12 | #ifndef INCLUDED_NWR_SAME_BURST_DECODER_H 13 | #define INCLUDED_NWR_SAME_BURST_DECODER_H 14 | 15 | #include 16 | #include 17 | 18 | namespace gr { 19 | namespace nwr { 20 | 21 | /*! 22 | * \brief SAME Burst Decoder 23 | * \ingroup nwr 24 | * 25 | * \details 26 | * This block takes on input delimited bursts of soft bits corresponding to 27 | * a received SAME message. This decodes the burst, and outputs the burst 28 | * in a number of forms in messages containing: 29 | * printable ASCII 30 | * properly aligned bytes 31 | * hard bits 32 | * soft bits 33 | * 34 | * The format of NWR Specific Area Message Encoding (SAME) messages 35 | * is documented here: 36 | * http://www.nws.noaa.gov/nwr/info/nwrsame.html 37 | */ 38 | class NWR_API same_burst_decoder : virtual public gr::sync_block 39 | { 40 | public: 41 | typedef boost::shared_ptr sptr; 42 | 43 | /*! 44 | * \brief Make a SAME burst decoder block 45 | * 46 | * \param sob_key Tag name that indicates the start of a burst 47 | * \param eob_key Tag name that indicates the end of a burst 48 | */ 49 | static sptr make(const std::string &sob_key = "rx_sob", 50 | const std::string &eob_key = "rx_eob"); 51 | }; 52 | 53 | } // namespace nwr 54 | } // namespace gr 55 | 56 | #endif /* INCLUDED_NWR_SAME_BURST_DECODER_H */ 57 | 58 | -------------------------------------------------------------------------------- /lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016 Andy Walls 3 | # 4 | # This file was automatically generated by gr_modtool from GNU Radio 5 | # 6 | # This file was automatically generated from a template incorporating 7 | # data input by Andy Walls and subsequently hand edited by Andy Walls. 8 | # See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 9 | # 10 | 11 | ######################################################################## 12 | # Setup library 13 | ######################################################################## 14 | include(GrPlatform) #define LIB_SUFFIX 15 | 16 | include_directories(${Boost_INCLUDE_DIR} ${UHD_INCLUDE_DIR}) 17 | link_directories(${Boost_LIBRARY_DIRS} ${UHD_LIBRARY_DIRS}) 18 | 19 | list(APPEND nwr_sources 20 | lms_da_equalizer_ff_impl.cc 21 | burst_detect_and_tag_impl.cc 22 | correction_estimator_ff_impl.cc 23 | multiply_by_tag_value_ff_impl.cc 24 | add_tag_value_ff_impl.cc 25 | pll_refout_cc_impl.cc 26 | same_burst_decoder_impl.cc 27 | ) 28 | 29 | set(nwr_sources "${nwr_sources}" PARENT_SCOPE) 30 | if(NOT nwr_sources) 31 | MESSAGE(STATUS "No C++ sources... skipping lib/") 32 | return() 33 | endif(NOT nwr_sources) 34 | 35 | add_library(gnuradio-nwr SHARED ${nwr_sources}) 36 | target_link_libraries(gnuradio-nwr ${Boost_LIBRARIES} ${UHD_LIBRARIES} ${GNURADIO_ALL_LIBRARIES}) 37 | set_target_properties(gnuradio-nwr PROPERTIES DEFINE_SYMBOL "gnuradio_nwr_EXPORTS") 38 | 39 | if(APPLE) 40 | set_target_properties(gnuradio-nwr PROPERTIES 41 | INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib" 42 | ) 43 | endif(APPLE) 44 | 45 | ######################################################################## 46 | # Install built library files 47 | ######################################################################## 48 | include(GrMiscUtils) 49 | GR_LIBRARY_FOO(gnuradio-nwr RUNTIME_COMPONENT "nwr_runtime" DEVEL_COMPONENT "nwr_devel") 50 | 51 | ######################################################################## 52 | # Build and register unit test 53 | ######################################################################## 54 | include(GrTest) 55 | 56 | include_directories(${CPPUNIT_INCLUDE_DIRS}) 57 | 58 | list(APPEND test_nwr_sources 59 | ${CMAKE_CURRENT_SOURCE_DIR}/test_nwr.cc 60 | ${CMAKE_CURRENT_SOURCE_DIR}/qa_nwr.cc 61 | ) 62 | 63 | add_executable(test-nwr ${test_nwr_sources}) 64 | 65 | target_link_libraries( 66 | test-nwr 67 | ${GNURADIO_RUNTIME_LIBRARIES} 68 | ${Boost_LIBRARIES} 69 | ${UHD_LIBRARIES} 70 | ${CPPUNIT_LIBRARIES} 71 | gnuradio-nwr 72 | ) 73 | 74 | GR_ADD_TEST(test_nwr test-nwr) 75 | 76 | ######################################################################## 77 | # Print summary 78 | ######################################################################## 79 | message(STATUS "Using install prefix: ${CMAKE_INSTALL_PREFIX}") 80 | message(STATUS "Building for version: ${VERSION} / ${LIBVER}") 81 | 82 | -------------------------------------------------------------------------------- /lib/add_tag_value_ff_impl.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2016 Free Software Foundation, Inc. 4 | * Copyright (C) 2016 Andy Walls 5 | * 6 | * GNU Radio is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * GNU Radio is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | 22 | #ifdef HAVE_CONFIG_H 23 | #include "config.h" 24 | #endif 25 | 26 | #include 27 | #include 28 | // FIXME we need a volk_32f_s32f_add_32f kernel created 29 | // #include 30 | 31 | namespace gr { 32 | namespace nwr { 33 | 34 | add_tag_value_ff::sptr 35 | add_tag_value_ff::make(const std::string& tag_name, size_t vlen) 36 | { 37 | return gnuradio::get_initial_sptr 38 | (new add_tag_value_ff_impl(tag_name, vlen)); 39 | } 40 | 41 | add_tag_value_ff_impl::add_tag_value_ff_impl(const std::string& tag_name, 42 | size_t vlen) 43 | : sync_block("add_tag_value_ff", 44 | io_signature::make (1, 1, sizeof (float)*vlen), 45 | io_signature::make (1, 1, sizeof (float)*vlen)), 46 | d_vlen(vlen), d_k(0.0f) 47 | { 48 | d_tag_key = pmt::intern(tag_name); 49 | 50 | // FIXME we need a volk_32f_s32f_add_32f kernel created 51 | //const int alignment_multiple = 52 | // volk_get_alignment() / sizeof(float); 53 | //set_alignment(std::max(1,alignment_multiple)); 54 | } 55 | 56 | add_tag_value_ff_impl::~add_tag_value_ff_impl() 57 | { 58 | } 59 | 60 | float 61 | add_tag_value_ff_impl::k() const 62 | { 63 | return d_k; 64 | } 65 | 66 | // FIXME we need a volk_32f_s32f_add_32f kernel created 67 | void 68 | add_tag_value_ff_impl::notvolk_32f_s32f_add_32f(float* cVector, 69 | const float* aVector, 70 | const float scalar, 71 | unsigned int num_points) 72 | { 73 | unsigned int number = 0; 74 | const float* inputPtr = aVector; 75 | float* outputPtr = cVector; 76 | for(number = 0; number < num_points; number++){ 77 | *outputPtr = (*inputPtr) + scalar; 78 | inputPtr++; 79 | outputPtr++; 80 | } 81 | } 82 | 83 | int 84 | add_tag_value_ff_impl::work(int noutput_items, 85 | gr_vector_const_void_star &input_items, 86 | gr_vector_void_star &output_items) 87 | { 88 | const float *in = (const float *) input_items[0]; 89 | float *out = (float *) output_items[0]; 90 | 91 | std::vector tags; 92 | get_tags_in_window(tags, 0, 0, noutput_items, d_tag_key); 93 | 94 | std::vector::iterator itag = tags.begin(); 95 | 96 | int start = 0, end; 97 | while(itag != tags.end()) { 98 | end = itag->offset - nitems_read(0); 99 | end *= d_vlen; 100 | 101 | // Add the current value of k from 'start' to 'end' 102 | // FIXME we need a volk_32f_s32f_add_32f kernel created 103 | notvolk_32f_s32f_add_32f(&out[start], &in[start], d_k, (end-start)); 104 | start = end; 105 | 106 | // Extract new value of k 107 | pmt::pmt_t k = itag->value; 108 | if(pmt::is_number(k)) { 109 | d_k = static_cast(pmt::to_double(k)); 110 | } 111 | else { 112 | GR_LOG_WARN(d_logger, 113 | boost::format("Got key '%1%' with incompatible value of '%2%'") \ 114 | % pmt::write_string(d_tag_key) % pmt::write_string(k)); 115 | } 116 | 117 | itag++; 118 | } 119 | 120 | // FIXME we need a volk_32f_s32f_add_32f kernel created 121 | notvolk_32f_s32f_add_32f(&out[start], &in[start], d_k, 122 | (d_vlen*noutput_items-start)); 123 | 124 | return noutput_items; 125 | } 126 | 127 | void 128 | add_tag_value_ff_impl::setup_rpc() 129 | { 130 | #ifdef GR_CTRLPORT 131 | add_rpc_variable( 132 | rpcbasic_sptr(new rpcbasic_register_get( 133 | alias(), "Constant", 134 | &add_tag_value_ff::k, 135 | pmt::from_double(-1024.0), 136 | pmt::from_double(1024.0), 137 | pmt::from_double(0.0), 138 | "", "Constant to add", RPC_PRIVLVL_MIN, 139 | DISPTIME | DISPOPTCPLX | DISPOPTSTRIP))); 140 | #endif /* GR_CTRLPORT */ 141 | } 142 | 143 | } /* namespace nwr */ 144 | } /* namespace gr */ 145 | -------------------------------------------------------------------------------- /lib/add_tag_value_ff_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2016 Free Software Foundation, Inc. 4 | * Copyright (C) 2016 Andy Walls 5 | * 6 | * GNU Radio is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * GNU Radio is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | 22 | #ifndef INCLUDED_ADD_TAG_VALUE_FF_IMPL_H 23 | #define INCLUDED_ADD_TAG_VALUE_FF_IMPL_H 24 | 25 | #include 26 | 27 | namespace gr { 28 | namespace nwr { 29 | 30 | class NWR_API add_tag_value_ff_impl 31 | : public add_tag_value_ff 32 | { 33 | private: 34 | size_t d_vlen; 35 | pmt::pmt_t d_tag_key; 36 | float d_k; 37 | 38 | void notvolk_32f_s32f_add_32f(float* cVector, 39 | const float* aVector, 40 | const float scalar, 41 | unsigned int num_points); 42 | 43 | public: 44 | add_tag_value_ff_impl(const std::string& tag_name, size_t vlen); 45 | ~add_tag_value_ff_impl(); 46 | 47 | float k() const; 48 | 49 | void setup_rpc(); 50 | 51 | int work(int noutput_items, 52 | gr_vector_const_void_star &input_items, 53 | gr_vector_void_star &output_items); 54 | }; 55 | 56 | } /* namespace nwr */ 57 | } /* namespace gr */ 58 | 59 | #endif /* INCLUDED_ADD_TAG_VALUE_FF_IMPL_H */ 60 | -------------------------------------------------------------------------------- /lib/burst_detect_and_tag_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright (C) 2016 Andy Walls 4 | * 5 | * This file was automatically generated by gr_modtool from GNU Radio 6 | * 7 | * This file was automatically generated from a template incorporating 8 | * data input by Andy Walls and subsequently hand edited by Andy Walls. 9 | * See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 10 | */ 11 | 12 | #ifndef INCLUDED_NWR_BURST_DETECT_AND_TAG_IMPL_H 13 | #define INCLUDED_NWR_BURST_DETECT_AND_TAG_IMPL_H 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | namespace gr { 20 | namespace nwr { 21 | 22 | class burst_detect_and_tag_impl : public burst_detect_and_tag 23 | { 24 | private: 25 | const size_t d_item_size; 26 | const float d_samp_rate; 27 | const float d_threshold; 28 | gr::thread::mutex d_floor_mutex; 29 | float d_floor; 30 | const int d_declare_len; 31 | const unsigned int d_max_len; 32 | const float d_sob_amp_frac; 33 | long int d_eob_smpl_delay; 34 | const unsigned long int d_guard_smpl_intvl; 35 | const pmt::pmt_t d_sob_key; 36 | const pmt::pmt_t d_eob_key; 37 | const pmt::pmt_t d_src_id; 38 | const pmt::pmt_t d_rx_time_key; 39 | const pmt::pmt_t d_msg_port; 40 | float *d_result; 41 | 42 | enum det_state { SEARCH, WINDOW, BURST, GUARD }; 43 | det_state d_state; 44 | unsigned int d_burst_len; 45 | unsigned int d_eob_len; 46 | uint64_t d_last_eob_offset; 47 | 48 | std::vector d_tags; 49 | 50 | ::uhd::time_spec_t d_ref_time; 51 | uint64_t d_ref_time_offset; 52 | 53 | void msg_handler(pmt::pmt_t msg); 54 | int calc_sob_index(int first, int last); 55 | 56 | bool parse_time_tag(const tag_t &time_tag, 57 | uint64_t &seconds, double &subseconds); 58 | void update_ref_time(uint64_t offset); 59 | pmt::pmt_t compute_sample_time(uint64_t offset); 60 | 61 | int find_next_above_thresh(const int start, const int end); 62 | int find_next_at_or_below_thresh(const int start, const int end); 63 | 64 | public: 65 | burst_detect_and_tag_impl(size_t item_size, 66 | float samp_rate, 67 | float thresh_db, 68 | float init_floor_est, 69 | float declare_dur, 70 | float max_dur, 71 | float sob_amp_frac, 72 | const std::string &sob_key, 73 | const std::string &eob_key, 74 | float eob_delay, 75 | float guard_interval); 76 | ~burst_detect_and_tag_impl(); 77 | 78 | int work(int noutput_items, 79 | gr_vector_const_void_star &input_items, 80 | gr_vector_void_star &output_items); 81 | }; 82 | 83 | } // namespace nwr 84 | } // namespace gr 85 | 86 | #endif /* INCLUDED_NWR_BURST_DETECT_AND_TAG_IMPL_H */ 87 | 88 | -------------------------------------------------------------------------------- /lib/correction_estimator_ff_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright (C) 2016 Andy Walls 4 | * 5 | * This file was automatically generated by gr_modtool from GNU Radio 6 | * 7 | * This file was automatically generated from a template incorporating 8 | * data input by Andy Walls and subsequently hand edited by Andy Walls. 9 | * See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 10 | */ 11 | 12 | #ifndef INCLUDED_NWR_CORRECTION_ESTIMATOR_FF_IMPL_H 13 | #define INCLUDED_NWR_CORRECTION_ESTIMATOR_FF_IMPL_H 14 | 15 | #include 16 | #include 17 | 18 | namespace gr { 19 | namespace nwr { 20 | 21 | class correction_estimator_ff_impl : public correction_estimator_ff 22 | { 23 | private: 24 | int d_inspection_len; 25 | int d_inspection_offset; 26 | float d_peak_ref; 27 | float d_trough_ref; 28 | int d_timing_win_start; 29 | int d_timing_win_end; 30 | pmt::pmt_t d_offset_corr_key; 31 | pmt::pmt_t d_scale_corr_key; 32 | pmt::pmt_t d_time_est_key; 33 | pmt::pmt_t d_clock_est_key; 34 | pmt::pmt_t d_sob_key; 35 | pmt::pmt_t d_eob_key; 36 | pmt::pmt_t d_eob_offset_corr; 37 | pmt::pmt_t d_eob_scale_corr; 38 | pmt::pmt_t d_src_id; 39 | 40 | std::vector d_tags; 41 | 42 | void compute_corrections(const float *in, 43 | double &offset_corr, double &scale_corr); 44 | 45 | bool compute_timing_estimate(const float *in, 46 | uint64_t &n, double &fraction, 47 | double &clock_period); 48 | 49 | public: 50 | correction_estimator_ff_impl(int inspection_length, 51 | int inspection_offset, 52 | float peak_ref, 53 | float trough_ref, 54 | const std::string &offset_corr_key, 55 | const std::string &scale_corr_key, 56 | bool scale_eob_zero, 57 | int timing_win_start, 58 | int timing_win_end, 59 | const std::string &time_est_key, 60 | const std::string &clock_est_key, 61 | const std::string &sob_key, 62 | const std::string &eob_key); 63 | ~correction_estimator_ff_impl(); 64 | 65 | int work(int noutput_items, 66 | gr_vector_const_void_star &input_items, 67 | gr_vector_void_star &output_items); 68 | }; 69 | 70 | } // namespace nwr 71 | } // namespace gr 72 | 73 | #endif /* INCLUDED_NWR_CORRECTION_ESTIMATOR_FF_IMPL_H */ 74 | 75 | -------------------------------------------------------------------------------- /lib/lms_da_equalizer_ff_impl.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright (C) 2016 Andy Walls 4 | * 5 | * This file was automatically generated by gr_modtool from GNU Radio 6 | * 7 | * This file was automatically generated from a template incorporating 8 | * data input by Andy Walls. 9 | * See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 10 | */ 11 | 12 | #ifdef HAVE_CONFIG_H 13 | #include "config.h" 14 | #endif 15 | 16 | #include 17 | #include "lms_da_equalizer_ff_impl.h" 18 | #include 19 | 20 | namespace gr { 21 | namespace nwr { 22 | 23 | lms_da_equalizer_ff::sptr 24 | lms_da_equalizer_ff::make(const std::vector &training_samples, 25 | const std::string &sync_tag, 26 | unsigned int num_taps, 27 | float mu) 28 | { 29 | return gnuradio::get_initial_sptr 30 | (new lms_da_equalizer_ff_impl(training_samples, 31 | sync_tag, 32 | num_taps, 33 | mu)); 34 | } 35 | 36 | lms_da_equalizer_ff_impl::lms_da_equalizer_ff_impl( 37 | const std::vector &training_samples, 38 | const std::string &sync_tag, 39 | unsigned int num_taps, 40 | float mu) 41 | : gr::sync_block("lms_da_equalizer_ff", 42 | gr::io_signature::make(1, 1, sizeof(float)), 43 | gr::io_signature::make(1, 1, sizeof(float))), 44 | fir_filter_fff(1, std::vector(num_taps, 0.0f)), 45 | d_sync_tag_key(pmt::intern(sync_tag)), 46 | d_new_taps(num_taps, 0.0f), 47 | d_updated(false), 48 | d_training_samples(training_samples), 49 | d_error(0.0f) 50 | { 51 | const int alignment_multiple = volk_get_alignment() / sizeof(float); 52 | set_alignment(std::max(1, alignment_multiple)); 53 | 54 | set_gain(mu); 55 | 56 | if (num_taps > 0) 57 | d_new_taps[0] = 1.0f; 58 | fir_filter_fff::set_taps(d_new_taps); 59 | set_history(fir_filter_fff::ntaps()); 60 | declare_sample_delay(0, (fir_filter_fff::ntaps() - 1)/2); 61 | } 62 | 63 | lms_da_equalizer_ff_impl::~lms_da_equalizer_ff_impl() 64 | { 65 | } 66 | 67 | void 68 | lms_da_equalizer_ff_impl::set_taps(const std::vector &taps) 69 | { 70 | // FIXME check on tap reversal 71 | d_new_taps = taps; 72 | d_updated = true; 73 | } 74 | 75 | std::vector 76 | lms_da_equalizer_ff_impl::taps() const 77 | { 78 | // FIXME check on tap reversal 79 | return fir_filter_fff::taps(); 80 | } 81 | 82 | void 83 | lms_da_equalizer_ff_impl::reinit_taps(void) 84 | { 85 | std::vector initial_taps(fir_filter_fff::ntaps(), 0.0f); 86 | 87 | if (initial_taps.size() > 0) 88 | initial_taps[0] = 1.0; 89 | fir_filter_fff::set_taps(initial_taps); 90 | } 91 | 92 | float 93 | lms_da_equalizer_ff_impl::a_priori_error(unsigned int i, float y) 94 | { 95 | return d_training_samples[i] - y; 96 | } 97 | 98 | void 99 | lms_da_equalizer_ff_impl::update_tap(float &tap, const float x) 100 | { 101 | tap += d_mu * x * d_error; 102 | } 103 | 104 | void 105 | lms_da_equalizer_ff_impl::filter_no_adapt(float *out, const float *in, 106 | unsigned int len) 107 | { 108 | fir_filter_fff::filterN(out, in, static_cast(len)); 109 | } 110 | 111 | void 112 | lms_da_equalizer_ff_impl::filter_and_adapt(float *out, const float *in, 113 | unsigned int len) 114 | { 115 | unsigned int i, j; 116 | unsigned int n = fir_filter_fff::ntaps(); 117 | 118 | for (i = 0; i < len; i++) { 119 | // Filter the next sample 120 | out[i] = fir_filter_fff::filter(&in[i]); 121 | 122 | // Compute the a-priori error from the expected signal 123 | d_error = a_priori_error(i, out[i]); 124 | 125 | // Adapt the equalization filter taps based on the error 126 | for (j = 0; j < n; j++) { 127 | // Update tap locally from d_error 128 | // N.B. this relies on the fir_filter_fff object's 129 | // d_taps being stored in reverse order. 130 | update_tap(d_taps[j], in[i+j]); 131 | 132 | // Update aligned taps in fir_filter_fff object 133 | fir_filter_fff::update_tap(d_taps[j], j); 134 | } 135 | } 136 | } 137 | 138 | bool 139 | lms_da_equalizer_ff_impl::p_tag_compare(const tag_t &a, const tag_t &b) 140 | { 141 | return (pmt::to_double(a.value) < pmt::to_double(b.value)); 142 | } 143 | 144 | 145 | void 146 | lms_da_equalizer_ff_impl::prune_sync_tags(std::vector p_tags) 147 | { 148 | unsigned int training_len = d_training_samples.size(); 149 | uint64_t ofirst; 150 | std::vector::iterator p; 151 | std::vector cluster; 152 | std::vector output; 153 | 154 | std::sort(p_tags.begin(), p_tags.end(), tag_t::offset_compare); 155 | 156 | // Sync sequence correlation tags will cluster together near the 157 | // start of a sync sequence so ditch all but the maximum in each 158 | // cluster. We assume the lower valued ones are false correlations 159 | // due to the correlator threshold setting being too low. 160 | output.clear(); 161 | p = p_tags.begin(); 162 | while (p != p_tags.end()) { 163 | // This sync tag starts a new cluster 164 | cluster.clear(); 165 | ofirst = p->offset; 166 | 167 | // Add nearby sync tags to the cluster 168 | do { 169 | cluster.push_back(*p); 170 | p++; 171 | } while (p != p_tags.end() and 172 | p->offset < (ofirst + training_len)); 173 | 174 | // Select the sync tag with the maximum correlation value 175 | // as the winner. 176 | output.push_back(*std::max_element(cluster.begin(), 177 | cluster.end(), 178 | lms_da_equalizer_ff_impl::p_tag_compare)); 179 | } 180 | 181 | p_tags = output; 182 | } 183 | 184 | 185 | int 186 | lms_da_equalizer_ff_impl::work(int noutput_items, 187 | gr_vector_const_void_star &input_items, 188 | gr_vector_void_star &output_items) 189 | { 190 | const float *in = (const float *) input_items[0]; 191 | float *out = (float *) output_items[0]; 192 | 193 | // If the user forces the equalizer taps, then change them. 194 | // Since we will reinit the taps at the next sync sequence, 195 | // the particular user taps values don't matter much. 196 | // This is really only useful for changing the length of the 197 | // equalization filter. 198 | if (d_updated) { 199 | fir_filter_fff::set_taps(d_new_taps); 200 | set_history(fir_filter_fff::ntaps()); 201 | declare_sample_delay(0, (fir_filter_fff::ntaps() - 1)/2); 202 | d_updated = false; 203 | return 0; // history requirement may have changed 204 | } 205 | 206 | uint64_t soffset = nitems_read(0); 207 | 208 | // Get all the sync tags in offset order 209 | std::vector p_tags; 210 | std::vector::iterator p; 211 | get_tags_in_range(p_tags, 212 | 0, soffset, soffset + noutput_items, d_sync_tag_key); 213 | 214 | prune_sync_tags(p_tags); 215 | 216 | unsigned int training_len = d_training_samples.size(); 217 | 218 | int idx = 0; 219 | uint64_t w_start = soffset; 220 | uint64_t w_len; 221 | 222 | // We work under the assumption that we will never start mid sync seq. 223 | 224 | for (p = p_tags.begin(); p != p_tags.end(); p++) { 225 | if (p->offset < w_start) { 226 | // Hmm. Somehow after pruning we still had multiple 227 | // sync tag markers within 1 sync sequence length. 228 | // We already performed filtering and data-aided adaptation 229 | // based on the first marker, so ditch this one. 230 | continue; 231 | } 232 | 233 | // Filter without and adaptation 234 | w_len = p->offset - w_start; 235 | filter_no_adapt(&out[idx], &in[idx], w_len); 236 | idx += w_len; 237 | w_start += w_len; 238 | 239 | // If not enough items left to perform Data-Aided adapation, 240 | // then bail-out, so we never come into work() mid sync sequence. 241 | if (idx + training_len >= noutput_items) 242 | return idx; 243 | 244 | // Reset equalization filter and filter and perform 245 | // Data-Aided adaptation using the training samples 246 | w_len = training_len; 247 | reinit_taps(); 248 | filter_and_adapt(&out[idx], &in[idx], w_len); 249 | idx += w_len; 250 | w_start += w_len; 251 | } 252 | 253 | // Filter without and adaptation 254 | w_len = (soffset + noutput_items) - w_start; 255 | filter_no_adapt(&out[idx], &in[idx], w_len); 256 | idx += w_len; 257 | w_start += w_len; 258 | return idx; 259 | } 260 | 261 | } /* namespace nwr */ 262 | } /* namespace gr */ 263 | 264 | -------------------------------------------------------------------------------- /lib/lms_da_equalizer_ff_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright (C) 2016 Andy Walls 4 | * 5 | * This file was automatically generated by gr_modtool from GNU Radio 6 | * 7 | * This file was automatically generated from a template incorporating 8 | * data input by Andy Walls. 9 | * See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 10 | */ 11 | 12 | #ifndef INCLUDED_NWR_LMS_DA_EQUALIZER_FF_IMPL_H 13 | #define INCLUDED_NWR_LMS_DA_EQUALIZER_FF_IMPL_H 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | namespace gr { 20 | namespace nwr { 21 | 22 | class lms_da_equalizer_ff_impl 23 | : public lms_da_equalizer_ff, filter::kernel::fir_filter_fff 24 | { 25 | private: 26 | pmt::pmt_t d_sync_tag_key; 27 | 28 | std::vector d_new_taps; 29 | bool d_updated; 30 | 31 | float d_mu; 32 | std::vector d_training_samples; 33 | 34 | float d_error; 35 | 36 | void reinit_taps(void); 37 | float a_priori_error(unsigned int i, float y); 38 | void update_tap(float &tap, const float x); 39 | void filter_no_adapt(float *out, const float *in, unsigned int len); 40 | void filter_and_adapt(float *out, const float *in, unsigned int len); 41 | 42 | static bool p_tag_compare(const tag_t &a, const tag_t &b); 43 | void prune_sync_tags(std::vector p_tags); 44 | 45 | public: 46 | lms_da_equalizer_ff_impl(const std::vector &training_samples, 47 | const std::string &sync_tag, 48 | unsigned int num_taps, 49 | float mu); 50 | ~lms_da_equalizer_ff_impl(); 51 | 52 | int work(int noutput_items, 53 | gr_vector_const_void_star &input_items, 54 | gr_vector_void_star &output_items); 55 | 56 | void set_taps(const std::vector &taps); 57 | std::vector taps() const; 58 | 59 | float gain() const { return d_mu; } 60 | void set_gain(float mu) 61 | { 62 | if (mu < 0.0f) 63 | throw std::out_of_range( 64 | "lms_da_equalizer_ff::set_gain: mu must be greater than 0"); 65 | d_mu = mu; 66 | } 67 | 68 | }; 69 | 70 | } // namespace nwr 71 | } // namespace gr 72 | 73 | #endif /* INCLUDED_NWR_LMS_DA_EQUALIZER_FF_IMPL_H */ 74 | 75 | -------------------------------------------------------------------------------- /lib/multiply_by_tag_value_ff_impl.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2016 Free Software Foundation, Inc. 4 | * Copyright (C) 2016 Andy Walls 5 | * 6 | * GNU Radio is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * GNU Radio is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | 22 | #ifdef HAVE_CONFIG_H 23 | #include "config.h" 24 | #endif 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | namespace gr { 31 | namespace nwr { 32 | 33 | multiply_by_tag_value_ff::sptr 34 | multiply_by_tag_value_ff::make(const std::string& tag_name, 35 | size_t vlen) 36 | { 37 | return gnuradio::get_initial_sptr 38 | (new multiply_by_tag_value_ff_impl(tag_name, vlen)); 39 | } 40 | 41 | multiply_by_tag_value_ff_impl::multiply_by_tag_value_ff_impl(const std::string& tag_name, 42 | size_t vlen) 43 | : sync_block("multiply_by_tag_value_ff", 44 | io_signature::make (1, 1, sizeof (float)*vlen), 45 | io_signature::make (1, 1, sizeof (float)*vlen)), 46 | d_vlen(vlen), d_k(1.0f) 47 | { 48 | d_tag_key = pmt::intern(tag_name); 49 | 50 | const int alignment_multiple = 51 | volk_get_alignment() / sizeof(float); 52 | set_alignment(std::max(1,alignment_multiple)); 53 | } 54 | 55 | multiply_by_tag_value_ff_impl::~multiply_by_tag_value_ff_impl() 56 | { 57 | } 58 | 59 | float 60 | multiply_by_tag_value_ff_impl::k() const 61 | { 62 | return d_k; 63 | } 64 | 65 | int 66 | multiply_by_tag_value_ff_impl::work(int noutput_items, 67 | gr_vector_const_void_star &input_items, 68 | gr_vector_void_star &output_items) 69 | { 70 | const float *in = (const float *) input_items[0]; 71 | float *out = (float *) output_items[0]; 72 | 73 | std::vector tags; 74 | get_tags_in_window(tags, 0, 0, noutput_items, d_tag_key); 75 | 76 | std::vector::iterator itag = tags.begin(); 77 | 78 | int start = 0, end; 79 | while(itag != tags.end()) { 80 | end = itag->offset - nitems_read(0); 81 | end *= d_vlen; 82 | 83 | // Multiply based on the current value of k from 'start' to 'end' 84 | volk_32f_s32f_multiply_32f(&out[start], &in[start], d_k, (end-start)); 85 | start = end; 86 | 87 | // Extract new value of k 88 | pmt::pmt_t k = itag->value; 89 | if(pmt::is_number(k)) { 90 | d_k = static_cast(pmt::to_double(k)); 91 | } 92 | else { 93 | GR_LOG_WARN(d_logger, 94 | boost::format("Got key '%1%' with incompatible value of '%2%'") \ 95 | % pmt::write_string(d_tag_key) % pmt::write_string(k)); 96 | } 97 | 98 | itag++; 99 | } 100 | 101 | volk_32f_s32f_multiply_32f(&out[start], &in[start], d_k, 102 | (d_vlen*noutput_items-start)); 103 | 104 | return noutput_items; 105 | } 106 | 107 | void 108 | multiply_by_tag_value_ff_impl::setup_rpc() 109 | { 110 | #ifdef GR_CTRLPORT 111 | add_rpc_variable( 112 | rpcbasic_sptr(new rpcbasic_register_get( 113 | alias(), "Constant", 114 | &multiply_by_tag_value_ff::k, 115 | pmt::from_double(-1024.0), 116 | pmt::from_double(1024.0), 117 | pmt::from_double(0.0), 118 | "", "Constant to multiply", RPC_PRIVLVL_MIN, 119 | DISPTIME | DISPOPTCPLX | DISPOPTSTRIP))); 120 | #endif /* GR_CTRLPORT */ 121 | } 122 | 123 | } /* namespace nwr */ 124 | } /* namespace gr */ 125 | -------------------------------------------------------------------------------- /lib/multiply_by_tag_value_ff_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2016 Free Software Foundation, Inc. 4 | * Copyright (C) 2016 Andy Walls 5 | * 6 | * GNU Radio is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * GNU Radio is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | 22 | #ifndef INCLUDED_MULTIPLY_BY_TAG_VALUE_FF_IMPL_H 23 | #define INCLUDED_MULTIPLY_BY_TAG_VALUE_FF_IMPL_H 24 | 25 | #include 26 | 27 | namespace gr { 28 | namespace nwr { 29 | 30 | class NWR_API multiply_by_tag_value_ff_impl 31 | : public multiply_by_tag_value_ff 32 | { 33 | private: 34 | size_t d_vlen; 35 | pmt::pmt_t d_tag_key; 36 | float d_k; 37 | 38 | public: 39 | multiply_by_tag_value_ff_impl(const std::string& tag_name, 40 | size_t vlen); 41 | ~multiply_by_tag_value_ff_impl(); 42 | 43 | float k() const; 44 | 45 | void setup_rpc(); 46 | 47 | int work(int noutput_items, 48 | gr_vector_const_void_star &input_items, 49 | gr_vector_void_star &output_items); 50 | }; 51 | 52 | } /* namespace nwr */ 53 | } /* namespace gr */ 54 | 55 | #endif /* INCLUDED_MULTIPLY_BY_TAG_VALUE_FF_IMPL_H */ 56 | -------------------------------------------------------------------------------- /lib/pll_refout_cc_impl.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2004,2010-2013 Free Software Foundation, Inc. 4 | * Copyright (C) 2017 Andy Walls 5 | * 6 | * GNU Radio is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * GNU Radio is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | 22 | #ifdef HAVE_CONFIG_H 23 | #include "config.h" 24 | #endif 25 | 26 | #include "pll_refout_cc_impl.h" 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | namespace gr { 33 | namespace nwr { 34 | 35 | #ifndef M_TWOPI 36 | #define M_TWOPI (2.0f*M_PI) 37 | #endif 38 | 39 | pll_refout_cc::sptr 40 | pll_refout_cc::make(float loop_bw, float max_freq, float min_freq, 41 | float df, float alpha, float beta) 42 | { 43 | return gnuradio::get_initial_sptr 44 | (new pll_refout_cc_impl(loop_bw, max_freq, min_freq, df, alpha, beta)); 45 | } 46 | 47 | pll_refout_cc_impl::pll_refout_cc_impl(float loop_bw, 48 | float max_freq, float min_freq, 49 | float df, float alpha, float beta) 50 | : sync_block("pll_refout_cc", 51 | io_signature::make(1, 1, sizeof(gr_complex)), 52 | io_signature::makev(1, 4, std::vector(4, sizeof(float)))), 53 | blocks::control_loop(loop_bw, max_freq, min_freq), 54 | d_noutputs(1), 55 | d_out_error(NULL), 56 | d_out_instantaneous_phase_inc(NULL), 57 | d_out_average_phase_inc(NULL) 58 | { 59 | // Brute force fix of the output io_signature, because I can't get 60 | // an anonymous std::vector() rvalue, with a const expression 61 | // initializing the vector, to work. Lvalues seem to make everything 62 | // better. 63 | int output_io_sizes[4] = { 64 | sizeof(gr_complex), 65 | sizeof(float), sizeof(float), sizeof(float) 66 | }; 67 | std::vector output_io_sizes_vector(&output_io_sizes[0], 68 | &output_io_sizes[4]); 69 | set_output_signature(io_signature::makev(1, 4, output_io_sizes_vector)); 70 | 71 | if (df >= 0.0f) 72 | set_damping_factor(df); 73 | 74 | if (alpha >= 0.0f and beta >= 0.0f) { 75 | set_alpha(alpha); 76 | set_beta(beta); 77 | } 78 | } 79 | 80 | pll_refout_cc_impl::~pll_refout_cc_impl() 81 | { 82 | } 83 | 84 | void 85 | pll_refout_cc_impl::setup_optional_outputs( 86 | gr_vector_void_star &output_items) 87 | { 88 | d_noutputs = output_items.size(); 89 | d_out_error = NULL; 90 | d_out_instantaneous_phase_inc = NULL; 91 | d_out_average_phase_inc = NULL; 92 | 93 | if (d_noutputs < 2) 94 | return; 95 | d_out_error = (float *) output_items[1]; 96 | 97 | if (d_noutputs < 3) 98 | return; 99 | d_out_instantaneous_phase_inc = (float *) output_items[2]; 100 | 101 | if (d_noutputs < 4) 102 | return; 103 | d_out_average_phase_inc = (float *) output_items[3]; 104 | } 105 | 106 | void 107 | pll_refout_cc_impl::emit_optional_output(int oidx, 108 | float error, 109 | float inst_phase_inc, 110 | float avg_phase_inc) 111 | { 112 | if (d_noutputs < 2) 113 | return; 114 | d_out_error[oidx] = error; 115 | 116 | if (d_noutputs < 3) 117 | return; 118 | d_out_instantaneous_phase_inc[oidx] = inst_phase_inc; 119 | 120 | if (d_noutputs < 4) 121 | return; 122 | d_out_average_phase_inc[oidx] = avg_phase_inc; 123 | } 124 | 125 | float 126 | pll_refout_cc_impl::mod_2pi(float in) 127 | { 128 | if(in > M_PI) 129 | return in - M_TWOPI; 130 | else if(in < -M_PI) 131 | return in+ M_TWOPI; 132 | else 133 | return in; 134 | } 135 | 136 | float 137 | pll_refout_cc_impl::phase_detector(gr_complex sample,float ref_phase) 138 | { 139 | float sample_phase; 140 | sample_phase = gr::fast_atan2f(sample.imag(),sample.real()); 141 | return mod_2pi(sample_phase-ref_phase); 142 | } 143 | 144 | int 145 | pll_refout_cc_impl::work(int noutput_items, 146 | gr_vector_const_void_star &input_items, 147 | gr_vector_void_star &output_items) 148 | { 149 | const gr_complex *iptr = (gr_complex*)input_items[0]; 150 | gr_complex *optr = (gr_complex*)output_items[0]; 151 | 152 | setup_optional_outputs(output_items); 153 | 154 | float error, prev_phase; 155 | float t_imag, t_real; 156 | 157 | for(int idx = 0; idx < noutput_items; idx++) { 158 | gr::sincosf(d_phase,&t_imag,&t_real); 159 | *optr++ = gr_complex(t_real,t_imag); 160 | 161 | error = phase_detector(*iptr++,d_phase); 162 | 163 | prev_phase = d_phase; 164 | advance_loop(error); 165 | emit_optional_output(idx, error, d_phase - prev_phase, d_freq); 166 | phase_wrap(); 167 | frequency_limit(); 168 | } 169 | return noutput_items; 170 | } 171 | 172 | void 173 | pll_refout_cc_impl::set_loop_bandwidth(float bw) 174 | { 175 | blocks::control_loop::set_loop_bandwidth(bw); 176 | } 177 | 178 | void 179 | pll_refout_cc_impl::set_damping_factor(float df) 180 | { 181 | blocks::control_loop::set_damping_factor(df); 182 | } 183 | 184 | void 185 | pll_refout_cc_impl::set_alpha(float alpha) 186 | { 187 | blocks::control_loop::set_alpha(alpha); 188 | } 189 | 190 | void 191 | pll_refout_cc_impl::set_beta(float beta) 192 | { 193 | blocks::control_loop::set_beta(beta); 194 | } 195 | 196 | void 197 | pll_refout_cc_impl::set_frequency(float freq) 198 | { 199 | blocks::control_loop::set_frequency(freq); 200 | } 201 | 202 | void 203 | pll_refout_cc_impl::set_phase(float phase) 204 | { 205 | blocks::control_loop::set_phase(phase); 206 | } 207 | 208 | void 209 | pll_refout_cc_impl::set_min_freq(float freq) 210 | { 211 | blocks::control_loop::set_min_freq(freq); 212 | } 213 | 214 | void 215 | pll_refout_cc_impl::set_max_freq(float freq) 216 | { 217 | blocks::control_loop::set_max_freq(freq); 218 | } 219 | 220 | 221 | float 222 | pll_refout_cc_impl::get_loop_bandwidth() const 223 | { 224 | return blocks::control_loop::get_loop_bandwidth(); 225 | } 226 | 227 | float 228 | pll_refout_cc_impl::get_damping_factor() const 229 | { 230 | return blocks::control_loop::get_damping_factor(); 231 | } 232 | 233 | float 234 | pll_refout_cc_impl::get_alpha() const 235 | { 236 | return blocks::control_loop::get_alpha(); 237 | } 238 | 239 | float 240 | pll_refout_cc_impl::get_beta() const 241 | { 242 | return blocks::control_loop::get_beta(); 243 | } 244 | 245 | float 246 | pll_refout_cc_impl::get_frequency() const 247 | { 248 | return blocks::control_loop::get_frequency(); 249 | } 250 | 251 | float 252 | pll_refout_cc_impl::get_phase() const 253 | { 254 | return blocks::control_loop::get_phase(); 255 | } 256 | 257 | float 258 | pll_refout_cc_impl::get_min_freq() const 259 | { 260 | return blocks::control_loop::get_min_freq(); 261 | } 262 | 263 | float 264 | pll_refout_cc_impl::get_max_freq() const 265 | { 266 | return blocks::control_loop::get_max_freq(); 267 | } 268 | 269 | } /* namespace nwr */ 270 | } /* namespace gr */ 271 | -------------------------------------------------------------------------------- /lib/pll_refout_cc_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2004,2011,2012 Free Software Foundation, Inc. 4 | * Copyright (C) 2017 Andy Walls 5 | * 6 | * GNU Radio is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3, or (at your option) 9 | * any later version. 10 | * 11 | * GNU Radio is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with GNU Radio; see the file COPYING. If not, write to 18 | * the Free Software Foundation, Inc., 51 Franklin Street, 19 | * Boston, MA 02110-1301, USA. 20 | */ 21 | 22 | #ifndef INCLUDED_NWR_PLL_REFOUT_CC_IMPL_H 23 | #define INCLUDED_NWR_PLL_REFOUT_CC_IMPL_H 24 | 25 | #include 26 | 27 | namespace gr { 28 | namespace nwr { 29 | 30 | class pll_refout_cc_impl : public pll_refout_cc 31 | { 32 | private: 33 | // Optional Diagnostic Outputs 34 | int d_noutputs; 35 | float *d_out_error; 36 | float *d_out_instantaneous_phase_inc; 37 | float *d_out_average_phase_inc; 38 | 39 | // Optional Diagnostic Outputs 40 | void setup_optional_outputs(gr_vector_void_star &output_items); 41 | void emit_optional_output(int oidx, 42 | float error, 43 | float inst_phase_inc, 44 | float avg_phase_inc); 45 | 46 | float mod_2pi (float in); 47 | float phase_detector(gr_complex sample, float ref_phase); 48 | 49 | public: 50 | pll_refout_cc_impl(float loop_bw, float max_freq, float min_freq, 51 | float df, float alpha, float beta); 52 | ~pll_refout_cc_impl(); 53 | 54 | void set_loop_bandwidth(float bw); 55 | void set_damping_factor(float df); 56 | void set_alpha(float alpha); 57 | void set_beta(float beta); 58 | void set_frequency(float freq); 59 | void set_phase(float phase); 60 | void set_min_freq(float freq); 61 | void set_max_freq(float freq); 62 | 63 | float get_loop_bandwidth() const; 64 | float get_damping_factor() const; 65 | float get_alpha() const; 66 | float get_beta() const; 67 | float get_frequency() const; 68 | float get_phase() const; 69 | float get_min_freq() const; 70 | float get_max_freq() const; 71 | 72 | int work(int noutput_items, 73 | gr_vector_const_void_star &input_items, 74 | gr_vector_void_star &output_items); 75 | }; 76 | 77 | } /* namespace nwr */ 78 | } /* namespace gr */ 79 | 80 | #endif /* INCLUDED_NWR_PLL_REFOUT_CC_IMPL_H */ 81 | -------------------------------------------------------------------------------- /lib/qa_nwr.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Andy Walls 3 | * 4 | * This file was automatically generated by gr_modtool from GNU Radio 5 | * 6 | * This file was automatically generated from a template incorporating 7 | * data input by Andy Walls. 8 | * See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 9 | */ 10 | 11 | /* 12 | * This class gathers together all the test cases for the gr-nwr 13 | * directory into a single test suite. As you create new test cases, 14 | * add them here. 15 | */ 16 | 17 | #include "qa_nwr.h" 18 | 19 | CppUnit::TestSuite * 20 | qa_nwr::suite() 21 | { 22 | CppUnit::TestSuite *s = new CppUnit::TestSuite("nwr"); 23 | 24 | return s; 25 | } 26 | -------------------------------------------------------------------------------- /lib/qa_nwr.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright (C) 2016 Andy Walls 4 | * 5 | * This file was automatically generated by gr_modtool from GNU Radio 6 | * 7 | * This file was automatically generated from a template incorporating 8 | * data input by Andy Walls. 9 | * See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 10 | */ 11 | 12 | #ifndef _QA_NWR_H_ 13 | #define _QA_NWR_H_ 14 | 15 | #include 16 | #include 17 | 18 | //! collect all the tests for the gr-nwr directory 19 | 20 | class __GR_ATTR_EXPORT qa_nwr 21 | { 22 | public: 23 | //! return suite of tests for all of gr-nwr directory 24 | static CppUnit::TestSuite *suite(); 25 | }; 26 | 27 | #endif /* _QA_NWR_H_ */ 28 | -------------------------------------------------------------------------------- /lib/same_burst_decoder_impl.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright (C) 2016 Andy Walls 4 | * 5 | * This file was automatically generated by gr_modtool from GNU Radio 6 | * 7 | * This file was automatically generated from a template incorporating 8 | * data input by Andy Walls and later hand edited by Andy Walls. 9 | * See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 10 | */ 11 | 12 | #ifdef HAVE_CONFIG_H 13 | #include "config.h" 14 | #endif 15 | 16 | #include 17 | #include "same_burst_decoder_impl.h" 18 | 19 | namespace gr { 20 | namespace nwr { 21 | 22 | same_burst_decoder::sptr 23 | same_burst_decoder::make(const std::string &sob_key, 24 | const std::string &eob_key) 25 | { 26 | return gnuradio::get_initial_sptr 27 | (new same_burst_decoder_impl(sob_key, eob_key)); 28 | } 29 | 30 | same_burst_decoder_impl::same_burst_decoder_impl(const std::string &sob_key, 31 | const std::string &eob_key) 32 | : gr::sync_block("same_burst_decoder", 33 | gr::io_signature::make(1, 1, sizeof(float)), 34 | gr::io_signature::make(0, 0, 0)), 35 | d_sob_key(pmt::intern(sob_key)), 36 | d_eob_key(pmt::intern(eob_key)), 37 | d_printable_key(pmt::intern("printable")), 38 | d_bytes_key(pmt::intern("bytes")), 39 | d_hard_bits_key(pmt::intern("hard_bits")), 40 | d_soft_bits_key(pmt::intern("soft_bits")), 41 | d_soft_bits(), 42 | d_hard_bits(), 43 | d_bytes(), 44 | d_printable_str(), 45 | d_tags(), 46 | d_in_burst(false) 47 | { 48 | message_port_register_out(d_printable_key); 49 | message_port_register_out(d_bytes_key); 50 | message_port_register_out(d_hard_bits_key); 51 | message_port_register_out(d_soft_bits_key); 52 | 53 | d_soft_bits.reserve(MAX_BITS); 54 | d_hard_bits.reserve(MAX_BITS); 55 | d_bytes.reserve(MAX_BYTES); 56 | d_printable_str.reserve(MAX_BYTES - PREAMBLE_BYTES); 57 | } 58 | 59 | same_burst_decoder_impl::~same_burst_decoder_impl() 60 | { 61 | } 62 | 63 | void 64 | same_burst_decoder_impl::clear() 65 | { 66 | d_printable_str.clear(); 67 | d_bytes.clear(); 68 | d_hard_bits.clear(); 69 | d_soft_bits.clear(); 70 | } 71 | 72 | void 73 | same_burst_decoder_impl::output_messages() 74 | { 75 | message_port_pub(d_printable_key, 76 | pmt::string_to_symbol(d_printable_str)); 77 | 78 | message_port_pub(d_bytes_key, 79 | pmt::cons(pmt::PMT_NIL, 80 | pmt::init_u8vector(d_bytes.size(), 81 | d_bytes))); 82 | 83 | message_port_pub(d_hard_bits_key, 84 | pmt::cons(pmt::PMT_NIL, 85 | pmt::init_u8vector(d_hard_bits.size(), 86 | d_hard_bits))); 87 | 88 | message_port_pub(d_soft_bits_key, 89 | pmt::cons(pmt::PMT_NIL, 90 | pmt::init_f32vector(d_soft_bits.size(), 91 | d_soft_bits))); 92 | } 93 | 94 | bool 95 | same_burst_decoder_impl::process_bits() 96 | { 97 | // We want to find the 4 header bytes and we'll allow 98 | // bytes of the preamble to be missing 99 | if (d_hard_bits.size() < (PREAMBLE_BYTES/2 + HEADER_BYTES) * 8) 100 | return false; 101 | 102 | // Find the header bytes and figure out our bit alignment 103 | uint32_t fourbytes = 0; 104 | int bit_idx; 105 | int bit_align; 106 | int preamble_bytes; 107 | bool hdr_found = false; 108 | for (bit_idx = 0; bit_idx < d_hard_bits.size(); bit_idx++) { 109 | fourbytes >>= 1; 110 | if (d_hard_bits[bit_idx]) 111 | fourbytes |= 0x80000000; 112 | if (fourbytes == 0x435a435a or // CZCZ, ZCZC in rev byte order 113 | fourbytes == 0x4e4e4e4e ) { // NNNN, NNNN in rev byte order 114 | // Found last bit of full header at bit_idx 115 | bit_align = (bit_idx + 1) % 8; 116 | preamble_bytes = (bit_idx - 31) / 8; 117 | hdr_found = true; 118 | } 119 | } 120 | 121 | if (hdr_found == false) 122 | return false; 123 | 124 | // Read in the bytes 125 | uint8_t byte = 0; 126 | int bit_count = 0; 127 | for (bit_idx = bit_align; bit_idx < d_hard_bits.size(); bit_idx++) { 128 | byte >>= 1; 129 | if (d_hard_bits[bit_idx]) 130 | byte |= 0x80; 131 | bit_count++; 132 | if (bit_count == 8) { 133 | d_bytes.push_back(byte); 134 | bit_count = 0; 135 | } 136 | } 137 | 138 | // Assemble the readable string 139 | for (int i = preamble_bytes; i < d_bytes.size(); i++) 140 | if (isprint(d_bytes[i])) 141 | d_printable_str.push_back(d_bytes[i]); 142 | 143 | return true; 144 | } 145 | 146 | void 147 | same_burst_decoder_impl::process_input(const float *in, 148 | int start, int bound, bool end) 149 | { 150 | for (int i = start; d_in_burst and i < bound; i++) { 151 | d_soft_bits.push_back(in[i]); 152 | d_hard_bits.push_back(slice(in[i])); 153 | if (d_soft_bits.size() >= MAX_BITS) { 154 | if (process_bits()) 155 | output_messages(); 156 | clear(); 157 | d_in_burst = false; 158 | } 159 | } 160 | if (end) { 161 | if (d_in_burst and process_bits()) 162 | output_messages(); 163 | clear(); 164 | d_in_burst = false; 165 | } 166 | } 167 | 168 | int 169 | same_burst_decoder_impl::work(int noutput_items, 170 | gr_vector_const_void_star &input_items, 171 | gr_vector_void_star &output_items) 172 | { 173 | const float *in = (const float *) input_items[0]; 174 | 175 | uint64_t nitems_rd = nitems_read(0); 176 | 177 | // Get all the input tags in offset order 178 | d_tags.clear(); 179 | get_tags_in_range(d_tags, 0, nitems_rd, nitems_rd + noutput_items); 180 | std::sort(d_tags.begin(), d_tags.end(), tag_t::offset_compare); 181 | 182 | // N.B. we might break badly if SOB and EOB are marked on the same 183 | // sample offset. Garbage in, garbage out... 184 | 185 | int idx = 0; 186 | int tidx; 187 | std::vector::iterator t; 188 | 189 | // Loop through all the tags 190 | for (t = d_tags.begin(); t != d_tags.end(); ++t) { 191 | if (pmt::eq(t->key, d_eob_key)) { 192 | tidx = static_cast(t->offset - nitems_rd); 193 | process_input(in, idx, tidx, true); 194 | idx = tidx; 195 | } else if (pmt::eq(t->key, d_sob_key)) { 196 | // Handle a missing EOB tag as robustly as we can. 197 | tidx = static_cast(t->offset - nitems_rd); 198 | process_input(in, idx, tidx, true); 199 | idx = tidx; 200 | 201 | // We'll handle the input from the SOB, when we find the next 202 | // SOB or EOB tag, or when there are none of those tags left 203 | // in this call to work. 204 | d_in_burst = true; 205 | } 206 | } 207 | 208 | process_input(in, idx, noutput_items, false); 209 | 210 | return noutput_items; 211 | } 212 | 213 | } /* namespace nwr */ 214 | } /* namespace gr */ 215 | 216 | -------------------------------------------------------------------------------- /lib/same_burst_decoder_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright (C) 2016 Andy Walls 4 | * 5 | * This file was automatically generated by gr_modtool from GNU Radio 6 | * 7 | * This file was automatically generated from a template incorporating 8 | * data input by Andy Walls and later hand edited by Andy Walls. 9 | * See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 10 | */ 11 | 12 | #ifndef INCLUDED_NWR_SAME_BURST_DECODER_IMPL_H 13 | #define INCLUDED_NWR_SAME_BURST_DECODER_IMPL_H 14 | 15 | #include 16 | #include 17 | 18 | namespace gr { 19 | namespace nwr { 20 | 21 | class same_burst_decoder_impl : public same_burst_decoder 22 | { 23 | private: 24 | pmt::pmt_t d_sob_key; 25 | pmt::pmt_t d_eob_key; 26 | pmt::pmt_t d_printable_key; 27 | pmt::pmt_t d_bytes_key; 28 | pmt::pmt_t d_hard_bits_key; 29 | pmt::pmt_t d_soft_bits_key; 30 | 31 | static const unsigned int PREAMBLE_BYTES = 16; 32 | static const unsigned int HEADER_BYTES = 4; 33 | static const unsigned int MAX_SAME_BYTES = 34 | 16 // Preamble: 0xAB, 16 times 35 | + 4 // Header: ZCZC (or NNNN for EOM) 36 | + 1 + 3 // -ORG 37 | + 1 + 3 // -EEE 38 | + (1 + 6) * 31 // -PSSCCC up to 31 times 39 | + 1 + 4 // +TTTT 40 | + 1 + 7 // -JJJHHMM 41 | + 1 + 8 + 1 // -LLLLLLLL- 42 | + 4; // 3 or 4 NULL bytes which real OTA gear seems to emit 43 | 44 | static const unsigned int MAX_BYTES = MAX_SAME_BYTES + 1; 45 | static const unsigned int MAX_BITS = MAX_BYTES * 8; 46 | 47 | std::vector d_soft_bits; 48 | std::vector d_hard_bits; 49 | std::vector d_bytes; 50 | std::string d_printable_str; 51 | 52 | std::vector d_tags; 53 | 54 | bool d_in_burst; 55 | 56 | uint8_t slice(float x) { return x < 0.0f ? 0 : 1; } 57 | void clear(); 58 | void output_messages(); 59 | bool process_bits(); 60 | void process_input(const float *in, int start, int bound, bool end); 61 | 62 | public: 63 | same_burst_decoder_impl(const std::string &sob_key, 64 | const std::string &eob_key); 65 | ~same_burst_decoder_impl(); 66 | 67 | int work(int noutput_items, 68 | gr_vector_const_void_star &input_items, 69 | gr_vector_void_star &output_items); 70 | }; 71 | 72 | } // namespace nwr 73 | } // namespace gr 74 | 75 | #endif /* INCLUDED_NWR_SAME_BURST_DECODER_IMPL_H */ 76 | 77 | -------------------------------------------------------------------------------- /lib/test_nwr.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright (C) 2016 Andy Walls 4 | * 5 | * This file was automatically generated by gr_modtool from GNU Radio 6 | * 7 | * This file was automatically generated from a template incorporating 8 | * data input by Andy Walls. 9 | * See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 10 | */ 11 | 12 | #ifdef HAVE_CONFIG_H 13 | #include "config.h" 14 | #endif 15 | 16 | #include 17 | #include 18 | 19 | #include 20 | #include "qa_nwr.h" 21 | #include 22 | #include 23 | 24 | int 25 | main (int argc, char **argv) 26 | { 27 | CppUnit::TextTestRunner runner; 28 | std::ofstream xmlfile(get_unittest_path("nwr.xml").c_str()); 29 | CppUnit::XmlOutputter *xmlout = new CppUnit::XmlOutputter(&runner.result(), xmlfile); 30 | 31 | runner.addTest(qa_nwr::suite()); 32 | runner.setOutputter(xmlout); 33 | 34 | bool was_successful = runner.run("", false); 35 | 36 | return was_successful ? 0 : 1; 37 | } 38 | -------------------------------------------------------------------------------- /python/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016 Andy Walls 3 | # 4 | # This file was automatically generated by gr_modtool from GNU Radio 5 | # 6 | # This file was automatically generated from a template incorporating 7 | # data input by Andy Walls and subsequently hand edited by Andy Walls. 8 | # See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 9 | # 10 | 11 | ######################################################################## 12 | # Include python install macros 13 | ######################################################################## 14 | include(GrPython) 15 | if(NOT PYTHONINTERP_FOUND) 16 | return() 17 | endif() 18 | 19 | ######################################################################## 20 | # Install python sources 21 | ######################################################################## 22 | GR_PYTHON_INSTALL( 23 | FILES 24 | __init__.py 25 | DESTINATION ${GR_PYTHON_DIR}/nwr 26 | ) 27 | 28 | ######################################################################## 29 | # Handle the unit tests 30 | ######################################################################## 31 | include(GrTest) 32 | 33 | set(GR_TEST_TARGET_DEPS gnuradio-nwr) 34 | set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig) 35 | GR_ADD_TEST(qa_lms_da_equalizer_ff ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_lms_da_equalizer_ff.py) 36 | GR_ADD_TEST(qa_burst_detect_and_tag ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_burst_detect_and_tag.py) 37 | GR_ADD_TEST(qa_correction_estimator_ff ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_correction_estimator_ff.py) 38 | GR_ADD_TEST(qa_multiply_by_tag_value_ff ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_multiply_by_tag_value_ff.py) 39 | GR_ADD_TEST(qa_add_tag_value_ff ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_add_tag_value_ff.py) 40 | GR_ADD_TEST(qa_pll_refout_cc ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_pll_refout_cc.py) 41 | GR_ADD_TEST(qa_same_burst_decoder ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_same_burst_decoder.py) 42 | -------------------------------------------------------------------------------- /python/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016 Andy Walls 3 | # 4 | # This file was automatically generated by gr_modtool from GNU Radio 5 | # 6 | # This file was automatically generated from a template incorporating 7 | # data input by Andy Walls. 8 | # See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 9 | # 10 | 11 | # The presence of this file turns this directory into a Python package 12 | 13 | ''' 14 | This is the NWR OOT GNU Radio module. Place your Python package 15 | description here (python/__init__.py). 16 | ''' 17 | 18 | # import swig generated symbols into the nwr namespace 19 | try: 20 | # this might fail if the module is python-only 21 | from nwr_swig import * 22 | except ImportError: 23 | pass 24 | 25 | # import any pure python here 26 | # 27 | -------------------------------------------------------------------------------- /python/build_utils.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2004,2009,2012 Free Software Foundation, Inc. 3 | # 4 | # This file was automatically generated by gr_modtool from GNU Radio 5 | # 6 | # GNU Radio is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # GNU Radio is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with GNU Radio; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | 22 | """Misc utilities used at build time 23 | """ 24 | 25 | import re, os, os.path 26 | from build_utils_codes import * 27 | 28 | 29 | # set srcdir to the directory that contains Makefile.am 30 | try: 31 | srcdir = os.environ['srcdir'] 32 | except KeyError, e: 33 | srcdir = "." 34 | srcdir = srcdir + '/' 35 | 36 | # set do_makefile to either true or false dependeing on the environment 37 | try: 38 | if os.environ['do_makefile'] == '0': 39 | do_makefile = False 40 | else: 41 | do_makefile = True 42 | except KeyError, e: 43 | do_makefile = False 44 | 45 | # set do_sources to either true or false dependeing on the environment 46 | try: 47 | if os.environ['do_sources'] == '0': 48 | do_sources = False 49 | else: 50 | do_sources = True 51 | except KeyError, e: 52 | do_sources = True 53 | 54 | name_dict = {} 55 | 56 | def log_output_name (name): 57 | (base, ext) = os.path.splitext (name) 58 | ext = ext[1:] # drop the leading '.' 59 | 60 | entry = name_dict.setdefault (ext, []) 61 | entry.append (name) 62 | 63 | def open_and_log_name (name, dir): 64 | global do_sources 65 | if do_sources: 66 | f = open (name, dir) 67 | else: 68 | f = None 69 | log_output_name (name) 70 | return f 71 | 72 | def expand_template (d, template_filename, extra = ""): 73 | '''Given a dictionary D and a TEMPLATE_FILENAME, expand template into output file 74 | ''' 75 | global do_sources 76 | output_extension = extract_extension (template_filename) 77 | template = open_src (template_filename, 'r') 78 | output_name = d['NAME'] + extra + '.' + output_extension 79 | log_output_name (output_name) 80 | if do_sources: 81 | output = open (output_name, 'w') 82 | do_substitution (d, template, output) 83 | output.close () 84 | template.close () 85 | 86 | def output_glue (dirname): 87 | output_makefile_fragment () 88 | output_ifile_include (dirname) 89 | 90 | def output_makefile_fragment (): 91 | global do_makefile 92 | if not do_makefile: 93 | return 94 | # overwrite the source, which must be writable; this should have been 95 | # checked for beforehand in the top-level Makefile.gen.gen . 96 | f = open (os.path.join (os.environ.get('gendir', os.environ.get('srcdir', '.')), 'Makefile.gen'), 'w') 97 | f.write ('#\n# This file is machine generated. All edits will be overwritten\n#\n') 98 | output_subfrag (f, 'h') 99 | output_subfrag (f, 'i') 100 | output_subfrag (f, 'cc') 101 | f.close () 102 | 103 | def output_ifile_include (dirname): 104 | global do_sources 105 | if do_sources: 106 | f = open ('%s_generated.i' % (dirname,), 'w') 107 | f.write ('//\n// This file is machine generated. All edits will be overwritten\n//\n') 108 | files = name_dict.setdefault ('i', []) 109 | files.sort () 110 | f.write ('%{\n') 111 | for file in files: 112 | f.write ('#include <%s>\n' % (file[0:-1] + 'h',)) 113 | f.write ('%}\n\n') 114 | for file in files: 115 | f.write ('%%include <%s>\n' % (file,)) 116 | 117 | def output_subfrag (f, ext): 118 | files = name_dict.setdefault (ext, []) 119 | files.sort () 120 | f.write ("GENERATED_%s =" % (ext.upper ())) 121 | for file in files: 122 | f.write (" \\\n\t%s" % (file,)) 123 | f.write ("\n\n") 124 | 125 | def extract_extension (template_name): 126 | # template name is something like: GrFIRfilterXXX.h.t 127 | # we return everything between the penultimate . and .t 128 | mo = re.search (r'\.([a-z]+)\.t$', template_name) 129 | if not mo: 130 | raise ValueError, "Incorrectly formed template_name '%s'" % (template_name,) 131 | return mo.group (1) 132 | 133 | def open_src (name, mode): 134 | global srcdir 135 | return open (os.path.join (srcdir, name), mode) 136 | 137 | def do_substitution (d, in_file, out_file): 138 | def repl (match_obj): 139 | key = match_obj.group (1) 140 | # print key 141 | return d[key] 142 | 143 | inp = in_file.read () 144 | out = re.sub (r"@([a-zA-Z0-9_]+)@", repl, inp) 145 | out_file.write (out) 146 | 147 | 148 | 149 | copyright = '''/* -*- c++ -*- */ 150 | /* 151 | * Copyright 2003,2004 Free Software Foundation, Inc. 152 | * 153 | * This file is part of GNU Radio 154 | * 155 | * GNU Radio is free software; you can redistribute it and/or modify 156 | * it under the terms of the GNU General Public License as published by 157 | * the Free Software Foundation; either version 3, or (at your option) 158 | * any later version. 159 | * 160 | * GNU Radio is distributed in the hope that it will be useful, 161 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 162 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 163 | * GNU General Public License for more details. 164 | * 165 | * You should have received a copy of the GNU General Public License 166 | * along with GNU Radio; see the file COPYING. If not, write to 167 | * the Free Software Foundation, Inc., 51 Franklin Street, 168 | * Boston, MA 02110-1301, USA. 169 | */ 170 | ''' 171 | 172 | def is_complex (code3): 173 | if i_code (code3) == 'c' or o_code (code3) == 'c': 174 | return '1' 175 | else: 176 | return '0' 177 | 178 | 179 | def standard_dict (name, code3, package='gr'): 180 | d = {} 181 | d['NAME'] = name 182 | d['NAME_IMPL'] = name+'_impl' 183 | d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper()) 184 | d['GUARD_NAME_IMPL'] = 'INCLUDED_%s_%s_IMPL_H' % (package.upper(), name.upper()) 185 | d['BASE_NAME'] = re.sub ('^' + package + '_', '', name) 186 | d['SPTR_NAME'] = '%s_sptr' % name 187 | d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten' 188 | d['COPYRIGHT'] = copyright 189 | d['TYPE'] = i_type (code3) 190 | d['I_TYPE'] = i_type (code3) 191 | d['O_TYPE'] = o_type (code3) 192 | d['TAP_TYPE'] = tap_type (code3) 193 | d['IS_COMPLEX'] = is_complex (code3) 194 | return d 195 | 196 | 197 | def standard_dict2 (name, code3, package): 198 | d = {} 199 | d['NAME'] = name 200 | d['BASE_NAME'] = name 201 | d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper()) 202 | d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten' 203 | d['COPYRIGHT'] = copyright 204 | d['TYPE'] = i_type (code3) 205 | d['I_TYPE'] = i_type (code3) 206 | d['O_TYPE'] = o_type (code3) 207 | d['TAP_TYPE'] = tap_type (code3) 208 | d['IS_COMPLEX'] = is_complex (code3) 209 | return d 210 | 211 | def standard_impl_dict2 (name, code3, package): 212 | d = {} 213 | d['NAME'] = name 214 | d['IMPL_NAME'] = name 215 | d['BASE_NAME'] = name.rstrip("impl").rstrip("_") 216 | d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper()) 217 | d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten' 218 | d['COPYRIGHT'] = copyright 219 | d['FIR_TYPE'] = "fir_filter_" + code3 220 | d['CFIR_TYPE'] = "fir_filter_" + code3[0:2] + 'c' 221 | d['TYPE'] = i_type (code3) 222 | d['I_TYPE'] = i_type (code3) 223 | d['O_TYPE'] = o_type (code3) 224 | d['TAP_TYPE'] = tap_type (code3) 225 | d['IS_COMPLEX'] = is_complex (code3) 226 | return d 227 | -------------------------------------------------------------------------------- /python/build_utils_codes.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2004 Free Software Foundation, Inc. 3 | # 4 | # This file was automatically generated by gr_modtool from GNU Radio 5 | # 6 | # GNU Radio is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # GNU Radio is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with GNU Radio; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | 22 | def i_code (code3): 23 | return code3[0] 24 | 25 | def o_code (code3): 26 | if len (code3) >= 2: 27 | return code3[1] 28 | else: 29 | return code3[0] 30 | 31 | def tap_code (code3): 32 | if len (code3) >= 3: 33 | return code3[2] 34 | else: 35 | return code3[0] 36 | 37 | def i_type (code3): 38 | return char_to_type[i_code (code3)] 39 | 40 | def o_type (code3): 41 | return char_to_type[o_code (code3)] 42 | 43 | def tap_type (code3): 44 | return char_to_type[tap_code (code3)] 45 | 46 | 47 | char_to_type = {} 48 | char_to_type['s'] = 'short' 49 | char_to_type['i'] = 'int' 50 | char_to_type['f'] = 'float' 51 | char_to_type['c'] = 'gr_complex' 52 | char_to_type['b'] = 'unsigned char' 53 | -------------------------------------------------------------------------------- /python/qa_add_tag_value_ff.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright (C) 2016 Andy Walls 5 | # 6 | # This file was automatically generated by gr_modtool from GNU Radio 7 | # 8 | # This file was automatically generated from a template incorporating 9 | # data input by Andy Walls and subsequently hand edited by Andy Walls. 10 | # See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 11 | # 12 | 13 | from gnuradio import gr, gr_unittest 14 | from gnuradio import blocks 15 | import nwr_swig as nwr 16 | 17 | class qa_add_tag_value_ff (gr_unittest.TestCase): 18 | 19 | def setUp (self): 20 | self.tb = gr.top_block () 21 | 22 | def tearDown (self): 23 | self.tb = None 24 | 25 | def test_001_t (self): 26 | # set up fg 27 | self.tb.run () 28 | # check data 29 | 30 | 31 | if __name__ == '__main__': 32 | gr_unittest.run(qa_add_tag_value_ff, "qa_add_tag_value_ff.xml") 33 | -------------------------------------------------------------------------------- /python/qa_burst_detect_and_tag.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright (C) 2016 Andy Walls 5 | # 6 | # This file was automatically generated by gr_modtool from GNU Radio 7 | # 8 | # This file was automatically generated from a template incorporating 9 | # data input by Andy Walls. 10 | # See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 11 | # 12 | 13 | from gnuradio import gr, gr_unittest 14 | from gnuradio import blocks 15 | import nwr_swig as nwr 16 | 17 | class qa_burst_detect_and_tag (gr_unittest.TestCase): 18 | 19 | def setUp (self): 20 | self.tb = gr.top_block () 21 | 22 | def tearDown (self): 23 | self.tb = None 24 | 25 | def test_001_t (self): 26 | # set up fg 27 | self.tb.run () 28 | # check data 29 | 30 | 31 | if __name__ == '__main__': 32 | gr_unittest.run(qa_burst_detect_and_tag, "qa_burst_detect_and_tag.xml") 33 | -------------------------------------------------------------------------------- /python/qa_correction_estimator_ff.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright (C) 2016 Andy Walls 5 | # 6 | # This file was automatically generated by gr_modtool from GNU Radio 7 | # 8 | # This file was automatically generated from a template incorporating 9 | # data input by Andy Walls. 10 | # See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 11 | # 12 | 13 | from gnuradio import gr, gr_unittest 14 | from gnuradio import blocks 15 | import nwr_swig as nwr 16 | 17 | class qa_correction_estimator_ff (gr_unittest.TestCase): 18 | 19 | def setUp (self): 20 | self.tb = gr.top_block () 21 | 22 | def tearDown (self): 23 | self.tb = None 24 | 25 | def test_001_t (self): 26 | # set up fg 27 | self.tb.run () 28 | # check data 29 | 30 | 31 | if __name__ == '__main__': 32 | gr_unittest.run(qa_correction_estimator_ff, "qa_correction_estimator_ff.xml") 33 | -------------------------------------------------------------------------------- /python/qa_lms_da_equalizer_ff.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright (C) 2016 Andy Walls 5 | # 6 | # This file was automatically generated by gr_modtool from GNU Radio 7 | # 8 | # This file was automatically generated from a template incorporating 9 | # data input by Andy Walls. 10 | # See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 11 | # 12 | 13 | from gnuradio import gr, gr_unittest 14 | from gnuradio import blocks 15 | import nwr_swig as nwr 16 | 17 | class qa_lms_da_equalizer_ff (gr_unittest.TestCase): 18 | 19 | def setUp (self): 20 | self.tb = gr.top_block () 21 | 22 | def tearDown (self): 23 | self.tb = None 24 | 25 | def test_001_t (self): 26 | # set up fg 27 | self.tb.run () 28 | # check data 29 | 30 | 31 | if __name__ == '__main__': 32 | gr_unittest.run(qa_lms_da_equalizer_ff, "qa_lms_da_equalizer_ff.xml") 33 | -------------------------------------------------------------------------------- /python/qa_multiply_by_tag_value_ff.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright (C) 2016 Andy Walls 5 | # 6 | # This file was automatically generated by gr_modtool from GNU Radio 7 | # 8 | # This file was automatically generated from a template incorporating 9 | # data input by Andy Walls and subsequently hand edited by Andy Walls. 10 | # See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 11 | # 12 | 13 | from gnuradio import gr, gr_unittest 14 | from gnuradio import blocks 15 | import nwr_swig as nwr 16 | 17 | class qa_multiply_by_tag_value_ff (gr_unittest.TestCase): 18 | 19 | def setUp (self): 20 | self.tb = gr.top_block () 21 | 22 | def tearDown (self): 23 | self.tb = None 24 | 25 | def test_001_t (self): 26 | # set up fg 27 | self.tb.run () 28 | # check data 29 | 30 | 31 | if __name__ == '__main__': 32 | gr_unittest.run(qa_multiply_by_tag_value_ff, "qa_multiply_by_tag_value_ff.xml") 33 | -------------------------------------------------------------------------------- /python/qa_pll_refout_cc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2004,2010,2012,2013 Free Software Foundation, Inc. 4 | # Copyright (C) 2017 Andy Walls 5 | # 6 | # GNU Radio is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 3, or (at your option) 9 | # any later version. 10 | # 11 | # GNU Radio is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with GNU Radio; see the file COPYING. If not, write to 18 | # the Free Software Foundation, Inc., 51 Franklin Street, 19 | # Boston, MA 02110-1301, USA. 20 | # 21 | 22 | import math 23 | 24 | from gnuradio import gr, gr_unittest, analog, blocks 25 | import nwr 26 | 27 | class test_pll_refout(gr_unittest.TestCase): 28 | 29 | def setUp(self): 30 | self.tb = gr.top_block() 31 | 32 | def tearDown(self): 33 | self.tb = None 34 | 35 | def test_pll_refout(self): 36 | expected_result = ((1+0j), 37 | (1+6.408735764296125e-10j), 38 | (0.9999844431877136+0.005577784031629562j), 39 | (0.9998642802238464+0.016474783420562744j), 40 | (0.9994739890098572+0.032431427389383316j), 41 | (0.9985847473144531+0.05318402871489525j), 42 | (0.996917188167572+0.07846084982156754j), 43 | (0.9941533207893372+0.10797744989395142j), 44 | (0.9899479150772095+0.14143235981464386j), 45 | (0.9839394092559814+0.1785029172897339j), 46 | (0.9757603406906128+0.2188417762517929j), 47 | (0.9650475978851318+0.26207470893859863j), 48 | (0.9514514803886414+0.30779871344566345j), 49 | (0.9346449971199036+0.35558223724365234j), 50 | (0.9143316149711609+0.40496626496315j), 51 | (0.8902531862258911+0.4554659426212311j), 52 | (0.8621962666511536+0.5065743923187256j), 53 | (0.8299974799156189+0.5577671527862549j), 54 | (0.7935484647750854+0.6085070967674255j), 55 | (0.7527987360954285+0.6582507491111755j), 56 | (0.7077582478523254+0.7064547538757324j), 57 | (0.6584978699684143+0.7525825500488281j), 58 | (0.6051493883132935+0.7961119413375854j), 59 | (0.547903835773468+0.8365413546562195j), 60 | (0.48700881004333496+0.8733970522880554j), 61 | (0.42276495695114136+0.90623939037323j), 62 | (0.35552138090133667+0.9346681237220764j), 63 | (0.2856702208518982+0.9583280086517334j), 64 | (0.21364101767539978+0.976912260055542j), 65 | (0.13989387452602386+0.9901664853096008j), 66 | (0.06491273641586304+0.9978909492492676j), 67 | (-0.01080091018229723+0.9999416470527649j), 68 | (-0.08673560619354248+0.9962313771247864j), 69 | (-0.16237612068653107+0.9867289662361145j), 70 | (-0.23721040785312653+0.9714583158493042j), 71 | (-0.3107353150844574+0.95049649477005j), 72 | (-0.3824624717235565+0.9239710569381714j), 73 | (-0.45192304253578186+0.892056941986084j), 74 | (-0.5186731219291687+0.8549726009368896j), 75 | (-0.5822963714599609+0.812976598739624j), 76 | (-0.6424083709716797+0.7663624882698059j), 77 | (-0.6986585855484009+0.7154552340507507j), 78 | (-0.7507330775260925+0.6606056690216064j), 79 | (-0.7983550429344177+0.6021870970726013j), 80 | (-0.841286301612854+0.5405898094177246j), 81 | (-0.879327654838562+0.47621726989746094j), 82 | (-0.912318229675293+0.4094819128513336j), 83 | (-0.9401354789733887+0.340800940990448j), 84 | (-0.9626938104629517+0.27059316635131836j), 85 | (-0.979943573474884+0.1992751508951187j), 86 | (-0.9918696284294128+0.12725839018821716j), 87 | (-0.9984893202781677+0.054946307092905045j), 88 | (-0.9998509287834167-0.017267409712076187j), 89 | (-0.9960314631462097-0.08900183439254761j), 90 | (-0.9871346950531006-0.1598907858133316j), 91 | (-0.9732890129089355-0.2295832633972168j), 92 | (-0.9546451568603516-0.29774588346481323j), 93 | (-0.9313743710517883-0.3640628457069397j), 94 | (-0.9036663174629211-0.42823725938796997j), 95 | (-0.8717266321182251-0.48999255895614624j), 96 | (-0.8357754945755005-0.5490713119506836j), 97 | (-0.7960456013679504-0.6052366495132446j), 98 | (-0.7527803182601929-0.658271849155426j), 99 | (-0.706232488155365-0.7079799771308899j), 100 | (-0.6566619873046875-0.7541850209236145j), 101 | (-0.6043350696563721-0.7967302799224854j), 102 | (-0.5495226979255676-0.8354787826538086j), 103 | (-0.4924990236759186-0.8703129887580872j), 104 | (-0.4335414469242096-0.9011335968971252j), 105 | (-0.3729270100593567-0.927860677242279j), 106 | (-0.3109343349933624-0.9504314064979553j), 107 | (-0.2478405237197876-0.9688008427619934j), 108 | (-0.18392162024974823-0.9829409122467041j), 109 | (-0.11945075541734695-0.9928401112556458j), 110 | (-0.05469784513115883-0.9985029697418213j), 111 | (0.010069688782095909-0.9999492764472961j), 112 | (0.07459097355604172-0.9972141981124878j), 113 | (0.13860897719860077-0.9903472065925598j), 114 | (0.2018725872039795-0.979411780834198j), 115 | (0.2641367018222809-0.964485228061676j), 116 | (0.32516375184059143-0.9456577301025391j), 117 | (0.3847236633300781-0.9230318069458008j), 118 | (0.44259318709373474-0.8967224955558777j), 119 | (0.49855801463127136-0.8668563365936279j), 120 | (0.5524120926856995-0.8335711359977722j), 121 | (0.6039596796035767-0.7970148921012878j), 122 | (0.6530137062072754-0.7573460936546326j), 123 | (0.6993972063064575-0.7147331833839417j), 124 | (0.7429447770118713-0.6693527102470398j), 125 | (0.7835012078285217-0.6213902235031128j), 126 | (0.8209227919578552-0.5710391998291016j), 127 | (0.8550769090652466-0.5185011625289917j), 128 | (0.8858439326286316-0.46398329734802246j), 129 | (0.9131162166595459-0.4076994061470032j), 130 | (0.936798632144928-0.3498689830303192j), 131 | (0.956809401512146-0.2907160222530365j), 132 | (0.9730796813964844-0.23046888411045074j), 133 | (0.9855544567108154-0.16935895383358002j), 134 | (0.9941920042037964-0.10762103646993637j), 135 | (0.9989647269248962-0.045491550117731094j)) 136 | 137 | sampling_freq = 10e3 138 | freq = sampling_freq / 100 139 | 140 | loop_bw = math.pi/100.0 141 | maxf = 1 142 | minf = -1 143 | 144 | src = analog.sig_source_c(sampling_freq, analog.GR_COS_WAVE, freq, 1.0) 145 | pll = nwr.pll_refout_cc(loop_bw, maxf, minf) 146 | head = blocks.head(gr.sizeof_gr_complex, int (freq)) 147 | dst = blocks.vector_sink_c() 148 | 149 | self.tb.connect(src, pll, head) 150 | self.tb.connect(head, dst) 151 | 152 | self.tb.run() 153 | dst_data = dst.data() 154 | self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4) 155 | 156 | if __name__ == '__main__': 157 | gr_unittest.run(test_pll_refout, "test_pll_refout_cc.xml") 158 | -------------------------------------------------------------------------------- /python/qa_same_burst_decoder.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright (C) 2016 Andy Walls 5 | # 6 | # This file was automatically generated from a template incorporating 7 | # data input by Andy Walls. 8 | # See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 9 | # 10 | 11 | from gnuradio import gr, gr_unittest 12 | from gnuradio import blocks 13 | import nwr_swig as nwr 14 | 15 | class qa_same_burst_decoder (gr_unittest.TestCase): 16 | 17 | def setUp (self): 18 | self.tb = gr.top_block () 19 | 20 | def tearDown (self): 21 | self.tb = None 22 | 23 | def test_001_t (self): 24 | # set up fg 25 | self.tb.run () 26 | # check data 27 | 28 | 29 | if __name__ == '__main__': 30 | gr_unittest.run(qa_same_burst_decoder, "qa_same_burst_decoder.xml") 31 | -------------------------------------------------------------------------------- /swig/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016 Andy Walls 3 | # 4 | # This file was automatically generated by gr_modtool from GNU Radio 5 | # 6 | # This file was automatically generated from a template incorporating 7 | # data input by Andy Walls. 8 | # See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 9 | # 10 | 11 | ######################################################################## 12 | # Check if there is C++ code at all 13 | ######################################################################## 14 | if(NOT nwr_sources) 15 | MESSAGE(STATUS "No C++ sources... skipping swig/") 16 | return() 17 | endif(NOT nwr_sources) 18 | 19 | ######################################################################## 20 | # Include swig generation macros 21 | ######################################################################## 22 | find_package(SWIG) 23 | find_package(PythonLibs 2) 24 | if(NOT SWIG_FOUND OR NOT PYTHONLIBS_FOUND) 25 | return() 26 | endif() 27 | include(GrSwig) 28 | include(GrPython) 29 | 30 | ######################################################################## 31 | # Setup swig generation 32 | ######################################################################## 33 | foreach(incdir ${GNURADIO_RUNTIME_INCLUDE_DIRS}) 34 | list(APPEND GR_SWIG_INCLUDE_DIRS ${incdir}/gnuradio/swig) 35 | endforeach(incdir) 36 | 37 | list(APPEND GR_SWIG_INCLUDE_DIRS ${Boost_INCLUDE_DIRS}) 38 | list(APPEND GR_SWIG_INCLUDE_DIRS ${UHD_INCLUDE_DIRS}) 39 | 40 | link_directories(${UHD_LIBRARY_DIRS}) 41 | set(GR_SWIG_LIBRARIES gnuradio-nwr ${UHD_LIBRARIES}) 42 | set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/nwr_swig_doc.i) 43 | set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../include) 44 | 45 | GR_SWIG_MAKE(nwr_swig nwr_swig.i) 46 | 47 | ######################################################################## 48 | # Install the build swig module 49 | ######################################################################## 50 | GR_SWIG_INSTALL(TARGETS nwr_swig DESTINATION ${GR_PYTHON_DIR}/nwr) 51 | 52 | ######################################################################## 53 | # Install swig .i files for development 54 | ######################################################################## 55 | install( 56 | FILES 57 | nwr_swig.i 58 | ${CMAKE_CURRENT_BINARY_DIR}/nwr_swig_doc.i 59 | DESTINATION ${GR_INCLUDE_DIR}/nwr/swig 60 | ) 61 | -------------------------------------------------------------------------------- /swig/nwr_swig.i: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright (C) 2016-2017 Andy Walls 4 | * 5 | * This file was automatically generated by gr_modtool from GNU Radio 6 | * 7 | * This file was automatically generated from a template incorporating 8 | * data input by Andy Walls and subsequently hand edited by Andy Walls. 9 | * See http://www.gnu.org/licenses/gpl-faq.en.html#GPLOutput . 10 | */ 11 | 12 | #define NWR_API 13 | 14 | %include "gnuradio.i" // the common stuff 15 | 16 | //load generated python docstrings 17 | %include "nwr_swig_doc.i" 18 | 19 | %{ 20 | #include "nwr/lms_da_equalizer_ff.h" 21 | #include "nwr/burst_detect_and_tag.h" 22 | #include "nwr/correction_estimator_ff.h" 23 | #include "nwr/multiply_by_tag_value_ff.h" 24 | #include "nwr/add_tag_value_ff.h" 25 | #include "nwr/pll_refout_cc.h" 26 | #include "nwr/same_burst_decoder.h" 27 | %} 28 | 29 | %include "nwr/lms_da_equalizer_ff.h" 30 | GR_SWIG_BLOCK_MAGIC2(nwr, lms_da_equalizer_ff); 31 | %include "nwr/burst_detect_and_tag.h" 32 | GR_SWIG_BLOCK_MAGIC2(nwr, burst_detect_and_tag); 33 | %include "nwr/correction_estimator_ff.h" 34 | GR_SWIG_BLOCK_MAGIC2(nwr, correction_estimator_ff); 35 | %include "nwr/multiply_by_tag_value_ff.h" 36 | GR_SWIG_BLOCK_MAGIC2(nwr, multiply_by_tag_value_ff); 37 | %include "nwr/add_tag_value_ff.h" 38 | GR_SWIG_BLOCK_MAGIC2(nwr, add_tag_value_ff); 39 | %include "nwr/pll_refout_cc.h" 40 | GR_SWIG_BLOCK_MAGIC2(nwr, pll_refout_cc); 41 | %include "nwr/same_burst_decoder.h" 42 | GR_SWIG_BLOCK_MAGIC2(nwr, same_burst_decoder); 43 | --------------------------------------------------------------------------------