├── CMakeLists.txt ├── MANIFEST.md ├── README.md ├── apps └── CMakeLists.txt ├── cmake ├── Modules │ ├── CMakeParseArgumentsCopy.cmake │ ├── mesaConfig.cmake │ └── targetConfig.cmake.in └── cmake_uninstall.cmake.in ├── docs ├── CMakeLists.txt ├── README.mesa └── 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 │ ├── pydoc_macros.h │ ├── swig_doc.py │ └── update_pydoc.py ├── examples ├── TestAutocorrelator.grc ├── TestInputSelect.grc ├── TestLongTermIntegrator.grc ├── TestMaxPower.grc ├── TestMaxPower_stateout.grc ├── TestSignalDetetor.grc ├── noaa_Receive_Multi.grc ├── noaa_relay_north.grc ├── noaa_relay_south.grc ├── scanner_fm.grc ├── scanner_fm_single_decode.grc ├── testAutoDoppler.grc └── test_ioselector.grc ├── grc ├── CMakeLists.txt ├── mesa_AutoCorrelator.block.yml ├── mesa_AutoCorrelatorSink.block.yml ├── mesa_AutoDopplerCorrect.block.yml ├── mesa_AvgToMsg.block.yml ├── mesa_LongTermIntegrator.block.yml ├── mesa_MaxPower.block.yml ├── mesa_Normalize.block.yml ├── mesa_SignalDetector.block.yml ├── mesa_SourceSelector.block.yml ├── mesa_VariableRotator.block.yml ├── mesa_ioselector.block.yml └── mesa_phase_shift.block.yml ├── include └── mesa │ ├── AutoDopplerCorrect.h │ ├── AvgToMsg.h │ ├── CMakeLists.txt │ ├── LongTermIntegrator.h │ ├── MaxPower.h │ ├── SignalDetector.h │ ├── SourceSelector.h │ ├── api.h │ ├── ioselector.h │ └── phase_shift.h ├── lib ├── AutoDopplerCorrect_impl.cc ├── AutoDopplerCorrect_impl.h ├── AvgToMsg_impl.cc ├── AvgToMsg_impl.h ├── CMakeLists.txt ├── LongTermIntegrator_impl.cc ├── LongTermIntegrator_impl.h ├── MaxPower_impl.cc ├── MaxPower_impl.h ├── SignalDetector_impl.cc ├── SignalDetector_impl.h ├── SourceSelector_impl.cc ├── SourceSelector_impl.h ├── fir_filter_lfast.h ├── ioselector_impl.cc ├── ioselector_impl.h ├── phase_shift_impl.cc ├── phase_shift_impl.h ├── scomplex.h ├── signals_mesa.cc └── signals_mesa.h └── python ├── AutoCorrelator.py ├── AutoCorrelatorSink.py ├── CMakeLists.txt ├── Normalize.py ├── VariableRotator.py ├── __init__.py └── bindings ├── AutoDopplerCorrect_python.cc ├── AvgToMsg_python.cc ├── CMakeLists.txt ├── LongTermIntegrator_python.cc ├── MaxPower_python.cc ├── README.md ├── SignalDetector_python.cc ├── SourceSelector_python.cc ├── bind_oot_file.py ├── docstrings ├── AutoDopplerCorrect_pydoc_template.h ├── AvgToMsg_pydoc_template.h ├── LongTermIntegrator_pydoc_template.h ├── MaxPower_pydoc_template.h ├── README.md ├── SignalDetector_pydoc_template.h ├── SourceSelector_pydoc_template.h ├── ioselector_pydoc_template.h └── phase_shift_pydoc_template.h ├── header_utils.py ├── ioselector_python.cc ├── phase_shift_python.cc └── python_bindings.cc /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011,2012,2014,2016,2018 Free Software Foundation, Inc. 2 | # 3 | # This file was generated by gr_modtool, a tool from the GNU Radio framework 4 | # This file is a part of gr-mesa 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 | # Project setup 23 | ######################################################################## 24 | cmake_minimum_required(VERSION 3.8) 25 | project(gr-mesa CXX C) 26 | enable_testing() 27 | 28 | # Install to PyBOMBS target prefix if defined 29 | if(DEFINED ENV{PYBOMBS_PREFIX}) 30 | set(CMAKE_INSTALL_PREFIX $ENV{PYBOMBS_PREFIX}) 31 | message(STATUS "PyBOMBS installed GNU Radio. Setting CMAKE_INSTALL_PREFIX to $ENV{PYBOMBS_PREFIX}") 32 | endif() 33 | 34 | # Select the release build type by default to get optimization flags 35 | if(NOT CMAKE_BUILD_TYPE) 36 | set(CMAKE_BUILD_TYPE "Release") 37 | message(STATUS "Build type not specified: defaulting to release.") 38 | endif(NOT CMAKE_BUILD_TYPE) 39 | set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "") 40 | 41 | # Make sure our local CMake Modules path comes first 42 | list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules) 43 | 44 | # Set the version information here 45 | set(VERSION_MAJOR 1) 46 | set(VERSION_API 0) 47 | set(VERSION_ABI 0) 48 | set(VERSION_PATCH git) 49 | 50 | cmake_policy(SET CMP0011 NEW) 51 | 52 | # Enable generation of compile_commands.json for code completion engines 53 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 54 | 55 | ######################################################################## 56 | # Compiler specific setup 57 | ######################################################################## 58 | if((CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR 59 | CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 60 | AND NOT WIN32) 61 | #http://gcc.gnu.org/wiki/Visibility 62 | add_definitions(-fvisibility=hidden) 63 | endif() 64 | 65 | IF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 66 | SET(CMAKE_CXX_STANDARD 11) 67 | ELSEIF(CMAKE_CXX_COMPILER_ID MATCHES "Clang") 68 | SET(CMAKE_CXX_STANDARD 11) 69 | ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") 70 | SET(CMAKE_CXX_STANDARD 11) 71 | ELSE() 72 | message(WARNING "C++ standard could not be set because compiler is not GNU, Clang or MSVC.") 73 | ENDIF() 74 | 75 | IF(CMAKE_C_COMPILER_ID STREQUAL "GNU") 76 | SET(CMAKE_C_STANDARD 11) 77 | ELSEIF(CMAKE_C_COMPILER_ID MATCHES "Clang") 78 | SET(CMAKE_C_STANDARD 11) 79 | ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "MSVC") 80 | SET(CMAKE_C_STANDARD 11) 81 | ELSE() 82 | message(WARNING "C standard could not be set because compiler is not GNU, Clang or MSVC.") 83 | ENDIF() 84 | 85 | ######################################################################## 86 | # Disable complex math NaN/INFO range checking for performance 87 | ######################################################################## 88 | include(CheckCXXCompilerFlag) 89 | check_cxx_compiler_flag(-fcx-limited-range HAVE_CX_LIMITED_RANGE) 90 | if(HAVE_CX_LIMITED_RANGE) 91 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcx-limited-range") 92 | endif(HAVE_CX_LIMITED_RANGE) 93 | 94 | ######################################################################## 95 | # Install directories 96 | ######################################################################## 97 | include(FindPkgConfig) 98 | find_package(Gnuradio "3.9" REQUIRED) 99 | include(GrVersion) 100 | 101 | include(GrPlatform) #define LIB_SUFFIX 102 | 103 | if(NOT CMAKE_MODULES_DIR) 104 | set(CMAKE_MODULES_DIR lib${LIB_SUFFIX}/cmake) 105 | endif(NOT CMAKE_MODULES_DIR) 106 | 107 | set(GR_INCLUDE_DIR include/mesa) 108 | set(GR_CMAKE_DIR ${CMAKE_MODULES_DIR}/mesa) 109 | set(GR_PKG_DATA_DIR ${GR_DATA_DIR}/${CMAKE_PROJECT_NAME}) 110 | set(GR_PKG_DOC_DIR ${GR_DOC_DIR}/${CMAKE_PROJECT_NAME}) 111 | set(GR_PKG_CONF_DIR ${GR_CONF_DIR}/${CMAKE_PROJECT_NAME}/conf.d) 112 | set(GR_PKG_LIBEXEC_DIR ${GR_LIBEXEC_DIR}/${CMAKE_PROJECT_NAME}) 113 | 114 | ######################################################################## 115 | # On Apple only, set install name and use rpath correctly, if not already set 116 | ######################################################################## 117 | if(APPLE) 118 | if(NOT CMAKE_INSTALL_NAME_DIR) 119 | set(CMAKE_INSTALL_NAME_DIR 120 | ${CMAKE_INSTALL_PREFIX}/${GR_LIBRARY_DIR} CACHE 121 | PATH "Library Install Name Destination Directory" FORCE) 122 | endif(NOT CMAKE_INSTALL_NAME_DIR) 123 | if(NOT CMAKE_INSTALL_RPATH) 124 | set(CMAKE_INSTALL_RPATH 125 | ${CMAKE_INSTALL_PREFIX}/${GR_LIBRARY_DIR} CACHE 126 | PATH "Library Install RPath" FORCE) 127 | endif(NOT CMAKE_INSTALL_RPATH) 128 | if(NOT CMAKE_BUILD_WITH_INSTALL_RPATH) 129 | set(CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE 130 | BOOL "Do Build Using Library Install RPath" FORCE) 131 | endif(NOT CMAKE_BUILD_WITH_INSTALL_RPATH) 132 | endif(APPLE) 133 | 134 | ######################################################################## 135 | # Find gnuradio build dependencies 136 | ######################################################################## 137 | find_package(Doxygen) 138 | 139 | ######################################################################## 140 | # PyBind11 Related 141 | ######################################################################## 142 | 143 | find_package(pybind11 REQUIRED) 144 | execute_process( 145 | COMMAND "${PYTHON_EXECUTABLE}" -c 146 | "try:\n import numpy\n import os\n inc_path = numpy.get_include()\n if os.path.exists(os.path.join(inc_path, 'numpy', 'arrayobject.h')):\n print(inc_path, end='')\nexcept:\n pass" 147 | OUTPUT_VARIABLE PYTHON_NUMPY_INCLUDE_DIR) 148 | 149 | ######################################################################## 150 | # Setup doxygen option 151 | ######################################################################## 152 | if(DOXYGEN_FOUND) 153 | option(ENABLE_DOXYGEN "Build docs using Doxygen" ON) 154 | else(DOXYGEN_FOUND) 155 | option(ENABLE_DOXYGEN "Build docs using Doxygen" OFF) 156 | endif(DOXYGEN_FOUND) 157 | 158 | ######################################################################## 159 | # Create uninstall target 160 | ######################################################################## 161 | configure_file( 162 | ${CMAKE_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in 163 | ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake 164 | @ONLY) 165 | 166 | add_custom_target(uninstall 167 | ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake 168 | ) 169 | 170 | 171 | ######################################################################## 172 | # Add subdirectories 173 | ######################################################################## 174 | add_subdirectory(include/mesa) 175 | add_subdirectory(lib) 176 | add_subdirectory(apps) 177 | add_subdirectory(docs) 178 | # NOTE: manually update below to use GRC to generate C++ flowgraphs w/o python 179 | if(ENABLE_PYTHON) 180 | message(STATUS "PYTHON and GRC components are enabled") 181 | add_subdirectory(python) 182 | add_subdirectory(grc) 183 | else(ENABLE_PYTHON) 184 | message(STATUS "PYTHON and GRC components are disabled") 185 | endif(ENABLE_PYTHON) 186 | 187 | ######################################################################## 188 | # Install cmake search helper for this library 189 | ######################################################################## 190 | 191 | install(FILES cmake/Modules/mesaConfig.cmake 192 | DESTINATION ${CMAKE_MODULES_DIR}/mesa 193 | ) 194 | -------------------------------------------------------------------------------- /MANIFEST.md: -------------------------------------------------------------------------------- 1 | title: The MESA OOT Module 2 | brief: Short description of gr-mesa 3 | tags: # Tags are arbitrary, but look at CGRAN what other authors are using 4 | - sdr 5 | author: 6 | - Author Name 7 | copyright_owner: 8 | - Copyright Owner 1 9 | license: 10 | #repo: # Put the URL of the repository here, or leave blank for default 11 | #website: # If you have a separate project website, put it here 12 | #icon: # Put a URL to a square image here that will be used as an icon on CGRAN 13 | --- 14 | A longer, multi-line description of gr-mesa. 15 | You may use some *basic* Markdown here. 16 | If left empty, it will try to find a README file instead. 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gr-mesa - GNURadio Modules for Enhanced Signal Analysis 2 | 3 | ## Overview 4 | gr-mesa is a project to incorporate some enhanced fundamental signal identification and processing blocks to assist with signal input select and downstream analysis. Current blocks include: 5 | 6 | 7 | 1. Max Power Detection - This block will analyze the input signal and based on some parameters that control the length of time / averaging will output a max power message. The block can also, given a threshold value, output a state change (max power above the threshold / below the threshold) when the threshold is crossed. Holddown timers prevent bouncing. This can then be used downstream if signal detection can be based solely on power levels. (e.g. good signal filtering in a dedicated band where seeing a signal power above a noise floor is sufficient to activate downstream processing). This block can also optionally be used to transition from stream inputs to message-based data outputs. 8 | 2. Source Selector - This block monitors the message data inputs for a meta tag "decisionvalue" associated with the input data. Whichever input has the maximum decision value is the one whose data is sent to the output. A hold-down timer is available to limit "bouncing". This can be combined with the MaxPower block to select the input with the best signal strength to continue downstream for processing. This block does provide some buffering to prevent jittery signals due to a lack of samples, however it will not by itself account for delays between signals due to the time variations between multiple receivers receiving the same signal. 9 | 3. Auto Doppler Correct - This block scans the input signal for a signal near the center frequency and attempts to keep the center frequency of the detected signal centered by automatically shifting the signal. This can be useful if you have unkown or dynamic doppler shifting going on. If you would like to switch to processing the output as a PDU at this block, enable PDU processing. This will enable the msgout port. 10 | 4. Signal Detector - This block scans the input signal looking for sub signals of the specified min/max width. The block takes a max-hold average to inspect the spectrum, then determines any signals present in the spectrum. Note that the FFT frames to average is configurable. Too small and the detection is jittery, too high and too many samples will be held/processed so pick a number that works well (or stick with the default). When a signal is detected, a PDU will be generated on the signaldetect connector with a 'state' metadata tag set to 1. PDU's are only sent on state changes, so any downstream blocks should track their own state. When no signals are present and the hold timer has expired, a PDU will be generated with 'state' set to 0. If more downstream data processing is desired, 'Gen Signal PDUs' can be turned on. In that case, for each detected signal, a PDU is generated along with some metadata (radio freq, sample rate, signal center freq, signal width, and signal max power) along with the full data block. This can be used downstream to tune filters and/or shift the signal. 11 | 5. A QT GUI version of the Fast Auto-correlator (example in the examples directory). This conversion makes this block GR 3.8/3.9-Ready. 12 | 6. A fast auto-correlator block that provides correlated vectors as output (example in the examples directory). 13 | 7. Normalize - Take an input vector and normalize all values to 1.0. 14 | 8. Phase Shift - Shift an incoming signal by shift_radians. Shift can be controlled via variable or incoming float message 15 | 9. Average to Message - Take the average of an incoming float vector and output the scalar average as a message 16 | 10. Variable Rotator - While named and functioning more generically, the drive behind this block was a block that could rotate frequencies as part of a GNURadio-based scanner. The block id can be used as a variable, and 2 messages get output: One is the current value, and one is the corresponding index from the list of provided values. The index facilitates different downstream processing paths using the IO Selector for each value. For instance, if the list is frequencies, f1 may be NBFM, f2 may be digital, etc. The block also has a message input that can be used to lock/hold a frequency where activity is detected. See the Scanner section below for more details. 17 | 18 | ## Building 19 | gr-mesa has no core dependencies. However if you will be using the state out ports, it is highly recommended to install gr-filerepeater as additional state blocks are included there. 20 | 21 | `` 22 | cd 23 | 24 | mkdir build 25 | 26 | cd build 27 | 28 | cmake .. 29 | 30 | make 31 | 32 | [sudo] make install 33 | 34 | sudo ldconfig 35 | `` 36 | 37 | If each step was successful (do not overlook the "sudo ldconfig" step if this is the first installation). 38 | 39 | ## GNURadio-Based Scanner 40 | One exciting solution that could be developed with gr-mesa (**note this also requires gr-lfast**) is a complete GNURadio-based scanner. Two basic examples are included in the examples directory. (Note the 3 frequencies is not a limitation, just a setting in the design of the flowgraph for this example) 41 | 1. The first flowgraph scans for voice NBFM signals on 3 different channels and allows for 3 different paths of decoding (examples/scanner_fm.grc). 42 | 2. The second folowgraph uses the same track for all decodes. (examples/scanner_fm_single_decode.grc) 43 | 44 | The key component behind enabling a scanner in GNURadio is the Variable Rotator block in this OOT module, which provides the fundamentals to iterate through a frequency list at set time intervals. The rotator also outputs an index corresponding to the configured list so that different downstream processing paths can be taken for each frequency (if that's how you would like to use it). The first Signal Detector block is then combined with this to detect when a signal is actually present. This mimics the basic scanner function of "is there a signal present? If so, stop here." The state output from the Signal Detector goes high when a signal is detected, when matches up with the hold input of the rotator block creating the necessary feedback loop to hold on a channel when a signal is detected. 45 | 46 | In the first example flowgraph, each path for 3 different frequencies is looking for a NBFM audio/analog signal. Each path uses a separate signal detector such that when the processing holds on a channel, the individual channel signal detector goes high telling an Advanced File Sink from the **gr-filerepeater** OOT module to start recording the signal to a WAV file that can be played back with any WAV file player. (Note: There were some recent updates to the Adv Sink block to support the scanning functionality, so if you already had it installed, please git pull and refresh it). When the signal goes away on the active frequency and the variable rotator's hold is released and it goes to the next frequency, the individual channel detector will transition low after a hold period and close the file. The net result of this whole process is individual recordings for each signal detection on each channel saved in files named and timestamped corresponding to their frequency. 47 | 48 | The second example with a single track capitalizes on the Adv File Sink's capability to rotate files when the frequency changes. If all scanned channels are the same type (in this example NBFM), this is a more efficient approach as it cuts out adding individual signal detectors. 49 | 50 | Both examples use 2 blocks from the **gr-guiextra** OOT module for some better visualization to complete the scanner. The first is a familiar frequency / digital number display. The other is a push / toggle button. Note gr-mesa's note about the digital display, make sure you 'sudo pip3 install pyqtchart' (or pip install if you're still on python2). There's a version issue with the native apt version, even in Ubuntu 18.04 as it only includes version 5.9 and version 5.11 or better is required for a specific function. If you have issues with this approach you can always remove the frequency display from the flowgraph and use a standard GNURadio control instead. THe second control is a toggle button in gr-guiextra that will stay down when pressed and generate messages on state changes. When combined with the State Message Or block from gr-filerepeater as demonstrated in the example flowgraphs, you can within the flowgraph dynamically HOLD or lock onto the current frequency. This tells the rotator to not go to the next frequency until the hold is released and there is no signal. With all of that said, this is a very basic but functioning example of a scanner implemented in GNURadio, and the flowgraphs provide a framework for more advanced processing depending on your needs (this part's up to you). 51 | 52 | From these examples, it's up to you how complex you make it. A couple of suggestions to keep in mind: 53 | 1. Test a single processing track in an isolated flowgraph before thinking something isn't working. And watch any decimations along the way if you integrate a number of stand-alone flowgraphs into one with frequency rotation. 54 | 2. The rotation most likely won't be timing-accurate enough to follow say FHSS, so if you try to put your own together to do that, it probably won't work. 55 | 3. Watch how different the frequencies are relative to the tuning of your antenna. Antenna rules still apply. An antenna tuned to 2m won't be optimal on 70cm, etc. 56 | 4. In the basic example flowgraph provided, you'll see different thresholds set in each track for the signal detector squelch thresholds. This is specifically to adjust differences observed due to (3) with the example frequencies used. You'll need to manually monitor and experiment with the best values here depending on the frequencies you select and overall design. 57 | 5. See the developer's notes below about non QtGUI flowgraphs with the rotator. 58 | 59 | ### Variable Rotator Technical / Developer Notes 60 | There are a few "tricks" in the Variable Rotator block worth mentioning. First, because a separate thread is used to control the scheduling of rotation and messages, sending pmt messages within the Qt GUI context runs into exceptions sending cross-thread. As a result, the workaround was to create the block as a QFrame and leverage Qt's signaling mechanisms to queue it into the message queue of the primary thread with an emit() call. So no GUI control is visually displayed, but one is used behind the scenes to allow for cross-thread behavior to work as expected. While not tested, this COULD mean that using the variable rotator may not work in non-QtGUI flowgraphs. Just something to keep in mind. 61 | 62 | -------------------------------------------------------------------------------- /apps/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file was generated by gr_modtool, a tool from the GNU Radio framework 4 | # This file is a part of gr-mesa 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 | include(GrPython) 22 | 23 | GR_PYTHON_INSTALL( 24 | PROGRAMS 25 | DESTINATION bin 26 | ) 27 | -------------------------------------------------------------------------------- /cmake/Modules/CMakeParseArgumentsCopy.cmake: -------------------------------------------------------------------------------- 1 | # CMAKE_PARSE_ARGUMENTS( args...) 2 | # 3 | # CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions for 4 | # parsing the arguments given to that macro or function. 5 | # It processes the arguments and defines a set of variables which hold the 6 | # values of the respective options. 7 | # 8 | # The argument contains all options for the respective macro, 9 | # i.e. keywords which can be used when calling the macro without any value 10 | # following, like e.g. the OPTIONAL keyword of the install() command. 11 | # 12 | # The argument contains all keywords for this macro 13 | # which are followed by one value, like e.g. DESTINATION keyword of the 14 | # install() command. 15 | # 16 | # The argument contains all keywords for this macro 17 | # which can be followed by more than one value, like e.g. the TARGETS or 18 | # FILES keywords of the install() command. 19 | # 20 | # When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the 21 | # keywords listed in , and 22 | # a variable composed of the given 23 | # followed by "_" and the name of the respective keyword. 24 | # These variables will then hold the respective value from the argument list. 25 | # For the keywords this will be TRUE or FALSE. 26 | # 27 | # All remaining arguments are collected in a variable 28 | # _UNPARSED_ARGUMENTS, this can be checked afterwards to see whether 29 | # your macro was called with unrecognized parameters. 30 | # 31 | # As an example here a my_install() macro, which takes similar arguments as the 32 | # real install() command: 33 | # 34 | # function(MY_INSTALL) 35 | # set(options OPTIONAL FAST) 36 | # set(oneValueArgs DESTINATION RENAME) 37 | # set(multiValueArgs TARGETS CONFIGURATIONS) 38 | # cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) 39 | # ... 40 | # 41 | # Assume my_install() has been called like this: 42 | # my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub) 43 | # 44 | # After the cmake_parse_arguments() call the macro will have set the following 45 | # variables: 46 | # MY_INSTALL_OPTIONAL = TRUE 47 | # MY_INSTALL_FAST = FALSE (this option was not used when calling my_install() 48 | # MY_INSTALL_DESTINATION = "bin" 49 | # MY_INSTALL_RENAME = "" (was not used) 50 | # MY_INSTALL_TARGETS = "foo;bar" 51 | # MY_INSTALL_CONFIGURATIONS = "" (was not used) 52 | # MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL" 53 | # 54 | # You can the continue and process these variables. 55 | # 56 | # Keywords terminate lists of values, e.g. if directly after a one_value_keyword 57 | # another recognized keyword follows, this is interpreted as the beginning of 58 | # the new option. 59 | # E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in 60 | # MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would 61 | # be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefore. 62 | 63 | #============================================================================= 64 | # Copyright 2010 Alexander Neundorf 65 | # 66 | # Distributed under the OSI-approved BSD License (the "License"); 67 | # see accompanying file Copyright.txt for details. 68 | # 69 | # This software is distributed WITHOUT ANY WARRANTY; without even the 70 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 71 | # See the License for more information. 72 | #============================================================================= 73 | # (To distribute this file outside of CMake, substitute the full 74 | # License text for the above reference.) 75 | 76 | 77 | if(__CMAKE_PARSE_ARGUMENTS_INCLUDED) 78 | return() 79 | endif() 80 | set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE) 81 | 82 | 83 | function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames) 84 | # first set all result variables to empty/FALSE 85 | foreach(arg_name ${_singleArgNames} ${_multiArgNames}) 86 | set(${prefix}_${arg_name}) 87 | endforeach(arg_name) 88 | 89 | foreach(option ${_optionNames}) 90 | set(${prefix}_${option} FALSE) 91 | endforeach(option) 92 | 93 | set(${prefix}_UNPARSED_ARGUMENTS) 94 | 95 | set(insideValues FALSE) 96 | set(currentArgName) 97 | 98 | # now iterate over all arguments and fill the result variables 99 | foreach(currentArg ${ARGN}) 100 | list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword 101 | list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword 102 | list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword 103 | 104 | if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1) 105 | if(insideValues) 106 | if("${insideValues}" STREQUAL "SINGLE") 107 | set(${prefix}_${currentArgName} ${currentArg}) 108 | set(insideValues FALSE) 109 | elseif("${insideValues}" STREQUAL "MULTI") 110 | list(APPEND ${prefix}_${currentArgName} ${currentArg}) 111 | endif() 112 | else(insideValues) 113 | list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg}) 114 | endif(insideValues) 115 | else() 116 | if(NOT ${optionIndex} EQUAL -1) 117 | set(${prefix}_${currentArg} TRUE) 118 | set(insideValues FALSE) 119 | elseif(NOT ${singleArgIndex} EQUAL -1) 120 | set(currentArgName ${currentArg}) 121 | set(${prefix}_${currentArgName}) 122 | set(insideValues "SINGLE") 123 | elseif(NOT ${multiArgIndex} EQUAL -1) 124 | set(currentArgName ${currentArg}) 125 | set(${prefix}_${currentArgName}) 126 | set(insideValues "MULTI") 127 | endif() 128 | endif() 129 | 130 | endforeach(currentArg) 131 | 132 | # propagate the result variables to the caller: 133 | foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames}) 134 | set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE) 135 | endforeach(arg_name) 136 | set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE) 137 | 138 | endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs) 139 | -------------------------------------------------------------------------------- /cmake/Modules/mesaConfig.cmake: -------------------------------------------------------------------------------- 1 | INCLUDE(FindPkgConfig) 2 | PKG_CHECK_MODULES(PC_MESA mesa) 3 | 4 | FIND_PATH( 5 | MESA_INCLUDE_DIRS 6 | NAMES mesa/api.h 7 | HINTS $ENV{MESA_DIR}/include 8 | ${PC_MESA_INCLUDEDIR} 9 | PATHS ${CMAKE_INSTALL_PREFIX}/include 10 | /usr/local/include 11 | /usr/include 12 | ) 13 | 14 | FIND_LIBRARY( 15 | MESA_LIBRARIES 16 | NAMES gnuradio-mesa 17 | HINTS $ENV{MESA_DIR}/lib 18 | ${PC_MESA_LIBDIR} 19 | PATHS ${CMAKE_INSTALL_PREFIX}/lib 20 | ${CMAKE_INSTALL_PREFIX}/lib64 21 | /usr/local/lib 22 | /usr/local/lib64 23 | /usr/lib 24 | /usr/lib64 25 | ) 26 | 27 | include("${CMAKE_CURRENT_LIST_DIR}/mesaTarget.cmake") 28 | 29 | INCLUDE(FindPackageHandleStandardArgs) 30 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(MESA DEFAULT_MSG MESA_LIBRARIES MESA_INCLUDE_DIRS) 31 | MARK_AS_ADVANCED(MESA_LIBRARIES MESA_INCLUDE_DIRS) 32 | -------------------------------------------------------------------------------- /cmake/Modules/targetConfig.cmake.in: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Free Software Foundation, Inc. 2 | # 3 | # This file is part of 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(CMakeFindDependencyMacro) 21 | 22 | set(target_deps "@TARGET_DEPENDENCIES@") 23 | foreach(dep IN LISTS target_deps) 24 | find_dependency(${dep}) 25 | endforeach() 26 | include("${CMAKE_CURRENT_LIST_DIR}/@TARGET@Targets.cmake") 27 | -------------------------------------------------------------------------------- /cmake/cmake_uninstall.cmake.in: -------------------------------------------------------------------------------- 1 | # http://www.vtk.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F 2 | 3 | IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 4 | MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") 5 | ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 6 | 7 | FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) 8 | STRING(REGEX REPLACE "\n" ";" files "${files}") 9 | FOREACH(file ${files}) 10 | MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") 11 | IF(EXISTS "$ENV{DESTDIR}${file}") 12 | EXEC_PROGRAM( 13 | "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 14 | OUTPUT_VARIABLE rm_out 15 | RETURN_VALUE rm_retval 16 | ) 17 | IF(NOT "${rm_retval}" STREQUAL 0) 18 | MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") 19 | ENDIF(NOT "${rm_retval}" STREQUAL 0) 20 | ELSEIF(IS_SYMLINK "$ENV{DESTDIR}${file}") 21 | EXEC_PROGRAM( 22 | "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 23 | OUTPUT_VARIABLE rm_out 24 | RETURN_VALUE rm_retval 25 | ) 26 | IF(NOT "${rm_retval}" STREQUAL 0) 27 | MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") 28 | ENDIF(NOT "${rm_retval}" STREQUAL 0) 29 | ELSE(EXISTS "$ENV{DESTDIR}${file}") 30 | MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") 31 | ENDIF(EXISTS "$ENV{DESTDIR}${file}") 32 | ENDFOREACH(file) 33 | -------------------------------------------------------------------------------- /docs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file was generated by gr_modtool, a tool from the GNU Radio framework 4 | # This file is a part of gr-mesa 5 | # 6 | # SPDX-License-Identifier: GPL-3.0-or-later 7 | # 8 | 9 | ######################################################################## 10 | # Setup dependencies 11 | ######################################################################## 12 | find_package(Doxygen) 13 | 14 | ######################################################################## 15 | # Begin conditional configuration 16 | ######################################################################## 17 | if(ENABLE_DOXYGEN) 18 | 19 | ######################################################################## 20 | # Add subdirectories 21 | ######################################################################## 22 | add_subdirectory(doxygen) 23 | 24 | endif(ENABLE_DOXYGEN) 25 | -------------------------------------------------------------------------------- /docs/README.mesa: -------------------------------------------------------------------------------- 1 | This is the mesa-write-a-block package meant as a guide to building 2 | out-of-tree packages. To use the mesa blocks, the Python namespaces 3 | is in 'mesa', which is imported as: 4 | 5 | import mesa 6 | 7 | See the Doxygen documentation for details about the blocks available 8 | in this package. A quick listing of the details can be found in Python 9 | after importing by using: 10 | 11 | help(mesa) 12 | -------------------------------------------------------------------------------- /docs/doxygen/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file was generated by gr_modtool, a tool from the GNU Radio framework 4 | # This file is a part of gr-mesa 5 | # 6 | # SPDX-License-Identifier: GPL-3.0-or-later 7 | # 8 | 9 | ######################################################################## 10 | # Create the doxygen configuration file 11 | ######################################################################## 12 | file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} top_srcdir) 13 | file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} top_builddir) 14 | file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} abs_top_srcdir) 15 | file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} abs_top_builddir) 16 | 17 | set(HAVE_DOT ${DOXYGEN_DOT_FOUND}) 18 | set(enable_html_docs YES) 19 | set(enable_latex_docs NO) 20 | set(enable_mathjax NO) 21 | set(enable_xml_docs YES) 22 | 23 | configure_file( 24 | ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in 25 | ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 26 | @ONLY) 27 | 28 | set(BUILT_DIRS ${CMAKE_CURRENT_BINARY_DIR}/xml ${CMAKE_CURRENT_BINARY_DIR}/html) 29 | 30 | ######################################################################## 31 | # Make and install doxygen docs 32 | ######################################################################## 33 | add_custom_command( 34 | OUTPUT ${BUILT_DIRS} 35 | COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 36 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} 37 | COMMENT "Generating documentation with doxygen" 38 | ) 39 | 40 | add_custom_target(doxygen_target ALL DEPENDS ${BUILT_DIRS}) 41 | 42 | install(DIRECTORY ${BUILT_DIRS} DESTINATION ${GR_PKG_DOC_DIR}) 43 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Free Software Foundation, Inc. 3 | # 4 | # This file was generated by gr_modtool, a tool from the GNU Radio framework 5 | # This file is a part of gr-mesa 6 | # 7 | # SPDX-License-Identifier: GPL-3.0-or-later 8 | # 9 | # 10 | """ 11 | Python interface to contents of doxygen xml documentation. 12 | 13 | Example use: 14 | See the contents of the example folder for the C++ and 15 | doxygen-generated xml used in this example. 16 | 17 | >>> # Parse the doxygen docs. 18 | >>> import os 19 | >>> this_dir = os.path.dirname(globals()['__file__']) 20 | >>> xml_path = this_dir + "/example/xml/" 21 | >>> di = DoxyIndex(xml_path) 22 | 23 | Get a list of all top-level objects. 24 | 25 | >>> print([mem.name() for mem in di.members()]) 26 | [u'Aadvark', u'aadvarky_enough', u'main'] 27 | 28 | Get all functions. 29 | 30 | >>> print([mem.name() for mem in di.in_category(DoxyFunction)]) 31 | [u'aadvarky_enough', u'main'] 32 | 33 | Check if an object is present. 34 | 35 | >>> di.has_member(u'Aadvark') 36 | True 37 | >>> di.has_member(u'Fish') 38 | False 39 | 40 | Get an item by name and check its properties. 41 | 42 | >>> aad = di.get_member(u'Aadvark') 43 | >>> print(aad.brief_description) 44 | Models the mammal Aadvark. 45 | >>> print(aad.detailed_description) 46 | Sadly the model is incomplete and cannot capture all aspects of an aadvark yet. 47 | 48 | This line is uninformative and is only to test line breaks in the comments. 49 | >>> [mem.name() for mem in aad.members()] 50 | [u'aadvarkness', u'print', u'Aadvark', u'get_aadvarkness'] 51 | >>> aad.get_member(u'print').brief_description 52 | u'Outputs the vital aadvark statistics.' 53 | 54 | """ 55 | 56 | from .doxyindex import DoxyIndex, DoxyFunction, DoxyParam, DoxyClass, DoxyFile, DoxyNamespace, DoxyGroup, DoxyFriend, DoxyOther 57 | 58 | def _test(): 59 | import os 60 | this_dir = os.path.dirname(globals()['__file__']) 61 | xml_path = this_dir + "/example/xml/" 62 | di = DoxyIndex(xml_path) 63 | # Get the Aadvark class 64 | aad = di.get_member('Aadvark') 65 | aad.brief_description 66 | import doctest 67 | return doctest.testmod() 68 | 69 | if __name__ == "__main__": 70 | _test() 71 | 72 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/base.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Free Software Foundation, Inc. 3 | # 4 | # This file was generated by gr_modtool, a tool from the GNU Radio framework 5 | # This file is a part of gr-mesa 6 | # 7 | # SPDX-License-Identifier: GPL-3.0-or-later 8 | # 9 | # 10 | """ 11 | A base class is created. 12 | 13 | Classes based upon this are used to make more user-friendly interfaces 14 | to the doxygen xml docs than the generated classes provide. 15 | """ 16 | 17 | import os 18 | import pdb 19 | 20 | from xml.parsers.expat import ExpatError 21 | 22 | from .generated import compound 23 | 24 | 25 | class Base(object): 26 | 27 | class Duplicate(Exception): 28 | pass 29 | 30 | class NoSuchMember(Exception): 31 | pass 32 | 33 | class ParsingError(Exception): 34 | pass 35 | 36 | def __init__(self, parse_data, top=None): 37 | self._parsed = False 38 | self._error = False 39 | self._parse_data = parse_data 40 | self._members = [] 41 | self._dict_members = {} 42 | self._in_category = {} 43 | self._data = {} 44 | if top is not None: 45 | self._xml_path = top._xml_path 46 | # Set up holder of references 47 | else: 48 | top = self 49 | self._refs = {} 50 | self._xml_path = parse_data 51 | self.top = top 52 | 53 | @classmethod 54 | def from_refid(cls, refid, top=None): 55 | """ Instantiate class from a refid rather than parsing object. """ 56 | # First check to see if its already been instantiated. 57 | if top is not None and refid in top._refs: 58 | return top._refs[refid] 59 | # Otherwise create a new instance and set refid. 60 | inst = cls(None, top=top) 61 | inst.refid = refid 62 | inst.add_ref(inst) 63 | return inst 64 | 65 | @classmethod 66 | def from_parse_data(cls, parse_data, top=None): 67 | refid = getattr(parse_data, 'refid', None) 68 | if refid is not None and top is not None and refid in top._refs: 69 | return top._refs[refid] 70 | inst = cls(parse_data, top=top) 71 | if refid is not None: 72 | inst.refid = refid 73 | inst.add_ref(inst) 74 | return inst 75 | 76 | def add_ref(self, obj): 77 | if hasattr(obj, 'refid'): 78 | self.top._refs[obj.refid] = obj 79 | 80 | mem_classes = [] 81 | 82 | def get_cls(self, mem): 83 | for cls in self.mem_classes: 84 | if cls.can_parse(mem): 85 | return cls 86 | raise Exception(("Did not find a class for object '%s'." \ 87 | % (mem.get_name()))) 88 | 89 | def convert_mem(self, mem): 90 | try: 91 | cls = self.get_cls(mem) 92 | converted = cls.from_parse_data(mem, self.top) 93 | if converted is None: 94 | raise Exception('No class matched this object.') 95 | self.add_ref(converted) 96 | return converted 97 | except Exception as e: 98 | print(e) 99 | 100 | @classmethod 101 | def includes(cls, inst): 102 | return isinstance(inst, cls) 103 | 104 | @classmethod 105 | def can_parse(cls, obj): 106 | return False 107 | 108 | def _parse(self): 109 | self._parsed = True 110 | 111 | def _get_dict_members(self, cat=None): 112 | """ 113 | For given category a dictionary is returned mapping member names to 114 | members of that category. For names that are duplicated the name is 115 | mapped to None. 116 | """ 117 | self.confirm_no_error() 118 | if cat not in self._dict_members: 119 | new_dict = {} 120 | for mem in self.in_category(cat): 121 | if mem.name() not in new_dict: 122 | new_dict[mem.name()] = mem 123 | else: 124 | new_dict[mem.name()] = self.Duplicate 125 | self._dict_members[cat] = new_dict 126 | return self._dict_members[cat] 127 | 128 | def in_category(self, cat): 129 | self.confirm_no_error() 130 | if cat is None: 131 | return self._members 132 | if cat not in self._in_category: 133 | self._in_category[cat] = [mem for mem in self._members 134 | if cat.includes(mem)] 135 | return self._in_category[cat] 136 | 137 | def get_member(self, name, cat=None): 138 | self.confirm_no_error() 139 | # Check if it's in a namespace or class. 140 | bits = name.split('::') 141 | first = bits[0] 142 | rest = '::'.join(bits[1:]) 143 | member = self._get_dict_members(cat).get(first, self.NoSuchMember) 144 | # Raise any errors that are returned. 145 | if member in set([self.NoSuchMember, self.Duplicate]): 146 | raise member() 147 | if rest: 148 | return member.get_member(rest, cat=cat) 149 | return member 150 | 151 | def has_member(self, name, cat=None): 152 | try: 153 | mem = self.get_member(name, cat=cat) 154 | return True 155 | except self.NoSuchMember: 156 | return False 157 | 158 | def data(self): 159 | self.confirm_no_error() 160 | return self._data 161 | 162 | def members(self): 163 | self.confirm_no_error() 164 | return self._members 165 | 166 | def process_memberdefs(self): 167 | mdtss = [] 168 | for sec in self._retrieved_data.compounddef.sectiondef: 169 | mdtss += sec.memberdef 170 | # At the moment we lose all information associated with sections. 171 | # Sometimes a memberdef is in several sectiondef. 172 | # We make sure we don't get duplicates here. 173 | uniques = set([]) 174 | for mem in mdtss: 175 | converted = self.convert_mem(mem) 176 | pair = (mem.name, mem.__class__) 177 | if pair not in uniques: 178 | uniques.add(pair) 179 | self._members.append(converted) 180 | 181 | def retrieve_data(self): 182 | filename = os.path.join(self._xml_path, self.refid + '.xml') 183 | try: 184 | self._retrieved_data = compound.parse(filename) 185 | except ExpatError: 186 | print('Error in xml in file %s' % filename) 187 | self._error = True 188 | self._retrieved_data = None 189 | 190 | def check_parsed(self): 191 | if not self._parsed: 192 | self._parse() 193 | 194 | def confirm_no_error(self): 195 | self.check_parsed() 196 | if self._error: 197 | raise self.ParsingError() 198 | 199 | def error(self): 200 | self.check_parsed() 201 | return self._error 202 | 203 | def name(self): 204 | # first see if we can do it without processing. 205 | if self._parse_data is not None: 206 | return self._parse_data.name 207 | self.check_parsed() 208 | return self._retrieved_data.compounddef.name 209 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/doxyindex.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Free Software Foundation, Inc. 3 | # 4 | # This file was generated by gr_modtool, a tool from the GNU Radio framework 5 | # This file is a part of gr-mesa 6 | # 7 | # SPDX-License-Identifier: GPL-3.0-or-later 8 | # 9 | # 10 | """ 11 | Classes providing more user-friendly interfaces to the doxygen xml 12 | docs than the generated classes provide. 13 | """ 14 | 15 | import os 16 | 17 | from .generated import index 18 | from .base import Base 19 | from .text import description 20 | 21 | class DoxyIndex(Base): 22 | """ 23 | Parses a doxygen xml directory. 24 | """ 25 | 26 | __module__ = "gnuradio.utils.doxyxml" 27 | 28 | def _parse(self): 29 | if self._parsed: 30 | return 31 | super(DoxyIndex, self)._parse() 32 | self._root = index.parse(os.path.join(self._xml_path, 'index.xml')) 33 | for mem in self._root.compound: 34 | converted = self.convert_mem(mem) 35 | # For files and namespaces we want the contents to be 36 | # accessible directly from the parent rather than having 37 | # to go through the file object. 38 | if self.get_cls(mem) == DoxyFile: 39 | if mem.name.endswith('.h'): 40 | self._members += converted.members() 41 | self._members.append(converted) 42 | elif self.get_cls(mem) == DoxyNamespace: 43 | self._members += converted.members() 44 | self._members.append(converted) 45 | else: 46 | self._members.append(converted) 47 | 48 | 49 | class DoxyCompMem(Base): 50 | 51 | 52 | kind = None 53 | 54 | def __init__(self, *args, **kwargs): 55 | super(DoxyCompMem, self).__init__(*args, **kwargs) 56 | 57 | @classmethod 58 | def can_parse(cls, obj): 59 | return obj.kind == cls.kind 60 | 61 | def set_descriptions(self, parse_data): 62 | bd = description(getattr(parse_data, 'briefdescription', None)) 63 | dd = description(getattr(parse_data, 'detaileddescription', None)) 64 | self._data['brief_description'] = bd 65 | self._data['detailed_description'] = dd 66 | 67 | def set_parameters(self, data): 68 | vs = [ddc.value for ddc in data.detaileddescription.content_] 69 | pls = [] 70 | for v in vs: 71 | if hasattr(v, 'parameterlist'): 72 | pls += v.parameterlist 73 | pis = [] 74 | for pl in pls: 75 | pis += pl.parameteritem 76 | dpis = [] 77 | for pi in pis: 78 | dpi = DoxyParameterItem(pi) 79 | dpi._parse() 80 | dpis.append(dpi) 81 | self._data['params'] = dpis 82 | 83 | 84 | class DoxyCompound(DoxyCompMem): 85 | pass 86 | 87 | class DoxyMember(DoxyCompMem): 88 | pass 89 | 90 | class DoxyFunction(DoxyMember): 91 | 92 | __module__ = "gnuradio.utils.doxyxml" 93 | 94 | kind = 'function' 95 | 96 | def _parse(self): 97 | if self._parsed: 98 | return 99 | super(DoxyFunction, self)._parse() 100 | self.set_descriptions(self._parse_data) 101 | self.set_parameters(self._parse_data) 102 | if not self._data['params']: 103 | # If the params weren't set by a comment then just grab the names. 104 | self._data['params'] = [] 105 | prms = self._parse_data.param 106 | for prm in prms: 107 | self._data['params'].append(DoxyParam(prm)) 108 | 109 | brief_description = property(lambda self: self.data()['brief_description']) 110 | detailed_description = property(lambda self: self.data()['detailed_description']) 111 | params = property(lambda self: self.data()['params']) 112 | 113 | Base.mem_classes.append(DoxyFunction) 114 | 115 | 116 | class DoxyParam(DoxyMember): 117 | 118 | __module__ = "gnuradio.utils.doxyxml" 119 | 120 | def _parse(self): 121 | if self._parsed: 122 | return 123 | super(DoxyParam, self)._parse() 124 | self.set_descriptions(self._parse_data) 125 | self._data['declname'] = self._parse_data.declname 126 | 127 | @property 128 | def description(self): 129 | descriptions = [] 130 | if self.brief_description: 131 | descriptions.append(self.brief_description) 132 | if self.detailed_description: 133 | descriptions.append(self.detailed_description) 134 | return '\n\n'.join(descriptions) 135 | 136 | brief_description = property(lambda self: self.data()['brief_description']) 137 | detailed_description = property(lambda self: self.data()['detailed_description']) 138 | name = property(lambda self: self.data()['declname']) 139 | 140 | class DoxyParameterItem(DoxyMember): 141 | """A different representation of a parameter in Doxygen.""" 142 | 143 | def _parse(self): 144 | if self._parsed: 145 | return 146 | super(DoxyParameterItem, self)._parse() 147 | names = [] 148 | for nl in self._parse_data.parameternamelist: 149 | for pn in nl.parametername: 150 | names.append(description(pn)) 151 | # Just take first name 152 | self._data['name'] = names[0] 153 | # Get description 154 | pd = description(self._parse_data.get_parameterdescription()) 155 | self._data['description'] = pd 156 | 157 | description = property(lambda self: self.data()['description']) 158 | name = property(lambda self: self.data()['name']) 159 | 160 | 161 | class DoxyClass(DoxyCompound): 162 | 163 | __module__ = "gnuradio.utils.doxyxml" 164 | 165 | kind = 'class' 166 | 167 | def _parse(self): 168 | if self._parsed: 169 | return 170 | super(DoxyClass, self)._parse() 171 | self.retrieve_data() 172 | if self._error: 173 | return 174 | self.set_descriptions(self._retrieved_data.compounddef) 175 | self.set_parameters(self._retrieved_data.compounddef) 176 | # Sectiondef.kind tells about whether private or public. 177 | # We just ignore this for now. 178 | self.process_memberdefs() 179 | 180 | brief_description = property(lambda self: self.data()['brief_description']) 181 | detailed_description = property(lambda self: self.data()['detailed_description']) 182 | params = property(lambda self: self.data()['params']) 183 | 184 | Base.mem_classes.append(DoxyClass) 185 | 186 | 187 | class DoxyFile(DoxyCompound): 188 | 189 | __module__ = "gnuradio.utils.doxyxml" 190 | 191 | kind = 'file' 192 | 193 | def _parse(self): 194 | if self._parsed: 195 | return 196 | super(DoxyFile, self)._parse() 197 | self.retrieve_data() 198 | self.set_descriptions(self._retrieved_data.compounddef) 199 | if self._error: 200 | return 201 | self.process_memberdefs() 202 | 203 | brief_description = property(lambda self: self.data()['brief_description']) 204 | detailed_description = property(lambda self: self.data()['detailed_description']) 205 | 206 | Base.mem_classes.append(DoxyFile) 207 | 208 | 209 | class DoxyNamespace(DoxyCompound): 210 | 211 | __module__ = "gnuradio.utils.doxyxml" 212 | 213 | kind = 'namespace' 214 | 215 | def _parse(self): 216 | if self._parsed: 217 | return 218 | super(DoxyNamespace, self)._parse() 219 | self.retrieve_data() 220 | self.set_descriptions(self._retrieved_data.compounddef) 221 | if self._error: 222 | return 223 | self.process_memberdefs() 224 | 225 | Base.mem_classes.append(DoxyNamespace) 226 | 227 | 228 | class DoxyGroup(DoxyCompound): 229 | 230 | __module__ = "gnuradio.utils.doxyxml" 231 | 232 | kind = 'group' 233 | 234 | def _parse(self): 235 | if self._parsed: 236 | return 237 | super(DoxyGroup, self)._parse() 238 | self.retrieve_data() 239 | if self._error: 240 | return 241 | cdef = self._retrieved_data.compounddef 242 | self._data['title'] = description(cdef.title) 243 | # Process inner groups 244 | grps = cdef.innergroup 245 | for grp in grps: 246 | converted = DoxyGroup.from_refid(grp.refid, top=self.top) 247 | self._members.append(converted) 248 | # Process inner classes 249 | klasses = cdef.innerclass 250 | for kls in klasses: 251 | converted = DoxyClass.from_refid(kls.refid, top=self.top) 252 | self._members.append(converted) 253 | # Process normal members 254 | self.process_memberdefs() 255 | 256 | title = property(lambda self: self.data()['title']) 257 | 258 | 259 | Base.mem_classes.append(DoxyGroup) 260 | 261 | 262 | class DoxyFriend(DoxyMember): 263 | 264 | __module__ = "gnuradio.utils.doxyxml" 265 | 266 | kind = 'friend' 267 | 268 | Base.mem_classes.append(DoxyFriend) 269 | 270 | 271 | class DoxyOther(Base): 272 | 273 | __module__ = "gnuradio.utils.doxyxml" 274 | 275 | kinds = set(['variable', 'struct', 'union', 'define', 'typedef', 'enum', 276 | 'dir', 'page', 'signal', 'slot', 'property']) 277 | 278 | @classmethod 279 | def can_parse(cls, obj): 280 | return obj.kind in cls.kinds 281 | 282 | Base.mem_classes.append(DoxyOther) 283 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/generated/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Contains generated files produced by generateDS.py. 3 | 4 | These do the real work of parsing the doxygen xml files but the 5 | resultant classes are not very friendly to navigate so the rest of the 6 | doxyxml module processes them further. 7 | """ 8 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/generated/index.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Generated Mon Feb 9 19:08:05 2009 by generateDS.py. 5 | """ 6 | 7 | from xml.dom import minidom 8 | 9 | import os 10 | import sys 11 | from . import compound 12 | 13 | from . import indexsuper as supermod 14 | 15 | class DoxygenTypeSub(supermod.DoxygenType): 16 | def __init__(self, version=None, compound=None): 17 | supermod.DoxygenType.__init__(self, version, compound) 18 | 19 | def find_compounds_and_members(self, details): 20 | """ 21 | Returns a list of all compounds and their members which match details 22 | """ 23 | 24 | results = [] 25 | for compound in self.compound: 26 | members = compound.find_members(details) 27 | if members: 28 | results.append([compound, members]) 29 | else: 30 | if details.match(compound): 31 | results.append([compound, []]) 32 | 33 | return results 34 | 35 | supermod.DoxygenType.subclass = DoxygenTypeSub 36 | # end class DoxygenTypeSub 37 | 38 | 39 | class CompoundTypeSub(supermod.CompoundType): 40 | def __init__(self, kind=None, refid=None, name='', member=None): 41 | supermod.CompoundType.__init__(self, kind, refid, name, member) 42 | 43 | def find_members(self, details): 44 | """ 45 | Returns a list of all members which match details 46 | """ 47 | 48 | results = [] 49 | 50 | for member in self.member: 51 | if details.match(member): 52 | results.append(member) 53 | 54 | return results 55 | 56 | supermod.CompoundType.subclass = CompoundTypeSub 57 | # end class CompoundTypeSub 58 | 59 | 60 | class MemberTypeSub(supermod.MemberType): 61 | 62 | def __init__(self, kind=None, refid=None, name=''): 63 | supermod.MemberType.__init__(self, kind, refid, name) 64 | 65 | supermod.MemberType.subclass = MemberTypeSub 66 | # end class MemberTypeSub 67 | 68 | 69 | def parse(inFilename): 70 | 71 | doc = minidom.parse(inFilename) 72 | rootNode = doc.documentElement 73 | rootObj = supermod.DoxygenType.factory() 74 | rootObj.build(rootNode) 75 | 76 | return rootObj 77 | 78 | -------------------------------------------------------------------------------- /docs/doxygen/doxyxml/text.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2010 Free Software Foundation, Inc. 3 | # 4 | # This file was generated by gr_modtool, a tool from the GNU Radio framework 5 | # This file is a part of gr-mesa 6 | # 7 | # SPDX-License-Identifier: GPL-3.0-or-later 8 | # 9 | # 10 | """ 11 | Utilities for extracting text from generated classes. 12 | """ 13 | 14 | def is_string(txt): 15 | if isinstance(txt, str): 16 | return True 17 | try: 18 | if isinstance(txt, str): 19 | return True 20 | except NameError: 21 | pass 22 | return False 23 | 24 | def description(obj): 25 | if obj is None: 26 | return None 27 | return description_bit(obj).strip() 28 | 29 | def description_bit(obj): 30 | if hasattr(obj, 'content'): 31 | contents = [description_bit(item) for item in obj.content] 32 | result = ''.join(contents) 33 | elif hasattr(obj, 'content_'): 34 | contents = [description_bit(item) for item in obj.content_] 35 | result = ''.join(contents) 36 | elif hasattr(obj, 'value'): 37 | result = description_bit(obj.value) 38 | elif is_string(obj): 39 | return obj 40 | else: 41 | raise Exception('Expecting a string or something with content, content_ or value attribute') 42 | # If this bit is a paragraph then add one some line breaks. 43 | if hasattr(obj, 'name') and obj.name == 'para': 44 | result += "\n\n" 45 | return result 46 | -------------------------------------------------------------------------------- /docs/doxygen/other/group_defs.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | * \defgroup block GNU Radio MESA C++ Signal Processing Blocks 3 | * \brief All C++ blocks that can be used from the MESA GNU Radio 4 | * module are listed here or in the subcategories below. 5 | * 6 | */ 7 | 8 | -------------------------------------------------------------------------------- /docs/doxygen/other/main_page.dox: -------------------------------------------------------------------------------- 1 | /*! \mainpage 2 | 3 | Welcome to the GNU Radio MESA Block 4 | 5 | This is the intro page for the Doxygen manual generated for the MESA 6 | block (docs/doxygen/other/main_page.dox). Edit it to add more detailed 7 | documentation about the new GNU Radio modules contained in this 8 | project. 9 | 10 | */ 11 | -------------------------------------------------------------------------------- /docs/doxygen/pydoc_macros.h: -------------------------------------------------------------------------------- 1 | #ifndef PYDOC_MACROS_H 2 | #define PYDOC_MACROS_H 3 | 4 | #define __EXPAND(x) x 5 | #define __COUNT(_1, _2, _3, _4, _5, _6, _7, COUNT, ...) COUNT 6 | #define __VA_SIZE(...) __EXPAND(__COUNT(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1)) 7 | #define __CAT1(a, b) a##b 8 | #define __CAT2(a, b) __CAT1(a, b) 9 | #define __DOC1(n1) __doc_##n1 10 | #define __DOC2(n1, n2) __doc_##n1##_##n2 11 | #define __DOC3(n1, n2, n3) __doc_##n1##_##n2##_##n3 12 | #define __DOC4(n1, n2, n3, n4) __doc_##n1##_##n2##_##n3##_##n4 13 | #define __DOC5(n1, n2, n3, n4, n5) __doc_##n1##_##n2##_##n3##_##n4##_##n5 14 | #define __DOC6(n1, n2, n3, n4, n5, n6) __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6 15 | #define __DOC7(n1, n2, n3, n4, n5, n6, n7) \ 16 | __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6##_##n7 17 | #define DOC(...) __EXPAND(__EXPAND(__CAT2(__DOC, __VA_SIZE(__VA_ARGS__)))(__VA_ARGS__)) 18 | 19 | #endif // PYDOC_MACROS_H -------------------------------------------------------------------------------- /examples/TestAutocorrelator.grc: -------------------------------------------------------------------------------- 1 | options: 2 | parameters: 3 | author: '' 4 | category: '[GRC Hier Blocks]' 5 | cmake_opt: '' 6 | comment: '' 7 | copyright: '' 8 | description: '' 9 | gen_cmake: 'On' 10 | gen_linking: dynamic 11 | generate_options: qt_gui 12 | hier_block_src_path: '.:' 13 | id: test_autocorrelator 14 | max_nouts: '0' 15 | output_language: python 16 | placement: (0,0) 17 | qt_qss_theme: '' 18 | realtime_scheduling: '' 19 | run: 'True' 20 | run_command: '{python} -u {filename}' 21 | run_options: prompt 22 | sizing_mode: fixed 23 | thread_safe_setters: '' 24 | title: '' 25 | window_size: '' 26 | states: 27 | bus_sink: false 28 | bus_source: false 29 | bus_structure: null 30 | coordinate: [8, 8] 31 | rotation: 0 32 | state: enabled 33 | 34 | blocks: 35 | - name: fac_decimation 36 | id: variable 37 | parameters: 38 | comment: '' 39 | value: '10' 40 | states: 41 | bus_sink: false 42 | bus_source: false 43 | bus_structure: null 44 | coordinate: [640, 12] 45 | rotation: 0 46 | state: enabled 47 | - name: fac_size 48 | id: variable 49 | parameters: 50 | comment: '' 51 | value: '512' 52 | states: 53 | bus_sink: false 54 | bus_source: false 55 | bus_structure: null 56 | coordinate: [440, 12] 57 | rotation: 0 58 | state: enabled 59 | - name: freq 60 | id: variable 61 | parameters: 62 | comment: '' 63 | value: 2441e6 64 | states: 65 | bus_sink: false 66 | bus_source: false 67 | bus_structure: null 68 | coordinate: [312, 12] 69 | rotation: 0 70 | state: enabled 71 | - name: samp_rate 72 | id: variable 73 | parameters: 74 | comment: '' 75 | value: 10e3 76 | states: 77 | bus_sink: false 78 | bus_source: false 79 | bus_structure: null 80 | coordinate: [200, 12] 81 | rotation: 0 82 | state: enabled 83 | - name: window_time 84 | id: variable 85 | parameters: 86 | comment: '' 87 | value: samp_rate/fac_size 88 | states: 89 | bus_sink: false 90 | bus_source: false 91 | bus_structure: null 92 | coordinate: [528, 12] 93 | rotation: 0 94 | state: enabled 95 | - name: analog_sig_source_x_0 96 | id: analog_sig_source_x 97 | parameters: 98 | affinity: '' 99 | alias: '' 100 | amp: '1' 101 | comment: '' 102 | freq: '1000' 103 | maxoutbuf: '0' 104 | minoutbuf: '0' 105 | offset: '0' 106 | phase: '0' 107 | samp_rate: samp_rate 108 | type: complex 109 | waveform: analog.GR_TRI_WAVE 110 | states: 111 | bus_sink: false 112 | bus_source: false 113 | bus_structure: null 114 | coordinate: [216, 272] 115 | rotation: 0 116 | state: enabled 117 | - name: blocks_throttle_0 118 | id: blocks_throttle 119 | parameters: 120 | affinity: '' 121 | alias: '' 122 | comment: '' 123 | ignoretag: 'True' 124 | maxoutbuf: '0' 125 | minoutbuf: '0' 126 | samples_per_second: samp_rate 127 | type: complex 128 | vlen: '1' 129 | states: 130 | bus_sink: false 131 | bus_source: false 132 | bus_structure: null 133 | coordinate: [448, 300] 134 | rotation: 0 135 | state: enabled 136 | - name: blocks_vector_to_stream_0 137 | id: blocks_vector_to_stream 138 | parameters: 139 | affinity: '' 140 | alias: '' 141 | comment: '' 142 | maxoutbuf: '0' 143 | minoutbuf: '0' 144 | num_items: fac_size 145 | type: float 146 | vlen: '1' 147 | states: 148 | bus_sink: false 149 | bus_source: false 150 | bus_structure: null 151 | coordinate: [728, 444] 152 | rotation: 0 153 | state: enabled 154 | - name: import_0 155 | id: import 156 | parameters: 157 | alias: '' 158 | comment: '' 159 | imports: import math 160 | states: 161 | bus_sink: false 162 | bus_source: false 163 | bus_structure: null 164 | coordinate: [1112, 20] 165 | rotation: 0 166 | state: enabled 167 | - name: mesa_AutoCorrelatorSink_1 168 | id: mesa_AutoCorrelatorSink 169 | parameters: 170 | affinity: '' 171 | alias: '' 172 | autoScale: 'False' 173 | comment: '' 174 | fac_decimation: '10' 175 | fac_size: '512' 176 | grid: 'True' 177 | gui_hint: 2,0,1,3 178 | sampRate: samp_rate 179 | title: Fast Autocorrelation Sink 180 | useDB: 'False' 181 | yMax: '1' 182 | yMin: '0' 183 | states: 184 | bus_sink: false 185 | bus_source: false 186 | bus_structure: null 187 | coordinate: [832, 580] 188 | rotation: 0 189 | state: enabled 190 | - name: mesa_AutoCorrelator_0 191 | id: mesa_AutoCorrelator 192 | parameters: 193 | affinity: '' 194 | alias: '' 195 | comment: '' 196 | fac_decimation: fac_decimation 197 | fac_size: fac_size 198 | maxoutbuf: '0' 199 | minoutbuf: '0' 200 | sampRate: samp_rate 201 | useDB: 'False' 202 | states: 203 | bus_sink: false 204 | bus_source: false 205 | bus_structure: null 206 | coordinate: [408, 424] 207 | rotation: 0 208 | state: enabled 209 | - name: mesa_Normalize_0 210 | id: mesa_Normalize 211 | parameters: 212 | affinity: '' 213 | alias: '' 214 | comment: '' 215 | maxoutbuf: '0' 216 | minoutbuf: '0' 217 | vecsize: fac_size 218 | states: 219 | bus_sink: false 220 | bus_source: false 221 | bus_structure: null 222 | coordinate: [592, 444] 223 | rotation: 0 224 | state: enabled 225 | - name: note_0 226 | id: note 227 | parameters: 228 | alias: '' 229 | comment: '' 230 | note: Access to the Correlated Data 231 | states: 232 | bus_sink: false 233 | bus_source: false 234 | bus_structure: null 235 | coordinate: [712, 396] 236 | rotation: 0 237 | state: enabled 238 | - name: note_0_0 239 | id: note 240 | parameters: 241 | alias: '' 242 | comment: '' 243 | note: Direct Plot 244 | states: 245 | bus_sink: false 246 | bus_source: false 247 | bus_structure: null 248 | coordinate: [784, 524] 249 | rotation: 0 250 | state: enabled 251 | - name: qtgui_sink_x_0 252 | id: qtgui_sink_x 253 | parameters: 254 | affinity: '' 255 | alias: '' 256 | bw: samp_rate 257 | comment: '' 258 | fc: freq 259 | fftsize: '1024' 260 | gui_hint: 0,0,1,3 261 | maxoutbuf: '0' 262 | minoutbuf: '0' 263 | name: '""' 264 | plotconst: 'False' 265 | plotfreq: 'True' 266 | plottime: 'True' 267 | plotwaterfall: 'True' 268 | rate: '10' 269 | showports: 'True' 270 | showrf: 'False' 271 | type: complex 272 | wintype: window.WIN_BLACKMAN_hARRIS 273 | states: 274 | bus_sink: false 275 | bus_source: false 276 | bus_structure: null 277 | coordinate: [784, 288] 278 | rotation: 0 279 | state: enabled 280 | - name: qtgui_time_sink_x_1 281 | id: qtgui_time_sink_x 282 | parameters: 283 | affinity: '' 284 | alias: '' 285 | alpha1: '1.0' 286 | alpha10: '1.0' 287 | alpha2: '1.0' 288 | alpha3: '1.0' 289 | alpha4: '1.0' 290 | alpha5: '1.0' 291 | alpha6: '1.0' 292 | alpha7: '1.0' 293 | alpha8: '1.0' 294 | alpha9: '1.0' 295 | autoscale: 'True' 296 | axislabels: 'True' 297 | color1: blue 298 | color10: dark blue 299 | color2: red 300 | color3: green 301 | color4: black 302 | color5: cyan 303 | color6: magenta 304 | color7: yellow 305 | color8: dark red 306 | color9: dark green 307 | comment: '' 308 | ctrlpanel: 'False' 309 | entags: 'True' 310 | grid: 'True' 311 | gui_hint: 1,0,1,3 312 | label1: '' 313 | label10: '' 314 | label2: '' 315 | label3: '' 316 | label4: '' 317 | label5: '' 318 | label6: '' 319 | label7: '' 320 | label8: '' 321 | label9: '' 322 | legend: 'False' 323 | marker1: '-1' 324 | marker10: '-1' 325 | marker2: '-1' 326 | marker3: '-1' 327 | marker4: '-1' 328 | marker5: '-1' 329 | marker6: '-1' 330 | marker7: '-1' 331 | marker8: '-1' 332 | marker9: '-1' 333 | name: Fast Autocorrelation 334 | nconnections: '1' 335 | size: int(fac_size/2) 336 | srate: samp_rate 337 | stemplot: 'False' 338 | style1: '1' 339 | style10: '1' 340 | style2: '1' 341 | style3: '1' 342 | style4: '1' 343 | style5: '1' 344 | style6: '1' 345 | style7: '1' 346 | style8: '1' 347 | style9: '1' 348 | tr_chan: '0' 349 | tr_delay: '0' 350 | tr_level: '0.0' 351 | tr_mode: qtgui.TRIG_MODE_FREE 352 | tr_slope: qtgui.TRIG_SLOPE_POS 353 | tr_tag: '""' 354 | type: float 355 | update_time: '0.10' 356 | width1: '1' 357 | width10: '1' 358 | width2: '1' 359 | width3: '1' 360 | width4: '1' 361 | width5: '1' 362 | width6: '1' 363 | width7: '1' 364 | width8: '1' 365 | width9: '1' 366 | ylabel: dB 367 | ymax: '1' 368 | ymin: '-1' 369 | yunit: '""' 370 | states: 371 | bus_sink: false 372 | bus_source: false 373 | bus_structure: null 374 | coordinate: [912, 424] 375 | rotation: 0 376 | state: enabled 377 | 378 | connections: 379 | - [analog_sig_source_x_0, '0', blocks_throttle_0, '0'] 380 | - [blocks_throttle_0, '0', mesa_AutoCorrelatorSink_1, '0'] 381 | - [blocks_throttle_0, '0', mesa_AutoCorrelator_0, '0'] 382 | - [blocks_throttle_0, '0', qtgui_sink_x_0, '0'] 383 | - [blocks_vector_to_stream_0, '0', qtgui_time_sink_x_1, '0'] 384 | - [mesa_AutoCorrelator_0, '0', mesa_Normalize_0, '0'] 385 | - [mesa_Normalize_0, '0', blocks_vector_to_stream_0, '0'] 386 | 387 | metadata: 388 | file_format: 1 389 | -------------------------------------------------------------------------------- /grc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file was generated by gr_modtool, a tool from the GNU Radio framework 4 | # This file is a part of gr-mesa 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 | install(FILES 21 | mesa_SignalDetector.block.yml 22 | mesa_AutoDopplerCorrect.block.yml 23 | mesa_MaxPower.block.yml 24 | mesa_SourceSelector.block.yml 25 | mesa_LongTermIntegrator.block.yml 26 | mesa_ioselector.block.yml 27 | mesa_AutoCorrelator.block.yml 28 | mesa_AutoCorrelatorSink.block.yml 29 | mesa_Normalize.block.yml 30 | mesa_phase_shift.block.yml 31 | mesa_AvgToMsg.block.yml 32 | mesa_VariableRotator.block.yml DESTINATION share/gnuradio/grc/blocks 33 | ) 34 | -------------------------------------------------------------------------------- /grc/mesa_AutoCorrelator.block.yml: -------------------------------------------------------------------------------- 1 | # auto-generated by grc.converter 2 | 3 | id: mesa_AutoCorrelator 4 | label: Fast Auto-Correlator 5 | category: '[mesa]' 6 | 7 | parameters: 8 | - id: sampRate 9 | label: Sample Rate 10 | dtype: float 11 | default: samp_rate 12 | - id: fac_size 13 | label: FAC Size 14 | dtype: int 15 | default: '512' 16 | - id: fac_decimation 17 | label: FAC Decimation 18 | dtype: int 19 | default: '10' 20 | - id: useDB 21 | label: Output 22 | dtype: enum 23 | options: ['False', 'True'] 24 | option_labels: [Normalized, dB] 25 | 26 | inputs: 27 | - domain: stream 28 | dtype: complex 29 | 30 | outputs: 31 | - domain: stream 32 | dtype: float 33 | vlen: ${ fac_size } 34 | 35 | templates: 36 | imports: import mesa 37 | make: mesa.AutoCorrelator(${sampRate}, ${fac_size}, ${fac_decimation}, ${useDB}) 38 | 39 | documentation: |- 40 | This block is the numerical calculation of the fast auto-correlation block previously available in gr-baz. It uses the Wiener Khinchin theorem that the FFT of a signal's power spectrum is its auto-correlation function. FAC Size controls the FFT size and therefore the length of time (samp_rate/fac_size) the auto-correlation runs over. While a separate block provides an all-in-one sink, this can be fed into a vector-to-stream then into a time sink block for display. 41 | 42 | file_format: 1 43 | -------------------------------------------------------------------------------- /grc/mesa_AutoCorrelatorSink.block.yml: -------------------------------------------------------------------------------- 1 | # auto-generated by grc.converter 2 | 3 | id: mesa_AutoCorrelatorSink 4 | label: Fast Auto-Correlator Sink 5 | category: '[mesa]' 6 | 7 | parameters: 8 | - id: sampRate 9 | label: Sample Rate 10 | dtype: float 11 | default: samp_rate 12 | - id: fac_size 13 | label: FAC Size 14 | dtype: int 15 | default: '512' 16 | - id: fac_decimation 17 | label: FAC Decimation 18 | dtype: int 19 | default: '10' 20 | - id: useDB 21 | label: Output 22 | dtype: enum 23 | options: ['False', 'True'] 24 | option_labels: [Normalized, dB] 25 | - id: title 26 | label: Title 27 | dtype: string 28 | default: '""' 29 | - id: grid 30 | label: Show Grid 31 | dtype: enum 32 | options: ['True', 'False'] 33 | option_labels: ['Yes', 'No'] 34 | - id: autoScale 35 | label: Auto-Scale 36 | dtype: enum 37 | options: ['False', 'True'] 38 | option_labels: ['No', 'Yes'] 39 | - id: yMin 40 | label: Y Min 41 | dtype: float 42 | default: '0' 43 | - id: yMax 44 | label: Y Max 45 | dtype: float 46 | default: '1' 47 | - id: gui_hint 48 | label: GUI Hint 49 | dtype: gui_hint 50 | hide: part 51 | 52 | inputs: 53 | - domain: stream 54 | dtype: complex 55 | 56 | templates: 57 | imports: import mesa 58 | make: |- 59 | <% 60 | win = 'self._%s_win'%id 61 | %>\ 62 | mesa.AutoCorrelatorSink(${sampRate}, 63 | ${fac_size}, 64 | ${fac_decimation}, 65 | ${title}, 66 | ${autoScale}, 67 | ${grid}, 68 | ${yMin}, 69 | ${yMax}, 70 | ${useDB} 71 | ) 72 | self._${id}_win = self.${id}.getWidget() 73 | ${gui_hint() % win} 74 | 75 | documentation: |- 76 | This block is a QT GUI replacement for the fast auto-correlation block previously available in gr-baz. It uses the Wiener Khinchin theorem that the FFT of a signal's power spectrum is its auto-correlation function. FAC Size controls the FFT size and therefore the length of time (samp_rate/fac_size) the auto-correlation runs over. While a separate block provides an all-in-one sink, this can be fed into a vector-to-stream then into a time sink block for display. 77 | 78 | file_format: 1 79 | -------------------------------------------------------------------------------- /grc/mesa_AutoDopplerCorrect.block.yml: -------------------------------------------------------------------------------- 1 | # auto-generated by grc.converter 2 | 3 | id: mesa_AutoDopplerCorrect 4 | label: Auto Doppler Correct 5 | category: '[mesa]' 6 | 7 | parameters: 8 | - id: freq 9 | label: Radio Frequency 10 | dtype: float 11 | default: freq 12 | - id: sampleRate 13 | label: Sample Rate 14 | dtype: float 15 | default: samp_rate 16 | - id: maxDrift 17 | label: Max Drift (Hz) 18 | dtype: float 19 | default: '3000.0' 20 | - id: minWidth 21 | label: Min Signal Width (Hz) 22 | dtype: float 23 | default: '2000.0' 24 | - id: expectedWidth 25 | label: Expected Signal Width (Hz) 26 | dtype: float 27 | default: '6000.0' 28 | - id: shiftHolddownMS 29 | label: Shift Hold Time (ms) 30 | dtype: int 31 | default: '2000' 32 | - id: holdUpSec 33 | label: Detect Hold Time (s) 34 | dtype: float 35 | default: '10.0' 36 | - id: fft_size 37 | label: FFT Size 38 | dtype: int 39 | default: '1024' 40 | - id: squelchThreshold 41 | label: Squelch Threshold 42 | dtype: float 43 | default: '-80.0' 44 | - id: framesToAvg 45 | label: Frames to Avg 46 | dtype: int 47 | default: '6' 48 | - id: detectionMethod 49 | label: Detection Method 50 | dtype: enum 51 | options: ['1', '2'] 52 | option_labels: [Closest Signal, Boxing Outside-In] 53 | - id: processMessages 54 | label: Message Processing 55 | dtype: enum 56 | options: ['False', 'True'] 57 | option_labels: ['Off', 'On'] 58 | 59 | inputs: 60 | - domain: stream 61 | dtype: complex 62 | - domain: message 63 | id: msgin 64 | optional: true 65 | 66 | outputs: 67 | - domain: stream 68 | dtype: complex 69 | - domain: message 70 | id: msgout 71 | optional: true 72 | - domain: message 73 | id: signaldetect 74 | optional: true 75 | - domain: message 76 | id: freq_info 77 | optional: true 78 | - domain: message 79 | id: state 80 | optional: true 81 | - domain: message 82 | id: freq_shift 83 | optional: true 84 | 85 | templates: 86 | imports: import mesa 87 | make: mesa.AutoDopplerCorrect(${freq}, ${sampleRate}, ${maxDrift}, ${minWidth}, 88 | ${expectedWidth}, ${shiftHolddownMS}, ${fft_size}, ${squelchThreshold}, ${framesToAvg}, 89 | ${holdUpSec}, ${processMessages},${detectionMethod}) 90 | callbacks: 91 | - setSquelch(${squelchThreshold}) 92 | - setMinWidthHz(${minWidthHz}) 93 | - setCenterFrequency(${radioCenterFreq}) 94 | - setExpectedWidth(${expectedWidth}) 95 | - setMaxDrift(${maxDrift}) 96 | 97 | documentation: "This block scans the input signal for a signal near the center frequency\ 98 | \ and attempts to keep the output centered.\n\nIf you would like to switch to\ 99 | \ processing the output as a PDU, enable PDU processing. This will enable the\ 100 | \ msgout port. \n\nNOTES: \n\nFor SQUELCHTHRESHOLD, pick a number that's above\ 101 | \ any noise floor. The detector looks for the upward transition from this squelch\ 102 | \ threshold, therefore everything that's not a signal should be below this threshold,\ 103 | \ such that everything above it can be assumed to be a signal.\n\nTwo methods\ 104 | \ of detecting the active signal to center are availble. The first (closest signal)\ 105 | \ looks for a peak and edges closest to the specified center frequency. This\ 106 | \ will work well for a single channel, ASK/FSK/PSK signal. However, if you have\ 107 | \ a channelized signal with multiple subchannels, this will not work as well.\ 108 | \ A boxing method is available that will look at the spectrum from the edges\ 109 | \ in looking for the farthest edges to define the signal." 110 | 111 | file_format: 1 112 | -------------------------------------------------------------------------------- /grc/mesa_AvgToMsg.block.yml: -------------------------------------------------------------------------------- 1 | # auto-generated by grc.converter 2 | 3 | id: mesa_AvgToMsg 4 | label: Average To Msg 5 | category: '[mesa]' 6 | 7 | parameters: 8 | - id: veclen 9 | label: Vector Length 10 | dtype: int 11 | default: '1024' 12 | hide: ${ 'part' if veclen == 1 else 'none' } 13 | - id: hold 14 | label: Lock 15 | dtype: bool 16 | default: 'False' 17 | 18 | inputs: 19 | - domain: stream 20 | dtype: float 21 | vlen: ${ veclen } 22 | 23 | outputs: 24 | - domain: message 25 | id: avg 26 | 27 | templates: 28 | imports: import mesa 29 | make: |- 30 | mesa.AvgToMsg(${veclen}) 31 | self.${id}.setHold(${hold}) 32 | callbacks: 33 | - setHold(${hold}) 34 | 35 | documentation: |- 36 | This block will output the single scalar float average of the input floats as a message. 37 | 38 | file_format: 1 39 | -------------------------------------------------------------------------------- /grc/mesa_LongTermIntegrator.block.yml: -------------------------------------------------------------------------------- 1 | # auto-generated by grc.converter 2 | 3 | id: mesa_LongTermIntegrator 4 | label: Long Term Integrator 5 | category: '[mesa]' 6 | 7 | parameters: 8 | - id: vlength 9 | label: Vector Length 10 | dtype: int 11 | default: '1' 12 | hide: ${ 'part' if vlength == 1 else 'none' } 13 | - id: normalize 14 | label: Normalize Output 15 | dtype: enum 16 | options: ['True', 'False'] 17 | option_labels: ['Yes', 'No'] 18 | - id: reset 19 | label: Reset 20 | dtype: bool 21 | default: 'False' 22 | 23 | inputs: 24 | - domain: stream 25 | dtype: float 26 | vlen: ${ vlength } 27 | 28 | outputs: 29 | - domain: stream 30 | dtype: float 31 | vlen: ${ vlength } 32 | - domain: message 33 | id: runtime 34 | optional: true 35 | 36 | templates: 37 | imports: import mesa 38 | make: mesa.LongTermIntegrator(${vlength},${normalize}) 39 | callbacks: 40 | - reset(${reset}) 41 | 42 | documentation: |- 43 | This block will take an input stream-to-vector (vlen/fftsize), and performs continuous vector aggregation. The block will output a message few seconds containing the runtime as a string. 44 | 45 | NOTE: A snapshot period of zero disables snapshots. 46 | 47 | file_format: 1 48 | -------------------------------------------------------------------------------- /grc/mesa_MaxPower.block.yml: -------------------------------------------------------------------------------- 1 | # auto-generated by grc.converter 2 | 3 | id: mesa_MaxPower 4 | label: Max Power 5 | category: '[mesa]' 6 | 7 | parameters: 8 | - id: sampleRate 9 | label: Sample Rate 10 | dtype: float 11 | default: samp_rate 12 | - id: fft_size 13 | label: FFT Size 14 | dtype: int 15 | default: '1024' 16 | - id: squelchThreshold 17 | label: Squelch Threshold 18 | dtype: float 19 | default: '-80.0' 20 | - id: framesToAvg 21 | label: Frames to Avg 22 | dtype: int 23 | default: '6' 24 | - id: stateThreshold 25 | label: State Notify Threshold 26 | dtype: float 27 | default: '-65.0' 28 | - id: holdUpSec 29 | label: Detect Hold Time (s) 30 | dtype: float 31 | default: '10.0' 32 | - id: produceOut 33 | label: Produce Out Msg 34 | dtype: enum 35 | options: ['False', 'True'] 36 | option_labels: ['No', 'Yes'] 37 | 38 | inputs: 39 | - domain: stream 40 | dtype: complex 41 | optional: true 42 | - domain: message 43 | id: msgin 44 | optional: true 45 | 46 | outputs: 47 | - domain: message 48 | id: out 49 | optional: true 50 | - domain: message 51 | id: maxpower 52 | optional: true 53 | - domain: message 54 | id: state 55 | optional: true 56 | 57 | templates: 58 | imports: import mesa 59 | make: mesa.MaxPower(${sampleRate}, ${fft_size}, ${squelchThreshold}, ${framesToAvg}, 60 | ${produceOut},${stateThreshold}, ${holdUpSec}) 61 | callbacks: 62 | - setSquelchThreshold(${squelchThreshold}) 63 | - setStateThreshold(${stateThreshold}) 64 | - setHoldTime(${holdUpSec}) 65 | 66 | documentation: |- 67 | This block monitors the input block for the maximum power seen. This is output in a "maxpower" meta tag in the maxpower connector, and also output on the out port along with the data block. For compatibility with the input selector block, a "decisionvalue" tag is also in the metadata that matches maxpower. 68 | 69 | The block can also be used to send a state (1/0) message if the detected power is above the specified notify threshold. 70 | 71 | NOTE: For performance purposes, if you don't need the full data stream, set 'Produce Out Msg' to No. 72 | 73 | file_format: 1 74 | -------------------------------------------------------------------------------- /grc/mesa_Normalize.block.yml: -------------------------------------------------------------------------------- 1 | # auto-generated by grc.converter 2 | 3 | id: mesa_Normalize 4 | label: Normalize 5 | category: '[mesa]' 6 | 7 | parameters: 8 | - id: vecsize 9 | label: Size 10 | dtype: int 11 | default: '1024' 12 | 13 | inputs: 14 | - domain: stream 15 | dtype: float 16 | vlen: ${ vecsize } 17 | 18 | outputs: 19 | - domain: stream 20 | dtype: float 21 | vlen: ${ vecsize } 22 | 23 | templates: 24 | imports: import mesa 25 | make: mesa.Normalize(${vecsize}) 26 | 27 | documentation: |- 28 | This block will take an input vector and normalize the results over the vector. (This block is an adaptation of the RA Vector Normalize block that had some hard-coded values preventing proper use) 29 | 30 | file_format: 1 31 | -------------------------------------------------------------------------------- /grc/mesa_SignalDetector.block.yml: -------------------------------------------------------------------------------- 1 | # auto-generated by grc.converter 2 | 3 | id: mesa_SignalDetector 4 | label: Signal Detector 5 | category: '[mesa]' 6 | 7 | parameters: 8 | - id: fft_size 9 | label: FFT Size 10 | dtype: int 11 | default: '1024' 12 | - id: squelchThreshold 13 | label: Sig Detect Threshold 14 | dtype: float 15 | default: '-80.0' 16 | - id: minWidthHz 17 | label: Min Signal Width (Hz) 18 | dtype: float 19 | default: '6000.0' 20 | - id: maxWidthHz 21 | label: Max Signal Width (Hz) 22 | dtype: float 23 | default: '60000.0' 24 | - id: radioCenterFreq 25 | label: Radio Frequency 26 | dtype: float 27 | default: freq 28 | - id: sampleRate 29 | label: Sample Rate 30 | dtype: float 31 | default: samp_rate 32 | - id: holdUpSec 33 | label: Hold Time (s) 34 | dtype: float 35 | default: '10.0' 36 | - id: framesToAvg 37 | label: Frames to Avg 38 | dtype: int 39 | default: '6' 40 | - id: detectionMethod 41 | label: Detection Method 42 | dtype: enum 43 | options: ['1', '2'] 44 | option_labels: [Separate Signals, Single Channelized (Boxing)] 45 | - id: genSignalPDUs 46 | label: Gen Signal PDUs 47 | dtype: enum 48 | options: ['False', 'True'] 49 | option_labels: ['Off', 'On'] 50 | - id: enableDebug 51 | label: Debug 52 | dtype: enum 53 | options: ['False', 'True'] 54 | option_labels: ['Off', 'On'] 55 | 56 | inputs: 57 | - domain: stream 58 | dtype: complex 59 | - domain: message 60 | id: msgin 61 | optional: true 62 | 63 | outputs: 64 | - label: signal 65 | domain: stream 66 | dtype: complex 67 | - domain: message 68 | id: signaldetect 69 | optional: true 70 | - domain: message 71 | id: state 72 | optional: true 73 | - domain: message 74 | id: signals 75 | optional: true 76 | 77 | templates: 78 | imports: import mesa 79 | make: "mesa.SignalDetector(${fft_size}, ${squelchThreshold}, ${minWidthHz}, ${maxWidthHz},\ 80 | \ ${radioCenterFreq}, ${sampleRate}, \n \t\t\t${holdUpSec}, ${framesToAvg},\ 81 | \ ${genSignalPDUs}, ${enableDebug},${detectionMethod})" 82 | callbacks: 83 | - setSquelch(${squelchThreshold}) 84 | - setMinWidthHz(${minWidthHz}) 85 | - setMaxWidthHz(${maxWidthHz}) 86 | - setCenterFrequency(${radioCenterFreq}) 87 | 88 | documentation: "This block scans the input signal looking for sub signals of the specified\ 89 | \ min/max width. The block takes a max-hold average to inspect the spectrum,\ 90 | \ then determines any signals present. Note that the FFT frames to average is\ 91 | \ configurable. Too small and the detection is jittery, too high and too many\ 92 | \ samples will be held/processed so pick a number that works well (or stick with\ 93 | \ the default).\n\nWhen a signal is detected, a PDU will be generated on the signaldetect\ 94 | \ connector with a 'state' metadata tag set to 1. PDU's are only sent on state\ 95 | \ changes, so any downstream blocks should track their own state. When no signals\ 96 | \ are present and the hold timer has expired, a PDU will be generated with 'state'\ 97 | \ set to 0.\n\nIf more data processing is desired, 'Gen Signal PDUs' can be turned\ 98 | \ on. In that case, for each detected signal, a PDU is generated along with some\ 99 | \ metadata (radio freq, sample rate, signal center freq, signal width, and signal\ 100 | \ max power) along with the full data block. This can be used downstream to tune\ 101 | \ filters and/or shift the signal. \n\nNOTES: \n\nUsing the standard 'out' source\ 102 | \ only produces a single pipeline, however: THE OUTPUT 'SIGNALS' MESSAGE SOURCE\ 103 | \ CONNECTOR SENDS A MESSAGE FOR EACH DETECTED SIGNAL IN A GIVEN INPUT BUFFER.\ 104 | \ This means that the out data will be sent along with the detected signal info\ 105 | \ for EACH detected signal in a given input buffer. If you write this to say\ 106 | \ a file sink or assume it's a single pipeline downstream, it's NOT!\n\nFor the signal detect threshold,\ 107 | \ pick a number that's above any noise floor to avoid false positives. The detector looks for the upward\ 108 | \ transition from this squelch threshold, therefore everything that's not a signal\ 109 | \ should be below this threshold, such that everything above it can be assumed\ 110 | \ to be a signal." 111 | 112 | file_format: 1 113 | -------------------------------------------------------------------------------- /grc/mesa_SourceSelector.block.yml: -------------------------------------------------------------------------------- 1 | # auto-generated by grc.converter 2 | 3 | id: mesa_SourceSelector 4 | label: Source Selector 5 | category: '[mesa]' 6 | 7 | parameters: 8 | - id: holdTime 9 | label: Input Hold Time (s) 10 | dtype: float 11 | default: '10.0' 12 | 13 | inputs: 14 | - domain: message 15 | id: in1 16 | - domain: message 17 | id: in2 18 | optional: true 19 | - domain: message 20 | id: in3 21 | optional: true 22 | - domain: message 23 | id: in4 24 | optional: true 25 | 26 | outputs: 27 | - domain: message 28 | id: inputport 29 | optional: true 30 | 31 | templates: 32 | imports: import mesa 33 | make: mesa.SourceSelector(${holdTime}, 4, 1,6144) 34 | 35 | documentation: |- 36 | This block monitors the message inputs for a meta tag "decisionvalue" associated with the input data. Whichever input has the maximum power is the one whose data is sent to the output. A hold-down timer is available to limit "bouncing". 37 | 38 | file_format: 1 39 | -------------------------------------------------------------------------------- /grc/mesa_VariableRotator.block.yml: -------------------------------------------------------------------------------- 1 | id: mesa_VariableRotator 2 | label: Variable Rotator 3 | category: '[mesa]' 4 | flags: [ show_id, python ] 5 | 6 | parameters: 7 | - id: valueList 8 | label: Value List 9 | dtype: float_vector 10 | default: 100.0e6,101.0e6,102.0e6 11 | - id: rotationTime 12 | label: Rotation Time (sec) 13 | dtype: float 14 | default: '2.0' 15 | value: ${ valueList[0] } 16 | 17 | inputs: 18 | - domain: message 19 | id: hold 20 | optional: true 21 | 22 | outputs: 23 | - domain: message 24 | id: value 25 | optional: true 26 | - domain: message 27 | id: index 28 | optional: true 29 | 30 | templates: 31 | imports: import mesa 32 | var_make: self.${id} = ${id} = ${valueList}[0] 33 | make: |- 34 | <% 35 | win = 'self._%s_var_rotator_win'%id 36 | %>\ 37 | ${win} = mesa.VariableRotator(${valueList}, ${rotationTime},self.set_${id},self) 38 | self.${id} = ${win} 39 | 40 | documentation: |- 41 | This block will change the value of the specified and output a value message at the specified interval unless a hold message is high (integer message set to 1). The index output corresponds to the index in the supplied list for the current value. This can be combined with other controls to take different processing paths depending on the value (e.g. a frequency scanner with different decoders) 42 | 43 | 44 | # 'file_format' specifies the version of the GRC yml format used in the file 45 | # and should usually not be changed. 46 | file_format: 1 47 | -------------------------------------------------------------------------------- /grc/mesa_ioselector.block.yml: -------------------------------------------------------------------------------- 1 | # auto-generated by grc.converter 2 | 3 | id: mesa_ioselector 4 | label: IO Selector 5 | category: '[mesa]' 6 | 7 | parameters: 8 | - id: type 9 | label: Type 10 | dtype: enum 11 | options: [complex, float, int, short, byte] 12 | option_attributes: 13 | size: [gr.sizeof_gr_complex, gr.sizeof_float, gr.sizeof_int, gr.sizeof_short, 14 | gr.sizeof_char] 15 | hide: part 16 | - id: num_inputs 17 | label: Num Inputs 18 | dtype: int 19 | default: '2' 20 | hide: part 21 | - id: num_outputs 22 | label: Num Outputs 23 | dtype: int 24 | default: '2' 25 | hide: part 26 | - id: input_index 27 | label: Input Index 28 | dtype: int 29 | default: '0' 30 | - id: output_index 31 | label: Output Index 32 | dtype: int 33 | default: '0' 34 | - id: vlen 35 | label: Vec Length 36 | dtype: int 37 | default: '1' 38 | hide: ${ 'part' if vlen == 1 else 'none' } 39 | 40 | inputs: 41 | - domain: stream 42 | dtype: ${ type } 43 | vlen: ${ vlen } 44 | multiplicity: ${ num_inputs } 45 | - domain: message 46 | id: inputindex 47 | optional: true 48 | - domain: message 49 | id: outputindex 50 | optional: true 51 | 52 | outputs: 53 | - domain: stream 54 | dtype: ${ type } 55 | vlen: ${ vlen } 56 | multiplicity: ${ num_outputs } 57 | asserts: 58 | - ${ num_inputs > 0 } 59 | - ${ num_outputs > 0 } 60 | - ${ vlen > 0 } 61 | 62 | templates: 63 | imports: import mesa 64 | make: mesa.ioselector(${num_inputs}, ${num_outputs}, ${input_index}, ${output_index}, 65 | ${type.size}*${vlen}) 66 | callbacks: 67 | - set_input_index(int(${input_index})) 68 | - set_output_index(int(${output_index})) 69 | 70 | documentation: |- 71 | Connect the sink at input index to the source at output index. Leave all other ports disconnected. 72 | 73 | file_format: 1 74 | -------------------------------------------------------------------------------- /grc/mesa_phase_shift.block.yml: -------------------------------------------------------------------------------- 1 | id: mesa_phase_shift 2 | label: Phase Shift 3 | category: '[mesa]' 4 | 5 | parameters: 6 | - id: shift_in_radians 7 | label: Phase Shift (rad) 8 | dtype: float 9 | default: '0.0' 10 | 11 | inputs: 12 | - domain: stream 13 | dtype: complex 14 | - domain: message 15 | id: shift_rad 16 | optional: true 17 | 18 | outputs: 19 | - domain: stream 20 | dtype: complex 21 | 22 | templates: 23 | imports: import mesa 24 | make: mesa.phase_shift(${shift_in_radians}) 25 | callbacks: 26 | - set_shift(${shift_in_radians}) 27 | 28 | documentation: |- 29 | This block will phase shift the input signal by the specified number of radians by multiplying the input times a shift value: gr_complex(cos(d_shift_in_radians),sin(d_shift_in_radians)) 30 | 31 | file_format: 1 32 | -------------------------------------------------------------------------------- /include/mesa/AutoDopplerCorrect.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2019 ghostop14. 4 | * 5 | * This 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 | * This software 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 this software; 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 | #ifndef INCLUDED_MESA_AUTODOPPLERCORRECT_H 22 | #define INCLUDED_MESA_AUTODOPPLERCORRECT_H 23 | 24 | #include 25 | #include 26 | 27 | namespace gr { 28 | namespace mesa { 29 | 30 | /*! 31 | * \brief <+description of block+> 32 | * \ingroup mesa 33 | * 34 | */ 35 | class MESA_API AutoDopplerCorrect : virtual public gr::sync_block { 36 | public: 37 | typedef std::shared_ptr sptr; 38 | 39 | /*! 40 | * \brief Return a shared_ptr to a new instance of mesa::AutoDopplerCorrect. 41 | * 42 | * To avoid accidental use of raw pointers, mesa::AutoDopplerCorrect's 43 | * constructor is in a private implementation 44 | * class. mesa::AutoDopplerCorrect::make is the public interface for 45 | * creating new instances. 46 | */ 47 | static sptr make(double freq, double sampleRate, double maxDrift, 48 | double minWidth, double expectedWidth, int shiftHolddownMS, 49 | int fft_size, float squelchThreshold, int framesToAvg, 50 | float holdUpSec, bool processMessages, int detectionMethod); 51 | 52 | virtual float getSquelch() const = 0; 53 | virtual void setSquelch(float newValue) = 0; 54 | 55 | virtual double getCenterFrequency() const = 0; 56 | virtual void setCenterFrequency(double newValue) = 0; 57 | 58 | virtual double getMinWidthHz() const = 0; 59 | virtual void setMinWidthHz(double newValue) = 0; 60 | 61 | virtual double getExpectedWidth() const = 0; 62 | virtual void setExpectedWidth(double newValue) = 0; 63 | 64 | virtual double getMaxDrift() const = 0; 65 | virtual void setMaxDrift(double newValue) = 0; 66 | }; 67 | 68 | } // namespace mesa 69 | } // namespace gr 70 | 71 | #endif /* INCLUDED_MESA_AUTODOPPLERCORRECT_H */ 72 | -------------------------------------------------------------------------------- /include/mesa/AvgToMsg.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2019 ghostop14. 4 | * 5 | * This 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 | * This software 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 this software; 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 | #ifndef INCLUDED_MESA_AVGTOMSG_H 22 | #define INCLUDED_MESA_AVGTOMSG_H 23 | 24 | #include 25 | #include 26 | 27 | namespace gr { 28 | namespace mesa { 29 | 30 | /*! 31 | * \brief <+description of block+> 32 | * \ingroup mesa 33 | * 34 | */ 35 | class MESA_API AvgToMsg : virtual public gr::sync_block { 36 | public: 37 | typedef std::shared_ptr sptr; 38 | 39 | /*! 40 | * \brief Return a shared_ptr to a new instance of mesa::AvgToMsg. 41 | * 42 | * To avoid accidental use of raw pointers, mesa::AvgToMsg's 43 | * constructor is in a private implementation 44 | * class. mesa::AvgToMsg::make is the public interface for 45 | * creating new instances. 46 | */ 47 | static sptr make(int veclen); 48 | 49 | virtual void setHold(bool newValue) = 0; 50 | }; 51 | 52 | } // namespace mesa 53 | } // namespace gr 54 | 55 | #endif /* INCLUDED_MESA_AVGTOMSG_H */ 56 | -------------------------------------------------------------------------------- /include/mesa/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011,2012 Free Software Foundation, Inc. 2 | # 3 | # This file was generated by gr_modtool, a tool from the GNU Radio framework 4 | # This file is a part of gr-mesa 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 | # Install public header files 23 | ######################################################################## 24 | install(FILES 25 | api.h 26 | SignalDetector.h 27 | AutoDopplerCorrect.h 28 | MaxPower.h 29 | SourceSelector.h 30 | LongTermIntegrator.h 31 | ioselector.h 32 | phase_shift.h 33 | AvgToMsg.h 34 | DESTINATION include/mesa 35 | ) 36 | -------------------------------------------------------------------------------- /include/mesa/LongTermIntegrator.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2019 ghostop14. 4 | * 5 | * This 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 | * This software 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 this software; 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 | #ifndef INCLUDED_MESA_LONGTERMINTEGRATOR_H 22 | #define INCLUDED_MESA_LONGTERMINTEGRATOR_H 23 | 24 | #include 25 | #include 26 | 27 | namespace gr { 28 | namespace mesa { 29 | 30 | /*! 31 | * \brief <+description of block+> 32 | * \ingroup mesa 33 | * 34 | */ 35 | class MESA_API LongTermIntegrator : virtual public gr::sync_block { 36 | public: 37 | typedef std::shared_ptr sptr; 38 | 39 | /*! 40 | * \brief Return a shared_ptr to a new instance of mesa::LongTermIntegrator. 41 | * 42 | * To avoid accidental use of raw pointers, mesa::LongTermIntegrator's 43 | * constructor is in a private implementation 44 | * class. mesa::LongTermIntegrator::make is the public interface for 45 | * creating new instances. 46 | */ 47 | static sptr make(int fftsize, bool normalize); 48 | virtual void reset(bool bReset) = 0; 49 | }; 50 | 51 | } // namespace mesa 52 | } // namespace gr 53 | 54 | #endif /* INCLUDED_MESA_LONGTERMINTEGRATOR_H */ 55 | -------------------------------------------------------------------------------- /include/mesa/MaxPower.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2019 ghostop14. 4 | * 5 | * This 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 | * This software 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 this software; 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 | #ifndef INCLUDED_MESA_MAXPOWER_H 22 | #define INCLUDED_MESA_MAXPOWER_H 23 | 24 | #include 25 | #include 26 | 27 | namespace gr { 28 | namespace mesa { 29 | 30 | /*! 31 | * \brief <+description of block+> 32 | * \ingroup mesa 33 | * 34 | */ 35 | class MESA_API MaxPower : virtual public gr::sync_block { 36 | public: 37 | typedef std::shared_ptr sptr; 38 | 39 | /*! 40 | * \brief Return a shared_ptr to a new instance of mesa::MaxPower. 41 | * 42 | * To avoid accidental use of raw pointers, mesa::MaxPower's 43 | * constructor is in a private implementation 44 | * class. mesa::MaxPower::make is the public interface for 45 | * creating new instances. 46 | */ 47 | static sptr make(double sampleRate, int fft_size, float squelchThreshold, 48 | float framesToAvg, bool produceOut, float stateThreshold, 49 | float holdUpSec); 50 | 51 | virtual float getSquelchThreshold() const = 0; 52 | virtual void setSquelchThreshold(float newValue) = 0; 53 | virtual float getStateThreshold() const = 0; 54 | virtual void setStateThreshold(float newValue) = 0; 55 | virtual float getHoldTime() const = 0; 56 | virtual void setHoldTime(float newValue) = 0; 57 | }; 58 | 59 | } // namespace mesa 60 | } // namespace gr 61 | 62 | #endif /* INCLUDED_MESA_MAXPOWER_H */ 63 | -------------------------------------------------------------------------------- /include/mesa/SignalDetector.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2019 ghostop14. 4 | * 5 | * This 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 | * This software 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 this software; 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 | #ifndef INCLUDED_MESA_SIGNALDETECTOR_H 22 | #define INCLUDED_MESA_SIGNALDETECTOR_H 23 | 24 | #include 25 | #include 26 | 27 | namespace gr { 28 | namespace mesa { 29 | 30 | /*! 31 | * \brief <+description of block+> 32 | * \ingroup mesa 33 | * 34 | */ 35 | class MESA_API SignalDetector : virtual public gr::sync_block { 36 | public: 37 | typedef std::shared_ptr sptr; 38 | 39 | /*! 40 | * \brief Return a shared_ptr to a new instance of mesa::SignalDetector. 41 | * 42 | * To avoid accidental use of raw pointers, mesa::SignalDetector's 43 | * constructor is in a private implementation 44 | * class. mesa::SignalDetector::make is the public interface for 45 | * creating new instances. 46 | */ 47 | static sptr make(int fftsize, float squelchThreshold, double minWidthHz, 48 | double maxWidthHz, double radioCenterFreq, double sampleRate, 49 | float holdUpSec, int framesToAvg, bool genSignalPDUs, 50 | bool enableDebug, int detectionMethod); 51 | 52 | virtual float getSquelch() const = 0; 53 | virtual void setSquelch(float newValue) = 0; 54 | 55 | virtual double getCenterFrequency() const = 0; 56 | virtual void setCenterFrequency(double newValue) = 0; 57 | 58 | virtual double getMinWidthHz() const = 0; 59 | virtual void setMinWidthHz(double newValue) = 0; 60 | 61 | virtual double getMaxWidthHz() const = 0; 62 | virtual void setMaxWidthHz(double newValue) = 0; 63 | }; 64 | 65 | } // namespace mesa 66 | } // namespace gr 67 | 68 | #endif /* INCLUDED_MESA_SIGNALDETECTOR_H */ 69 | -------------------------------------------------------------------------------- /include/mesa/SourceSelector.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2019 ghostop14. 4 | * 5 | * This 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 | * This software 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 this software; 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 | #ifndef INCLUDED_MESA_SOURCESELECTOR_H 22 | #define INCLUDED_MESA_SOURCESELECTOR_H 23 | 24 | #include 25 | #include 26 | 27 | namespace gr { 28 | namespace mesa { 29 | 30 | /*! 31 | * \brief <+description of block+> 32 | * \ingroup mesa 33 | * 34 | */ 35 | class MESA_API SourceSelector : virtual public gr::sync_block { 36 | public: 37 | typedef std::shared_ptr sptr; 38 | 39 | /*! 40 | * \brief Return a shared_ptr to a new instance of mesa::SourceSelector. 41 | * 42 | * To avoid accidental use of raw pointers, mesa::SourceSelector's 43 | * constructor is in a private implementation 44 | * class. mesa::SourceSelector::make is the public interface for 45 | * creating new instances. 46 | */ 47 | static sptr make(float holdTime, int numInputs, int defaultInput, 48 | int inputBlockSize); 49 | }; 50 | 51 | } // namespace mesa 52 | } // namespace gr 53 | 54 | #endif /* INCLUDED_MESA_SOURCESELECTOR_H */ 55 | -------------------------------------------------------------------------------- /include/mesa/api.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Free Software Foundation, Inc. 3 | * 4 | * This file was generated by gr_modtool, a tool from the GNU Radio framework 5 | * This file is a part of gr-mesa 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 | #ifndef INCLUDED_MESA_API_H 24 | #define INCLUDED_MESA_API_H 25 | 26 | #include 27 | 28 | #ifdef gnuradio_mesa_EXPORTS 29 | #define MESA_API __GR_ATTR_EXPORT 30 | #else 31 | #define MESA_API __GR_ATTR_IMPORT 32 | #endif 33 | 34 | #endif /* INCLUDED_MESA_API_H */ 35 | -------------------------------------------------------------------------------- /include/mesa/ioselector.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2019 ghostop14. 4 | * 5 | * This 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 | * This software 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 this software; 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 | #ifndef INCLUDED_MESA_IOSELECTOR_H 22 | #define INCLUDED_MESA_IOSELECTOR_H 23 | 24 | #include 25 | #include 26 | 27 | namespace gr { 28 | namespace mesa { 29 | 30 | /*! 31 | * \brief <+description of block+> 32 | * \ingroup mesa 33 | * 34 | */ 35 | class MESA_API ioselector : virtual public gr::sync_block { 36 | public: 37 | typedef std::shared_ptr sptr; 38 | 39 | /*! 40 | * \brief Return a shared_ptr to a new instance of mesa::ioselector. 41 | * 42 | * To avoid accidental use of raw pointers, mesa::ioselector's 43 | * constructor is in a private implementation 44 | * class. mesa::ioselector::make is the public interface for 45 | * creating new instances. 46 | */ 47 | static sptr make(int numinputs, int numoutputs, int inputport, int outputport, 48 | int itemsize); 49 | 50 | virtual void set_input_index(int newValue) = 0; 51 | virtual void set_output_index(int newValue) = 0; 52 | }; 53 | 54 | } // namespace mesa 55 | } // namespace gr 56 | 57 | #endif /* INCLUDED_MESA_IOSELECTOR_H */ 58 | -------------------------------------------------------------------------------- /include/mesa/phase_shift.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2019 ghostop14. 4 | * 5 | * This 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 | * This software 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 this software; 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 | #ifndef INCLUDED_MESA_PHASESHIFT_H 22 | #define INCLUDED_MESA_PHASESHIFT_H 23 | 24 | #include 25 | #include 26 | 27 | namespace gr { 28 | namespace mesa { 29 | 30 | /*! 31 | * \brief This block will shift the incoming signal by the specified radians. 32 | * \ingroup mesa 33 | * 34 | */ 35 | class MESA_API phase_shift : virtual public gr::sync_block { 36 | public: 37 | typedef std::shared_ptr sptr; 38 | 39 | /*! 40 | * \brief Return a shared_ptr to a new instance of mesa::phase_shift. 41 | * 42 | * To avoid accidental use of raw pointers, mesa::phase_shift's 43 | * constructor is in a private implementation 44 | * class. mesa::phase_shift::make is the public interface for 45 | * creating new instances. 46 | */ 47 | static sptr make(float shift_in_radians); 48 | virtual float get_shift() const = 0; 49 | virtual void set_shift(float newValue) = 0; 50 | }; 51 | 52 | } // namespace mesa 53 | } // namespace gr 54 | 55 | #endif /* INCLUDED_MESA_PHASESHIFT_H */ 56 | -------------------------------------------------------------------------------- /lib/AutoDopplerCorrect_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2019 ghostop14. 4 | * 5 | * This 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 | * This software 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 this software; 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 | #ifndef INCLUDED_MESA_AUTODOPPLERCORRECT_IMPL_H 22 | #define INCLUDED_MESA_AUTODOPPLERCORRECT_IMPL_H 23 | 24 | #include "signals_mesa.h" 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | using namespace MesaSignals; 31 | 32 | #define AUTODOPPLER_METHOD_CLOSESTSIGNAL 1 33 | #define AUTODOPPLER_METHOD_BOXOUTSIDEIN 2 34 | 35 | namespace gr { 36 | namespace mesa { 37 | 38 | class AutoDopplerCorrect_impl : public AutoDopplerCorrect { 39 | protected: 40 | boost::mutex d_mutex; 41 | 42 | EnergyAnalyzer *pEnergyAnalyzer; 43 | int d_detectionMethod; 44 | 45 | gr::fxpt_nco d_nco; 46 | 47 | gr_complex *pMsgOutBuff; 48 | int msgBufferSize; 49 | 50 | double d_sampleRate; 51 | double d_centerFreq; 52 | double d_maxDrift; 53 | double d_expectedWidth; 54 | int d_shiftHolddownMS; 55 | bool d_processMessages; 56 | 57 | int d_framesToAvg; 58 | int d_fftSize; 59 | double d_minWidthHz; 60 | double d_maxWidthHz; 61 | bool d_startInitialized; 62 | float d_holdUpSec; 63 | 64 | double d_currentFreqShiftDelta; 65 | 66 | std::chrono::time_point lastSeen, lastShifted; 67 | 68 | virtual void sendMessageData(gr_complex *data, long datasize, 69 | double signalCenterFreq, double signalWidth, 70 | float maxPower, pmt::pmt_t *pMetadata); 71 | void sendState(bool state); 72 | 73 | public: 74 | AutoDopplerCorrect_impl(double freq, double sampleRate, double maxDrift, 75 | double minWidth, double expectedWidth, 76 | int shiftHolddownMS, int fft_size, 77 | float squelchThreshold, int framesToAvg, 78 | float holdUpSec, bool processMessages, 79 | int detectionMethod); 80 | ~AutoDopplerCorrect_impl(); 81 | 82 | virtual bool stop(); 83 | 84 | // Needed to be public for debug testing 85 | virtual int processData(int noutput_items, const gr_complex *in, 86 | gr_complex *out, pmt::pmt_t *pMetadata, 87 | bool testMode = false); 88 | 89 | void handleMsgIn(pmt::pmt_t msg); 90 | 91 | // Where all the action really happens 92 | int work(int noutput_items, gr_vector_const_void_star &input_items, 93 | gr_vector_void_star &output_items); 94 | 95 | virtual float getSquelch() const; 96 | virtual void setSquelch(float newValue); 97 | 98 | virtual double getCenterFrequency() const; 99 | virtual void setCenterFrequency(double newValue); 100 | 101 | virtual double getMinWidthHz() const; 102 | virtual void setMinWidthHz(double newValue); 103 | 104 | virtual double getExpectedWidth() const; 105 | virtual void setExpectedWidth(double newValue); 106 | 107 | virtual double getMaxDrift() const; 108 | virtual void setMaxDrift(double newValue); 109 | }; 110 | 111 | } // namespace mesa 112 | } // namespace gr 113 | 114 | #endif /* INCLUDED_MESA_AUTODOPPLERCORRECT_IMPL_H */ 115 | -------------------------------------------------------------------------------- /lib/AvgToMsg_impl.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2019 ghostop14. 4 | * 5 | * This 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 | * This software 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 this software; 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 | #include "AvgToMsg_impl.h" 22 | #include 23 | 24 | #include 25 | 26 | namespace gr { 27 | namespace mesa { 28 | 29 | AvgToMsg::sptr AvgToMsg::make(int veclen) { 30 | return gnuradio::make_block_sptr(veclen); 31 | } 32 | 33 | /* 34 | * The private constructor 35 | */ 36 | AvgToMsg_impl::AvgToMsg_impl(int veclen) 37 | : gr::sync_block("AvgToMsg", 38 | gr::io_signature::make(1, 1, sizeof(float) * veclen), 39 | gr::io_signature::make(0, 0, 0)) { 40 | d_veclen = veclen; 41 | b_hold = false; 42 | b_useStdDev = true; 43 | 44 | message_port_register_out(pmt::mp("avg")); 45 | } 46 | 47 | /* 48 | * Our virtual destructor. 49 | */ 50 | AvgToMsg_impl::~AvgToMsg_impl() {} 51 | 52 | int AvgToMsg_impl::work(int noutput_items, 53 | gr_vector_const_void_star &input_items, 54 | gr_vector_void_star &output_items) { 55 | const float *in = (const float *)input_items[0]; 56 | 57 | float sum = 0.0; 58 | int vecstart; 59 | long nitems = d_veclen * noutput_items; 60 | 61 | volk_32f_accumulator_s32f(&sum, in, nitems); 62 | 63 | float avg = sum / (d_veclen * noutput_items); 64 | 65 | /* 66 | if (b_useStdDev) { 67 | // include in result only if value is within 2 std_dev (98% of all samples 68 | should fall here) float standardDeviation = 0.0; for(long i = 0; i < nitems; 69 | ++i) { standardDeviation += pow(in[i] - avg, 2); 70 | } 71 | standardDeviation = sqrt(standardDeviation / (float)nitems); 72 | 73 | float TwoStdDev = 2.0*standardDeviation; 74 | 75 | long itemsUsed = 0; 76 | float newSum = 0.0; 77 | 78 | for(long i = 0; i < nitems; ++i) { 79 | if (fabs(in[i] - avg) <= TwoStdDev) { 80 | itemsUsed++; 81 | newSum += in[i]; 82 | } 83 | } 84 | 85 | if (itemsUsed > 0) { 86 | avg = newSum / (float)itemsUsed; 87 | } 88 | 89 | } 90 | */ 91 | 92 | if (!b_hold) 93 | message_port_pub(pmt::mp("avg"), pmt::from_float(avg)); 94 | 95 | // Tell runtime system how many output items we produced. 96 | return noutput_items; 97 | } 98 | 99 | void AvgToMsg_impl::setHold(bool newValue) { b_hold = newValue; } 100 | 101 | void AvgToMsg_impl::setup_rpc() { 102 | #ifdef GR_CTRLPORT 103 | // Setters 104 | add_rpc_variable(rpcbasic_sptr(new rpcbasic_register_set( 105 | alias(), "hold", &AvgToMsg_impl::setHold, pmt::mp(false), pmt::mp(true), 106 | pmt::mp(false), "bool", "hold", RPC_PRIVLVL_MIN, 107 | DISPTIME | DISPOPTSTRIP))); 108 | 109 | #endif /* GR_CTRLPORT */ 110 | } 111 | } /* namespace mesa */ 112 | } /* namespace gr */ 113 | -------------------------------------------------------------------------------- /lib/AvgToMsg_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2019 ghostop14. 4 | * 5 | * This 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 | * This software 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 this software; 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 | #ifndef INCLUDED_MESA_AVGTOMSG_IMPL_H 22 | #define INCLUDED_MESA_AVGTOMSG_IMPL_H 23 | 24 | #include 25 | 26 | namespace gr { 27 | namespace mesa { 28 | 29 | class AvgToMsg_impl : public AvgToMsg { 30 | private: 31 | int d_veclen; 32 | bool b_hold; 33 | bool b_useStdDev; 34 | 35 | public: 36 | AvgToMsg_impl(int veclen); 37 | ~AvgToMsg_impl(); 38 | 39 | void setup_rpc(); 40 | 41 | virtual void setHold(bool newValue); 42 | 43 | // Where all the action really happens 44 | int work(int noutput_items, gr_vector_const_void_star &input_items, 45 | gr_vector_void_star &output_items); 46 | }; 47 | 48 | } // namespace mesa 49 | } // namespace gr 50 | 51 | #endif /* INCLUDED_MESA_AVGTOMSG_IMPL_H */ 52 | -------------------------------------------------------------------------------- /lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011,2012,2016,2018,2019 Free Software Foundation, Inc. 2 | # 3 | # This file was generated by gr_modtool, a tool from the GNU Radio framework 4 | # This file is a part of gr-mesa 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 | find_package(FFTW3f) 22 | 23 | ######################################################################## 24 | # Setup library 25 | ######################################################################## 26 | include(GrPlatform) #define LIB_SUFFIX 27 | 28 | list(APPEND mesa_sources 29 | signals_mesa.cc 30 | SignalDetector_impl.cc 31 | AutoDopplerCorrect_impl.cc 32 | MaxPower_impl.cc 33 | SourceSelector_impl.cc 34 | LongTermIntegrator_impl.cc 35 | ioselector_impl.cc 36 | phase_shift_impl.cc 37 | AvgToMsg_impl.cc ) 38 | 39 | set(mesa_sources "${mesa_sources}" PARENT_SCOPE) 40 | if(NOT mesa_sources) 41 | MESSAGE(STATUS "No C++ sources... skipping lib/") 42 | return() 43 | endif(NOT mesa_sources) 44 | 45 | add_library(gnuradio-mesa SHARED ${mesa_sources}) 46 | target_link_libraries(gnuradio-mesa gnuradio::gnuradio-runtime) 47 | target_link_libraries(gnuradio-mesa ${Boost_LIBRARIES} gnuradio-fft 48 | volk 49 | fftw3f 50 | fftw3f_threads 51 | gnuradio-lfast 52 | ) 53 | target_include_directories(gnuradio-mesa 54 | PUBLIC $ 55 | PUBLIC $ 56 | ) 57 | set_target_properties(gnuradio-mesa PROPERTIES DEFINE_SYMBOL "gnuradio_mesa_EXPORTS") 58 | 59 | if(APPLE) 60 | set_target_properties(gnuradio-mesa PROPERTIES 61 | INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib" 62 | ) 63 | endif(APPLE) 64 | 65 | ######################################################################## 66 | # Install built library files 67 | ######################################################################## 68 | include(GrMiscUtils) 69 | GR_LIBRARY_FOO(gnuradio-mesa) 70 | 71 | ######################################################################## 72 | # Print summary 73 | ######################################################################## 74 | message(STATUS "Using install prefix: ${CMAKE_INSTALL_PREFIX}") 75 | message(STATUS "Building for version: ${VERSION} / ${LIBVER}") 76 | 77 | ######################################################################## 78 | # Build and register unit test 79 | ######################################################################## 80 | include(GrTest) 81 | 82 | # If your unit tests require special include paths, add them here 83 | #include_directories() 84 | # List all files that contain Boost.UTF unit tests here 85 | list(APPEND test_mesa_sources 86 | ) 87 | # Anything we need to link to for the unit tests go here 88 | list(APPEND GR_TEST_TARGET_DEPS gnuradio-mesa) 89 | 90 | if(NOT test_mesa_sources) 91 | MESSAGE(STATUS "No C++ unit tests... skipping") 92 | return() 93 | endif(NOT test_mesa_sources) 94 | 95 | foreach(qa_file ${test_mesa_sources}) 96 | GR_ADD_CPP_TEST("mesa_${qa_file}" 97 | ${CMAKE_CURRENT_SOURCE_DIR}/${qa_file} 98 | ) 99 | endforeach(qa_file) 100 | -------------------------------------------------------------------------------- /lib/LongTermIntegrator_impl.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2019 ghostop14. 4 | * 5 | * This 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 | * This software 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 this software; 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 | #include "LongTermIntegrator_impl.h" 22 | #include 23 | #include 24 | #include 25 | namespace gr { 26 | namespace mesa { 27 | 28 | LongTermIntegrator::sptr LongTermIntegrator::make(int fftsize, bool normalize) 29 | { 30 | return gnuradio::make_block_sptr(fftsize, normalize); 31 | } 32 | 33 | /* 34 | * The private constructor 35 | */ 36 | LongTermIntegrator_impl::LongTermIntegrator_impl(int fftsize, bool normalize) 37 | : gr::sync_block("LongTermIntegrator", 38 | gr::io_signature::make(1, 1, sizeof(float) * fftsize), 39 | gr::io_signature::make(1, 1, sizeof(float) * fftsize)) { 40 | d_fftsize = fftsize; 41 | d_normalize = normalize; 42 | 43 | size_t memAlignment = volk_get_alignment(); 44 | aggBuffer = (double *)volk_malloc(fftsize * sizeof(double), memAlignment); 45 | for (int i = 0; i < d_fftsize; i++) 46 | aggBuffer[i] = 0.0; 47 | 48 | startTime = std::chrono::steady_clock::now(); 49 | 50 | threadRunning = false; 51 | stopThread = false; 52 | readThread = 53 | new boost::thread(boost::bind(&LongTermIntegrator_impl::runThread, this)); 54 | 55 | message_port_register_out(pmt::mp("runtime")); 56 | } 57 | 58 | void LongTermIntegrator_impl::runThread() { 59 | threadRunning = true; 60 | int loopCount = 0; 61 | int maxLoop = 5 / 0.01; // 5 seconds 62 | 63 | usleep(10000); // let primary thread start. 64 | startTime = std::chrono::steady_clock::now(); 65 | 66 | while (!stopThread) { 67 | std::chrono::time_point curTimestamp = 68 | std::chrono::steady_clock::now(); 69 | std::chrono::duration elapsed_seconds; 70 | 71 | elapsed_seconds = curTimestamp - startTime; 72 | 73 | float sec = elapsed_seconds.count(); 74 | stringstream stream; 75 | string timeStr; 76 | if (sec < 60.0) { 77 | stream << std::fixed << std::setprecision(2) << sec; 78 | timeStr = stream.str() + " seconds"; 79 | } else { 80 | stream << std::fixed << std::setprecision(2) << (sec / 60.0); 81 | timeStr = stream.str() + " minutes"; 82 | } 83 | 84 | // std::cout << "Sending " << timeStr << std::endl; 85 | 86 | message_port_pub(pmt::mp("runtime"), pmt::intern(timeStr)); 87 | 88 | loopCount = 0; 89 | 90 | while (!stopThread && loopCount < maxLoop) { 91 | // check increment 92 | usleep(10000); // sleep 10 millisec 93 | loopCount++; 94 | } 95 | } 96 | 97 | threadRunning = false; 98 | } 99 | 100 | void LongTermIntegrator_impl::reset(bool bReset) { 101 | if (bReset) { 102 | gr::thread::scoped_lock guard(d_mutex); 103 | 104 | // Zero out all aggregation buckets 105 | for (int i = 0; i < d_fftsize; i++) 106 | aggBuffer[i] = 0.0; 107 | 108 | // Reset integration time 109 | startTime = std::chrono::steady_clock::now(); 110 | } 111 | } 112 | 113 | bool LongTermIntegrator_impl::stop() { 114 | if (readThread) { 115 | stopThread = true; 116 | 117 | while (threadRunning) { 118 | usleep(10000); // sleep 10 millisec 119 | } 120 | 121 | delete readThread; 122 | readThread = NULL; 123 | } 124 | 125 | if (aggBuffer) { 126 | volk_free(aggBuffer); 127 | aggBuffer = NULL; 128 | } 129 | 130 | return true; 131 | } 132 | 133 | /* 134 | * Our virtual destructor. 135 | */ 136 | LongTermIntegrator_impl::~LongTermIntegrator_impl() { bool retval = stop(); } 137 | 138 | int LongTermIntegrator_impl::work(int noutput_items, 139 | gr_vector_const_void_star &input_items, 140 | gr_vector_void_star &output_items) { 141 | const float *in = (const float *)input_items[0]; 142 | float *out = (float *)output_items[0]; 143 | int noi = noutput_items * d_fftsize; 144 | uint32_t maxIndex; 145 | 146 | gr::thread::scoped_lock guard(d_mutex); 147 | 148 | // Vectors have to be done individually to map into aggBuffer; 149 | for (int curVector = 0; curVector < noutput_items; curVector++) { 150 | // Switched to double precision to avoid accumulation errors with floats. 151 | for (int i=0;i max) { 168 | max = aggBuffer[i]; 169 | } 170 | } 171 | 172 | // Can use volk here since out is float 173 | if (max != 0.0) 174 | volk_32f_s32f_multiply_32f(&out[curVector*d_fftsize], &out[curVector*d_fftsize], 100.0 / max, d_fftsize); 175 | } 176 | } 177 | 178 | // Tell runtime system how many output items we produced. 179 | return noutput_items; 180 | } 181 | 182 | void LongTermIntegrator_impl::setup_rpc() { 183 | #ifdef GR_CTRLPORT 184 | // Setters 185 | add_rpc_variable( 186 | rpcbasic_sptr(new rpcbasic_register_set( 187 | alias(), "reset", &LongTermIntegrator_impl::reset, pmt::mp(false), 188 | pmt::mp(true), pmt::mp(false), "bool", "reset", RPC_PRIVLVL_MIN, 189 | DISPTIME | DISPOPTSTRIP))); 190 | 191 | #endif /* GR_CTRLPORT */ 192 | } 193 | } /* namespace mesa */ 194 | } /* namespace gr */ 195 | -------------------------------------------------------------------------------- /lib/LongTermIntegrator_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2019 ghostop14. 4 | * 5 | * This 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 | * This software 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 this software; 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 | #ifndef INCLUDED_MESA_LONGTERMINTEGRATOR_IMPL_H 22 | #define INCLUDED_MESA_LONGTERMINTEGRATOR_IMPL_H 23 | 24 | #include "signals_mesa.h" 25 | #include 26 | 27 | using namespace std; 28 | using namespace MesaSignals; 29 | #include 30 | #include 31 | #include 32 | 33 | namespace gr { 34 | namespace mesa { 35 | 36 | class LongTermIntegrator_impl : public LongTermIntegrator { 37 | private: 38 | int d_fftsize; 39 | bool d_normalize; 40 | double *aggBuffer; 41 | boost::mutex d_mutex; 42 | 43 | std::chrono::time_point startTime; 44 | 45 | boost::thread *readThread = NULL; 46 | bool threadRunning; 47 | bool stopThread; 48 | 49 | void runThread(); 50 | 51 | public: 52 | LongTermIntegrator_impl(int fftsize, bool normalize); 53 | ~LongTermIntegrator_impl(); 54 | 55 | virtual void reset(bool bReset); 56 | void setup_rpc(); 57 | 58 | bool stop(); 59 | 60 | // Where all the action really happens 61 | int work(int noutput_items, gr_vector_const_void_star &input_items, 62 | gr_vector_void_star &output_items); 63 | }; 64 | 65 | } // namespace mesa 66 | } // namespace gr 67 | 68 | #endif /* INCLUDED_MESA_LONGTERMINTEGRATOR_IMPL_H */ 69 | -------------------------------------------------------------------------------- /lib/MaxPower_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2019 ghostop14. 4 | * 5 | * This 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 | * This software 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 this software; 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 | #ifndef INCLUDED_MESA_MAXPOWER_IMPL_H 22 | #define INCLUDED_MESA_MAXPOWER_IMPL_H 23 | 24 | #include "signals_mesa.h" 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | using namespace MesaSignals; 31 | 32 | namespace gr { 33 | namespace mesa { 34 | 35 | class MaxPower_impl : public MaxPower { 36 | private: 37 | // Nothing to declare in this block. 38 | boost::mutex d_mutex; 39 | EnergyAnalyzer *pEnergyAnalyzer; 40 | double d_sampleRate; 41 | int d_framesToAvg; 42 | float d_squelchThreshold; 43 | 44 | int d_fftSize; 45 | 46 | bool d_produceOut; 47 | 48 | int iBufferCapacity; 49 | 50 | boost::circular_buffer *maxBuffer; 51 | 52 | bool d_startInitialized; 53 | float d_holdUpSec; 54 | bool curState; 55 | float d_stateThreshold; 56 | std::chrono::time_point holdTime; 57 | 58 | virtual void handleMsgIn(pmt::pmt_t msg); 59 | 60 | virtual int processData(int noutput_items, const gr_complex *in); 61 | virtual void sendState(bool state); 62 | 63 | virtual float calcAverage(); 64 | 65 | public: 66 | MaxPower_impl(double sampleRate, int fft_size, float squelchThreshold, 67 | float framesToAvg, bool produceOut, float stateThreshold, 68 | float holdUpSec); 69 | ~MaxPower_impl(); 70 | 71 | void setup_rpc(); 72 | virtual float getSquelchThreshold() const; 73 | virtual void setSquelchThreshold(float newValue); 74 | virtual float getStateThreshold() const; 75 | virtual void setStateThreshold(float newValue); 76 | virtual float getHoldTime() const; 77 | virtual void setHoldTime(float newValue); 78 | 79 | virtual bool stop(); 80 | 81 | // Where all the action really happens 82 | int work(int noutput_items, gr_vector_const_void_star &input_items, 83 | gr_vector_void_star &output_items); 84 | }; 85 | 86 | } // namespace mesa 87 | } // namespace gr 88 | 89 | #endif /* INCLUDED_MESA_MAXPOWER_IMPL_H */ 90 | -------------------------------------------------------------------------------- /lib/SignalDetector_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2019 ghostop14. 4 | * 5 | * This 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 | * This software 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 this software; 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 | #ifndef INCLUDED_MESA_SIGNALDETECTOR_IMPL_H 22 | #define INCLUDED_MESA_SIGNALDETECTOR_IMPL_H 23 | 24 | #include "signals_mesa.h" 25 | #include 26 | #include 27 | #include 28 | 29 | using namespace MesaSignals; 30 | 31 | #define SIGDETECTOR_METHOD_SEPARATESIGNALS 1 32 | #define SIGDETECTOR_METHOD_BOXOUTSIDEIN 2 33 | 34 | namespace gr { 35 | namespace mesa { 36 | 37 | class SignalDetector_impl : public SignalDetector { 38 | protected: 39 | boost::mutex d_mutex; 40 | EnergyAnalyzer *pEnergyAnalyzer; 41 | int d_detectionMethod; 42 | 43 | gr_complex *pMsgOutBuff; 44 | int msgBufferSize; 45 | 46 | double d_sampleRate; 47 | double d_centerFreq; 48 | double d_minWidthHz; 49 | double d_maxWidthHz; 50 | int d_framesToAvg; 51 | 52 | int d_fftSize; 53 | bool d_enableDebug; 54 | 55 | bool d_genSignalPDUs; 56 | 57 | std::chrono::time_point startup, endup; 58 | bool d_startInitialized; 59 | float d_holdUpSec; 60 | 61 | // Methods 62 | float calcMinDutyCycle(); 63 | virtual int processData(int noutput_items, const gr_complex *in, 64 | gr_complex *out, pmt::pmt_t *pMetadata); 65 | void sendState(bool state); 66 | 67 | public: 68 | SignalDetector_impl(int fftsize, float squelchThreshold, double minWidthHz, 69 | double maxWidthHz, double radioCenterFreq, 70 | double sampleRate, float holdUpSec, int framesToAvg, 71 | bool genSignalPDUs, bool enableDebug, 72 | int detectionMethod); 73 | virtual ~SignalDetector_impl(); 74 | 75 | virtual bool stop(); 76 | 77 | void handleMsgIn(pmt::pmt_t msg); 78 | 79 | virtual float getSquelch() const; 80 | virtual void setSquelch(float newValue); 81 | 82 | virtual double getCenterFrequency() const; 83 | virtual void setCenterFrequency(double newValue); 84 | 85 | virtual double getMinWidthHz() const; 86 | virtual void setMinWidthHz(double newValue); 87 | 88 | virtual double getMaxWidthHz() const; 89 | virtual void setMaxWidthHz(double newValue); 90 | 91 | // Where all the action really happens 92 | int work(int noutput_items, gr_vector_const_void_star &input_items, 93 | gr_vector_void_star &output_items); 94 | }; 95 | 96 | } // namespace mesa 97 | } // namespace gr 98 | 99 | #endif /* INCLUDED_MESA_SIGNALDETECTOR_IMPL_H */ 100 | -------------------------------------------------------------------------------- /lib/SourceSelector_impl.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2019 ghostop14. 4 | * 5 | * This 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 | * This software 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 this software; 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 | #include "SourceSelector_impl.h" 22 | #include 23 | #include 24 | namespace gr { 25 | namespace mesa { 26 | 27 | SourceSelector::sptr 28 | SourceSelector::make(float holdTime, int numInputs, int defaultInput, int inputBlockSize) 29 | { 30 | return gnuradio::make_block_sptr( 31 | holdTime, numInputs, defaultInput, inputBlockSize); 32 | } 33 | 34 | /* 35 | * The private constructor 36 | */ 37 | SourceSelector_impl::SourceSelector_impl(float holdTime, int numInputs, 38 | int defaultInput, int inputBlockSize) 39 | : gr::sync_block("SourceSelector", gr::io_signature::make(0, 0, 0), 40 | gr::io_signature::make(0, 1, sizeof(gr_complex))) { 41 | d_holdTime = holdTime; 42 | d_numInputs = numInputs; 43 | d_defaultInput = defaultInput; 44 | d_inputBlockSize = inputBlockSize; 45 | 46 | if (defaultInput <= 0) 47 | defaultInput = 1; 48 | d_currentInput = defaultInput; 49 | 50 | d_startInitialized = false; 51 | 52 | limitQueue = false; 53 | 54 | // Initial anti-jitter buffer 55 | minQueueLength = d_inputBlockSize * 2; 56 | initialDataQueueRequirement = d_inputBlockSize * 6; 57 | initialQueueSizeMet = false; 58 | 59 | std::cout << "[Source Selector] Buffering initial frames..." << std::endl; 60 | 61 | for (int i = 0; i < 4; i++) 62 | maxPower[i] = -999.0; 63 | 64 | message_port_register_in(pmt::mp("in1")); 65 | set_msg_handler(pmt::mp("in1"), 66 | std::bind(&SourceSelector_impl::handleMsgIn1, this, std::placeholders::_1)); 67 | message_port_register_in(pmt::mp("in2")); 68 | set_msg_handler(pmt::mp("in2"), 69 | std::bind(&SourceSelector_impl::handleMsgIn2, this, std::placeholders::_1)); 70 | message_port_register_in(pmt::mp("in3")); 71 | set_msg_handler(pmt::mp("in3"), 72 | std::bind(&SourceSelector_impl::handleMsgIn3, this, std::placeholders::_1)); 73 | message_port_register_in(pmt::mp("in4")); 74 | set_msg_handler(pmt::mp("in4"), 75 | std::bind(&SourceSelector_impl::handleMsgIn4, this, std::placeholders::_1)); 76 | 77 | message_port_register_out(pmt::mp("inputport")); 78 | 79 | if (inputBlockSize > 0) 80 | gr::block::set_output_multiple(inputBlockSize); 81 | } 82 | 83 | bool SourceSelector_impl::stop() { return true; } 84 | 85 | /* 86 | * Our virtual destructor. 87 | */ 88 | SourceSelector_impl::~SourceSelector_impl() { bool retVal = stop(); } 89 | 90 | int SourceSelector_impl::maxPowerIndex() { 91 | int maxIndex = 0; 92 | float curMax = maxPower[0]; 93 | 94 | for (int i = 1; i < 4; i++) { 95 | if (maxPower[i] > curMax) { 96 | maxIndex = i; 97 | } 98 | } 99 | 100 | return maxIndex; 101 | } 102 | 103 | int SourceSelector_impl::getDataAvailable() { 104 | gr::thread::scoped_lock guard(d_queuemutex); 105 | return dataQueue.size(); 106 | } 107 | 108 | void SourceSelector_impl::queueData(pmt::pmt_t msg) { 109 | // Since we removed the output, just return. 110 | /* 111 | pmt::pmt_t data = pmt::cdr(msg); 112 | 113 | if (data == pmt::PMT_NIL) 114 | return; 115 | 116 | size_t vecSize = pmt::length(data); 117 | const gr_complex *cc_samples; 118 | cc_samples = pmt::c32vector_elements(data,vecSize); 119 | 120 | // queue the data 121 | gr::thread::scoped_lock guard(d_queuemutex); 122 | for (long i=0;i curTimestamp = 179 | std::chrono::steady_clock::now(); 180 | std::chrono::duration elapsed_seconds = 181 | curTimestamp - lastShifted; 182 | if (elapsed_seconds.count() > (double)d_holdTime) { 183 | d_currentInput = port; 184 | lastShifted = curTimestamp; // Reset the shifted timer. 185 | queueData(msg); 186 | sendNewPortMsg(port); 187 | } // elapsed_seconds 188 | /* 189 | * The else to this that drops through is that we're not the max port 190 | * and we're within our hold-down timer, so we're not allowed to shift. 191 | * Which means we have to just drop the data. So there's no queueing. 192 | */ 193 | } // else initialized 194 | 195 | } // iMaxPower == port 196 | } 197 | } 198 | 199 | void SourceSelector_impl::handleMsgIn1(pmt::pmt_t msg) { handleMsg(msg, 1); } 200 | 201 | void SourceSelector_impl::handleMsgIn2(pmt::pmt_t msg) { handleMsg(msg, 2); } 202 | 203 | void SourceSelector_impl::handleMsgIn3(pmt::pmt_t msg) { handleMsg(msg, 3); } 204 | 205 | void SourceSelector_impl::handleMsgIn4(pmt::pmt_t msg) { handleMsg(msg, 4); } 206 | 207 | int SourceSelector_impl::work(int noutput_items, 208 | gr_vector_const_void_star &input_items, 209 | gr_vector_void_star &output_items) { 210 | int curQueueSize = getDataAvailable(); 211 | 212 | gr_complex *out = (gr_complex *)output_items[0]; 213 | 214 | if ((!initialQueueSizeMet && (curQueueSize < initialDataQueueRequirement)) || 215 | (curQueueSize == 0)) { 216 | // std::cout << "iU"; 217 | // Return zeros to keep the flowgraph running 218 | memset((void *)out, 0x00, noutput_items * sizeof(gr_complex)); 219 | return noutput_items; 220 | } 221 | 222 | initialQueueSizeMet = true; 223 | 224 | int itemsProduced = noutput_items; 225 | 226 | if (curQueueSize < noutput_items) 227 | itemsProduced = curQueueSize; 228 | 229 | gr::thread::scoped_lock guard(d_queuemutex); 230 | for (long i = 0; i < itemsProduced; i++) { 231 | out[i] = dataQueue.front(); 232 | dataQueue.pop(); 233 | } 234 | 235 | return itemsProduced; 236 | } 237 | 238 | } /* namespace mesa */ 239 | } /* namespace gr */ 240 | -------------------------------------------------------------------------------- /lib/SourceSelector_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2019 ghostop14. 4 | * 5 | * This 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 | * This software 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 this software; 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 | #ifndef INCLUDED_MESA_SOURCESELECTOR_IMPL_H 22 | #define INCLUDED_MESA_SOURCESELECTOR_IMPL_H 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | using namespace std; 31 | 32 | namespace gr { 33 | namespace mesa { 34 | class SourceSelector_impl : public SourceSelector { 35 | protected: 36 | boost::mutex d_mutex; 37 | boost::mutex d_queuemutex; 38 | float d_holdTime; 39 | int d_numInputs; 40 | int d_defaultInput; 41 | int d_inputBlockSize; 42 | int d_currentInput; 43 | 44 | // Data queue management 45 | queue dataQueue; 46 | // long maxQueueSize; 47 | bool limitQueue; 48 | 49 | long minQueueLength; 50 | long initialDataQueueRequirement; 51 | bool initialQueueSizeMet; 52 | 53 | // Max Power for each input 54 | float maxPower[4]; 55 | 56 | bool d_startInitialized; 57 | std::chrono::time_point lastShifted; 58 | 59 | int maxPowerIndex(); 60 | void queueData(pmt::pmt_t msg); 61 | 62 | int getDataAvailable(); 63 | 64 | void sendNewPortMsg(int port); 65 | 66 | virtual void handleMsg(pmt::pmt_t msg, int port); 67 | 68 | public: 69 | SourceSelector_impl(float holdTime, int numInputs, int defaultInput, 70 | int inputBlockSize); 71 | ~SourceSelector_impl(); 72 | virtual bool stop(); 73 | 74 | void handleMsgIn1(pmt::pmt_t msg); 75 | void handleMsgIn2(pmt::pmt_t msg); 76 | void handleMsgIn3(pmt::pmt_t msg); 77 | void handleMsgIn4(pmt::pmt_t msg); 78 | 79 | // Where all the action really happens 80 | int work(int noutput_items, gr_vector_const_void_star &input_items, 81 | gr_vector_void_star &output_items); 82 | }; 83 | 84 | } // namespace mesa 85 | } // namespace gr 86 | 87 | #endif /* INCLUDED_MESA_SOURCESELECTOR_IMPL_H */ 88 | -------------------------------------------------------------------------------- /lib/ioselector_impl.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2019 ghostop14. 4 | * 5 | * This 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 | * This software 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 this software; 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 | #include "ioselector_impl.h" 22 | #include 23 | #include 24 | namespace gr { 25 | namespace mesa { 26 | 27 | ioselector::sptr ioselector::make( 28 | int numinputs, int numoutputs, int inputport, int outputport, int itemsize) 29 | { 30 | return gnuradio::make_block_sptr( 31 | numinputs, numoutputs, inputport, outputport, itemsize); 32 | } 33 | 34 | /* 35 | * The private constructor 36 | */ 37 | ioselector_impl::ioselector_impl(int numinputs, int numoutputs, int inputport, 38 | int outputport, int itemsize) 39 | : gr::sync_block("ioselector", 40 | gr::io_signature::make(1, numinputs, itemsize), 41 | gr::io_signature::make(1, numoutputs, itemsize)) { 42 | d_numinputs = numinputs; 43 | d_numoutputs = numoutputs; 44 | d_curInput = inputport; 45 | d_curOutput = outputport; 46 | d_itemsize = itemsize; 47 | 48 | message_port_register_in(pmt::mp("inputindex")); 49 | set_msg_handler(pmt::mp("inputindex"), 50 | std::bind(&ioselector_impl::handleMsgInputIndex, this, std::placeholders::_1)); 51 | message_port_register_in(pmt::mp("outputindex")); 52 | set_msg_handler( 53 | pmt::mp("outputindex"), 54 | std::bind(&ioselector_impl::handleMsgOutputIndex, this, std::placeholders::_1)); 55 | } 56 | 57 | /* 58 | * Our virtual destructor. 59 | */ 60 | ioselector_impl::~ioselector_impl() {} 61 | 62 | void ioselector_impl::handleMsgInputIndex(pmt::pmt_t msg) { 63 | pmt::pmt_t data = pmt::cdr(msg); 64 | 65 | if (pmt::is_integer(data)) { 66 | int newPort = pmt::to_long(data); 67 | 68 | if (newPort < (d_numinputs)) { 69 | set_input_index(newPort); 70 | } 71 | } 72 | } 73 | 74 | void ioselector_impl::handleMsgOutputIndex(pmt::pmt_t msg) { 75 | pmt::pmt_t data = pmt::cdr(msg); 76 | 77 | if (pmt::is_integer(data)) { 78 | int newPort = pmt::to_long(data); 79 | if (newPort < (d_numoutputs)) 80 | set_output_index(newPort); 81 | } 82 | } 83 | 84 | void ioselector_impl::set_input_index(int newValue) { d_curInput = newValue; } 85 | 86 | void ioselector_impl::set_output_index(int newValue) { d_curOutput = newValue; } 87 | 88 | int ioselector_impl::work(int noutput_items, 89 | gr_vector_const_void_star &input_items, 90 | gr_vector_void_star &output_items) { 91 | const char *in = (const char *)input_items[d_curInput]; 92 | char *out = (char *)output_items[d_curOutput]; 93 | 94 | int noi = noutput_items * d_itemsize; 95 | memcpy(out, in, noi); 96 | 97 | // Tell runtime system how many output items we produced. 98 | return noutput_items; 99 | } 100 | 101 | } /* namespace mesa */ 102 | } /* namespace gr */ 103 | -------------------------------------------------------------------------------- /lib/ioselector_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2019 ghostop14. 4 | * 5 | * This 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 | * This software 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 this software; 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 | #ifndef INCLUDED_MESA_IOSELECTOR_IMPL_H 22 | #define INCLUDED_MESA_IOSELECTOR_IMPL_H 23 | 24 | #include 25 | 26 | namespace gr { 27 | namespace mesa { 28 | 29 | class ioselector_impl : public ioselector { 30 | private: 31 | // Nothing to declare in this block. 32 | int d_numinputs; 33 | int d_numoutputs; 34 | int d_curInput; 35 | int d_curOutput; 36 | int d_itemsize; 37 | 38 | public: 39 | ioselector_impl(int numinputs, int numoutputs, int inputport, int outputport, 40 | int itemsize); 41 | ~ioselector_impl(); 42 | 43 | virtual void set_input_index(int newValue); 44 | virtual void set_output_index(int newValue); 45 | 46 | void handleMsgInputIndex(pmt::pmt_t msg); 47 | void handleMsgOutputIndex(pmt::pmt_t msg); 48 | 49 | // Where all the action really happens 50 | int work(int noutput_items, gr_vector_const_void_star &input_items, 51 | gr_vector_void_star &output_items); 52 | }; 53 | 54 | } // namespace mesa 55 | } // namespace gr 56 | 57 | #endif /* INCLUDED_MESA_IOSELECTOR_IMPL_H */ 58 | -------------------------------------------------------------------------------- /lib/phase_shift_impl.cc: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2019 ghostop14. 4 | * 5 | * This 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 | * This software 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 this software; 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 | #include "phase_shift_impl.h" 22 | #include 23 | 24 | #include 25 | 26 | namespace gr { 27 | namespace mesa { 28 | 29 | phase_shift::sptr phase_shift::make(float shift_in_radians) 30 | { 31 | return gnuradio::make_block_sptr(shift_in_radians); 32 | } 33 | 34 | /* 35 | * The private constructor 36 | */ 37 | phase_shift_impl::phase_shift_impl(float shift_in_radians) 38 | : gr::sync_block("phase_shift", 39 | gr::io_signature::make(1, 1, sizeof(gr_complex)), 40 | gr::io_signature::make(1, 1, sizeof(gr_complex))) { 41 | d_shift_in_radians = shift_in_radians; 42 | d_shift_cc = gr_complex(cos(d_shift_in_radians), sin(d_shift_in_radians)); 43 | 44 | message_port_register_in(pmt::mp("shift_rad")); 45 | set_msg_handler(pmt::mp("shift_rad"), 46 | [this](pmt::pmt_t msg) { this->handle_msg_in(msg); }); 47 | } 48 | 49 | /* 50 | * Our virtual destructor. 51 | */ 52 | phase_shift_impl::~phase_shift_impl() {} 53 | 54 | void phase_shift_impl::handle_msg_in(pmt::pmt_t msg) { 55 | set_shift(pmt::to_float(msg)); 56 | } 57 | 58 | float phase_shift_impl::get_shift() const { return d_shift_in_radians; } 59 | 60 | void phase_shift_impl::set_shift(float newValue) { 61 | gr::thread::scoped_lock guard(d_setlock); 62 | d_shift_in_radians = newValue; 63 | d_shift_cc = gr_complex(cos(d_shift_in_radians), sin(d_shift_in_radians)); 64 | } 65 | 66 | int phase_shift_impl::work(int noutput_items, 67 | gr_vector_const_void_star &input_items, 68 | gr_vector_void_star &output_items) { 69 | const gr_complex *in = (const gr_complex *)input_items[0]; 70 | gr_complex *out = (gr_complex *)output_items[0]; 71 | 72 | gr::thread::scoped_lock guard(d_setlock); 73 | 74 | if (d_shift_in_radians != 0.0) { 75 | volk_32fc_s32fc_multiply_32fc(out, in, d_shift_cc, noutput_items); 76 | } else { 77 | memcpy(out, in, sizeof(gr_complex) * noutput_items); 78 | } 79 | 80 | // Tell runtime system how many output items we produced. 81 | return noutput_items; 82 | } 83 | 84 | } /* namespace mesa */ 85 | } /* namespace gr */ 86 | -------------------------------------------------------------------------------- /lib/phase_shift_impl.h: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | /* 3 | * Copyright 2019 ghostop14. 4 | * 5 | * This 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 | * This software 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 this software; 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 | #ifndef INCLUDED_MESA_PHASE_SHIFT_IMPL_H 22 | #define INCLUDED_MESA_PHASE_SHIFT_IMPL_H 23 | 24 | #include 25 | 26 | namespace gr { 27 | namespace mesa { 28 | 29 | class phase_shift_impl : public phase_shift { 30 | private: 31 | float d_shift_in_radians; 32 | gr_complex d_shift_cc; 33 | 34 | public: 35 | phase_shift_impl(float shift_in_radians); 36 | ~phase_shift_impl(); 37 | 38 | virtual float get_shift() const; 39 | virtual void set_shift(float newValue); 40 | 41 | void handle_msg_in(pmt::pmt_t msg); 42 | 43 | // Where all the action really happens 44 | int work(int noutput_items, gr_vector_const_void_star &input_items, 45 | gr_vector_void_star &output_items); 46 | }; 47 | 48 | } // namespace mesa 49 | } // namespace gr 50 | 51 | #endif /* INCLUDED_MESA_PHASE_SHIFT_IMPL_H */ 52 | -------------------------------------------------------------------------------- /lib/scomplex.h: -------------------------------------------------------------------------------- 1 | /* 2 | * scomplex.h 3 | * 4 | * Copyright 2017, Michael Piscopo 5 | * 6 | */ 7 | 8 | #ifndef LIB_SCOMPLEX_H_ 9 | #define LIB_SCOMPLEX_H_ 10 | 11 | #include 12 | #include 13 | 14 | // Common type definitions 15 | typedef std::complex SComplex; 16 | typedef std::vector> ComplexVector; 17 | 18 | // This structure version is used in some places for optimization to get direct 19 | // access to the values without having to make function calls to get/set. 20 | struct ComplexStruct { 21 | float real; 22 | float imag; 23 | }; 24 | 25 | typedef struct ComplexStruct StructComplex; 26 | 27 | #endif /* LIB_SCOMPLEX_H_ */ 28 | -------------------------------------------------------------------------------- /python/AutoCorrelator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright 2019 ghostop14. 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 | from gnuradio import gr 23 | from gnuradio import blocks, fft, filter 24 | import math 25 | 26 | class AutoCorrelator(gr.hier_block2): 27 | """ 28 | docstring for block AutoCorrelator 29 | """ 30 | def __init__(self, sample_rate, fac_size,fac_decimation, useDB): 31 | gr.hier_block2.__init__(self,"AutoCorrelator", 32 | gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature 33 | gr.io_signature(1, 1, gr.sizeof_float*fac_size)) # Output signature 34 | 35 | self.fac_size = fac_size 36 | self.fac_decimation = fac_decimation 37 | self.sample_rate = sample_rate 38 | 39 | streamToVec = blocks.stream_to_vector(gr.sizeof_gr_complex, self.fac_size) 40 | # Make sure N is at least 1 41 | decimation = int(self.sample_rate/self.fac_size/self.fac_decimation) 42 | self.one_in_n = blocks.keep_one_in_n(gr.sizeof_gr_complex * self.fac_size, max(1,decimation)) 43 | 44 | # FFT Note: No windowing. 45 | fac = fft.fft_vcc(self.fac_size, True, ()) 46 | 47 | complex2Mag = blocks.complex_to_mag(self.fac_size) 48 | self.avg = filter.single_pole_iir_filter_ff(1.0, self.fac_size) 49 | 50 | fac_fac = fft.fft_vfc(self.fac_size, True, ()) 51 | fac_c2mag = blocks.complex_to_mag(fac_size) 52 | 53 | # There's a note in Baz's block about needing to add 3 dB to each bin but the DC bin, however it was never implemented 54 | n = 20 55 | k = -20*math.log10(self.fac_size) 56 | log = blocks.nlog10_ff(n, self.fac_size, k ) 57 | 58 | if useDB: 59 | self.connect(self, streamToVec, self.one_in_n, fac, complex2Mag, fac_fac, fac_c2mag, self.avg, log, self) 60 | else: 61 | self.connect(self, streamToVec, self.one_in_n, fac, complex2Mag, fac_fac, fac_c2mag, self.avg, self) 62 | -------------------------------------------------------------------------------- /python/AutoCorrelatorSink.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright 2019 ghostop14. 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 | from gnuradio import gr 23 | from gnuradio import blocks 24 | from mesa import AutoCorrelator 25 | from mesa import Normalize 26 | from gnuradio import qtgui 27 | # SIP import lets us wrap our control as a pyQt widget 28 | import sip 29 | from PyQt5 import QtGui 30 | from PyQt5.QtWidgets import QWidget 31 | 32 | class AutoCorrelatorSink(gr.hier_block2): 33 | """ 34 | docstring for block AutoCorrelatorSink 35 | """ 36 | def __init__(self, sample_rate, fac_size, fac_decimation, title, autoScale, grid, yMin, yMax, useDB): 37 | gr.hier_block2.__init__(self, 38 | "AutoCorrelatorSink", 39 | gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature 40 | gr.io_signature(0, 0, 0)) # Output signature 41 | 42 | self.fac_size = fac_size 43 | self.fac_decimation = fac_decimation 44 | self.sample_rate = sample_rate 45 | 46 | autoCorr = AutoCorrelator(sample_rate, fac_size, fac_decimation, useDB) 47 | vecToStream = blocks.vector_to_stream(gr.sizeof_float, self.fac_size) 48 | 49 | self.timeSink = qtgui.time_sink_f(self.fac_size/2, sample_rate, title, 1) 50 | self.timeSink.enable_grid(grid) 51 | self.timeSink.set_y_axis(yMin, yMax) 52 | self.timeSink.enable_autoscale(autoScale) 53 | self.timeSink.disable_legend() 54 | self.timeSink.set_update_time(0.1) 55 | 56 | if useDB: 57 | self.connect(self, autoCorr, vecToStream, self.timeSink) 58 | else: 59 | norm = Normalize.Normalize(self.fac_size) 60 | self.connect(self, autoCorr, norm, vecToStream, self.timeSink) 61 | 62 | #pyQt = self.timeSink.pyqwidget() 63 | #self.pyWin = sip.wrapinstance(pyQt, QtGui.QWidget) 64 | # self.pyWin.show() 65 | 66 | def getWidget(self): 67 | return sip.wrapinstance(self.timeSink.pyqwidget(), QWidget) 68 | -------------------------------------------------------------------------------- /python/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Free Software Foundation, Inc. 2 | # 3 | # This file was generated by gr_modtool, a tool from the GNU Radio framework 4 | # This file is a part of gr-mesa 5 | # 6 | # SPDX-License-Identifier: GPL-3.0-or-later 7 | # 8 | 9 | ######################################################################## 10 | # Include python install macros 11 | ######################################################################## 12 | include(GrPython) 13 | if(NOT PYTHONINTERP_FOUND) 14 | return() 15 | endif() 16 | 17 | add_subdirectory(bindings) 18 | 19 | ######################################################################## 20 | # Install python sources 21 | ######################################################################## 22 | GR_PYTHON_INSTALL( 23 | FILES 24 | __init__.py 25 | AutoCorrelator.py 26 | AutoCorrelatorSink.py 27 | Normalize.py 28 | VariableRotator.py DESTINATION ${GR_PYTHON_DIR}/mesa 29 | ) 30 | 31 | ######################################################################## 32 | # Handle the unit tests 33 | ######################################################################## 34 | include(GrTest) 35 | 36 | set(GR_TEST_TARGET_DEPS gnuradio-mesa) 37 | -------------------------------------------------------------------------------- /python/Normalize.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright 2019 ghostop14. 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 | from gnuradio import gr 23 | from gnuradio import blocks 24 | 25 | class Normalize(gr.hier_block2): 26 | def __init__(self, vecsize=1024): 27 | gr.hier_block2.__init__( 28 | self, "Normalize", 29 | gr.io_signature(1, 1, gr.sizeof_float*vecsize), 30 | gr.io_signature(1, 1, gr.sizeof_float*vecsize), 31 | ) 32 | 33 | ################################################## 34 | # Parameters 35 | ################################################## 36 | self.vecsize = vecsize 37 | 38 | ################################################## 39 | # Blocks 40 | ################################################## 41 | self.blocks_stream_to_vector_0 = blocks.stream_to_vector(gr.sizeof_float, vecsize) 42 | self.blocks_repeat_0 = blocks.repeat(gr.sizeof_float, vecsize) 43 | self.blocks_max_xx_0 = blocks.max_ff(vecsize) 44 | self.blocks_divide_xx_0 = blocks.divide_ff(vecsize) 45 | 46 | ################################################## 47 | # Connections 48 | ################################################## 49 | self.connect((self.blocks_divide_xx_0, 0), (self, 0)) 50 | self.connect((self.blocks_stream_to_vector_0, 0), (self.blocks_divide_xx_0, 1)) 51 | self.connect((self, 0), (self.blocks_max_xx_0, 0)) 52 | self.connect((self.blocks_repeat_0, 0), (self.blocks_stream_to_vector_0, 0)) 53 | self.connect((self.blocks_max_xx_0, 0), (self.blocks_repeat_0, 0)) 54 | self.connect((self, 0), (self.blocks_divide_xx_0, 0)) 55 | 56 | 57 | def get_vecsize(self): 58 | return self.vecsize 59 | 60 | def set_vecsize(self, vecsize): 61 | self.vecsize = vecsize 62 | 63 | -------------------------------------------------------------------------------- /python/VariableRotator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright 2019 ghostop14. 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 | 23 | import numpy 24 | from gnuradio import gr 25 | import pmt 26 | 27 | import threading 28 | import time 29 | import sys 30 | 31 | # Cheat to send messages across threads 32 | from PyQt5.QtWidgets import QFrame 33 | from PyQt5 import QtCore 34 | 35 | class RotationThread(threading.Thread): 36 | def __init__(self, parentCtl, valueList,rotationTime): 37 | threading.Thread.__init__(self) 38 | 39 | self.stopThread = False 40 | self.threadRunning = False 41 | 42 | self.hold = False 43 | 44 | self.parentCtl = parentCtl 45 | self.valueList = valueList 46 | self.rotationTime = rotationTime 47 | self.curValue = valueList[0] 48 | 49 | def run(self): 50 | self.threadRunning = True 51 | 52 | curIndex = 0 53 | numEntries = len(self.valueList) 54 | 55 | time.sleep(0.5) # TODO: Find better way to know if init is all done 56 | 57 | while not self.stopThread: 58 | if not self.hold: 59 | self.curValue = self.valueList[curIndex] 60 | self.parentCtl.sigNewValue.emit(self.curValue,curIndex) 61 | 62 | # Need to shorten detection time for threadRunning 63 | time.sleep(self.rotationTime) 64 | 65 | curIndex = curIndex + 1 66 | if curIndex > (numEntries-1): 67 | curIndex = 0 68 | else: 69 | # Just a short sleep waiting to see if the hold gets released 70 | time.sleep(0.002) 71 | 72 | self.threadRunning = False 73 | 74 | class VariableRotator(gr.sync_block,QFrame): 75 | """ 76 | docstring for block VariableRotator 77 | """ 78 | sigNewValue = QtCore.pyqtSignal(float,int) 79 | 80 | def __init__(self, valueList,rotationTime,varCallback,parent): 81 | gr.sync_block.__init__(self,name="VariableRotator",in_sig=None,out_sig=None) 82 | QFrame.__init__(self,parent=parent) 83 | 84 | if (len(valueList) == 0): 85 | print("[ValueRotator] Error: Please provide a list of values") 86 | sys.exit(1) 87 | 88 | self.varCallback = varCallback 89 | self.sigNewValue.connect(self.newValue) 90 | 91 | self.lastValue = valueList[0] 92 | 93 | self.thread = RotationThread(self, valueList, rotationTime) 94 | self.thread.start() 95 | 96 | self.message_port_register_in(pmt.intern("hold")) 97 | self.set_msg_handler(pmt.intern("hold"), self.holdHandler) 98 | 99 | self.message_port_register_out(pmt.intern("value")) 100 | self.message_port_register_out(pmt.intern("index")) 101 | 102 | def holdHandler(self, msg): 103 | try: 104 | newVal = pmt.to_python(pmt.cdr(msg)) 105 | 106 | if type(newVal) == int: 107 | if newVal == 0: 108 | self.thread.hold = False 109 | else: 110 | self.thread.hold = True 111 | else: 112 | print("[ValueRotator] Error: Value received was not an int: %s" % str(e)) 113 | 114 | except Exception as e: 115 | print("[ValueRotator] Error with message conversion: %s" % str(e)) 116 | 117 | def newValue(self,curValue,curIndex): 118 | p_val = pmt.from_float(curValue) 119 | p_index = pmt.from_long(curIndex) 120 | 121 | if curValue != self.lastValue: 122 | try: 123 | self.varCallback(curValue) 124 | except: 125 | pass 126 | 127 | self.message_port_pub(pmt.intern("value"),pmt.cons(pmt.intern("value"),p_val)) 128 | 129 | self.lastValue = curValue 130 | 131 | self.message_port_pub(pmt.intern("index"),pmt.cons(pmt.intern("index"),p_index)) 132 | 133 | def stop(self): 134 | self.thread.stopThread = True 135 | self.thread.join() 136 | 137 | return True 138 | 139 | 140 | def work(self, input_items, output_items): 141 | out = output_items[0] 142 | return len(output_items[0]) 143 | 144 | -------------------------------------------------------------------------------- /python/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2008,2009 Free Software Foundation, Inc. 3 | # 4 | # SPDX-License-Identifier: GPL-3.0-or-later 5 | # 6 | 7 | # The presence of this file turns this directory into a Python package 8 | 9 | ''' 10 | This is the GNU Radio MESA module. Place your Python package 11 | description here (python/__init__.py). 12 | ''' 13 | import os 14 | 15 | # import pybind11 generated symbols into the mesa namespace 16 | try: 17 | # this might fail if the module is python-only 18 | from .mesa_python import * 19 | except ModuleNotFoundError: 20 | pass 21 | 22 | # import any pure python here 23 | # 24 | from .AutoCorrelator import AutoCorrelator 25 | from .AutoCorrelatorSink import AutoCorrelatorSink 26 | from .Normalize import Normalize 27 | from .VariableRotator import VariableRotator 28 | 29 | -------------------------------------------------------------------------------- /python/bindings/AutoDopplerCorrect_python.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * SPDX-License-Identifier: GPL-3.0-or-later 7 | * 8 | */ 9 | 10 | /***********************************************************************************/ 11 | /* This file is automatically generated using bindtool and can be manually edited */ 12 | /* The following lines can be configured to regenerate this file during cmake */ 13 | /* If manual edits are made, the following tags should be modified accordingly. */ 14 | /* BINDTOOL_GEN_AUTOMATIC(0) */ 15 | /* BINDTOOL_USE_PYGCCXML(0) */ 16 | /* BINDTOOL_HEADER_FILE(AutoDopplerCorrect.h) */ 17 | /* BINDTOOL_HEADER_FILE_HASH(e67c3da6e40321ef09a6742aed170b21) */ 18 | /***********************************************************************************/ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | namespace py = pybind11; 25 | 26 | #include 27 | // pydoc.h is automatically generated in the build directory 28 | #include 29 | 30 | void bind_AutoDopplerCorrect(py::module& m) 31 | { 32 | 33 | using AutoDopplerCorrect = ::gr::mesa::AutoDopplerCorrect; 34 | 35 | 36 | py::class_>(m, "AutoDopplerCorrect", D(AutoDopplerCorrect)) 38 | 39 | .def(py::init(&AutoDopplerCorrect::make), 40 | py::arg("freq"), 41 | py::arg("sampleRate"), 42 | py::arg("maxDrift"), 43 | py::arg("minWidth"), 44 | py::arg("expectedWidth"), 45 | py::arg("shiftHolddownMS"), 46 | py::arg("fft_size"), 47 | py::arg("squelchThreshold"), 48 | py::arg("framesToAvg"), 49 | py::arg("holdUpSec"), 50 | py::arg("processMessages"), 51 | py::arg("detectionMethod"), 52 | D(AutoDopplerCorrect,make) 53 | ) 54 | 55 | 56 | 57 | 58 | 59 | 60 | .def("getSquelch",&AutoDopplerCorrect::getSquelch, 61 | D(AutoDopplerCorrect,getSquelch) 62 | ) 63 | 64 | 65 | 66 | .def("setSquelch",&AutoDopplerCorrect::setSquelch, 67 | py::arg("newValue"), 68 | D(AutoDopplerCorrect,setSquelch) 69 | ) 70 | 71 | 72 | 73 | .def("getCenterFrequency",&AutoDopplerCorrect::getCenterFrequency, 74 | D(AutoDopplerCorrect,getCenterFrequency) 75 | ) 76 | 77 | 78 | 79 | .def("setCenterFrequency",&AutoDopplerCorrect::setCenterFrequency, 80 | py::arg("newValue"), 81 | D(AutoDopplerCorrect,setCenterFrequency) 82 | ) 83 | 84 | 85 | 86 | .def("getMinWidthHz",&AutoDopplerCorrect::getMinWidthHz, 87 | D(AutoDopplerCorrect,getMinWidthHz) 88 | ) 89 | 90 | 91 | 92 | .def("setMinWidthHz",&AutoDopplerCorrect::setMinWidthHz, 93 | py::arg("newValue"), 94 | D(AutoDopplerCorrect,setMinWidthHz) 95 | ) 96 | 97 | 98 | 99 | .def("getExpectedWidth",&AutoDopplerCorrect::getExpectedWidth, 100 | D(AutoDopplerCorrect,getExpectedWidth) 101 | ) 102 | 103 | 104 | 105 | .def("setExpectedWidth",&AutoDopplerCorrect::setExpectedWidth, 106 | py::arg("newValue"), 107 | D(AutoDopplerCorrect,setExpectedWidth) 108 | ) 109 | 110 | 111 | 112 | .def("getMaxDrift",&AutoDopplerCorrect::getMaxDrift, 113 | D(AutoDopplerCorrect,getMaxDrift) 114 | ) 115 | 116 | 117 | 118 | .def("setMaxDrift",&AutoDopplerCorrect::setMaxDrift, 119 | py::arg("newValue"), 120 | D(AutoDopplerCorrect,setMaxDrift) 121 | ) 122 | 123 | ; 124 | 125 | 126 | 127 | 128 | } 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /python/bindings/AvgToMsg_python.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * SPDX-License-Identifier: GPL-3.0-or-later 7 | * 8 | */ 9 | 10 | /***********************************************************************************/ 11 | /* This file is automatically generated using bindtool and can be manually edited */ 12 | /* The following lines can be configured to regenerate this file during cmake */ 13 | /* If manual edits are made, the following tags should be modified accordingly. */ 14 | /* BINDTOOL_GEN_AUTOMATIC(0) */ 15 | /* BINDTOOL_USE_PYGCCXML(0) */ 16 | /* BINDTOOL_HEADER_FILE(AvgToMsg.h) */ 17 | /* BINDTOOL_HEADER_FILE_HASH(f2bbd4fe97e72bd0951f247bb023a3a8) */ 18 | /***********************************************************************************/ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | namespace py = pybind11; 25 | 26 | #include 27 | // pydoc.h is automatically generated in the build directory 28 | #include 29 | 30 | void bind_AvgToMsg(py::module& m) 31 | { 32 | 33 | using AvgToMsg = ::gr::mesa::AvgToMsg; 34 | 35 | 36 | py::class_>(m, "AvgToMsg", D(AvgToMsg)) 38 | 39 | .def(py::init(&AvgToMsg::make), 40 | py::arg("veclen"), 41 | D(AvgToMsg,make) 42 | ) 43 | 44 | 45 | 46 | 47 | 48 | 49 | .def("setHold",&AvgToMsg::setHold, 50 | py::arg("newValue"), 51 | D(AvgToMsg,setHold) 52 | ) 53 | 54 | ; 55 | 56 | 57 | 58 | 59 | } 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /python/bindings/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright 2020 Free Software Foundation, Inc. 2 | # 3 | # This file is part of GNU Radio 4 | # 5 | # SPDX-License-Identifier: GPL-3.0-or-later 6 | # 7 | 8 | ######################################################################## 9 | # Check if there is C++ code at all 10 | ######################################################################## 11 | if(NOT mesa_sources) 12 | MESSAGE(STATUS "No C++ sources... skipping python bindings") 13 | return() 14 | endif(NOT mesa_sources) 15 | 16 | ######################################################################## 17 | # Check for pygccxml 18 | ######################################################################## 19 | GR_PYTHON_CHECK_MODULE_RAW( 20 | "pygccxml" 21 | "import pygccxml" 22 | PYGCCXML_FOUND 23 | ) 24 | 25 | include(GrPybind) 26 | 27 | ######################################################################## 28 | # Python Bindings 29 | ######################################################################## 30 | 31 | list(APPEND mesa_python_files 32 | AutoDopplerCorrect_python.cc 33 | AvgToMsg_python.cc 34 | ioselector_python.cc 35 | LongTermIntegrator_python.cc 36 | MaxPower_python.cc 37 | phase_shift_python.cc 38 | SignalDetector_python.cc 39 | SourceSelector_python.cc python_bindings.cc) 40 | 41 | GR_PYBIND_MAKE_OOT(mesa 42 | ../.. 43 | gr::mesa 44 | "${mesa_python_files}") 45 | 46 | install(TARGETS mesa_python DESTINATION ${GR_PYTHON_DIR}/mesa COMPONENT pythonapi) 47 | -------------------------------------------------------------------------------- /python/bindings/LongTermIntegrator_python.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * SPDX-License-Identifier: GPL-3.0-or-later 7 | * 8 | */ 9 | 10 | /***********************************************************************************/ 11 | /* This file is automatically generated using bindtool and can be manually edited */ 12 | /* The following lines can be configured to regenerate this file during cmake */ 13 | /* If manual edits are made, the following tags should be modified accordingly. */ 14 | /* BINDTOOL_GEN_AUTOMATIC(0) */ 15 | /* BINDTOOL_USE_PYGCCXML(0) */ 16 | /* BINDTOOL_HEADER_FILE(LongTermIntegrator.h) */ 17 | /* BINDTOOL_HEADER_FILE_HASH(cc1d80f3c52ba213403f0111cc430f64) */ 18 | /***********************************************************************************/ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | namespace py = pybind11; 25 | 26 | #include 27 | // pydoc.h is automatically generated in the build directory 28 | #include 29 | 30 | void bind_LongTermIntegrator(py::module& m) 31 | { 32 | 33 | using LongTermIntegrator = ::gr::mesa::LongTermIntegrator; 34 | 35 | 36 | py::class_>(m, "LongTermIntegrator", D(LongTermIntegrator)) 38 | 39 | .def(py::init(&LongTermIntegrator::make), 40 | py::arg("fftsize"), 41 | py::arg("normalize"), 42 | D(LongTermIntegrator,make) 43 | ) 44 | 45 | 46 | 47 | 48 | 49 | 50 | .def("reset",&LongTermIntegrator::reset, 51 | py::arg("bReset"), 52 | D(LongTermIntegrator,reset) 53 | ) 54 | 55 | ; 56 | 57 | 58 | 59 | 60 | } 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /python/bindings/MaxPower_python.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * SPDX-License-Identifier: GPL-3.0-or-later 7 | * 8 | */ 9 | 10 | /***********************************************************************************/ 11 | /* This file is automatically generated using bindtool and can be manually edited */ 12 | /* The following lines can be configured to regenerate this file during cmake */ 13 | /* If manual edits are made, the following tags should be modified accordingly. */ 14 | /* BINDTOOL_GEN_AUTOMATIC(0) */ 15 | /* BINDTOOL_USE_PYGCCXML(0) */ 16 | /* BINDTOOL_HEADER_FILE(MaxPower.h) */ 17 | /* BINDTOOL_HEADER_FILE_HASH(5f7a34f1d501784d21e92145169c2c90) */ 18 | /***********************************************************************************/ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | namespace py = pybind11; 25 | 26 | #include 27 | // pydoc.h is automatically generated in the build directory 28 | #include 29 | 30 | void bind_MaxPower(py::module& m) 31 | { 32 | 33 | using MaxPower = ::gr::mesa::MaxPower; 34 | 35 | 36 | py::class_>(m, "MaxPower", D(MaxPower)) 38 | 39 | .def(py::init(&MaxPower::make), 40 | py::arg("sampleRate"), 41 | py::arg("fft_size"), 42 | py::arg("squelchThreshold"), 43 | py::arg("framesToAvg"), 44 | py::arg("produceOut"), 45 | py::arg("stateThreshold"), 46 | py::arg("holdUpSec"), 47 | D(MaxPower,make) 48 | ) 49 | 50 | 51 | 52 | 53 | 54 | 55 | .def("getSquelchThreshold",&MaxPower::getSquelchThreshold, 56 | D(MaxPower,getSquelchThreshold) 57 | ) 58 | 59 | 60 | 61 | .def("setSquelchThreshold",&MaxPower::setSquelchThreshold, 62 | py::arg("newValue"), 63 | D(MaxPower,setSquelchThreshold) 64 | ) 65 | 66 | 67 | 68 | .def("getStateThreshold",&MaxPower::getStateThreshold, 69 | D(MaxPower,getStateThreshold) 70 | ) 71 | 72 | 73 | 74 | .def("setStateThreshold",&MaxPower::setStateThreshold, 75 | py::arg("newValue"), 76 | D(MaxPower,setStateThreshold) 77 | ) 78 | 79 | 80 | 81 | .def("getHoldTime",&MaxPower::getHoldTime, 82 | D(MaxPower,getHoldTime) 83 | ) 84 | 85 | 86 | 87 | .def("setHoldTime",&MaxPower::setHoldTime, 88 | py::arg("newValue"), 89 | D(MaxPower,setHoldTime) 90 | ) 91 | 92 | ; 93 | 94 | 95 | 96 | 97 | } 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /python/bindings/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostop14/gr-mesa/1840556948343d2398721f1bd23c1f42b389f136/python/bindings/README.md -------------------------------------------------------------------------------- /python/bindings/SignalDetector_python.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * SPDX-License-Identifier: GPL-3.0-or-later 7 | * 8 | */ 9 | 10 | /***********************************************************************************/ 11 | /* This file is automatically generated using bindtool and can be manually edited */ 12 | /* The following lines can be configured to regenerate this file during cmake */ 13 | /* If manual edits are made, the following tags should be modified accordingly. */ 14 | /* BINDTOOL_GEN_AUTOMATIC(0) */ 15 | /* BINDTOOL_USE_PYGCCXML(0) */ 16 | /* BINDTOOL_HEADER_FILE(SignalDetector.h) */ 17 | /* BINDTOOL_HEADER_FILE_HASH(9a98e56807078028380bac28f4ca4f2a) */ 18 | /***********************************************************************************/ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | namespace py = pybind11; 25 | 26 | #include 27 | // pydoc.h is automatically generated in the build directory 28 | #include 29 | 30 | void bind_SignalDetector(py::module& m) 31 | { 32 | 33 | using SignalDetector = ::gr::mesa::SignalDetector; 34 | 35 | 36 | py::class_>(m, "SignalDetector", D(SignalDetector)) 38 | 39 | .def(py::init(&SignalDetector::make), 40 | py::arg("fftsize"), 41 | py::arg("squelchThreshold"), 42 | py::arg("minWidthHz"), 43 | py::arg("maxWidthHz"), 44 | py::arg("radioCenterFreq"), 45 | py::arg("sampleRate"), 46 | py::arg("holdUpSec"), 47 | py::arg("framesToAvg"), 48 | py::arg("genSignalPDUs"), 49 | py::arg("enableDebug"), 50 | py::arg("detectionMethod"), 51 | D(SignalDetector,make) 52 | ) 53 | 54 | 55 | 56 | 57 | 58 | 59 | .def("getSquelch",&SignalDetector::getSquelch, 60 | D(SignalDetector,getSquelch) 61 | ) 62 | 63 | 64 | 65 | .def("setSquelch",&SignalDetector::setSquelch, 66 | py::arg("newValue"), 67 | D(SignalDetector,setSquelch) 68 | ) 69 | 70 | 71 | 72 | .def("getCenterFrequency",&SignalDetector::getCenterFrequency, 73 | D(SignalDetector,getCenterFrequency) 74 | ) 75 | 76 | 77 | 78 | .def("setCenterFrequency",&SignalDetector::setCenterFrequency, 79 | py::arg("newValue"), 80 | D(SignalDetector,setCenterFrequency) 81 | ) 82 | 83 | 84 | 85 | .def("getMinWidthHz",&SignalDetector::getMinWidthHz, 86 | D(SignalDetector,getMinWidthHz) 87 | ) 88 | 89 | 90 | 91 | .def("setMinWidthHz",&SignalDetector::setMinWidthHz, 92 | py::arg("newValue"), 93 | D(SignalDetector,setMinWidthHz) 94 | ) 95 | 96 | 97 | 98 | .def("getMaxWidthHz",&SignalDetector::getMaxWidthHz, 99 | D(SignalDetector,getMaxWidthHz) 100 | ) 101 | 102 | 103 | 104 | .def("setMaxWidthHz",&SignalDetector::setMaxWidthHz, 105 | py::arg("newValue"), 106 | D(SignalDetector,setMaxWidthHz) 107 | ) 108 | 109 | ; 110 | 111 | 112 | 113 | 114 | } 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /python/bindings/SourceSelector_python.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * SPDX-License-Identifier: GPL-3.0-or-later 7 | * 8 | */ 9 | 10 | /***********************************************************************************/ 11 | /* This file is automatically generated using bindtool and can be manually edited */ 12 | /* The following lines can be configured to regenerate this file during cmake */ 13 | /* If manual edits are made, the following tags should be modified accordingly. */ 14 | /* BINDTOOL_GEN_AUTOMATIC(0) */ 15 | /* BINDTOOL_USE_PYGCCXML(0) */ 16 | /* BINDTOOL_HEADER_FILE(SourceSelector.h) */ 17 | /* BINDTOOL_HEADER_FILE_HASH(89d4a400cef004091084cf7f4bdcfea5) */ 18 | /***********************************************************************************/ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | namespace py = pybind11; 25 | 26 | #include 27 | // pydoc.h is automatically generated in the build directory 28 | #include 29 | 30 | void bind_SourceSelector(py::module& m) 31 | { 32 | 33 | using SourceSelector = ::gr::mesa::SourceSelector; 34 | 35 | 36 | py::class_>(m, "SourceSelector", D(SourceSelector)) 38 | 39 | .def(py::init(&SourceSelector::make), 40 | py::arg("holdTime"), 41 | py::arg("numInputs"), 42 | py::arg("defaultInput"), 43 | py::arg("inputBlockSize"), 44 | D(SourceSelector,make) 45 | ) 46 | 47 | 48 | 49 | 50 | ; 51 | 52 | 53 | 54 | 55 | } 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /python/bindings/bind_oot_file.py: -------------------------------------------------------------------------------- 1 | import warnings 2 | import argparse 3 | import os 4 | from gnuradio.bindtool import BindingGenerator 5 | import pathlib 6 | import sys 7 | 8 | parser = argparse.ArgumentParser(description='Bind a GR Out of Tree Block') 9 | parser.add_argument('--module', type=str, 10 | help='Name of gr module containing file to bind (e.g. fft digital analog)') 11 | 12 | parser.add_argument('--output_dir', default='/tmp', 13 | help='Output directory of generated bindings') 14 | parser.add_argument('--prefix', help='Prefix of Installed GNU Radio') 15 | parser.add_argument('--src', help='Directory of gnuradio source tree', 16 | default=os.path.dirname(os.path.abspath(__file__))+'/../../..') 17 | 18 | parser.add_argument( 19 | '--filename', help="File to be parsed") 20 | 21 | parser.add_argument( 22 | '--defines', help='Set additional defines for precompiler',default=(), nargs='*') 23 | parser.add_argument( 24 | '--include', help='Additional Include Dirs, separated', default=(), nargs='*') 25 | 26 | parser.add_argument( 27 | '--status', help='Location of output file for general status (used during cmake)', default=None 28 | ) 29 | parser.add_argument( 30 | '--flag_automatic', default='0' 31 | ) 32 | parser.add_argument( 33 | '--flag_pygccxml', default='0' 34 | ) 35 | 36 | args = parser.parse_args() 37 | 38 | prefix = args.prefix 39 | output_dir = args.output_dir 40 | defines = tuple(','.join(args.defines).split(',')) 41 | includes = ','.join(args.include) 42 | name = args.module 43 | 44 | namespace = ['gr', name] 45 | prefix_include_root = name 46 | 47 | 48 | with warnings.catch_warnings(): 49 | warnings.filterwarnings("ignore", category=DeprecationWarning) 50 | 51 | bg = BindingGenerator(prefix, namespace, 52 | prefix_include_root, output_dir, define_symbols=defines, addl_includes=includes, 53 | catch_exceptions=False, write_json_output=False, status_output=args.status, 54 | flag_automatic=True if args.flag_automatic.lower() in [ 55 | '1', 'true'] else False, 56 | flag_pygccxml=True if args.flag_pygccxml.lower() in ['1', 'true'] else False) 57 | bg.gen_file_binding(args.filename) 58 | -------------------------------------------------------------------------------- /python/bindings/docstrings/AutoDopplerCorrect_pydoc_template.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * SPDX-License-Identifier: GPL-3.0-or-later 7 | * 8 | */ 9 | #include "pydoc_macros.h" 10 | #define D(...) DOC(gr,mesa, __VA_ARGS__ ) 11 | /* 12 | This file contains placeholders for docstrings for the Python bindings. 13 | Do not edit! These were automatically extracted during the binding process 14 | and will be overwritten during the build process 15 | */ 16 | 17 | 18 | 19 | static const char *__doc_gr_mesa_AutoDopplerCorrect = R"doc()doc"; 20 | 21 | 22 | static const char *__doc_gr_mesa_AutoDopplerCorrect_AutoDopplerCorrect_0 = R"doc()doc"; 23 | 24 | 25 | static const char *__doc_gr_mesa_AutoDopplerCorrect_AutoDopplerCorrect_1 = R"doc()doc"; 26 | 27 | 28 | static const char *__doc_gr_mesa_AutoDopplerCorrect_make = R"doc()doc"; 29 | 30 | 31 | static const char *__doc_gr_mesa_AutoDopplerCorrect_getSquelch = R"doc()doc"; 32 | 33 | 34 | static const char *__doc_gr_mesa_AutoDopplerCorrect_setSquelch = R"doc()doc"; 35 | 36 | 37 | static const char *__doc_gr_mesa_AutoDopplerCorrect_getCenterFrequency = R"doc()doc"; 38 | 39 | 40 | static const char *__doc_gr_mesa_AutoDopplerCorrect_setCenterFrequency = R"doc()doc"; 41 | 42 | 43 | static const char *__doc_gr_mesa_AutoDopplerCorrect_getMinWidthHz = R"doc()doc"; 44 | 45 | 46 | static const char *__doc_gr_mesa_AutoDopplerCorrect_setMinWidthHz = R"doc()doc"; 47 | 48 | 49 | static const char *__doc_gr_mesa_AutoDopplerCorrect_getExpectedWidth = R"doc()doc"; 50 | 51 | 52 | static const char *__doc_gr_mesa_AutoDopplerCorrect_setExpectedWidth = R"doc()doc"; 53 | 54 | 55 | static const char *__doc_gr_mesa_AutoDopplerCorrect_getMaxDrift = R"doc()doc"; 56 | 57 | 58 | static const char *__doc_gr_mesa_AutoDopplerCorrect_setMaxDrift = R"doc()doc"; 59 | 60 | 61 | -------------------------------------------------------------------------------- /python/bindings/docstrings/AvgToMsg_pydoc_template.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * SPDX-License-Identifier: GPL-3.0-or-later 7 | * 8 | */ 9 | #include "pydoc_macros.h" 10 | #define D(...) DOC(gr,mesa, __VA_ARGS__ ) 11 | /* 12 | This file contains placeholders for docstrings for the Python bindings. 13 | Do not edit! These were automatically extracted during the binding process 14 | and will be overwritten during the build process 15 | */ 16 | 17 | 18 | 19 | static const char *__doc_gr_mesa_AvgToMsg = R"doc()doc"; 20 | 21 | 22 | static const char *__doc_gr_mesa_AvgToMsg_AvgToMsg_0 = R"doc()doc"; 23 | 24 | 25 | static const char *__doc_gr_mesa_AvgToMsg_AvgToMsg_1 = R"doc()doc"; 26 | 27 | 28 | static const char *__doc_gr_mesa_AvgToMsg_make = R"doc()doc"; 29 | 30 | 31 | static const char *__doc_gr_mesa_AvgToMsg_setHold = R"doc()doc"; 32 | 33 | 34 | -------------------------------------------------------------------------------- /python/bindings/docstrings/LongTermIntegrator_pydoc_template.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * SPDX-License-Identifier: GPL-3.0-or-later 7 | * 8 | */ 9 | #include "pydoc_macros.h" 10 | #define D(...) DOC(gr,mesa, __VA_ARGS__ ) 11 | /* 12 | This file contains placeholders for docstrings for the Python bindings. 13 | Do not edit! These were automatically extracted during the binding process 14 | and will be overwritten during the build process 15 | */ 16 | 17 | 18 | 19 | static const char *__doc_gr_mesa_LongTermIntegrator = R"doc()doc"; 20 | 21 | 22 | static const char *__doc_gr_mesa_LongTermIntegrator_LongTermIntegrator_0 = R"doc()doc"; 23 | 24 | 25 | static const char *__doc_gr_mesa_LongTermIntegrator_LongTermIntegrator_1 = R"doc()doc"; 26 | 27 | 28 | static const char *__doc_gr_mesa_LongTermIntegrator_make = R"doc()doc"; 29 | 30 | 31 | static const char *__doc_gr_mesa_LongTermIntegrator_reset = R"doc()doc"; 32 | 33 | 34 | -------------------------------------------------------------------------------- /python/bindings/docstrings/MaxPower_pydoc_template.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * SPDX-License-Identifier: GPL-3.0-or-later 7 | * 8 | */ 9 | #include "pydoc_macros.h" 10 | #define D(...) DOC(gr,mesa, __VA_ARGS__ ) 11 | /* 12 | This file contains placeholders for docstrings for the Python bindings. 13 | Do not edit! These were automatically extracted during the binding process 14 | and will be overwritten during the build process 15 | */ 16 | 17 | 18 | 19 | static const char *__doc_gr_mesa_MaxPower = R"doc()doc"; 20 | 21 | 22 | static const char *__doc_gr_mesa_MaxPower_MaxPower_0 = R"doc()doc"; 23 | 24 | 25 | static const char *__doc_gr_mesa_MaxPower_MaxPower_1 = R"doc()doc"; 26 | 27 | 28 | static const char *__doc_gr_mesa_MaxPower_make = R"doc()doc"; 29 | 30 | 31 | static const char *__doc_gr_mesa_MaxPower_getSquelchThreshold = R"doc()doc"; 32 | 33 | 34 | static const char *__doc_gr_mesa_MaxPower_setSquelchThreshold = R"doc()doc"; 35 | 36 | 37 | static const char *__doc_gr_mesa_MaxPower_getStateThreshold = R"doc()doc"; 38 | 39 | 40 | static const char *__doc_gr_mesa_MaxPower_setStateThreshold = R"doc()doc"; 41 | 42 | 43 | static const char *__doc_gr_mesa_MaxPower_getHoldTime = R"doc()doc"; 44 | 45 | 46 | static const char *__doc_gr_mesa_MaxPower_setHoldTime = R"doc()doc"; 47 | 48 | 49 | -------------------------------------------------------------------------------- /python/bindings/docstrings/README.md: -------------------------------------------------------------------------------- 1 | This directory stores templates for docstrings that are scraped from the include header files for each block -------------------------------------------------------------------------------- /python/bindings/docstrings/SignalDetector_pydoc_template.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * SPDX-License-Identifier: GPL-3.0-or-later 7 | * 8 | */ 9 | #include "pydoc_macros.h" 10 | #define D(...) DOC(gr,mesa, __VA_ARGS__ ) 11 | /* 12 | This file contains placeholders for docstrings for the Python bindings. 13 | Do not edit! These were automatically extracted during the binding process 14 | and will be overwritten during the build process 15 | */ 16 | 17 | 18 | 19 | static const char *__doc_gr_mesa_SignalDetector = R"doc()doc"; 20 | 21 | 22 | static const char *__doc_gr_mesa_SignalDetector_SignalDetector_0 = R"doc()doc"; 23 | 24 | 25 | static const char *__doc_gr_mesa_SignalDetector_SignalDetector_1 = R"doc()doc"; 26 | 27 | 28 | static const char *__doc_gr_mesa_SignalDetector_make = R"doc()doc"; 29 | 30 | 31 | static const char *__doc_gr_mesa_SignalDetector_getSquelch = R"doc()doc"; 32 | 33 | 34 | static const char *__doc_gr_mesa_SignalDetector_setSquelch = R"doc()doc"; 35 | 36 | 37 | static const char *__doc_gr_mesa_SignalDetector_getCenterFrequency = R"doc()doc"; 38 | 39 | 40 | static const char *__doc_gr_mesa_SignalDetector_setCenterFrequency = R"doc()doc"; 41 | 42 | 43 | static const char *__doc_gr_mesa_SignalDetector_getMinWidthHz = R"doc()doc"; 44 | 45 | 46 | static const char *__doc_gr_mesa_SignalDetector_setMinWidthHz = R"doc()doc"; 47 | 48 | 49 | static const char *__doc_gr_mesa_SignalDetector_getMaxWidthHz = R"doc()doc"; 50 | 51 | 52 | static const char *__doc_gr_mesa_SignalDetector_setMaxWidthHz = R"doc()doc"; 53 | 54 | 55 | -------------------------------------------------------------------------------- /python/bindings/docstrings/SourceSelector_pydoc_template.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * SPDX-License-Identifier: GPL-3.0-or-later 7 | * 8 | */ 9 | #include "pydoc_macros.h" 10 | #define D(...) DOC(gr,mesa, __VA_ARGS__ ) 11 | /* 12 | This file contains placeholders for docstrings for the Python bindings. 13 | Do not edit! These were automatically extracted during the binding process 14 | and will be overwritten during the build process 15 | */ 16 | 17 | 18 | 19 | static const char *__doc_gr_mesa_SourceSelector = R"doc()doc"; 20 | 21 | 22 | static const char *__doc_gr_mesa_SourceSelector_SourceSelector = R"doc()doc"; 23 | 24 | 25 | static const char *__doc_gr_mesa_SourceSelector_make = R"doc()doc"; 26 | 27 | 28 | -------------------------------------------------------------------------------- /python/bindings/docstrings/ioselector_pydoc_template.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * SPDX-License-Identifier: GPL-3.0-or-later 7 | * 8 | */ 9 | #include "pydoc_macros.h" 10 | #define D(...) DOC(gr,mesa, __VA_ARGS__ ) 11 | /* 12 | This file contains placeholders for docstrings for the Python bindings. 13 | Do not edit! These were automatically extracted during the binding process 14 | and will be overwritten during the build process 15 | */ 16 | 17 | 18 | 19 | static const char *__doc_gr_mesa_ioselector = R"doc()doc"; 20 | 21 | 22 | static const char *__doc_gr_mesa_ioselector_ioselector_0 = R"doc()doc"; 23 | 24 | 25 | static const char *__doc_gr_mesa_ioselector_ioselector_1 = R"doc()doc"; 26 | 27 | 28 | static const char *__doc_gr_mesa_ioselector_make = R"doc()doc"; 29 | 30 | 31 | static const char *__doc_gr_mesa_ioselector_set_input_index = R"doc()doc"; 32 | 33 | 34 | static const char *__doc_gr_mesa_ioselector_set_output_index = R"doc()doc"; 35 | 36 | 37 | -------------------------------------------------------------------------------- /python/bindings/docstrings/phase_shift_pydoc_template.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * SPDX-License-Identifier: GPL-3.0-or-later 7 | * 8 | */ 9 | #include "pydoc_macros.h" 10 | #define D(...) DOC(gr,mesa, __VA_ARGS__ ) 11 | /* 12 | This file contains placeholders for docstrings for the Python bindings. 13 | Do not edit! These were automatically extracted during the binding process 14 | and will be overwritten during the build process 15 | */ 16 | 17 | 18 | 19 | static const char *__doc_gr_mesa_phase_shift = R"doc()doc"; 20 | 21 | 22 | static const char *__doc_gr_mesa_phase_shift_phase_shift_0 = R"doc()doc"; 23 | 24 | 25 | static const char *__doc_gr_mesa_phase_shift_phase_shift_1 = R"doc()doc"; 26 | 27 | 28 | static const char *__doc_gr_mesa_phase_shift_make = R"doc()doc"; 29 | 30 | 31 | static const char *__doc_gr_mesa_phase_shift_get_shift = R"doc()doc"; 32 | 33 | 34 | static const char *__doc_gr_mesa_phase_shift_set_shift = R"doc()doc"; 35 | 36 | 37 | -------------------------------------------------------------------------------- /python/bindings/header_utils.py: -------------------------------------------------------------------------------- 1 | # Utilities for reading values in header files 2 | 3 | from argparse import ArgumentParser 4 | import re 5 | 6 | 7 | class PybindHeaderParser: 8 | def __init__(self, pathname): 9 | with open(pathname,'r') as f: 10 | self.file_txt = f.read() 11 | 12 | def get_flag_automatic(self): 13 | # p = re.compile(r'BINDTOOL_GEN_AUTOMATIC\(([^\s])\)') 14 | # m = p.search(self.file_txt) 15 | m = re.search(r'BINDTOOL_GEN_AUTOMATIC\(([^\s])\)', self.file_txt) 16 | if (m and m.group(1) == '1'): 17 | return True 18 | else: 19 | return False 20 | 21 | def get_flag_pygccxml(self): 22 | # p = re.compile(r'BINDTOOL_USE_PYGCCXML\(([^\s])\)') 23 | # m = p.search(self.file_txt) 24 | m = re.search(r'BINDTOOL_USE_PYGCCXML\(([^\s])\)', self.file_txt) 25 | if (m and m.group(1) == '1'): 26 | return True 27 | else: 28 | return False 29 | 30 | def get_header_filename(self): 31 | # p = re.compile(r'BINDTOOL_HEADER_FILE\(([^\s]*)\)') 32 | # m = p.search(self.file_txt) 33 | m = re.search(r'BINDTOOL_HEADER_FILE\(([^\s]*)\)', self.file_txt) 34 | if (m): 35 | return m.group(1) 36 | else: 37 | return None 38 | 39 | def get_header_file_hash(self): 40 | # p = re.compile(r'BINDTOOL_HEADER_FILE_HASH\(([^\s]*)\)') 41 | # m = p.search(self.file_txt) 42 | m = re.search(r'BINDTOOL_HEADER_FILE_HASH\(([^\s]*)\)', self.file_txt) 43 | if (m): 44 | return m.group(1) 45 | else: 46 | return None 47 | 48 | def get_flags(self): 49 | return f'{self.get_flag_automatic()};{self.get_flag_pygccxml()};{self.get_header_filename()};{self.get_header_file_hash()};' 50 | 51 | 52 | 53 | def argParse(): 54 | """Parses commandline args.""" 55 | desc='Reads the parameters from the comment block in the pybind files' 56 | parser = ArgumentParser(description=desc) 57 | 58 | parser.add_argument("function", help="Operation to perform on comment block of pybind file", choices=["flag_auto","flag_pygccxml","header_filename","header_file_hash","all"]) 59 | parser.add_argument("pathname", help="Pathname of pybind c++ file to read, e.g. blockname_python.cc") 60 | 61 | return parser.parse_args() 62 | 63 | if __name__ == "__main__": 64 | # Parse command line options and set up doxyxml. 65 | args = argParse() 66 | 67 | pbhp = PybindHeaderParser(args.pathname) 68 | 69 | if args.function == "flag_auto": 70 | print(pbhp.get_flag_automatic()) 71 | elif args.function == "flag_pygccxml": 72 | print(pbhp.get_flag_pygccxml()) 73 | elif args.function == "header_filename": 74 | print(pbhp.get_header_filename()) 75 | elif args.function == "header_file_hash": 76 | print(pbhp.get_header_file_hash()) 77 | elif args.function == "all": 78 | print(pbhp.get_flags()) -------------------------------------------------------------------------------- /python/bindings/ioselector_python.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * SPDX-License-Identifier: GPL-3.0-or-later 7 | * 8 | */ 9 | 10 | /***********************************************************************************/ 11 | /* This file is automatically generated using bindtool and can be manually edited */ 12 | /* The following lines can be configured to regenerate this file during cmake */ 13 | /* If manual edits are made, the following tags should be modified accordingly. */ 14 | /* BINDTOOL_GEN_AUTOMATIC(0) */ 15 | /* BINDTOOL_USE_PYGCCXML(0) */ 16 | /* BINDTOOL_HEADER_FILE(ioselector.h) */ 17 | /* BINDTOOL_HEADER_FILE_HASH(88a896322737bf0a21bf316fa6f8565e) */ 18 | /***********************************************************************************/ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | namespace py = pybind11; 25 | 26 | #include 27 | // pydoc.h is automatically generated in the build directory 28 | #include 29 | 30 | void bind_ioselector(py::module& m) 31 | { 32 | 33 | using ioselector = ::gr::mesa::ioselector; 34 | 35 | 36 | py::class_>(m, "ioselector", D(ioselector)) 38 | 39 | .def(py::init(&ioselector::make), 40 | py::arg("numinputs"), 41 | py::arg("numoutputs"), 42 | py::arg("inputport"), 43 | py::arg("outputport"), 44 | py::arg("itemsize"), 45 | D(ioselector,make) 46 | ) 47 | 48 | 49 | 50 | 51 | 52 | 53 | .def("set_input_index",&ioselector::set_input_index, 54 | py::arg("newValue"), 55 | D(ioselector,set_input_index) 56 | ) 57 | 58 | 59 | 60 | .def("set_output_index",&ioselector::set_output_index, 61 | py::arg("newValue"), 62 | D(ioselector,set_output_index) 63 | ) 64 | 65 | ; 66 | 67 | 68 | 69 | 70 | } 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /python/bindings/phase_shift_python.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * SPDX-License-Identifier: GPL-3.0-or-later 7 | * 8 | */ 9 | 10 | /***********************************************************************************/ 11 | /* This file is automatically generated using bindtool and can be manually edited */ 12 | /* The following lines can be configured to regenerate this file during cmake */ 13 | /* If manual edits are made, the following tags should be modified accordingly. */ 14 | /* BINDTOOL_GEN_AUTOMATIC(0) */ 15 | /* BINDTOOL_USE_PYGCCXML(0) */ 16 | /* BINDTOOL_HEADER_FILE(phase_shift.h) */ 17 | /* BINDTOOL_HEADER_FILE_HASH(1860b0052b1f30793f3deceebaf479d6) */ 18 | /***********************************************************************************/ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | namespace py = pybind11; 25 | 26 | #include 27 | // pydoc.h is automatically generated in the build directory 28 | #include 29 | 30 | void bind_phase_shift(py::module& m) 31 | { 32 | 33 | using phase_shift = ::gr::mesa::phase_shift; 34 | 35 | 36 | py::class_>(m, "phase_shift", D(phase_shift)) 38 | 39 | .def(py::init(&phase_shift::make), 40 | py::arg("shift_in_radians"), 41 | D(phase_shift,make) 42 | ) 43 | 44 | 45 | 46 | 47 | 48 | 49 | .def("get_shift",&phase_shift::get_shift, 50 | D(phase_shift,get_shift) 51 | ) 52 | 53 | 54 | 55 | .def("set_shift",&phase_shift::set_shift, 56 | py::arg("newValue"), 57 | D(phase_shift,set_shift) 58 | ) 59 | 60 | ; 61 | 62 | 63 | 64 | 65 | } 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /python/bindings/python_bindings.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Free Software Foundation, Inc. 3 | * 4 | * This file is part of GNU Radio 5 | * 6 | * SPDX-License-Identifier: GPL-3.0-or-later 7 | * 8 | */ 9 | 10 | #include 11 | 12 | #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION 13 | #include 14 | 15 | namespace py = pybind11; 16 | 17 | // Headers for binding functions 18 | /**************************************/ 19 | /* The following comment block is used for 20 | /* gr_modtool to insert function prototypes 21 | /* Please do not delete 22 | /**************************************/ 23 | // BINDING_FUNCTION_PROTOTYPES( 24 | void bind_AutoDopplerCorrect(py::module& m); 25 | void bind_AvgToMsg(py::module& m); 26 | void bind_ioselector(py::module& m); 27 | void bind_LongTermIntegrator(py::module& m); 28 | void bind_MaxPower(py::module& m); 29 | void bind_phase_shift(py::module& m); 30 | void bind_SignalDetector(py::module& m); 31 | void bind_SourceSelector(py::module& m); 32 | // ) END BINDING_FUNCTION_PROTOTYPES 33 | 34 | 35 | // We need this hack because import_array() returns NULL 36 | // for newer Python versions. 37 | // This function is also necessary because it ensures access to the C API 38 | // and removes a warning. 39 | void* init_numpy() 40 | { 41 | import_array(); 42 | return NULL; 43 | } 44 | 45 | PYBIND11_MODULE(mesa_python, m) 46 | { 47 | // Initialize the numpy C API 48 | // (otherwise we will see segmentation faults) 49 | init_numpy(); 50 | 51 | // Allow access to base block methods 52 | py::module::import("gnuradio.gr"); 53 | 54 | /**************************************/ 55 | /* The following comment block is used for 56 | /* gr_modtool to insert binding function calls 57 | /* Please do not delete 58 | /**************************************/ 59 | // BINDING_FUNCTION_CALLS( 60 | bind_AutoDopplerCorrect(m); 61 | bind_AvgToMsg(m); 62 | bind_ioselector(m); 63 | bind_LongTermIntegrator(m); 64 | bind_MaxPower(m); 65 | bind_phase_shift(m); 66 | bind_SignalDetector(m); 67 | bind_SourceSelector(m); 68 | // ) END BINDING_FUNCTION_CALLS 69 | } --------------------------------------------------------------------------------