mirror of https://github.com/pvnis/srsRAN_4G.git
Reorganized the directory structure. Added Graphics support. Added precoding/layer mapper. MIB detection now working with 1 or 2 tx antennas. Initial eNodeB implementation with PSS/SSS and PBCH generation
parent
40238fe023
commit
8f4dee7c53
@ -1,42 +1,196 @@
|
||||
#
|
||||
# Copyright 2012-2013 The libLTE Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution.
|
||||
#
|
||||
# This file is part of the libLTE library.
|
||||
#
|
||||
# libLTE is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# libLTE 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 Lesser General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Lesser General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
|
||||
########################################################################
|
||||
# Prevent in-tree builds
|
||||
########################################################################
|
||||
|
||||
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
||||
message(FATAL_ERROR "Prevented in-tree build. This is bad practice.")
|
||||
endif(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
||||
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
project (osldlib)
|
||||
|
||||
|
||||
# The version number.
|
||||
set (OSLDLIB_VERSION_MAJOR 0)
|
||||
set (OSLDLIB_VERSION_MINOR 0)
|
||||
########################################################################
|
||||
# Project setup
|
||||
########################################################################
|
||||
CMAKE_MINIMUM_REQUIRED (VERSION 2.6)
|
||||
PROJECT (LIBLTE)
|
||||
|
||||
LIST(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules")
|
||||
|
||||
INCLUDE(libLTEPackage) #setup cpack
|
||||
|
||||
########################################################################
|
||||
# Install Dirs
|
||||
########################################################################
|
||||
SET(RUNTIME_DIR bin)
|
||||
SET(LIBRARY_DIR lib)
|
||||
SET(INCLUDE_DIR include)
|
||||
SET(DOC_DIR "share/doc/${CPACK_PACKAGE_NAME}")
|
||||
SET(DATA_DIR share/${CPACK_PACKAGE_NAME})
|
||||
|
||||
|
||||
IF(NOT CMAKE_BUILD_TYPE)
|
||||
SET(CMAKE_BUILD_TYPE "Release")
|
||||
MESSAGE(STATUS "Build type not specified: defaulting to release.")
|
||||
ENDIF(NOT CMAKE_BUILD_TYPE)
|
||||
SET(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
|
||||
|
||||
########################################################################
|
||||
# Compiler specific setup
|
||||
########################################################################
|
||||
IF(CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-format-extra-args -Wno-reorder -Winline -Wno-unused-result -Wno-format -D_GNU_SOURCE")
|
||||
ENDIF(CMAKE_COMPILER_IS_GNUCXX)
|
||||
|
||||
IF(CMAKE_COMPILER_IS_GNUCC)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-format-extra-args -Winline -Wno-unused-result -Wno-format -std=c99 -D_GNU_SOURCE")
|
||||
ENDIF(CMAKE_COMPILER_IS_GNUCC)
|
||||
|
||||
IF(MSVC)
|
||||
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/msvc) #missing headers
|
||||
ADD_DEFINITIONS(-D_WIN32_WINNT=0x0501) #minimum version required is windows xp
|
||||
ADD_DEFINITIONS(-DNOMINMAX) #disables stupidity and enables std::min and std::max
|
||||
ADD_DEFINITIONS( #stop all kinds of compatibility warnings
|
||||
-D_SCL_SECURE_NO_WARNINGS
|
||||
-D_CRT_SECURE_NO_WARNINGS
|
||||
-D_CRT_SECURE_NO_DEPRECATE
|
||||
-D_CRT_NONSTDC_NO_DEPRECATE
|
||||
)
|
||||
LIST(APPEND IRIS_CORE_COMMON_FLAGS_AND_DEFINES -DHAVE_CONFIG_H)
|
||||
ADD_DEFINITIONS(/MP) #build with multiple processors
|
||||
ENDIF(MSVC)
|
||||
|
||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
# The following is needed for weak linking to work under OS X
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "-undefined dynamic_lookup")
|
||||
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
|
||||
|
||||
########################################################################
|
||||
# Setup Boost
|
||||
########################################################################
|
||||
MESSAGE(STATUS "")
|
||||
MESSAGE(STATUS "Configuring Boost C++ Libraries...")
|
||||
SET(BOOST_REQUIRED_COMPONENTS
|
||||
program_options
|
||||
system
|
||||
thread
|
||||
unit_test_framework
|
||||
)
|
||||
|
||||
IF(UNIX AND EXISTS "/usr/lib64")
|
||||
LIST(APPEND BOOST_LIBRARYDIR "/usr/lib64") #fedora 64-bit fix
|
||||
ENDIF(UNIX AND EXISTS "/usr/lib64")
|
||||
|
||||
IF(MSVC)
|
||||
SET(BOOST_ALL_DYN_LINK "${BOOST_ALL_DYN_LINK}" CACHE BOOL "boost enable dynamic linking")
|
||||
IF(BOOST_ALL_DYN_LINK)
|
||||
ADD_DEFINITIONS(-DBOOST_ALL_DYN_LINK) #setup boost auto-linking in msvc
|
||||
ELSE(BOOST_ALL_DYN_LINK)
|
||||
UNSET(BOOST_REQUIRED_COMPONENTS) #empty components list for static link
|
||||
ENDIF(BOOST_ALL_DYN_LINK)
|
||||
ENDIF(MSVC)
|
||||
|
||||
SET(Boost_ADDITIONAL_VERSIONS
|
||||
"1.37.0" "1.37" "1.38.0" "1.38" "1.39.0" "1.39" "1.40.0" "1.40"
|
||||
"1.41.0" "1.41" "1.42.0" "1.42" "1.43.0" "1.43" "1.44.0" "1.44"
|
||||
"1.42.0" "1.42" "1.43.0" "1.43" "1.44.0" "1.44" "1.45.0" "1.45"
|
||||
"1.46.0" "1.46" "1.47.0" "1.47" "1.48.0" "1.48" "1.49.0" "1.49"
|
||||
"1.50.0" "1.50" "1.51.0" "1.51" "1.52.0" "1.52" "1.53.0" "1.53")
|
||||
FIND_PACKAGE(Boost 1.37 REQUIRED ${BOOST_REQUIRED_COMPONENTS})
|
||||
MESSAGE(STATUS "Boost version: ${Boost_VERSION}")
|
||||
|
||||
IF(Boost_VERSION LESS 104600)
|
||||
ADD_DEFINITIONS( -DBOOST_FILESYSTEM_VERSION=2 ) #use filesystem version 2 in boost < 1.46
|
||||
MESSAGE(STATUS "Using Boost Filesystem V2")
|
||||
ENDIF(Boost_VERSION LESS 104600)
|
||||
|
||||
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
|
||||
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
|
||||
|
||||
MESSAGE(STATUS "Boost include directories: ${Boost_INCLUDE_DIRS}")
|
||||
MESSAGE(STATUS "Boost library directories: ${Boost_LIBRARY_DIRS}")
|
||||
MESSAGE(STATUS "Boost libraries: ${Boost_LIBRARIES}")
|
||||
|
||||
|
||||
########################################################################
|
||||
# Create uninstall targets
|
||||
########################################################################
|
||||
CONFIGURE_FILE(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
IMMEDIATE @ONLY)
|
||||
|
||||
ADD_CUSTOM_TARGET(uninstall
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
|
||||
|
||||
########################################################################
|
||||
# Macro to add -fPIC property to static libs
|
||||
########################################################################
|
||||
MACRO(LIBLTE_SET_PIC)
|
||||
IF( CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" )
|
||||
SET_TARGET_PROPERTIES(${ARGV} PROPERTIES COMPILE_FLAGS -fPIC)
|
||||
ENDIF( CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" )
|
||||
ENDMACRO(LIBLTE_SET_PIC)
|
||||
|
||||
########################################################################
|
||||
# A macro for passing lists between different directories
|
||||
# through an internal cache variable.
|
||||
########################################################################
|
||||
MACRO (APPEND_INTERNAL_LIST LIST_NAME VALUE)
|
||||
|
||||
# If the list in not in the cache, create it.
|
||||
IF (${LIST_NAME})
|
||||
SET (${LIST_NAME} "${${LIST_NAME}};${VALUE}" CACHE INTERNAL "Internal
|
||||
variable")
|
||||
ELSE (${LIST_NAME})
|
||||
SET (${LIST_NAME} "${VALUE}" CACHE INTERNAL "Internal variable")
|
||||
ENDIF (${LIST_NAME})
|
||||
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR ${OSLDLIB_VERSION_MAJOR})
|
||||
set(CPACK_PACKAGE_VERSION_MINOR ${OSLDLIB_VERSION_MINOR})
|
||||
set(CPACK_PACKAGE_VERSION_PATCH "1")
|
||||
set(CPACK_SOURCE_GENERATOR "TBZ2")
|
||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME
|
||||
"${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
||||
set(CPACK_SOURCE_IGNORE_FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR};/.bzr/;~$;${CPACK_SOURCE_IGNORE_FILES}")
|
||||
include(CPack)
|
||||
add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source)
|
||||
ENDMACRO (APPEND_INTERNAL_LIST)
|
||||
|
||||
option(DEBUG "Compiles with debugging symbols and no optimizations" OFF)
|
||||
|
||||
if(DEBUG)
|
||||
message("-- Configuring debugging CFLAGS")
|
||||
set(CFDEB "-O0 -g -rdynamic")
|
||||
else()
|
||||
set(CFDEB "-O2")
|
||||
endif()
|
||||
########################################################################
|
||||
# Print summary
|
||||
########################################################################
|
||||
MESSAGE(STATUS "Using install prefix: ${CMAKE_INSTALL_PREFIX}")
|
||||
MESSAGE(STATUS "Building for version: ${VERSION}")
|
||||
|
||||
set(CMAKE_C_FLAGS "${CFDEB} -Wall -Wno-format-extra-args -Winline -Wno-unused-result -Wno-format -std=c99 -D_GNU_SOURCE")
|
||||
set(CMAKE_BINARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
########################################################################
|
||||
# Add general includes and dependencies
|
||||
########################################################################
|
||||
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/lte/include)
|
||||
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/cuhd/include)
|
||||
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/graphics/include)
|
||||
|
||||
### INCLUDES
|
||||
include_directories("{CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
########################################################################
|
||||
# Add the subdirectories
|
||||
########################################################################
|
||||
|
||||
add_subdirectory(examples)
|
||||
add_subdirectory(lib)
|
||||
ADD_SUBDIRECTORY(lte)
|
||||
ADD_SUBDIRECTORY(cuhd)
|
||||
ADD_SUBDIRECTORY(graphics)
|
||||
ADD_SUBDIRECTORY(examples)
|
||||
|
||||
|
@ -1,22 +0,0 @@
|
||||
# - Find FFTW
|
||||
# Find the native FFTW includes and library
|
||||
#
|
||||
# FFTW_INCLUDES - where to find fftw3.h
|
||||
# FFTW_LIBRARIES - List of libraries when using FFTW.
|
||||
# FFTW_FOUND - True if FFTW found.
|
||||
|
||||
if (FFTWS_INCLUDES)
|
||||
# Already in cache, be silent
|
||||
set (FFTWS_FIND_QUIETLY TRUE)
|
||||
endif (FFTWS_INCLUDES)
|
||||
|
||||
find_path (FFTWS_INCLUDES fftw3.h)
|
||||
SET(CMAKE_FIND_LIBRARY_SUFFIXES .a)
|
||||
find_library (FFTWfS_LIBRARIES NAMES fftw3f)
|
||||
find_library (FFTWnS_LIBRARIES NAMES fftw3)
|
||||
set(FFTWS_LIBRARIES ${FFTWfS_LIBRARIES} ${FFTWnS_LIBRARIES})
|
||||
|
||||
include (FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args (FFTWS DEFAULT_MSG FFTWS_LIBRARIES FFTWS_INCLUDES)
|
||||
|
||||
mark_as_advanced (FFTWS_LIBRARIES FFTWS_INCLUDES)
|
@ -0,0 +1,55 @@
|
||||
#
|
||||
# Copyright 2012-2013 The Iris Project Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution
|
||||
# and at http://www.softwareradiosystems.com/iris/copyright.html.
|
||||
#
|
||||
# This file is part of the Iris Project.
|
||||
#
|
||||
# Iris is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# Iris 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 Lesser General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Lesser General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
# - Try to find fftw3f - the single-precision version of FFTW3
|
||||
# Once done this will define
|
||||
# FFTW3F_FOUND - System has fftw3f
|
||||
# FFTW3F_INCLUDE_DIRS - The fftw3f include directories
|
||||
# FFTW3F_LIBRARIES - The libraries needed to use fftw3f
|
||||
# FFTW3F_DEFINITIONS - Compiler switches required for using fftw3f
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(PC_FFTW3F "fftw3f >= 3.0")
|
||||
set(FFTW3F_DEFINITIONS ${PC_FFTW3F_CFLAGS_OTHER})
|
||||
|
||||
find_path(FFTW3F_INCLUDE_DIR
|
||||
NAMES fftw3.h
|
||||
HINTS ${PC_FFTW3F_INCLUDEDIR} ${PC_FFTW3F_INCLUDE_DIRS} $ENV{FFTW3_DIR}/include
|
||||
PATHS /usr/local/include
|
||||
/usr/include )
|
||||
|
||||
find_library(FFTW3F_LIBRARY
|
||||
NAMES fftw3f libfftw3f libfftw3f-3
|
||||
HINTS ${PC_FFTW3F_LIBDIR} ${PC_FFTW3F_LIBRARY_DIRS} $ENV{FFTW3_DIR}/lib
|
||||
PATHS /usr/local/lib
|
||||
/usr/lib)
|
||||
|
||||
set(FFTW3F_LIBRARIES ${FFTW3F_LIBRARY} )
|
||||
set(FFTW3F_INCLUDE_DIRS ${FFTW3F_INCLUDE_DIR} )
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set FFTW3F_FOUND to TRUE
|
||||
# if all listed variables are TRUE
|
||||
find_package_handle_standard_args(fftw3f DEFAULT_MSG
|
||||
FFTW3F_LIBRARY FFTW3F_INCLUDE_DIR)
|
||||
|
||||
mark_as_advanced(FFTW3F_INCLUDE_DIR FFTW3F_LIBRARY )
|
@ -0,0 +1,141 @@
|
||||
#
|
||||
# Copyright 2012-2013 The Iris Project Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution
|
||||
# and at http://www.softwareradiosystems.com/iris/copyright.html.
|
||||
#
|
||||
# This file is part of the Iris Project.
|
||||
#
|
||||
# Iris is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# Iris 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 Lesser General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Lesser General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
# - Try to find the Qwt includes and library
|
||||
# - Defines the following:
|
||||
#
|
||||
# QWT_FOUND - system has Qwt
|
||||
# QWT_INCLUDE_DIR - where to find qwt.h
|
||||
# QWT_INCLUDE_DIRS - the qwt include directories
|
||||
# QWT_LIBRARY - where to find the Qwt library (not for general use)
|
||||
# QWT_LIBRARIES - the libraries to link against to use Qwt
|
||||
# QWT_MAJOR_VERSION - major version
|
||||
# QWT_MINOR_VERSION - minor version
|
||||
# QWT_PATCH_VERSION - patch version
|
||||
# QWT_VERSION_STRING - version (ex. 5.2.1)
|
||||
|
||||
SET(QWT_FOUND "NO")
|
||||
|
||||
FIND_PATH(QWT_INCLUDE_DIR qwt.h
|
||||
/usr/local/qwt/include
|
||||
/usr/local/include
|
||||
/usr/include/qwt
|
||||
/usr/include/qwt-qt4
|
||||
/usr/include/qwt5
|
||||
/usr/include
|
||||
/opt/local/include/qwt #macports path
|
||||
$ENV{QWT_DIR}/include
|
||||
$ENV{QWT_DIR}/src
|
||||
$ENV{QWTDIR}/include
|
||||
$ENV{QWTDIR}/src
|
||||
$ENV{QWT_ROOT}/include
|
||||
$ENV{QWT_ROOT}/src
|
||||
$ENV{QWTROOT}/include
|
||||
$ENV{QWTROOT}/src
|
||||
)
|
||||
|
||||
SET(QWT_INCLUDE_DIRS ${QWT_INCLUDE_DIR})
|
||||
|
||||
# version
|
||||
SET(_VERSION_FILE ${QWT_INCLUDE_DIR}/qwt_global.h)
|
||||
IF(EXISTS ${_VERSION_FILE} )
|
||||
FILE( STRINGS ${_VERSION_FILE} _VERSION_LINE REGEX "define[ ]+QWT_VERSION_STR")
|
||||
IF( _VERSION_LINE )
|
||||
STRING( REGEX REPLACE ".*define[ ]+QWT_VERSION_STR[ ]+\"(.*)\".*" "\\1" QWT_VERSION_STRING "${_VERSION_LINE}" )
|
||||
STRING( REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\1" QWT_MAJOR_VERSION "${QWT_VERSION_STRING}" )
|
||||
STRING( REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\2" QWT_MINOR_VERSION "${QWT_VERSION_STRING}" )
|
||||
STRING( REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\3" QWT_PATCH_VERSION "${QWT_VERSION_STRING}" )
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
|
||||
# check version
|
||||
SET( _QWT_VERSION_MATCH TRUE )
|
||||
IF( Qwt_FIND_VERSION AND QWT_VERSION_STRING )
|
||||
IF( Qwt_FIND_VERSION_EXACT )
|
||||
IF( NOT Qwt_FIND_VERSION VERSION_EQUAL QWT_VERSION_STRING )
|
||||
SET( _QWT_VERSION_MATCH FALSE )
|
||||
ENDIF()
|
||||
ELSE()
|
||||
IF( QWT_VERSION_STRING VERSION_LESS Qwt_FIND_VERSION )
|
||||
SET( _QWT_VERSION_MATCH FALSE )
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
SET(POTENTIAL_LIBRARY_PATHS /usr/local/qwt/lib /usr/local/lib /usr/lib /opt/local/lib
|
||||
$ENV{QWT_DIR}/lib $ENV{QWTDIR}/lib $ENV{QWT_ROOT}/lib $ENV{QWTROOT}/lib)
|
||||
|
||||
SET(QWT_NAMES ${QWT_NAMES} qwt qwt-qt4 qwt5 )
|
||||
FIND_LIBRARY(QWT_LIBRARY
|
||||
NAMES ${QWT_NAMES}
|
||||
PATHS ${POTENTIAL_LIBRARY_PATHS}
|
||||
)
|
||||
MARK_AS_ADVANCED(QWT_LIBRARY)
|
||||
|
||||
IF (QWT_LIBRARY)
|
||||
|
||||
IF(WIN32 AND NOT CYGWIN)
|
||||
|
||||
SET(QWT_NAMES_DEBUG qwtd qwtd-qt4 qwtd5 )
|
||||
FIND_LIBRARY(QWT_LIBRARY_DEBUG
|
||||
NAMES ${QWT_NAMES_DEBUG}
|
||||
PATHS ${POTENTIAL_LIBRARY_PATHS}
|
||||
)
|
||||
MARK_AS_ADVANCED(QWT_LIBRARY_DEBUG)
|
||||
|
||||
IF(QWT_LIBRARY_DEBUG)
|
||||
SET(QWT_LIBRARIES optimized ${QWT_LIBRARY} debug ${QWT_LIBRARY_DEBUG} CACHE DOC "QWT library files")
|
||||
ELSE(QWT_LIBRARY_DEBUG)
|
||||
SET(QWT_LIBRARIES ${QWT_LIBRARY} CACHE DOC "QWT library files")
|
||||
ENDIF(QWT_LIBRARY_DEBUG)
|
||||
|
||||
ADD_DEFINITIONS(-DQWT_DLL)
|
||||
|
||||
ELSE(WIN32 AND NOT CYGWIN)
|
||||
|
||||
SET(QWT_LIBRARIES ${QWT_LIBRARY} CACHE DOC "QWT library files")
|
||||
|
||||
ENDIF(WIN32 AND NOT CYGWIN)
|
||||
|
||||
SET(QWT_FOUND "YES")
|
||||
|
||||
IF (CYGWIN)
|
||||
IF(BUILD_SHARED_LIBS)
|
||||
# No need to define QWT_USE_DLL here, because it's default for Cygwin.
|
||||
ELSE(BUILD_SHARED_LIBS)
|
||||
SET (QWT_DEFINITIONS -DQWT_STATIC)
|
||||
ENDIF(BUILD_SHARED_LIBS)
|
||||
ENDIF (CYGWIN)
|
||||
|
||||
ENDIF (QWT_LIBRARY)
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments
|
||||
INCLUDE( FindPackageHandleStandardArgs )
|
||||
IF( CMAKE_VERSION LESS 2.8.3 )
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS( Qwt DEFAULT_MSG QWT_LIBRARY QWT_INCLUDE_DIR _QWT_VERSION_MATCH )
|
||||
ELSE()
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS( Qwt REQUIRED_VARS QWT_LIBRARY QWT_INCLUDE_DIR _QWT_VERSION_MATCH VERSION_VAR QWT_VERSION_STRING )
|
||||
ENDIF()
|
||||
|
||||
MARK_AS_ADVANCED(QWT_INCLUDE_DIR QWT_LIBRARY)
|
||||
|
@ -0,0 +1,85 @@
|
||||
#
|
||||
# Copyright 2012-2013 The Iris Project Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution
|
||||
# and at http://www.softwareradiosystems.com/iris/copyright.html.
|
||||
#
|
||||
# This file is part of the Iris Project.
|
||||
#
|
||||
# Iris is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# Iris 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 Lesser General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Lesser General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
SET(CPACK_PACKAGE_DESCRIPTION "libLTE")
|
||||
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "LTE library for SDR.")
|
||||
SET(CPACK_PACKAGE_NAME "liblte")
|
||||
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.3.6), libgcc1 (>= 1:4.1), libboost-dev (>= 1.35)")
|
||||
|
||||
SET(CPACK_PACKAGE_CONTACT "Ismael Gomez ")
|
||||
SET(CPACK_PACKAGE_VENDOR "University of Dublin, Trinity College")
|
||||
SET(CPACK_PACKAGE_VERSION_MAJOR "0")
|
||||
SET(CPACK_PACKAGE_VERSION_MINOR "1")
|
||||
SET(CPACK_PACKAGE_VERSION_PATCH "0")
|
||||
SET(VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
||||
|
||||
########################################################################
|
||||
# Setup additional defines for OS types
|
||||
########################################################################
|
||||
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
SET(LINUX TRUE)
|
||||
ENDIF()
|
||||
|
||||
IF(LINUX AND EXISTS "/etc/debian_version")
|
||||
SET(DEBIAN TRUE)
|
||||
ENDIF()
|
||||
|
||||
IF(LINUX AND EXISTS "/etc/redhat-release")
|
||||
SET(REDHAT TRUE)
|
||||
ENDIF()
|
||||
|
||||
########################################################################
|
||||
# Set generator type for recognized systems
|
||||
########################################################################
|
||||
IF(CPACK_GENERATOR)
|
||||
#already set
|
||||
ELSEIF(APPLE)
|
||||
SET(CPACK_GENERATOR PackageMaker)
|
||||
ELSEIF(WIN32)
|
||||
SET(CPACK_GENERATOR NSIS)
|
||||
ELSEIF(DEBIAN)
|
||||
SET(CPACK_GENERATOR DEB)
|
||||
ELSEIF(REDHAT)
|
||||
SET(CPACK_GENERATOR RPM)
|
||||
ELSE()
|
||||
SET(CPACK_GENERATOR TGZ)
|
||||
ENDIF()
|
||||
|
||||
########################################################################
|
||||
# Setup CPack Debian
|
||||
########################################################################
|
||||
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libboost-dev")
|
||||
|
||||
########################################################################
|
||||
# Setup CPack RPM
|
||||
########################################################################
|
||||
SET(CPACK_RPM_PACKAGE_REQUIRES "boost-devel")
|
||||
|
||||
########################################################################
|
||||
# Setup CPack NSIS
|
||||
########################################################################
|
||||
SET(CPACK_NSIS_MODIFY_PATH ON)
|
||||
|
||||
|
||||
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}-${CMAKE_SYSTEM_PROCESSOR}")
|
||||
INCLUDE(CPack)
|
||||
|
@ -0,0 +1,26 @@
|
||||
if(POLICY CMP0007)
|
||||
cmake_policy(SET CMP0007 OLD)
|
||||
endif(POLICY CMP0007)
|
||||
|
||||
if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
|
||||
endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
|
||||
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
|
||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||
list(REVERSE files)
|
||||
foreach (file ${files})
|
||||
message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
|
||||
if (EXISTS "$ENV{DESTDIR}${file}")
|
||||
execute_process(
|
||||
COMMAND @CMAKE_COMMAND@ -E remove "$ENV{DESTDIR}${file}"
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RESULT_VARIABLE rm_retval
|
||||
)
|
||||
if(NOT ${rm_retval} EQUAL 0)
|
||||
message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
|
||||
endif (NOT ${rm_retval} EQUAL 0)
|
||||
else (EXISTS "$ENV{DESTDIR}${file}")
|
||||
message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
|
||||
endif (EXISTS "$ENV{DESTDIR}${file}")
|
||||
endforeach(file)
|
@ -0,0 +1,36 @@
|
||||
#
|
||||
# Copyright 2012-2013 The libLTE Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution.
|
||||
#
|
||||
# This file is part of the libLTE library.
|
||||
#
|
||||
# libLTE is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# libLTE 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 Lesser General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Lesser General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
########################################################################
|
||||
# Install headers
|
||||
########################################################################
|
||||
INSTALL(DIRECTORY include/ DESTINATION "${INCLUDE_DIR}"
|
||||
FILES_MATCHING PATTERN "*.h"
|
||||
PATTERN ".svn" EXCLUDE
|
||||
)
|
||||
|
||||
|
||||
########################################################################
|
||||
# Add the subdirectories
|
||||
########################################################################
|
||||
|
||||
ADD_SUBDIRECTORY(lib)
|
||||
|
@ -0,0 +1,58 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The libLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the libLTE library.
|
||||
*
|
||||
* libLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* libLTE 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "cuhd/cuhd_utils.h"
|
||||
|
||||
int cuhd_open(char *args, void **handler);
|
||||
int cuhd_close(void *h);
|
||||
|
||||
int cuhd_start_rx_stream(void *h);
|
||||
int cuhd_start_rx_stream_nsamples(void *h, int nsamples);
|
||||
int cuhd_stop_rx_stream(void *h);
|
||||
bool cuhd_rx_wait_lo_locked(void *h);
|
||||
double cuhd_set_rx_srate(void *h, double freq);
|
||||
double cuhd_set_rx_gain(void *h, double gain);
|
||||
double cuhd_set_rx_freq(void *h, double freq);
|
||||
int cuhd_recv(void *h, void *data, int nsamples, int blocking);
|
||||
|
||||
int cuhd_start_tx_stream(void *h);
|
||||
double cuhd_set_tx_srate(void *h, double freq);
|
||||
double cuhd_set_tx_gain(void *h, double gain);
|
||||
double cuhd_set_tx_freq(void *h, double freq);
|
||||
int cuhd_send(void *h, void *data, int nsamples, int blocking);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1,30 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The libLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the libLTE library.
|
||||
*
|
||||
* libLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* libLTE 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
int cuhd_rssi_scan(void *uhd, float *freqs, float *rssi, int nof_bands, double fs, int nsamp);
|
@ -0,0 +1,43 @@
|
||||
#
|
||||
# Copyright 2012-2013 The libLTE Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution.
|
||||
#
|
||||
# This file is part of the libLTE library.
|
||||
#
|
||||
# libLTE is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# libLTE 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 Lesser General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Lesser General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
FIND_PACKAGE(UHD)
|
||||
|
||||
IF(UHD_FOUND)
|
||||
|
||||
ADD_LIBRARY(cuhd cuhd_imp.cpp cuhd_utils.c)
|
||||
INCLUDE_DIRECTORIES(${UHD_INCLUDE_DIRS})
|
||||
TARGET_LINK_LIBRARIES(cuhd ${UHD_LIBRARIES})
|
||||
|
||||
LIBLTE_SET_PIC(cuhd)
|
||||
APPEND_INTERNAL_LIST(OPTIONAL_LIBS cuhd)
|
||||
INSTALL(TARGETS cuhd DESTINATION ${LIBRARY_DIR})
|
||||
|
||||
MESSAGE(STATUS " cuhd UHD C wrapper will be installed.")
|
||||
|
||||
ELSE(UHD_FOUND)
|
||||
|
||||
MESSAGE(STATUS " UHD driver not found. CUHD library is not generated")
|
||||
|
||||
ENDIF(UHD_FOUND)
|
||||
|
||||
|
||||
|
@ -0,0 +1,38 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The libLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the libLTE library.
|
||||
*
|
||||
* libLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* libLTE 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <uhd/usrp/multi_usrp.hpp>
|
||||
|
||||
class cuhd_handler {
|
||||
public:
|
||||
uhd::usrp::multi_usrp::sptr usrp;
|
||||
uhd::rx_streamer::sptr rx_stream;
|
||||
bool rx_stream_enable;
|
||||
uhd::tx_streamer::sptr tx_stream;
|
||||
|
||||
};
|
@ -0,0 +1,210 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The libLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the libLTE library.
|
||||
*
|
||||
* libLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* libLTE 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <uhd/usrp/multi_usrp.hpp>
|
||||
#include <iostream>
|
||||
#include <complex>
|
||||
#include <cstdio>
|
||||
#include <uhd/utils/msg.hpp>
|
||||
|
||||
#include "cuhd_handler.hpp"
|
||||
#include "cuhd.h"
|
||||
|
||||
|
||||
void my_handler(uhd::msg::type_t type, const std::string &msg){
|
||||
//handle the message...
|
||||
}
|
||||
|
||||
typedef _Complex float complex_t;
|
||||
|
||||
#define SAMPLE_SZ sizeof(complex_t)
|
||||
|
||||
bool isLocked(void *h)
|
||||
{
|
||||
cuhd_handler* handler = static_cast<cuhd_handler*>(h);
|
||||
return handler->usrp->get_rx_sensor("lo_locked", 0).to_bool();
|
||||
}
|
||||
|
||||
bool cuhd_rx_wait_lo_locked(void *h)
|
||||
{
|
||||
|
||||
double report = 0.0;
|
||||
while(isLocked(h) && report < 3.0)
|
||||
{
|
||||
report += 0.1;
|
||||
usleep(1000);
|
||||
}
|
||||
return isLocked(h);
|
||||
}
|
||||
|
||||
int cuhd_start_rx_stream(void *h) {
|
||||
cuhd_handler* handler = static_cast<cuhd_handler*>(h);
|
||||
uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
|
||||
cmd.time_spec = handler->usrp->get_time_now();
|
||||
cmd.stream_now = true;
|
||||
handler->usrp->issue_stream_cmd(cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cuhd_stop_rx_stream(void *h) {
|
||||
cuhd_handler* handler = static_cast<cuhd_handler*>(h);
|
||||
uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS);
|
||||
cmd.time_spec = handler->usrp->get_time_now();
|
||||
cmd.stream_now = true;
|
||||
handler->usrp->issue_stream_cmd(cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cuhd_start_rx_stream_nsamples(void *h, int nsamples) {
|
||||
cuhd_handler* handler = static_cast<cuhd_handler*>(h);
|
||||
uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_MORE);
|
||||
cmd.time_spec = handler->usrp->get_time_now();
|
||||
cmd.stream_now = true;
|
||||
cmd.num_samps = nsamples;
|
||||
handler->usrp->issue_stream_cmd(cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int cuhd_open(char *args, void **h) {
|
||||
cuhd_handler* handler = new cuhd_handler();
|
||||
std::string _args=std::string(args);
|
||||
handler->usrp = uhd::usrp::multi_usrp::make(_args);
|
||||
|
||||
//uhd::msg::register_handler(&my_handler);
|
||||
|
||||
std::string otw, cpu;
|
||||
otw="sc16";
|
||||
cpu="fc32";
|
||||
|
||||
handler->usrp->set_clock_source("internal");
|
||||
|
||||
uhd::stream_args_t stream_args(cpu, otw);
|
||||
// stream_args.channels.push_back(0);
|
||||
// stream_args.args["noclear"] = "1";
|
||||
|
||||
handler->rx_stream = handler->usrp->get_rx_stream(stream_args);
|
||||
*h = handler;
|
||||
|
||||
handler->tx_stream = handler->usrp->get_tx_stream(stream_args);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cuhd_close(void *h) {
|
||||
/** TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
double cuhd_set_rx_srate(void *h, double freq) {
|
||||
cuhd_handler* handler = static_cast<cuhd_handler*>(h);
|
||||
handler->usrp->set_rx_rate(freq);
|
||||
double ret = handler->usrp->get_rx_rate();
|
||||
return ret;
|
||||
}
|
||||
|
||||
double cuhd_set_rx_gain(void *h, double gain) {
|
||||
cuhd_handler* handler = static_cast<cuhd_handler*>(h);
|
||||
handler->usrp->set_rx_gain(gain);
|
||||
return handler->usrp->get_rx_gain();
|
||||
}
|
||||
|
||||
double cuhd_set_rx_freq(void *h, double freq) {
|
||||
cuhd_handler* handler = static_cast<cuhd_handler*>(h);
|
||||
handler->usrp->set_rx_freq(freq);
|
||||
return handler->usrp->get_rx_freq();
|
||||
}
|
||||
|
||||
int cuhd_recv(void *h, void *data, int nsamples, int blocking) {
|
||||
cuhd_handler* handler = static_cast<cuhd_handler*>(h);
|
||||
uhd::rx_metadata_t md;
|
||||
if (blocking) {
|
||||
int n=0,p;
|
||||
complex_t *data_c = (complex_t*) data;
|
||||
do {
|
||||
p=handler->rx_stream->recv(&data_c[n], nsamples-n, md);
|
||||
if (p == -1) {
|
||||
return -1;
|
||||
}
|
||||
n+=p;
|
||||
} while(n<nsamples);
|
||||
return nsamples;
|
||||
} else {
|
||||
return handler->rx_stream->recv(data, nsamples, md, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int cuhd_start_tx_stream(void *h) {
|
||||
cuhd_handler* handler = static_cast<cuhd_handler*>(h);
|
||||
uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
|
||||
cmd.time_spec = handler->usrp->get_time_now();
|
||||
cmd.stream_now = true;
|
||||
handler->usrp->issue_stream_cmd(cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
double cuhd_set_tx_gain(void *h, double gain) {
|
||||
cuhd_handler* handler = static_cast<cuhd_handler*>(h);
|
||||
handler->usrp->set_tx_gain(gain);
|
||||
return handler->usrp->get_tx_gain();
|
||||
}
|
||||
|
||||
double cuhd_set_tx_srate(void *h, double freq) {
|
||||
cuhd_handler* handler = static_cast<cuhd_handler*>(h);
|
||||
handler->usrp->set_tx_rate(freq);
|
||||
return handler->usrp->get_tx_rate();
|
||||
}
|
||||
|
||||
double cuhd_set_tx_freq(void *h, double freq) {
|
||||
cuhd_handler* handler = static_cast<cuhd_handler*>(h);
|
||||
handler->usrp->set_tx_freq(freq);
|
||||
return handler->usrp->get_tx_freq();
|
||||
}
|
||||
|
||||
int cuhd_send(void *h, void *data, int nsamples, int blocking) {
|
||||
cuhd_handler* handler = static_cast<cuhd_handler*>(h);
|
||||
uhd::tx_metadata_t md;
|
||||
if (blocking) {
|
||||
int n=0,p;
|
||||
complex_t *data_c = (complex_t*) data;
|
||||
do {
|
||||
p=handler->tx_stream->send(&data_c[n], nsamples-n, md);
|
||||
if (p == -1) {
|
||||
return -1;
|
||||
}
|
||||
n+=p;
|
||||
} while(n<nsamples);
|
||||
return nsamples;
|
||||
} else {
|
||||
return handler->tx_stream->send(data, nsamples, md, 0.0);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,79 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The libLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the libLTE library.
|
||||
*
|
||||
* libLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* libLTE 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
#include "cuhd.h"
|
||||
#include "lte/utils/vector.h"
|
||||
#include "lte/utils/debug.h"
|
||||
|
||||
int cuhd_rssi_scan(void *uhd, float *freqs, float *rssi, int nof_bands, double fs, int nsamp) {
|
||||
int i, j;
|
||||
int ret = -1;
|
||||
_Complex float *buffer;
|
||||
double f;
|
||||
|
||||
buffer = calloc(nsamp, sizeof(_Complex float));
|
||||
if (!buffer) {
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
cuhd_set_rx_gain(uhd, 0.0);
|
||||
cuhd_set_rx_srate(uhd, fs);
|
||||
|
||||
for (i=0;i<nof_bands;i++) {
|
||||
cuhd_stop_rx_stream(uhd);
|
||||
|
||||
f = (double) freqs[i];
|
||||
cuhd_set_rx_freq(uhd, f);
|
||||
cuhd_rx_wait_lo_locked(uhd);
|
||||
|
||||
cuhd_start_rx_stream(uhd);
|
||||
|
||||
/* discard first samples */
|
||||
for (j=0;j<2;j++) {
|
||||
if (cuhd_recv(uhd, buffer, nsamp, 1) != nsamp) {
|
||||
goto free_and_exit;
|
||||
}
|
||||
}
|
||||
rssi[i] = vec_avg_power_cf(buffer, nsamp);
|
||||
printf("[%3d]: Freq %4.1f Mhz - RSSI: %3.2f dBm\r", i, f/1000000, 10*log10f(rssi[i]) + 30); fflush(stdout);
|
||||
if (VERBOSE_ISINFO()) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
cuhd_stop_rx_stream(uhd);
|
||||
|
||||
ret = 0;
|
||||
free_and_exit:
|
||||
free(buffer);
|
||||
return ret;
|
||||
}
|
@ -1,50 +1,71 @@
|
||||
#include fftw3 directories
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/")
|
||||
|
||||
find_package(FFTWS REQUIRED)
|
||||
include_directories(${FFTWS_INCLUDE_DIRS})
|
||||
|
||||
find_package(UHD)
|
||||
|
||||
|
||||
set(LIBRARIES osld m ${FFTWS_LIBRARIES})
|
||||
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include)
|
||||
#
|
||||
# Copyright 2012-2013 The libLTE Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution.
|
||||
#
|
||||
# This file is part of the libLTE library.
|
||||
#
|
||||
# libLTE is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# libLTE 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 Lesser General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Lesser General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
# TO BE MOVED TO UNIT TESTS
|
||||
|
||||
add_executable(hl_example hl_example.c)
|
||||
target_link_libraries(hl_example ${LIBRARIES})
|
||||
target_link_libraries(hl_example lte)
|
||||
|
||||
add_executable(ll_example ll_example.c)
|
||||
target_link_libraries(ll_example ${LIBRARIES})
|
||||
target_link_libraries(ll_example lte)
|
||||
|
||||
add_executable(synch_test synch_test.c)
|
||||
target_link_libraries(synch_test ${LIBRARIES})
|
||||
target_link_libraries(synch_test lte)
|
||||
|
||||
add_executable(equalizer_test equalizer_test.c)
|
||||
target_link_libraries(equalizer_test ${LIBRARIES})
|
||||
target_link_libraries(equalizer_test lte)
|
||||
|
||||
add_executable(viterbi_test viterbi_test.c)
|
||||
target_link_libraries(viterbi_test ${LIBRARIES})
|
||||
|
||||
add_executable(cell_search cell_search.c)
|
||||
target_link_libraries(cell_search ${LIBRARIES})
|
||||
|
||||
|
||||
include_directories(${UHD_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/../uhd)
|
||||
add_executable(rssi_scan_usrp rssi_scan_usrp.c ../uhd/uhd_imp.cpp ../uhd/uhd_utils.c)
|
||||
target_link_libraries(rssi_scan_usrp ${LIBRARIES} ${UHD_LIBRARIES})
|
||||
|
||||
|
||||
include_directories(${UHD_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/../uhd)
|
||||
add_executable(pss_scan_usrp pss_scan_usrp.c ../uhd/uhd_imp.cpp ../uhd/uhd_utils.c)
|
||||
target_link_libraries(pss_scan_usrp ${LIBRARIES} ${UHD_LIBRARIES})
|
||||
|
||||
|
||||
include_directories(${UHD_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/../uhd)
|
||||
add_executable(mib_scan_usrp mib_scan_usrp.c ../uhd/uhd_imp.cpp ../uhd/uhd_utils.c)
|
||||
target_link_libraries(mib_scan_usrp ${LIBRARIES} ${UHD_LIBRARIES})
|
||||
|
||||
|
||||
target_link_libraries(viterbi_test lte)
|
||||
|
||||
add_executable(mib_test mib_test.c)
|
||||
target_link_libraries(mib_test lte)
|
||||
|
||||
LIST(FIND OPTIONAL_LIBS cuhd CUHD_FIND)
|
||||
LIST(FIND OPTIONAL_LIBS graphics GRAPHICS_FIND)
|
||||
|
||||
|
||||
IF(${CUHD_FIND} GREATER -1)
|
||||
IF(${GRAPHICS_FIND} GREATER -1)
|
||||
add_executable(mib_track mib_track.c)
|
||||
target_link_libraries(mib_track lte cuhd graphics)
|
||||
ELSE(${GRAPHICS_FIND} GREATER -1)
|
||||
MESSAGE(STATUS " mib_track is ignored: GRAPHICS library not compiled.")
|
||||
ENDIF(${GRAPHICS_FIND} GREATER -1)
|
||||
|
||||
add_executable(enodeb_bch enodeb_bch.c)
|
||||
target_link_libraries(enodeb_bch lte cuhd )
|
||||
|
||||
add_executable(rssi_scan_usrp rssi_scan_usrp.c)
|
||||
target_link_libraries(rssi_scan_usrp lte cuhd )
|
||||
|
||||
add_executable(pss_scan_usrp pss_scan_usrp.c)
|
||||
target_link_libraries(pss_scan_usrp lte cuhd )
|
||||
|
||||
add_executable(mib_scan_usrp mib_scan_usrp.c)
|
||||
target_link_libraries(mib_scan_usrp lte cuhd )
|
||||
|
||||
MESSAGE(STATUS " UHD examples will be installed.")
|
||||
|
||||
ELSE(${CUHD_FIND} GREATER -1)
|
||||
MESSAGE(STATUS " UHD examples NOT INSTALLED: CUHD library not compiled.")
|
||||
ENDIF(${CUHD_FIND} GREATER -1)
|
||||
|
||||
|
@ -1,22 +0,0 @@
|
||||
# - Find FFTW
|
||||
# Find the native FFTW includes and library
|
||||
#
|
||||
# FFTW_INCLUDES - where to find fftw3.h
|
||||
# FFTW_LIBRARIES - List of libraries when using FFTW.
|
||||
# FFTW_FOUND - True if FFTW found.
|
||||
|
||||
if (FFTWS_INCLUDES)
|
||||
# Already in cache, be silent
|
||||
set (FFTWS_FIND_QUIETLY TRUE)
|
||||
endif (FFTWS_INCLUDES)
|
||||
|
||||
find_path (FFTWS_INCLUDES fftw3.h)
|
||||
SET(CMAKE_FIND_LIBRARY_SUFFIXES .a)
|
||||
find_library (FFTWfS_LIBRARIES NAMES fftw3f)
|
||||
find_library (FFTWnS_LIBRARIES NAMES fftw3)
|
||||
set(FFTWS_LIBRARIES ${FFTWfS_LIBRARIES} ${FFTWnS_LIBRARIES})
|
||||
|
||||
include (FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args (FFTWS DEFAULT_MSG FFTWS_LIBRARIES FFTWS_INCLUDES)
|
||||
|
||||
mark_as_advanced (FFTWS_LIBRARIES FFTWS_INCLUDES)
|
@ -0,0 +1,275 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The libLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the libLTE library.
|
||||
*
|
||||
* libLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* libLTE 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lte.h"
|
||||
|
||||
#define ENABLE_UHD
|
||||
|
||||
#ifdef ENABLE_UHD
|
||||
#include "cuhd.h"
|
||||
void *uhd;
|
||||
#endif
|
||||
|
||||
char *output_file_name = NULL;
|
||||
int nof_frames=-1;
|
||||
int cell_id = 1;
|
||||
int nof_prb = 6;
|
||||
|
||||
|
||||
filesink_t fsink;
|
||||
lte_fft_t ifft;
|
||||
pbch_t pbch;
|
||||
|
||||
cf_t *slot_buffer = NULL, *output_buffer = NULL;
|
||||
int slot_n_re, slot_n_samples;
|
||||
|
||||
#define cuhd_FREQ 2680000000
|
||||
#define cuhd_SAMP_FREQ 1920000
|
||||
#define cuhd_GAIN 10
|
||||
#define cuhd_AMP 0.25
|
||||
#define cuhd_ARGS "addr=192.168.10.3"
|
||||
|
||||
void usage(char *prog) {
|
||||
printf("Usage: %s [ncvp]\n", prog);
|
||||
printf("\t-o output_file [Default USRP]\n");
|
||||
printf("\t-n number of frames [Default %d]\n", nof_frames);
|
||||
printf("\t-c cell id [Default %d]\n", cell_id);
|
||||
printf("\t-p nof_prb [Default %d]\n", nof_prb);
|
||||
printf("\t-v [set verbose to debug, default none]\n");
|
||||
}
|
||||
|
||||
void parse_args(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "oncpv")) != -1) {
|
||||
switch(opt) {
|
||||
case 'o':
|
||||
output_file_name = argv[optind];
|
||||
break;
|
||||
case 'n':
|
||||
nof_frames = atoi(argv[optind]);
|
||||
break;
|
||||
case 'p':
|
||||
nof_prb = atoi(argv[optind]);
|
||||
break;
|
||||
case 'c':
|
||||
cell_id = atoi(argv[optind]);
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
#ifndef ENABLE_UHD
|
||||
if (!output_file_name) {
|
||||
usage(argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void base_init() {
|
||||
/* init memory */
|
||||
slot_buffer = malloc(sizeof(cf_t) * slot_n_re);
|
||||
if (!slot_buffer) {
|
||||
perror("malloc");
|
||||
exit(-1);
|
||||
}
|
||||
output_buffer = malloc(sizeof(cf_t) * slot_n_samples);
|
||||
if (!output_buffer) {
|
||||
perror("malloc");
|
||||
exit(-1);
|
||||
}
|
||||
/* open file or USRP */
|
||||
if (output_file_name) {
|
||||
if (filesink_init(&fsink, output_file_name, COMPLEX_FLOAT_BIN)) {
|
||||
fprintf(stderr, "Error opening file %s\n", output_file_name);
|
||||
exit(-1);
|
||||
}
|
||||
} else {
|
||||
#ifdef ENABLE_UHD
|
||||
printf("Opening UHD device...\n");
|
||||
if (cuhd_open(cuhd_ARGS,&uhd)) {
|
||||
fprintf(stderr, "Error opening uhd\n");
|
||||
exit(-1);
|
||||
}
|
||||
#else
|
||||
exit(-1); // not supposed to be here
|
||||
#endif
|
||||
}
|
||||
/* create ifft object */
|
||||
if (lte_ifft_init(&ifft, CPNORM, nof_prb)) {
|
||||
fprintf(stderr, "Error creating iFFT object\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (pbch_init(&pbch, cell_id, CPNORM)) {
|
||||
fprintf(stderr, "Error creating PBCH object\n");
|
||||
exit(-1);
|
||||
}
|
||||
#ifdef ENABLE_MATLAB
|
||||
fmatlab = fopen("output.m", "w");
|
||||
if (!fmatlab) {
|
||||
perror("fopen");
|
||||
exit(-1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void base_free() {
|
||||
|
||||
pbch_free(&pbch);
|
||||
|
||||
lte_ifft_free(&ifft);
|
||||
|
||||
if (slot_buffer) {
|
||||
free(slot_buffer);
|
||||
}
|
||||
if (output_buffer) {
|
||||
free(output_buffer);
|
||||
}
|
||||
if (output_file_name) {
|
||||
filesink_free(&fsink);
|
||||
} else {
|
||||
#ifdef ENABLE_UHD
|
||||
cuhd_close(&uhd);
|
||||
#endif
|
||||
}
|
||||
#ifdef ENABLE_MATLAB
|
||||
fclose(fmatlab);
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int nf, ns, N_id_2;
|
||||
cf_t pss_signal[PSS_LEN];
|
||||
float sss_signal0[SSS_LEN]; // for subframe 0
|
||||
float sss_signal5[SSS_LEN]; // for subframe 5
|
||||
pbch_mib_t mib;
|
||||
refsignal_t refs[NSLOTS_X_FRAME];
|
||||
int i;
|
||||
cf_t *slot1_symbols[MAX_PORTS_CTRL];
|
||||
|
||||
|
||||
#ifndef ENABLE_UHD
|
||||
if (argc < 3) {
|
||||
usage(argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
parse_args(argc,argv);
|
||||
|
||||
N_id_2 = cell_id%3;
|
||||
slot_n_re = CPNORM_NSYMB * nof_prb * RE_X_RB;
|
||||
slot_n_samples = SLOT_LEN_CPNORM(lte_symbol_sz(nof_prb));
|
||||
|
||||
/* this *must* be called after setting slot_len_* */
|
||||
base_init();
|
||||
|
||||
/* Generate PSS/SSS signals */
|
||||
pss_generate(pss_signal, N_id_2);
|
||||
sss_generate(sss_signal0, sss_signal5, cell_id);
|
||||
|
||||
/* Generate CRS signals */
|
||||
for (i=0;i<NSLOTS_X_FRAME;i++) {
|
||||
if (refsignal_init_LTEDL(&refs[i], 0, i, cell_id, CPNORM, nof_prb)) {
|
||||
fprintf(stderr, "Error initiating CRS slot=%d\n", i);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
mib.nof_ports = 1;
|
||||
mib.nof_prb = 6;
|
||||
mib.phich_length = NORMAL;
|
||||
mib.phich_resources = R_1;
|
||||
mib.sfn = 0;
|
||||
|
||||
for (i=0;i<MAX_PORTS_CTRL;i++) { // now there's only 1 port
|
||||
slot1_symbols[i] = slot_buffer;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_UHD
|
||||
if (!output_file_name) {
|
||||
printf("Set TX rate: %.2f MHz\n", cuhd_set_tx_srate(uhd, cuhd_SAMP_FREQ)/1000000);
|
||||
printf("Set TX gain: %.1f dB\n", cuhd_set_tx_gain(uhd, cuhd_GAIN));
|
||||
printf("Set TX freq: %.2f MHz\n", cuhd_set_tx_freq(uhd, cuhd_FREQ)/1000000);
|
||||
cuhd_start_tx_stream(uhd);
|
||||
}
|
||||
#endif
|
||||
|
||||
nf = 0;
|
||||
|
||||
while(nf<nof_frames || nof_frames == -1) {
|
||||
for (ns=0;ns<NSLOTS_X_FRAME;ns++) {
|
||||
bzero(slot_buffer, sizeof(cf_t) * slot_n_re);
|
||||
|
||||
switch(ns) {
|
||||
case 0: // tx pss/sss
|
||||
case 10: // tx pss/sss
|
||||
pss_put_slot(pss_signal, slot_buffer, nof_prb, CPNORM);
|
||||
sss_put_slot(ns?sss_signal5:sss_signal0, slot_buffer, nof_prb, CPNORM);
|
||||
break;
|
||||
case 1: // tx pbch
|
||||
pbch_encode(&pbch, &mib, slot1_symbols, nof_prb, 1);
|
||||
break;
|
||||
default: // transmit zeros
|
||||
break;
|
||||
}
|
||||
|
||||
refsignal_put(&refs[ns], slot_buffer);
|
||||
|
||||
/* Transform to OFDM symbols */
|
||||
lte_ifft_run(&ifft, slot_buffer, output_buffer);
|
||||
|
||||
/* send to file or usrp */
|
||||
if (output_file_name) {
|
||||
filesink_write(&fsink, output_buffer, slot_n_samples);
|
||||
} else {
|
||||
#ifdef ENABLE_UHD
|
||||
vec_sc_prod_cfc(output_buffer, cuhd_AMP, output_buffer, slot_n_samples);
|
||||
cuhd_send(uhd, output_buffer, slot_n_samples, 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
mib.sfn=(mib.sfn+1)%1024;
|
||||
printf("SFN: %4d\r", mib.sfn);fflush(stdout);
|
||||
nf++;
|
||||
}
|
||||
|
||||
base_free();
|
||||
|
||||
printf("Done\n");
|
||||
exit(0);
|
||||
}
|
@ -0,0 +1,417 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The libLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the libLTE library.
|
||||
*
|
||||
* libLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* libLTE 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef DISABLE_UHD
|
||||
#include "cuhd.h"
|
||||
#endif
|
||||
|
||||
#include "lte.h"
|
||||
#include "plot.h"
|
||||
|
||||
#define MHZ 1000000
|
||||
#define SAMP_FREQ 1920000
|
||||
#define FLEN 9600
|
||||
#define FLEN_PERIOD 0.005
|
||||
|
||||
#define NOF_PORTS 2
|
||||
|
||||
float freq = 2680000000.0;
|
||||
float find_threshold = 40.0, track_threshold = 8.0;
|
||||
int max_track_lost = 9, nof_frames = -1;
|
||||
int track_len=300;
|
||||
char *input_file_name = NULL;
|
||||
int disable_plots = 0;
|
||||
|
||||
filesource_t fsrc;
|
||||
cf_t *input_buffer, *fft_buffer, *ce[MAX_PORTS_CTRL];
|
||||
pbch_t pbch;
|
||||
lte_fft_t fft;
|
||||
chest_t chest;
|
||||
sync_t sfind, strack;
|
||||
|
||||
plot_real_t poutfft;
|
||||
plot_complex_t pce;
|
||||
plot_scatter_t pscatrecv, pscatequal;
|
||||
|
||||
void *uhd;
|
||||
float gain = 30.0;
|
||||
|
||||
enum sync_state {FIND, TRACK};
|
||||
|
||||
void usage(char *prog) {
|
||||
printf("Usage: %s [ifgv]\n", prog);
|
||||
printf("\t-i input_file [Default use USRP]\n");
|
||||
printf("\t-n nof_frames [Default %d]\n", nof_frames);
|
||||
printf("\t-d disable plots [Default enabled]\n");
|
||||
printf("\t-f freq [Default %.1f MHz]\n", freq/MHZ);
|
||||
printf("\t-g gain [Default %.2f dB]\n", gain);
|
||||
printf("\t-v [set verbose to debug, default none]\n");
|
||||
}
|
||||
|
||||
void parse_args(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "ifdgv")) != -1) {
|
||||
switch(opt) {
|
||||
case 'i':
|
||||
input_file_name = argv[optind];
|
||||
break;
|
||||
case 'f':
|
||||
freq = atof(argv[optind]);
|
||||
break;
|
||||
case 'g':
|
||||
gain = atof(argv[optind]);
|
||||
break;
|
||||
case 'd':
|
||||
disable_plots = 1;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void init_plots() {
|
||||
plot_init();
|
||||
plot_real_init(&poutfft);
|
||||
plot_real_setTitle(&poutfft, "Output FFT - Magnitude");
|
||||
plot_real_setLabels(&poutfft, "Index", "dB");
|
||||
plot_real_setYAxisScale(&poutfft, -60, 0);
|
||||
plot_real_setXAxisScale(&poutfft, 1, 504);
|
||||
|
||||
plot_complex_init(&pce);
|
||||
plot_complex_setTitle(&pce, "Channel Estimates");
|
||||
plot_complex_setYAxisScale(&pce, Ip, -0.01, 0.01);
|
||||
plot_complex_setYAxisScale(&pce, Q, -0.01, 0.01);
|
||||
plot_complex_setYAxisScale(&pce, Magnitude, 0, 0.01);
|
||||
plot_complex_setYAxisScale(&pce, Phase, -M_PI, M_PI);
|
||||
|
||||
plot_scatter_init(&pscatrecv);
|
||||
plot_scatter_setTitle(&pscatrecv, "Received Symbols");
|
||||
plot_scatter_setXAxisScale(&pscatrecv, -0.01, 0.01);
|
||||
plot_scatter_setYAxisScale(&pscatrecv, -0.01, 0.01);
|
||||
|
||||
plot_scatter_init(&pscatequal);
|
||||
plot_scatter_setTitle(&pscatequal, "Equalized Symbols");
|
||||
plot_scatter_setXAxisScale(&pscatequal, -1, 1);
|
||||
plot_scatter_setYAxisScale(&pscatequal, -1, 1);
|
||||
|
||||
}
|
||||
|
||||
int base_init(int frame_length) {
|
||||
int i;
|
||||
|
||||
if (!disable_plots) {
|
||||
init_plots();
|
||||
}
|
||||
|
||||
if (input_file_name) {
|
||||
if (filesource_init(&fsrc, input_file_name, COMPLEX_FLOAT_BIN)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
input_buffer = (cf_t*) malloc(frame_length * sizeof(cf_t));
|
||||
if (!input_buffer) {
|
||||
perror("malloc");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fft_buffer = (cf_t*) malloc(CPNORM_NSYMB * 72 * sizeof(cf_t));
|
||||
if (!fft_buffer) {
|
||||
perror("malloc");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i=0;i<MAX_PORTS_CTRL;i++) {
|
||||
ce[i] = (cf_t*) malloc(CPNORM_NSYMB * 72 * sizeof(cf_t));
|
||||
if (!ce[i]) {
|
||||
perror("malloc");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (sync_init(&sfind, FLEN)) {
|
||||
fprintf(stderr, "Error initiating PSS/SSS\n");
|
||||
return -1;
|
||||
}
|
||||
if (sync_init(&strack, track_len)) {
|
||||
fprintf(stderr, "Error initiating PSS/SSS\n");
|
||||
return -1;
|
||||
}
|
||||
if (chest_init(&chest, LINEAR, CPNORM, 6, NOF_PORTS)) {
|
||||
fprintf(stderr, "Error initializing equalizer\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lte_fft_init(&fft, CPNORM, 6)) {
|
||||
fprintf(stderr, "Error initializing FFT\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* open UHD device */
|
||||
#ifndef DISABLE_UHD
|
||||
printf("Opening UHD device...\n");
|
||||
if (cuhd_open("addr=192.168.10.2",&uhd)) {
|
||||
fprintf(stderr, "Error opening uhd\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void base_free() {
|
||||
int i;
|
||||
|
||||
#ifndef DISABLE_UHD
|
||||
cuhd_close(&uhd);
|
||||
#endif
|
||||
|
||||
if (input_file_name) {
|
||||
filesource_free(&fsrc);
|
||||
}
|
||||
|
||||
sync_free(&sfind);
|
||||
sync_free(&strack);
|
||||
lte_fft_free(&fft);
|
||||
chest_free(&chest);
|
||||
|
||||
free(input_buffer);
|
||||
free(fft_buffer);
|
||||
for (i=0;i<MAX_PORTS_CTRL;i++) {
|
||||
free(ce[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int mib_decoder_init(int cell_id) {
|
||||
|
||||
if (chest_ref_LTEDL(&chest, cell_id)) {
|
||||
fprintf(stderr, "Error initializing reference signal\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pbch_init(&pbch, cell_id, CPNORM)) {
|
||||
fprintf(stderr, "Error initiating PBCH\n");
|
||||
return -1;
|
||||
}
|
||||
DEBUG("PBCH initiated cell_id=%d\n", cell_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mib_decoder_run(cf_t *input, pbch_mib_t *mib) {
|
||||
int i, n;
|
||||
lte_fft_run(&fft, input, fft_buffer);
|
||||
float tmp[72*7];
|
||||
|
||||
/* Get channel estimates for each port */
|
||||
for (i=0;i<NOF_PORTS;i++) {
|
||||
chest_ce_slot_port(&chest, fft_buffer, ce[i], 1, i);
|
||||
}
|
||||
|
||||
DEBUG("Decoding PBCH\n", 0);
|
||||
n = pbch_decode(&pbch, fft_buffer, ce, 6, 1, mib);
|
||||
|
||||
if (!disable_plots) {
|
||||
for (i=0;i<72*7;i++) {
|
||||
tmp[i] = 10*log10f(cabsf(fft_buffer[i]));
|
||||
}
|
||||
plot_real_setNewData(&poutfft, tmp, 72*7);
|
||||
plot_complex_setNewData(&pce, ce[0], 72*7);
|
||||
plot_scatter_setNewData(&pscatrecv, pbch.pbch_symbols[0], pbch.nof_symbols);
|
||||
if (n) {
|
||||
plot_scatter_setNewData(&pscatequal, pbch.pbch_d, pbch.nof_symbols);
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int frame_cnt;
|
||||
int cell_id;
|
||||
int find_idx, track_idx, last_found;
|
||||
enum sync_state state;
|
||||
int nslot;
|
||||
pbch_mib_t mib;
|
||||
float cfo;
|
||||
int nof_found_mib = 0;
|
||||
|
||||
parse_args(argc,argv);
|
||||
|
||||
if (base_init(FLEN)) {
|
||||
fprintf(stderr, "Error initializing memory\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
sync_pss_det_peakmean(&sfind);
|
||||
sync_pss_det_peakmean(&strack);
|
||||
|
||||
#ifndef DISABLE_UHD
|
||||
INFO("Setting sampling frequency %.2f MHz\n", (float) SAMP_FREQ/MHZ);
|
||||
cuhd_set_rx_srate(uhd, SAMP_FREQ);
|
||||
cuhd_set_rx_gain(uhd, gain);
|
||||
#endif
|
||||
|
||||
state = FIND;
|
||||
nslot = 0;
|
||||
find_idx = 0;
|
||||
cfo = 0;
|
||||
mib.sfn = -1;
|
||||
frame_cnt = 0;
|
||||
last_found = 0;
|
||||
sync_set_threshold(&sfind, find_threshold);
|
||||
sync_force_N_id_2(&sfind, -1);
|
||||
|
||||
#ifndef DISABLE_UHD
|
||||
/* set freq */
|
||||
cuhd_set_rx_freq(uhd, (double) freq);
|
||||
cuhd_rx_wait_lo_locked(uhd);
|
||||
DEBUG("Set freq to %.3f MHz\n", (double) freq);
|
||||
|
||||
DEBUG("Starting receiver...\n",0);
|
||||
cuhd_start_rx_stream(uhd);
|
||||
#endif
|
||||
|
||||
while(frame_cnt < nof_frames || nof_frames==-1) {
|
||||
INFO(" ----- RECEIVING %d SAMPLES ---- \n", FLEN);
|
||||
#ifndef DISABLE_UHD
|
||||
cuhd_recv(uhd, input_buffer, FLEN, 1);
|
||||
#else
|
||||
if (input_file_name) {
|
||||
n = filesource_read(&fsrc, input_buffer, FLEN);
|
||||
if (n == -1) {
|
||||
fprintf(stderr, "Error reading file\n");
|
||||
exit(-1);
|
||||
} else if (n < FLEN) {
|
||||
filesource_seek(&fsrc, 0);
|
||||
filesource_read(&fsrc, input_buffer, FLEN);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "UHD is DISABLED but input file name not specified\n");
|
||||
usage(argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
switch(state) {
|
||||
case FIND:
|
||||
/* find peak in all frame */
|
||||
find_idx = sync_run(&sfind, input_buffer);
|
||||
INFO("FIND %3d:\tPAR=%.2f\n", frame_cnt, sync_get_peak_to_avg(&sfind));
|
||||
if (find_idx != -1) {
|
||||
/* if found peak, go to track and set track threshold */
|
||||
frame_cnt = -1;
|
||||
last_found = 0;
|
||||
sync_set_threshold(&strack, track_threshold);
|
||||
sync_force_N_id_2(&strack, sync_get_N_id_2(&sfind));
|
||||
cell_id = sync_get_cell_id(&sfind);
|
||||
mib_decoder_init(cell_id);
|
||||
nslot = sync_get_slot_id(&sfind);
|
||||
nslot=(nslot+10)%20;
|
||||
cfo = 0;
|
||||
printf("\n");
|
||||
state = TRACK;
|
||||
}
|
||||
if (verbose == VERBOSE_NONE) {
|
||||
printf("Tracking... PAR=%.2f\r", sync_get_peak_to_avg(&sfind));
|
||||
}
|
||||
break;
|
||||
case TRACK:
|
||||
/* Find peak around known position find_idx */
|
||||
INFO("TRACK %3d: PSS find_idx %d offset %d\n", frame_cnt, find_idx, find_idx - track_len);
|
||||
track_idx = sync_run(&strack, &input_buffer[find_idx - track_len]);
|
||||
|
||||
if (track_idx != -1) {
|
||||
/* compute cumulative moving average CFO */
|
||||
cfo = (sync_get_cfo(&strack) + frame_cnt * cfo) / (frame_cnt + 1);
|
||||
last_found = frame_cnt;
|
||||
find_idx += track_idx - track_len;
|
||||
if (nslot != sync_get_slot_id(&strack)) {
|
||||
INFO("Expected slot %d but got %d\n", nslot, sync_get_slot_id(&strack));
|
||||
state = TRACK;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we missed too many PSS go back to track */
|
||||
if (frame_cnt - last_found > max_track_lost) {
|
||||
INFO("%d frames lost. Going back to TRACK\n", frame_cnt - last_found);
|
||||
}
|
||||
|
||||
// Correct CFO
|
||||
INFO("Correcting CFO=%.4f\n", cfo);
|
||||
nco_cexp_f_direct(input_buffer, (-cfo)/128, FLEN);
|
||||
|
||||
if (nslot == 0) {
|
||||
INFO("Finding MIB at idx %d\n", find_idx);
|
||||
if (mib_decoder_run(&input_buffer[find_idx], &mib)) {
|
||||
INFO("MIB detected attempt=%d\n", frame_cnt);
|
||||
last_found = frame_cnt;
|
||||
if (verbose == VERBOSE_NONE) {
|
||||
if (!nof_found_mib) {
|
||||
pbch_mib_fprint(stdout, &mib);
|
||||
}
|
||||
}
|
||||
nof_found_mib++;
|
||||
} else {
|
||||
INFO("MIB not found attempt %d\n",frame_cnt);
|
||||
}
|
||||
if (frame_cnt) {
|
||||
printf("SFN: %4d\tCFO: %+.4f KHz\tTimeOffset: %4d\tErrors: %4d/%4d\tErrorRate: %.1e\r", mib.sfn,
|
||||
cfo*15, find_idx, frame_cnt-2*(nof_found_mib-1), frame_cnt,
|
||||
(float) (frame_cnt-2*(nof_found_mib-1))/frame_cnt);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
if (input_file_name) {
|
||||
usleep(5000);
|
||||
}
|
||||
nslot = (nslot+10)%20;
|
||||
break;
|
||||
}
|
||||
frame_cnt++;
|
||||
}
|
||||
|
||||
base_free();
|
||||
|
||||
printf("\n\nDone\n");
|
||||
exit(0);
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
#
|
||||
# Copyright 2012-2013 The libLTE Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution.
|
||||
#
|
||||
# This file is part of the libLTE library.
|
||||
#
|
||||
# libLTE is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# libLTE 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 Lesser General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Lesser General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
########################################################################
|
||||
# Install headers
|
||||
########################################################################
|
||||
INSTALL(DIRECTORY include/ DESTINATION "${INCLUDE_DIR}"
|
||||
FILES_MATCHING PATTERN "*.h"
|
||||
PATTERN ".svn" EXCLUDE
|
||||
)
|
||||
|
||||
########################################################################
|
||||
# Add the subdirectories
|
||||
########################################################################
|
||||
|
||||
ADD_SUBDIRECTORY(lib)
|
||||
|
@ -0,0 +1,48 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The libLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the libLTE library.
|
||||
*
|
||||
* libLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* libLTE 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _plot_h
|
||||
#define _plot_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "plot/plot_real.h"
|
||||
#include "plot/plot_scatter.h"
|
||||
#include "plot/plot_complex.h"
|
||||
#include "plot/plot_waterfall.h"
|
||||
|
||||
int plot_init();
|
||||
void plot_exit();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,59 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The libLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the libLTE library.
|
||||
*
|
||||
* libLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* libLTE 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _plot_complex_h
|
||||
#define _plot_complex_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef enum {
|
||||
Ip, Q, Magnitude, Phase
|
||||
} plot_complex_id_t;
|
||||
|
||||
typedef void* plot_complex_t;
|
||||
|
||||
int plot_complex_init(plot_complex_t *h);
|
||||
void plot_complex_setTitle(plot_complex_t *h, char *title);
|
||||
void plot_complex_setNewData(plot_complex_t *h, _Complex float *data,
|
||||
int num_points);
|
||||
void plot_complex_setXAxisAutoScale(plot_complex_t *h, plot_complex_id_t id, bool on);
|
||||
void plot_complex_setYAxisAutoScale(plot_complex_t *h, plot_complex_id_t id, bool on);
|
||||
void plot_complex_setXAxisScale(plot_complex_t *h, plot_complex_id_t id, double xMin, double xMax);
|
||||
void plot_complex_setYAxisScale(plot_complex_t *h, plot_complex_id_t id, double yMin, double yMax);
|
||||
void plot_complex_setXAxisRange(plot_complex_t *h, double xMin, double xMax);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,55 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The libLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the libLTE library.
|
||||
*
|
||||
* libLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* libLTE 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _plot_real_h
|
||||
#define _plot_real_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef void* plot_real_t;
|
||||
|
||||
int plot_real_init(plot_real_t *h);
|
||||
void plot_real_setTitle(plot_real_t *h, char *title);
|
||||
void plot_real_setNewData(plot_real_t *h, float *data,
|
||||
int num_points);
|
||||
void plot_real_setXAxisAutoScale(plot_real_t *h, bool on);
|
||||
void plot_real_setYAxisAutoScale(plot_real_t *h, bool on);
|
||||
void plot_real_setXAxisScale(plot_real_t *h, double xMin, double xMax);
|
||||
void plot_real_setYAxisScale(plot_real_t *h, double yMin, double yMax);
|
||||
void plot_real_setXAxisRange(plot_real_t *h, double xMin, double xMax);
|
||||
void plot_real_setLabels(plot_real_t *h, char *xLabel, char *yLabel);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,54 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The libLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the libLTE library.
|
||||
*
|
||||
* libLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* libLTE 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _plot_scatter_h
|
||||
#define _plot_scatter_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef void* plot_scatter_t;
|
||||
|
||||
int plot_scatter_init(plot_scatter_t *h);
|
||||
void plot_scatter_setTitle(plot_scatter_t *h, char *title);
|
||||
void plot_scatter_setNewData(plot_scatter_t *h, _Complex float *data,
|
||||
int num_points);
|
||||
void plot_scatter_setXAxisAutoScale(plot_scatter_t *h, bool on);
|
||||
void plot_scatter_setYAxisAutoScale(plot_scatter_t *h, bool on);
|
||||
void plot_scatter_setXAxisScale(plot_scatter_t *h, double xMin, double xMax);
|
||||
void plot_scatter_setYAxisScale(plot_scatter_t *h, double yMin, double yMax);
|
||||
void plot_scatter_setAxisLabels(plot_scatter_t *h, char *xLabel, char *yLabel);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,61 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The libLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the libLTE library.
|
||||
*
|
||||
* libLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* libLTE 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _plot_waterfall_h
|
||||
#define _plot_waterfall_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef void* plot_waterfall_t;
|
||||
|
||||
int plot_waterfall_init(plot_waterfall_t *h);
|
||||
void plot_waterfall_setTitle(plot_waterfall_t *h, char *title);
|
||||
void plot_waterfall_appendNewData(plot_waterfall_t *h, float *data,
|
||||
int num_points);
|
||||
void plot_complex_setPlotXLabel(plot_waterfall_t *h, char *xLabel);
|
||||
void plot_complex_setPlotYLabel(plot_waterfall_t *h, char *yLabel);
|
||||
void plot_waterfall_setPlotXAxisRange(plot_waterfall_t *h, double xMin, double xMax);
|
||||
void plot_waterfall_setPlotXAxisScale(plot_waterfall_t *h, double xMin, double xMax);
|
||||
void plot_waterfall_setPlotYAxisScale(plot_waterfall_t *h, double yMin, double yMax);
|
||||
|
||||
void plot_waterfall_setSpectrogramXLabel(plot_waterfall_t *h, char* xLabel);
|
||||
void plot_waterfall_setSpectrogramYLabel(plot_waterfall_t *h, char* yLabel);
|
||||
void plot_waterfall_setSpectrogramXAxisRange(plot_waterfall_t *h, double xMin, double xMax);
|
||||
void plot_waterfall_setSpectrogramYAxisRange(plot_waterfall_t *h, double yMin, double yMax);
|
||||
void plot_waterfall_setSpectrogramZAxisScale(plot_waterfall_t *h, double zMin, double zMax);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,86 @@
|
||||
#
|
||||
# Copyright 2012-2013 The libLTE Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution.
|
||||
#
|
||||
# This file is part of the libLTE library.
|
||||
#
|
||||
# libLTE is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# libLTE 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 Lesser General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Lesser General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
|
||||
########################################################################
|
||||
# Setup Qt and Qwt
|
||||
########################################################################
|
||||
|
||||
FIND_PACKAGE(Qt4)
|
||||
IF(QT4_FOUND)
|
||||
INCLUDE(${QT_USE_FILE})
|
||||
ENDIF(QT4_FOUND)
|
||||
|
||||
FIND_PACKAGE(Qwt)
|
||||
IF(QT4_FOUND AND QWT_FOUND)
|
||||
INCLUDE_DIRECTORIES(${QWT_INCLUDE_DIRS})
|
||||
ENDIF(QT4_FOUND AND QWT_FOUND)
|
||||
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../)
|
||||
|
||||
########################################################################
|
||||
# Build the graphics library
|
||||
########################################################################
|
||||
|
||||
file(GLOB modules *)
|
||||
|
||||
SET(SOURCES_ALL "")
|
||||
FOREACH (_module ${modules})
|
||||
IF(IS_DIRECTORY ${_module})
|
||||
FILE(GLOB tmp "${_module}/*.cpp")
|
||||
LIST(APPEND SOURCES_ALL ${tmp})
|
||||
ENDIF(IS_DIRECTORY ${_module})
|
||||
ENDFOREACH(_module ${modules})
|
||||
|
||||
IF(QT4_FOUND AND QWT_FOUND)
|
||||
QT4_WRAP_CPP(lineplotwraps common/Lineplot.h)
|
||||
QT4_WRAP_CPP(pointplotwraps common/Pointplot.h)
|
||||
QT4_WRAP_CPP(spectrogramplotwraps common/Spectrogramplot.h)
|
||||
QT4_WRAP_CPP(complex complexplot/ComplexWidget.h complexplot/ComplexplotWrapper.h)
|
||||
QT4_WRAP_CPP(real realplot/RealWidget.h realplot/RealplotWrapper.h)
|
||||
QT4_WRAP_CPP(scatter scatterplot/ScatterWidget.h scatterplot/ScatterplotWrapper.h)
|
||||
QT4_WRAP_CPP(waterfall waterfallplot/WaterfallWidget.h waterfallplot/WaterfallplotWrapper.h)
|
||||
|
||||
INCLUDE_DIRECTORIES(common complexplot realplot scatterplot waterfallplot)
|
||||
|
||||
ADD_LIBRARY(graphics ${eventwraps} ${lineplotwraps} ${pointplotwraps} ${spectrogramplotwraps} ${complex} ${real} ${scatter} ${waterfall} ${SOURCES_ALL} )
|
||||
TARGET_LINK_LIBRARIES(graphics pthread ${QT_LIBRARIES} ${QWT_LIBRARIES})
|
||||
INSTALL(TARGETS graphics DESTINATION ${LIBRARY_DIR})
|
||||
LIBLTE_SET_PIC(graphics)
|
||||
|
||||
APPEND_INTERNAL_LIST(OPTIONAL_LIBS graphics)
|
||||
|
||||
MESSAGE(STATUS " graphics library will be installed.")
|
||||
|
||||
ELSE(QT4_FOUND AND QWT_FOUND)
|
||||
|
||||
MESSAGE(STATUS " QT4/Qwt not found. GRAPHICS library is not generated")
|
||||
|
||||
ENDIF(QT4_FOUND AND QWT_FOUND)
|
||||
|
||||
|
||||
ADD_SUBDIRECTORY(complexplot/test)
|
||||
ADD_SUBDIRECTORY(realplot/test)
|
||||
ADD_SUBDIRECTORY(scatterplot/test)
|
||||
ADD_SUBDIRECTORY(waterfallplot/test)
|
||||
|
||||
|
@ -0,0 +1,94 @@
|
||||
/**
|
||||
* \file lib/generic/graphics/qt/common/Events.cpp
|
||||
* \version 1.0
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2012-2013 The Iris Project Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution
|
||||
* and at http://www.softwareradiosystems.com/iris/copyright.html.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the Iris Project.
|
||||
*
|
||||
* Iris is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Iris 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
* \section DESCRIPTION
|
||||
*
|
||||
* Implementation of events used to pass data to Qt-based classes.
|
||||
*/
|
||||
|
||||
#include "Events.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
const QEvent::Type RealDataEvent::type = static_cast<QEvent::Type>(10000);
|
||||
|
||||
RealDataEvent::RealDataEvent(double* dataPoints, int numPoints)
|
||||
: QEvent(QEvent::Type(type))
|
||||
{
|
||||
dataPoints_ = new double[numPoints];
|
||||
numPoints_ = numPoints;
|
||||
memcpy(dataPoints_, dataPoints, numPoints*sizeof(double));
|
||||
}
|
||||
|
||||
RealDataEvent::RealDataEvent(float* dataPoints, int numPoints)
|
||||
: QEvent(QEvent::Type(type))
|
||||
{
|
||||
dataPoints_ = new double[numPoints];
|
||||
numPoints_ = numPoints;
|
||||
|
||||
for(int i=0;i<numPoints_;i++)
|
||||
{
|
||||
dataPoints_[i] = (double)(dataPoints[i]);
|
||||
}
|
||||
}
|
||||
|
||||
RealDataEvent::~RealDataEvent()
|
||||
{
|
||||
delete[] dataPoints_;
|
||||
}
|
||||
|
||||
|
||||
const QEvent::Type ComplexDataEvent::type = static_cast<QEvent::Type>(10001);
|
||||
|
||||
ComplexDataEvent::ComplexDataEvent(complex<double>* dataPoints,
|
||||
int numPoints)
|
||||
: QEvent(QEvent::Type(type))
|
||||
{
|
||||
dataPoints_ = new complex<double>[numPoints];
|
||||
numPoints_ = numPoints;
|
||||
memcpy(dataPoints_, dataPoints, numPoints*sizeof(complex<double>));
|
||||
}
|
||||
|
||||
ComplexDataEvent::ComplexDataEvent(complex<float>* dataPoints,
|
||||
int numPoints)
|
||||
: QEvent(QEvent::Type(type))
|
||||
{
|
||||
dataPoints_ = new complex<double>[numPoints];
|
||||
numPoints_ = numPoints;
|
||||
|
||||
for(int i=0;i<numPoints_;i++)
|
||||
{
|
||||
dataPoints_[i] = complex<double>(dataPoints[i].real(),
|
||||
dataPoints[i].imag());
|
||||
}
|
||||
}
|
||||
|
||||
ComplexDataEvent::~ComplexDataEvent()
|
||||
{
|
||||
delete[] dataPoints_;
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* \file lib/generic/graphics/qt/common/Events.h
|
||||
* \version 1.0
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2012-2013 The Iris Project Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution
|
||||
* and at http://www.softwareradiosystems.com/iris/copyright.html.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the Iris Project.
|
||||
*
|
||||
* Iris is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Iris 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
* \section DESCRIPTION
|
||||
*
|
||||
* Events used to pass data to Qt-based classes.
|
||||
*/
|
||||
|
||||
#ifndef EVENTS_H
|
||||
#define EVENTS_H
|
||||
|
||||
#include <QEvent>
|
||||
#include <complex>
|
||||
|
||||
class RealDataEvent
|
||||
: public QEvent
|
||||
{
|
||||
public:
|
||||
const static QEvent::Type type;
|
||||
|
||||
RealDataEvent(double* dataPoints,
|
||||
int numPoints);
|
||||
RealDataEvent(float* dataPoints,
|
||||
int numPoints);
|
||||
virtual ~RealDataEvent();
|
||||
|
||||
double* dataPoints_;
|
||||
int numPoints_;
|
||||
};
|
||||
|
||||
class ComplexDataEvent
|
||||
: public QEvent
|
||||
{
|
||||
public:
|
||||
const static QEvent::Type type;
|
||||
|
||||
ComplexDataEvent(std::complex<double>* dataPoints,
|
||||
int numPoints);
|
||||
ComplexDataEvent(std::complex<float>* dataPoints,
|
||||
int numPoints);
|
||||
virtual ~ComplexDataEvent();
|
||||
|
||||
std::complex<double>* dataPoints_;
|
||||
int numPoints_;
|
||||
};
|
||||
|
||||
#endif // EVENTS_H
|
@ -0,0 +1,164 @@
|
||||
/**
|
||||
* \file lib/generic/graphics/qt/common/Lineplot.cpp
|
||||
* \version 1.0
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2012-2013 The Iris Project Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution
|
||||
* and at http://www.softwareradiosystems.com/iris/copyright.html.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the Iris Project.
|
||||
*
|
||||
* Iris is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Iris 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
* \section DESCRIPTION
|
||||
*
|
||||
* Implementation of a simple line plotted using a QwtPlot.
|
||||
*/
|
||||
|
||||
#include "Lineplot.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
class MyZoomer: public QwtPlotZoomer
|
||||
{
|
||||
public:
|
||||
MyZoomer(QwtPlotCanvas *canvas):
|
||||
QwtPlotZoomer(canvas)
|
||||
{
|
||||
setTrackerMode(AlwaysOn);
|
||||
}
|
||||
|
||||
virtual QwtText trackerTextF(const QPointF &pos) const
|
||||
{
|
||||
QColor bg(Qt::white);
|
||||
bg.setAlpha(200);
|
||||
|
||||
QwtText text = QwtPlotZoomer::trackerTextF(pos);
|
||||
text.setBackgroundBrush( QBrush( bg ));
|
||||
return text;
|
||||
}
|
||||
};
|
||||
|
||||
Lineplot::Lineplot(QWidget *parent)
|
||||
:QwtPlot(parent)
|
||||
,xMin_(0)
|
||||
,xMax_(0)
|
||||
{
|
||||
counter_ = 0;
|
||||
numPoints_ = 1;
|
||||
indexPoints_ = new double[numPoints_];
|
||||
dataPoints_ = new double[numPoints_];
|
||||
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
QPalette palette;
|
||||
palette.setColor(canvas()->backgroundRole(), QColor("white"));
|
||||
canvas()->setPalette(palette);
|
||||
|
||||
curve_ = new QwtPlotCurve("Curve");
|
||||
curve_->setPen(QPen(Qt::blue, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||
curve_->setStyle(QwtPlotCurve::Lines);
|
||||
curve_->setRawSamples(indexPoints_, dataPoints_, numPoints_);
|
||||
curve_->setYAxis(QwtPlot::yLeft);
|
||||
curve_->attach(this);
|
||||
|
||||
memset(dataPoints_, 0x0, numPoints_*sizeof(double));
|
||||
for(int i=0;i<numPoints_;i++)
|
||||
indexPoints_[i] = i;
|
||||
|
||||
enableAxis(QwtPlot::yRight);
|
||||
QwtScaleWidget *leftAxis = axisWidget(QwtPlot::yLeft);
|
||||
connect(leftAxis, SIGNAL(scaleDivChanged()), this, SLOT(linkScales()));
|
||||
|
||||
setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine);
|
||||
setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine);
|
||||
setAxisScaleEngine(QwtPlot::yRight, new QwtLinearScaleEngine);
|
||||
|
||||
axisScaleEngine(QwtPlot::xBottom)->setAttribute(QwtScaleEngine::Floating,true);
|
||||
axisScaleEngine(QwtPlot::yLeft)->setAttribute(QwtScaleEngine::Floating,true);
|
||||
axisScaleEngine(QwtPlot::yRight)->setAttribute(QwtScaleEngine::Floating,true);
|
||||
|
||||
zoomer_ = new MyZoomer(canvas());
|
||||
zoomer_->setMousePattern(QwtEventPattern::MouseSelect1, Qt::LeftButton);
|
||||
zoomer_->setMousePattern(QwtEventPattern::MouseSelect2, Qt::LeftButton,
|
||||
Qt::ControlModifier);
|
||||
|
||||
panner_ = new QwtPlotPanner(canvas());
|
||||
panner_->setMouseButton(Qt::RightButton);
|
||||
|
||||
magnifier_ = new QwtPlotMagnifier(canvas());
|
||||
magnifier_->setMouseButton(Qt::NoButton);
|
||||
|
||||
}
|
||||
|
||||
Lineplot::~Lineplot()
|
||||
{
|
||||
delete[] indexPoints_;
|
||||
delete[] dataPoints_;
|
||||
}
|
||||
|
||||
void Lineplot::setData(double* data, int n)
|
||||
{
|
||||
if(numPoints_ != n)
|
||||
{
|
||||
numPoints_ = n;
|
||||
delete[] indexPoints_;
|
||||
delete[] dataPoints_;
|
||||
indexPoints_ = new double[numPoints_];
|
||||
dataPoints_ = new double[numPoints_];
|
||||
if(xMin_==xMax_)
|
||||
{
|
||||
for(int i=0;i<numPoints_;i++)
|
||||
indexPoints_[i] = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
double step = (xMax_-xMin_)/numPoints_;
|
||||
double val = xMin_;
|
||||
for(int i=0;i<numPoints_;i++,val+=step)
|
||||
indexPoints_[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(dataPoints_, data, numPoints_*sizeof(double));
|
||||
//Need to setRawSamples again for autoscaling to work
|
||||
curve_->setRawSamples(indexPoints_, dataPoints_, numPoints_);
|
||||
resetZoom();
|
||||
}
|
||||
|
||||
void Lineplot::setXAxisRange(double xMin, double xMax)
|
||||
{
|
||||
xMin_ = xMin;
|
||||
xMax_ = xMax;
|
||||
double step = (xMax_-xMin_)/numPoints_;
|
||||
double val = xMin_;
|
||||
for(int i=0;i<numPoints_;i++,val+=step)
|
||||
indexPoints_[i] = val;
|
||||
curve_->setRawSamples(indexPoints_, dataPoints_, numPoints_);
|
||||
}
|
||||
|
||||
void Lineplot::resetZoom()
|
||||
{
|
||||
zoomer_->setZoomBase(curve_->boundingRect());
|
||||
}
|
||||
|
||||
void Lineplot::linkScales()
|
||||
{
|
||||
setAxisScaleDiv(QwtPlot::yRight, *axisScaleDiv(QwtPlot::yLeft));
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/**
|
||||
* \file lib/generic/graphics/qt/common/Lineplot.h
|
||||
* \version 1.0
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2012-2013 The Iris Project Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution
|
||||
* and at http://www.softwareradiosystems.com/iris/copyright.html.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the Iris Project.
|
||||
*
|
||||
* Iris is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Iris 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
* \section DESCRIPTION
|
||||
*
|
||||
* A simple line plotted using a QwtPlot.
|
||||
*/
|
||||
|
||||
#ifndef LINEPLOT_H
|
||||
#define LINEPLOT_H
|
||||
|
||||
#include <qapplication.h>
|
||||
#include <qwt_plot.h>
|
||||
#include <qwt_painter.h>
|
||||
#include <qwt_plot_canvas.h>
|
||||
#include <qwt_plot_curve.h>
|
||||
#include <qwt_scale_engine.h>
|
||||
#include <qwt_scale_widget.h>
|
||||
#include <qwt_plot_zoomer.h>
|
||||
#include <qwt_plot_panner.h>
|
||||
#include <qwt_plot_magnifier.h>
|
||||
|
||||
class Lineplot
|
||||
: public QwtPlot
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Lineplot(QWidget* parent = 0);
|
||||
virtual ~Lineplot();
|
||||
|
||||
void setData(double* data, int n);
|
||||
void setXAxisRange(double xMin, double xMax);
|
||||
void resetZoom();
|
||||
|
||||
public slots:
|
||||
void linkScales();
|
||||
|
||||
private:
|
||||
QwtPlotCurve* curve_;
|
||||
|
||||
QwtPlotPanner* panner_;
|
||||
QwtPlotZoomer* zoomer_;
|
||||
QwtPlotMagnifier* magnifier_;
|
||||
|
||||
double* indexPoints_;
|
||||
double* dataPoints_;
|
||||
|
||||
int numPoints_;
|
||||
int counter_;
|
||||
double xMin_;
|
||||
double xMax_;
|
||||
};
|
||||
|
||||
#endif // LINEPLOT_H
|
@ -0,0 +1,121 @@
|
||||
/**
|
||||
* \file lib/generic/graphics/qt/common/Pointplot.h
|
||||
* \version 1.0
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2012-2013 The Iris Project Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution
|
||||
* and at http://www.softwareradiosystems.com/iris/copyright.html.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the Iris Project.
|
||||
*
|
||||
* Iris is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Iris 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
* \section DESCRIPTION
|
||||
*
|
||||
* Implementation of a plot of complex data values as points on an IQ axis.
|
||||
*/
|
||||
|
||||
#include "Pointplot.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class MyZoomer: public QwtPlotZoomer
|
||||
{
|
||||
public:
|
||||
MyZoomer(QwtPlotCanvas *canvas):
|
||||
QwtPlotZoomer(canvas)
|
||||
{
|
||||
setTrackerMode(AlwaysOn);
|
||||
}
|
||||
|
||||
virtual QwtText trackerTextF(const QPointF &pos) const
|
||||
{
|
||||
QColor bg(Qt::white);
|
||||
bg.setAlpha(200);
|
||||
|
||||
QwtText text = QwtPlotZoomer::trackerTextF(pos);
|
||||
text.setBackgroundBrush( QBrush( bg ));
|
||||
return text;
|
||||
}
|
||||
};
|
||||
|
||||
Pointplot::Pointplot(QWidget *parent)
|
||||
:QwtPlot(parent)
|
||||
{
|
||||
counter_ = 0;
|
||||
numPoints_ = 1;
|
||||
realPoints_ = new double[numPoints_];
|
||||
imagPoints_ = new double[numPoints_];
|
||||
|
||||
QPalette palette;
|
||||
palette.setColor(canvas()->backgroundRole(), QColor("white"));
|
||||
canvas()->setPalette(palette);
|
||||
|
||||
setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine);
|
||||
setAxisTitle(QwtPlot::xBottom, "In-phase");
|
||||
|
||||
setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine);
|
||||
setAxisTitle(QwtPlot::yLeft, "Quadrature");
|
||||
|
||||
curve_ = new QwtPlotCurve("Constellation Points");
|
||||
curve_->attach(this);
|
||||
curve_->setPen(QPen(Qt::blue, 5, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
|
||||
curve_->setStyle(QwtPlotCurve::Dots);
|
||||
curve_->setRawSamples(realPoints_, imagPoints_, numPoints_);
|
||||
|
||||
memset(realPoints_, 0x0, numPoints_*sizeof(double));
|
||||
memset(imagPoints_, 0x0, numPoints_*sizeof(double));
|
||||
|
||||
zoomer_ = new MyZoomer(canvas());
|
||||
zoomer_->setMousePattern(QwtEventPattern::MouseSelect1, Qt::LeftButton);
|
||||
zoomer_->setMousePattern(QwtEventPattern::MouseSelect2, Qt::LeftButton,
|
||||
Qt::ControlModifier);
|
||||
|
||||
panner_ = new QwtPlotPanner(canvas());
|
||||
panner_->setMouseButton(Qt::RightButton);
|
||||
|
||||
magnifier_ = new QwtPlotMagnifier(canvas());
|
||||
magnifier_->setMouseButton(Qt::NoButton);
|
||||
|
||||
}
|
||||
|
||||
Pointplot::~Pointplot()
|
||||
{
|
||||
delete[] realPoints_;
|
||||
delete[] imagPoints_;
|
||||
}
|
||||
|
||||
void Pointplot::setData(double* iData, double* qData, int n)
|
||||
{
|
||||
if(numPoints_ != n)
|
||||
{
|
||||
numPoints_ = n;
|
||||
delete[] realPoints_;
|
||||
delete[] imagPoints_;
|
||||
realPoints_ = new double[numPoints_];
|
||||
imagPoints_ = new double[numPoints_];
|
||||
}
|
||||
|
||||
copy(iData, iData+n, realPoints_);
|
||||
copy(qData, qData+n, imagPoints_);
|
||||
//Need to setRawSamples again for autoscaling to work
|
||||
curve_->setRawSamples(realPoints_, imagPoints_, numPoints_);
|
||||
zoomer_->setZoomBase(curve_->boundingRect());
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/**
|
||||
* \file lib/generic/graphics/qt/common/Pointplot.h
|
||||
* \version 1.0
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2012-2013 The Iris Project Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution
|
||||
* and at http://www.softwareradiosystems.com/iris/copyright.html.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the Iris Project.
|
||||
*
|
||||
* Iris is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Iris 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
* \section DESCRIPTION
|
||||
*
|
||||
* A plot of complex data values as points on an IQ axis.
|
||||
*/
|
||||
|
||||
#ifndef POINTPLOT_H
|
||||
#define POINTPLOT_H
|
||||
|
||||
#include <qapplication.h>
|
||||
#include <qwt_plot.h>
|
||||
#include <qwt_painter.h>
|
||||
#include <qwt_plot_canvas.h>
|
||||
#include <qwt_plot_curve.h>
|
||||
#include <qwt_scale_engine.h>
|
||||
#include <qwt_scale_widget.h>
|
||||
#include <qwt_plot_zoomer.h>
|
||||
#include <qwt_plot_panner.h>
|
||||
#include <qwt_plot_magnifier.h>
|
||||
#include <complex>
|
||||
|
||||
class Pointplot
|
||||
: public QwtPlot
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Pointplot(QWidget* parent = 0);
|
||||
virtual ~Pointplot();
|
||||
void setData(double* iData, double* qData, int n);
|
||||
|
||||
private:
|
||||
QwtPlotCurve* curve_;
|
||||
|
||||
QwtPlotPanner* panner_;
|
||||
QwtPlotZoomer* zoomer_;
|
||||
QwtPlotMagnifier* magnifier_;
|
||||
|
||||
struct opReal{double operator()(std::complex<double> i) const{return real(i);}};
|
||||
struct opImag{double operator()(std::complex<double> i) const{return imag(i);}};
|
||||
|
||||
double* realPoints_;
|
||||
double* imagPoints_;
|
||||
|
||||
int numPoints_;
|
||||
int counter_;
|
||||
};
|
||||
|
||||
#endif // POINTPLOT_H
|
@ -0,0 +1,198 @@
|
||||
/**
|
||||
* \file lib/generic/graphics/qt/common/Spectrogramplot.cpp
|
||||
* \version 1.0
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2012-2013 The Iris Project Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution
|
||||
* and at http://www.softwareradiosystems.com/iris/copyright.html.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the Iris Project.
|
||||
*
|
||||
* Iris is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Iris 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
* \section DESCRIPTION
|
||||
*
|
||||
* A spectrogram plot which acts as a waterfall. New data is plotted
|
||||
* at the top row of the spectrogram and all old data is shifted
|
||||
* downwards.
|
||||
*/
|
||||
|
||||
#include <qprinter.h>
|
||||
#include <qprintdialog.h>
|
||||
#include <qwt_color_map.h>
|
||||
#include <qwt_plot_spectrogram.h>
|
||||
#include <qwt_scale_widget.h>
|
||||
#include <qwt_scale_draw.h>
|
||||
#include <qwt_plot_layout.h>
|
||||
#include <qwt_plot_renderer.h>
|
||||
#include <qwt_matrix_raster_data.h>
|
||||
#include "Spectrogramplot.h"
|
||||
|
||||
class MyZoomer: public QwtPlotZoomer
|
||||
{
|
||||
public:
|
||||
MyZoomer(QwtPlotCanvas *canvas):
|
||||
QwtPlotZoomer(canvas)
|
||||
{
|
||||
setTrackerMode(AlwaysOn);
|
||||
}
|
||||
|
||||
virtual QwtText trackerTextF(const QPointF &pos) const
|
||||
{
|
||||
QColor bg(Qt::white);
|
||||
bg.setAlpha(200);
|
||||
|
||||
QwtText text = QwtPlotZoomer::trackerTextF(pos);
|
||||
text.setBackgroundBrush( QBrush( bg ));
|
||||
return text;
|
||||
}
|
||||
};
|
||||
|
||||
//Set up a colormap to use the "jet" colormap from matlab
|
||||
class ColorMap
|
||||
:public QwtLinearColorMap
|
||||
{
|
||||
public:
|
||||
ColorMap()
|
||||
:QwtLinearColorMap(QColor(0,0,189), QColor(132,0,0))
|
||||
{
|
||||
double pos;
|
||||
pos = 1.0/13.0*1.0; addColorStop(pos, QColor(0,0,255));
|
||||
pos = 1.0/13.0*2.0; addColorStop(pos, QColor(0,66,255));
|
||||
pos = 1.0/13.0*3.0; addColorStop(pos, QColor(0,132,255));
|
||||
pos = 1.0/13.0*4.0; addColorStop(pos, QColor(0,189,255));
|
||||
pos = 1.0/13.0*5.0; addColorStop(pos, QColor(0,255,255));
|
||||
pos = 1.0/13.0*6.0; addColorStop(pos, QColor(66,255,189));
|
||||
pos = 1.0/13.0*7.0; addColorStop(pos, QColor(132,255,132));
|
||||
pos = 1.0/13.0*8.0; addColorStop(pos, QColor(189,255,66));
|
||||
pos = 1.0/13.0*9.0; addColorStop(pos, QColor(255,255,0));
|
||||
pos = 1.0/13.0*10.0; addColorStop(pos, QColor(255,189,0));
|
||||
pos = 1.0/13.0*12.0; addColorStop(pos, QColor(255,66,0));
|
||||
pos = 1.0/13.0*13.0; addColorStop(pos, QColor(189,0,0));
|
||||
}
|
||||
};
|
||||
|
||||
Spectrogramplot::Spectrogramplot(int numDataPoints, int numRows, QWidget *parent)
|
||||
:QwtPlot(parent)
|
||||
,nData_(numDataPoints)
|
||||
,nRows_(numRows)
|
||||
{
|
||||
spectrogram_ = new QwtPlotSpectrogram();
|
||||
spectrogram_->setRenderThreadCount(0); // set system specific thread count
|
||||
data_ = new WaterfallData(nData_, nRows_);
|
||||
spectrogram_->attach(this);
|
||||
|
||||
setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine);
|
||||
setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine);
|
||||
|
||||
axisScaleEngine(QwtPlot::xBottom)->setAttribute(QwtScaleEngine::Floating,true);
|
||||
axisScaleEngine(QwtPlot::yLeft)->setAttribute(QwtScaleEngine::Floating,true);
|
||||
|
||||
spectrogram_->setColorMap(new ColorMap());
|
||||
spectrogram_->setData(data_);
|
||||
|
||||
setXAxisRange(0, nData_);
|
||||
setYAxisRange(0, nRows_);
|
||||
setZAxisScale(-1,1);
|
||||
|
||||
// LeftButton for the zooming
|
||||
// MidButton for the panning
|
||||
// RightButton: zoom out by 1
|
||||
// Ctrl+RighButton: zoom out to full size
|
||||
|
||||
zoomer_ = new MyZoomer(canvas());
|
||||
zoomer_->setMousePattern(QwtEventPattern::MouseSelect1,
|
||||
Qt::LeftButton);
|
||||
zoomer_->setMousePattern(QwtEventPattern::MouseSelect2,
|
||||
Qt::LeftButton, Qt::ControlModifier);
|
||||
|
||||
panner_ = new QwtPlotPanner(canvas());
|
||||
panner_->setAxisEnabled(QwtPlot::yRight, false);
|
||||
panner_->setMouseButton(Qt::RightButton);
|
||||
|
||||
magnifier_ = new QwtPlotMagnifier(canvas());
|
||||
magnifier_->setMouseButton(Qt::NoButton);
|
||||
|
||||
// Avoid jumping when labels with more/less digits
|
||||
// appear/disappear when scrolling vertically
|
||||
|
||||
const QFontMetrics fm(axisWidget(QwtPlot::yLeft)->font());
|
||||
QwtScaleDraw *sd = axisScaleDraw(QwtPlot::yLeft);
|
||||
sd->setMinimumExtent( fm.width("100.00") );
|
||||
|
||||
const QColor c(Qt::darkBlue);
|
||||
zoomer_->setRubberBandPen(c);
|
||||
zoomer_->setTrackerPen(c);
|
||||
}
|
||||
|
||||
void Spectrogramplot::appendData(double* data, int n)
|
||||
{
|
||||
data_->appendData(data, n);
|
||||
}
|
||||
|
||||
void Spectrogramplot::setXAxisRange(double xMin, double xMax)
|
||||
{
|
||||
xMin_ = xMin;
|
||||
xMax_ = xMax;
|
||||
data_->setInterval( Qt::XAxis, QwtInterval( xMin_, xMax_ ) );
|
||||
plotLayout()->setAlignCanvasToScales(true);
|
||||
replot();
|
||||
}
|
||||
|
||||
void Spectrogramplot::setYAxisRange(double yMin, double yMax)
|
||||
{
|
||||
yMin_ = yMin;
|
||||
yMax_ = yMax;
|
||||
data_->setInterval( Qt::YAxis, QwtInterval( yMin_, yMax_ ) );
|
||||
plotLayout()->setAlignCanvasToScales(true);
|
||||
replot();
|
||||
}
|
||||
|
||||
void Spectrogramplot::setZAxisScale(double zMin, double zMax)
|
||||
{
|
||||
zMin_ = zMin;
|
||||
zMax_ = zMax;
|
||||
data_->setInterval( Qt::ZAxis, QwtInterval( zMin_, zMax_ ) );
|
||||
|
||||
//Set up the intensity bar on the right
|
||||
const QwtInterval zInterval = spectrogram_->data()->interval( Qt::ZAxis );
|
||||
QwtScaleWidget *rightAxis = axisWidget(QwtPlot::yRight);
|
||||
rightAxis->setColorBarEnabled(true);
|
||||
rightAxis->setColorMap( zInterval, new ColorMap());
|
||||
setAxisScale(QwtPlot::yRight, zInterval.minValue(), zInterval.maxValue() );
|
||||
enableAxis(QwtPlot::yRight);
|
||||
|
||||
plotLayout()->setAlignCanvasToScales(true);
|
||||
replot();
|
||||
}
|
||||
|
||||
double Spectrogramplot::min()
|
||||
{
|
||||
return data_->min();
|
||||
}
|
||||
|
||||
double Spectrogramplot::max()
|
||||
{
|
||||
return data_->max();
|
||||
}
|
||||
|
||||
void Spectrogramplot::autoscale()
|
||||
{
|
||||
setZAxisScale(min(),max());
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
#ifndef WATERFALLDATA_H
|
||||
#define WATERFALLDATA_H
|
||||
|
||||
#include <qwt_raster_data.h>
|
||||
#include <boost/circular_buffer.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include "irisapi/Exceptions.h"
|
||||
|
||||
|
||||
class WaterfallData
|
||||
:public QwtRasterData
|
||||
{
|
||||
public:
|
||||
typedef std::vector<double> Vec;
|
||||
typedef boost::shared_ptr< std::vector<double> > VecPtr;
|
||||
typedef boost::circular_buffer< VecPtr > VecPtrBuf;
|
||||
typedef VecPtrBuf::iterator VecPtrBufIt;
|
||||
|
||||
WaterfallData(int numDataPoints, int numRows)
|
||||
:QwtRasterData()
|
||||
,nData_(numDataPoints)
|
||||
,nRows_(numRows)
|
||||
,data_(numRows)
|
||||
{
|
||||
for(int i=0;i<nRows_;i++)
|
||||
{
|
||||
data_.push_front(VecPtr(new std::vector<double>(nData_)));
|
||||
data_[0]->assign(nData_, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void appendData(double* data, int n)
|
||||
{
|
||||
if(n != nData_)
|
||||
throw iris::InvalidDataException("WaterfallData: invalid data length");
|
||||
|
||||
VecPtr v = data_.front();
|
||||
v->assign(data, data+n);
|
||||
data_.push_back(v);
|
||||
}
|
||||
|
||||
double max()
|
||||
{
|
||||
Vec maxVec;
|
||||
for(int i=0;i<nRows_;i++)
|
||||
{
|
||||
VecPtr v = data_[i];
|
||||
maxVec.push_back(*(std::max_element(v->begin(),v->end())));
|
||||
}
|
||||
return *(std::max_element(maxVec.begin(),maxVec.end()));
|
||||
}
|
||||
|
||||
double min()
|
||||
{
|
||||
Vec minVec;
|
||||
for(int i=0;i<nRows_;i++)
|
||||
{
|
||||
VecPtr v = data_[i];
|
||||
minVec.push_back(*(std::min_element(v->begin(),v->end())));
|
||||
}
|
||||
return *(std::min_element(minVec.begin(),minVec.end()));
|
||||
}
|
||||
|
||||
double value(double x, double y) const
|
||||
{
|
||||
double bottom = interval(Qt::YAxis).minValue();
|
||||
double top = interval(Qt::YAxis).maxValue();
|
||||
double left = interval(Qt::XAxis).minValue();
|
||||
double right = interval(Qt::XAxis).maxValue();
|
||||
double xStep = std::abs(right-left)/nData_;
|
||||
double yStep = std::abs(top-bottom)/nRows_;
|
||||
|
||||
int ix = (x-left) / xStep;
|
||||
int iy = (y-bottom) / yStep;
|
||||
if(ix >= nData_)
|
||||
ix = nData_-1;
|
||||
if(iy >= nRows_)
|
||||
iy = nRows_-1;
|
||||
double ret = (*data_[iy])[ix];
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
VecPtrBuf data_;
|
||||
int nData_;
|
||||
int nRows_;
|
||||
};
|
||||
|
||||
#endif // WATERFALLDATA_H
|
@ -0,0 +1,65 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The libLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the libLTE library.
|
||||
*
|
||||
* libLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* libLTE 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "plot.h"
|
||||
#include <stdio.h>
|
||||
#include <QApplication>
|
||||
#include <QMainWindow>
|
||||
#include <unistd.h>
|
||||
|
||||
pthread_t thread;
|
||||
static int plot_initiated=0;
|
||||
|
||||
void *qt_thread(void *arg)
|
||||
{
|
||||
int argc = 1;
|
||||
char* argv[] = { const_cast<char *>("libLTE Visualizer"), NULL };
|
||||
QApplication app(argc, argv);
|
||||
app.exec();
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
int plot_init() {
|
||||
if (!plot_initiated) {
|
||||
/** FIXME: Set attributes to detachable */
|
||||
if (pthread_create(&thread, NULL, qt_thread, NULL)) {
|
||||
perror("phtread_create");
|
||||
return -1;
|
||||
}
|
||||
usleep(100000);
|
||||
plot_initiated=1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void plot_exit() {
|
||||
if (plot_initiated) {
|
||||
pthread_cancel(thread);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,197 @@
|
||||
#include "ComplexWidget.h"
|
||||
#include "Lineplot.h"
|
||||
#include "Events.h"
|
||||
|
||||
#include <qlayout.h>
|
||||
#include <algorithm>
|
||||
#include <boost/lambda/lambda.hpp>
|
||||
|
||||
using namespace std;
|
||||
namespace bl = boost::lambda;
|
||||
|
||||
ComplexWidget::ComplexWidget(QWidget *parent)
|
||||
:QWidget(parent)
|
||||
{
|
||||
i_ = new Lineplot();
|
||||
q_ = new Lineplot();
|
||||
m_ = new Lineplot();
|
||||
p_ = new Lineplot();
|
||||
|
||||
i_->setAxisTitle(QwtPlot::xBottom, "In-phase");
|
||||
q_->setAxisTitle(QwtPlot::xBottom, "Quadrature");
|
||||
m_->setAxisTitle(QwtPlot::xBottom, "Magnitude");
|
||||
p_->setAxisTitle(QwtPlot::xBottom, "Phase");
|
||||
|
||||
QVBoxLayout* vLayout1 = new QVBoxLayout(this);
|
||||
vLayout1->addWidget(i_);
|
||||
vLayout1->addWidget(q_);
|
||||
vLayout1->addWidget(m_);
|
||||
vLayout1->addWidget(p_);
|
||||
|
||||
numPoints_ = 16;
|
||||
iData_ = new double[numPoints_];
|
||||
qData_ = new double[numPoints_];
|
||||
mData_ = new double[numPoints_];
|
||||
pData_ = new double[numPoints_];
|
||||
timerId_ = startTimer(10);
|
||||
haveNewData_ = false;
|
||||
}
|
||||
|
||||
ComplexWidget::~ComplexWidget()
|
||||
{
|
||||
delete i_;
|
||||
delete q_;
|
||||
delete m_;
|
||||
delete p_;
|
||||
}
|
||||
|
||||
void ComplexWidget::customEvent( QEvent * e )
|
||||
{
|
||||
if(e->type() == ComplexDataEvent::type)
|
||||
{
|
||||
ComplexDataEvent* dataEvent = (ComplexDataEvent*)e;
|
||||
setData(dataEvent);
|
||||
}
|
||||
}
|
||||
|
||||
void ComplexWidget::timerEvent(QTimerEvent *event)
|
||||
{
|
||||
if(event->timerId() == timerId_)
|
||||
{
|
||||
if(haveNewData_)
|
||||
{
|
||||
i_->replot();
|
||||
q_->replot();
|
||||
m_->replot();
|
||||
p_->replot();
|
||||
haveNewData_ = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
QWidget::timerEvent(event);
|
||||
}
|
||||
|
||||
void ComplexWidget::setData(ComplexDataEvent* e)
|
||||
{
|
||||
if(e->numPoints_ != numPoints_)
|
||||
{
|
||||
numPoints_ = e->numPoints_;
|
||||
delete [] iData_;
|
||||
delete [] qData_;
|
||||
delete [] mData_;
|
||||
delete [] pData_;
|
||||
|
||||
iData_ = new double[numPoints_];
|
||||
qData_ = new double[numPoints_];
|
||||
mData_ = new double[numPoints_];
|
||||
pData_ = new double[numPoints_];
|
||||
}
|
||||
|
||||
transform(e->dataPoints_, &e->dataPoints_[numPoints_], iData_, opReal());
|
||||
transform(e->dataPoints_, &e->dataPoints_[numPoints_], qData_, opImag());
|
||||
transform(e->dataPoints_, &e->dataPoints_[numPoints_], mData_, opAbs());
|
||||
transform(e->dataPoints_, &e->dataPoints_[numPoints_], pData_, opArg());
|
||||
|
||||
i_->setData(iData_, numPoints_);
|
||||
q_->setData(qData_, numPoints_);
|
||||
m_->setData(mData_, numPoints_);
|
||||
p_->setData(pData_, numPoints_);
|
||||
haveNewData_ = true;
|
||||
}
|
||||
|
||||
void ComplexWidget::setWidgetTitle(QString title)
|
||||
{
|
||||
setWindowTitle(title);
|
||||
}
|
||||
|
||||
void ComplexWidget::setWidgetXAxisScale(int id, double xMin, double xMax)
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case 0:
|
||||
i_->setAxisScale(QwtPlot::xBottom, xMin, xMax);
|
||||
break;
|
||||
case 1:
|
||||
q_->setAxisScale(QwtPlot::xBottom, xMin, xMax);
|
||||
break;
|
||||
case 2:
|
||||
m_->setAxisScale(QwtPlot::xBottom, xMin, xMax);
|
||||
break;
|
||||
case 3:
|
||||
p_->setAxisScale(QwtPlot::xBottom, xMin, xMax);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ComplexWidget::setWidgetYAxisScale(int id, double yMin, double yMax)
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case 0:
|
||||
i_->setAxisScale(QwtPlot::yLeft, yMin, yMax);
|
||||
break;
|
||||
case 1:
|
||||
q_->setAxisScale(QwtPlot::yLeft, yMin, yMax);
|
||||
break;
|
||||
case 2:
|
||||
m_->setAxisScale(QwtPlot::yLeft, yMin, yMax);
|
||||
break;
|
||||
case 3:
|
||||
p_->setAxisScale(QwtPlot::yLeft, yMin, yMax);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ComplexWidget::setWidgetXAxisAutoScale(int id, bool on=true)
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case 0:
|
||||
i_->setAxisAutoScale(QwtPlot::xBottom, on);
|
||||
break;
|
||||
case 1:
|
||||
q_->setAxisAutoScale(QwtPlot::xBottom, on);
|
||||
break;
|
||||
case 2:
|
||||
m_->setAxisAutoScale(QwtPlot::xBottom, on);
|
||||
break;
|
||||
case 3:
|
||||
p_->setAxisAutoScale(QwtPlot::xBottom, on);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ComplexWidget::setWidgetYAxisAutoScale(int id, bool on=true)
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case 0:
|
||||
i_->setAxisAutoScale(QwtPlot::yLeft, on);
|
||||
break;
|
||||
case 1:
|
||||
q_->setAxisAutoScale(QwtPlot::yLeft, on);
|
||||
break;
|
||||
case 2:
|
||||
m_->setAxisAutoScale(QwtPlot::yLeft, on);
|
||||
break;
|
||||
case 3:
|
||||
p_->setAxisAutoScale(QwtPlot::yLeft, on);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ComplexWidget::setWidgetXAxisRange(double xMin, double xMax)
|
||||
{
|
||||
i_->setXAxisRange(xMin, xMax);
|
||||
q_->setXAxisRange(xMin, xMax);
|
||||
m_->setXAxisRange(xMin, xMax);
|
||||
p_->setXAxisRange(xMin, xMax);
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
#ifndef COMPLEXWIDGET_H
|
||||
#define COMPLEXWIDGET_H
|
||||
|
||||
#include <qapplication.h>
|
||||
#include <qwidget.h>
|
||||
#include <complex>
|
||||
|
||||
class ComplexDataEvent;
|
||||
class Lineplot;
|
||||
|
||||
class ComplexWidget
|
||||
: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ComplexWidget(QWidget* parent = 0);
|
||||
virtual ~ComplexWidget();
|
||||
|
||||
public slots:
|
||||
void customEvent( QEvent * e );
|
||||
void setWidgetTitle(QString title);
|
||||
void setWidgetXAxisScale(int id, double xMin, double xMax);
|
||||
void setWidgetYAxisScale(int id, double yMin, double yMax);
|
||||
void setWidgetXAxisAutoScale(int id, bool on);
|
||||
void setWidgetYAxisAutoScale(int id, bool on);
|
||||
void setWidgetXAxisRange(double xMin, double xMax);
|
||||
|
||||
protected:
|
||||
virtual void timerEvent(QTimerEvent *event);
|
||||
|
||||
private:
|
||||
void setData(ComplexDataEvent* e);
|
||||
Lineplot* i_; //In-phase plot
|
||||
Lineplot* q_; //Quadrature plot
|
||||
Lineplot* m_; //Magnitude plot
|
||||
Lineplot* p_; //Phase plot
|
||||
|
||||
struct opReal{double operator()(std::complex<double> i) const{return real(i);}};
|
||||
struct opImag{double operator()(std::complex<double> i) const{return imag(i);}};
|
||||
struct opAbs{double operator()(std::complex<double> i) const{return abs(i);}};
|
||||
struct opArg{double operator()(std::complex<double> i) const{return arg(i);}};
|
||||
|
||||
double* iData_;
|
||||
double* qData_;
|
||||
double* mData_;
|
||||
double* pData_;
|
||||
int numPoints_;
|
||||
int timerId_;
|
||||
bool haveNewData_;
|
||||
};
|
||||
|
||||
#endif // COMPLEXWIDGET_H
|
@ -0,0 +1,55 @@
|
||||
#include "Complexplot.h"
|
||||
#include "ComplexplotWrapper.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
Complexplot::Complexplot()
|
||||
{
|
||||
plot_ = new ComplexplotWrapper;
|
||||
}
|
||||
|
||||
Complexplot::~Complexplot()
|
||||
{
|
||||
delete plot_;
|
||||
}
|
||||
|
||||
void Complexplot::setNewData(complex<double>* data, int numPoints)
|
||||
{
|
||||
plot_->setNewData(data, numPoints);
|
||||
}
|
||||
|
||||
void Complexplot::setNewData(complex<float>* data, int numPoints)
|
||||
{
|
||||
plot_->setNewData(data, numPoints);
|
||||
}
|
||||
|
||||
void Complexplot::setTitle(std::string title)
|
||||
{
|
||||
plot_->setTitle(title);
|
||||
}
|
||||
|
||||
void Complexplot::setXAxisAutoScale(PlotId id, bool on=true)
|
||||
{
|
||||
plot_->setXAxisAutoScale(id, on);
|
||||
}
|
||||
|
||||
void Complexplot::setYAxisAutoScale(PlotId id, bool on=true)
|
||||
{
|
||||
plot_->setYAxisAutoScale(id, on);
|
||||
}
|
||||
|
||||
void Complexplot::setXAxisScale(PlotId id, double xMin, double xMax)
|
||||
{
|
||||
plot_->setXAxisScale(id, xMin, xMax);
|
||||
}
|
||||
|
||||
void Complexplot::setYAxisScale(PlotId id, double yMin, double yMax)
|
||||
{
|
||||
plot_->setYAxisScale(id, yMin, yMax);
|
||||
}
|
||||
|
||||
void Complexplot::setXAxisRange(double xMin, double xMax)
|
||||
{
|
||||
plot_->setXAxisRange(xMin, xMax);
|
||||
}
|
||||
|
@ -0,0 +1,53 @@
|
||||
#ifndef COMPLEXPLOT_H
|
||||
#define COMPLEXPLOT_H
|
||||
|
||||
#include <string>
|
||||
#include <complex>
|
||||
|
||||
class ComplexplotWrapper;
|
||||
|
||||
class Complexplot
|
||||
{
|
||||
public:
|
||||
enum PlotId
|
||||
{
|
||||
I,
|
||||
Q,
|
||||
Magnitude,
|
||||
Phase
|
||||
};
|
||||
Complexplot();
|
||||
~Complexplot();
|
||||
|
||||
template<class Iterator>
|
||||
void setNewData(Iterator begin, Iterator end);
|
||||
void setNewData(std::complex<float>* data, int numPoints);
|
||||
void setNewData(std::complex<double>* data, int numPoints);
|
||||
void setTitle(std::string title);
|
||||
void setXAxisAutoScale(PlotId id, bool on);
|
||||
void setYAxisAutoScale(PlotId id, bool on);
|
||||
void setXAxisScale(PlotId id, double xMin, double xMax);
|
||||
void setYAxisScale(PlotId id, double yMin, double yMax);
|
||||
void setXAxisRange(double xMin, double xMax);
|
||||
|
||||
private:
|
||||
ComplexplotWrapper* plot_;
|
||||
};
|
||||
|
||||
template<class Iterator>
|
||||
void Complexplot::setNewData(Iterator begin, Iterator end)
|
||||
{
|
||||
int numPoints = end-begin;
|
||||
std::complex<double>* data = new std::complex<double>[numPoints];
|
||||
|
||||
for(int i=0;begin!=end;begin++,i++)
|
||||
{
|
||||
data[i] = *begin;
|
||||
}
|
||||
|
||||
setNewData(data, numPoints);
|
||||
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
#endif // COMPLEXPLOT_H
|
@ -0,0 +1,141 @@
|
||||
#include "ComplexplotWrapper.h"
|
||||
|
||||
#include "ComplexWidget.h"
|
||||
#include "Events.h"
|
||||
#include <qapplication.h>
|
||||
#include <QThread>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
ComplexplotWrapper::ComplexplotWrapper()
|
||||
:widget_(NULL)
|
||||
,destroyed_(true)
|
||||
{
|
||||
if(QCoreApplication::instance() == NULL)
|
||||
return; //TODO: throw exception here in Iris
|
||||
if(QCoreApplication::instance()->thread() == QThread::currentThread())
|
||||
{
|
||||
connect( this, SIGNAL( createWidgetSignal() ),
|
||||
this, SLOT(createWidgetSlot()) );
|
||||
connect( this, SIGNAL( destroyWidgetSignal() ),
|
||||
this, SLOT(destroyWidgetSlot()) );
|
||||
connect( this, SIGNAL( destroyWidgetSignalBlocking() ),
|
||||
this, SLOT(destroyWidgetSlot()) );
|
||||
}
|
||||
else
|
||||
{
|
||||
connect( this, SIGNAL( createWidgetSignal() ),
|
||||
this, SLOT(createWidgetSlot()),
|
||||
Qt::BlockingQueuedConnection );
|
||||
connect( this, SIGNAL( destroyWidgetSignal() ),
|
||||
this, SLOT(destroyWidgetSlot()) );
|
||||
connect( this, SIGNAL( destroyWidgetSignalBlocking() ),
|
||||
this, SLOT(destroyWidgetSlot()),
|
||||
Qt::BlockingQueuedConnection );
|
||||
moveToThread(QCoreApplication::instance()->thread());
|
||||
}
|
||||
emit createWidgetSignal();
|
||||
}
|
||||
|
||||
ComplexplotWrapper::~ComplexplotWrapper()
|
||||
{
|
||||
if(destroyed_)
|
||||
emit destroyWidgetSignal();
|
||||
else
|
||||
emit destroyWidgetSignalBlocking();
|
||||
}
|
||||
|
||||
void ComplexplotWrapper::createWidgetSlot()
|
||||
{
|
||||
widget_ = new ComplexWidget;
|
||||
destroyed_ = false;
|
||||
widget_->setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
connect(widget_, SIGNAL( destroyed() ),
|
||||
this, SLOT( widgetDestroyed() ));
|
||||
connect(this, SIGNAL(setWidgetTitle(QString)),
|
||||
widget_, SLOT(setWidgetTitle(QString)));
|
||||
connect(this, SIGNAL(setWidgetXAxisScale(int,double,double)),
|
||||
widget_, SLOT(setWidgetXAxisScale(int,double,double)));
|
||||
connect(this, SIGNAL(setWidgetYAxisScale(int,double,double)),
|
||||
widget_, SLOT(setWidgetYAxisScale(int,double,double)));
|
||||
connect(this, SIGNAL(setWidgetXAxisAutoScale(int,bool)),
|
||||
widget_, SLOT(setWidgetXAxisAutoScale(int,bool)));
|
||||
connect(this, SIGNAL(setWidgetYAxisAutoScale(int,bool)),
|
||||
widget_, SLOT(setWidgetYAxisAutoScale(int,bool)));
|
||||
connect(this, SIGNAL(setWidgetXAxisRange(double,double)),
|
||||
widget_, SLOT(setWidgetXAxisRange(double,double)));
|
||||
|
||||
widget_->resize( 800, 600 );
|
||||
widget_->show();
|
||||
}
|
||||
|
||||
void ComplexplotWrapper::destroyWidgetSlot()
|
||||
{
|
||||
if(widget_)
|
||||
delete widget_;
|
||||
widget_ = NULL;
|
||||
}
|
||||
|
||||
void ComplexplotWrapper::widgetDestroyed()
|
||||
{
|
||||
destroyed_ = true;
|
||||
}
|
||||
|
||||
void ComplexplotWrapper::setNewData(complex<double>* data, int numPoints)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
qApp->postEvent(widget_, new ComplexDataEvent(data, numPoints));
|
||||
}
|
||||
|
||||
void ComplexplotWrapper::setNewData(complex<float>* data, int numPoints)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
qApp->postEvent(widget_, new ComplexDataEvent(data, numPoints));
|
||||
}
|
||||
|
||||
void ComplexplotWrapper::setTitle(std::string title)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
QString str = QString::fromUtf8(title.c_str());
|
||||
emit setWidgetTitle(str);
|
||||
}
|
||||
|
||||
void ComplexplotWrapper::setXAxisAutoScale(int id, bool on=true)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
emit setWidgetXAxisAutoScale(id, on);
|
||||
}
|
||||
|
||||
void ComplexplotWrapper::setYAxisAutoScale(int id, bool on=true)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
emit setWidgetYAxisAutoScale(id, on);
|
||||
}
|
||||
|
||||
void ComplexplotWrapper::setXAxisScale(int id, double xMin, double xMax)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
emit setWidgetXAxisScale(id, xMin, xMax);
|
||||
}
|
||||
|
||||
void ComplexplotWrapper::setYAxisScale(int id, double yMin, double yMax)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
emit setWidgetYAxisScale(id, yMin, yMax);
|
||||
}
|
||||
|
||||
void ComplexplotWrapper::setXAxisRange(double xMin, double xMax)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
emit setWidgetXAxisRange(xMin, xMax);
|
||||
}
|
||||
|
@ -0,0 +1,48 @@
|
||||
#ifndef COMPLEXPLOTWRAPPER_H
|
||||
#define COMPLEXPLOTWRAPPER_H
|
||||
|
||||
#include <qapplication.h>
|
||||
#include <complex>
|
||||
|
||||
class ComplexWidget;
|
||||
|
||||
class ComplexplotWrapper
|
||||
: QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ComplexplotWrapper();
|
||||
~ComplexplotWrapper();
|
||||
|
||||
void setNewData(std::complex<float>* data, int numPoints);
|
||||
void setNewData(std::complex<double>* data, int numPoints);
|
||||
void setTitle(std::string title);
|
||||
void setXAxisAutoScale(int id, bool on);
|
||||
void setYAxisAutoScale(int id, bool on);
|
||||
void setXAxisScale(int id, double xMin, double xMax);
|
||||
void setYAxisScale(int id, double yMin, double yMax);
|
||||
void setXAxisRange(double xMin, double xMax);
|
||||
|
||||
public slots:
|
||||
void createWidgetSlot();
|
||||
void destroyWidgetSlot();
|
||||
void widgetDestroyed();
|
||||
|
||||
signals:
|
||||
void createWidgetSignal();
|
||||
void destroyWidgetSignal();
|
||||
void destroyWidgetSignalBlocking();
|
||||
void setWidgetTitle(QString title);
|
||||
void setWidgetXAxisAutoScale(int id, bool on);
|
||||
void setWidgetYAxisAutoScale(int id, bool on);
|
||||
void setWidgetXAxisScale(int id, double xMin, double xMax);
|
||||
void setWidgetYAxisScale(int id, double yMin, double yMax);
|
||||
void setWidgetXAxisRange(double xMin, double xMax);
|
||||
|
||||
private:
|
||||
ComplexWidget* widget_;
|
||||
bool destroyed_;
|
||||
};
|
||||
|
||||
#endif // COMPLEXPLOTWRAPPER_H
|
@ -0,0 +1,76 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The libLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the libLTE library.
|
||||
*
|
||||
* libLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* libLTE 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include "plot/plot_complex.h"
|
||||
#include "Complexplot.h"
|
||||
#include <complex.h>
|
||||
|
||||
|
||||
int plot_complex_init(plot_complex_t *h) {
|
||||
*h = (void*) new Complexplot();
|
||||
return (*h != NULL)?0:-1;
|
||||
}
|
||||
|
||||
void plot_complex_setTitle(plot_complex_t *h, char *title) {
|
||||
Complexplot *plot = static_cast<Complexplot*>(*h);
|
||||
plot->setTitle(title);
|
||||
}
|
||||
|
||||
void plot_complex_setNewData(plot_complex_t *h, _Complex float *data,
|
||||
int num_points) {
|
||||
Complexplot *plot = static_cast<Complexplot*>(*h);
|
||||
plot->setNewData(reinterpret_cast<std::complex<float>*> (data), num_points);
|
||||
}
|
||||
|
||||
|
||||
void plot_complex_setXAxisAutoScale(plot_complex_t *h, plot_complex_id_t id, bool on) {
|
||||
Complexplot *plot = static_cast<Complexplot*>(*h);
|
||||
plot->setXAxisAutoScale(static_cast<Complexplot::PlotId> (id), on);
|
||||
}
|
||||
|
||||
void plot_complex_setYAxisAutoScale(plot_complex_t *h, plot_complex_id_t id, bool on) {
|
||||
Complexplot *plot = static_cast<Complexplot*>(*h);
|
||||
plot->setYAxisAutoScale(static_cast<Complexplot::PlotId> (id), on);
|
||||
}
|
||||
|
||||
void plot_complex_setXAxisScale(plot_complex_t *h, plot_complex_id_t id, double xMin, double xMax) {
|
||||
Complexplot *plot = static_cast<Complexplot*>(*h);
|
||||
plot->setXAxisScale(static_cast<Complexplot::PlotId> (id), xMin, xMax);
|
||||
}
|
||||
|
||||
void plot_complex_setYAxisScale(plot_complex_t *h, plot_complex_id_t id, double yMin, double yMax) {
|
||||
Complexplot *plot = static_cast<Complexplot*>(*h);
|
||||
plot->setYAxisScale(static_cast<Complexplot::PlotId> (id), yMin, yMax);
|
||||
}
|
||||
|
||||
void plot_complex_setXAxisRange(plot_complex_t *h, double xMin, double xMax) {
|
||||
Complexplot *plot = static_cast<Complexplot*>(*h);
|
||||
plot->setXAxisRange(xMin, xMax);
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
#
|
||||
# Copyright 2012-2013 The Iris Project Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution
|
||||
# and at http://www.softwareradiosystems.com/iris/copyright.html.
|
||||
#
|
||||
# This file is part of the Iris Project.
|
||||
#
|
||||
# Iris is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# Iris 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 Lesser General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Lesser General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
########################################################################
|
||||
# Build tests
|
||||
########################################################################
|
||||
#turn the test cpp file into an executable with an int main() function
|
||||
ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK -DBOOST_TEST_MAIN)
|
||||
INCLUDE_DIRECTORIES(..)
|
||||
ADD_EXECUTABLE(complexplot_test complexplot_test.cpp)
|
||||
TARGET_LINK_LIBRARIES(complexplot_test ${Boost_LIBRARIES} graphics)
|
||||
ADD_TEST(complexplot_test complexplot_test)
|
||||
|
@ -0,0 +1,146 @@
|
||||
/**
|
||||
* \file lib/generic/modulation/Crc_test.cpp
|
||||
* \version 1.0
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2012-2013 The Iris Project Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution
|
||||
* and at http://www.softwareradiosystems.com/iris/copyright.html.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the Iris Project.
|
||||
*
|
||||
* Iris is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Iris 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
* \section DESCRIPTION
|
||||
*
|
||||
* Main test file for Complexplot class.
|
||||
*/
|
||||
|
||||
#define BOOST_TEST_MODULE Complexplot_Test
|
||||
|
||||
#include "Complexplot.h"
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/progress.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <qapplication.h>
|
||||
#include <cstdlib>
|
||||
#include <complex>
|
||||
#include <vector>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#define PI 3.14159265358979323846
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef vector< complex<float> > FloatVec;
|
||||
|
||||
void threadMain1()
|
||||
{
|
||||
Complexplot plot;
|
||||
plot.setTitle("Float");
|
||||
plot.setXAxisRange(0,2);
|
||||
plot.setYAxisScale(Complexplot::Magnitude, 0.9, 1.1);
|
||||
|
||||
int n=1024;
|
||||
float step = 2.0*PI/n;
|
||||
complex<float>* data = new complex<float>[n];
|
||||
for(int i=0;i<n;i++)
|
||||
data[i] = polar(1.0f,step*i);
|
||||
|
||||
plot.setNewData(data, n);
|
||||
|
||||
for(int i=0;i<n;i++)
|
||||
{
|
||||
rotate(data, data+1, data+n);
|
||||
plot.setNewData(data, n);
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
|
||||
}
|
||||
}
|
||||
|
||||
void threadMain2()
|
||||
{
|
||||
Complexplot plot;
|
||||
plot.setTitle("Double");
|
||||
plot.setXAxisRange(0,2);
|
||||
plot.setYAxisScale(Complexplot::Magnitude, 0.9, 1.1);
|
||||
|
||||
int n=1024;
|
||||
double step = 2.0*PI/n;
|
||||
complex<double>* data = new complex<double>[n];
|
||||
for(int i=0;i<n;i++)
|
||||
data[i] = polar(1.0,step*i);
|
||||
|
||||
plot.setNewData(data, n);
|
||||
|
||||
for(int i=0;i<n;i++)
|
||||
{
|
||||
rotate(data, data+1, data+n);
|
||||
plot.setNewData(data, n);
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
|
||||
}
|
||||
}
|
||||
|
||||
void threadMain3()
|
||||
{
|
||||
|
||||
Complexplot plot;
|
||||
plot.setTitle("FloatVec");
|
||||
plot.setXAxisRange(0,2);
|
||||
plot.setYAxisScale(Complexplot::Magnitude, 0.9, 1.1);
|
||||
|
||||
FloatVec data(1024);
|
||||
int n=data.size();
|
||||
float step = 2.0*PI/n;
|
||||
for(int i=0;i<n;i++)
|
||||
data[i] = polar(1.0f,step*i);
|
||||
|
||||
plot.setNewData(data.begin(), data.end());
|
||||
|
||||
for(int i=0;i<n;i++)
|
||||
{
|
||||
rotate(data.begin(), data.begin()+1, data.end());
|
||||
plot.setNewData(data.begin(), data.end());
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE (Complexplot_Test)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Complexplot_Basic_Test)
|
||||
{
|
||||
int argc = 1;
|
||||
char* argv[] = { const_cast<char *>("Compleplot_Basic_Test"), NULL };
|
||||
QApplication a(argc, argv);
|
||||
|
||||
boost::scoped_ptr< boost::thread > thread1_;
|
||||
boost::scoped_ptr< boost::thread > thread2_;
|
||||
boost::scoped_ptr< boost::thread > thread3_;
|
||||
|
||||
thread1_.reset( new boost::thread( &threadMain1 ) );
|
||||
thread2_.reset( new boost::thread( &threadMain2 ) );
|
||||
thread3_.reset( new boost::thread( &threadMain3 ) );
|
||||
|
||||
qApp->exec();
|
||||
thread1_->join();
|
||||
thread2_->join();
|
||||
thread3_->join();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
@ -0,0 +1,102 @@
|
||||
#include "RealWidget.h"
|
||||
#include "Lineplot.h"
|
||||
#include "Events.h"
|
||||
|
||||
#include <qlayout.h>
|
||||
#include <algorithm>
|
||||
#include <boost/lambda/lambda.hpp>
|
||||
|
||||
using namespace std;
|
||||
namespace bl = boost::lambda;
|
||||
|
||||
RealWidget::RealWidget(QWidget *parent)
|
||||
:QWidget(parent)
|
||||
{
|
||||
l_ = new Lineplot();
|
||||
QVBoxLayout* vLayout1 = new QVBoxLayout(this);
|
||||
vLayout1->addWidget(l_);
|
||||
|
||||
numPoints_ = 16;
|
||||
dataPoints_ = new double[numPoints_];
|
||||
timerId_ = startTimer(10);
|
||||
haveNewData_ = false;
|
||||
}
|
||||
|
||||
RealWidget::~RealWidget()
|
||||
{
|
||||
delete l_;
|
||||
}
|
||||
|
||||
void RealWidget::customEvent( QEvent * e )
|
||||
{
|
||||
if(e->type() == RealDataEvent::type)
|
||||
{
|
||||
RealDataEvent* dataEvent = (RealDataEvent*)e;
|
||||
setData(dataEvent);
|
||||
}
|
||||
}
|
||||
|
||||
void RealWidget::timerEvent(QTimerEvent *event)
|
||||
{
|
||||
if(event->timerId() == timerId_)
|
||||
{
|
||||
if(haveNewData_)
|
||||
{
|
||||
l_->replot();
|
||||
haveNewData_ = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
QWidget::timerEvent(event);
|
||||
}
|
||||
|
||||
void RealWidget::setData(RealDataEvent* e)
|
||||
{
|
||||
if(e->numPoints_ != numPoints_)
|
||||
{
|
||||
numPoints_ = e->numPoints_;
|
||||
delete [] dataPoints_;
|
||||
dataPoints_ = new double[numPoints_];
|
||||
}
|
||||
for(int i=0;i<numPoints_;i++)
|
||||
dataPoints_[i] = e->dataPoints_[i];
|
||||
|
||||
l_->setData(dataPoints_, numPoints_);
|
||||
haveNewData_ = true;
|
||||
}
|
||||
|
||||
void RealWidget::setWidgetTitle(QString title)
|
||||
{
|
||||
l_->setTitle(title);
|
||||
}
|
||||
|
||||
void RealWidget::setWidgetAxisLabels(QString xLabel, QString yLabel)
|
||||
{
|
||||
l_->setAxisTitle(QwtPlot::xBottom, xLabel);
|
||||
l_->setAxisTitle(QwtPlot::yLeft, yLabel);
|
||||
}
|
||||
|
||||
void RealWidget::setWidgetXAxisScale(double xMin, double xMax)
|
||||
{
|
||||
l_->setAxisScale(QwtPlot::xBottom, xMin, xMax);
|
||||
}
|
||||
|
||||
void RealWidget::setWidgetYAxisScale(double yMin, double yMax)
|
||||
{
|
||||
l_->setAxisScale(QwtPlot::yLeft, yMin, yMax);
|
||||
}
|
||||
|
||||
void RealWidget::setWidgetXAxisAutoScale(bool on=true)
|
||||
{
|
||||
l_->setAxisAutoScale(QwtPlot::xBottom, on);
|
||||
}
|
||||
|
||||
void RealWidget::setWidgetYAxisAutoScale(bool on=true)
|
||||
{
|
||||
l_->setAxisAutoScale(QwtPlot::yLeft, on);
|
||||
}
|
||||
|
||||
void RealWidget::setWidgetXAxisRange(double xMin, double xMax)
|
||||
{
|
||||
l_->setXAxisRange(xMin, xMax);
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
#ifndef REALWIDGET_H
|
||||
#define REALWIDGET_H
|
||||
|
||||
#include <qapplication.h>
|
||||
#include <qwidget.h>
|
||||
#include <complex>
|
||||
|
||||
class RealDataEvent;
|
||||
class Lineplot;
|
||||
|
||||
class RealWidget
|
||||
: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RealWidget(QWidget* parent = 0);
|
||||
virtual ~RealWidget();
|
||||
|
||||
public slots:
|
||||
void customEvent( QEvent * e );
|
||||
void setWidgetTitle(QString title);
|
||||
void setWidgetAxisLabels(QString xLabel, QString yLabel);
|
||||
void setWidgetXAxisScale(double xMin, double xMax);
|
||||
void setWidgetYAxisScale(double yMin, double yMax);
|
||||
void setWidgetXAxisAutoScale(bool on);
|
||||
void setWidgetYAxisAutoScale(bool on);
|
||||
void setWidgetXAxisRange(double xMin, double xMax);
|
||||
|
||||
protected:
|
||||
virtual void timerEvent(QTimerEvent *event);
|
||||
|
||||
private:
|
||||
void setData(RealDataEvent* e);
|
||||
Lineplot* l_; //The line plot
|
||||
|
||||
double* dataPoints_;
|
||||
int numPoints_;
|
||||
int timerId_;
|
||||
bool haveNewData_;
|
||||
};
|
||||
|
||||
#endif // REALWIDGET_H
|
@ -0,0 +1,58 @@
|
||||
#include "Realplot.h"
|
||||
#include "RealplotWrapper.h"
|
||||
|
||||
Realplot::Realplot()
|
||||
{
|
||||
plot_ = new RealplotWrapper;
|
||||
}
|
||||
|
||||
Realplot::~Realplot()
|
||||
{
|
||||
delete plot_;
|
||||
}
|
||||
|
||||
void Realplot::setNewData(double* data, int numPoints)
|
||||
{
|
||||
plot_->setNewData(data, numPoints);
|
||||
}
|
||||
|
||||
void Realplot::setNewData(float* data, int numPoints)
|
||||
{
|
||||
plot_->setNewData(data, numPoints);
|
||||
}
|
||||
|
||||
void Realplot::setTitle(std::string title)
|
||||
{
|
||||
plot_->setTitle(title);
|
||||
}
|
||||
|
||||
void Realplot::setXAxisScale(double xMin, double xMax)
|
||||
{
|
||||
plot_->setXAxisScale(xMin, xMax);
|
||||
}
|
||||
|
||||
void Realplot::setYAxisScale(double yMin, double yMax)
|
||||
{
|
||||
plot_->setYAxisScale(yMin, yMax);
|
||||
}
|
||||
|
||||
void Realplot::setXAxisAutoScale(bool on=true)
|
||||
{
|
||||
plot_->setXAxisAutoScale(on);
|
||||
}
|
||||
|
||||
void Realplot::setYAxisAutoScale(bool on=true)
|
||||
{
|
||||
plot_->setYAxisAutoScale(on);
|
||||
}
|
||||
|
||||
void Realplot::setXAxisRange(double xMin, double xMax)
|
||||
{
|
||||
plot_->setXAxisRange(xMin, xMax);
|
||||
}
|
||||
|
||||
void Realplot::setLabels(std::string xLabel, std::string yLabel)
|
||||
{
|
||||
plot_->setAxisLabels(xLabel, yLabel);
|
||||
}
|
||||
|
@ -0,0 +1,46 @@
|
||||
#ifndef REALPLOT_H
|
||||
#define REALPLOT_H
|
||||
|
||||
#include <string>
|
||||
|
||||
class RealplotWrapper;
|
||||
|
||||
class Realplot
|
||||
{
|
||||
public:
|
||||
Realplot();
|
||||
~Realplot();
|
||||
|
||||
template<class Iterator>
|
||||
void setNewData(Iterator begin, Iterator end);
|
||||
void setNewData(float* data, int numPoints);
|
||||
void setNewData(double* data, int numPoints);
|
||||
void setTitle(std::string title);
|
||||
void setXAxisScale(double xMin, double xMax);
|
||||
void setYAxisScale(double yMin, double yMax);
|
||||
void setXAxisAutoScale(bool on);
|
||||
void setYAxisAutoScale(bool on);
|
||||
void setXAxisRange(double xMin, double xMax);
|
||||
void setLabels(std::string xLabel, std::string yLabel);
|
||||
|
||||
private:
|
||||
RealplotWrapper* plot_;
|
||||
};
|
||||
|
||||
template<class Iterator>
|
||||
void Realplot::setNewData(Iterator begin, Iterator end)
|
||||
{
|
||||
int numPoints = end-begin;
|
||||
double* data = new double[numPoints];
|
||||
|
||||
for(int i=0;begin!=end;begin++,i++)
|
||||
{
|
||||
data[i] = *begin;
|
||||
}
|
||||
|
||||
setNewData(data, numPoints);
|
||||
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
#endif // REALPLOT_H
|
@ -0,0 +1,147 @@
|
||||
#include "RealplotWrapper.h"
|
||||
|
||||
#include "RealWidget.h"
|
||||
#include "Events.h"
|
||||
#include <qapplication.h>
|
||||
#include <QThread>
|
||||
|
||||
|
||||
RealplotWrapper::RealplotWrapper()
|
||||
:widget_(NULL)
|
||||
,destroyed_(true)
|
||||
{
|
||||
if(QCoreApplication::instance() == NULL)
|
||||
return; //TODO: throw exception here in Iris
|
||||
if(QCoreApplication::instance()->thread() == QThread::currentThread())
|
||||
{
|
||||
connect( this, SIGNAL( createWidgetSignal() ),
|
||||
this, SLOT(createWidgetSlot()) );
|
||||
connect( this, SIGNAL( destroyWidgetSignal() ),
|
||||
this, SLOT(destroyWidgetSlot()) );
|
||||
connect( this, SIGNAL( destroyWidgetSignalBlocking() ),
|
||||
this, SLOT(destroyWidgetSlot()) );
|
||||
}
|
||||
else
|
||||
{
|
||||
connect( this, SIGNAL( createWidgetSignal() ),
|
||||
this, SLOT(createWidgetSlot()),
|
||||
Qt::BlockingQueuedConnection );
|
||||
connect( this, SIGNAL( destroyWidgetSignal() ),
|
||||
this, SLOT(destroyWidgetSlot()) );
|
||||
connect( this, SIGNAL( destroyWidgetSignalBlocking() ),
|
||||
this, SLOT(destroyWidgetSlot()),
|
||||
Qt::BlockingQueuedConnection );
|
||||
moveToThread(QCoreApplication::instance()->thread());
|
||||
}
|
||||
emit createWidgetSignal();
|
||||
}
|
||||
|
||||
RealplotWrapper::~RealplotWrapper()
|
||||
{
|
||||
if(destroyed_)
|
||||
emit destroyWidgetSignal();
|
||||
else
|
||||
emit destroyWidgetSignalBlocking();
|
||||
}
|
||||
|
||||
void RealplotWrapper::createWidgetSlot()
|
||||
{
|
||||
widget_ = new RealWidget;
|
||||
destroyed_ = false;
|
||||
widget_->setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
connect(widget_, SIGNAL( destroyed() ),
|
||||
this, SLOT( widgetDestroyed() ));
|
||||
connect(this, SIGNAL(setWidgetTitle(QString)),
|
||||
widget_, SLOT(setWidgetTitle(QString)));
|
||||
connect(this, SIGNAL(setWidgetAxisLabels(QString, QString)),
|
||||
widget_, SLOT(setWidgetAxisLabels(QString, QString)));
|
||||
connect(this, SIGNAL(setWidgetXAxisScale(double,double)),
|
||||
widget_, SLOT(setWidgetXAxisScale(double,double)));
|
||||
connect(this, SIGNAL(setWidgetYAxisScale(double,double)),
|
||||
widget_, SLOT(setWidgetYAxisScale(double,double)));
|
||||
connect(this, SIGNAL(setWidgetXAxisAutoScale(bool)),
|
||||
widget_, SLOT(setWidgetXAxisAutoScale(bool)));
|
||||
connect(this, SIGNAL(setWidgetYAxisAutoScale(bool)),
|
||||
widget_, SLOT(setWidgetYAxisAutoScale(bool)));
|
||||
connect(this, SIGNAL(setWidgetXAxisRange(double,double)),
|
||||
widget_, SLOT(setWidgetXAxisRange(double,double)));
|
||||
|
||||
widget_->resize( 800, 600 );
|
||||
widget_->show();
|
||||
}
|
||||
|
||||
void RealplotWrapper::destroyWidgetSlot()
|
||||
{
|
||||
delete widget_;
|
||||
}
|
||||
|
||||
void RealplotWrapper::widgetDestroyed()
|
||||
{
|
||||
destroyed_ = true;
|
||||
}
|
||||
|
||||
void RealplotWrapper::setNewData(double* data, int numPoints)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
qApp->postEvent(widget_, new RealDataEvent(data, numPoints));
|
||||
}
|
||||
|
||||
void RealplotWrapper::setNewData(float* data, int numPoints)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
qApp->postEvent(widget_, new RealDataEvent(data, numPoints));
|
||||
}
|
||||
|
||||
void RealplotWrapper::setTitle(std::string title)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
QString str = QString::fromUtf8(title.c_str());
|
||||
emit setWidgetTitle(str);
|
||||
}
|
||||
|
||||
void RealplotWrapper::setAxisLabels(std::string xLabel, std::string yLabel)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
QString xStr = QString::fromUtf8(xLabel.c_str());
|
||||
QString yStr = QString::fromUtf8(yLabel.c_str());
|
||||
emit setWidgetAxisLabels(xStr, yStr);
|
||||
}
|
||||
|
||||
void RealplotWrapper::setXAxisScale(double xMin, double xMax)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
emit setWidgetXAxisScale(xMin, xMax);
|
||||
}
|
||||
|
||||
void RealplotWrapper::setYAxisScale(double yMin, double yMax)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
emit setWidgetYAxisScale(yMin, yMax);
|
||||
}
|
||||
|
||||
void RealplotWrapper::setXAxisAutoScale(bool on=true)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
emit setWidgetXAxisAutoScale(on);
|
||||
}
|
||||
|
||||
void RealplotWrapper::setYAxisAutoScale(bool on=true)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
emit setWidgetYAxisAutoScale(on);
|
||||
}
|
||||
|
||||
void RealplotWrapper::setXAxisRange(double xMin, double xMax)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
emit setWidgetXAxisRange(xMin, xMax);
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
#ifndef REALPLOTWRAPPER_H
|
||||
#define REALPLOTWRAPPER_H
|
||||
|
||||
#include <qapplication.h>
|
||||
|
||||
class RealWidget;
|
||||
|
||||
class RealplotWrapper
|
||||
: QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RealplotWrapper();
|
||||
~RealplotWrapper();
|
||||
|
||||
void setNewData(float* data, int numPoints);
|
||||
void setNewData(double* data, int numPoints);
|
||||
void setTitle(std::string title);
|
||||
void setAxisLabels(std::string xLabel, std::string yLabel);
|
||||
void setXAxisScale(double xMin, double xMax);
|
||||
void setYAxisScale(double yMin, double yMax);
|
||||
void setXAxisAutoScale(bool on);
|
||||
void setYAxisAutoScale(bool on);
|
||||
void setXAxisRange(double xMin, double xMax);
|
||||
|
||||
public slots:
|
||||
void createWidgetSlot();
|
||||
void destroyWidgetSlot();
|
||||
void widgetDestroyed();
|
||||
|
||||
signals:
|
||||
void createWidgetSignal();
|
||||
void destroyWidgetSignal();
|
||||
void destroyWidgetSignalBlocking();
|
||||
void setWidgetTitle(QString title);
|
||||
void setWidgetAxisLabels(QString xLabel, QString yLabel);
|
||||
void setWidgetXAxisScale(double xMin, double xMax);
|
||||
void setWidgetYAxisScale(double yMin, double yMax);
|
||||
void setWidgetXAxisAutoScale(bool on);
|
||||
void setWidgetYAxisAutoScale(bool on);
|
||||
void setWidgetXAxisRange(double xMin, double xMax);
|
||||
|
||||
private:
|
||||
RealWidget* widget_;
|
||||
bool destroyed_;
|
||||
};
|
||||
|
||||
#endif // REALPLOTWRAPPER_H
|
@ -0,0 +1,79 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The libLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the libLTE library.
|
||||
*
|
||||
* libLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* libLTE 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "plot/plot_real.h"
|
||||
#include "Realplot.h"
|
||||
#include <complex.h>
|
||||
|
||||
|
||||
int plot_real_init(plot_real_t *h) {
|
||||
*h = (void*) new Realplot();
|
||||
return (*h != NULL)?0:-1;
|
||||
}
|
||||
|
||||
void plot_real_setTitle(plot_real_t *h, char *title) {
|
||||
Realplot *plot = static_cast<Realplot*>(*h);
|
||||
plot->setTitle(title);
|
||||
}
|
||||
void plot_real_setNewData(plot_real_t *h, float *data,
|
||||
int num_points) {
|
||||
Realplot *plot = static_cast<Realplot*>(*h);
|
||||
plot->setNewData(data, num_points);
|
||||
|
||||
}
|
||||
|
||||
void plot_real_setXAxisAutoScale(plot_real_t *h, bool on) {
|
||||
Realplot *plot = static_cast<Realplot*>(*h);
|
||||
plot->setXAxisAutoScale(on);
|
||||
}
|
||||
|
||||
void plot_real_setYAxisAutoScale(plot_real_t *h, bool on) {
|
||||
Realplot *plot = static_cast<Realplot*>(*h);
|
||||
plot->setYAxisAutoScale(on);
|
||||
}
|
||||
|
||||
void plot_real_setXAxisScale(plot_real_t *h, double xMin, double xMax) {
|
||||
Realplot *plot = static_cast<Realplot*>(*h);
|
||||
plot->setXAxisScale(xMin, xMax);
|
||||
}
|
||||
|
||||
void plot_real_setYAxisScale(plot_real_t *h, double yMin, double yMax) {
|
||||
Realplot *plot = static_cast<Realplot*>(*h);
|
||||
plot->setYAxisScale(yMin, yMax);
|
||||
}
|
||||
|
||||
void plot_real_setXAxisRange(plot_real_t *h, double xMin, double xMax) {
|
||||
Realplot *plot = static_cast<Realplot*>(*h);
|
||||
plot->setXAxisRange(xMin, xMax);
|
||||
}
|
||||
|
||||
void plot_real_setLabels(plot_real_t *h, char *xLabel, char *yLabel) {
|
||||
Realplot *plot = static_cast<Realplot*>(*h);
|
||||
plot->setLabels(xLabel, yLabel);
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
#
|
||||
# Copyright 2012-2013 The Iris Project Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution
|
||||
# and at http://www.softwareradiosystems.com/iris/copyright.html.
|
||||
#
|
||||
# This file is part of the Iris Project.
|
||||
#
|
||||
# Iris is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# Iris 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 Lesser General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Lesser General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
########################################################################
|
||||
# Build tests
|
||||
########################################################################
|
||||
#turn the test cpp file into an executable with an int main() function
|
||||
ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK -DBOOST_TEST_MAIN)
|
||||
INCLUDE_DIRECTORIES(..)
|
||||
ADD_EXECUTABLE(realplot_test realplot_test.cpp)
|
||||
TARGET_LINK_LIBRARIES(realplot_test ${Boost_LIBRARIES} graphics)
|
||||
ADD_TEST(realplot_test realplot_test)
|
||||
|
@ -0,0 +1,130 @@
|
||||
/**
|
||||
* \file lib/generic/modulation/Crc_test.cpp
|
||||
* \version 1.0
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2012-2013 The Iris Project Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution
|
||||
* and at http://www.softwareradiosystems.com/iris/copyright.html.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the Iris Project.
|
||||
*
|
||||
* Iris is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Iris 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
* \section DESCRIPTION
|
||||
*
|
||||
* Main test file for Realplot class.
|
||||
*/
|
||||
|
||||
#define BOOST_TEST_MODULE Realplot_Test
|
||||
|
||||
#include "Realplot.h"
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/progress.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <qapplication.h>
|
||||
#include <cstdlib>
|
||||
#include <complex>
|
||||
#include <vector>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
typedef std::vector<float> FloatVec;
|
||||
|
||||
template<class T>
|
||||
void getPoints(T* data, int numPoints)
|
||||
{
|
||||
for(int i=0;i<numPoints;i++)
|
||||
{
|
||||
data[i] = 10*((T)rand()/RAND_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
template<class Iterator>
|
||||
void getPoints(Iterator begin, Iterator end)
|
||||
{
|
||||
for(;begin!=end;begin++)
|
||||
{
|
||||
*begin = 10*((double)rand()/RAND_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
void threadMain1()
|
||||
{
|
||||
Realplot plot;
|
||||
|
||||
float data[1024];
|
||||
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
getPoints(data, 504);
|
||||
plot.setNewData(data, 504);
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(5));
|
||||
}
|
||||
}
|
||||
|
||||
void threadMain2()
|
||||
{
|
||||
Realplot plot;
|
||||
double data[1024];
|
||||
|
||||
for(int i=0;i<10000;i++)
|
||||
{
|
||||
getPoints(data, 504);
|
||||
plot.setNewData(data, 504);
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(5));
|
||||
}
|
||||
}
|
||||
|
||||
void threadMain3()
|
||||
{
|
||||
Realplot plot;
|
||||
FloatVec v(1024);
|
||||
|
||||
for(int i=0;i<10000;i++)
|
||||
{
|
||||
getPoints(v.begin(), v.end());
|
||||
plot.setNewData(v.begin(), v.end());
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(10));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE (Realplot_Test)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Realplot_Basic_Test)
|
||||
{
|
||||
int argc = 1;
|
||||
char* argv[] = { const_cast<char *>("Realplot_Basic_Test"), NULL };
|
||||
QApplication a(argc, argv);
|
||||
|
||||
boost::scoped_ptr< boost::thread > thread1_;
|
||||
boost::scoped_ptr< boost::thread > thread2_;
|
||||
boost::scoped_ptr< boost::thread > thread3_;
|
||||
|
||||
thread1_.reset( new boost::thread( &threadMain1 ) );
|
||||
thread2_.reset( new boost::thread( &threadMain2 ) );
|
||||
thread3_.reset( new boost::thread( &threadMain3 ) );
|
||||
|
||||
qApp->exec();
|
||||
thread1_->join();
|
||||
thread2_->join();
|
||||
thread3_->join();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
@ -0,0 +1,101 @@
|
||||
#include "ScatterWidget.h"
|
||||
#include "Pointplot.h"
|
||||
#include "Events.h"
|
||||
|
||||
#include <qlayout.h>
|
||||
#include <algorithm>
|
||||
#include <boost/lambda/lambda.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
ScatterWidget::ScatterWidget(QWidget *parent)
|
||||
:QWidget(parent)
|
||||
{
|
||||
plot_ = new Pointplot();
|
||||
QVBoxLayout* vLayout1 = new QVBoxLayout(this);
|
||||
vLayout1->addWidget(plot_);
|
||||
|
||||
numPoints_ = 16;
|
||||
iData_ = new double[numPoints_];
|
||||
qData_ = new double[numPoints_];
|
||||
timerId_ = startTimer(10);
|
||||
haveNewData_ = false;
|
||||
}
|
||||
|
||||
ScatterWidget::~ScatterWidget()
|
||||
{
|
||||
delete iData_;
|
||||
delete qData_;
|
||||
}
|
||||
|
||||
void ScatterWidget::customEvent( QEvent * e )
|
||||
{
|
||||
if(e->type() == ComplexDataEvent::type)
|
||||
{
|
||||
ComplexDataEvent* dataEvent = (ComplexDataEvent*)e;
|
||||
setData(dataEvent);
|
||||
}
|
||||
}
|
||||
|
||||
void ScatterWidget::timerEvent(QTimerEvent *event)
|
||||
{
|
||||
if(event->timerId() == timerId_)
|
||||
{
|
||||
if(haveNewData_)
|
||||
{
|
||||
plot_->replot();
|
||||
haveNewData_ = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
QWidget::timerEvent(event);
|
||||
}
|
||||
|
||||
void ScatterWidget::setData(ComplexDataEvent* e)
|
||||
{
|
||||
if(e->numPoints_ != numPoints_)
|
||||
{
|
||||
numPoints_ = e->numPoints_;
|
||||
delete [] iData_;
|
||||
delete [] qData_;
|
||||
iData_ = new double[numPoints_];
|
||||
qData_ = new double[numPoints_];
|
||||
}
|
||||
|
||||
transform(e->dataPoints_, &e->dataPoints_[numPoints_], iData_, opReal());
|
||||
transform(e->dataPoints_, &e->dataPoints_[numPoints_], qData_, opImag());
|
||||
|
||||
plot_->setData(iData_, qData_, numPoints_);
|
||||
haveNewData_ = true;
|
||||
}
|
||||
|
||||
void ScatterWidget::setWidgetTitle(QString title)
|
||||
{
|
||||
plot_->setTitle(title);
|
||||
}
|
||||
|
||||
void ScatterWidget::setWidgetAxisLabels(QString xLabel, QString yLabel)
|
||||
{
|
||||
plot_->setAxisTitle(QwtPlot::xBottom, xLabel);
|
||||
plot_->setAxisTitle(QwtPlot::yLeft, yLabel);
|
||||
}
|
||||
|
||||
void ScatterWidget::setWidgetXAxisScale(double xMin, double xMax)
|
||||
{
|
||||
plot_->setAxisScale(QwtPlot::xBottom, xMin, xMax);
|
||||
}
|
||||
|
||||
void ScatterWidget::setWidgetYAxisScale(double yMin, double yMax)
|
||||
{
|
||||
plot_->setAxisScale(QwtPlot::yLeft, yMin, yMax);
|
||||
}
|
||||
|
||||
void ScatterWidget::setWidgetXAxisAutoScale(bool on=true)
|
||||
{
|
||||
plot_->setAxisAutoScale(QwtPlot::xBottom, on);
|
||||
}
|
||||
|
||||
void ScatterWidget::setWidgetYAxisAutoScale(bool on)
|
||||
{
|
||||
plot_->setAxisAutoScale(QwtPlot::yLeft, on);
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
#ifndef SCATTERWIDGET_H
|
||||
#define SCATTERWIDGET_H
|
||||
|
||||
#include <qapplication.h>
|
||||
#include <qwidget.h>
|
||||
#include <complex>
|
||||
|
||||
class ComplexDataEvent;
|
||||
class Pointplot;
|
||||
|
||||
class ScatterWidget
|
||||
: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ScatterWidget(QWidget* parent = 0);
|
||||
virtual ~ScatterWidget();
|
||||
|
||||
public slots:
|
||||
void customEvent( QEvent * e );
|
||||
void setWidgetTitle(QString title);
|
||||
void setWidgetAxisLabels(QString xLabel, QString yLabel);
|
||||
void setWidgetXAxisScale(double xMin, double xMax);
|
||||
void setWidgetYAxisScale(double yMin, double yMax);
|
||||
void setWidgetXAxisAutoScale(bool on);
|
||||
void setWidgetYAxisAutoScale(bool on);
|
||||
|
||||
protected:
|
||||
virtual void timerEvent(QTimerEvent *event);
|
||||
|
||||
private:
|
||||
void setData(ComplexDataEvent* e);
|
||||
Pointplot* plot_;
|
||||
|
||||
struct opReal{double operator()(std::complex<double> i) const{return real(i);}};
|
||||
struct opImag{double operator()(std::complex<double> i) const{return imag(i);}};
|
||||
|
||||
double* iData_;
|
||||
double* qData_;
|
||||
int numPoints_;
|
||||
int timerId_;
|
||||
bool haveNewData_;
|
||||
};
|
||||
|
||||
#endif // SCATTERWIDGET_H
|
@ -0,0 +1,53 @@
|
||||
#include "Scatterplot.h"
|
||||
#include "ScatterplotWrapper.h"
|
||||
|
||||
Scatterplot::Scatterplot()
|
||||
{
|
||||
plot_ = new ScatterplotWrapper;
|
||||
}
|
||||
|
||||
Scatterplot::~Scatterplot()
|
||||
{
|
||||
delete plot_;
|
||||
}
|
||||
|
||||
void Scatterplot::setNewData(std::complex<float>* data, int numPoints)
|
||||
{
|
||||
plot_->setNewData(data, numPoints);
|
||||
}
|
||||
|
||||
void Scatterplot::setNewData(std::complex<double>* data, int numPoints)
|
||||
{
|
||||
plot_->setNewData(data, numPoints);
|
||||
}
|
||||
|
||||
void Scatterplot::setTitle(std::string title)
|
||||
{
|
||||
plot_->setTitle(title);
|
||||
}
|
||||
|
||||
void Scatterplot::setXAxisScale(double xMin, double xMax)
|
||||
{
|
||||
plot_->setXAxisScale(xMin, xMax);
|
||||
}
|
||||
|
||||
void Scatterplot::setYAxisScale(double yMin, double yMax)
|
||||
{
|
||||
plot_->setYAxisScale(yMin, yMax);
|
||||
}
|
||||
|
||||
void Scatterplot::setXAxisAutoScale(bool on=true)
|
||||
{
|
||||
plot_->setXAxisAutoScale(on);
|
||||
}
|
||||
|
||||
void Scatterplot::setYAxisAutoScale(bool on=true)
|
||||
{
|
||||
plot_->setYAxisAutoScale(on);
|
||||
}
|
||||
|
||||
void Scatterplot::setAxisLabels(std::string xLabel, std::string yLabel)
|
||||
{
|
||||
plot_->setAxisLabels(xLabel, yLabel);
|
||||
}
|
||||
|
@ -0,0 +1,46 @@
|
||||
#ifndef SCATTERPLOT_H
|
||||
#define SCATTERPLOT_H
|
||||
|
||||
#include <string>
|
||||
#include <complex>
|
||||
|
||||
class ScatterplotWrapper;
|
||||
|
||||
class Scatterplot
|
||||
{
|
||||
public:
|
||||
Scatterplot();
|
||||
~Scatterplot();
|
||||
|
||||
template<class Iterator>
|
||||
void setNewData(Iterator begin, Iterator end);
|
||||
void setNewData(std::complex<float>* data, int numPoints);
|
||||
void setNewData(std::complex<double>* data, int numPoints);
|
||||
void setTitle(std::string title);
|
||||
void setXAxisScale(double xMin, double xMax);
|
||||
void setYAxisScale(double yMin, double yMax);
|
||||
void setXAxisAutoScale(bool on);
|
||||
void setYAxisAutoScale(bool on);
|
||||
void setAxisLabels(std::string xLabel, std::string yLabel);
|
||||
|
||||
private:
|
||||
ScatterplotWrapper* plot_;
|
||||
};
|
||||
|
||||
template<class Iterator>
|
||||
void Scatterplot::setNewData(Iterator begin, Iterator end)
|
||||
{
|
||||
int numPoints = end-begin;
|
||||
std::complex<double>* data = new std::complex<double>[numPoints];
|
||||
|
||||
for(int i=0;begin!=end;begin++,i++)
|
||||
{
|
||||
data[i] = *begin;
|
||||
}
|
||||
|
||||
setNewData(data, numPoints);
|
||||
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
#endif // SCATTERPLOT_H
|
@ -0,0 +1,142 @@
|
||||
#include "ScatterplotWrapper.h"
|
||||
|
||||
#include "ScatterWidget.h"
|
||||
#include "Events.h"
|
||||
#include <qapplication.h>
|
||||
#include <QThread>
|
||||
#include <complex>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
ScatterplotWrapper::ScatterplotWrapper()
|
||||
:widget_(NULL)
|
||||
,destroyed_(true)
|
||||
{
|
||||
if(QCoreApplication::instance() == NULL)
|
||||
return; //TODO: throw exception here in Iris
|
||||
if(QCoreApplication::instance()->thread() == QThread::currentThread())
|
||||
{
|
||||
connect( this, SIGNAL(createWidgetSignal()),
|
||||
this, SLOT(createWidgetSlot()) );
|
||||
connect( this, SIGNAL(destroyWidgetSignal()),
|
||||
this, SLOT(destroyWidgetSlot()) );
|
||||
connect( this, SIGNAL( destroyWidgetSignalBlocking() ),
|
||||
this, SLOT(destroyWidgetSlot()) );
|
||||
}
|
||||
else
|
||||
{
|
||||
connect( this, SIGNAL(createWidgetSignal()),
|
||||
this, SLOT(createWidgetSlot()),
|
||||
Qt::BlockingQueuedConnection );
|
||||
connect( this, SIGNAL(destroyWidgetSignal()),
|
||||
this, SLOT(destroyWidgetSlot()) );
|
||||
connect( this, SIGNAL( destroyWidgetSignalBlocking() ),
|
||||
this, SLOT(destroyWidgetSlot()),
|
||||
Qt::BlockingQueuedConnection );
|
||||
moveToThread(QCoreApplication::instance()->thread());
|
||||
}
|
||||
emit createWidgetSignal();
|
||||
}
|
||||
|
||||
ScatterplotWrapper::~ScatterplotWrapper()
|
||||
{
|
||||
if(destroyed_)
|
||||
emit destroyWidgetSignal();
|
||||
else
|
||||
emit destroyWidgetSignalBlocking();
|
||||
}
|
||||
|
||||
void ScatterplotWrapper::createWidgetSlot()
|
||||
{
|
||||
widget_ = new ScatterWidget;
|
||||
destroyed_ = false;
|
||||
widget_->setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
connect(widget_, SIGNAL( destroyed() ),
|
||||
this, SLOT( widgetDestroyed() ));
|
||||
connect(this, SIGNAL(setWidgetXAxisScale(double,double)),
|
||||
widget_, SLOT(setWidgetXAxisScale(double,double)));
|
||||
connect(this, SIGNAL(setWidgetYAxisScale(double,double)),
|
||||
widget_, SLOT(setWidgetYAxisScale(double,double)));
|
||||
connect(this, SIGNAL(setWidgetXAxisAutoScale(bool)),
|
||||
widget_, SLOT(setWidgetXAxisAutoScale(bool)));
|
||||
connect(this, SIGNAL(setWidgetYAxisAutoScale(bool)),
|
||||
widget_, SLOT(setWidgetYAxisAutoScale(bool)));
|
||||
connect(this, SIGNAL(setWidgetTitle(QString)),
|
||||
widget_, SLOT(setWidgetTitle(QString)));
|
||||
connect(this, SIGNAL(setWidgetAxisLabels(QString, QString)),
|
||||
widget_, SLOT(setWidgetAxisLabels(QString, QString)));
|
||||
|
||||
widget_->resize( 800, 600 );
|
||||
widget_->show();
|
||||
}
|
||||
|
||||
void ScatterplotWrapper::destroyWidgetSlot()
|
||||
{
|
||||
delete widget_;
|
||||
}
|
||||
|
||||
void ScatterplotWrapper::widgetDestroyed()
|
||||
{
|
||||
destroyed_ = true;
|
||||
}
|
||||
|
||||
void ScatterplotWrapper::setNewData(complex<double>* data, int numPoints)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
qApp->postEvent(widget_, new ComplexDataEvent(data, numPoints));
|
||||
}
|
||||
|
||||
void ScatterplotWrapper::setNewData(complex<float>* data, int numPoints)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
qApp->postEvent(widget_, new ComplexDataEvent(data, numPoints));
|
||||
}
|
||||
|
||||
void ScatterplotWrapper::setTitle(std::string title)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
QString str = QString::fromUtf8(title.c_str());
|
||||
emit setWidgetTitle(str);
|
||||
}
|
||||
|
||||
void ScatterplotWrapper::setXAxisScale(double xMin, double xMax)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
emit setWidgetXAxisScale(xMin, xMax);
|
||||
}
|
||||
|
||||
void ScatterplotWrapper::setYAxisScale(double yMin, double yMax)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
emit setWidgetYAxisScale(yMin, yMax);
|
||||
}
|
||||
|
||||
void ScatterplotWrapper::setXAxisAutoScale(bool on=true)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
emit setWidgetXAxisAutoScale(on);
|
||||
}
|
||||
|
||||
void ScatterplotWrapper::setYAxisAutoScale(bool on=true)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
emit setWidgetYAxisAutoScale(on);
|
||||
}
|
||||
|
||||
void ScatterplotWrapper::setAxisLabels(std::string xLabel, std::string yLabel)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
QString xStr = QString::fromUtf8(xLabel.c_str());
|
||||
QString yStr = QString::fromUtf8(yLabel.c_str());
|
||||
emit setWidgetAxisLabels(xStr, yStr);
|
||||
}
|
||||
|
@ -0,0 +1,48 @@
|
||||
#ifndef SCATTERPLOTWRAPPER_H
|
||||
#define SCATTERPLOTWRAPPER_H
|
||||
|
||||
#include <qapplication.h>
|
||||
#include <complex>
|
||||
|
||||
class ScatterWidget;
|
||||
|
||||
class ScatterplotWrapper
|
||||
: QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ScatterplotWrapper();
|
||||
~ScatterplotWrapper();
|
||||
|
||||
void setNewData(std::complex<float>* data, int numPoints);
|
||||
void setNewData(std::complex<double>* data, int numPoints);
|
||||
void setTitle(std::string title);
|
||||
void setXAxisScale(double xMin, double xMax);
|
||||
void setYAxisScale(double yMin, double yMax);
|
||||
void setXAxisAutoScale(bool on);
|
||||
void setYAxisAutoScale(bool on);
|
||||
void setAxisLabels(std::string xLabel, std::string yLabel);
|
||||
|
||||
public slots:
|
||||
void createWidgetSlot();
|
||||
void destroyWidgetSlot();
|
||||
void widgetDestroyed();
|
||||
|
||||
signals:
|
||||
void createWidgetSignal();
|
||||
void destroyWidgetSignal();
|
||||
void destroyWidgetSignalBlocking();
|
||||
void setWidgetTitle(QString title);
|
||||
void setWidgetAxisLabels(QString xLabel, QString yLabel);
|
||||
void setWidgetXAxisScale(double xMin, double xMax);
|
||||
void setWidgetYAxisScale(double yMin, double yMax);
|
||||
void setWidgetXAxisAutoScale(bool on);
|
||||
void setWidgetYAxisAutoScale(bool on);
|
||||
|
||||
private:
|
||||
ScatterWidget* widget_;
|
||||
bool destroyed_;
|
||||
};
|
||||
|
||||
#endif // SCATTERPLOTWRAPPER_H
|
@ -0,0 +1,75 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The libLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the libLTE library.
|
||||
*
|
||||
* libLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* libLTE 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "plot/plot_scatter.h"
|
||||
#include "Scatterplot.h"
|
||||
#include <complex.h>
|
||||
|
||||
|
||||
|
||||
int plot_scatter_init(plot_scatter_t *h) {
|
||||
*h = (void*) new Scatterplot();
|
||||
return (*h != NULL)?0:-1;
|
||||
}
|
||||
|
||||
void plot_scatter_setTitle(plot_scatter_t *h, char *title) {
|
||||
Scatterplot *plot = static_cast<Scatterplot*>(*h);
|
||||
plot->setTitle(title);
|
||||
}
|
||||
void plot_scatter_setNewData(plot_scatter_t *h, _Complex float *data,
|
||||
int num_points) {
|
||||
Scatterplot *plot = static_cast<Scatterplot*>(*h);
|
||||
plot->setNewData(reinterpret_cast<std::complex<float>*> (data), num_points);
|
||||
|
||||
}
|
||||
|
||||
void plot_scatter_setXAxisAutoScale(plot_scatter_t *h, bool on) {
|
||||
Scatterplot *plot = static_cast<Scatterplot*>(*h);
|
||||
plot->setXAxisAutoScale(on);
|
||||
}
|
||||
|
||||
void plot_scatter_setYAxisAutoScale(plot_scatter_t *h, bool on) {
|
||||
Scatterplot *plot = static_cast<Scatterplot*>(*h);
|
||||
plot->setYAxisAutoScale(on);
|
||||
}
|
||||
|
||||
void plot_scatter_setXAxisScale(plot_scatter_t *h, double xMin, double xMax) {
|
||||
Scatterplot *plot = static_cast<Scatterplot*>(*h);
|
||||
plot->setXAxisScale(xMin, xMax);
|
||||
}
|
||||
|
||||
void plot_scatter_setYAxisScale(plot_scatter_t *h, double yMin, double yMax) {
|
||||
Scatterplot *plot = static_cast<Scatterplot*>(*h);
|
||||
plot->setYAxisScale(yMin, yMax);
|
||||
}
|
||||
|
||||
void plot_scatter_setAxisLabels(plot_scatter_t *h, char *xLabel, char *yLabel) {
|
||||
Scatterplot *plot = static_cast<Scatterplot*>(*h);
|
||||
plot->setAxisLabels(xLabel, yLabel);
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
#
|
||||
# Copyright 2012-2013 The Iris Project Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution
|
||||
# and at http://www.softwareradiosystems.com/iris/copyright.html.
|
||||
#
|
||||
# This file is part of the Iris Project.
|
||||
#
|
||||
# Iris is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# Iris 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 Lesser General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Lesser General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
########################################################################
|
||||
# Build tests
|
||||
########################################################################
|
||||
#turn the test cpp file into an executable with an int main() function
|
||||
ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK -DBOOST_TEST_MAIN)
|
||||
INCLUDE_DIRECTORIES(..)
|
||||
ADD_EXECUTABLE(scatterplot_test scatterplot_test.cpp)
|
||||
TARGET_LINK_LIBRARIES(scatterplot_test ${Boost_LIBRARIES} graphics)
|
||||
ADD_TEST(scatterplot_test scatterplot_test)
|
||||
|
@ -0,0 +1,133 @@
|
||||
/**
|
||||
* \file lib/generic/modulation/Crc_test.cpp
|
||||
* \version 1.0
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2012-2013 The Iris Project Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution
|
||||
* and at http://www.softwareradiosystems.com/iris/copyright.html.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the Iris Project.
|
||||
*
|
||||
* Iris is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Iris 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
* \section DESCRIPTION
|
||||
*
|
||||
* Main test file for scatterplot class.
|
||||
*/
|
||||
|
||||
#define BOOST_TEST_MODULE Scatterplot_Test
|
||||
|
||||
#include "Scatterplot.h"
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/progress.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <qapplication.h>
|
||||
#include <cstdlib>
|
||||
#include <complex>
|
||||
#include <vector>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
typedef std::complex<float> Cplx;
|
||||
typedef std::vector<Cplx> CplxVec;
|
||||
|
||||
template<class T>
|
||||
void getPoints(std::complex<T>* data, int numPoints)
|
||||
{
|
||||
for(int i=0;i<numPoints;i++)
|
||||
{
|
||||
data[i] = std::complex<T>(2*((T)rand()/RAND_MAX)-1,
|
||||
2*((T)rand()/RAND_MAX)-1);
|
||||
}
|
||||
}
|
||||
|
||||
template<class Iterator>
|
||||
void getPoints(Iterator begin, Iterator end)
|
||||
{
|
||||
for(;begin!=end;begin++)
|
||||
{
|
||||
float r = 2*((double)rand()/RAND_MAX)-1;
|
||||
float i = 2*((double)rand()/RAND_MAX)-1;
|
||||
*begin = Cplx(r,i);
|
||||
}
|
||||
}
|
||||
|
||||
void threadMain1()
|
||||
{
|
||||
Scatterplot plot;
|
||||
std::complex<float> data[1024];
|
||||
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
getPoints(data, 1024);
|
||||
plot.setNewData(data, 1024);
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
|
||||
}
|
||||
}
|
||||
|
||||
void threadMain2()
|
||||
{
|
||||
Scatterplot plot;
|
||||
std::complex<double> data[1024];
|
||||
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
getPoints(data, 1024);
|
||||
plot.setNewData(data, 1024);
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
|
||||
}
|
||||
}
|
||||
|
||||
void threadMain3()
|
||||
{
|
||||
Scatterplot plot;
|
||||
CplxVec v(1024);
|
||||
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
getPoints(v.begin(), v.end());
|
||||
plot.setNewData(v.begin(), v.end());
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE (Scatterplot_Test)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Scatterplot_Basic_Test)
|
||||
{
|
||||
int argc = 1;
|
||||
char* argv[] = { const_cast<char *>("Scatterplot_Basic_Test"), NULL };
|
||||
QApplication a(argc, argv);
|
||||
|
||||
boost::scoped_ptr< boost::thread > thread1_;
|
||||
boost::scoped_ptr< boost::thread > thread2_;
|
||||
boost::scoped_ptr< boost::thread > thread3_;
|
||||
|
||||
thread1_.reset( new boost::thread( &threadMain1 ) );
|
||||
thread2_.reset( new boost::thread( &threadMain2 ) );
|
||||
thread3_.reset( new boost::thread( &threadMain3 ) );
|
||||
|
||||
qApp->exec();
|
||||
thread1_->join();
|
||||
thread2_->join();
|
||||
thread3_->join();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
@ -0,0 +1,143 @@
|
||||
#include "WaterfallWidget.h"
|
||||
#include "Spectrogramplot.h"
|
||||
#include "Lineplot.h"
|
||||
#include "Events.h"
|
||||
|
||||
#include <qlayout.h>
|
||||
#include <qpushbutton.h>
|
||||
#include <algorithm>
|
||||
#include <boost/lambda/lambda.hpp>
|
||||
|
||||
using namespace std;
|
||||
namespace bl = boost::lambda;
|
||||
|
||||
|
||||
WaterfallWidget::WaterfallWidget(int numDataPoints, int numRows, QWidget *parent)
|
||||
:QWidget(parent)
|
||||
{
|
||||
p_ = new Lineplot();
|
||||
s_ = new Spectrogramplot(numDataPoints, numRows);
|
||||
b_ = new QPushButton("Autoscale");
|
||||
|
||||
connect(b_, SIGNAL(clicked()), this, SLOT(autoscale()));
|
||||
|
||||
QVBoxLayout* vLayout1 = new QVBoxLayout(this);
|
||||
vLayout1->addWidget(p_);vLayout1->setStretch(0,1);
|
||||
vLayout1->addWidget(s_);vLayout1->setStretch(1,3);
|
||||
vLayout1->addWidget(b_);
|
||||
|
||||
numPoints_ = numDataPoints;
|
||||
data_ = new double[numPoints_];
|
||||
timerId_ = startTimer(10);
|
||||
haveNewData_ = false;
|
||||
}
|
||||
|
||||
WaterfallWidget::~WaterfallWidget()
|
||||
{
|
||||
delete p_;
|
||||
delete s_;
|
||||
}
|
||||
|
||||
void WaterfallWidget::customEvent( QEvent * e )
|
||||
{
|
||||
if(e->type() == RealDataEvent::type)
|
||||
{
|
||||
RealDataEvent* dataEvent = (RealDataEvent*)e;
|
||||
appendData(dataEvent);
|
||||
}
|
||||
}
|
||||
|
||||
void WaterfallWidget::setWidgetTitle(QString title)
|
||||
{
|
||||
setWindowTitle(title);
|
||||
}
|
||||
|
||||
void WaterfallWidget::setPlotXLabel(QString xLabel)
|
||||
{
|
||||
p_->setAxisTitle(QwtPlot::xBottom, xLabel);
|
||||
}
|
||||
|
||||
void WaterfallWidget::setPlotYLabel(QString yLabel)
|
||||
{
|
||||
p_->setAxisTitle(QwtPlot::yLeft, yLabel);
|
||||
}
|
||||
|
||||
void WaterfallWidget::setPlotXAxisRange(double xMin, double xMax)
|
||||
{
|
||||
p_->setXAxisRange(xMin, xMax);
|
||||
}
|
||||
|
||||
void WaterfallWidget::setPlotXAxisScale(double xMin, double xMax)
|
||||
{
|
||||
p_->setAxisScale(QwtPlot::xBottom, xMin, xMax);
|
||||
}
|
||||
|
||||
void WaterfallWidget::setPlotYAxisScale(double yMin, double yMax)
|
||||
{
|
||||
p_->setAxisScale(QwtPlot::yLeft, yMin, yMax);
|
||||
}
|
||||
|
||||
void WaterfallWidget::setSpectrogramXLabel(QString xLabel)
|
||||
{
|
||||
s_->setAxisTitle(QwtPlot::xBottom, xLabel);
|
||||
}
|
||||
|
||||
void WaterfallWidget::setSpectrogramYLabel(QString yLabel)
|
||||
{
|
||||
s_->setAxisTitle(QwtPlot::yLeft, yLabel);
|
||||
}
|
||||
|
||||
void WaterfallWidget::setSpectrogramXAxisRange(double xMin, double xMax)
|
||||
{
|
||||
s_->setXAxisRange(xMin, xMax);
|
||||
}
|
||||
|
||||
void WaterfallWidget::setSpectrogramYAxisRange(double yMin, double yMax)
|
||||
{
|
||||
s_->setYAxisRange(yMin, yMax);
|
||||
}
|
||||
|
||||
void WaterfallWidget::setSpectrogramZAxisScale(double zMin, double zMax)
|
||||
{
|
||||
s_->setZAxisScale(zMin, zMax);
|
||||
}
|
||||
|
||||
void WaterfallWidget::autoscale()
|
||||
{
|
||||
double min = s_->min();
|
||||
double max = s_->max();
|
||||
s_->setZAxisScale(min, max);
|
||||
p_->setAxisAutoScale(QwtPlot::yLeft, false);
|
||||
p_->setAxisScale(QwtPlot::yLeft, min, max);
|
||||
}
|
||||
|
||||
void WaterfallWidget::timerEvent(QTimerEvent *event)
|
||||
{
|
||||
if(event->timerId() == timerId_)
|
||||
{
|
||||
if(haveNewData_)
|
||||
{
|
||||
p_->replot();
|
||||
s_->replot();
|
||||
haveNewData_ = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
QWidget::timerEvent(event);
|
||||
}
|
||||
|
||||
void WaterfallWidget::appendData(RealDataEvent* e)
|
||||
{
|
||||
if(e->numPoints_ != numPoints_)
|
||||
{
|
||||
numPoints_ = e->numPoints_;
|
||||
delete [] data_;
|
||||
data_ = new double[numPoints_];
|
||||
}
|
||||
|
||||
memcpy(data_, e->dataPoints_, numPoints_*sizeof(double));
|
||||
|
||||
p_->setData(data_, numPoints_);
|
||||
s_->appendData(data_, numPoints_);
|
||||
haveNewData_ = true;
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
#include "Waterfallplot.h"
|
||||
#include "WaterfallplotWrapper.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
Waterfallplot::Waterfallplot(int numDataPoints, int numRows)
|
||||
{
|
||||
plot_ = new WaterfallplotWrapper(numDataPoints, numRows);
|
||||
}
|
||||
|
||||
Waterfallplot::~Waterfallplot()
|
||||
{
|
||||
delete plot_;
|
||||
}
|
||||
|
||||
void Waterfallplot::appendNewData(float* data, int numPoints)
|
||||
{
|
||||
plot_->appendNewData(data, numPoints);
|
||||
}
|
||||
|
||||
void Waterfallplot::appendNewData(double* data, int numPoints)
|
||||
{
|
||||
plot_->appendNewData(data, numPoints);
|
||||
}
|
||||
|
||||
void Waterfallplot::setTitle(std::string title)
|
||||
{
|
||||
plot_->setTitle(title);
|
||||
}
|
||||
|
||||
void Waterfallplot::setPlotXLabel(std::string xLabel)
|
||||
{
|
||||
plot_->setPlotXLabel(xLabel);
|
||||
}
|
||||
|
||||
void Waterfallplot::setPlotYLabel(std::string yLabel)
|
||||
{
|
||||
plot_->setPlotYLabel(yLabel);
|
||||
}
|
||||
|
||||
void Waterfallplot::setPlotXAxisRange(double xMin, double xMax)
|
||||
{
|
||||
plot_->setPlotXAxisRange(xMin, xMax);
|
||||
}
|
||||
|
||||
void Waterfallplot::setPlotXAxisScale(double xMin, double xMax)
|
||||
{
|
||||
plot_->setPlotXAxisScale(xMin, xMax);
|
||||
}
|
||||
|
||||
void Waterfallplot::setPlotYAxisScale(double yMin, double yMax)
|
||||
{
|
||||
plot_->setPlotYAxisScale(yMin, yMax);
|
||||
}
|
||||
|
||||
void Waterfallplot::setSpectrogramXLabel(std::string xLabel)
|
||||
{
|
||||
plot_->setSpectrogramXLabel(xLabel);
|
||||
}
|
||||
|
||||
void Waterfallplot::setSpectrogramYLabel(std::string yLabel)
|
||||
{
|
||||
plot_->setSpectrogramYLabel(yLabel);
|
||||
}
|
||||
|
||||
void Waterfallplot::setSpectrogramXAxisRange(double xMin, double xMax)
|
||||
{
|
||||
plot_->setSpectrogramXAxisRange(xMin, xMax);
|
||||
}
|
||||
|
||||
void Waterfallplot::setSpectrogramYAxisRange(double yMin, double yMax)
|
||||
{
|
||||
plot_->setSpectrogramYAxisRange(yMin, yMax);
|
||||
}
|
||||
|
||||
void Waterfallplot::setSpectrogramZAxisScale(double zMin, double zMax)
|
||||
{
|
||||
plot_->setSpectrogramZAxisScale(zMin, zMax);
|
||||
}
|
||||
|
@ -0,0 +1,49 @@
|
||||
#ifndef WATERFALLPLOT_H
|
||||
#define WATERFALLPLOT_H
|
||||
|
||||
#include <string>
|
||||
|
||||
class WaterfallplotWrapper;
|
||||
|
||||
class Waterfallplot
|
||||
{
|
||||
public:
|
||||
Waterfallplot(int numDataPoints, int numRows);
|
||||
~Waterfallplot();
|
||||
|
||||
template<class Iterator>
|
||||
void appendNewData(Iterator begin, Iterator end);
|
||||
void appendNewData(float* data, int numPoints);
|
||||
void appendNewData(double* data, int numPoints);
|
||||
void setTitle(std::string title);
|
||||
void setPlotXLabel(std::string xLabel);
|
||||
void setPlotYLabel(std::string yLabel);
|
||||
void setPlotXAxisRange(double xMin, double xMax);
|
||||
void setPlotXAxisScale(double xMin, double xMax);
|
||||
void setPlotYAxisScale(double yMin, double yMax);
|
||||
void setSpectrogramXLabel(std::string xLabel);
|
||||
void setSpectrogramYLabel(std::string yLabel);
|
||||
void setSpectrogramXAxisRange(double xMin, double xMax);
|
||||
void setSpectrogramYAxisRange(double yMin, double yMax);
|
||||
void setSpectrogramZAxisScale(double zMin, double zMax);
|
||||
|
||||
private:
|
||||
WaterfallplotWrapper* plot_;
|
||||
};
|
||||
|
||||
template<class Iterator>
|
||||
void Waterfallplot::appendNewData(Iterator begin, Iterator end)
|
||||
{
|
||||
int numPoints = end-begin;
|
||||
double* data = new double[numPoints];
|
||||
|
||||
for(int i=0;begin!=end;begin++,i++)
|
||||
{
|
||||
data[i] = *begin;
|
||||
}
|
||||
|
||||
appendNewData(data, numPoints);
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
#endif // WATERFALLPLOT_H
|
@ -0,0 +1,187 @@
|
||||
#include "WaterfallplotWrapper.h"
|
||||
|
||||
#include "WaterfallWidget.h"
|
||||
#include "Events.h"
|
||||
#include <qapplication.h>
|
||||
#include <QThread>
|
||||
|
||||
using namespace std;
|
||||
|
||||
WaterfallplotWrapper::WaterfallplotWrapper(int numDataPoints, int numRows)
|
||||
:widget_(NULL)
|
||||
,destroyed_(true)
|
||||
{
|
||||
if(QCoreApplication::instance() == NULL)
|
||||
return; //TODO: throw exception here in Iris
|
||||
if(QCoreApplication::instance()->thread() == QThread::currentThread())
|
||||
{
|
||||
connect( this, SIGNAL( createWidgetSignal(int, int) ),
|
||||
this, SLOT(createWidgetSlot(int, int)) );
|
||||
connect( this, SIGNAL( destroyWidgetSignal() ),
|
||||
this, SLOT(destroyWidgetSlot()) );
|
||||
connect( this, SIGNAL( destroyWidgetSignalBlocking() ),
|
||||
this, SLOT(destroyWidgetSlot()) );
|
||||
}
|
||||
else
|
||||
{
|
||||
connect( this, SIGNAL( createWidgetSignal(int, int) ),
|
||||
this, SLOT(createWidgetSlot(int, int)),
|
||||
Qt::BlockingQueuedConnection );
|
||||
connect( this, SIGNAL( destroyWidgetSignal() ),
|
||||
this, SLOT(destroyWidgetSlot()) );
|
||||
connect( this, SIGNAL( destroyWidgetSignalBlocking() ),
|
||||
this, SLOT(destroyWidgetSlot()),
|
||||
Qt::BlockingQueuedConnection );
|
||||
moveToThread(QCoreApplication::instance()->thread());
|
||||
}
|
||||
emit createWidgetSignal(numDataPoints, numRows);
|
||||
}
|
||||
|
||||
WaterfallplotWrapper::~WaterfallplotWrapper()
|
||||
{
|
||||
if(destroyed_)
|
||||
emit destroyWidgetSignal();
|
||||
else
|
||||
emit destroyWidgetSignalBlocking();
|
||||
}
|
||||
|
||||
void WaterfallplotWrapper::createWidgetSlot(int numDataPoints, int numRows)
|
||||
{
|
||||
widget_ = new WaterfallWidget(numDataPoints, numRows);
|
||||
destroyed_ = false;
|
||||
widget_->setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
connect(widget_, SIGNAL( destroyed() ),
|
||||
this, SLOT( widgetDestroyed() ));
|
||||
connect(this, SIGNAL(setWidgetTitle(QString)),
|
||||
widget_, SLOT(setWidgetTitle(QString)));
|
||||
connect(this, SIGNAL(setWidgetPXLabel(QString)),
|
||||
widget_, SLOT(setPlotXLabel(QString)));
|
||||
connect(this, SIGNAL(setWidgetPYLabel(QString)),
|
||||
widget_, SLOT(setPlotYLabel(QString)));
|
||||
connect(this, SIGNAL(setWidgetPXAxisRange(double, double)),
|
||||
widget_, SLOT(setPlotXAxisRange(double, double)));
|
||||
connect(this, SIGNAL(setWidgetPXAxisScale(double, double)),
|
||||
widget_, SLOT(setPlotXAxisScale(double, double)));
|
||||
connect(this, SIGNAL(setWidgetPYAxisScale(double, double)),
|
||||
widget_, SLOT(setPlotYAxisScale(double, double)));
|
||||
connect(this, SIGNAL(setWidgetSXLabel(QString)),
|
||||
widget_, SLOT(setSpectrogramXLabel(QString)));
|
||||
connect(this, SIGNAL(setWidgetSYLabel(QString)),
|
||||
widget_, SLOT(setSpectrogramYLabel(QString)));
|
||||
connect(this, SIGNAL(setWidgetSXAxisRange(double, double)),
|
||||
widget_, SLOT(setSpectrogramXAxisRange(double, double)));
|
||||
connect(this, SIGNAL(setWidgetSYAxisRange(double, double)),
|
||||
widget_, SLOT(setSpectrogramYAxisRange(double, double)));
|
||||
connect(this, SIGNAL(setWidgetSZAxisScale(double, double)),
|
||||
widget_, SLOT(setSpectrogramZAxisScale(double, double)));
|
||||
|
||||
widget_->resize( 800, 600 );
|
||||
widget_->show();
|
||||
}
|
||||
|
||||
void WaterfallplotWrapper::destroyWidgetSlot()
|
||||
{
|
||||
delete widget_;
|
||||
}
|
||||
|
||||
void WaterfallplotWrapper::widgetDestroyed()
|
||||
{
|
||||
destroyed_ = true;
|
||||
}
|
||||
|
||||
void WaterfallplotWrapper::appendNewData(float* data, int numPoints)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
qApp->postEvent(widget_, new RealDataEvent(data, numPoints));
|
||||
}
|
||||
|
||||
void WaterfallplotWrapper::appendNewData(double* data, int numPoints)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
qApp->postEvent(widget_, new RealDataEvent(data, numPoints));
|
||||
}
|
||||
|
||||
|
||||
void WaterfallplotWrapper::setTitle(std::string title)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
QString str = QString::fromUtf8(title.c_str());
|
||||
emit setWidgetTitle(str);
|
||||
}
|
||||
|
||||
void WaterfallplotWrapper::setPlotXLabel(std::string xLabel)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
QString str = QString::fromUtf8(xLabel.c_str());
|
||||
emit setWidgetPXLabel(str);
|
||||
}
|
||||
|
||||
void WaterfallplotWrapper::setPlotYLabel(std::string yLabel)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
QString str = QString::fromUtf8(yLabel.c_str());
|
||||
emit setWidgetPYLabel(str);
|
||||
}
|
||||
|
||||
void WaterfallplotWrapper::setPlotXAxisRange(double xMin, double xMax)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
emit setWidgetPXAxisRange(xMin, xMax);
|
||||
}
|
||||
|
||||
void WaterfallplotWrapper::setPlotXAxisScale(double xMin, double xMax)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
emit setWidgetPXAxisScale(xMin, xMax);
|
||||
}
|
||||
|
||||
void WaterfallplotWrapper::setPlotYAxisScale(double yMin, double yMax)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
emit setWidgetPYAxisScale(yMin, yMax);
|
||||
}
|
||||
|
||||
void WaterfallplotWrapper::setSpectrogramXAxisRange(double xMin, double xMax)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
emit setWidgetSXAxisRange(xMin, xMax);
|
||||
}
|
||||
|
||||
void WaterfallplotWrapper::setSpectrogramXLabel(std::string xLabel)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
QString str = QString::fromUtf8(xLabel.c_str());
|
||||
emit setWidgetSXLabel(str);
|
||||
}
|
||||
|
||||
void WaterfallplotWrapper::setSpectrogramYLabel(std::string yLabel)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
QString str = QString::fromUtf8(yLabel.c_str());
|
||||
emit setWidgetSYLabel(str);
|
||||
}
|
||||
|
||||
void WaterfallplotWrapper::setSpectrogramYAxisRange(double yMin, double yMax)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
emit setWidgetSYAxisRange(yMin, yMax);
|
||||
}
|
||||
|
||||
void WaterfallplotWrapper::setSpectrogramZAxisScale(double zMin, double zMax)
|
||||
{
|
||||
if(destroyed_)
|
||||
return;
|
||||
emit setWidgetSZAxisScale(zMin, zMax);
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
#ifndef WATERFALLPLOTWRAPPER_H
|
||||
#define WATERFALLPLOTWRAPPER_H
|
||||
|
||||
#include <qapplication.h>
|
||||
|
||||
class WaterfallWidget;
|
||||
|
||||
class WaterfallplotWrapper
|
||||
: QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
WaterfallplotWrapper(int numDataPoints, int numRows);
|
||||
~WaterfallplotWrapper();
|
||||
|
||||
void appendNewData(float* data, int numPoints);
|
||||
void appendNewData(double* data, int numPoints);
|
||||
void setTitle(std::string title);
|
||||
void setPlotXLabel(std::string xLabel);
|
||||
void setPlotYLabel(std::string yLabel);
|
||||
void setPlotXAxisRange(double xMin, double xMax);
|
||||
void setPlotXAxisScale(double xMin, double xMax);
|
||||
void setPlotYAxisScale(double yMin, double yMax);
|
||||
void setSpectrogramXLabel(std::string xLabel);
|
||||
void setSpectrogramYLabel(std::string yLabel);
|
||||
void setSpectrogramXAxisRange(double xMin, double xMax);
|
||||
void setSpectrogramYAxisRange(double yMin, double yMax);
|
||||
void setSpectrogramZAxisScale(double zMin, double zMax);
|
||||
|
||||
public slots:
|
||||
void createWidgetSlot(int numDataPoints, int numRows);
|
||||
void destroyWidgetSlot();
|
||||
void widgetDestroyed();
|
||||
|
||||
signals:
|
||||
void createWidgetSignal(int numDataPoints, int numRows);
|
||||
void destroyWidgetSignal();
|
||||
void destroyWidgetSignalBlocking();
|
||||
void setWidgetTitle(QString title);
|
||||
void setWidgetPXLabel(QString xLabel);
|
||||
void setWidgetPYLabel(QString yLabel);
|
||||
void setWidgetPXAxisRange(double xMin, double xMax);
|
||||
void setWidgetPXAxisScale(double xMin, double xMax);
|
||||
void setWidgetPYAxisScale(double yMin, double yMax);
|
||||
void setWidgetSXLabel(QString xLabel);
|
||||
void setWidgetSYLabel(QString yLabel);
|
||||
void setWidgetSXAxisRange(double xMin, double xMax);
|
||||
void setWidgetSYAxisRange(double yMin, double yMax);
|
||||
void setWidgetSZAxisScale(double zMin, double zMax);
|
||||
|
||||
private:
|
||||
WaterfallWidget* widget_;
|
||||
bool destroyed_;
|
||||
};
|
||||
|
||||
#endif // WATERFALLPLOTWRAPPER_H
|
@ -0,0 +1,102 @@
|
||||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The libLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the libLTE library.
|
||||
*
|
||||
* libLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* libLTE 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include "plot/plot_waterfall.h"
|
||||
#include "Waterfallplot.h"
|
||||
#include <complex.h>
|
||||
|
||||
|
||||
int plot_waterfall_init(plot_waterfall_t *h, int numDataPoints, int numRows) {
|
||||
*h = (void*) new Waterfallplot(numDataPoints, numRows);
|
||||
return (*h != NULL)?0:-1;
|
||||
}
|
||||
|
||||
void plot_waterfall_setTitle(plot_waterfall_t *h, char *title) {
|
||||
Waterfallplot *plot = static_cast<Waterfallplot*>(*h);
|
||||
plot->setTitle(title);
|
||||
}
|
||||
|
||||
void plot_waterfall_appendNewData(plot_waterfall_t *h, float *data,
|
||||
int num_points) {
|
||||
Waterfallplot *plot = static_cast<Waterfallplot*>(*h);
|
||||
plot->appendNewData(data, num_points);
|
||||
}
|
||||
|
||||
void plot_complex_setPlotXLabel(plot_waterfall_t *h, char *xLabel) {
|
||||
Waterfallplot *plot = static_cast<Waterfallplot*>(*h);
|
||||
plot->setPlotXLabel(xLabel);
|
||||
}
|
||||
|
||||
void plot_complex_setPlotYLabel(plot_waterfall_t *h, char *yLabel) {
|
||||
Waterfallplot *plot = static_cast<Waterfallplot*>(*h);
|
||||
plot->setPlotXLabel(yLabel);
|
||||
}
|
||||
|
||||
void plot_waterfall_setPlotXAxisRange(plot_waterfall_t *h, double xMin, double xMax) {
|
||||
Waterfallplot *plot = static_cast<Waterfallplot*>(*h);
|
||||
plot->setPlotXAxisRange(xMin, xMax);
|
||||
}
|
||||
|
||||
void plot_waterfall_setPlotXAxisScale(plot_waterfall_t *h, double xMin, double xMax) {
|
||||
Waterfallplot *plot = static_cast<Waterfallplot*>(*h);
|
||||
plot->setPlotXAxisScale(xMin, xMax);
|
||||
}
|
||||
|
||||
void plot_waterfall_setPlotYAxisScale(plot_waterfall_t *h, double yMin, double yMax) {
|
||||
Waterfallplot *plot = static_cast<Waterfallplot*>(*h);
|
||||
plot->setPlotYAxisScale(yMin, yMax);
|
||||
}
|
||||
|
||||
|
||||
void plot_waterfall_setSpectrogramXLabel(plot_waterfall_t *h, char* xLabel) {
|
||||
Waterfallplot *plot = static_cast<Waterfallplot*>(*h);
|
||||
plot->setSpectrogramXLabel(xLabel);
|
||||
}
|
||||
|
||||
void plot_waterfall_setSpectrogramYLabel(plot_waterfall_t *h, char* yLabel) {
|
||||
Waterfallplot *plot = static_cast<Waterfallplot*>(*h);
|
||||
plot->setSpectrogramYLabel(yLabel);
|
||||
}
|
||||
|
||||
void plot_waterfall_setSpectrogramXAxisRange(plot_waterfall_t *h, double xMin, double xMax) {
|
||||
Waterfallplot *plot = static_cast<Waterfallplot*>(*h);
|
||||
plot->setSpectrogramXAxisRange(xMin, xMax);
|
||||
}
|
||||
|
||||
void plot_waterfall_setSpectrogramYAxisRange(plot_waterfall_t *h, double yMin, double yMax) {
|
||||
Waterfallplot *plot = static_cast<Waterfallplot*>(*h);
|
||||
plot->setSpectrogramYAxisRange(yMin, yMax);
|
||||
}
|
||||
|
||||
void plot_waterfall_setSpectrogramZAxisScale(plot_waterfall_t *h, double zMin, double zMax) {
|
||||
Waterfallplot *plot = static_cast<Waterfallplot*>(*h);
|
||||
plot->setSpectrogramZAxisScale(zMin, zMax);
|
||||
}
|
||||
|
@ -0,0 +1,32 @@
|
||||
#
|
||||
# Copyright 2012-2013 The Iris Project Developers. See the
|
||||
# COPYRIGHT file at the top-level directory of this distribution
|
||||
# and at http://www.softwareradiosystems.com/iris/copyright.html.
|
||||
#
|
||||
# This file is part of the Iris Project.
|
||||
#
|
||||
# Iris is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of
|
||||
# the License, or (at your option) any later version.
|
||||
#
|
||||
# Iris 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 Lesser General Public License for more details.
|
||||
#
|
||||
# A copy of the GNU Lesser General Public License can be found in
|
||||
# the LICENSE file in the top-level directory of this distribution
|
||||
# and at http://www.gnu.org/licenses/.
|
||||
#
|
||||
|
||||
########################################################################
|
||||
# Build tests
|
||||
########################################################################
|
||||
#turn the test cpp file into an executable with an int main() function
|
||||
ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK -DBOOST_TEST_MAIN)
|
||||
INCLUDE_DIRECTORIES(..)
|
||||
ADD_EXECUTABLE(waterfallplot_test Waterfallplot_test.cpp)
|
||||
TARGET_LINK_LIBRARIES(waterfallplot_test ${Boost_LIBRARIES} graphics)
|
||||
ADD_TEST(waterfallplot_test waterfallplot_test)
|
||||
|
@ -0,0 +1,128 @@
|
||||
/**
|
||||
* \file lib/generic/modulation/Crc_test.cpp
|
||||
* \version 1.0
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2012-2013 The Iris Project Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution
|
||||
* and at http://www.softwareradiosystems.com/iris/copyright.html.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the Iris Project.
|
||||
*
|
||||
* Iris is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Iris 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 Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
* \section DESCRIPTION
|
||||
*
|
||||
* Main test file for Waterfallplot class.
|
||||
*/
|
||||
|
||||
#define BOOST_TEST_MODULE Waterfallplot_Test
|
||||
|
||||
#include "Waterfallplot.h"
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/progress.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <qapplication.h>
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#define PI 3.14159265358979323846
|
||||
|
||||
using namespace std;
|
||||
|
||||
void threadMain1()
|
||||
{
|
||||
int n=2048;
|
||||
Waterfallplot plot(n,n);
|
||||
plot.setTitle("Float");
|
||||
|
||||
float step = 1.0*PI/n;
|
||||
float* data = new float[n*2];
|
||||
for(int i=0;i<n*2;i++)
|
||||
data[i] = sinf(step*i);
|
||||
|
||||
for(int i=0;i<n;i++)
|
||||
{
|
||||
plot.appendNewData(data+i, n);
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
|
||||
}
|
||||
}
|
||||
|
||||
void threadMain2()
|
||||
{
|
||||
int n=2048;
|
||||
Waterfallplot plot(n,n);
|
||||
plot.setTitle("Double");
|
||||
|
||||
double step = 2.0*PI/n;
|
||||
double* data = new double[n*2];
|
||||
for(int i=0;i<n*2;i++)
|
||||
data[i] = sin(step*i);
|
||||
|
||||
for(int i=0;i<n;i++)
|
||||
{
|
||||
plot.appendNewData(data+i, n);
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
|
||||
}
|
||||
}
|
||||
|
||||
void threadMain3()
|
||||
{
|
||||
int n=2048;
|
||||
Waterfallplot plot(n,n);
|
||||
plot.setTitle("FloatVec");
|
||||
|
||||
double step = 2.0*PI/n;
|
||||
std::vector<float> data;
|
||||
data.resize(n*2);
|
||||
for(int i=0;i<n*2;i++)
|
||||
data[i] = sin(step*i);
|
||||
|
||||
for(int i=0;i<n;i++)
|
||||
{
|
||||
plot.appendNewData(data.begin()+i, data.begin()+i+n);
|
||||
boost::this_thread::sleep(boost::posix_time::milliseconds(1));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE (Waterfallplot_Test)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Waterfallplot_Init_Test)
|
||||
{
|
||||
int argc = 1;
|
||||
char* argv[] = { const_cast<char *>("Waterfallplot_Init_Test"), NULL };
|
||||
QApplication a(argc, argv);
|
||||
|
||||
boost::scoped_ptr< boost::thread > thread1_;
|
||||
boost::scoped_ptr< boost::thread > thread2_;
|
||||
boost::scoped_ptr< boost::thread > thread3_;
|
||||
|
||||
thread1_.reset( new boost::thread( &threadMain1 ) );
|
||||
thread2_.reset( new boost::thread( &threadMain2 ) );
|
||||
thread3_.reset( new boost::thread( &threadMain3 ) );
|
||||
|
||||
qApp->exec();
|
||||
thread1_->join();
|
||||
thread2_->join();
|
||||
thread3_->join();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Ismael Gomez-Miguelez <gomezi@tcd.ie>.
|
||||
* This file is part of OSLD-lib (http://https://github.com/ismagom/osld-lib)
|
||||
*
|
||||
* OSLD-lib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* OSLD-lib 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with OSLD-lib. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <complex.h>
|
||||
|
||||
#ifndef CH_AWGN_
|
||||
#define CH_AWGN_
|
||||
|
||||
typedef _Complex float cf;
|
||||
|
||||
void ch_awgn(const cf* input, cf* output, float variance, int buff_sz);
|
||||
|
||||
/* High-level API */
|
||||
|
||||
typedef struct {
|
||||
const cf* input;
|
||||
int in_len;
|
||||
struct ch_awgn_ctrl_in {
|
||||
float variance; // Noise variance
|
||||
} ctrl_in;
|
||||
|
||||
cf* output;
|
||||
int out_len;
|
||||
}ch_awgn_hl;
|
||||
|
||||
int ch_awgn_initialize(ch_awgn_hl* hl);
|
||||
int ch_awgn_work(ch_awgn_hl* hl);
|
||||
int ch_awgn_stop(ch_awgn_hl* hl);
|
||||
|
||||
#endif
|
@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Ismael Gomez-Miguelez <gomezi@tcd.ie>.
|
||||
* This file is part of OSLD-lib (http://https://github.com/ismagom/osld-lib)
|
||||
*
|
||||
* OSLD-lib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* OSLD-lib 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with OSLD-lib. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CRC_
|
||||
#define CRC_
|
||||
|
||||
|
||||
unsigned int crc(unsigned int crc, char *bufptr, int len,
|
||||
int long_crc,unsigned int poly, int paste_word);
|
||||
|
||||
#endif
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Ismael Gomez-Miguelez <gomezi@tcd.ie>.
|
||||
* This file is part of OSLD-lib (http://https://github.com/ismagom/osld-lib)
|
||||
*
|
||||
* OSLD-lib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* OSLD-lib 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with OSLD-lib. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef FILESINK_
|
||||
#define FILESINK_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "io/format.h"
|
||||
|
||||
/* Low-level API */
|
||||
typedef struct {
|
||||
FILE *f;
|
||||
file_data_type_t type;
|
||||
}filesink_t;
|
||||
|
||||
int filesink_init(filesink_t *q, char *filename, file_data_type_t type);
|
||||
void filesink_close(filesink_t *q);
|
||||
|
||||
int filesink_write(filesink_t *q, void *buffer, int nsamples);
|
||||
|
||||
|
||||
/* High-level API */
|
||||
typedef struct {
|
||||
filesink_t obj;
|
||||
struct filesink_init {
|
||||
char *file_name;
|
||||
int block_length;
|
||||
int data_type;
|
||||
} init;
|
||||
void* input;
|
||||
int in_len;
|
||||
}filesink_hl;
|
||||
|
||||
int filesink_initialize(filesink_hl* h);
|
||||
int filesink_work( filesink_hl* hl);
|
||||
int filesink_stop(filesink_hl* h);
|
||||
|
||||
#endif
|
@ -1,7 +0,0 @@
|
||||
|
||||
#ifndef FORMAT_
|
||||
#define FORMAT_
|
||||
|
||||
typedef enum { FLOAT, COMPLEX_FLOAT, COMPLEX_SHORT, FLOAT_BIN, COMPLEX_FLOAT_BIN, COMPLEX_SHORT_BIN} file_data_type_t;
|
||||
|
||||
#endif
|
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Ismael Gomez-Miguelez <gomezi@tcd.ie>.
|
||||
* This file is part of OSLD-lib (http://https://github.com/ismagom/osld-lib)
|
||||
*
|
||||
* OSLD-lib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* OSLD-lib 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with OSLD-lib. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <complex.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifndef _LTE_
|
||||
#define _LTE_
|
||||
|
||||
#include "utils/bit.h"
|
||||
#include "utils/convolution.h"
|
||||
#include "utils/debug.h"
|
||||
#include "utils/dft.h"
|
||||
#include "utils/matrix.h"
|
||||
#include "utils/mux.h"
|
||||
#include "utils/nco.h"
|
||||
#include "utils/pack.h"
|
||||
#include "utils/vector.h"
|
||||
|
||||
#include "lte/base.h"
|
||||
#include "lte/fft.h"
|
||||
#include "lte/sequence.h"
|
||||
|
||||
#include "ch_estimation/chest.h"
|
||||
#include "ch_estimation/refsignal.h"
|
||||
|
||||
#include "channel/ch_awgn.h"
|
||||
|
||||
#include "fec/viterbi.h"
|
||||
#include "fec/convcoder.h"
|
||||
#include "fec/crc.h"
|
||||
|
||||
#include "filter/filter2d.h"
|
||||
|
||||
#include "io/binsource.h"
|
||||
#include "io/filesink.h"
|
||||
#include "io/filesource.h"
|
||||
|
||||
#include "modem/demod_hard.h"
|
||||
#include "modem/demod_soft.h"
|
||||
#include "modem/mod.h"
|
||||
#include "modem/modem_table.h"
|
||||
|
||||
#include "phch/pbch.h"
|
||||
|
||||
#include "ratematching/rm_conv.h"
|
||||
|
||||
#include "scrambling/scrambling.h"
|
||||
|
||||
#include "resampling/interp.h"
|
||||
|
||||
#include "sync/pss.h"
|
||||
#include "sync/sfo.h"
|
||||
#include "sync/sss.h"
|
||||
#include "sync/sync.h"
|
||||
|
||||
|
||||
#endif
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Ismael Gomez-Miguelez <gomezi@tcd.ie>.
|
||||
* This file is part of OSLD-lib (http://https://github.com/ismagom/osld-lib)
|
||||
*
|
||||
* OSLD-lib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* OSLD-lib 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with OSLD-lib. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LTESEQ_
|
||||
#define LTESEQ_
|
||||
|
||||
#include "lte/base.h"
|
||||
|
||||
typedef struct {
|
||||
char *c;
|
||||
int len;
|
||||
}sequence_t;
|
||||
|
||||
int sequence_init(sequence_t *q, int len);
|
||||
void sequence_free(sequence_t *q);
|
||||
|
||||
int sequence_LTEPRS(sequence_t *q, int len, int seed);
|
||||
|
||||
int sequence_pbch(sequence_t *seq, lte_cp_t cp, int cell_id);
|
||||
int sequence_pbch_crc(sequence_t *seq, int nof_ports);
|
||||
|
||||
#endif
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Ismael Gomez-Miguelez <gomezi@tcd.ie>.
|
||||
* This file is part of OSLD-lib (http://https://github.com/ismagom/osld-lib)
|
||||
*
|
||||
* OSLD-lib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* OSLD-lib 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with OSLD-lib. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MOD_
|
||||
#define MOD_
|
||||
|
||||
#include <complex.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "modem_table.h"
|
||||
|
||||
typedef _Complex float cf;
|
||||
|
||||
int mod_modulate(modem_table_t* table, const char *bits, cf* symbols, int nbits);
|
||||
|
||||
/* High-level API */
|
||||
typedef struct {
|
||||
modem_table_t obj;
|
||||
struct mod_init {
|
||||
enum modem_std std; // symbol mapping standard (see modem_table.h)
|
||||
} init;
|
||||
|
||||
const char* input;
|
||||
int in_len;
|
||||
|
||||
cf* output;
|
||||
int out_len;
|
||||
}mod_hl;
|
||||
|
||||
int mod_initialize(mod_hl* hl);
|
||||
int mod_work(mod_hl* hl);
|
||||
int mod_stop(mod_hl* hl);
|
||||
|
||||
#endif
|
@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Ismael Gomez-Miguelez <gomezi@tcd.ie>.
|
||||
* This file is part of OSLD-lib (http://https://github.com/ismagom/osld-lib)
|
||||
*
|
||||
* OSLD-lib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* OSLD-lib 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with OSLD-lib. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PBCH_
|
||||
#define PBCH_
|
||||
|
||||
#include "lte/base.h"
|
||||
#include "modem/mod.h"
|
||||
#include "modem/demod_soft.h"
|
||||
#include "scrambling/scrambling.h"
|
||||
#include "ratematching/rm_conv.h"
|
||||
#include "fec/convcoder.h"
|
||||
#include "fec/viterbi.h"
|
||||
#include "fec/crc.h"
|
||||
|
||||
#define PBCH_RE_CPNORM 240
|
||||
#define PBCH_RE_CPEXT 216
|
||||
|
||||
typedef _Complex float cf_t;
|
||||
|
||||
enum phich_length { NORMAL, EXTENDED};
|
||||
enum phich_resources { R_1_6, R_1_2, R_1, R_2};
|
||||
|
||||
typedef struct {
|
||||
int nof_ports;
|
||||
int nof_prb;
|
||||
int sfn;
|
||||
enum phich_length phich_length;
|
||||
int phich_resources;
|
||||
}pbch_mib_t;
|
||||
|
||||
/* PBCH receiver */
|
||||
typedef struct {
|
||||
int cell_id;
|
||||
lte_cp_t cp;
|
||||
|
||||
/* buffers */
|
||||
cf_t *pbch_symbols;
|
||||
float *pbch_llr;
|
||||
float *temp;
|
||||
float *pbch_rm;
|
||||
char *data;
|
||||
|
||||
int frame_idx;
|
||||
|
||||
/* tx & rx objects */
|
||||
modem_table_t mod;
|
||||
demod_soft_t demod;
|
||||
sequence_t seq_pbch;
|
||||
viterbi_t decoder;
|
||||
|
||||
}pbch_t;
|
||||
|
||||
int pbch_init(pbch_t *q, int cell_id, lte_cp_t cp);
|
||||
void pbch_free(pbch_t *q);
|
||||
int pbch_decode(pbch_t *q, cf_t *slot1_symbols, cf_t **ce, int nof_ports, int nof_prb, float ebno, pbch_mib_t *data);
|
||||
void pbch_mib_fprint(FILE *stream, pbch_mib_t *mib);
|
||||
|
||||
|
||||
bool pbch_exists(int nframe, int nslot);
|
||||
int pbch_put(cf_t *pbch, cf_t *slot1_data, int nof_prb, lte_cp_t cp, int cell_id);
|
||||
int pbch_get(cf_t *pbch, cf_t *slot1_data, int nof_prb, lte_cp_t cp, int cell_id);
|
||||
|
||||
#endif
|
@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Ismael Gomez-Miguelez <gomezi@tcd.ie>.
|
||||
* This file is part of OSLD-lib (http://https://github.com/ismagom/osld-lib)
|
||||
*
|
||||
* OSLD-lib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* OSLD-lib 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with OSLD-lib. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
typedef _Complex float cf_t;
|
||||
|
||||
|
||||
void interp_linear_offset(cf_t *input, cf_t *output, int M, int len, int off_st, int off_end);
|
||||
void interp_linear(cf_t *input, cf_t *output, int M, int len);
|
||||
void interp_linear_f(float *input, float *output, int M, int len);
|
@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Ismael Gomez-Miguelez <gomezi@tcd.ie>.
|
||||
* This file is part of OSLD-lib (http://https://github.com/ismagom/osld-lib)
|
||||
*
|
||||
* OSLD-lib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* OSLD-lib 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with OSLD-lib. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SFO_
|
||||
#define SFO_
|
||||
|
||||
float sfo_estimate(int *t0, int len, float period);
|
||||
float sfo_estimate_period(int *t0, int *t, int len, float period);
|
||||
|
||||
#endif
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Ismael Gomez-Miguelez <gomezi@tcd.ie>.
|
||||
* This file is part of OSLD-lib (http://https://github.com/ismagom/osld-lib)
|
||||
*
|
||||
* OSLD-lib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* OSLD-lib 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with OSLD-lib. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BIT_
|
||||
#define BIT_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
uint32_t bit_unpack(char **bits, int nof_bits);
|
||||
void bit_pack(uint32_t value, char **bits, int nof_bits);
|
||||
void bit_fprint(FILE *stream, char *bits, int nof_bits);
|
||||
unsigned int bit_diff(char *x, char *y, int nbits);
|
||||
|
||||
#endif
|
||||
|
@ -1,37 +0,0 @@
|
||||
#ifndef DEBUG_H
|
||||
#define DEBUG_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define VERBOSE_DEBUG 2
|
||||
#define VERBOSE_INFO 1
|
||||
#define VERBOSE_NONE 0
|
||||
|
||||
#include <sys/time.h>
|
||||
void get_time_interval(struct timeval * tdata);
|
||||
|
||||
#ifndef DEBUG_DISABLED
|
||||
|
||||
extern int verbose;
|
||||
|
||||
#define VERBOSE_ISINFO() (verbose==VERBOSE_INFO)
|
||||
#define VERBOSE_ISDEBUG() (verbose==VERBOSE_DEBUG)
|
||||
|
||||
#define PRINT_DEBUG verbose=VERBOSE_DEBUG
|
||||
#define PRINT_INFO verbose=VERBOSE_INFO
|
||||
#define PRINT_NONE verbose=VERBOSE_NONE
|
||||
|
||||
#define DEBUG(_fmt, ...) if (verbose >= VERBOSE_DEBUG) \
|
||||
fprintf(stdout, "[DEBUG]: " _fmt, __VA_ARGS__)
|
||||
|
||||
#define INFO(_fmt, ...) if (verbose >= VERBOSE_INFO) \
|
||||
fprintf(stdout, "[INFO]: " _fmt, __VA_ARGS__)
|
||||
|
||||
#else
|
||||
|
||||
#define DEBUG
|
||||
#define INFO
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Ismael Gomez-Miguelez <gomezi@tcd.ie>.
|
||||
* This file is part of OSLD-lib (http://https://github.com/ismagom/osld-lib)
|
||||
*
|
||||
* OSLD-lib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* OSLD-lib 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with OSLD-lib. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MUX_
|
||||
#define MUX_
|
||||
|
||||
void mux(void **input, void *output, int *input_lengths, int *input_padding_pre, int nof_inputs,
|
||||
int sample_sz);
|
||||
|
||||
void demux(void *input, void **output, int *output_lengths,
|
||||
int *output_padding_pre, int *output_padding_post, int nof_outputs,
|
||||
int sample_sz);
|
||||
|
||||
#endif
|
@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Ismael Gomez-Miguelez <gomezi@tcd.ie>.
|
||||
* This file is part of OSLD-lib (http://https://github.com/ismagom/osld-lib)
|
||||
*
|
||||
* OSLD-lib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* OSLD-lib 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with OSLD-lib. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PACK_
|
||||
#define PACK_
|
||||
|
||||
unsigned int unpack_bits(char **bits, int nof_bits);
|
||||
void pack_bits(unsigned int value, char **bits, int nof_bits);
|
||||
|
||||
#endif
|
@ -1,28 +0,0 @@
|
||||
|
||||
|
||||
file(GLOB modules *)
|
||||
|
||||
SET(SOURCES_ALL "")
|
||||
foreach (_module ${modules})
|
||||
if (IS_DIRECTORY ${_module})
|
||||
file(GLOB_RECURSE tmp "${_module}/src/*.c")
|
||||
LIST(APPEND SOURCES_ALL ${tmp})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include)
|
||||
|
||||
|
||||
add_library(osld ${SOURCES_ALL})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Ismael Gomez-Miguelez <gomezi@tcd.ie>.
|
||||
* This file is part of OSLD-lib (http://https://github.com/ismagom/osld-lib)
|
||||
*
|
||||
* OSLD-lib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* OSLD-lib 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with OSLD-lib. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <complex.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include "gauss.h"
|
||||
#include "channel/ch_awgn.h"
|
||||
|
||||
void ch_awgn(const cf* x, cf* y, float variance, int buff_sz) {
|
||||
_Complex float tmp;
|
||||
int i;
|
||||
|
||||
for (i=0;i<buff_sz;i++) {
|
||||
__real__ tmp = rand_gauss();
|
||||
__imag__ tmp = rand_gauss();
|
||||
tmp *= variance;
|
||||
y[i] = tmp + x[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* High-level API */
|
||||
int ch_awgn_initialize(ch_awgn_hl* hl) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ch_awgn_work(ch_awgn_hl* hl) {
|
||||
ch_awgn(hl->input,hl->output,hl->ctrl_in.variance,hl->in_len);
|
||||
hl->out_len = hl->in_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ch_awgn_stop(ch_awgn_hl* hl) {
|
||||
return 0;
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Ismael Gomez-Miguelez <gomezi@tcd.ie>.
|
||||
* This file is part of OSLD-lib (http://https://github.com/ismagom/osld-lib)
|
||||
*
|
||||
* OSLD-lib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* OSLD-lib 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with OSLD-lib. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
float rand_gauss (void) {
|
||||
float v1,v2,s;
|
||||
|
||||
do {
|
||||
v1 = 2.0 * ((float) rand()/RAND_MAX) - 1;
|
||||
v2 = 2.0 * ((float) rand()/RAND_MAX) - 1;
|
||||
|
||||
s = v1*v1 + v2*v2;
|
||||
} while ( s >= 1.0 );
|
||||
|
||||
if (s == 0.0)
|
||||
return 0.0;
|
||||
else
|
||||
return (v1*sqrt(-2.0 * log(s) / s));
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Ismael Gomez-Miguelez <gomezi@tcd.ie>.
|
||||
* This file is part of OSLD-lib (http://https://github.com/ismagom/osld-lib)
|
||||
*
|
||||
* OSLD-lib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* OSLD-lib 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with OSLD-lib. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
float rand_gauss (void);
|
@ -1,144 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Ismael Gomez-Miguelez <gomezi@tcd.ie>.
|
||||
* This file is part of OSLD-lib (http://https://github.com/ismagom/osld-lib)
|
||||
*
|
||||
* OSLD-lib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* OSLD-lib 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with OSLD-lib. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**@TODO frontend to FEC library if installed
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "fec/viterbi.h"
|
||||
#include "parity.h"
|
||||
#include "viterbi37.h"
|
||||
|
||||
#define DEB 0
|
||||
|
||||
int decode37(void *o, float *symbols, char *data) {
|
||||
viterbi_t *q = o;
|
||||
int i;
|
||||
int len = q->tail_biting ? q->framebits : (q->framebits + q->K - 1);
|
||||
float amp = 0;
|
||||
|
||||
for (i=0;i<3*len;i++) {
|
||||
if (fabsf(symbols[i] > amp)) {
|
||||
amp = symbols[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Decode it and make sure we get the right answer */
|
||||
/* Initialize Viterbi decoder */
|
||||
init_viterbi37_port(q->ptr, q->tail_biting?-1:0);
|
||||
|
||||
/* Decode block */
|
||||
update_viterbi37_blk_port(q->ptr, symbols,q->framebits + q->K - 1, amp, len);
|
||||
|
||||
/* Do Viterbi chainback */
|
||||
chainback_viterbi37_port(q->ptr, data, q->framebits, 0);
|
||||
|
||||
return q->framebits;
|
||||
}
|
||||
|
||||
void free37(void *o) {
|
||||
viterbi_t *q = o;
|
||||
delete_viterbi37_port(q->ptr);
|
||||
}
|
||||
|
||||
int init37(viterbi_t *q, int poly[3], int framebits, bool tail_biting) {
|
||||
q->K = 7;
|
||||
q->R = 3;
|
||||
q->framebits = framebits;
|
||||
q->tail_biting = tail_biting;
|
||||
q->decode = decode37;
|
||||
q->free = free37;
|
||||
|
||||
if ((q->ptr = create_viterbi37_port(poly, framebits, tail_biting)) == NULL) {
|
||||
fprintf(stderr, "create_viterbi37 failed\n");
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int viterbi_init(viterbi_t *q, viterbi_type_t type, int poly[3], int framebits, bool tail_bitting) {
|
||||
switch(type) {
|
||||
case viterbi_37:
|
||||
return init37(q, poly, framebits, tail_bitting);
|
||||
default:
|
||||
fprintf(stderr, "Decoder not implemented\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void viterbi_free(viterbi_t *q) {
|
||||
q->free(q);
|
||||
}
|
||||
|
||||
/* symbols are real-valued */
|
||||
int viterbi_decode(viterbi_t *q, float *symbols, char *data) {
|
||||
return q->decode(q, symbols, data);
|
||||
}
|
||||
|
||||
|
||||
int viterbi_initialize(viterbi_hl* h) {
|
||||
int poly[3];
|
||||
viterbi_type_t type;
|
||||
if (h->init.rate == 2) {
|
||||
if (h->init.constraint_length == 7) {
|
||||
type = viterbi_27;
|
||||
} else if (h->init.constraint_length == 9) {
|
||||
type = viterbi_29;
|
||||
} else {
|
||||
fprintf(stderr, "Unsupported decoder %d/%d\n", h->init.rate,
|
||||
h->init.constraint_length);
|
||||
return -1;
|
||||
}
|
||||
} else if (h->init.rate == 3) {
|
||||
if (h->init.constraint_length == 7) {
|
||||
type = viterbi_37;
|
||||
} else if (h->init.constraint_length == 9) {
|
||||
type = viterbi_39;
|
||||
} else {
|
||||
fprintf(stderr, "Unsupported decoder %d/%d\n", h->init.rate,
|
||||
h->init.constraint_length);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Unsupported decoder %d/%d\n", h->init.rate,
|
||||
h->init.constraint_length);
|
||||
return -1;
|
||||
}
|
||||
poly[0] = h->init.generator_0;
|
||||
poly[1] = h->init.generator_1;
|
||||
poly[2] = h->init.generator_2;
|
||||
return viterbi_init(&h->obj, type, poly, h->init.frame_length,
|
||||
h->init.tail_bitting?true:false);
|
||||
}
|
||||
|
||||
int viterbi_work(viterbi_hl* hl) {
|
||||
if (hl->in_len != hl->init.frame_length) {
|
||||
fprintf(stderr, "Expected input length %d but got %d\n", hl->init.frame_length, hl->in_len);
|
||||
return -1;
|
||||
}
|
||||
return viterbi_decode(&hl->obj, hl->input, hl->output);
|
||||
}
|
||||
|
||||
int viterbi_stop(viterbi_hl* h) {
|
||||
viterbi_free(&h->obj);
|
||||
return 0;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue