Compare commits

..

11 Commits
dev ... gr-3.8

  1. 1
      .gitignore
  2. 70
      CMakeLists.txt
  3. 8937
      apps/fft-multi-decoder_fixed_dual-rtlsdr.grc
  4. 4
      apps/fft-multi-decoder_fixed_rtlsdr.grc
  5. 4556
      apps/ifft-RDS-decoder_hier-block.grc
  6. 1005
      apps/read_sync_decim.grc
  7. 4
      cmake/Modules/.directory
  8. 2
      cmake/Modules/CMakeParseArgumentsCopy.cmake
  9. 36
      cmake/Modules/FindGnuradioRuntime.cmake
  10. 528
      cmake/Modules/GrMiscUtils.cmake
  11. 54
      cmake/Modules/GrPlatform.cmake
  12. 241
      cmake/Modules/GrPython.cmake
  13. 251
      cmake/Modules/GrSwig.cmake
  14. 143
      cmake/Modules/GrTest.cmake
  15. 304
      cmake/Modules/UseSWIG.cmake
  16. 5
      cmake/Modules/multirdsConfig.cmake
  17. 28
      grc/CMakeLists.txt
  18. 25
      grc/multirds_decoder_compare.block.yml
  19. 28
      grc/multirds_decoder_compare.xml
  20. 57
      grc/multirds_pilot_SNR.block.yml
  21. 84
      grc/multirds_pilot_SNR.xml
  22. 136
      grc/multirds_qtgui_range.xml
  23. 32
      grc/multirds_rds_decoder.block.yml
  24. 45
      grc/multirds_rds_decoder.xml
  25. 32
      grc/multirds_rds_decoder_redsea.block.yml
  26. 45
      grc/multirds_rds_decoder_redsea.xml
  27. 96
      grc/multirds_rds_parser_table_qt.block.yml
  28. 141
      grc/multirds_rds_parser_table_qt.xml
  29. 37
      grc/multirds_rds_table_qt.block.yml
  30. 46
      grc/multirds_rds_table_qt.xml
  31. 52
      grc/multirds_station_search.block.yml
  32. 78
      grc/multirds_station_search.xml
  33. 29
      grc/multirds_stream_router.block.yml
  34. 54
      grc/multirds_stream_router.xml
  35. 30
      grc/multirds_stream_selector.block.yml
  36. 38
      grc/multirds_stream_selector.xml
  37. 30
      grc/multirds_symbol_combiner.block.yml
  38. 70
      grc/multirds_symbol_combiner.xml
  39. 62
      grc/multirds_tmc_parser.block.yml
  40. 112
      grc/multirds_tmc_parser.xml
  41. 37
      grc/multirds_variable_setter.block.yml
  42. 59
      grc/multirds_variable_setter.xml
  43. 55
      grc/multirds_vector_cutter.block.yml
  44. 87
      grc/multirds_vector_cutter.xml
  45. 4
      python/CMakeLists.txt
  46. 25
      python/__init__.py
  47. 226
      python/build_utils.py
  48. 52
      python/build_utils_codes.py
  49. 2
      python/chart.py
  50. 4
      python/decoder_compare.py
  51. 2
      python/qa_rds_parser_table_qt.py
  52. 2
      python/qa_tmc_parser.py
  53. 279
      python/qtgui_range.py
  54. 176
      python/rds_parser_table_qt.py
  55. 8
      python/rds_table_qt.py
  56. 2
      python/station_search.py
  57. 2
      python/stream_selector.py
  58. 13
      python/tmc_classes.py
  59. 8
      python/tmc_parser.py
  60. 105
      python/top_block.py
  61. 2
      python/variable_setter.py
  62. 4
      python/vector_cutter.py

1
.gitignore vendored

@ -6,3 +6,4 @@ apps/*.pyc
build-manlap
*.bak
directory_writable
data/LCL

70
CMakeLists.txt

@ -24,7 +24,7 @@ add_definitions(-std=c++11)
########################################################################
# Project setup
########################################################################
cmake_minimum_required(VERSION 2.6)
cmake_minimum_required(VERSION 3.8)
project(gr-multirds CXX C)
enable_testing()
@ -53,11 +53,33 @@ set(VERSION_INFO_MAINT_VERSION git)
########################################################################
# Compiler specific setup
########################################################################
if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32)
if((CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR
CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
AND NOT WIN32)
#http://gcc.gnu.org/wiki/Visibility
add_definitions(-fvisibility=hidden)
endif()
IF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
SET(CMAKE_CXX_STANDARD 11)
ELSEIF(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
SET(CMAKE_CXX_STANDARD 11)
ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
SET(CMAKE_CXX_STANDARD 11)
ELSE()
message(WARNING "C++ standard could not be set because compiler is not GNU, Clang or MSVC.")
ENDIF()
IF(CMAKE_C_COMPILER_ID STREQUAL "GNU")
SET(CMAKE_C_STANDARD 11)
ELSEIF(CMAKE_C_COMPILER_ID MATCHES "Clang")
SET(CMAKE_C_STANDARD 11)
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
SET(CMAKE_C_STANDARD 11)
ELSE()
message(WARNING "C standard could not be set because compiler is not GNU, Clang or MSVC.")
ENDIF()
########################################################################
# Find boost
########################################################################
@ -82,19 +104,21 @@ endif()
########################################################################
# Install directories
########################################################################
find_package(Gnuradio "3.8" REQUIRED)
include(GrVersion)
include(GrPlatform) #define LIB_SUFFIX
set(GR_RUNTIME_DIR bin)
set(GR_LIBRARY_DIR lib${LIB_SUFFIX})
if(NOT CMAKE_MODULES_DIR)
set(CMAKE_MODULES_DIR lib${LIB_SUFFIX}/cmake)
endif(NOT CMAKE_MODULES_DIR)
set(GR_INCLUDE_DIR include/multirds)
set(GR_DATA_DIR share)
set(GR_CMAKE_DIR ${CMAKE_MODULES_DIR}/multirds)
set(GR_PKG_DATA_DIR ${GR_DATA_DIR}/${CMAKE_PROJECT_NAME})
set(GR_DOC_DIR ${GR_DATA_DIR}/doc)
set(GR_PKG_DOC_DIR ${GR_DOC_DIR}/${CMAKE_PROJECT_NAME})
set(GR_CONF_DIR etc)
set(GR_PKG_CONF_DIR ${GR_CONF_DIR}/${CMAKE_PROJECT_NAME}/conf.d)
set(GR_LIBEXEC_DIR libexec)
set(GR_PKG_LIBEXEC_DIR ${GR_LIBEXEC_DIR}/${CMAKE_PROJECT_NAME})
set(GRC_BLOCKS_DIR ${GR_PKG_DATA_DIR}/grc/blocks)
########################################################################
# On Apple only, set install name and use rpath correctly, if not already set
@ -116,24 +140,12 @@ if(APPLE)
endif(NOT CMAKE_BUILD_WITH_INSTALL_RPATH)
endif(APPLE)
########################################################################
# Find gnuradio build dependencies
########################################################################
find_package(CppUnit)
find_package(Doxygen)
# Search for GNU Radio and its components and versions. Add any
# components required to the list of GR_REQUIRED_COMPONENTS (in all
# caps such as FILTER or FFT) and change the version to the minimum
# API compatible version required.
set(GR_REQUIRED_COMPONENTS RUNTIME)
find_package(Gnuradio "3.7.2" REQUIRED)
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules)
include(GrVersion)
if(NOT CPPUNIT_FOUND)
message(FATAL_ERROR "CppUnit required to compile multirds")
endif()
find_package(CppUnit)
########################################################################
# Setup doxygen option
@ -166,7 +178,6 @@ link_directories(
# Set component parameters
set(GR_MULTIRDS_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include CACHE INTERNAL "" FORCE)
set(GR_MULTIRDS_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/swig CACHE INTERNAL "" FORCE)
########################################################################
# Create uninstall target
########################################################################
@ -177,25 +188,22 @@ configure_file(
add_custom_target(uninstall
${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
)
)
########################################################################
# Add subdirectories
########################################################################
add_subdirectory(include/multirds)
add_subdirectory(lib)
add_subdirectory(apps)
add_subdirectory(docs)
add_subdirectory(swig)
add_subdirectory(python)
add_subdirectory(grc)
add_subdirectory(apps)
add_subdirectory(docs)
########################################################################
# Install cmake search helper for this library
########################################################################
if(NOT CMAKE_MODULES_DIR)
set(CMAKE_MODULES_DIR lib${LIB_SUFFIX}/cmake)
endif(NOT CMAKE_MODULES_DIR)
install(FILES cmake/Modules/multirdsConfig.cmake
DESTINATION ${CMAKE_MODULES_DIR}/multirds

8937
apps/fft-multi-decoder_fixed_dual-rtlsdr.grc

File diff suppressed because it is too large Load Diff

4
apps/fft-multi-decoder_fixed_rtlsdr.grc

@ -2282,7 +2282,7 @@ class blk(gr.sync_block): # other base classes are basic_block, decim_block, in
</param>
<param>
<key>workdir</key>
<value>/media/clemens/intdaten/uni_bulk/forschungsarbeit/data/</value>
<value>/media/clemens/teratemp/tmp/gr-multirds/data/</value>
</param>
<param>
<key>writeDB</key>
@ -2341,7 +2341,7 @@ class blk(gr.sync_block): # other base classes are basic_block, decim_block, in
</param>
<param>
<key>workdir</key>
<value>/media/clemens/intdaten/uni_bulk/forschungsarbeit/data/</value>
<value>/media/clemens/teratemp/tmp/gr-multirds/data/</value>
</param>
<param>
<key>writeDB</key>

4556
apps/ifft-RDS-decoder_hier-block.grc

File diff suppressed because it is too large Load Diff

1005
apps/read_sync_decim.grc

File diff suppressed because it is too large Load Diff

4
cmake/Modules/.directory

@ -1,4 +0,0 @@
[Dolphin]
Timestamp=2016,12,6,13,18,42
Version=3
ViewMode=2

2
cmake/Modules/CMakeParseArgumentsCopy.cmake

@ -58,7 +58,7 @@
# the new option.
# E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in
# MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would
# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor.
# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefore.
#=============================================================================
# Copyright 2010 Alexander Neundorf <neundorf@kde.org>

36
cmake/Modules/FindGnuradioRuntime.cmake

@ -1,36 +0,0 @@
INCLUDE(FindPkgConfig)
PKG_CHECK_MODULES(PC_GNURADIO_RUNTIME gnuradio-runtime)
if(PC_GNURADIO_RUNTIME_FOUND)
# look for include files
FIND_PATH(
GNURADIO_RUNTIME_INCLUDE_DIRS
NAMES gnuradio/top_block.h
HINTS $ENV{GNURADIO_RUNTIME_DIR}/include
${PC_GNURADIO_RUNTIME_INCLUDE_DIRS}
${CMAKE_INSTALL_PREFIX}/include
PATHS /usr/local/include
/usr/include
)
# look for libs
FIND_LIBRARY(
GNURADIO_RUNTIME_LIBRARIES
NAMES gnuradio-runtime
HINTS $ENV{GNURADIO_RUNTIME_DIR}/lib
${PC_GNURADIO_RUNTIME_LIBDIR}
${CMAKE_INSTALL_PREFIX}/lib/
${CMAKE_INSTALL_PREFIX}/lib64/
PATHS /usr/local/lib
/usr/local/lib64
/usr/lib
/usr/lib64
)
set(GNURADIO_RUNTIME_FOUND ${PC_GNURADIO_RUNTIME_FOUND})
endif(PC_GNURADIO_RUNTIME_FOUND)
INCLUDE(FindPackageHandleStandardArgs)
# do not check GNURADIO_RUNTIME_INCLUDE_DIRS, is not set when default include path us used.
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_RUNTIME DEFAULT_MSG GNURADIO_RUNTIME_LIBRARIES)
MARK_AS_ADVANCED(GNURADIO_RUNTIME_LIBRARIES GNURADIO_RUNTIME_INCLUDE_DIRS)

528
cmake/Modules/GrMiscUtils.cmake

@ -1,528 +0,0 @@
# Copyright 2010-2011,2014 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
if(DEFINED __INCLUDED_GR_MISC_UTILS_CMAKE)
return()
endif()
set(__INCLUDED_GR_MISC_UTILS_CMAKE TRUE)
########################################################################
# Set global variable macro.
# Used for subdirectories to export settings.
# Example: include and library paths.
########################################################################
function(GR_SET_GLOBAL var)
set(${var} ${ARGN} CACHE INTERNAL "" FORCE)
endfunction(GR_SET_GLOBAL)
########################################################################
# Set the pre-processor definition if the condition is true.
# - def the pre-processor definition to set and condition name
########################################################################
function(GR_ADD_COND_DEF def)
if(${def})
add_definitions(-D${def})
endif(${def})
endfunction(GR_ADD_COND_DEF)
########################################################################
# Check for a header and conditionally set a compile define.
# - hdr the relative path to the header file
# - def the pre-processor definition to set
########################################################################
function(GR_CHECK_HDR_N_DEF hdr def)
include(CheckIncludeFileCXX)
CHECK_INCLUDE_FILE_CXX(${hdr} ${def})
GR_ADD_COND_DEF(${def})
endfunction(GR_CHECK_HDR_N_DEF)
########################################################################
# Include subdirectory macro.
# Sets the CMake directory variables,
# includes the subdirectory CMakeLists.txt,
# resets the CMake directory variables.
#
# This macro includes subdirectories rather than adding them
# so that the subdirectory can affect variables in the level above.
# This provides a work-around for the lack of convenience libraries.
# This way a subdirectory can append to the list of library sources.
########################################################################
macro(GR_INCLUDE_SUBDIRECTORY subdir)
#insert the current directories on the front of the list
list(INSERT _cmake_source_dirs 0 ${CMAKE_CURRENT_SOURCE_DIR})
list(INSERT _cmake_binary_dirs 0 ${CMAKE_CURRENT_BINARY_DIR})
#set the current directories to the names of the subdirs
set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/${subdir})
set(CMAKE_CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${subdir})
#include the subdirectory CMakeLists to run it
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
include(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt)
#reset the value of the current directories
list(GET _cmake_source_dirs 0 CMAKE_CURRENT_SOURCE_DIR)
list(GET _cmake_binary_dirs 0 CMAKE_CURRENT_BINARY_DIR)
#pop the subdir names of the front of the list
list(REMOVE_AT _cmake_source_dirs 0)
list(REMOVE_AT _cmake_binary_dirs 0)
endmacro(GR_INCLUDE_SUBDIRECTORY)
########################################################################
# Check if a compiler flag works and conditionally set a compile define.
# - flag the compiler flag to check for
# - have the variable to set with result
########################################################################
macro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE flag have)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG(${flag} ${have})
if(${have})
if(${CMAKE_VERSION} VERSION_GREATER "2.8.4")
STRING(FIND "${CMAKE_CXX_FLAGS}" "${flag}" flag_dup)
if(${flag_dup} EQUAL -1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
endif(${flag_dup} EQUAL -1)
endif(${CMAKE_VERSION} VERSION_GREATER "2.8.4")
endif(${have})
endmacro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE)
########################################################################
# Generates the .la libtool file
# This appears to generate libtool files that cannot be used by auto*.
# Usage GR_LIBTOOL(TARGET [target] DESTINATION [dest])
# Notice: there is not COMPONENT option, these will not get distributed.
########################################################################
function(GR_LIBTOOL)
if(NOT DEFINED GENERATE_LIBTOOL)
set(GENERATE_LIBTOOL OFF) #disabled by default
endif()
if(GENERATE_LIBTOOL)
include(CMakeParseArgumentsCopy)
CMAKE_PARSE_ARGUMENTS(GR_LIBTOOL "" "TARGET;DESTINATION" "" ${ARGN})
find_program(LIBTOOL libtool)
if(LIBTOOL)
include(CMakeMacroLibtoolFile)
CREATE_LIBTOOL_FILE(${GR_LIBTOOL_TARGET} /${GR_LIBTOOL_DESTINATION})
endif(LIBTOOL)
endif(GENERATE_LIBTOOL)
endfunction(GR_LIBTOOL)
########################################################################
# Do standard things to the library target
# - set target properties
# - make install rules
# Also handle gnuradio custom naming conventions w/ extras mode.
########################################################################
function(GR_LIBRARY_FOO target)
#parse the arguments for component names
include(CMakeParseArgumentsCopy)
CMAKE_PARSE_ARGUMENTS(GR_LIBRARY "" "RUNTIME_COMPONENT;DEVEL_COMPONENT" "" ${ARGN})
#set additional target properties
set_target_properties(${target} PROPERTIES SOVERSION ${LIBVER})
#install the generated files like so...
install(TARGETS ${target}
LIBRARY DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT} # .so/.dylib file
ARCHIVE DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_DEVEL_COMPONENT} # .lib file
RUNTIME DESTINATION ${GR_RUNTIME_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT} # .dll file
)
#extras mode enabled automatically on linux
if(NOT DEFINED LIBRARY_EXTRAS)
set(LIBRARY_EXTRAS ${LINUX})
endif()
#special extras mode to enable alternative naming conventions
if(LIBRARY_EXTRAS)
#create .la file before changing props
GR_LIBTOOL(TARGET ${target} DESTINATION ${GR_LIBRARY_DIR})
#give the library a special name with ultra-zero soversion
set_target_properties(${target} PROPERTIES OUTPUT_NAME ${target}-${LIBVER} SOVERSION "0.0.0")
set(target_name lib${target}-${LIBVER}.so.0.0.0)
#custom command to generate symlinks
add_custom_command(
TARGET ${target}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E create_symlink ${target_name} ${CMAKE_CURRENT_BINARY_DIR}/lib${target}.so
COMMAND ${CMAKE_COMMAND} -E create_symlink ${target_name} ${CMAKE_CURRENT_BINARY_DIR}/lib${target}-${LIBVER}.so.0
COMMAND ${CMAKE_COMMAND} -E touch ${target_name} #so the symlinks point to something valid so cmake 2.6 will install
)
#and install the extra symlinks
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/lib${target}.so
${CMAKE_CURRENT_BINARY_DIR}/lib${target}-${LIBVER}.so.0
DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT}
)
endif(LIBRARY_EXTRAS)
endfunction(GR_LIBRARY_FOO)
########################################################################
# Create a dummy custom command that depends on other targets.
# Usage:
# GR_GEN_TARGET_DEPS(unique_name target_deps <target1> <target2> ...)
# ADD_CUSTOM_COMMAND(<the usual args> ${target_deps})
#
# Custom command cant depend on targets, but can depend on executables,
# and executables can depend on targets. So this is the process:
########################################################################
function(GR_GEN_TARGET_DEPS name var)
file(
WRITE ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp.in
"int main(void){return 0;}\n"
)
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp.in
${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp
)
add_executable(${name} ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp)
if(ARGN)
add_dependencies(${name} ${ARGN})
endif(ARGN)
if(CMAKE_CROSSCOMPILING)
set(${var} "DEPENDS;${name}" PARENT_SCOPE) #cant call command when cross
else()
set(${var} "DEPENDS;${name};COMMAND;${name}" PARENT_SCOPE)
endif()
endfunction(GR_GEN_TARGET_DEPS)
########################################################################
# Control use of gr_logger
# Usage:
# GR_LOGGING()
#
# Will set ENABLE_GR_LOG to 1 by default.
# Can manually set with -DENABLE_GR_LOG=0|1
########################################################################
function(GR_LOGGING)
find_package(Log4cpp)
OPTION(ENABLE_GR_LOG "Use gr_logger" ON)
if(ENABLE_GR_LOG)
# If gr_logger is enabled, make it usable
add_definitions( -DENABLE_GR_LOG )
# also test LOG4CPP; if we have it, use this version of the logger
# otherwise, default to the stdout/stderr model.
if(LOG4CPP_FOUND)
SET(HAVE_LOG4CPP True CACHE INTERNAL "" FORCE)
add_definitions( -DHAVE_LOG4CPP )
else(not LOG4CPP_FOUND)
SET(HAVE_LOG4CPP False CACHE INTERNAL "" FORCE)
SET(LOG4CPP_INCLUDE_DIRS "" CACHE INTERNAL "" FORCE)
SET(LOG4CPP_LIBRARY_DIRS "" CACHE INTERNAL "" FORCE)
SET(LOG4CPP_LIBRARIES "" CACHE INTERNAL "" FORCE)
endif(LOG4CPP_FOUND)
SET(ENABLE_GR_LOG ${ENABLE_GR_LOG} CACHE INTERNAL "" FORCE)
else(ENABLE_GR_LOG)
SET(HAVE_LOG4CPP False CACHE INTERNAL "" FORCE)
SET(LOG4CPP_INCLUDE_DIRS "" CACHE INTERNAL "" FORCE)
SET(LOG4CPP_LIBRARY_DIRS "" CACHE INTERNAL "" FORCE)
SET(LOG4CPP_LIBRARIES "" CACHE INTERNAL "" FORCE)
endif(ENABLE_GR_LOG)
message(STATUS "ENABLE_GR_LOG set to ${ENABLE_GR_LOG}.")
message(STATUS "HAVE_LOG4CPP set to ${HAVE_LOG4CPP}.")
message(STATUS "LOG4CPP_LIBRARIES set to ${LOG4CPP_LIBRARIES}.")
endfunction(GR_LOGGING)
########################################################################
# Run GRCC to compile .grc files into .py files.
#
# Usage: GRCC(filename, directory)
# - filenames: List of file name of .grc file
# - directory: directory of built .py file - usually in
# ${CMAKE_CURRENT_BINARY_DIR}
# - Sets PYFILES: output converted GRC file names to Python files.
########################################################################
function(GRCC)
# Extract directory from list of args, remove it for the list of filenames.
list(GET ARGV -1 directory)
list(REMOVE_AT ARGV -1)
set(filenames ${ARGV})
file(MAKE_DIRECTORY ${directory})
SET(GRCC_COMMAND ${CMAKE_SOURCE_DIR}/gr-utils/python/grcc)
# GRCC uses some stuff in grc and gnuradio-runtime, so we force
# the known paths here
list(APPEND PYTHONPATHS
${CMAKE_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/gnuradio-runtime/python
${CMAKE_SOURCE_DIR}/gnuradio-runtime/lib/swig
${CMAKE_BINARY_DIR}/gnuradio-runtime/lib/swig
)
if(WIN32)
#SWIG generates the python library files into a subdirectory.
#Therefore, we must append this subdirectory into PYTHONPATH.
#Only do this for the python directories matching the following:
foreach(pydir ${PYTHONPATHS})
get_filename_component(name ${pydir} NAME)
if(name MATCHES "^(swig|lib|src)$")
list(APPEND PYTHONPATHS ${pydir}/${CMAKE_BUILD_TYPE})
endif()
endforeach(pydir)
endif(WIN32)
file(TO_NATIVE_PATH "${PYTHONPATHS}" pypath)
if(UNIX)
list(APPEND pypath "$PYTHONPATH")
string(REPLACE ";" ":" pypath "${pypath}")
set(ENV{PYTHONPATH} ${pypath})
endif(UNIX)
if(WIN32)
list(APPEND pypath "%PYTHONPATH%")
string(REPLACE ";" "\\;" pypath "${pypath}")
#list(APPEND environs "PYTHONPATH=${pypath}")
set(ENV{PYTHONPATH} ${pypath})
endif(WIN32)
foreach(f ${filenames})
execute_process(
COMMAND ${GRCC_COMMAND} -d ${directory} ${f}
)
string(REPLACE ".grc" ".py" pyfile "${f}")
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" pyfile "${pyfile}")
list(APPEND pyfiles ${pyfile})
endforeach(f)
set(PYFILES ${pyfiles} PARENT_SCOPE)
endfunction(GRCC)
########################################################################
# Check if HAVE_PTHREAD_SETSCHEDPARAM and HAVE_SCHED_SETSCHEDULER
# should be defined
########################################################################
macro(GR_CHECK_LINUX_SCHED_AVAIL)
set(CMAKE_REQUIRED_LIBRARIES -lpthread)
CHECK_CXX_SOURCE_COMPILES("
#include <pthread.h>
int main(){
pthread_t pthread;
pthread_setschedparam(pthread, 0, 0);
return 0;
} " HAVE_PTHREAD_SETSCHEDPARAM
)
GR_ADD_COND_DEF(HAVE_PTHREAD_SETSCHEDPARAM)
CHECK_CXX_SOURCE_COMPILES("
#include <sched.h>
int main(){
pid_t pid;
sched_setscheduler(pid, 0, 0);
return 0;
} " HAVE_SCHED_SETSCHEDULER
)
GR_ADD_COND_DEF(HAVE_SCHED_SETSCHEDULER)
endmacro(GR_CHECK_LINUX_SCHED_AVAIL)
########################################################################
# Macros to generate source and header files from template
########################################################################
macro(GR_EXPAND_X_H component root)
include(GrPython)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
"#!${PYTHON_EXECUTABLE}
import sys, os, re
sys.path.append('${GR_RUNTIME_PYTHONPATH}')
sys.path.append('${CMAKE_SOURCE_DIR}/python')
os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
if __name__ == '__main__':
import build_utils
root, inp = sys.argv[1:3]
for sig in sys.argv[3:]:
name = re.sub ('X+', sig, root)
d = build_utils.standard_dict2(name, sig, '${component}')
build_utils.expand_template(d, inp)
")
#make a list of all the generated headers
unset(expanded_files_h)
foreach(sig ${ARGN})
string(REGEX REPLACE "X+" ${sig} name ${root})
list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h)
endforeach(sig)
unset(name)
#create a command to generate the headers
add_custom_command(
OUTPUT ${expanded_files_h}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
${root} ${root}.h.t ${ARGN}
)
#install rules for the generated headers
list(APPEND generated_includes ${expanded_files_h})
endmacro(GR_EXPAND_X_H)
macro(GR_EXPAND_X_CC_H component root)
include(GrPython)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
"#!${PYTHON_EXECUTABLE}
import sys, os, re
sys.path.append('${GR_RUNTIME_PYTHONPATH}')
sys.path.append('${CMAKE_SOURCE_DIR}/python')
os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
if __name__ == '__main__':
import build_utils
root, inp = sys.argv[1:3]
for sig in sys.argv[3:]:
name = re.sub ('X+', sig, root)
d = build_utils.standard_impl_dict2(name, sig, '${component}')
build_utils.expand_template(d, inp)
")
#make a list of all the generated files
unset(expanded_files_cc)
unset(expanded_files_h)
foreach(sig ${ARGN})
string(REGEX REPLACE "X+" ${sig} name ${root})
list(APPEND expanded_files_cc ${CMAKE_CURRENT_BINARY_DIR}/${name}.cc)
list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h)
endforeach(sig)
unset(name)
#create a command to generate the source files
add_custom_command(
OUTPUT ${expanded_files_cc}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.cc.t
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
${root} ${root}.cc.t ${ARGN}
)
#create a command to generate the header files
add_custom_command(
OUTPUT ${expanded_files_h}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
${root} ${root}.h.t ${ARGN}
)
#make source files depends on headers to force generation
set_source_files_properties(${expanded_files_cc}
PROPERTIES OBJECT_DEPENDS "${expanded_files_h}"
)
#install rules for the generated files
list(APPEND generated_sources ${expanded_files_cc})
list(APPEND generated_headers ${expanded_files_h})
endmacro(GR_EXPAND_X_CC_H)
macro(GR_EXPAND_X_CC_H_IMPL component root)
include(GrPython)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
"#!${PYTHON_EXECUTABLE}
import sys, os, re
sys.path.append('${GR_RUNTIME_PYTHONPATH}')
sys.path.append('${CMAKE_SOURCE_DIR}/python')
os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
if __name__ == '__main__':
import build_utils
root, inp = sys.argv[1:3]
for sig in sys.argv[3:]:
name = re.sub ('X+', sig, root)
d = build_utils.standard_dict(name, sig, '${component}')
build_utils.expand_template(d, inp, '_impl')
")
#make a list of all the generated files
unset(expanded_files_cc_impl)
unset(expanded_files_h_impl)
unset(expanded_files_h)
foreach(sig ${ARGN})
string(REGEX REPLACE "X+" ${sig} name ${root})
list(APPEND expanded_files_cc_impl ${CMAKE_CURRENT_BINARY_DIR}/${name}_impl.cc)
list(APPEND expanded_files_h_impl ${CMAKE_CURRENT_BINARY_DIR}/${name}_impl.h)
list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/../include/gnuradio/${component}/${name}.h)
endforeach(sig)
unset(name)
#create a command to generate the _impl.cc files
add_custom_command(
OUTPUT ${expanded_files_cc_impl}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}_impl.cc.t
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
${root} ${root}_impl.cc.t ${ARGN}
)
#create a command to generate the _impl.h files
add_custom_command(
OUTPUT ${expanded_files_h_impl}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}_impl.h.t
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
${root} ${root}_impl.h.t ${ARGN}
)
#make _impl.cc source files depend on _impl.h to force generation
set_source_files_properties(${expanded_files_cc_impl}
PROPERTIES OBJECT_DEPENDS "${expanded_files_h_impl}"
)
#make _impl.h source files depend on headers to force generation
set_source_files_properties(${expanded_files_h_impl}
PROPERTIES OBJECT_DEPENDS "${expanded_files_h}"
)
#install rules for the generated files
list(APPEND generated_sources ${expanded_files_cc_impl})
list(APPEND generated_headers ${expanded_files_h_impl})
endmacro(GR_EXPAND_X_CC_H_IMPL)

54
cmake/Modules/GrPlatform.cmake

@ -1,54 +0,0 @@
# Copyright 2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
if(DEFINED __INCLUDED_GR_PLATFORM_CMAKE)
return()
endif()
set(__INCLUDED_GR_PLATFORM_CMAKE TRUE)
########################################################################
# Setup additional defines for OS types
########################################################################
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(LINUX TRUE)
endif()
if(NOT CMAKE_CROSSCOMPILING AND LINUX AND EXISTS "/etc/debian_version")
set(DEBIAN TRUE)
endif()
if(NOT CMAKE_CROSSCOMPILING AND LINUX AND EXISTS "/etc/redhat-release")
set(REDHAT TRUE)
endif()
if(NOT CMAKE_CROSSCOMPILING AND LINUX AND EXISTS "/etc/slackware-version")
set(SLACKWARE TRUE)
endif()
########################################################################
# when the library suffix should be 64 (applies to redhat linux family)
########################################################################
if (REDHAT OR SLACKWARE)
set(LIB64_CONVENTION TRUE)
endif()
if(NOT DEFINED LIB_SUFFIX AND LIB64_CONVENTION AND CMAKE_SYSTEM_PROCESSOR MATCHES "64$")
set(LIB_SUFFIX 64)
endif()
set(LIB_SUFFIX ${LIB_SUFFIX} CACHE STRING "lib directory suffix")

241
cmake/Modules/GrPython.cmake

@ -1,241 +0,0 @@
# Copyright 2010-2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
if(DEFINED __INCLUDED_GR_PYTHON_CMAKE)
return()
endif()
set(__INCLUDED_GR_PYTHON_CMAKE TRUE)
########################################################################
# Setup the python interpreter:
# This allows the user to specify a specific interpreter,
# or finds the interpreter via the built-in cmake module.
########################################################################
#this allows the user to override PYTHON_EXECUTABLE
if(PYTHON_EXECUTABLE)
set(PYTHONINTERP_FOUND TRUE)
#otherwise if not set, try to automatically find it
else(PYTHON_EXECUTABLE)
#use the built-in find script
find_package(PythonInterp 2)
#and if that fails use the find program routine
if(NOT PYTHONINTERP_FOUND)
find_program(PYTHON_EXECUTABLE NAMES python python2 python2.7 python2.6 python2.5)
if(PYTHON_EXECUTABLE)
set(PYTHONINTERP_FOUND TRUE)
endif(PYTHON_EXECUTABLE)
endif(NOT PYTHONINTERP_FOUND)
endif(PYTHON_EXECUTABLE)
if (CMAKE_CROSSCOMPILING)
set(QA_PYTHON_EXECUTABLE "/usr/bin/python")
else (CMAKE_CROSSCOMPILING)
set(QA_PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE})
endif(CMAKE_CROSSCOMPILING)
#make the path to the executable appear in the cmake gui
set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter")
set(QA_PYTHON_EXECUTABLE ${QA_PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter for QA tests")
#make sure we can use -B with python (introduced in 2.6)
if(PYTHON_EXECUTABLE)
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -B -c ""
OUTPUT_QUIET ERROR_QUIET
RESULT_VARIABLE PYTHON_HAS_DASH_B_RESULT
)
if(PYTHON_HAS_DASH_B_RESULT EQUAL 0)
set(PYTHON_DASH_B "-B")
endif()
endif(PYTHON_EXECUTABLE)
########################################################################
# Check for the existence of a python module:
# - desc a string description of the check
# - mod the name of the module to import
# - cmd an additional command to run
# - have the result variable to set
########################################################################
macro(GR_PYTHON_CHECK_MODULE desc mod cmd have)
message(STATUS "")
message(STATUS "Python checking for ${desc}")
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -c "
#########################################
try:
import ${mod}
assert ${cmd}
except ImportError, AssertionError: exit(-1)
except: pass
#########################################"
RESULT_VARIABLE ${have}
)
if(${have} EQUAL 0)
message(STATUS "Python checking for ${desc} - found")
set(${have} TRUE)
else(${have} EQUAL 0)
message(STATUS "Python checking for ${desc} - not found")
set(${have} FALSE)
endif(${have} EQUAL 0)
endmacro(GR_PYTHON_CHECK_MODULE)
########################################################################
# Sets the python installation directory GR_PYTHON_DIR
########################################################################
if(NOT DEFINED GR_PYTHON_DIR)
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "
from distutils import sysconfig
print sysconfig.get_python_lib(plat_specific=True, prefix='')
" OUTPUT_VARIABLE GR_PYTHON_DIR OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()
file(TO_CMAKE_PATH ${GR_PYTHON_DIR} GR_PYTHON_DIR)
########################################################################
# Create an always-built target with a unique name
# Usage: GR_UNIQUE_TARGET(<description> <dependencies list>)
########################################################################
function(GR_UNIQUE_TARGET desc)
file(RELATIVE_PATH reldir ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib
unique = hashlib.md5('${reldir}${ARGN}').hexdigest()[:5]
print(re.sub('\\W', '_', '${desc} ${reldir} ' + unique))"
OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE)
add_custom_target(${_target} ALL DEPENDS ${ARGN})
endfunction(GR_UNIQUE_TARGET)
########################################################################
# Install python sources (also builds and installs byte-compiled python)
########################################################################
function(GR_PYTHON_INSTALL)
include(CMakeParseArgumentsCopy)
CMAKE_PARSE_ARGUMENTS(GR_PYTHON_INSTALL "" "DESTINATION;COMPONENT" "FILES;PROGRAMS" ${ARGN})
####################################################################
if(GR_PYTHON_INSTALL_FILES)
####################################################################
install(${ARGN}) #installs regular python files
#create a list of all generated files
unset(pysrcfiles)
unset(pycfiles)
unset(pyofiles)
foreach(pyfile ${GR_PYTHON_INSTALL_FILES})
get_filename_component(pyfile ${pyfile} ABSOLUTE)
list(APPEND pysrcfiles ${pyfile})
#determine if this file is in the source or binary directory
file(RELATIVE_PATH source_rel_path ${CMAKE_CURRENT_SOURCE_DIR} ${pyfile})
string(LENGTH "${source_rel_path}" source_rel_path_len)
file(RELATIVE_PATH binary_rel_path ${CMAKE_CURRENT_BINARY_DIR} ${pyfile})
string(LENGTH "${binary_rel_path}" binary_rel_path_len)
#and set the generated path appropriately
if(${source_rel_path_len} GREATER ${binary_rel_path_len})
set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${binary_rel_path})
else()
set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${source_rel_path})
endif()
list(APPEND pycfiles ${pygenfile}c)
list(APPEND pyofiles ${pygenfile}o)
#ensure generation path exists
get_filename_component(pygen_path ${pygenfile} PATH)
file(MAKE_DIRECTORY ${pygen_path})
endforeach(pyfile)
#the command to generate the pyc files
add_custom_command(
DEPENDS ${pysrcfiles} OUTPUT ${pycfiles}
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pycfiles}
)
#the command to generate the pyo files
add_custom_command(
DEPENDS ${pysrcfiles} OUTPUT ${pyofiles}
COMMAND ${PYTHON_EXECUTABLE} -O ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pyofiles}
)
#create install rule and add generated files to target list
set(python_install_gen_targets ${pycfiles} ${pyofiles})
install(FILES ${python_install_gen_targets}
DESTINATION ${GR_PYTHON_INSTALL_DESTINATION}
COMPONENT ${GR_PYTHON_INSTALL_COMPONENT}
)
####################################################################
elseif(GR_PYTHON_INSTALL_PROGRAMS)
####################################################################
file(TO_NATIVE_PATH ${PYTHON_EXECUTABLE} pyexe_native)
if (CMAKE_CROSSCOMPILING)
set(pyexe_native "/usr/bin/env python")
endif()
foreach(pyfile ${GR_PYTHON_INSTALL_PROGRAMS})
get_filename_component(pyfile_name ${pyfile} NAME)
get_filename_component(pyfile ${pyfile} ABSOLUTE)
string(REPLACE "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" pyexefile "${pyfile}.exe")
list(APPEND python_install_gen_targets ${pyexefile})
get_filename_component(pyexefile_path ${pyexefile} PATH)
file(MAKE_DIRECTORY ${pyexefile_path})
add_custom_command(
OUTPUT ${pyexefile} DEPENDS ${pyfile}
COMMAND ${PYTHON_EXECUTABLE} -c
"import re; R=re.compile('^\#!.*$\\n',flags=re.MULTILINE); open('${pyexefile}','w').write('\#!${pyexe_native}\\n'+R.sub('',open('${pyfile}','r').read()))"
COMMENT "Shebangin ${pyfile_name}"
VERBATIM
)
#on windows, python files need an extension to execute
get_filename_component(pyfile_ext ${pyfile} EXT)
if(WIN32 AND NOT pyfile_ext)
set(pyfile_name "${pyfile_name}.py")
endif()
install(PROGRAMS ${pyexefile} RENAME ${pyfile_name}
DESTINATION ${GR_PYTHON_INSTALL_DESTINATION}
COMPONENT ${GR_PYTHON_INSTALL_COMPONENT}
)
endforeach(pyfile)
endif()
GR_UNIQUE_TARGET("pygen" ${python_install_gen_targets})
endfunction(GR_PYTHON_INSTALL)
########################################################################
# Write the python helper script that generates byte code files
########################################################################
file(WRITE ${CMAKE_BINARY_DIR}/python_compile_helper.py "
import sys, py_compile
files = sys.argv[1:]
srcs, gens = files[:len(files)/2], files[len(files)/2:]
for src, gen in zip(srcs, gens):
py_compile.compile(file=src, cfile=gen, doraise=True)
")

251
cmake/Modules/GrSwig.cmake

@ -1,251 +0,0 @@
# Copyright 2010-2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
if(DEFINED __INCLUDED_GR_SWIG_CMAKE)
return()
endif()
set(__INCLUDED_GR_SWIG_CMAKE TRUE)
include(GrPython)
########################################################################
# Builds a swig documentation file to be generated into python docstrings
# Usage: GR_SWIG_MAKE_DOCS(output_file input_path input_path....)
#
# Set the following variable to specify extra dependent targets:
# - GR_SWIG_DOCS_SOURCE_DEPS
# - GR_SWIG_DOCS_TARGET_DEPS
########################################################################
function(GR_SWIG_MAKE_DOCS output_file)
if(ENABLE_DOXYGEN)
#setup the input files variable list, quote formated
set(input_files)
unset(INPUT_PATHS)
foreach(input_path ${ARGN})
if(IS_DIRECTORY ${input_path}) #when input path is a directory
file(GLOB input_path_h_files ${input_path}/*.h)
else() #otherwise its just a file, no glob
set(input_path_h_files ${input_path})
endif()
list(APPEND input_files ${input_path_h_files})
set(INPUT_PATHS "${INPUT_PATHS} \"${input_path}\"")
endforeach(input_path)
#determine the output directory
get_filename_component(name ${output_file} NAME_WE)
get_filename_component(OUTPUT_DIRECTORY ${output_file} PATH)
set(OUTPUT_DIRECTORY ${OUTPUT_DIRECTORY}/${name}_swig_docs)
make_directory(${OUTPUT_DIRECTORY})
#generate the Doxyfile used by doxygen
configure_file(
${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile.swig_doc.in
${OUTPUT_DIRECTORY}/Doxyfile
@ONLY)
#Create a dummy custom command that depends on other targets
include(GrMiscUtils)
GR_GEN_TARGET_DEPS(_${name}_tag tag_deps ${GR_SWIG_DOCS_TARGET_DEPS})
#call doxygen on the Doxyfile + input headers
add_custom_command(
OUTPUT ${OUTPUT_DIRECTORY}/xml/index.xml
DEPENDS ${input_files} ${GR_SWIG_DOCS_SOURCE_DEPS} ${tag_deps}
COMMAND ${DOXYGEN_EXECUTABLE} ${OUTPUT_DIRECTORY}/Doxyfile
COMMENT "Generating doxygen xml for ${name} docs"
)
#call the swig_doc script on the xml files
add_custom_command(
OUTPUT ${output_file}
DEPENDS ${input_files} ${stamp-file} ${OUTPUT_DIRECTORY}/xml/index.xml
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
${CMAKE_SOURCE_DIR}/docs/doxygen/swig_doc.py
${OUTPUT_DIRECTORY}/xml
${output_file}
COMMENT "Generating python docstrings for ${name}"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs/doxygen
)
else(ENABLE_DOXYGEN)
file(WRITE ${output_file} "\n") #no doxygen -> empty file
endif(ENABLE_DOXYGEN)
endfunction(GR_SWIG_MAKE_DOCS)
########################################################################
# Build a swig target for the common gnuradio use case. Usage:
# GR_SWIG_MAKE(target ifile ifile ifile...)
#
# Set the following variables before calling:
# - GR_SWIG_FLAGS
# - GR_SWIG_INCLUDE_DIRS
# - GR_SWIG_LIBRARIES
# - GR_SWIG_SOURCE_DEPS
# - GR_SWIG_TARGET_DEPS
# - GR_SWIG_DOC_FILE
# - GR_SWIG_DOC_DIRS
########################################################################
macro(GR_SWIG_MAKE name)
set(ifiles ${ARGN})
# Shimming this in here to take care of a SWIG bug with handling
# vector<size_t> and vector<unsigned int> (on 32-bit machines) and
# vector<long unsigned int> (on 64-bit machines). Use this to test
# the size of size_t, then set SIZE_T_32 if it's a 32-bit machine
# or not if it's 64-bit. The logic in gr_type.i handles the rest.
INCLUDE(CheckTypeSize)
CHECK_TYPE_SIZE("size_t" SIZEOF_SIZE_T)
CHECK_TYPE_SIZE("unsigned int" SIZEOF_UINT)
if(${SIZEOF_SIZE_T} EQUAL ${SIZEOF_UINT})
list(APPEND GR_SWIG_FLAGS -DSIZE_T_32)
endif(${SIZEOF_SIZE_T} EQUAL ${SIZEOF_UINT})
#do swig doc generation if specified
if(GR_SWIG_DOC_FILE)
set(GR_SWIG_DOCS_SOURCE_DEPS ${GR_SWIG_SOURCE_DEPS})
list(APPEND GR_SWIG_DOCS_TARGET_DEPS ${GR_SWIG_TARGET_DEPS})
GR_SWIG_MAKE_DOCS(${GR_SWIG_DOC_FILE} ${GR_SWIG_DOC_DIRS})
add_custom_target(${name}_swig_doc DEPENDS ${GR_SWIG_DOC_FILE})
list(APPEND GR_SWIG_TARGET_DEPS ${name}_swig_doc ${GR_RUNTIME_SWIG_DOC_FILE})
endif()
#append additional include directories
find_package(PythonLibs 2)
list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_PATH}) #deprecated name (now dirs)
list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS})
#prepend local swig directories
list(INSERT GR_SWIG_INCLUDE_DIRS 0 ${CMAKE_CURRENT_SOURCE_DIR})
list(INSERT GR_SWIG_INCLUDE_DIRS 0 ${CMAKE_CURRENT_BINARY_DIR})
#determine include dependencies for swig file
execute_process(
COMMAND ${PYTHON_EXECUTABLE}
${CMAKE_BINARY_DIR}/get_swig_deps.py
"${ifiles}" "${GR_SWIG_INCLUDE_DIRS}"
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE SWIG_MODULE_${name}_EXTRA_DEPS
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
#Create a dummy custom command that depends on other targets
include(GrMiscUtils)
GR_GEN_TARGET_DEPS(_${name}_swig_tag tag_deps ${GR_SWIG_TARGET_DEPS})
set(tag_file ${CMAKE_CURRENT_BINARY_DIR}/${name}.tag)
add_custom_command(
OUTPUT ${tag_file}
DEPENDS ${GR_SWIG_SOURCE_DEPS} ${tag_deps}
COMMAND ${CMAKE_COMMAND} -E touch ${tag_file}
)
#append the specified include directories
include_directories(${GR_SWIG_INCLUDE_DIRS})
list(APPEND SWIG_MODULE_${name}_EXTRA_DEPS ${tag_file})
#setup the swig flags with flags and include directories
set(CMAKE_SWIG_FLAGS -fvirtual -modern -keyword -w511 -module ${name} ${GR_SWIG_FLAGS})
foreach(dir ${GR_SWIG_INCLUDE_DIRS})
list(APPEND CMAKE_SWIG_FLAGS "-I${dir}")
endforeach(dir)
#set the C++ property on the swig .i file so it builds
set_source_files_properties(${ifiles} PROPERTIES CPLUSPLUS ON)
#setup the actual swig library target to be built
include(UseSWIG)
SWIG_ADD_MODULE(${name} python ${ifiles})
SWIG_LINK_LIBRARIES(${name} ${PYTHON_LIBRARIES} ${GR_SWIG_LIBRARIES})
if(${name} STREQUAL "runtime_swig")
SET_TARGET_PROPERTIES(${SWIG_MODULE_runtime_swig_REAL_NAME} PROPERTIES DEFINE_SYMBOL "gnuradio_runtime_EXPORTS")
endif(${name} STREQUAL "runtime_swig")
endmacro(GR_SWIG_MAKE)
########################################################################
# Install swig targets generated by GR_SWIG_MAKE. Usage:
# GR_SWIG_INSTALL(
# TARGETS target target target...
# [DESTINATION destination]
# [COMPONENT component]
# )
########################################################################
macro(GR_SWIG_INSTALL)
include(CMakeParseArgumentsCopy)
CMAKE_PARSE_ARGUMENTS(GR_SWIG_INSTALL "" "DESTINATION;COMPONENT" "TARGETS" ${ARGN})
foreach(name ${GR_SWIG_INSTALL_TARGETS})
install(TARGETS ${SWIG_MODULE_${name}_REAL_NAME}
DESTINATION ${GR_SWIG_INSTALL_DESTINATION}
COMPONENT ${GR_SWIG_INSTALL_COMPONENT}
)
include(GrPython)
GR_PYTHON_INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${name}.py
DESTINATION ${GR_SWIG_INSTALL_DESTINATION}
COMPONENT ${GR_SWIG_INSTALL_COMPONENT}
)
GR_LIBTOOL(
TARGET ${SWIG_MODULE_${name}_REAL_NAME}
DESTINATION ${GR_SWIG_INSTALL_DESTINATION}
)
endforeach(name)
endmacro(GR_SWIG_INSTALL)
########################################################################
# Generate a python file that can determine swig dependencies.
# Used by the make macro above to determine extra dependencies.
# When you build C++, CMake figures out the header dependencies.
# This code essentially performs that logic for swig includes.
########################################################################
file(WRITE ${CMAKE_BINARY_DIR}/get_swig_deps.py "
import os, sys, re
i_include_matcher = re.compile('%(include|import)\\s*[<|\"](.*)[>|\"]')
h_include_matcher = re.compile('#(include)\\s*[<|\"](.*)[>|\"]')
include_dirs = sys.argv[2].split(';')
def get_swig_incs(file_path):
if file_path.endswith('.i'): matcher = i_include_matcher
else: matcher = h_include_matcher
file_contents = open(file_path, 'r').read()
return matcher.findall(file_contents, re.MULTILINE)
def get_swig_deps(file_path, level):
deps = [file_path]
if level == 0: return deps
for keyword, inc_file in get_swig_incs(file_path):
for inc_dir in include_dirs:
inc_path = os.path.join(inc_dir, inc_file)
if not os.path.exists(inc_path): continue
deps.extend(get_swig_deps(inc_path, level-1))
break #found, we dont search in lower prio inc dirs
return deps
if __name__ == '__main__':
ifiles = sys.argv[1].split(';')
deps = sum([get_swig_deps(ifile, 3) for ifile in ifiles], [])
#sys.stderr.write(';'.join(set(deps)) + '\\n\\n')
print(';'.join(set(deps)))
")

143
cmake/Modules/GrTest.cmake

@ -1,143 +0,0 @@
# Copyright 2010-2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
if(DEFINED __INCLUDED_GR_TEST_CMAKE)
return()
endif()
set(__INCLUDED_GR_TEST_CMAKE TRUE)
########################################################################
# Add a unit test and setup the environment for a unit test.
# Takes the same arguments as the ADD_TEST function.
#
# Before calling set the following variables:
# GR_TEST_TARGET_DEPS - built targets for the library path
# GR_TEST_LIBRARY_DIRS - directories for the library path
# GR_TEST_PYTHON_DIRS - directories for the python path
# GR_TEST_ENVIRONS - other environment key/value pairs
########################################################################
function(GR_ADD_TEST test_name)
#Ensure that the build exe also appears in the PATH.
list(APPEND GR_TEST_TARGET_DEPS ${ARGN})
#In the land of windows, all libraries must be in the PATH.
#Since the dependent libraries are not yet installed,
#we must manually set them in the PATH to run tests.
#The following appends the path of a target dependency.
foreach(target ${GR_TEST_TARGET_DEPS})
get_target_property(location ${target} LOCATION)
if(location)
get_filename_component(path ${location} PATH)
string(REGEX REPLACE "\\$\\(.*\\)" ${CMAKE_BUILD_TYPE} path ${path})
list(APPEND GR_TEST_LIBRARY_DIRS ${path})
endif(location)
endforeach(target)
if(WIN32)
#SWIG generates the python library files into a subdirectory.
#Therefore, we must append this subdirectory into PYTHONPATH.
#Only do this for the python directories matching the following:
foreach(pydir ${GR_TEST_PYTHON_DIRS})
get_filename_component(name ${pydir} NAME)
if(name MATCHES "^(swig|lib|src)$")
list(APPEND GR_TEST_PYTHON_DIRS ${pydir}/${CMAKE_BUILD_TYPE})
endif()
endforeach(pydir)
endif(WIN32)
file(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR} srcdir)
file(TO_NATIVE_PATH "${GR_TEST_LIBRARY_DIRS}" libpath) #ok to use on dir list?
file(TO_NATIVE_PATH "${GR_TEST_PYTHON_DIRS}" pypath) #ok to use on dir list?
set(environs "VOLK_GENERIC=1" "GR_DONT_LOAD_PREFS=1" "srcdir=${srcdir}")
list(APPEND environs ${GR_TEST_ENVIRONS})
#http://www.cmake.org/pipermail/cmake/2009-May/029464.html
#Replaced this add test + set environs code with the shell script generation.
#Its nicer to be able to manually run the shell script to diagnose problems.
#ADD_TEST(${ARGV})
#SET_TESTS_PROPERTIES(${test_name} PROPERTIES ENVIRONMENT "${environs}")
if(UNIX)
set(LD_PATH_VAR "LD_LIBRARY_PATH")
if(APPLE)
set(LD_PATH_VAR "DYLD_LIBRARY_PATH")
endif()
set(binpath "${CMAKE_CURRENT_BINARY_DIR}:$PATH")
list(APPEND libpath "$${LD_PATH_VAR}")
list(APPEND pypath "$PYTHONPATH")
#replace list separator with the path separator
string(REPLACE ";" ":" libpath "${libpath}")
string(REPLACE ";" ":" pypath "${pypath}")
list(APPEND environs "PATH=${binpath}" "${LD_PATH_VAR}=${libpath}" "PYTHONPATH=${pypath}")
#generate a bat file that sets the environment and runs the test
if (CMAKE_CROSSCOMPILING)
set(SHELL "/bin/sh")
else(CMAKE_CROSSCOMPILING)
find_program(SHELL sh)
endif(CMAKE_CROSSCOMPILING)
set(sh_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.sh)
file(WRITE ${sh_file} "#!${SHELL}\n")
#each line sets an environment variable
foreach(environ ${environs})
file(APPEND ${sh_file} "export ${environ}\n")
endforeach(environ)
#load the command to run with its arguments
foreach(arg ${ARGN})
file(APPEND ${sh_file} "${arg} ")
endforeach(arg)
file(APPEND ${sh_file} "\n")
#make the shell file executable
execute_process(COMMAND chmod +x ${sh_file})
add_test(${test_name} ${SHELL} ${sh_file})
endif(UNIX)
if(WIN32)
list(APPEND libpath ${DLL_PATHS} "%PATH%")
list(APPEND pypath "%PYTHONPATH%")
#replace list separator with the path separator (escaped)
string(REPLACE ";" "\\;" libpath "${libpath}")
string(REPLACE ";" "\\;" pypath "${pypath}")
list(APPEND environs "PATH=${libpath}" "PYTHONPATH=${pypath}")
#generate a bat file that sets the environment and runs the test
set(bat_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.bat)
file(WRITE ${bat_file} "@echo off\n")
#each line sets an environment variable
foreach(environ ${environs})
file(APPEND ${bat_file} "SET ${environ}\n")
endforeach(environ)
#load the command to run with its arguments
foreach(arg ${ARGN})
file(APPEND ${bat_file} "${arg} ")
endforeach(arg)
file(APPEND ${bat_file} "\n")
add_test(${test_name} ${bat_file})
endif(WIN32)
endfunction(GR_ADD_TEST)

304
cmake/Modules/UseSWIG.cmake

@ -1,304 +0,0 @@
# - SWIG module for CMake
# Defines the following macros:
# SWIG_ADD_MODULE(name language [ files ])
# - Define swig module with given name and specified language
# SWIG_LINK_LIBRARIES(name [ libraries ])
# - Link libraries to swig module
# All other macros are for internal use only.
# To get the actual name of the swig module,
# use: ${SWIG_MODULE_${name}_REAL_NAME}.
# Set Source files properties such as CPLUSPLUS and SWIG_FLAGS to specify
# special behavior of SWIG. Also global CMAKE_SWIG_FLAGS can be used to add
# special flags to all swig calls.
# Another special variable is CMAKE_SWIG_OUTDIR, it allows one to specify
# where to write all the swig generated module (swig -outdir option)
# The name-specific variable SWIG_MODULE_<name>_EXTRA_DEPS may be used
# to specify extra dependencies for the generated modules.
# If the source file generated by swig need some special flag you can use
# set_source_files_properties( ${swig_generated_file_fullname}
# PROPERTIES COMPILE_FLAGS "-bla")
#=============================================================================
# Copyright 2004-2009 Kitware, Inc.
# Copyright 2009 Mathieu Malaterre <mathieu.malaterre@gmail.com>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
set(SWIG_CXX_EXTENSION "cxx")
set(SWIG_EXTRA_LIBRARIES "")
set(SWIG_PYTHON_EXTRA_FILE_EXTENSION "py")
#
# For given swig module initialize variables associated with it
#
macro(SWIG_MODULE_INITIALIZE name language)
string(TOUPPER "${language}" swig_uppercase_language)
string(TOLOWER "${language}" swig_lowercase_language)
set(SWIG_MODULE_${name}_LANGUAGE "${swig_uppercase_language}")
set(SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG "${swig_lowercase_language}")
set(SWIG_MODULE_${name}_REAL_NAME "${name}")
if("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "UNKNOWN")
message(FATAL_ERROR "SWIG Error: Language \"${language}\" not found")
elseif("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "PYTHON")
# when swig is used without the -interface it will produce in the module.py
# a 'import _modulename' statement, which implies having a corresponding
# _modulename.so (*NIX), _modulename.pyd (Win32).
set(SWIG_MODULE_${name}_REAL_NAME "_${name}")
elseif("${SWIG_MODULE_${name}_LANGUAGE}" STREQUAL "PERL")
set(SWIG_MODULE_${name}_EXTRA_FLAGS "-shadow")
endif()
endmacro()
#
# For a given language, input file, and output file, determine extra files that
# will be generated. This is internal swig macro.
#
macro(SWIG_GET_EXTRA_OUTPUT_FILES language outfiles generatedpath infile)
set(${outfiles} "")
get_source_file_property(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename
${infile} SWIG_MODULE_NAME)
if(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename STREQUAL "NOTFOUND")
get_filename_component(SWIG_GET_EXTRA_OUTPUT_FILES_module_basename "${infile}" NAME_WE)
endif()
foreach(it ${SWIG_${language}_EXTRA_FILE_EXTENSION})
set(${outfiles} ${${outfiles}}
"${generatedpath}/${SWIG_GET_EXTRA_OUTPUT_FILES_module_basename}.${it}")
endforeach()
endmacro()
#
# Take swig (*.i) file and add proper custom commands for it
#
macro(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
set(swig_full_infile ${infile})
get_filename_component(swig_source_file_path "${infile}" PATH)
get_filename_component(swig_source_file_name_we "${infile}" NAME_WE)
get_source_file_property(swig_source_file_generated ${infile} GENERATED)
get_source_file_property(swig_source_file_cplusplus ${infile} CPLUSPLUS)
get_source_file_property(swig_source_file_flags ${infile} SWIG_FLAGS)
if("${swig_source_file_flags}" STREQUAL "NOTFOUND")
set(swig_source_file_flags "")
endif()
set(swig_source_file_fullname "${infile}")
if(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_SOURCE_DIR}")
string(REGEX REPLACE
"^${CMAKE_CURRENT_SOURCE_DIR}" ""
swig_source_file_relative_path
"${swig_source_file_path}")
else()
if(${swig_source_file_path} MATCHES "^${CMAKE_CURRENT_BINARY_DIR}")
string(REGEX REPLACE
"^${CMAKE_CURRENT_BINARY_DIR}" ""
swig_source_file_relative_path
"${swig_source_file_path}")
set(swig_source_file_generated 1)
else()
set(swig_source_file_relative_path "${swig_source_file_path}")
if(swig_source_file_generated)
set(swig_source_file_fullname "${CMAKE_CURRENT_BINARY_DIR}/${infile}")
else()
set(swig_source_file_fullname "${CMAKE_CURRENT_SOURCE_DIR}/${infile}")
endif()
endif()
endif()
set(swig_generated_file_fullname
"${CMAKE_CURRENT_BINARY_DIR}")
if(swig_source_file_relative_path)
set(swig_generated_file_fullname
"${swig_generated_file_fullname}/${swig_source_file_relative_path}")
endif()
# If CMAKE_SWIG_OUTDIR was specified then pass it to -outdir
if(CMAKE_SWIG_OUTDIR)
set(swig_outdir ${CMAKE_SWIG_OUTDIR})
else()
set(swig_outdir ${CMAKE_CURRENT_BINARY_DIR})
endif()
SWIG_GET_EXTRA_OUTPUT_FILES(${SWIG_MODULE_${name}_LANGUAGE}
swig_extra_generated_files
"${swig_outdir}"
"${infile}")
set(swig_generated_file_fullname
"${swig_generated_file_fullname}/${swig_source_file_name_we}")
# add the language into the name of the file (i.e. TCL_wrap)
# this allows for the same .i file to be wrapped into different languages
set(swig_generated_file_fullname
"${swig_generated_file_fullname}${SWIG_MODULE_${name}_LANGUAGE}_wrap")
if(swig_source_file_cplusplus)
set(swig_generated_file_fullname
"${swig_generated_file_fullname}.${SWIG_CXX_EXTENSION}")
else()
set(swig_generated_file_fullname
"${swig_generated_file_fullname}.c")
endif()
# Shut up some warnings from poor SWIG code generation that we
# can do nothing about, when this flag is available
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag("-Wno-unused-but-set-variable" HAVE_WNO_UNUSED_BUT_SET_VARIABLE)
if(HAVE_WNO_UNUSED_BUT_SET_VARIABLE)
set_source_files_properties(${swig_generated_file_fullname}
PROPERTIES COMPILE_FLAGS "-Wno-unused-but-set-variable")
endif(HAVE_WNO_UNUSED_BUT_SET_VARIABLE)
get_directory_property(cmake_include_directories INCLUDE_DIRECTORIES)
set(swig_include_dirs)
foreach(it ${cmake_include_directories})
set(swig_include_dirs ${swig_include_dirs} "-I${it}")
endforeach()
set(swig_special_flags)
# default is c, so add c++ flag if it is c++
if(swig_source_file_cplusplus)
set(swig_special_flags ${swig_special_flags} "-c++")
endif()
set(swig_extra_flags)
if(SWIG_MODULE_${name}_EXTRA_FLAGS)
set(swig_extra_flags ${swig_extra_flags} ${SWIG_MODULE_${name}_EXTRA_FLAGS})
endif()
# hack to work around CMake bug in add_custom_command with multiple OUTPUT files
file(RELATIVE_PATH reldir ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib
unique = hashlib.md5('${reldir}${ARGN}').hexdigest()[:5]
print(re.sub('\\W', '_', '${name} ${reldir} ' + unique))"
OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE
)
file(
WRITE ${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp.in
"int main(void){return 0;}\n"
)
# create dummy dependencies
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp.in
${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp
DEPENDS "${swig_source_file_fullname}" ${SWIG_MODULE_${name}_EXTRA_DEPS}
COMMENT ""
)
# create the dummy target
add_executable(${_target} ${CMAKE_CURRENT_BINARY_DIR}/${_target}.cpp)
# add a custom command to the dummy target
add_custom_command(
TARGET ${_target}
# Let's create the ${swig_outdir} at execution time, in case dir contains $(OutDir)
COMMAND ${CMAKE_COMMAND} -E make_directory ${swig_outdir}
COMMAND "${SWIG_EXECUTABLE}"
ARGS "-${SWIG_MODULE_${name}_SWIG_LANGUAGE_FLAG}"
${swig_source_file_flags}
${CMAKE_SWIG_FLAGS}
-outdir ${swig_outdir}
${swig_special_flags}
${swig_extra_flags}
${swig_include_dirs}
-o "${swig_generated_file_fullname}"
"${swig_source_file_fullname}"
COMMENT "Swig source"
)
#add dummy independent dependencies from the _target to each file
#that will be generated by the SWIG command above
set(${outfiles} "${swig_generated_file_fullname}" ${swig_extra_generated_files})
foreach(swig_gen_file ${${outfiles}})
add_custom_command(
OUTPUT ${swig_gen_file}
COMMAND ""
DEPENDS ${_target}
COMMENT ""
)
endforeach()
set_source_files_properties(
${outfiles} PROPERTIES GENERATED 1
)
endmacro()
#
# Create Swig module
#
macro(SWIG_ADD_MODULE name language)
SWIG_MODULE_INITIALIZE(${name} ${language})
set(swig_dot_i_sources)
set(swig_other_sources)
foreach(it ${ARGN})
if(${it} MATCHES ".*\\.i$")
set(swig_dot_i_sources ${swig_dot_i_sources} "${it}")
else()
set(swig_other_sources ${swig_other_sources} "${it}")
endif()
endforeach()
set(swig_generated_sources)
foreach(it ${swig_dot_i_sources})
SWIG_ADD_SOURCE_TO_MODULE(${name} swig_generated_source ${it})
set(swig_generated_sources ${swig_generated_sources} "${swig_generated_source}")
endforeach()
get_directory_property(swig_extra_clean_files ADDITIONAL_MAKE_CLEAN_FILES)
set_directory_properties(PROPERTIES
ADDITIONAL_MAKE_CLEAN_FILES "${swig_extra_clean_files};${swig_generated_sources}")
add_library(${SWIG_MODULE_${name}_REAL_NAME}
MODULE
${swig_generated_sources}
${swig_other_sources})
string(TOLOWER "${language}" swig_lowercase_language)
if ("${swig_lowercase_language}" STREQUAL "java")
if (APPLE)
# In java you want:
# System.loadLibrary("LIBRARY");
# then JNI will look for a library whose name is platform dependent, namely
# MacOS : libLIBRARY.jnilib
# Windows: LIBRARY.dll
# Linux : libLIBRARY.so
set_target_properties (${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".jnilib")
endif ()
endif ()
if ("${swig_lowercase_language}" STREQUAL "python")
# this is only needed for the python case where a _modulename.so is generated
set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES PREFIX "")
# Python extension modules on Windows must have the extension ".pyd"
# instead of ".dll" as of Python 2.5. Older python versions do support
# this suffix.
# http://docs.python.org/whatsnew/ports.html#SECTION0001510000000000000000
# <quote>
# Windows: .dll is no longer supported as a filename extension for extension modules.
# .pyd is now the only filename extension that will be searched for.
# </quote>
if(WIN32 AND NOT CYGWIN)
set_target_properties(${SWIG_MODULE_${name}_REAL_NAME} PROPERTIES SUFFIX ".pyd")
endif()
endif ()
endmacro()
#
# Like TARGET_LINK_LIBRARIES but for swig modules
#
macro(SWIG_LINK_LIBRARIES name)
if(SWIG_MODULE_${name}_REAL_NAME)
target_link_libraries(${SWIG_MODULE_${name}_REAL_NAME} ${ARGN})
else()
message(SEND_ERROR "Cannot find Swig library \"${name}\".")
endif()
endmacro()

5
cmake/Modules/multirdsConfig.cmake

@ -22,9 +22,10 @@ FIND_LIBRARY(
/usr/local/lib64
/usr/lib
/usr/lib64
)
)
include("${CMAKE_CURRENT_LIST_DIR}/multirdsTarget.cmake")
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(MULTIRDS DEFAULT_MSG MULTIRDS_LIBRARIES MULTIRDS_INCLUDE_DIRS)
MARK_AS_ADVANCED(MULTIRDS_LIBRARIES MULTIRDS_INCLUDE_DIRS)

28
grc/CMakeLists.txt

@ -17,18 +17,18 @@
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
install(FILES
multirds_rds_table_qt.xml
multirds_rds_parser_table_qt.xml
multirds_rds_decoder.xml
multirds_station_search.xml
multirds_stream_selector.xml
multirds_vector_cutter.xml
multirds_decoder_compare.xml
multirds_symbol_combiner.xml
multirds_rds_decoder_redsea.xml
multirds_qtgui_range.xml
multirds_variable_setter.xml
multirds_tmc_parser.xml
multirds_pilot_SNR.xml
multirds_stream_router.xml DESTINATION share/gnuradio/grc/blocks
multirds_rds_table_qt.block.yml
multirds_rds_parser_table_qt.block.yml
multirds_rds_decoder.block.yml
multirds_station_search.block.yml
multirds_stream_selector.block.yml
multirds_vector_cutter.block.yml
multirds_decoder_compare.block.yml
multirds_symbol_combiner.block.yml
multirds_rds_decoder_redsea.block.yml
multirds_variable_setter.block.yml
multirds_tmc_parser.block.yml
multirds_pilot_SNR.block.yml
multirds_stream_router.block.yml
DESTINATION share/gnuradio/grc/blocks
)

25
grc/multirds_decoder_compare.block.yml

@ -0,0 +1,25 @@
# auto-generated by grc.converter
id: multirds_decoder_compare
label: decoder_compare
category: '[multirds]'
parameters:
- id: nPorts
label: Number of Ports
dtype: int
default: '2'
hide: part
inputs:
- domain: message
id: in
multiplicity: ${ nPorts }
asserts:
- ${ nPorts > 0 }
templates:
imports: import multirds
make: multirds.decoder_compare(${nPorts})
file_format: 1

28
grc/multirds_decoder_compare.xml

@ -1,28 +0,0 @@
<?xml version="1.0"?>
<block>
<name>decoder_compare</name>
<key>multirds_decoder_compare</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>multirds.decoder_compare($nPorts)</make>
<!-- Make one 'param' node for every Parameter you want settable from the GUI.
Sub-nodes:
* name
* key (makes the value accessible as $keyname, e.g. in the make node)
* type -->
<param>
<name>Number of Ports</name>
<key>nPorts</key>
<value>2</value>
<type>int</type>
<hide>part</hide>
</param>
<check>$nPorts &gt; 0</check>
<sink>
<name>in</name>
<type>message</type>
<nports>$nPorts</nports>
<!-- <optional>1</optional> -->
</sink>
</block>

57
grc/multirds_pilot_SNR.block.yml

@ -0,0 +1,57 @@
# auto-generated by grc.converter
id: multirds_pilot_SNR
label: pilot_SNR
category: '[multirds]'
parameters:
- id: debug
label: Debug
dtype: bool
default: 'False'
options: ['True', 'False']
option_labels: [Enable, Disable]
- id: carrier_freq
label: carrier_freq
dtype: float
default: 19e3
- id: gap_width
label: gap_width
dtype: float
default: 4e3
- id: update_period
label: update_period
dtype: float
default: '0.2'
- id: samp_rate
label: samp_rate
dtype: int
default: '240000'
- id: fft_len
label: fft_len
dtype: int
default: '2048'
- id: msg_adr
label: msg_adr
dtype: int
default: '3'
inputs:
- domain: stream
dtype: float
vlen: ${ fft_len }
outputs:
- domain: message
id: out
optional: true
templates:
imports: import multirds
make: multirds.pilot_SNR(${debug}, ${samp_rate}, ${fft_len}, ${carrier_freq},${gap_width},
${msg_adr},${update_period})
documentation: |-
outputs PMT pair of longs (msg_adr . SNR) SNR is calculated as difference (in dB) between the 19k carrier power and the average power between carrier_freq-gap_width and carrier_freq+gap_width \
file_format: 1

84
grc/multirds_pilot_SNR.xml

@ -1,84 +0,0 @@
<?xml version="1.0"?>
<block>
<name>pilot_SNR</name>
<key>multirds_pilot_SNR</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>multirds.pilot_SNR($debug, $samp_rate, $fft_len, $carrier_freq,$gap_width, $msg_adr,$update_period)</make>
<!-- Make one 'param' node for every Parameter you want settable from the GUI.
Sub-nodes:
* name
* key (makes the value accessible as $keyname, e.g. in the make node)
* type -->
<param>
<name>Debug</name>
<key>debug</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<param>
<name>carrier_freq</name>
<key>carrier_freq</key>
<value>19e3</value>
<type>float</type>
</param>
<param>
<name>gap_width</name>
<key>gap_width</key>
<value>4e3</value>
<type>float</type>
</param>
<param>
<name>update_period</name>
<key>update_period</key>
<value>0.2</value>
<type>float</type>
</param>
<param>
<name>samp_rate</name>
<key>samp_rate</key>
<value>240000</value>
<type>int</type>
</param>
<param>
<name>fft_len</name>
<key>fft_len</key>
<value>2048</value>
<type>int</type>
</param>
<param>
<name>msg_adr</name>
<key>msg_adr</key>
<value>3</value>
<type>int</type>
</param>
<!-- Make one 'sink' node per input. Sub-nodes:
* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<sink>
<name>in</name>
<type>float</type>
<vlen>$fft_len</vlen>
</sink>
<source>
<name>out</name>
<type>message</type>
<optional>1</optional>
</source>
<doc>outputs PMT pair of longs (msg_adr . SNR) \
SNR is calculated as difference (in dB)\
between the 19k carrier power and the \
average power between carrier_freq-gap_width and carrier_freq+gap_width \
</doc>
</block>

136
grc/multirds_qtgui_range.xml

@ -1,136 +0,0 @@
<?xml version="1.0"?>
<block>
<name>qtgui_range (cr)</name>
<key>variable_multirds_qtgui_range</key>
<category>[multirds]</category>
<import>import multirds</import>
<import>from multirds.qtgui_range import qtgui_range, RangeWidget</import>
<var_make>self.$(id) = $(id) = $value</var_make>
<make>#set $win = 'self._%s_win'%$id
#set $range = 'self.%s_range'%$id
#if not $label()
#set $label = '"%s"'%$id
#end if
$(range) = qtgui_range($start, $stop, $step, $value, $min_len)
$(win) = RangeWidget($range, self.set_$(id), $label, "$widget", $rangeType)
$(gui_hint()($win))</make>
<!--<callback>self.freq2_range.set_test($value);</callback>-->
<!-- <callback>self.set_$(id)($value)</callback> -->
<!-- <callback>set_test($(id));</callback> -->
<!-- <callback>self._$(id)_win.set_test($(id));</callback>-->
<param>
<name>Label</name>
<key>label</key>
<value></value>
<type>string</type>
<hide>#if $label() then 'none' else 'part'#</hide>
</param>
<param>
<name>Type</name>
<key>rangeType</key>
<value>"float"</value>
<type>enum</type>
<hide>part</hide>
<option><name>Float</name><key>float</key><opt>type:float</opt></option>
<option><name>Int</name><key>int</key><opt>type:int</opt></option>
</param>
<param>
<name>Default Value</name>
<key>value</key>
<value>50</value>
<type>$rangeType.type</type>
</param>
<param>
<name>Start</name>
<key>start</key>
<value>0</value>
<type>$rangeType.type</type>
</param>
<param>
<name>Stop</name>
<key>stop</key>
<value>100</value>
<type>$rangeType.type</type>
</param>
<param>
<name>Step</name>
<key>step</key>
<value>1</value>
<type>$rangeType.type</type>
</param>
<param>
<name>Widget</name>
<key>widget</key>
<value>counter_slider</value>
<type>enum</type>
<hide>part</hide>
<option><name>Counter + Slider</name><key>counter_slider</key></option>
<option><name>Counter</name><key>counter</key></option>
<option><name>Slider</name><key>slider</key></option>
<option><name>Knob</name><key>dial</key></option>
</param>
<param>
<name>Orientation</name>
<key>orient</key>
<value>Qt.Horizontal</value>
<type>enum</type>
<hide>#if $widget() == "slider" then 'part' else 'all'#</hide>
<option>
<name>Horizontal</name>
<key>Qt.Horizontal</key>
<opt>scalepos:BottomScale</opt>
<opt>minfcn:setMinimumWidth</opt>
</option>
<option>
<name>Vertical</name>
<key>Qt.Vertical</key>
<opt>scalepos:LeftScale</opt>
<opt>minfcn:setMinimumHeight</opt>
</option>
</param>
<param>
<name>Minimum Length</name>
<key>min_len</key>
<value>200</value>
<type>int</type>
<hide>part</hide>
</param>
<!-- from min_len <hide>#if $widget().split('_')[0] in ("slider", "counter") then 'part' else 'all'#</hide>-->
<param>
<name>GUI Hint</name>
<key>gui_hint</key>
<value></value>
<type>gui_hint</type>
<hide>part</hide>
</param>
<check>$start &lt;= $value &lt;= $stop</check>
<check>$start &lt; $stop</check>
<!-- <sink>
<name>set</name>
<type>message</type>
<optional>1</optional>
</sink>-->
<doc>
This block creates a variable with a slider. \
Leave the label blank to use the variable id as the label. \
The value must be a real number. \
The value must be between the start and the stop.
The GUI hint can be used to position the widget within the application. \
The hint is of the form [tab_id@tab_index]: [row, col, row_span, col_span]. \
Both the tab specification and the grid position are optional.
</doc>
</block>

32
grc/multirds_rds_decoder.block.yml

@ -0,0 +1,32 @@
# auto-generated by grc.converter
id: multirds_rds_decoder
label: multirds Rds decoder
category: '[multirds]'
parameters:
- id: log
label: Log
dtype: bool
default: 'False'
options: ['True', 'False']
option_labels: [Enable, Disable]
- id: debug
label: Debug
dtype: bool
default: 'False'
options: ['True', 'False']
option_labels: [Enable, Disable]
inputs:
- domain: stream
dtype: byte
outputs:
- domain: message
optional: true
templates:
imports: import multirds
make: multirds.rds_decoder(${log}, ${debug})
file_format: 1

45
grc/multirds_rds_decoder.xml

@ -1,45 +0,0 @@
<?xml version="1.0"?>
<block>
<name>RDS Decoder (cr)</name>
<key>multirds_rds_decoder</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>multirds.rds_decoder($log, $debug)</make>
<param>
<name>Log</name>
<key>log</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<param>
<name>Debug</name>
<key>debug</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<sink>
<name>in</name>
<type>byte</type>
</sink>
<source>
<name>out</name>
<type>message</type>
<optional>1</optional>
</source>
</block>

32
grc/multirds_rds_decoder_redsea.block.yml

@ -0,0 +1,32 @@
# auto-generated by grc.converter
id: multirds_rds_decoder_redsea
label: multirds Rds decoder redsea
category: '[multirds]'
parameters:
- id: log
label: Log
dtype: bool
default: 'False'
options: ['True', 'False']
option_labels: [Enable, Disable]
- id: debug
label: Debug
dtype: bool
default: 'False'
options: ['True', 'False']
option_labels: [Enable, Disable]
inputs:
- domain: stream
dtype: byte
outputs:
- domain: message
optional: true
templates:
imports: import multirds
make: multirds.rds_decoder_redsea(${log}, ${debug})
file_format: 1

45
grc/multirds_rds_decoder_redsea.xml

@ -1,45 +0,0 @@
<?xml version="1.0"?>
<block>
<name>RDS Decoder (redsea)</name>
<key>multirds_rds_decoder_redsea</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>multirds.rds_decoder_redsea($log, $debug)</make>
<param>
<name>Log</name>
<key>log</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<param>
<name>Debug</name>
<key>debug</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<sink>
<name>in</name>
<type>byte</type>
</sink>
<source>
<name>out</name>
<type>message</type>
<optional>1</optional>
</source>
</block>

96
grc/multirds_rds_parser_table_qt.block.yml

@ -0,0 +1,96 @@
# auto-generated by grc.converter
id: multirds_rds_parser_table_qt
label: RDS Parser Table (qt)
category: '[multirds]'
parameters:
- id: freq_tune
label: tuned frequency
dtype: float
- id: label
label: Label
dtype: string
hide: ${ ('none' if label else 'part') }
- id: workdir
label: work directory
dtype: string
hide: part
- id: gui_hint
label: GUI Hint
dtype: gui_hint
hide: part
- id: nPorts
label: Number of Ports
dtype: int
default: '2'
hide: part
- id: log
label: Log
dtype: bool
default: 'False'
options: ['True', 'False']
option_labels: [Enable, Disable]
- id: debug
label: Debug
dtype: bool
default: 'False'
options: ['True', 'False']
option_labels: [Enable, Disable]
- id: writeDB
label: write Database
dtype: bool
default: 'False'
options: ['True', 'False']
option_labels: [Enable, Disable]
inputs:
- domain: message
id: in
multiplicity: ${ nPorts }
- domain: message
id: freq
optional: true
outputs:
- domain: message
id: ctrl
optional: true
- domain: message
id: tmc_raw
optional: true
asserts:
- ${ open(workdir+"pty-list.csv").close() or True }
- ${ open(workdir+"directory_writable","w").close() or True }
- ${ nPorts > 0 }
templates:
imports: |-
import multirds
from multirds.rds_parser_table_qt import rds_parser_table_qt, rds_parser_table_qt_Widget,rds_parser_table_qt_Signals
make: "<% win = 'self._%s_win'%id %>\n\t\t<% signals = 'self._%s_signals'%id %>\n\
% if not label:\n\t<% label = '\"%s\"'%id %>\n% endif\n${signals} = rds_parser_table_qt_Signals()\n\
self.${id} = multirds.rds_parser_table_qt(${signals},${nPorts},self.set_${freq_tune},${freq_tune},${log},\
\ ${debug},${workdir},${writeDB})\n${win} = rds_parser_table_qt_Widget(${signals},\
\ ${label},self.${id})\n${gui_hint(in)}"
make: |-
<%
win = 'self._%s_win'%id
signals = 'self._%s_signals'%id
%>\
${signals} = rds_parser_table_qt_Signals()
self.${id} = multirds.rds_parser_table_qt(${signals},${nPorts},self.set_${freq_tune},${freq_tune},${log},${debug},${workdir},${writeDB})
${win} = rds_parser_table_qt_Widget(${signals},${label},self.${id})
${gui_hint() % win}
callbacks:
- set_freq_tune(${freq_tune});
documentation: "show RDS data from multiple stations in QT table input: raw group\
\ data (array of ints) 4x2 raw block data, 4x1 offset chars, 1x1 number of valid\
\ blocks (of last 50) [block1_upper,block1_lower,block2_upper,block2_lower,...,offset1,offset2,offset3,offset4,numerrors]\\\
\ \n The GUI hint can be used to position the widget within the application.\
\ The hint is of the form \"tab_id@tab_index: row, col, row_span, col_span\"\
\ Both the tab specification and the grid position are optional."
file_format: 1

141
grc/multirds_rds_parser_table_qt.xml

@ -1,141 +0,0 @@
<?xml version="1.0"?>
<block>
<name>RDS Parser Table (qt)</name>
<key>multirds_rds_parser_table_qt</key>
<category>[multirds]</category>
<import>import multirds</import>
<import>from multirds.rds_parser_table_qt import rds_parser_table_qt, rds_parser_table_qt_Widget,rds_parser_table_qt_Signals</import>
<!--
<var_make>self.$(id) = $(id) = $value</var_make>
-->
<make>#set $win = 'self._%s_win'%$id
#set $signals = 'self._%s_signals'%$id
#if not $label()
#set $label = '"%s"'%$id
#end if
$(signals) = rds_parser_table_qt_Signals()
self.$(id) = multirds.rds_parser_table_qt($(signals),$nPorts,self.set_$(freq_tune),$freq_tune,$log, $debug,$workdir,$writeDB)
$(win) = rds_parser_table_qt_Widget($signals, $label,self.$(id))
$(gui_hint()($win))</make>
<callback>set_freq_tune($freq_tune);</callback>
<param>
<name>tuned frequency</name>
<key>freq_tune</key>
<value></value>
<type>float</type>
</param>
<param>
<name>Label</name>
<key>label</key>
<value></value>
<type>string</type>
<hide>#if $label() then 'none' else 'part'#</hide>
</param>
<param>
<name>work directory</name>
<key>workdir</key>
<value></value>
<type>string</type>
<hide>part</hide>
</param>
<param>
<name>GUI Hint</name>
<key>gui_hint</key>
<value></value>
<type>gui_hint</type>
<hide>part</hide>
</param>
<param>
<name>Number of Ports</name>
<key>nPorts</key>
<value>2</value>
<type>int</type>
<hide>part</hide>
</param>
<param>
<name>Log</name>
<key>log</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<param>
<name>Debug</name>
<key>debug</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<param>
<name>write Database</name>
<key>writeDB</key>
<value>False</value>
<type>bool</type>
<!--<hide>part</hide>-->
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<!--
check if pty list file exists
check directory doesnt work:
<check>os.path.isdir($workdir)</check>
-->
<check>open($workdir+"pty-list.csv").close() or True</check>
<!--
check if workdir is writable
-->
<check>open($workdir+"directory_writable","w").close() or True</check>
<check>$nPorts &gt; 0</check>
<sink>
<name>in</name>
<type>message</type>
<nports>$nPorts</nports>
<!-- <optional>1</optional> -->
</sink>
<sink>
<name>freq</name>
<type>message</type>
<optional>1</optional>
</sink>
<source>
<name>ctrl</name>
<type>message</type>
<optional>1</optional>
</source>
<source>
<name>tmc_raw</name>
<type>message</type>
<optional>1</optional>
</source>
<doc>show RDS data from multiple stations in QT table \
input: raw group data (array of ints) \
4x2 raw block data, 4x1 offset chars, 1x1 number of valid blocks (of last 50) \
[block1_upper,block1_lower,block2_upper,block2_lower,...,offset1,offset2,offset3,offset4,numerrors]\\
The GUI hint can be used to position the widget within the application. \
The hint is of the form "tab_id@tab_index: row, col, row_span, col_span" \
Both the tab specification and the grid position are optional.
</doc>
</block>

37
grc/multirds_rds_table_qt.block.yml

@ -0,0 +1,37 @@
# auto-generated by grc.converter
id: multirds_rds_table_qt
label: RDS Table (qt)
category: '[multirds]'
parameters:
- id: label
label: Label
dtype: string
hide: ${ ('none' if label else 'part') }
- id: gui_hint
label: GUI Hint
dtype: gui_hint
hide: part
- id: nPorts
label: Number of Ports
dtype: int
default: '2'
hide: part
inputs:
- domain: message
id: in
multiplicity: ${ nPorts }
templates:
imports: |-
import multirds
from multirds.rds_table_qt import rds_table_qt, rds_table_qt_Widget,rds_table_qt_Signals
var_make: self.${id} = ${id} = ${value}
make: "<% win = 'self._%s_win'%id %>\n\t\t<% signals = 'self._%s_signals'%id %>\n\
% if not label:\n\t<% label = '\"%s\"'%id %>\n% endif\n${signals} = rds_table_qt_Signals()\n\
self.${id} = multirds.rds_table_qt(${signals},${nPorts})\n${win} = rds_table_qt_Widget(${signals},\
\ ${label})\n${gui_hint(in)}"
file_format: 1

46
grc/multirds_rds_table_qt.xml

@ -1,46 +0,0 @@
<?xml version="1.0"?>
<block>
<name>RDS Table (qt)</name>
<key>multirds_rds_table_qt</key>
<category>[multirds]</category>
<import>import multirds</import>
<import>from multirds.rds_table_qt import rds_table_qt, rds_table_qt_Widget,rds_table_qt_Signals</import>
<var_make>self.$(id) = $(id) = $value</var_make>
<make>#set $win = 'self._%s_win'%$id
#set $signals = 'self._%s_signals'%$id
#if not $label()
#set $label = '"%s"'%$id
#end if
$(signals) = rds_table_qt_Signals()
self.$(id) = multirds.rds_table_qt($(signals),$nPorts)
$(win) = rds_table_qt_Widget($signals, $label)
$(gui_hint()($win))</make>
<param>
<name>Label</name>
<key>label</key>
<value></value>
<type>string</type>
<hide>#if $label() then 'none' else 'part'#</hide>
</param>
<param>
<name>GUI Hint</name>
<key>gui_hint</key>
<value></value>
<type>gui_hint</type>
<hide>part</hide>
</param>
<param>
<name>Number of Ports</name>
<key>nPorts</key>
<value>2</value>
<type>int</type>
<hide>part</hide>
</param>
<sink>
<name>in</name>
<type>message</type>
<nports>$nPorts</nports>
<!--<optional>1</optional>-->
</sink>
</block>

52
grc/multirds_station_search.block.yml

@ -0,0 +1,52 @@
# auto-generated by grc.converter
id: multirds_station_search
label: station_search
category: '[multirds]'
parameters:
- id: fft_len
label: fft lenngth
dtype: int
hide: ${ 'part' if vlen == 1 else 'none' }
- id: round_to
label: round to (in hz)
dtype: int
- id: num_decoders
label: number of decoders
dtype: int
hide: part
- id: center_freq
label: center frequency
dtype: float
- id: samp_rate
label: sample rate
dtype: int
- id: debug
label: Debug
dtype: bool
default: 'False'
options: ['True', 'False']
option_labels: [Enable, Disable]
hide: part
inputs:
- domain: stream
dtype: float
vlen: ${ fft_len }
- domain: message
id: ctrl
optional: true
outputs:
- domain: message
id: out
optional: true
templates:
imports: import multirds
make: multirds.station_search(${fft_len}, ${num_decoders}, ${center_freq}, ${samp_rate},${round_to},${debug})
callbacks:
- set_center_freq(${center_freq});
file_format: 1

78
grc/multirds_station_search.xml

@ -1,78 +0,0 @@
<?xml version="1.0"?>
<block>
<name>station_search</name>
<key>multirds_station_search</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>multirds.station_search($fft_len, $num_decoders, $center_freq, $samp_rate,$round_to,$debug)</make>
<!-- Make one 'param' node for every Parameter you want settable from the GUI.
Sub-nodes:
* name
* key (makes the value accessible as $keyname, e.g. in the make node)
* type -->
<callback>set_center_freq($center_freq);</callback>
<param>
<name>fft lenngth</name>
<key>fft_len</key>
<type>int</type>
</param>
<param>
<name>round to (in hz)</name>
<key>round_to</key>
<type>int</type>
</param>
<param>
<name>number of decoders</name>
<key>num_decoders</key>
<type>int</type>
<hide>part</hide>
</param>
<param>
<name>center frequency</name>
<key>center_freq</key>
<type>float</type>
</param>
<param>
<name>sample rate</name>
<key>samp_rate</key>
<type>int</type>
</param>
<param>
<name>Debug</name>
<key>debug</key>
<value>False</value>
<type>bool</type>
<hide>part</hide>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<!-- Make one 'sink' node per input. Sub-nodes:
* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<sink>
<name>in</name>
<type>float</type>
<vlen>$fft_len</vlen>
</sink>
<sink>
<name>ctrl</name>
<type>message</type>
<optional>1</optional>
</sink>
<source>
<name>out</name>
<type>message</type>
<optional>1</optional>
</source>
</block>

29
grc/multirds_stream_router.block.yml

@ -0,0 +1,29 @@
# auto-generated by grc.converter
id: multirds_stream_router
label: Stream router
category: '[MULTIRDS]'
parameters:
- id: ninputs
label: Ninputs
dtype: int
- id: noutputs
label: Noutputs
dtype: int
inputs:
- domain: stream
dtype: float
multiplicity: '9'
outputs:
- domain: stream
dtype: float
multiplicity: '3'
templates:
imports: import multirds
make: multirds.stream_router(${ninputs}, ${noutputs})
file_format: 1

54
grc/multirds_stream_router.xml

@ -1,54 +0,0 @@
<?xml version="1.0"?>
<block>
<name>stream_router</name>
<key>multirds_stream_router</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>multirds.stream_router($ninputs, $noutputs)</make>
<param>
<name>Type</name>
<key>type</key>
<value>float</value>
<type>enum</type>
<option><name>Complex</name><key>complex</key><opt>fcn:sink_c</opt></option>
<option><name>Float</name><key>float</key><opt>fcn:sink_f</opt></option>
</param>
<param>
<name>Number of inputs</name>
<key>ninputs</key>
<value>9</value>
<type>int</type>
</param>
<param>
<name>Number of outputs</name>
<key>noutputs</key>
<value>3</value>
<type>int</type>
</param>
<!-- Make one 'sink' node per input. Sub-nodes:
* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<sink>
<name>in</name>
<type>$type</type>
<nports>$ninputs</nports>
</sink>
<sink>
<name>ctrl</name>
<type>message</type>
</sink>
<!-- Make one 'source' node per output. Sub-nodes:
* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<source>
<name>out</name>
<type>$type</type>
<nports>$noutputs</nports>
</source>
</block>

30
grc/multirds_stream_selector.block.yml

@ -0,0 +1,30 @@
# auto-generated by grc.converter
id: multirds_stream_selector
label: stream_selector
category: '[multirds]'
inputs:
- label: in_re
domain: stream
dtype: float
- label: in_arg
domain: stream
dtype: float
- domain: message
id: rds_re
optional: true
- domain: message
id: rds_arg
optional: true
outputs:
- domain: message
id: rds_out
optional: true
templates:
imports: import multirds
make: multirds.stream_selector()
file_format: 1

38
grc/multirds_stream_selector.xml

@ -1,38 +0,0 @@
<?xml version="1.0"?>
<block>
<name>stream_selector</name>
<key>multirds_stream_selector</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>multirds.stream_selector()</make>
<!-- <param>
<name>...</name>
<key>...</key>
<type>...</type>
</param>-->
<sink>
<name>in_re</name>
<type>float</type>
</sink>
<sink>
<name>in_arg</name>
<type>float</type>
</sink>
<sink>
<name>rds_re</name>
<type>message</type>
<optional>1</optional>
</sink>
<sink>
<name>rds_arg</name>
<type>message</type>
<optional>1</optional>
</sink>
<source>
<name>rds_out</name>
<type>message</type>
<optional>1</optional>
</source>
</block>

30
grc/multirds_symbol_combiner.block.yml

@ -0,0 +1,30 @@
# auto-generated by grc.converter
id: multirds_symbol_combiner
label: Symbol combiner
category: '[MULTIRDS]'
parameters:
- id: threshold
label: Threshold
dtype: float
- id: min_diff
label: Min_diff
dtype: float
- id: log
label: Log
dtype: raw
inputs:
- domain: stream
dtype: float
outputs:
- domain: stream
dtype: float
templates:
imports: import multirds
make: multirds.symbol_combiner(${threshold}, ${min_diff}, ${log})
file_format: 1

70
grc/multirds_symbol_combiner.xml

@ -1,70 +0,0 @@
<?xml version="1.0"?>
<block>
<name>symbol_combiner</name>
<key>multirds_symbol_combiner</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>multirds.symbol_combiner($threshold, $min_diff, $log)</make>
<!-- Make one 'param' node for every Parameter you want settable from the GUI.
Sub-nodes:
* name
* key (makes the value accessible as $keyname, e.g. in the make node)
* type -->
<param>
<name>Log</name>
<key>log</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<param>
<name>Threshold</name>
<key>threshold</key>
<value>0.25</value>
<type>float</type>
</param>
<param>
<name>min_diff</name>
<key>min_diff</key>
<value>0.2</value>
<type>float</type>
</param>
<check>0 &lt; $min_diff &lt; 1</check>
<!-- Make one 'sink' node per input. Sub-nodes:
* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<sink>
<name>in</name>
<type>float</type>
</sink>
<sink>
<name>ctrl</name>
<type>message</type>
<optional>1</optional>
</sink>
<!-- Make one 'source' node per output. Sub-nodes:
* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<source>
<name>ctrl</name>
<type>message</type>
<optional>1</optional>
</source>
<source>
<name>out</name>
<type>float</type>
</source>
</block>

62
grc/multirds_tmc_parser.block.yml

@ -0,0 +1,62 @@
# auto-generated by grc.converter
id: multirds_tmc_parser
label: tmc_parser
category: '[multirds]'
parameters:
- id: maxheight
label: maxheight
dtype: int
default: '160'
hide: part
- id: workdir
label: work directory
dtype: string
hide: part
- id: label
label: Label
dtype: string
hide: ${ ('none' if label else 'part') }
- id: log
label: Log
dtype: bool
default: 'False'
options: ['True', 'False']
option_labels: [Enable, Disable]
- id: debug
label: Debug
dtype: bool
default: 'False'
options: ['True', 'False']
option_labels: [Enable, Disable]
- id: writeDB
label: write Database
dtype: bool
default: 'False'
options: ['True', 'False']
option_labels: [Enable, Disable]
- id: gui_hint
label: GUI Hint
dtype: gui_hint
hide: part
inputs:
- domain: message
id: in
optional: true
asserts:
- ${ open(workdir+"event-list_with_forecast_sort.csv").close() or True }
- ${ open(workdir+"directory_writable","w").close() or True }
templates:
imports: import multirds
make: "<% win = 'self._%s_win'%id %>\n <% parser = 'self.%s_parser'%id\
\ %>\n% if not label:\n\t<% label = '\"%s\"'%id %>\n% endif\n${parser} = multirds.tmc_parser(${workdir},\
\ ${log}, ${debug}, ${writeDB},${maxheight})\n${win} = ${parser}.getqtwidget()\n\
${gui_hint(in)}\n "
documentation: "maxheight = max height of widget in pixels\n\t maxheight == 0 ->\
\ no restriction"
file_format: 1

112
grc/multirds_tmc_parser.xml

@ -1,112 +0,0 @@
<?xml version="1.0"?>
<block>
<name>tmc_parser</name>
<key>multirds_tmc_parser</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>#set $win = 'self._%s_win'%$id
#set $parser = 'self.%s_parser'%$id
#if not $label()
#set $label = '"%s"'%$id
#end if
$(parser) = multirds.tmc_parser($workdir, $log, $debug, $writeDB,$maxheight)
$(win) = $(parser).getqtwidget()
$(gui_hint()($win))
</make>
<!--
multirds.tmc_parser($workdir, $log, $debug, $writeDB)
-->
<param>
<name>maxheight</name>
<key>maxheight</key>
<value>160</value>
<type>int</type>
<hide>part</hide>
</param>
<param>
<name>work directory</name>
<key>workdir</key>
<value></value>
<type>string</type>
<hide>part</hide>
</param>
<param>
<name>Label</name>
<key>label</key>
<value></value>
<type>string</type>
<hide>#if $label() then 'none' else 'part'#</hide>
</param>
<param>
<name>Log</name>
<key>log</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<param>
<name>Debug</name>
<key>debug</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<param>
<name>write Database</name>
<key>writeDB</key>
<value>False</value>
<type>bool</type>
<!--<hide>part</hide>-->
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<param>
<name>GUI Hint</name>
<key>gui_hint</key>
<value></value>
<type>gui_hint</type>
<hide>part</hide>
</param>
<!--
check if event-list file exists
check directory doesnt work:
<check>os.path.isdir($workdir)</check>
-->
<check>open($workdir+"event-list_with_forecast_sort.csv").close() or True</check>
<!--
check if workdir is writable
-->
<check>open($workdir+"directory_writable","w").close() or True</check>
<sink>
<name>in</name>
<type>message</type>
<optional>1</optional>
</sink>
<doc>
maxheight = max height of widget in pixels
maxheight == 0 -> no restriction
</doc>
</block>

37
grc/multirds_variable_setter.block.yml

@ -0,0 +1,37 @@
# auto-generated by grc.converter
id: multirds_variable_setter
label: variable_setter
category: '[multirds]'
parameters:
- id: varname
label: varname
dtype: raw
- id: is_pair
label: Pair Mode
dtype: enum
default: 'False'
options: ['False', 'True']
- id: msgkey
label: Key
dtype: string
hide: ${ ('none' if is_pair == 'True' else 'all') }
inputs:
- domain: message
id: in
templates:
imports: import multirds
make: |-
<% block = 'self.%s'%id %>
<% varsetter = 'self.set_%s'%varname %>
<% guiupdater = 'self._%s_win.update_gui'%varname %>
multirds.variable_setter("$varname",${varsetter},${guiupdater},${is_pair},${msgkey})
documentation: |-
in pair mode this block only accepts PMT pairs that have a matching CAR
no pair mode: block accepts pmt symbols directly
file_format: 1

59
grc/multirds_variable_setter.xml

@ -1,59 +0,0 @@
<?xml version="1.0"?>
<block>
<name>variable_setter</name>
<key>multirds_variable_setter</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>#set $block = 'self.%s'%$id
#set $varsetter = 'self.set_%s'%$varname
#set $guiupdater = 'self._%s_win.update_gui'%$varname
multirds.variable_setter("$varname",$varsetter,$guiupdater,$is_pair,$msgkey)</make>
<!--$(block) = multirds.variable_setter($varname,$varsetter) -->
<param>
<name>varname</name>
<key>varname</key>
<value></value>
<type>raw</type>
</param>
<param>
<name>Pair Mode</name>
<key>is_pair</key>
<value>False</value>
<type>enum</type>
<option>
<name>False</name>
<key>False</key>
</option>
<option>
<name>True</name>
<key>True</key>
</option>
</param>
<param>
<name>Key</name>
<key>msgkey</key>
<value></value>
<type>string</type>
<hide>#if $is_pair() == 'True' then 'none' else 'all'#</hide>
</param>
<!-- Make one 'sink' node per input. Sub-nodes:
* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<sink>
<name>in</name>
<type>message</type>
</sink>
<!-- Make one 'source' node per output. Sub-nodes:
* name (an identifier for the GUI)
* type
* vlen
* optional (set to 1 for optional inputs) -->
<doc>
in pair mode this block only accepts PMT pairs that have a matching CAR
no pair mode: block accepts pmt symbols directly
</doc>
</block>

55
grc/multirds_vector_cutter.block.yml

@ -0,0 +1,55 @@
# auto-generated by grc.converter
id: multirds_vector_cutter
label: vector_cutter
category: '[multirds]'
parameters:
- id: pad_out
label: padded output
dtype: enum
default: 'False'
options: ['True', 'False']
option_labels: ['Yes', 'No']
hide: part
- id: zero_len
label: num-zeros
dtype: int
default: '0'
- id: insize
label: insize
dtype: int
default: '2048'
- id: outsize
label: outsize
dtype: int
default: '1024'
- id: cutpoint
label: cutpoint
dtype: int
default: '512'
inputs:
- domain: stream
dtype: complex
vlen: ${ insize }
outputs:
- domain: stream
dtype: complex
vlen: ${ outsize }
- label: out_padded
domain: stream
dtype: complex
vlen: ${ insize }
optional: true
hide: ${ ('False' if pad_out == 'True' else 'True') }
templates:
imports: import multirds
make: multirds.vector_cutter(${insize}, ${outsize}, ${cutpoint},${pad_out},${zero_len})
callbacks:
- set_cutpoint(${cutpoint});
- set_zero_len(${zero_len});
file_format: 1

87
grc/multirds_vector_cutter.xml

@ -1,87 +0,0 @@
<?xml version="1.0"?>
<block>
<name>vector_cutter</name>
<key>multirds_vector_cutter</key>
<category>[multirds]</category>
<import>import multirds</import>
<make>multirds.vector_cutter($insize, $outsize, $cutpoint,$pad_out,$zero_len)</make>
<!-- Make one 'param' node for every Parameter you want settable from the GUI.
Sub-nodes:
* name
* key (makes the value accessible as $keyname, e.g. in the make node)
* type -->
<callback>set_cutpoint($cutpoint);</callback>
<callback>set_zero_len($zero_len);</callback>
<!-- <param>
<name>padded output</name>
<key>pad_out</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>-->
<param>
<name>padded output</name>
<key>pad_out</key>
<value>False</value>
<type>enum</type>
<hide>part</hide>
<option>
<name>Yes</name>
<key>True</key>
</option>
<option>
<name>No</name>
<key>False</key>
</option>
</param>
<param>
<name>num-zeros</name>
<key>zero_len</key>
<value>0</value>
<type>int</type>
</param>
<param>
<name>insize</name>
<key>insize</key>
<value>2048</value>
<type>int</type>
</param>
<param>
<name>outsize</name>
<key>outsize</key>
<value>1024</value>
<type>int</type>
</param>
<param>
<name>cutpoint</name>
<key>cutpoint</key>
<value>512</value>
<type>int</type>
</param>
<sink>
<name>in</name>
<type>complex</type>
<vlen>$insize</vlen>
</sink>
<source>
<name>out</name>
<type>complex</type>
<vlen>$outsize</vlen>
</source>
<source>
<name>out_padded</name>
<type>complex</type>
<vlen>$insize</vlen>
<optional>#if $pad_out() == 'True' then 'False' else 'True'#</optional>
<!--<optional>#if $pad_out==True then '1' else '0'#</optional>-->
<hide>#if $pad_out() == 'True' then 'False' else 'True'#</hide>
</source>
</block>

4
python/CMakeLists.txt

@ -38,11 +38,11 @@ GR_PYTHON_INSTALL(
stream_selector.py
vector_cutter.py
decoder_compare.py
qtgui_range.py
variable_setter.py
tmc_classes.py
tmc_parser.py
pilot_SNR.py DESTINATION ${GR_PYTHON_DIR}/multirds
pilot_SNR.py
DESTINATION ${GR_PYTHON_DIR}/multirds
)
########################################################################

25
python/__init__.py

@ -33,16 +33,17 @@ except ImportError:
# import any pure python here
from rds_table_qt import rds_table_qt
from rds_parser_table_qt import rds_parser_table_qt
from station_search import station_search
from chart import Chart
from stream_selector import stream_selector
from vector_cutter import vector_cutter
from decoder_compare import decoder_compare
from qtgui_range import qtgui_range
from variable_setter import variable_setter
from tmc_parser import tmc_parser
from pilot_SNR import pilot_SNR
from .rds_table_qt import rds_table_qt
from .rds_parser_table_qt import rds_parser_table_qt
from .station_search import station_search
from .chart import Chart
from .stream_selector import stream_selector
from .vector_cutter import vector_cutter
from .decoder_compare import decoder_compare
from .variable_setter import variable_setter
from .tmc_parser import tmc_parser
from .pilot_SNR import pilot_SNR
#

226
python/build_utils.py

@ -1,226 +0,0 @@
#
# Copyright 2004,2009,2012 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
"""Misc utilities used at build time
"""
import re, os, os.path
from build_utils_codes import *
# set srcdir to the directory that contains Makefile.am
try:
srcdir = os.environ['srcdir']
except KeyError, e:
srcdir = "."
srcdir = srcdir + '/'
# set do_makefile to either true or false dependeing on the environment
try:
if os.environ['do_makefile'] == '0':
do_makefile = False
else:
do_makefile = True
except KeyError, e:
do_makefile = False
# set do_sources to either true or false dependeing on the environment
try:
if os.environ['do_sources'] == '0':
do_sources = False
else:
do_sources = True
except KeyError, e:
do_sources = True
name_dict = {}
def log_output_name (name):
(base, ext) = os.path.splitext (name)
ext = ext[1:] # drop the leading '.'
entry = name_dict.setdefault (ext, [])
entry.append (name)
def open_and_log_name (name, dir):
global do_sources
if do_sources:
f = open (name, dir)
else:
f = None
log_output_name (name)
return f
def expand_template (d, template_filename, extra = ""):
'''Given a dictionary D and a TEMPLATE_FILENAME, expand template into output file
'''
global do_sources
output_extension = extract_extension (template_filename)
template = open_src (template_filename, 'r')
output_name = d['NAME'] + extra + '.' + output_extension
log_output_name (output_name)
if do_sources:
output = open (output_name, 'w')
do_substitution (d, template, output)
output.close ()
template.close ()
def output_glue (dirname):
output_makefile_fragment ()
output_ifile_include (dirname)
def output_makefile_fragment ():
global do_makefile
if not do_makefile:
return
# overwrite the source, which must be writable; this should have been
# checked for beforehand in the top-level Makefile.gen.gen .
f = open (os.path.join (os.environ.get('gendir', os.environ.get('srcdir', '.')), 'Makefile.gen'), 'w')
f.write ('#\n# This file is machine generated. All edits will be overwritten\n#\n')
output_subfrag (f, 'h')
output_subfrag (f, 'i')
output_subfrag (f, 'cc')
f.close ()
def output_ifile_include (dirname):
global do_sources
if do_sources:
f = open ('%s_generated.i' % (dirname,), 'w')
f.write ('//\n// This file is machine generated. All edits will be overwritten\n//\n')
files = name_dict.setdefault ('i', [])
files.sort ()
f.write ('%{\n')
for file in files:
f.write ('#include <%s>\n' % (file[0:-1] + 'h',))
f.write ('%}\n\n')
for file in files:
f.write ('%%include <%s>\n' % (file,))
def output_subfrag (f, ext):
files = name_dict.setdefault (ext, [])
files.sort ()
f.write ("GENERATED_%s =" % (ext.upper ()))
for file in files:
f.write (" \\\n\t%s" % (file,))
f.write ("\n\n")
def extract_extension (template_name):
# template name is something like: GrFIRfilterXXX.h.t
# we return everything between the penultimate . and .t
mo = re.search (r'\.([a-z]+)\.t$', template_name)
if not mo:
raise ValueError, "Incorrectly formed template_name '%s'" % (template_name,)
return mo.group (1)
def open_src (name, mode):
global srcdir
return open (os.path.join (srcdir, name), mode)
def do_substitution (d, in_file, out_file):
def repl (match_obj):
key = match_obj.group (1)
# print key
return d[key]
inp = in_file.read ()
out = re.sub (r"@([a-zA-Z0-9_]+)@", repl, inp)
out_file.write (out)
copyright = '''/* -*- c++ -*- */
/*
* Copyright 2003,2004 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* GNU Radio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU Radio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
'''
def is_complex (code3):
if i_code (code3) == 'c' or o_code (code3) == 'c':
return '1'
else:
return '0'
def standard_dict (name, code3, package='gr'):
d = {}
d['NAME'] = name
d['NAME_IMPL'] = name+'_impl'
d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper())
d['GUARD_NAME_IMPL'] = 'INCLUDED_%s_%s_IMPL_H' % (package.upper(), name.upper())
d['BASE_NAME'] = re.sub ('^' + package + '_', '', name)
d['SPTR_NAME'] = '%s_sptr' % name
d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten'
d['COPYRIGHT'] = copyright
d['TYPE'] = i_type (code3)
d['I_TYPE'] = i_type (code3)
d['O_TYPE'] = o_type (code3)
d['TAP_TYPE'] = tap_type (code3)
d['IS_COMPLEX'] = is_complex (code3)
return d
def standard_dict2 (name, code3, package):
d = {}
d['NAME'] = name
d['BASE_NAME'] = name
d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper())
d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten'
d['COPYRIGHT'] = copyright
d['TYPE'] = i_type (code3)
d['I_TYPE'] = i_type (code3)
d['O_TYPE'] = o_type (code3)
d['TAP_TYPE'] = tap_type (code3)
d['IS_COMPLEX'] = is_complex (code3)
return d
def standard_impl_dict2 (name, code3, package):
d = {}
d['NAME'] = name
d['IMPL_NAME'] = name
d['BASE_NAME'] = name.rstrip("impl").rstrip("_")
d['GUARD_NAME'] = 'INCLUDED_%s_%s_H' % (package.upper(), name.upper())
d['WARNING'] = 'WARNING: this file is machine generated. Edits will be overwritten'
d['COPYRIGHT'] = copyright
d['FIR_TYPE'] = "fir_filter_" + code3
d['CFIR_TYPE'] = "fir_filter_" + code3[0:2] + 'c'
d['TYPE'] = i_type (code3)
d['I_TYPE'] = i_type (code3)
d['O_TYPE'] = o_type (code3)
d['TAP_TYPE'] = tap_type (code3)
d['IS_COMPLEX'] = is_complex (code3)
return d

52
python/build_utils_codes.py

@ -1,52 +0,0 @@
#
# Copyright 2004 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
def i_code (code3):
return code3[0]
def o_code (code3):
if len (code3) >= 2:
return code3[1]
else:
return code3[0]
def tap_code (code3):
if len (code3) >= 3:
return code3[2]
else:
return code3[0]
def i_type (code3):
return char_to_type[i_code (code3)]
def o_type (code3):
return char_to_type[o_code (code3)]
def tap_type (code3):
return char_to_type[tap_code (code3)]
char_to_type = {}
char_to_type['s'] = 'short'
char_to_type['i'] = 'int'
char_to_type['f'] = 'float'
char_to_type['c'] = 'gr_complex'
char_to_type['b'] = 'unsigned char'

2
python/chart.py

@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
from gnuradio import gr
from itertools import cycle
from PyQt4.Qt import *
from PyQt5.Qt import *
DEFAULT_COLORS = [0x3366cc, 0xdc3912, 0xff9900, 0x109618, 0x990099,
0x0099c6, 0xdd4477, 0x66aa00, 0xb82e2e, 0x316395,

4
python/decoder_compare.py

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2017 <+YOU OR YOUR COMPANY+>.
@ -46,7 +46,7 @@ class decoder_compare(gr.sync_block):
self.printTime=time.time()
def handle_msg(self,msg,port):
#print("port:%i, msg:%s"%(port,pmt.to_python(msg)))
if pmt.to_long(pmt.car(msg))==1L:
if pmt.to_long(pmt.car(msg))==1:
data=pmt.to_python(pmt.cdr(msg))
#print("port:%i, data: %s"%(port,data))
self.synced[port]=data

2
python/qa_rds_parser_table_qt.py

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2017 <+YOU OR YOUR COMPANY+>.

2
python/qa_tmc_parser.py

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2017 <+YOU OR YOUR COMPANY+>.

279
python/qtgui_range.py

@ -1,279 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2015 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
from PyQt4 import Qt, QtCore, QtGui
import pmt
from gnuradio import gr
class qtgui_range(gr.basic_block):
def set_test(self,value):
print("test callback invoked")
print(value)
def __init__(self, minv, maxv, step, default, min_length):
gr.basic_block.__init__(self,
name="qtgui_range",
in_sig=None,
out_sig=None)
self.min = float(minv)
self.max = float(maxv)
self.step = float(step)
self.default = float(default)
self.min_length = min_length
self.find_precision()
self.find_nsteps()
def find_precision(self):
# Get the decimal part of the step
temp = str(float(self.step) - int(self.step))[2:]
precision = len(temp) if temp is not '0' else 0
precision = min(precision, 13)
if precision == 0 and self.max < 100:
self.precision = 1 # Always have a decimal in this case
else:
self.precision = (precision + 2) if precision > 0 else 0
def find_nsteps(self):
self.nsteps = (self.max + self.step - self.min)/self.step
def demap_range(self, val):
if val > self.max:
val = self.max
if val < self.min:
val = self.min
return ((val-self.min)/self.step)
def map_range(self, val):
if val > self.nsteps:
val = self.max
if val < 0:
val = 0
return (val*self.step+self.min)
class RangeWidget(QtGui.QWidget):
def update_gui(self,value):
#print("update_gui called on widget %s"%self.label)
#print(value)
#self.d_widget.slider.setValue(value)
if self.range.min < value < self.range.max:
if self.style=="counter_slider":
self.d_widget.counter.setValue(value)
else:
self.d_widget.setValue(value)
else:
print("value %i not in range %i...%i"%(value,self.range.min,self.range.max))
#self.notifyChanged(self.rangeType(value))
def __init__(self, ranges, slot, label, style, rangeType=float):
""" Creates the QT Range widget """
QtGui.QWidget.__init__(self)
self.range = ranges
self.style = style
self.label=label
# rangeType tells the block how to return the value as a standard
self.rangeType = rangeType
# Top-block function to call when any value changes
# Some widgets call this directly when their value changes.
# Others have intermediate functions to map the value into the right range.
self.notifyChanged = slot
layout = Qt.QHBoxLayout()
label = Qt.QLabel(label)
layout.addWidget(label)
if style == "dial":
self.d_widget = self.Dial(self, self.range, self.notifyChanged, rangeType)
elif style == "slider":
self.d_widget = self.Slider(self, self.range, self.notifyChanged, rangeType)
elif style == "counter":
# The counter widget can be directly wired to the notifyChanged slot
self.d_widget = self.Counter(self, self.range, self.notifyChanged, rangeType)
else:
# The CounterSlider needs its own internal handlers before calling notifyChanged
self.d_widget = self.CounterSlider(self, self.range, self.notifyChanged, rangeType)
layout.addWidget(self.d_widget)
self.setLayout(layout)
class Dial(QtGui.QDial):
""" Creates the range using a dial """
def __init__(self, parent, ranges, slot, rangeType=float):
QtGui.QDial.__init__(self, parent)
self.rangeType = rangeType
# Setup the dial
self.setRange(0, ranges.nsteps-1)
self.setSingleStep(1)
self.setNotchesVisible(True)
self.range = ranges
# Round the initial value to the closest tick
temp = int(round(ranges.demap_range(ranges.default), 0))
self.setValue(temp)
# Setup the slots
self.valueChanged.connect(self.changed)
self.notifyChanged = slot
def changed(self, value):
""" Handles maping the value to the right range before calling the slot. """
val = self.range.map_range(value)
self.notifyChanged(self.rangeType(val))
class Slider(QtGui.QSlider):
""" Creates the range using a slider """
def __init__(self, parent, ranges, slot, rangeType=float):
QtGui.QSlider.__init__(self, QtCore.Qt.Horizontal, parent)
self.rangeType = rangeType
# Setup the slider
#self.setFocusPolicy(QtCore.Qt.NoFocus)
self.setRange(0, ranges.nsteps - 1)
self.setTickPosition(2)
self.setSingleStep(1)
self.range = ranges
# Round the initial value to the closest tick
temp = int(round(ranges.demap_range(ranges.default), 0))
self.setValue(temp)
if ranges.nsteps > ranges.min_length:
interval = int(ranges.nsteps/ranges.min_length)
self.setTickInterval(interval)
self.setPageStep(interval)
else:
self.setTickInterval(1)
self.setPageStep(1)
# Setup the handler function
self.valueChanged.connect(self.changed)
self.notifyChanged = slot
def changed(self, value):
""" Handle the valueChanged signal and map the value into the correct range """
val = self.range.map_range(value)
self.notifyChanged(self.rangeType(val))
def mousePressEvent(self, event):
if((event.button() == QtCore.Qt.LeftButton)):
new = self.minimum() + ((self.maximum()-self.minimum()) * event.x()) / self.width()
self.setValue(new)
event.accept()
# Use repaint rather than calling the super mousePressEvent.
# Calling super causes issue where slider jumps to wrong value.
QtGui.QSlider.repaint(self)
def mouseMoveEvent(self, event):
new = self.minimum() + ((self.maximum()-self.minimum()) * event.x()) / self.width()
self.setValue(new)
event.accept()
QtGui.QSlider.repaint(self)
class Counter(QtGui.QDoubleSpinBox):
""" Creates the range using a counter """
def __init__(self, parent, ranges, slot, rangeType=float):
QtGui.QDoubleSpinBox.__init__(self, parent)
self.rangeType = rangeType
# Setup the counter
self.setRange(ranges.min, ranges.max)
self.setValue(ranges.default)
self.setSingleStep(ranges.step)
self.setKeyboardTracking(False)
self.setDecimals(ranges.precision)
# The counter already handles floats and can be connected directly.
self.valueChanged.connect(self.changed)
self.notifyChanged = slot
def changed(self, value):
""" Handle the valueChanged signal by converting to the right type """
self.notifyChanged(self.rangeType(value))
class CounterSlider(QtGui.QWidget):
""" Creates the range using a counter and slider """
def __init__(self, parent, ranges, slot, rangeType=float):
QtGui.QWidget.__init__(self, parent)
self.rangeType = rangeType
# Slot to call in the parent
self.notifyChanged = slot
self.slider = RangeWidget.Slider(parent, ranges, self.sliderChanged, rangeType)
self.counter = RangeWidget.Counter(parent, ranges, self.counterChanged, rangeType)
# Need another horizontal layout to wrap the other widgets.
layout = Qt.QHBoxLayout()
layout.addWidget(self.slider)
layout.addWidget(self.counter)
self.setLayout(layout)
# Flag to ignore the slider event caused by a change to the counter.
self.ignoreSlider = False
self.range = ranges
def sliderChanged(self, value):
""" Handles changing the counter when the slider is updated """
# If the counter was changed, ignore any of these events
if not self.ignoreSlider:
# Value is already float. Just set the counter
self.counter.setValue(self.rangeType(value))
self.notifyChanged(self.rangeType(value))
self.ignoreSlider = False
def counterChanged(self, value):
""" Handles changing the slider when the counter is updated """
# Get the current slider value and check to see if the new value changes it
current = self.slider.value()
new = int(round(self.range.demap_range(value), 0))
# If it needs to change, ignore the slider event
# Otherwise, the slider will cause the counter to round to the nearest tick
if current != new:
self.ignoreSlider = True
self.slider.setValue(new)
self.notifyChanged(self.rangeType(value))
if __name__ == "__main__":
from PyQt4 import Qt
import sys
def valueChanged(frequency):
print("Value updated - " + str(frequency))
app = Qt.QApplication(sys.argv)
widget = RangeWidget(qtgui_range(0, 100, 10, 1, 100), valueChanged, "Test", "counter_slider", int)
widget.show()
widget.setWindowTitle("Test Qt Range")
app.exec_()
widget = None

176
python/rds_parser_table_qt.py

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2016 <+YOU OR YOUR COMPANY+>.
@ -22,26 +22,30 @@
from __future__ import print_function#print without newline print('.', end="")
from gnuradio import gr
import pmt,functools,csv,md5,collections,copy,sqlite3,atexit,time,re,sys
import pmt,functools,csv,collections,copy,sqlite3,atexit,time,re,sys,hashlib
#old imports: folium
from datetime import datetime
from datetime import timedelta
import multirds.chart as chart
from multirds.tmc_classes import language#supported: de, en (both partially)
from PyQt4 import Qt, QtCore, QtGui
from PyQt5 import Qt, QtCore, QtGui, QtWidgets
import pprint,code
pp = pprint.PrettyPrinter()
import cProfile, pstats, StringIO #for profiling
import cProfile, pstats #for profiling
from io import StringIO #py3
pr = cProfile.Profile()
#from threading import Timer#to periodically save DB
from PyQt4.QtCore import QObject, pyqtSignal
from PyQt5.QtCore import QObject, pyqtSignal
from bitstring import BitArray
class rds_parser_table_qt_Signals(QObject):
DataUpdateEvent = QtCore.pyqtSignal(dict)
def __init__(self, parent=None):
@ -127,18 +131,18 @@ class rds_parser_table_qt(gr.sync_block):#START
# (time text,PI text,rtp_string text)''')
reader = csv.reader(open(self.workdir+'RDS_ODA-AIDs_names_only.csv'),
delimiter=',', quotechar='"')
reader.next()#skip header
next(reader)#skip header
for row in reader:
self.ODA_application_names[int(row[0])]=row[1]
#read RT+ class name list:
reader = csv.reader(open(self.workdir+'RTplus_classnames.csv'),
delimiter=',', quotechar='"')
reader.next()#skip header
next(reader)#skip header
self.rtp_classnames=dict((int(rows[0]),rows[1]) for rows in reader)
#read TMC-event list
reader = csv.reader(open(self.workdir+'event-list_with_forecast_sort.csv'),
delimiter=',', quotechar='"')
reader.next()#skip header
next(reader)#skip header
self.ecl_dict=dict((int(rows[0]),rows[1:]) for rows in reader)
#Code,Text CEN-English,Text (German),Text (German) kein Quantifier,Text (Quantifier = 1),Text (Quantifier >1),N,Q,T,D,U,C,R ,Comment
#N:nature (blank): information, F:forecast, S:silent
@ -151,7 +155,7 @@ class rds_parser_table_qt(gr.sync_block):#START
#read update classes
reader = csv.reader(open(self.workdir+'tmc_update_class_names.csv'),
delimiter=',', quotechar='"')
reader.next()#skip header, "code(C),english,german"
next(reader)#skip header, "code(C),english,german"
if language=="de":
self.tmc_update_class_names=dict((int(rows[0]),rows[2])
for rows in reader)#german names
@ -161,7 +165,7 @@ class rds_parser_table_qt(gr.sync_block):#START
#read supplementary information code list
reader = csv.reader(open(self.workdir+'label6-supplementary-information-codes.csv'),
delimiter=',', quotechar='"')
reader.next()#skip header, "code,english,german"
next(reader)#skip header, "code,english,german"
if language=="de":
self.label6_suppl_info=dict((int(rows[0]),rows[2])
for rows in reader)#german
@ -171,8 +175,8 @@ class rds_parser_table_qt(gr.sync_block):#START
#read PTY list
f=open(self.workdir+'pty-list.csv')
reader = csv.reader(f, delimiter=',', quotechar='"')
reader.next()#skip header
self.pty_dict=dict((int(rows[0]),unicode(rows[1],errors='ignore'))
next(reader)#skip header
self.pty_dict=dict((int(rows[0]),rows[1])
for rows in reader)
f.close()
self.minute_count=0
@ -264,8 +268,8 @@ class rds_parser_table_qt(gr.sync_block):#START
self.RDS_data[PI]["internals"]={"last_rt_tooltip":"","unfinished_TMC":{},"last_valid_rt":"","last_valid_psn":"","RT_history":[]}
self.RDS_data[PI]["time"]={"timestring":"88:88","datestring":"00-00-0000","datetime":None}
self.RDS_data[PI]["wrong_block_ratio"]=1#100%
def handle_msg(self, msg, port):#port from 0 to 3
if pmt.to_long(pmt.car(msg))==1L:#sync/desync messages from RDS decoder
def handle_msg(self, msg, port): #port from 0 to 3
if pmt.is_integer(pmt.car(msg)) and pmt.to_long(pmt.car(msg))==1: #sync/desync messages from RDS decoder
synced=pmt.to_python(pmt.cdr(msg))
#print("port:%i, data: %s"%(port,data))
self.decoders[port]['synced']=synced
@ -276,21 +280,21 @@ class rds_parser_table_qt(gr.sync_block):#START
wrong_block_ratio=1#100%
self.RDS_data[PI]["wrong_block_ratio"]=wrong_block_ratio
self.signals.DataUpdateEvent.emit({'PI':PI,'wrong_block_ratio':wrong_block_ratio,'dots':dots})
elif pmt.to_long(pmt.car(msg))==2L:#wrong_block_ratio messages from RDS decoder
elif pmt.is_integer(pmt.car(msg)) and pmt.to_long(pmt.car(msg))==2: #wrong_block_ratio messages from RDS decoder
wrong_block_ratio=pmt.to_python(pmt.cdr(msg))
PI=self.decoders[port]['PI']
if self.RDS_data.has_key(PI):
dots="."*self.RDS_data[PI]["blockcounts"]["any"]
self.RDS_data[PI]["wrong_block_ratio"]=wrong_block_ratio
self.signals.DataUpdateEvent.emit({'PI':PI,'wrong_block_ratio':wrong_block_ratio,'dots':dots})
elif pmt.to_long(pmt.car(msg))==3L: #carrier quality message
elif pmt.is_integer(pmt.car(msg)) and pmt.to_long(pmt.car(msg))==3: #carrier quality message
pilot_SNR=pmt.to_long(pmt.cdr(msg))
self.decoders[port]['pilot_SNR']=pilot_SNR
self.update_freq()
PI=self.decoders[port]['PI']
if self.RDS_data.has_key(PI):
self.signals.DataUpdateEvent.emit({'PI':PI,'pilot_SNR':pilot_SNR})
elif pmt.to_long(pmt.car(msg))==4L:#mode messages from RDS sync_decim
elif pmt.is_integer(pmt.car(msg)) and pmt.to_long(pmt.car(msg))==4: #mode messages from RDS sync_decim
mode=pmt.to_python(pmt.cdr(msg))
self.decoders[port]['decim_mode']=mode
self.update_freq()
@ -318,11 +322,11 @@ class rds_parser_table_qt(gr.sync_block):#START
groupNR=array[2]&0b11110000
groupVar=array[2]&0b00001000
if (groupVar == 0):
groupType=str(groupNR >> 4)+"A"
groupType=bytes(groupNR >> 4)+"A"
else:
groupType=str(groupNR >> 4)+"B"
groupType=bytes(groupNR >> 4)+"B"
#if self.debug:
#PI=str(port)+"_%02X%02X" %(array[0],array[1])
#PI=bytes(port)+"_%02X%02X" %(array[0],array[1])
#else:
#PI="%02X%02X" %(array[0],array[1])
PI="%02X%02X" %(array[0],array[1])
@ -361,7 +365,7 @@ class rds_parser_table_qt(gr.sync_block):#START
if self.RDS_data[PI]["blockcounts"]["any"]==5:
self.RDS_data[PI]["blockcounts"]["any"]=0
if self.writeDB:
t=(str(PI),groupType,self.RDS_data[PI]["blockcounts"][groupType])#TODO only update DB every few seconds
t=(bytes(PI),groupType,self.RDS_data[PI]["blockcounts"][groupType])#TODO only update DB every few seconds
db.execute("INSERT OR REPLACE INTO grouptypeCounts (PI,grouptype,count) VALUES (?,?,?)",t)
dots="."*self.RDS_data[PI]["blockcounts"]["any"]
self.RDS_data[PI]["TP"]=TP
@ -376,7 +380,7 @@ class rds_parser_table_qt(gr.sync_block):#START
#add any received groups to DB (slow)
#content="%02X%02X%02X%02X%02X" %(array[3]&0x1f,array[4],array[5],array[6],array[7])
#t=(str(datetime.now()),PI,self.RDS_data[PI]["PSN"],groupType,content)
#t=(bytes(datetime.now()),PI,self.RDS_data[PI]["PSN"],groupType,content)
#db.execute("INSERT INTO groups VALUES (?,?,?,?,?)",t)
if (groupType == "0A"):#AF PSN
@ -392,7 +396,7 @@ class rds_parser_table_qt(gr.sync_block):#START
MS=(array[3]>>3)&0x1
self.RDS_data[PI]["TA"]=TA
#style='font-family:Courier New;color:%s'
flag_string="<span style=''>TP:%i, TA:%i, MS:%i, DI:%s</span>"%(TP,TA,MS,str(self.RDS_data[PI]["DI"]))
flag_string="<span style=''>TP:%i, TA:%i, MS:%i, DI:%s</span>"%(TP,TA,MS,bytes(self.RDS_data[PI]["DI"]))
pty_colored=self.RDS_data[PI]["PTY"]
if TP==1:
if TA==1:
@ -482,7 +486,7 @@ class rds_parser_table_qt(gr.sync_block):#START
#textcolor="black"
textcolor=""#use default color (white if background is black)
if not self.RDS_data[PI]["internals"]["last_valid_psn"]==self.RDS_data[PI]["PSN"]:#ignore duplicates
t=(str(datetime.now()),PI,self.RDS_data[PI]["PSN"],"PSN_valid",self.RDS_data[PI]["PSN"])
t=(bytes(datetime.now()),PI,self.RDS_data[PI]["PSN"],"PSN_valid",self.RDS_data[PI]["PSN"])
if self.writeDB:
db.execute("INSERT INTO data (time,PI,PSN,dataType,data) VALUES (?,?,?,?,?)",t)
t=(self.RDS_data[PI]["PSN"],PI)
@ -507,12 +511,12 @@ class rds_parser_table_qt(gr.sync_block):#START
PIN_valid= PIN_day in range(1,32) and PIN_hour in range(0,24) and PIN_minute in range(0,60)
if PIN_valid:
self.RDS_data[PI]["PIN"]=[PIN_day,PIN_hour,PIN_minute]
data_string="radio paging code:%i,LA:%i,variant:%i,SLC:%04X,PIN (valid):%s "%(radio_paging,LA,variant,SLC,str([PIN_day,PIN_hour,PIN_minute]))
data_string="radio paging code:%i,LA:%i,variant:%i,SLC:%04X,PIN (valid):%s "%(radio_paging,LA,variant,SLC,bytes([PIN_day,PIN_hour,PIN_minute]))
else:
data_string="radio paging code:%i,LA:%i,variant:%i,SLC:%04X,PIN:%04X "%(radio_paging,LA,variant,SLC,PIN)
#%02X%02X%02X%02X%02X
t=(str(datetime.now()),PI,self.RDS_data[PI]["PSN"],"PIN",data_string)
t=(bytes(datetime.now()),PI,self.RDS_data[PI]["PSN"],"PIN",data_string)
if self.writeDB:
db.execute("INSERT INTO data (time,PI,PSN,dataType,data) VALUES (?,?,?,?,?)",t)
if self.debug and not variant==0:#print if not seen before
@ -554,7 +558,7 @@ class rds_parser_table_qt(gr.sync_block):#START
segment=chr(array[4])+chr(array[5])+chr(array[6])+chr(array[7])#EDIT:latedecode
#self.signals.DataUpdateEvent.emit({'col':5,'row':port,'PI':PI,'groupType':groupType,'adress':adr,'segment':segment})
text_list=list(self.RDS_data[PI]["RT_"+str(ab_flag)]["RT"])
text_list=list(self.RDS_data[PI]["RT_"+bytes(ab_flag)]["RT"])
#determine text length:
try:
text_end=text_list.index('\r')
@ -572,27 +576,27 @@ class rds_parser_table_qt(gr.sync_block):#START
text_list=['_']*64 #clear text
text_list[adr*4:adr*4+4]=segment
#reset stored text:
#self.RDS_data[PI]["RT_"+str(ab_flag)]["RT"]="_"*64 #done in text_list
self.RDS_data[PI]["RT_"+str(ab_flag)]["RT_valid"]=[False]*64
#self.RDS_data[PI]["RT_"+bytes(ab_flag)]["RT"]="_"*64 #done in text_list
self.RDS_data[PI]["RT_"+bytes(ab_flag)]["RT_valid"]=[False]*64
#predict RT from last texts:
for rt in self.RDS_data[PI]["internals"]["RT_history"]:
if rt[adr*4:adr*4+4]==list(segment):
self.RDS_data[PI]["RT_"+str(ab_flag)]["RT"]="".join(rt)
self.RDS_data[PI]["RT_"+bytes(ab_flag)]["RT"]="".join(rt)
predicted=True
self.RDS_data[PI]["RT_"+str(ab_flag)]["RT_valid"][adr*4:adr*4+4]=[True] *4
self.RDS_data[PI]["RT_"+bytes(ab_flag)]["RT_valid"][adr*4:adr*4+4]=[True] *4
if not predicted:
self.RDS_data[PI]["RT_"+str(ab_flag)]["RT"]="".join(text_list)
self.RDS_data[PI]["RT_"+bytes(ab_flag)]["RT"]="".join(text_list)
#determine if (new) text is valid
self.RDS_data[PI]["RT_"+str(ab_flag)]["RT_all_valid"]=True
self.RDS_data[PI]["RT_"+bytes(ab_flag)]["RT_all_valid"]=True
for i in range(0,text_end):
if (not self.RDS_data[PI]["RT_"+str(ab_flag)]["RT_valid"][i]):
self.RDS_data[PI]["RT_"+str(ab_flag)]["RT_all_valid"] = False
if(self.RDS_data[PI]["RT_"+str(ab_flag)]["RT_all_valid"]):
if (not self.RDS_data[PI]["RT_"+bytes(ab_flag)]["RT_valid"][i]):
self.RDS_data[PI]["RT_"+bytes(ab_flag)]["RT_all_valid"] = False
if(self.RDS_data[PI]["RT_"+bytes(ab_flag)]["RT_all_valid"]):
#textcolor="black"
textcolor=""#use default color (white if background is black)
l=list(self.RDS_data[PI]["RT_"+str(ab_flag)]["RT"])
l=list(self.RDS_data[PI]["RT_"+bytes(ab_flag)]["RT"])
rt="".join(l[0:text_end])#remove underscores(default symbol) after line end marker
if not self.RDS_data[PI]["internals"]["last_valid_rt"]==rt:#ignore duplicates #TODO add 2nd order duplicates ABAB
self.RDS_data[PI]["internals"]["RT_history"].append(l)
@ -600,23 +604,23 @@ class rds_parser_table_qt(gr.sync_block):#START
self.RDS_data[PI]["internals"]["RT_history"].pop(0)
if self.writeDB:
t=(
str(datetime.now()),PI,self.RDS_data[PI]["PSN"],
bytes(datetime.now()),PI,self.RDS_data[PI]["PSN"],
"RT",self.decode_chars(rt)
)
db.execute("INSERT INTO data (time,PI,PSN,dataType,data) VALUES (?,?,?,?,?)",t)
self.RDS_data[PI]["internals"]["last_valid_rt"]=rt
try:#save rt+ if it exist
if self.writeDB:
t=(str(datetime.now()),PI,
t=(bytes(datetime.now()),PI,
self.RDS_data[PI]["PSN"],"RT+",
self.decode_chars(str(self.RDS_data[PI]["RT+"]))
self.decode_chars(bytes(self.RDS_data[PI]["RT+"]))
)
db.execute("INSERT INTO data (time,PI,PSN,dataType,data) VALUES (?,?,?,?,?)",t)
except KeyError:
pass#no rt+ -> dont save
else:
textcolor="gray"
display_text=self.decode_chars(self.RDS_data[PI]["RT_"+str(ab_flag)]["RT"].split("\r")[0])
display_text=self.decode_chars(self.RDS_data[PI]["RT_"+bytes(ab_flag)]["RT"].split("\r")[0])
formatted_text=self.color_text(display_text,adr*4,adr*4+4,textcolor,segmentcolor)
rtcol=self.colorder.index('text')
self.signals.DataUpdateEvent.emit({'col':rtcol,'row':port,'PI':PI,'string':formatted_text})
@ -626,9 +630,9 @@ class rds_parser_table_qt(gr.sync_block):#START
app_data=int((array[4]<<8)|(array[5]))#content defined by ODA-app
app_group_raw=int(array[3]&0x1f) #group type in which this app is sent
if (app_group_raw&0x1 == 0):
app_group=str(app_group_raw >> 1)+"A"
app_group=bytes(app_group_raw >> 1)+"A"
else:
app_group=str(app_group_raw >> 1)+"B"
app_group=bytes(app_group_raw >> 1)+"B"
if not self.RDS_data[PI]["AID_list"].has_key(AID):#new ODA found
try:
@ -711,7 +715,7 @@ class rds_parser_table_qt(gr.sync_block):#START
self.RDS_data[PI]["time"]["datestring"]=datestring
self.RDS_data[PI]["time"]["datetime"]=datetime(date.year,date.month,date.day,hours,minutes)+timedelta(hours=local_time_offset)
if self.writeDB:
t=(str(datetime.now()),PI,self.RDS_data[PI]["PSN"],"CT",datestring+" "+timestring+"; datecode(MJD):"+str(datecode))
t=(bytes(datetime.now()),PI,self.RDS_data[PI]["PSN"],"CT",datestring+" "+timestring+"; datecode(MJD):"+bytes(datecode))
db.execute("INSERT INTO data (time,PI,PSN,dataType,data) VALUES (?,?,?,?,?)",t)
except ValueError as e:
print("ERROR: could not interpret time or date:")
@ -734,7 +738,7 @@ class rds_parser_table_qt(gr.sync_block):#START
self.IH_data[PI][ih_data]={}
self.IH_data[PI][ih_data]["count"]=0
self.IH_data[PI][ih_data]["count"]+=1
self.IH_data[PI][ih_data]["last_time"]=str(datetime.now())
self.IH_data[PI][ih_data]["last_time"]=bytes(datetime.now())
#TMC-alert-c (grouptype mostly 8A):
elif (self.RDS_data[PI]["AID_list"].has_key(52550)
and self.RDS_data[PI]["AID_list"][52550]["groupType"]==groupType):#TMC alert-C
@ -759,7 +763,7 @@ class rds_parser_table_qt(gr.sync_block):#START
})#this gnuradio instance doesnt seem to be able to convert from numpy.int64 to pmt
self.message_port_pub(pmt.intern('tmc_raw'), send_pmt)
#~ tmc_hash=md5.new(str([PI,tmc_x,tmc_y,tmc_z])).hexdigest()
#~ tmc_hash=hashlib.md5(bytes([PI,tmc_x,tmc_y,tmc_z])).hexdigest()
tmc_T=tmc_x>>4 #0:TMC-message 1:tuning info/service provider name
#~ tmc_F=int((tmc_x>>3)&0x1) #identifies the message as a Single Group (F = 1) or Multi Group (F = 0)
#~ Y15=int(tmc_y>>15)
@ -835,11 +839,11 @@ class rds_parser_table_qt(gr.sync_block):#START
tag2_start=int((tag2>>5)&(2**6-1))
tag2_len=int(tag2&(2**5-1))
if not self.RDS_data[PI]["RT+"]["last_item_toggle_bit"] == item_toggle_bit: #new item
#self.RDS_data[PI]["RT+"]["history"][str(datetime.now())]=self.RDS_data[PI]["internals"]["last_rt_tooltip"]
t=(str(datetime.now()),PI,self.RDS_data[PI]["PSN"],"RT+",str(self.RDS_data[PI]["RT+"]))
#self.RDS_data[PI]["RT+"]["history"][bytes(datetime.now())]=self.RDS_data[PI]["internals"]["last_rt_tooltip"]
t=(bytes(datetime.now()),PI,self.RDS_data[PI]["PSN"],"RT+",bytes(self.RDS_data[PI]["RT+"]))
if self.writeDB:
db.execute("INSERT INTO data (time,PI,PSN,dataType,data) VALUES (?,?,?,?,?)",t)
self.RDS_data[PI]["RT+_history"][str(datetime.now())]=copy.deepcopy(self.RDS_data[PI]["RT+"])#save old item
self.RDS_data[PI]["RT+_history"][bytes(datetime.now())]=copy.deepcopy(self.RDS_data[PI]["RT+"])#save old item
self.RDS_data[PI]["RT+"]["last_item_toggle_bit"] = item_toggle_bit
rtcol=self.colorder.index('text')
if self.debug:
@ -847,8 +851,8 @@ class rds_parser_table_qt(gr.sync_block):#START
self.signals.DataUpdateEvent.emit({'col':rtcol,'row':port,'PI':PI,'tooltip':""})
if self.RDS_data[PI].has_key("RT_0"):
ab_flag=self.RDS_data[PI]["RT_last_ab_flag"]
rt=self.RDS_data[PI]["RT_"+str(ab_flag)]["RT"]
rt_valid=self.RDS_data[PI]["RT_"+str(ab_flag)]["RT_valid"]
rt=self.RDS_data[PI]["RT_"+bytes(ab_flag)]["RT"]
rt_valid=self.RDS_data[PI]["RT_"+bytes(ab_flag)]["RT_valid"]
if not tag1_type=="DUMMY_CLASS" and all(rt_valid[tag1_start:tag1_start+tag1_len+1]):
self.RDS_data[PI]["RT+"][tag1_type]=rt[tag1_start:tag1_start+tag1_len+1]
self.RDS_data[PI]["internals"]["RT+_times"][tag1_type]=time.time()
@ -868,8 +872,8 @@ class rds_parser_table_qt(gr.sync_block):#START
self.signals.DataUpdateEvent.emit({'col':rtpcol,'row':port,'PI':PI,'string':tags})
if(tag2_type=="ITEM.TITLE" and self.RDS_data[PI].has_key("RT_0")):#TODO remove duplicate code
ab_flag=self.RDS_data[PI]["RT_last_ab_flag"]
rt=self.RDS_data[PI]["RT_"+str(ab_flag)]["RT"]
rt_valid=self.RDS_data[PI]["RT_"+str(ab_flag)]["RT_valid"]
rt=self.RDS_data[PI]["RT_"+bytes(ab_flag)]["RT"]
rt_valid=self.RDS_data[PI]["RT_"+bytes(ab_flag)]["RT_valid"]
artist="?"
song="?"
if all(rt_valid[tag1_start:tag1_start+tag1_len+1]):
@ -1046,7 +1050,7 @@ class rds_parser_table_qt(gr.sync_block):#START
print("symbol not decoded: "+"?%02X?"%ord(char)+
"in string:"+return_string)
pass
if not type(return_string)==unicode:
if not type(return_string)==str:
code.interact(local=locals())
return return_string
def color_text(self, text, start,end,textcolor,segmentcolor):
@ -1056,14 +1060,14 @@ class rds_parser_table_qt(gr.sync_block):#START
segmentcolor,text[start:end],
textcolor,text[end:])
return formatted_text
class rds_parser_table_qt_Widget(QtGui.QWidget):
class rds_parser_table_qt_Widget(QtWidgets.QWidget):
def __init__(self, signals,label,tableobj):
#print("gui initializing")self.tableobj.RDS_data["D3A2"]
self.signals = signals
self.tableobj=tableobj
self.signals.DataUpdateEvent.connect(self.display_data)
""" Creates the QT Range widget """
QtGui.QWidget.__init__(self)
QtWidgets.QWidget.__init__(self)
layout = Qt.QVBoxLayout()
#self.label = Qt.QLabel(label)
#layout.addWidget(self.label)#title of table disabled to save space
@ -1071,42 +1075,42 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
self.setLayout(layout)
#self.decoder_to_PI={}
self.PI_to_row={}
self.table=QtGui.QTableWidget(self)
self.table=QtWidgets.QTableWidget(self)
rowcount=0
self.table.setRowCount(rowcount)
#self.colorder=['ID','freq','name','buttons','PTY','AF','time','text','quality']
self.colorder=tableobj.colorder
self.table.setColumnCount(len(self.colorder))
self.table.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) #disallow editing
self.table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) #disallow editing
layout.addWidget(self.table)
self.table.setHorizontalHeaderLabels(self.colorder)
#self.table.setMaximumHeight(300)#TODO use dynamic value
button_layout = Qt.QHBoxLayout()
codebutton = QtGui.QPushButton("code.interact")
codebutton = QtWidgets.QPushButton("code.interact")
codebutton.clicked.connect(self.onCLick)
button_layout.addWidget(codebutton)
ih_button = QtGui.QPushButton("show IH data")
ih_button = QtWidgets.QPushButton("show IH data")
ih_button.clicked.connect(self.showIHdata)
button_layout.addWidget(ih_button)
save_button = QtGui.QPushButton("save")
save_button = QtWidgets.QPushButton("save")
save_button.clicked.connect(self.saveData)
button_layout.addWidget(save_button)
print_button = QtGui.QPushButton("print profile")
print_button = QtWidgets.QPushButton("print profile")
print_button.clicked.connect(self.printProfile)
button_layout.addWidget(print_button)
mode_button = QtGui.QPushButton("searchMode")
mode_button = QtWidgets.QPushButton("searchMode")
mode_button.clicked.connect(self.switchMode)
button_layout.addWidget(mode_button)
layout.addLayout(button_layout)
label_layout = Qt.QHBoxLayout()
self.freq_label=QtGui.QLabel("decoder frequencies:")
self.freq_label=QtWidgets.QLabel("decoder frequencies:")
self.freq_label.setWordWrap(True)
self.freq_label.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Ignored))#expand in horizontal direction and only wrap if window too small
self.freq_label.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding,
QtWidgets.QSizePolicy.Ignored))#expand in horizontal direction and only wrap if window too small
self.freq_label.setTextFormat(QtCore.Qt.RichText)#instead of AutoText
self.count_label=QtGui.QLabel("count:")
self.count_label=QtWidgets.QLabel("count:")
self.count_label.setAlignment(QtCore.Qt.AlignRight)
label_layout.addWidget(self.freq_label)
label_layout.addWidget(self.count_label)
@ -1114,7 +1118,7 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
#self.setMinimumSize(Qt.QSize(500,40*self.tableobj.nPorts))
self.setMinimumSize(Qt.QSize(500,40*(4+self.tableobj.nPorts)))
self.lastResizeTime=0
self.clip = QtGui.QApplication.clipboard()
self.clip = QtWidgets.QApplication.clipboard()
#self.cb.clear(mode=cb.Clipboard )
#self.cb.setText("Clipboard Text", mode=cb.Clipboard)
def keyPressEvent(self, e):
@ -1125,7 +1129,7 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
if e.key() == QtCore.Qt.Key_C: #copy
try:
qs = self.table.cellWidget(selected.topRow(),selected.leftColumn()).text()#get QString from table
s=re.sub("<.*?>","", str(qs))#remove html tags
s=re.sub("<.*?>","", bytes(qs))#remove html tags
self.clip.setText(s)
except Exception as e:
print(e)
@ -1134,30 +1138,30 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
rowPosition = self.table.rowCount()
self.table.insertRow(rowPosition)
#for col in range(self.table.columnCount()-1):#all labels except in last column -> buttons
# self.table.setCellWidget(rowPosition,col,QtGui.QLabel())
# self.table.setCellWidget(rowPosition,col,QtWidgets.QLabel())
#initialize labels everywhere:
for col in range(self.table.columnCount()):
self.table.setCellWidget(rowPosition,col,QtGui.QLabel())
self.table.setCellWidget(rowPosition,col,QtWidgets.QLabel())
button_layout = Qt.QHBoxLayout()
details_button=QtGui.QPushButton("Detail")
details_button=QtWidgets.QPushButton("Detail")
details_button.clicked.connect(functools.partial(self.getDetails, row=rowPosition))
button_layout.addWidget(details_button)
#2017-03-17 disabled LR buttons
#2017-04-24 enabled LR buttons
left_button=QtGui.QPushButton("L")
left_button=QtWidgets.QPushButton("L")
#left_button.clicked.connect(functools.partial(self.setAudio, row=rowPosition,audio_channel="left"))
left_button.clicked.connect(functools.partial(self.setAudio2, row=rowPosition,audio_channel=0))
button_layout.addWidget(left_button)
center_button=QtGui.QPushButton("C")
center_button=QtWidgets.QPushButton("C")
#center_button.clicked.connect(functools.partial(self.setAudio, row=rowPosition,audio_channel="center"))
center_button.clicked.connect(functools.partial(self.setAudio2, row=rowPosition,audio_channel=1))
button_layout.addWidget(center_button)
right_button=QtGui.QPushButton("R")
right_button=QtWidgets.QPushButton("R")
#right_button.clicked.connect(functools.partial(self.setAudio, row=rowPosition,audio_channel="right"))
right_button.clicked.connect(functools.partial(self.setAudio2, row=rowPosition,audio_channel=2))
button_layout.addWidget(right_button)
cellWidget = QtGui.QWidget()
cellWidget = QtWidgets.QWidget()
cellWidget.setLayout(button_layout)
button_col=3
self.table.setCellWidget(rowPosition,button_col,cellWidget)
@ -1209,7 +1213,7 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
if event.has_key('AF'):
#setAF
PIcol=self.colorder.index('AF')
self.table.cellWidget(row,PIcol).setText(str(event['AF']['number']))
self.table.cellWidget(row,PIcol).setText(bytes(event['AF']['number']))
if event.has_key('PSN'):
#setPSN
PSNcol=self.colorder.index('name')
@ -1227,7 +1231,7 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
#send_pmt = pmt.string_to_symbol("switch mode")
self.tableobj.message_port_pub(pmt.intern('ctrl'), send_pmt)
def saveData(self):
filename="RDS_data_"+str(datetime.now())+".txt"
filename="RDS_data_"+bytes(datetime.now())+".txt"
f=open(self.tableobj.workdir+filename,"w")
rds_data=copy.deepcopy(self.tableobj.RDS_data)
for PI in sorted(rds_data):
@ -1242,7 +1246,7 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
print("data saved in file %s"%filename)
def showIHdata(self):
view=Qt.QDialog()
l=QtGui.QLabel("In House Data:\n%s"%pp.pformat(self.tableobj.IH_data))
l=QtWidgets.QLabel("In House Data:\n%s"%pp.pformat(self.tableobj.IH_data))
l.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse |
QtCore.Qt.TextSelectableByKeyboard)
l.setWordWrap(True)
@ -1254,7 +1258,7 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
def setAudio(self,row,audio_channel):
PIcol=self.colorder.index('ID')
PI=str(self.table.cellWidget(row,PIcol).text())
PI=bytes(self.table.cellWidget(row,PIcol).text())
freq=int(self.tableobj.RDS_data[PI]['AF']['main'])
#print("setaudio row:%i, chan:%s, PI:%s,freq:%i"%(row,audio_channel,PI,freq))
send_pmt = pmt.pmt_to_python.pmt_from_dict({"cmd":"set_audio_freq",
@ -1267,7 +1271,7 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
def setAudio2(self,row,audio_channel):
PIcol=self.colorder.index('ID')
PI=str(self.table.cellWidget(row,PIcol).text())
PI=bytes(self.table.cellWidget(row,PIcol).text())
#find port:
for port,decoder in enumerate(self.tableobj.decoders):
if decoder['PI']==PI:
@ -1280,7 +1284,7 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
def getDetails(self,row):
PIcol=self.colorder.index('ID')
PI=str(self.table.cellWidget(row,PIcol).text())
PI=bytes(self.table.cellWidget(row,PIcol).text())
view = chart.DialogViewer()
if self.tableobj.PI_dict.has_key(PI) and self.tableobj.PI_dict[PI]>3:
#dont print piechart if no packets received (detected via EON)
@ -1293,7 +1297,7 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
#and sorts based on integer valure of number in front
for key in sorted(blockcounts,key=lambda elem: int(elem[0:-1])):
count=blockcounts[key]
table.addRow([key+": "+str(count),count])
table.addRow([key+": "+bytes(count),count])
mychart=chart.PieChart(table)
view.setGraph(mychart)
#view.resize(360, 240)
@ -1309,15 +1313,15 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
#combine char lists into strings (more compact)
except KeyError:
pass
l=QtGui.QLabel("Data:%s"%pp.pformat(rds_data))
l=QtWidgets.QLabel("Data:%s"%pp.pformat(rds_data))
l.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse |
QtCore.Qt.TextSelectableByKeyboard)
l.setWordWrap(True)
#l=QtGui.QLabel("Data:")
#l=QtWidgets.QLabel("Data:")
#view.layout().addWidget(l)
scrollArea = QtGui.QScrollArea(self)
scrollArea = QtWidgets.QScrollArea(self)
scrollArea.setWidgetResizable(True)
scrollArea.setWidget(l)
view.layout().addWidget(scrollArea)

8
python/rds_table_qt.py

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2016 <+YOU OR YOUR COMPANY+>.
@ -22,11 +22,11 @@
import numpy
from gnuradio import gr
import code,pmt,functools
from PyQt4 import Qt, QtCore, QtGui
from PyQt5 import Qt, QtCore, QtGui, QtWidgets
import pprint
pp = pprint.PrettyPrinter()
from PyQt4.QtCore import QObject, pyqtSignal
from PyQt5.QtCore import QObject, pyqtSignal
class rds_table_qt_Signals(QObject):
DataUpdateEvent = QtCore.pyqtSignal(dict)
@ -89,7 +89,7 @@ class rds_table_qt(gr.sync_block):
#def handle_msg(self, msg):
# self.signals.DataUpdateEvent.emit({'string':pmt.to_python(msg)})
# print(msg)
class rds_table_qt_Widget(QtGui.QWidget):
class rds_table_qt_Widget(QtWidgets.QWidget):
def __init__(self, signals,label):
print("gui initializing")
self.signals = signals

2
python/station_search.py

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2016 <+YOU OR YOUR COMPANY+>.

2
python/stream_selector.py

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2017 <+YOU OR YOUR COMPANY+>.

13
python/tmc_classes.py

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2017 <+YOU OR YOUR COMPANY+>.
@ -31,7 +31,8 @@
from bitstring import BitArray
import copy,csv,code
import hashlib,os,time
import cPickle as pickle#faster for python2
#import cPickle as pickle#faster for python2
import pickle
from collections import namedtuple
@ -826,7 +827,7 @@ class tmc_message:
try:
retstr=str(self.event.updateClass)+": "+self.getTime()+": "+self.location.loctype_str+": "+self.location.loctype_name.encode('utf-8')+": "+self.location_text()+": "+self.events_string()+"; "+self.info_str()+"; "+str(list(self.psns))+"x%i"%self.confirmations
except UnicodeDecodeError as e:
print e
print(e)
code.interact(local=locals())
#print("got log_string")
return retstr
@ -963,7 +964,7 @@ class tmc_message:
print("invalid main event")
print(self)
else:#subsequent groups in multigroup -> Y0..Y11 and Z0..Z15 are special format
raise ValueError, "subsequent groups must be added to existing tmc message"
raise ValueError("subsequent groups must be added to existing tmc message")
def add_group(self,tmc_y,tmc_z):
sg=int((tmc_y>>14)&0x1)#=1 if second group Y14
gsi=int((tmc_y>>12)&0x3)#group sequence indicator Y12..13 ,max length:5
@ -1072,7 +1073,7 @@ class mgm_tag:#mgm=multi group message
elif raw<=255:#months
return "%s months"%((raw-231)/2.0)
else:
raise ValueError, "label7/8 time must be between 0 and 255"
raise ValueError("label7/8 time must be between 0 and 255")
@staticmethod
def length_to_km(raw):#label2 raw to km
if raw==0:
@ -1084,7 +1085,7 @@ class mgm_tag:#mgm=multi group message
elif raw <=31:
return 5*raw-55
else:
raise ValueError, "label2-length must be between 0 and 31"
raise ValueError("label2-length must be between 0 and 31")
def __repr__(self):
try:

8
python/tmc_parser.py

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2017 <+YOU OR YOUR COMPANY+>.
@ -23,7 +23,7 @@ from __future__ import print_function#print without newline print('.', end="")
import numpy
from gnuradio import gr
import pmt
from PyQt4 import Qt, QtCore, QtGui
from PyQt5 import Qt, QtCore, QtGui, QtWidgets
import code,time,csv,sqlite3,atexit
from bitstring import BitArray
from multirds.tmc_classes import tmc_dict,tmc_message,language,lcl
@ -290,7 +290,7 @@ def print_dbg(message,end="\n"):
dbg=False
if dbg:
print(message,end=end)
class tmc_parser_Widget(QtGui.QWidget):
class tmc_parser_Widget(QtWidgets.QWidget):
def print_tmc_msg(self,tmc_msg):
self.parser.dataLock.acquire(1)
@ -361,7 +361,7 @@ class tmc_parser_Widget(QtGui.QWidget):
def update_showInvalid(self):
self.showInvalid=self.GUI_showInvalid.isChecked()
def __init__(self, parser,maxheight):
QtGui.QWidget.__init__(self)
QtWidgets.QWidget.__init__(self)
layout = Qt.QVBoxLayout()
self.logMutex=QtCore.QSemaphore(1)
self.setLayout(layout)

105
python/top_block.py

@ -1,105 +0,0 @@
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
##################################################
# GNU Radio Python Flow Graph
# Title: Top Block
# Generated: Thu Jun 8 13:38:58 2017
##################################################
if __name__ == '__main__':
import ctypes
import sys
if sys.platform.startswith('linux'):
try:
x11 = ctypes.cdll.LoadLibrary('libX11.so')
x11.XInitThreads()
except:
print "Warning: failed to XInitThreads()"
from PyQt4 import Qt
from gnuradio import blocks
from gnuradio import eng_notation
from gnuradio import gr
from gnuradio.eng_option import eng_option
from gnuradio.filter import firdes
from optparse import OptionParser
import multirds
import sys
from gnuradio import qtgui
class top_block(gr.top_block, Qt.QWidget):
def __init__(self):
gr.top_block.__init__(self, "Top Block")
Qt.QWidget.__init__(self)
self.setWindowTitle("Top Block")
qtgui.util.check_set_qss()
try:
self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc'))
except:
pass
self.top_scroll_layout = Qt.QVBoxLayout()
self.setLayout(self.top_scroll_layout)
self.top_scroll = Qt.QScrollArea()
self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame)
self.top_scroll_layout.addWidget(self.top_scroll)
self.top_scroll.setWidgetResizable(True)
self.top_widget = Qt.QWidget()
self.top_scroll.setWidget(self.top_widget)
self.top_layout = Qt.QVBoxLayout(self.top_widget)
self.top_grid_layout = Qt.QGridLayout()
self.top_layout.addLayout(self.top_grid_layout)
self.settings = Qt.QSettings("GNU Radio", "top_block")
self.restoreGeometry(self.settings.value("geometry").toByteArray())
##################################################
# Variables
##################################################
self.samp_rate = samp_rate = 32000
##################################################
# Blocks
##################################################
self.multirds_rds_decoder_redsea_0 = multirds.rds_decoder_redsea(False, True)
self.blocks_null_source_0 = blocks.null_source(gr.sizeof_char*1)
##################################################
# Connections
##################################################
self.connect((self.blocks_null_source_0, 0), (self.multirds_rds_decoder_redsea_0, 0))
def closeEvent(self, event):
self.settings = Qt.QSettings("GNU Radio", "top_block")
self.settings.setValue("geometry", self.saveGeometry())
event.accept()
def get_samp_rate(self):
return self.samp_rate
def set_samp_rate(self, samp_rate):
self.samp_rate = samp_rate
def main(top_block_cls=top_block, options=None):
from distutils.version import StrictVersion
if StrictVersion(Qt.qVersion()) >= StrictVersion("4.5.0"):
style = gr.prefs().get_string('qtgui', 'style', 'raster')
Qt.QApplication.setGraphicsSystem(style)
qapp = Qt.QApplication(sys.argv)
tb = top_block_cls()
tb.start()
tb.show()
def quitting():
tb.stop()
tb.wait()
qapp.connect(qapp, Qt.SIGNAL("aboutToQuit()"), quitting)
qapp.exec_()
if __name__ == '__main__':
main()

2
python/variable_setter.py

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2017 <+YOU OR YOUR COMPANY+>.

4
python/vector_cutter.py

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2017 <+YOU OR YOUR COMPANY+>.
@ -21,7 +21,6 @@
import numpy as np
from gnuradio import gr
import code
class vector_cutter(gr.sync_block):
"""
@ -87,7 +86,6 @@ class vector_cutter(gr.sync_block):
else:
out[i]=out_cut*self.mask
#out = in0[512:1536]
#code.interact(local=locals())
#out[0] = in0[0][512:1536]
#out[1] = in0[1][512:1536]
return len(output_items[0])

Loading…
Cancel
Save