mirror of https://github.com/pvnis/srsRAN_4G.git
commit
f2ae9d0217
@ -1,42 +1,156 @@
|
||||
#
|
||||
# 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
|
||||
|
||||
include(CTest)
|
||||
set( CTEST_MEMORYCHECK_COMMAND valgrind )
|
||||
CONFIGURE_FILE(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/CTestCustom.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.cmake"
|
||||
IMMEDIATE @ONLY)
|
||||
|
||||
########################################################################
|
||||
# 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)
|
||||
# do something
|
||||
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
|
||||
)
|
||||
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")
|
||||
|
||||
|
||||
|
||||
########################################################################
|
||||
# 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)
|
||||
|
||||
|
@ -0,0 +1,13 @@
|
||||
## This file should be placed in the root directory of your project.
|
||||
## Then modify the CMakeLists.txt file in the root directory of your
|
||||
## project to incorporate the testing dashboard.
|
||||
## # The following are required to uses Dart and the Cdash dashboard
|
||||
## ENABLE_TESTING()
|
||||
## INCLUDE(CTest)
|
||||
set(CTEST_PROJECT_NAME "libLTE")
|
||||
set(CTEST_NIGHTLY_START_TIME "00:00:00 GMT")
|
||||
|
||||
set(CTEST_DROP_METHOD "http")
|
||||
set(CTEST_DROP_SITE "my.cdash.org")
|
||||
set(CTEST_DROP_LOCATION "/submit.php?project=libLTE")
|
||||
set(CTEST_DROP_SITE_CDASH TRUE)
|
@ -0,0 +1,15 @@
|
||||
SET(CTEST_CUSTOM_MEMCHECK_IGNORE
|
||||
|
||||
# Ignore memcheck for plots. QT errors
|
||||
|
||||
waterfallplot_test
|
||||
scatterplot_test
|
||||
realplot_test
|
||||
complexplot_test
|
||||
|
||||
# Ignore these to, they take too lonk
|
||||
fft_normal
|
||||
fft_extened
|
||||
chest_test_all_cellids
|
||||
)
|
||||
|
@ -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,29 @@
|
||||
INCLUDE(FindPkgConfig)
|
||||
PKG_CHECK_MODULES(PC_VOLK volk QUIET)
|
||||
|
||||
FIND_PATH(
|
||||
VOLK_INCLUDE_DIRS
|
||||
NAMES volk.h
|
||||
HINTS $ENV{VOLK_DIR}/include/volk
|
||||
${CMAKE_INSTALL_PREFIX}/include/volk
|
||||
${PC_VOLK_INCLUDE_DIR}
|
||||
PATHS /usr/local/include/volk
|
||||
/usr/include/volk
|
||||
)
|
||||
|
||||
FIND_LIBRARY(
|
||||
VOLK_LIBRARIES
|
||||
NAMES volk
|
||||
HINTS $ENV{VOLK_DIR}/lib
|
||||
${CMAKE_INSTALL_PREFIX}/lib
|
||||
${CMAKE_INSTALL_PREFIX}/lib64
|
||||
${PC_VOLK_LIBDIR}
|
||||
PATHS /usr/local/lib
|
||||
/usr/local/lib64
|
||||
/usr/lib
|
||||
/usr/lib64
|
||||
)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(VOLK DEFAULT_MSG VOLK_LIBRARIES VOLK_INCLUDE_DIRS)
|
||||
MARK_AS_ADVANCED(VOLK_LIBRARIES VOLK_INCLUDE_DIRS)
|
@ -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,57 @@
|
||||
/**
|
||||
*
|
||||
* \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);
|
||||
|
||||
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,193 @@
|
||||
/**
|
||||
*
|
||||
* \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);
|
||||
handler->usrp->set_clock_source("internal");
|
||||
|
||||
std::string otw, cpu;
|
||||
otw="sc16";
|
||||
cpu="fc32";
|
||||
uhd::stream_args_t stream_args(cpu, otw);
|
||||
handler->rx_stream = handler->usrp->get_rx_stream(stream_args);
|
||||
handler->tx_stream = handler->usrp->get_tx_stream(stream_args);
|
||||
|
||||
*h = handler;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cuhd_close(void *h) {
|
||||
cuhd_stop_rx_stream(h);
|
||||
/** Something else to close the USRP?? */
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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,97 @@
|
||||
#include fftw3 directories
|
||||
#
|
||||
# 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/.
|
||||
#
|
||||
|
||||
|
||||
#################################################################
|
||||
# EXAMPLES
|
||||
#################################################################
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/")
|
||||
add_executable(hl_example hl_example.c)
|
||||
target_link_libraries(hl_example lte)
|
||||
|
||||
find_package(FFTWS REQUIRED)
|
||||
include_directories(${FFTWS_INCLUDE_DIRS})
|
||||
add_executable(ll_example ll_example.c)
|
||||
target_link_libraries(ll_example lte)
|
||||
|
||||
find_package(UHD)
|
||||
|
||||
#################################################################
|
||||
# Applications
|
||||
#################################################################
|
||||
|
||||
set(LIBRARIES osld m ${FFTWS_LIBRARIES})
|
||||
add_executable(synch_file synch_file.c)
|
||||
target_link_libraries(synch_file lte)
|
||||
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include)
|
||||
#################################################################
|
||||
# Check if UHD C-API and Graphics library are available
|
||||
#################################################################
|
||||
|
||||
add_executable(hl_example hl_example.c)
|
||||
target_link_libraries(hl_example ${LIBRARIES})
|
||||
LIST(FIND OPTIONAL_LIBS cuhd CUHD_FIND)
|
||||
LIST(FIND OPTIONAL_LIBS graphics GRAPHICS_FIND)
|
||||
|
||||
add_executable(ll_example ll_example.c)
|
||||
target_link_libraries(ll_example ${LIBRARIES})
|
||||
#################################################################
|
||||
# These two can be compiled without UHD or graphics support
|
||||
#################################################################
|
||||
|
||||
add_executable(pbch_ue pbch_ue.c)
|
||||
target_link_libraries(pbch_ue lte)
|
||||
|
||||
add_executable(synch_test synch_test.c)
|
||||
target_link_libraries(synch_test ${LIBRARIES})
|
||||
add_executable(pbch_enodeb pbch_enodeb.c)
|
||||
target_link_libraries(pbch_enodeb lte)
|
||||
|
||||
add_executable(equalizer_test equalizer_test.c)
|
||||
target_link_libraries(equalizer_test ${LIBRARIES})
|
||||
IF(${CUHD_FIND} EQUAL -1)
|
||||
SET_TARGET_PROPERTIES(pbch_ue PROPERTIES COMPILE_DEFINITIONS "DISABLE_UHD")
|
||||
SET_TARGET_PROPERTIES(pbch_enodeb PROPERTIES COMPILE_DEFINITIONS "DISABLE_UHD")
|
||||
ELSE(${CUHD_FIND} EQUAL -1)
|
||||
target_link_libraries(pbch_ue cuhd)
|
||||
target_link_libraries(pbch_enodeb cuhd)
|
||||
ENDIF(${CUHD_FIND} EQUAL -1)
|
||||
|
||||
add_executable(viterbi_test viterbi_test.c)
|
||||
target_link_libraries(viterbi_test ${LIBRARIES})
|
||||
IF(${GRAPHICS_FIND} EQUAL -1)
|
||||
SET_TARGET_PROPERTIES(pbch_ue PROPERTIES COMPILE_DEFINITIONS "DISABLE_GRAPHICS")
|
||||
SET_TARGET_PROPERTIES(pbch_enodeb PROPERTIES COMPILE_DEFINITIONS "DISABLE_GRAPHICS")
|
||||
ELSE(${GRAPHICS_FIND} EQUAL -1)
|
||||
target_link_libraries(pbch_ue graphics)
|
||||
target_link_libraries(pbch_enodeb graphics)
|
||||
ENDIF(${GRAPHICS_FIND} EQUAL -1)
|
||||
|
||||
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})
|
||||
#################################################################
|
||||
# These examples need the UHD driver
|
||||
#################################################################
|
||||
|
||||
IF(${CUHD_FIND} GREATER -1)
|
||||
|
||||
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})
|
||||
add_executable(scan_rssi scan_rssi.c)
|
||||
target_link_libraries(scan_rssi lte cuhd )
|
||||
|
||||
add_executable(scan_pss scan_pss.c)
|
||||
target_link_libraries(scan_pss lte cuhd )
|
||||
|
||||
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})
|
||||
add_executable(scan_mib scan_mib.c)
|
||||
target_link_libraries(scan_mib 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,282 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lte.h"
|
||||
|
||||
char *input_file_name = NULL;
|
||||
int nof_slots=100;
|
||||
float corr_peak_threshold=30;
|
||||
int file_binary = 0;
|
||||
int force_N_id_2=-1;
|
||||
int nof_ports = 1;
|
||||
|
||||
|
||||
#define FLEN 9600
|
||||
|
||||
filesource_t fsrc;
|
||||
cf_t *input_buffer, *fft_buffer, *ce[MAX_PORTS];
|
||||
pbch_t pbch;
|
||||
lte_fft_t fft;
|
||||
chest_t chest;
|
||||
sync_t synch;
|
||||
|
||||
void usage(char *prog) {
|
||||
printf("Usage: %s [onlt] -i input_file\n", prog);
|
||||
printf("\t-n number of frames [Default %d]\n", nof_slots);
|
||||
printf("\t-t correlation threshold [Default %g]\n", corr_peak_threshold);
|
||||
printf("\t-v [set verbose to debug, default none]\n");
|
||||
printf("\t-b Input files is binary [Default %s]\n", file_binary?"yes":"no");
|
||||
printf("\t-f force_N_id_2 [Default %d]\n", force_N_id_2);
|
||||
}
|
||||
|
||||
void parse_args(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "intvbf")) != -1) {
|
||||
switch(opt) {
|
||||
case 'i':
|
||||
input_file_name = argv[optind];
|
||||
break;
|
||||
case 'n':
|
||||
nof_slots = atoi(argv[optind]);
|
||||
break;
|
||||
case 't':
|
||||
corr_peak_threshold = atof(argv[optind]);
|
||||
break;
|
||||
case 'b':
|
||||
file_binary = 1;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'f':
|
||||
force_N_id_2 = atoi(argv[optind]);
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
if (!input_file_name) {
|
||||
usage(argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
int base_init() {
|
||||
int i;
|
||||
|
||||
file_data_type_t type = file_binary?COMPLEX_FLOAT_BIN:COMPLEX_FLOAT;
|
||||
if (filesource_init(&fsrc, input_file_name, type)) {
|
||||
fprintf(stderr, "Error opening file %s\n", input_file_name);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
input_buffer = malloc(4 * FLEN * sizeof(cf_t));
|
||||
if (!input_buffer) {
|
||||
perror("malloc");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
fft_buffer = malloc(CPNORM_NSYMB * 72 * sizeof(cf_t));
|
||||
if (!fft_buffer) {
|
||||
perror("malloc");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i=0;i<nof_ports;i++) {
|
||||
ce[i] = malloc(CPNORM_NSYMB * 72 * sizeof(cf_t));
|
||||
if (!ce[i]) {
|
||||
perror("malloc");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (chest_init(&chest, LINEAR, CPNORM, 6, 1)) {
|
||||
fprintf(stderr, "Error initializing equalizer\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lte_fft_init(&fft, CPNORM, 6)) {
|
||||
fprintf(stderr, "Error initializing FFT\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEBUG("Memory init OK\n",0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
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;
|
||||
lte_fft_run(&fft, input, fft_buffer);
|
||||
|
||||
/* Get channel estimates for each port */
|
||||
for (i=0;i<nof_ports;i++) {
|
||||
chest_ce_slot_port(&chest, fft_buffer, ce[i], 1, 0);
|
||||
}
|
||||
|
||||
DEBUG("Decoding PBCH\n", 0);
|
||||
return pbch_decode(&pbch, fft_buffer, ce, nof_ports, 6, 1, mib);
|
||||
}
|
||||
|
||||
int get_samples(int length, int offset) {
|
||||
int n = 0;
|
||||
if (length != -1 && offset != -1) {
|
||||
while(n < length) {
|
||||
DEBUG("Reading %d samples offset=%d\n", length - n, offset + n);
|
||||
n = filesource_read(&fsrc, &input_buffer[offset + n], length - n);
|
||||
if (n == -1) {
|
||||
fprintf(stderr, "Error reading %d samples from file\n", length - n);
|
||||
break;
|
||||
} else if (n == 0) {
|
||||
printf("End of file\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
enum radio_state { DONE, SYNC, MIB};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
enum radio_state state;
|
||||
int sf_size, slot_start;
|
||||
int read_length, frame_idx;
|
||||
int mib_attempts;
|
||||
pbch_mib_t mib;
|
||||
int cell_id;
|
||||
int idx;
|
||||
int frame_cnt;
|
||||
int read_offset;
|
||||
float cfo;
|
||||
|
||||
if (argc < 3) {
|
||||
usage(argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
parse_args(argc,argv);
|
||||
|
||||
if (base_init()) {
|
||||
fprintf(stderr, "Error initializing memory\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (sync_init(&synch, FLEN)) {
|
||||
fprintf(stderr, "Error initiating PSS/SSS\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
sync_force_N_id_2(&synch, force_N_id_2);
|
||||
sync_set_threshold(&synch, corr_peak_threshold);
|
||||
sync_pss_det_peakmean(&synch);
|
||||
|
||||
state = SYNC;
|
||||
sf_size = FLEN;
|
||||
read_length = sf_size;
|
||||
slot_start = 0;
|
||||
frame_idx = 0;
|
||||
mib_attempts = 0;
|
||||
frame_cnt = -1;
|
||||
read_offset = 0;
|
||||
cfo = 0.0;
|
||||
|
||||
printf("\n\n-- Initiating MIB search --\n\n");
|
||||
|
||||
while(state != DONE && frame_cnt < nof_slots) {
|
||||
if (get_samples(read_length, read_offset) == -1) {
|
||||
fprintf(stderr, "Error reading %d samples sf_start=%d\n", read_length, slot_start);
|
||||
break;
|
||||
}
|
||||
if (read_length) {
|
||||
frame_cnt++;
|
||||
INFO("\nFrame idx=%d\n\n", frame_idx);
|
||||
INFO("Correcting CFO=%.4f\n", cfo);
|
||||
nco_cexp_f_direct(&input_buffer[read_offset], -cfo/128, read_length);
|
||||
}
|
||||
switch(state) {
|
||||
case SYNC:
|
||||
INFO("State Sync, Slot idx=%d\n", frame_idx);
|
||||
idx = sync_run(&synch, input_buffer, read_offset);
|
||||
if (idx != -1) {
|
||||
idx -= 960;
|
||||
slot_start = read_offset + idx;
|
||||
read_length = idx;
|
||||
read_offset += FLEN;
|
||||
cell_id = sync_get_cell_id(&synch);
|
||||
cfo = sync_get_cfo(&synch);
|
||||
frame_idx = sync_get_slot_id(&synch)?1:0;
|
||||
state = MIB;
|
||||
if (mib_decoder_init(cell_id)) {
|
||||
fprintf(stderr, "Error initiating MIB decoder\n");
|
||||
exit(-1);
|
||||
}
|
||||
INFO("SYNC done, cell_id=%d slot_start=%d frame_idx=%d\n", cell_id, slot_start, frame_idx);
|
||||
} else {
|
||||
read_offset = FLEN;
|
||||
memcpy(input_buffer, &input_buffer[FLEN], FLEN * sizeof(cf_t));
|
||||
}
|
||||
break;
|
||||
case MIB:
|
||||
read_length = FLEN;
|
||||
read_offset = slot_start;
|
||||
INFO("State MIB, frame idx=%d\n", frame_idx);
|
||||
if (frame_idx == 0) {
|
||||
INFO("Trying to find MIB offset %d\n", slot_start);
|
||||
if (mib_decoder_run(&input_buffer[slot_start+FLEN/10], &mib)) {
|
||||
INFO("MIB detected attempt=%d\n", mib_attempts);
|
||||
state = DONE;
|
||||
} else {
|
||||
INFO("MIB not detected attempt=%d\n", mib_attempts);
|
||||
if (mib_attempts >= 4) {
|
||||
state = SYNC;
|
||||
}
|
||||
}
|
||||
mib_attempts++;
|
||||
}
|
||||
break;
|
||||
case DONE:
|
||||
INFO("State Done, Slot idx=%d\n", frame_idx);
|
||||
pbch_mib_fprint(stdout, &mib);
|
||||
printf("Done\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (read_length) {
|
||||
frame_idx++;
|
||||
if (frame_idx == 2) {
|
||||
frame_idx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sync_free(&synch);
|
||||
filesource_close(&fsrc);
|
||||
|
||||
free(input_buffer);
|
||||
|
||||
printf("Done\n");
|
||||
exit(0);
|
||||
}
|
@ -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)
|
@ -1,186 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lte.h"
|
||||
|
||||
char *input_file_name;
|
||||
int nof_slots=1;
|
||||
int cell_id = 0;
|
||||
int port_id = 0;
|
||||
int nof_prb = 6;
|
||||
lte_cp_t cp = CPNORM;
|
||||
int file_binary = 0;
|
||||
|
||||
int in_slot_length() {
|
||||
if (CP_ISNORM(cp)) {
|
||||
return SLOT_LEN_CPNORM(lte_symbol_sz(nof_prb));
|
||||
} else {
|
||||
return SLOT_LEN_CPEXT(lte_symbol_sz(nof_prb));
|
||||
}
|
||||
}
|
||||
|
||||
int slot_length() {
|
||||
return CP_NSYMB(cp)*lte_symbol_sz(nof_prb);
|
||||
}
|
||||
|
||||
|
||||
void usage(char *prog) {
|
||||
printf("Usage: %s [bncprev] -i input_file\n", prog);
|
||||
printf("\t-b input file is binary [Default no]\n");
|
||||
printf("\t-n number of slots [Default %d]\n", nof_slots);
|
||||
printf("\t-c cell_id [Default %d]\n", cell_id);
|
||||
printf("\t-p port_id [Default %d]\n", port_id);
|
||||
printf("\t-r nof_prb [Default %d]\n", nof_prb);
|
||||
printf("\t-e [extended cyclic prefix, Default normal]\n");
|
||||
printf("\t-v [set verbose to debug, default none]\n");
|
||||
}
|
||||
|
||||
void parse_args(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "bincprev")) != -1) {
|
||||
switch(opt) {
|
||||
case 'b':
|
||||
file_binary = 1;
|
||||
break;
|
||||
case 'i':
|
||||
input_file_name = argv[optind];
|
||||
break;
|
||||
case 'n':
|
||||
nof_slots = atoi(argv[optind]);
|
||||
break;
|
||||
case 'c':
|
||||
cell_id = atoi(argv[optind]);
|
||||
break;
|
||||
case 'p':
|
||||
port_id = atoi(argv[optind]);
|
||||
break;
|
||||
case 'r':
|
||||
nof_prb = atoi(argv[optind]);
|
||||
break;
|
||||
case 'e':
|
||||
cp = CPEXT;
|
||||
break;
|
||||
case 'v':
|
||||
PRINT_DEBUG;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
if (!input_file_name) {
|
||||
usage(argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
filesource_t fsrc;
|
||||
lte_fft_t fft;
|
||||
FILE *f = NULL;
|
||||
chest_t eq;
|
||||
int slot_cnt;
|
||||
cf_t *input = NULL;
|
||||
cf_t *outfft = NULL;
|
||||
cf_t *ce = NULL;
|
||||
int i;
|
||||
|
||||
if (argc < 3) {
|
||||
usage(argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
parse_args(argc,argv);
|
||||
|
||||
if (filesource_init(&fsrc, input_file_name, file_binary?COMPLEX_FLOAT_BIN:COMPLEX_FLOAT)) {
|
||||
fprintf(stderr, "Error opening file %s\n", input_file_name);
|
||||
goto do_exit;
|
||||
}
|
||||
f = fopen("output.m", "w");
|
||||
if (!f) {
|
||||
perror("fopen");
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
input = malloc(in_slot_length()*sizeof(cf_t));
|
||||
if (!input) {
|
||||
perror("malloc");
|
||||
goto do_exit;
|
||||
}
|
||||
outfft = malloc(slot_length()*sizeof(cf_t));
|
||||
if (!outfft) {
|
||||
perror("malloc");
|
||||
goto do_exit;
|
||||
}
|
||||
ce = malloc(nof_prb * RE_X_RB * CP_NSYMB(cp) * sizeof(cf_t));
|
||||
if (!ce) {
|
||||
perror("malloc");
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
if (lte_fft_init(&fft, cp, nof_prb)) {
|
||||
fprintf(stderr, "Error: initializing FFT\n");
|
||||
goto do_exit;
|
||||
}
|
||||
if (chest_init(&eq, LINEAR, cp, nof_prb, 1)) {
|
||||
fprintf(stderr, "Error initializing equalizer\n");
|
||||
goto do_exit;
|
||||
}
|
||||
if (chest_ref_LTEDL(&eq, cell_id)) {
|
||||
fprintf(stderr, "Error initializing reference signal\n");
|
||||
goto do_exit;
|
||||
}
|
||||
|
||||
bzero(input, sizeof(cf_t) * in_slot_length());
|
||||
bzero(outfft, sizeof(cf_t) * slot_length());
|
||||
|
||||
fprintf(f, "ce=zeros(%d, %d);\n", nof_slots * CP_NSYMB(cp), nof_prb * RE_X_RB);
|
||||
/* read all file or nof_slots */
|
||||
slot_cnt = 0;
|
||||
while (in_slot_length() == filesource_read(&fsrc, input, in_slot_length())
|
||||
&& (slot_cnt < nof_slots || nof_slots == -1)) {
|
||||
|
||||
fprintf(f, "infft=");
|
||||
vec_fprint_c(f, input, CP_NSYMB(cp) * 128);
|
||||
fprintf(f, ";\n");
|
||||
|
||||
lte_fft_run(&fft, input, outfft);
|
||||
|
||||
fprintf(f, "outfft=");
|
||||
vec_fprint_c(f, outfft, CP_NSYMB(cp) * nof_prb * RE_X_RB);
|
||||
fprintf(f, ";\n");
|
||||
|
||||
chest_ce_slot_port(&eq, outfft, ce, 0, 0);
|
||||
|
||||
chest_fprint(&eq, f, slot_cnt%20, 0);
|
||||
|
||||
for (i=0;i<CP_NSYMB(cp);i++) {
|
||||
fprintf(f, "ce(%d,:)=", slot_cnt * CP_NSYMB(cp) + i + 1);
|
||||
vec_fprint_c(f, &ce[i * nof_prb * RE_X_RB], nof_prb * RE_X_RB);
|
||||
}
|
||||
|
||||
slot_cnt++;
|
||||
}
|
||||
|
||||
do_exit:
|
||||
chest_free(&eq);
|
||||
lte_fft_free(&fft);
|
||||
if (ce) {
|
||||
free(ce);
|
||||
}
|
||||
if (outfft) {
|
||||
free(outfft);
|
||||
}
|
||||
if (input) {
|
||||
free(input);
|
||||
}
|
||||
if (f) {
|
||||
fclose(f);
|
||||
}
|
||||
filesource_close(&fsrc);
|
||||
|
||||
printf("Done processed %d slots\n", slot_cnt);
|
||||
exit(0);
|
||||
}
|
@ -0,0 +1,283 @@
|
||||
/**
|
||||
*
|
||||
* \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"
|
||||
|
||||
#ifndef DISABLE_UHD
|
||||
#include "cuhd.h"
|
||||
void *uhd;
|
||||
#endif
|
||||
|
||||
char *output_file_name = NULL;
|
||||
int nof_slots=-1;
|
||||
int cell_id = 1;
|
||||
int nof_prb = 6;
|
||||
char *uhd_args = "";
|
||||
|
||||
float uhd_amp=0.25, uhd_gain=10.0, uhd_freq=2400000000;
|
||||
|
||||
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 UHD_SAMP_FREQ 1920000
|
||||
|
||||
void usage(char *prog) {
|
||||
printf("Usage: %s [agmfoncvp]\n", prog);
|
||||
#ifndef DISABLE_UHD
|
||||
printf("\t-a UHD args [Default %s]\n", uhd_args);
|
||||
printf("\t-g UHD TX gain [Default %.2f dB]\n", uhd_gain);
|
||||
printf("\t-m UHD signal amplitude [Default %.2f]\n", uhd_amp);
|
||||
printf("\t-f UHD TX frequency [Default %.1f MHz]\n", uhd_freq/1000000);
|
||||
#else
|
||||
printf("\t UHD is disabled. CUHD library not available\n");
|
||||
#endif
|
||||
printf("\t-o output_file [Default USRP]\n");
|
||||
printf("\t-n number of frames [Default %d]\n", nof_slots);
|
||||
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, "agfmoncpv")) != -1) {
|
||||
switch(opt) {
|
||||
case 'a':
|
||||
uhd_args = argv[optind];
|
||||
break;
|
||||
case 'g':
|
||||
uhd_gain = atof(argv[optind]);
|
||||
break;
|
||||
case 'm':
|
||||
uhd_amp = atof(argv[optind]);
|
||||
break;
|
||||
case 'f':
|
||||
uhd_freq = atof(argv[optind]);
|
||||
break;
|
||||
case 'o':
|
||||
output_file_name = argv[optind];
|
||||
break;
|
||||
case 'n':
|
||||
nof_slots = 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);
|
||||
}
|
||||
}
|
||||
#ifdef DISABLE_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 {
|
||||
#ifndef DISABLE_UHD
|
||||
printf("Opening UHD device...\n");
|
||||
if (cuhd_open(uhd_args,&uhd)) {
|
||||
fprintf(stderr, "Error opening uhd\n");
|
||||
exit(-1);
|
||||
}
|
||||
#else
|
||||
printf("Error UHD not available. Select an output file\n");
|
||||
exit(-1);
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
#ifndef DISABLE_UHD
|
||||
cuhd_close(&uhd);
|
||||
#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];
|
||||
|
||||
|
||||
#ifdef DISABLE_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 = PHICH_NORM;
|
||||
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;
|
||||
}
|
||||
|
||||
#ifndef DISABLE_UHD
|
||||
if (!output_file_name) {
|
||||
printf("Set TX rate: %.2f MHz\n", cuhd_set_tx_srate(uhd, UHD_SAMP_FREQ)/1000000);
|
||||
printf("Set TX gain: %.1f dB\n", cuhd_set_tx_gain(uhd, uhd_gain));
|
||||
printf("Set TX freq: %.2f MHz\n", cuhd_set_tx_freq(uhd, uhd_freq)/1000000);
|
||||
}
|
||||
#endif
|
||||
|
||||
nf = 0;
|
||||
|
||||
while(nf<nof_slots || nof_slots == -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);
|
||||
usleep(5000);
|
||||
} else {
|
||||
#ifndef DISABLE_UHD
|
||||
vec_sc_prod_cfc(output_buffer, uhd_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,501 @@
|
||||
/**
|
||||
*
|
||||
* \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>
|
||||
#include <signal.h>
|
||||
|
||||
#include "lte.h"
|
||||
|
||||
#ifndef DISABLE_UHD
|
||||
#include "cuhd.h"
|
||||
void *uhd;
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_GRAPHICS
|
||||
#include "plot.h"
|
||||
plot_real_t poutfft;
|
||||
plot_complex_t pce;
|
||||
plot_scatter_t pscatrecv, pscatequal;
|
||||
#endif
|
||||
|
||||
#define MHZ 1000000
|
||||
#define SAMP_FREQ 1920000
|
||||
#define FLEN 9600
|
||||
#define FLEN_PERIOD 0.005
|
||||
|
||||
#define NOF_PORTS 2
|
||||
|
||||
float find_threshold = 30.0, track_threshold = 10.0;
|
||||
int max_track_lost = 20, nof_slots = -1;
|
||||
int track_len=300;
|
||||
char *input_file_name = NULL;
|
||||
int disable_plots = 0;
|
||||
|
||||
int go_exit=0;
|
||||
|
||||
float uhd_freq = 2600000000.0, uhd_gain = 20.0;
|
||||
char *uhd_args = "";
|
||||
|
||||
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;
|
||||
cfo_t cfocorr;
|
||||
|
||||
|
||||
enum sync_state {FIND, TRACK};
|
||||
|
||||
void usage(char *prog) {
|
||||
printf("Usage: %s [iagfndvp]\n", prog);
|
||||
printf("\t-i input_file [Default use USRP]\n");
|
||||
#ifndef DISABLE_UHD
|
||||
printf("\t-a UHD args [Default %s]\n", uhd_args);
|
||||
printf("\t-g UHD RX gain [Default %.2f dB]\n", uhd_gain);
|
||||
printf("\t-f UHD RX frequency [Default %.1f MHz]\n", uhd_freq/1000000);
|
||||
#else
|
||||
printf("\t UHD is disabled. CUHD library not available\n");
|
||||
#endif
|
||||
printf("\t-n nof_frames [Default %d]\n", nof_slots);
|
||||
printf("\t-p PSS threshold [Default %f]\n", find_threshold);
|
||||
#ifndef DISABLE_GRAPHICS
|
||||
printf("\t-d disable plots [Default enabled]\n");
|
||||
#else
|
||||
printf("\t plots are disabled. Graphics library not available\n");
|
||||
#endif
|
||||
printf("\t-v [set verbose to debug, default none]\n");
|
||||
}
|
||||
|
||||
void parse_args(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "iagfndvp")) != -1) {
|
||||
switch(opt) {
|
||||
case 'i':
|
||||
input_file_name = argv[optind];
|
||||
break;
|
||||
case 'a':
|
||||
uhd_args = argv[optind];
|
||||
break;
|
||||
case 'g':
|
||||
uhd_gain = atof(argv[optind]);
|
||||
break;
|
||||
case 'f':
|
||||
uhd_freq = atof(argv[optind]);
|
||||
break;
|
||||
case 'p':
|
||||
find_threshold = atof(argv[optind]);
|
||||
break;
|
||||
case 'n':
|
||||
nof_slots = atoi(argv[optind]);
|
||||
break;
|
||||
case 'd':
|
||||
disable_plots = 1;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef DISABLE_GRAPHICS
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int base_init(int frame_length) {
|
||||
int i;
|
||||
|
||||
#ifndef DISABLE_GRAPHICS
|
||||
if (!disable_plots) {
|
||||
init_plots();
|
||||
}
|
||||
#else
|
||||
printf("-- PLOTS are disabled. Graphics library not available --\n\n");
|
||||
#endif
|
||||
|
||||
if (input_file_name) {
|
||||
if (filesource_init(&fsrc, input_file_name, COMPLEX_FLOAT_BIN)) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/* open UHD device */
|
||||
#ifndef DISABLE_UHD
|
||||
printf("Opening UHD device...\n");
|
||||
if (cuhd_open(uhd_args,&uhd)) {
|
||||
fprintf(stderr, "Error opening uhd\n");
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
printf("Error UHD not available. Select an input file\n");
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
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 (cfo_init(&cfocorr, FLEN)) {
|
||||
fprintf(stderr, "Error initiating CFO\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lte_fft_init(&fft, CPNORM, 6)) {
|
||||
fprintf(stderr, "Error initializing FFT\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void base_free() {
|
||||
int i;
|
||||
|
||||
if (input_file_name) {
|
||||
filesource_free(&fsrc);
|
||||
} else {
|
||||
#ifndef DISABLE_UHD
|
||||
cuhd_close(uhd);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef DISABLE_GRAPHICS
|
||||
plot_exit();
|
||||
#endif
|
||||
|
||||
sync_free(&sfind);
|
||||
sync_free(&strack);
|
||||
lte_fft_free(&fft);
|
||||
chest_free(&chest);
|
||||
cfo_free(&cfocorr);
|
||||
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
|
||||
|
||||
#ifndef DISABLE_GRAPHICS
|
||||
float tmp[72*7];
|
||||
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);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void sigintHandler(int sig_num)
|
||||
{
|
||||
go_exit=1;
|
||||
}
|
||||
|
||||
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 n;
|
||||
int nof_found_mib = 0;
|
||||
float timeoffset = 0;
|
||||
|
||||
#ifdef DISABLE_UHD
|
||||
if (argc < 3) {
|
||||
usage(argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
parse_args(argc,argv);
|
||||
|
||||
if (base_init(FLEN)) {
|
||||
fprintf(stderr, "Error initializing memory\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
sync_pss_det_peak_to_avg(&sfind);
|
||||
sync_pss_det_peak_to_avg(&strack);
|
||||
|
||||
if (!input_file_name) {
|
||||
#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, uhd_gain);
|
||||
/* set uhd_freq */
|
||||
cuhd_set_rx_freq(uhd, (double) uhd_freq);
|
||||
cuhd_rx_wait_lo_locked(uhd);
|
||||
DEBUG("Set uhd_freq to %.3f MHz\n", (double) uhd_freq);
|
||||
|
||||
DEBUG("Starting receiver...\n",0);
|
||||
cuhd_start_rx_stream(uhd);
|
||||
#endif
|
||||
}
|
||||
|
||||
printf("\n --- Press Ctrl+C to exit --- \n");
|
||||
signal(SIGINT, sigintHandler);
|
||||
|
||||
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);
|
||||
|
||||
while(!go_exit && (frame_cnt < nof_slots || nof_slots==-1)) {
|
||||
INFO(" ----- RECEIVING %d SAMPLES ---- \n", FLEN);
|
||||
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 {
|
||||
#ifndef DISABLE_UHD
|
||||
cuhd_recv(uhd, input_buffer, FLEN, 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 */
|
||||
cell_id = sync_get_cell_id(&sfind);
|
||||
if (cell_id != -1) {
|
||||
frame_cnt = -1;
|
||||
last_found = 0;
|
||||
sync_set_threshold(&strack, track_threshold);
|
||||
sync_force_N_id_2(&strack, sync_get_N_id_2(&sfind));
|
||||
sync_force_cp(&strack, sync_get_cp(&sfind));
|
||||
mib_decoder_init(cell_id);
|
||||
nof_found_mib = 0;
|
||||
nslot = sync_get_slot_id(&sfind);
|
||||
nslot=(nslot+10)%20;
|
||||
cfo = 0;
|
||||
timeoffset = 0;
|
||||
printf("\n");
|
||||
state = TRACK;
|
||||
} else {
|
||||
printf("cellid=-1\n");
|
||||
}
|
||||
}
|
||||
if (verbose == VERBOSE_NONE) {
|
||||
printf("Finding PSS... 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);
|
||||
/* compute cumulative moving average time offset */
|
||||
timeoffset = (float) (track_idx-track_len + timeoffset * frame_cnt) / (frame_cnt + 1);
|
||||
last_found = frame_cnt;
|
||||
find_idx = (find_idx + track_idx - track_len)%FLEN;
|
||||
if (nslot != sync_get_slot_id(&strack)) {
|
||||
INFO("Expected slot %d but got %d\n", nslot, sync_get_slot_id(&strack));
|
||||
printf("\r\n");
|
||||
fflush(stdout);
|
||||
printf("\r\n");
|
||||
state = FIND;
|
||||
}
|
||||
} else {
|
||||
/* if sync not found, adjust time offset with the averaged value */
|
||||
find_idx = (find_idx + (int) timeoffset)%FLEN;
|
||||
}
|
||||
|
||||
/* if we missed too many PSS go back to FIND */
|
||||
if (frame_cnt - last_found > max_track_lost) {
|
||||
INFO("%d frames lost. Going back to FIND", frame_cnt - last_found);
|
||||
printf("\r\n");
|
||||
fflush(stdout);
|
||||
printf("\r\n");
|
||||
state = FIND;
|
||||
}
|
||||
|
||||
// Correct CFO
|
||||
INFO("Correcting CFO=%.4f\n", cfo);
|
||||
|
||||
cfo_correct(&cfocorr, input_buffer, -cfo/128);
|
||||
|
||||
if (nslot == 0 && find_idx + 960 < FLEN) {
|
||||
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);
|
||||
if (verbose == VERBOSE_NONE) {
|
||||
if (!nof_found_mib) {
|
||||
printf("\r\n");
|
||||
fflush(stdout);
|
||||
printf("\r\n");
|
||||
printf(" - Phy. CellId:\t%d\n", cell_id);
|
||||
pbch_mib_fprint(stdout, &mib);
|
||||
}
|
||||
}
|
||||
nof_found_mib++;
|
||||
} else {
|
||||
INFO("MIB not found attempt %d\n",frame_cnt);
|
||||
}
|
||||
if (frame_cnt) {
|
||||
printf("SFN: %4d, CFO: %+.4f KHz, SFO: %+.4f Khz, TimeOffset: %4d, Errors: %4d/%4d, ErrorRate: %.1e\r", mib.sfn,
|
||||
cfo*15, timeoffset/5, 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("\nBye\n");
|
||||
exit(0);
|
||||
}
|
||||
|
@ -1,168 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "lte.h"
|
||||
|
||||
typedef _Complex float cf_t;
|
||||
|
||||
int frame_length=1000, nof_slots=128;
|
||||
float ebno_db = 5.0;
|
||||
unsigned int seed=0;
|
||||
bool tail_biting = false;
|
||||
|
||||
char message[40] = {0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,1,1,0,1,0,0,0,0,1};
|
||||
|
||||
void usage(char *prog) {
|
||||
printf("Usage: %s [nl]\n", prog);
|
||||
printf("\t-n nof_frames [Default %d]\n", nof_slots);
|
||||
printf("\t-l frame_length [Default %d]\n", frame_length);
|
||||
printf("\t-e ebno in dB [Default %.2f dB]\n", ebno_db);
|
||||
printf("\t-s seed [Default 0=time]\n");
|
||||
printf("\t-t tail_bitting [Default %s]\n", tail_biting?"yes":"no");
|
||||
}
|
||||
|
||||
void parse_args(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "nlste")) != -1) {
|
||||
switch(opt) {
|
||||
case 'n':
|
||||
nof_slots = atoi(argv[optind]);
|
||||
break;
|
||||
case 'l':
|
||||
frame_length = atoi(argv[optind]);
|
||||
break;
|
||||
case 'e':
|
||||
ebno_db = atof(argv[optind]);
|
||||
break;
|
||||
case 's':
|
||||
seed = atoi(argv[optind]);
|
||||
break;
|
||||
case 't':
|
||||
tail_biting = true;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
viterbi_t dec;
|
||||
convcoder_t cod;
|
||||
modem_table_t modem;
|
||||
demod_soft_t demod;
|
||||
int frame_cnt;
|
||||
float *llr;
|
||||
char *data_tx, *data_rx, *symbols;
|
||||
cf_t *iq;
|
||||
int i;
|
||||
|
||||
parse_args(argc,argv);
|
||||
|
||||
if (!seed) {
|
||||
seed = time(NULL);
|
||||
}
|
||||
srand(seed);
|
||||
|
||||
int coded_length = 3 * (frame_length + ((tail_biting)?0:6));
|
||||
|
||||
printf("Convolutional Code 1/3 K=7 Test\n");
|
||||
printf(" Frame length: %d\n", frame_length);
|
||||
printf(" Codeword length: %d\n", coded_length);
|
||||
printf(" Tail bitting: %s\n", tail_biting?"yes":"no");
|
||||
printf(" EbNo: %.2f\n", ebno_db);
|
||||
|
||||
data_tx = malloc(frame_length * sizeof(char));
|
||||
if (!data_tx) {
|
||||
perror("malloc");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
data_rx = malloc(frame_length * sizeof(char));
|
||||
if (!data_rx) {
|
||||
perror("malloc");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
symbols = malloc(coded_length * sizeof(char));
|
||||
if (!symbols) {
|
||||
perror("malloc");
|
||||
exit(-1);
|
||||
}
|
||||
llr = malloc(coded_length * sizeof(float));
|
||||
if (!llr) {
|
||||
perror("malloc");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
iq = malloc(coded_length * sizeof(cf_t));
|
||||
if (!iq) {
|
||||
perror("malloc");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
cod.K = 7;
|
||||
cod.R = 3;
|
||||
cod.tail_biting = tail_biting;
|
||||
cod.framelength = frame_length;
|
||||
cod.poly[0] = 0x6D;
|
||||
cod.poly[1] = 0x4F;
|
||||
cod.poly[2] = 0x57;
|
||||
|
||||
float var = sqrt(pow(10,-ebno_db/10));
|
||||
|
||||
modem_table_init(&modem);
|
||||
modem_table_std(&modem, LTE_QPSK, true);
|
||||
demod_soft_init(&demod);
|
||||
demod_soft_table_set(&demod, &modem);
|
||||
demod_soft_alg_set(&demod, APPROX);
|
||||
demod_soft_sigma_set(&demod, var);
|
||||
|
||||
viterbi_init(&dec, viterbi_37, cod.poly, frame_length, tail_biting);
|
||||
|
||||
/* read all file or nof_frames */
|
||||
frame_cnt = 0;
|
||||
unsigned int errors=0;
|
||||
while (frame_cnt < nof_slots) {
|
||||
|
||||
/* generate data_tx */
|
||||
for (i=0;i<frame_length;i++) {
|
||||
data_tx[i] = message[i];
|
||||
}
|
||||
|
||||
convcoder_encode(&cod, data_tx, symbols);
|
||||
|
||||
bit_fprint(stdout, symbols, 120);
|
||||
|
||||
mod_modulate(&modem, symbols, iq, coded_length);
|
||||
|
||||
if (ebno_db < 100.0) {
|
||||
ch_awgn(iq, iq, var, coded_length/2);
|
||||
}
|
||||
|
||||
demod_soft_demodulate(&demod, iq, llr, coded_length/2);
|
||||
|
||||
viterbi_decode(&dec, llr, data_rx);
|
||||
|
||||
errors += bit_diff(data_tx, data_rx, frame_length);
|
||||
frame_cnt++;
|
||||
}
|
||||
|
||||
printf("BER:\t%g\t%u errors\n", (float) errors/(frame_cnt*frame_length), errors);
|
||||
|
||||
viterbi_free(&dec);
|
||||
|
||||
free(data_tx);
|
||||
free(symbols);
|
||||
free(iq);
|
||||
free(llr);
|
||||
free(data_rx);
|
||||
|
||||
printf("Done\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,94 @@
|
||||
#
|
||||
# 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)
|
||||
|
||||
|
||||
|
||||
########################################################################
|
||||
# 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})
|
||||
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../)
|
||||
|
||||
IF(QWT_MAJOR_VERSION LESS 6)
|
||||
MESSAGE(STATUS "QWT6 is required.")
|
||||
ENDIF(QWT_MAJOR_VERSION LESS 6)
|
||||
|
||||
IF(QT4_FOUND AND QWT_FOUND AND QWT_MAJOR_VERSION EQUAL 6)
|
||||
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 ${Boost_INCLUDE_DIRS})
|
||||
|
||||
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)
|
||||
|
||||
|
||||
ADD_SUBDIRECTORY(complexplot/test)
|
||||
ADD_SUBDIRECTORY(realplot/test)
|
||||
ADD_SUBDIRECTORY(scatterplot/test)
|
||||
ADD_SUBDIRECTORY(waterfallplot/test)
|
||||
|
||||
MESSAGE(STATUS " GRAPHICS library will be installed.")
|
||||
|
||||
|
||||
ELSE(QT4_FOUND AND QWT_FOUND AND AND QWT_MAJOR_VERSION EQUAL 6)
|
||||
|
||||
MESSAGE(STATUS " QT4 or Qwt6 not found. GRAPHICS library is not generated")
|
||||
|
||||
ENDIF(QT4_FOUND AND QWT_FOUND AND QWT_MAJOR_VERSION EQUAL 6)
|
||||
|
||||
|
||||
|
||||
|
@ -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,90 @@
|
||||
#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 <assert.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)
|
||||
{
|
||||
assert(n == nData_);
|
||||
|
||||
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,195 @@
|
||||
#include "ComplexWidget.h"
|
||||
#include "Lineplot.h"
|
||||
#include "Events.h"
|
||||
|
||||
#include <qlayout.h>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
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>
|
||||
|
||||
|
||||
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,31 @@
|
||||
#
|
||||
# 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
|
||||
INCLUDE_DIRECTORIES(..)
|
||||
ADD_EXECUTABLE(complexplot_test complexplot_test.cpp)
|
||||
TARGET_LINK_LIBRARIES(complexplot_test pthread graphics)
|
||||
ADD_TEST(complexplot_test complexplot_test)
|
||||
|
@ -0,0 +1,144 @@
|
||||
/**
|
||||
* \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.
|
||||
*/
|
||||
|
||||
#include "Complexplot.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <qapplication.h>
|
||||
#include <cstdlib>
|
||||
#include <complex>
|
||||
#include <vector>
|
||||
|
||||
#define PI 3.14159265358979323846
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef vector<complex<float> > FloatVec;
|
||||
|
||||
void *threadMain1(void *arg) {
|
||||
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);
|
||||
usleep(1000);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *threadMain2(void *arg) {
|
||||
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);
|
||||
usleep(1000);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *threadMain3(void *arg) {
|
||||
|
||||
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());
|
||||
usleep(1000);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int argc2 = 1;
|
||||
char* argv2[] = { const_cast<char *>("Compleplot_Basic_Test"), NULL };
|
||||
QApplication a(argc2, argv2);
|
||||
pthread_t threads[3];
|
||||
int i;
|
||||
|
||||
if (pthread_create(&threads[0], NULL, threadMain1, NULL)) {
|
||||
perror("pthread_create");
|
||||
exit(-1);
|
||||
}
|
||||
if (pthread_create(&threads[1], NULL, threadMain2, NULL)) {
|
||||
perror("pthread_create");
|
||||
exit(-1);
|
||||
}
|
||||
if (pthread_create(&threads[2], NULL, threadMain3, NULL)) {
|
||||
perror("pthread_create");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
qApp->exec();
|
||||
|
||||
for (i=0;i<3;i++) {
|
||||
pthread_join(threads[i], NULL);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
@ -0,0 +1,100 @@
|
||||
#include "RealWidget.h"
|
||||
#include "Lineplot.h"
|
||||
#include "Events.h"
|
||||
|
||||
#include <qlayout.h>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
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,31 @@
|
||||
#
|
||||
# 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
|
||||
INCLUDE_DIRECTORIES(..)
|
||||
ADD_EXECUTABLE(realplot_test realplot_test.cpp)
|
||||
TARGET_LINK_LIBRARIES(realplot_test pthread graphics)
|
||||
ADD_TEST(realplot_test realplot_test)
|
||||
|
@ -0,0 +1,123 @@
|
||||
/**
|
||||
* \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.
|
||||
*/
|
||||
|
||||
#include "Realplot.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <qapplication.h>
|
||||
#include <cstdlib>
|
||||
#include <complex>
|
||||
#include <vector>
|
||||
|
||||
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(void *arg) {
|
||||
Realplot plot;
|
||||
|
||||
float data[1024];
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
getPoints(data, 504);
|
||||
plot.setNewData(data, 504);
|
||||
usleep(5000);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *threadMain2(void *arg) {
|
||||
Realplot plot;
|
||||
double data[1024];
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
getPoints(data, 504);
|
||||
plot.setNewData(data, 504);
|
||||
usleep(5000);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *threadMain3(void *arg) {
|
||||
Realplot plot;
|
||||
FloatVec v(1024);
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
getPoints(v.begin(), v.end());
|
||||
plot.setNewData(v.begin(), v.end());
|
||||
usleep(5000);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int argc2 = 1;
|
||||
char* argv2[] = { const_cast<char *>("Realplot_Basic_Test"), NULL };
|
||||
QApplication a(argc2, argv2);
|
||||
pthread_t threads[3];
|
||||
int i;
|
||||
|
||||
if (pthread_create(&threads[0], NULL, threadMain1, NULL)) {
|
||||
perror("pthread_create");
|
||||
exit(-1);
|
||||
}
|
||||
if (pthread_create(&threads[1], NULL, threadMain2, NULL)) {
|
||||
perror("pthread_create");
|
||||
exit(-1);
|
||||
}
|
||||
if (pthread_create(&threads[2], NULL, threadMain3, NULL)) {
|
||||
perror("pthread_create");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
qApp->exec();
|
||||
|
||||
for (i=0;i<3;i++) {
|
||||
pthread_join(threads[i], NULL);
|
||||
}
|
||||
exit(0);
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
#include "ScatterWidget.h"
|
||||
#include "Pointplot.h"
|
||||
#include "Events.h"
|
||||
|
||||
#include <qlayout.h>
|
||||
#include <algorithm>
|
||||
|
||||
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>
|
||||
|
||||
|
||||
|
||||
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,30 @@
|
||||
#
|
||||
# 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
|
||||
########################################################################
|
||||
INCLUDE_DIRECTORIES(..)
|
||||
ADD_EXECUTABLE(scatterplot_test scatterplot_test.cpp)
|
||||
TARGET_LINK_LIBRARIES(scatterplot_test pthread graphics)
|
||||
ADD_TEST(scatterplot_test scatterplot_test)
|
||||
|
@ -0,0 +1,126 @@
|
||||
/**
|
||||
* \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.
|
||||
*/
|
||||
|
||||
#include "Scatterplot.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <qapplication.h>
|
||||
#include <cstdlib>
|
||||
#include <complex>
|
||||
#include <vector>
|
||||
|
||||
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(void *arg) {
|
||||
Scatterplot plot;
|
||||
std::complex<float> data[1024];
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
getPoints(data, 1024);
|
||||
plot.setNewData(data, 1024);
|
||||
usleep(100000);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *threadMain2(void *arg) {
|
||||
Scatterplot plot;
|
||||
std::complex<double> data[1024];
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
getPoints(data, 1024);
|
||||
plot.setNewData(data, 1024);
|
||||
usleep(100000);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *threadMain3(void *arg) {
|
||||
Scatterplot plot;
|
||||
CplxVec v(1024);
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
getPoints(v.begin(), v.end());
|
||||
plot.setNewData(v.begin(), v.end());
|
||||
usleep(100000);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int argc2 = 1;
|
||||
char* argv2[] = { const_cast<char *>("Scatterplot_Basic_Test"), NULL };
|
||||
QApplication a(argc2, argv2);
|
||||
pthread_t threads[3];
|
||||
int i;
|
||||
|
||||
if (pthread_create(&threads[0], NULL, threadMain1, NULL)) {
|
||||
perror("pthread_create");
|
||||
exit(-1);
|
||||
}
|
||||
if (pthread_create(&threads[1], NULL, threadMain2, NULL)) {
|
||||
perror("pthread_create");
|
||||
exit(-1);
|
||||
}
|
||||
if (pthread_create(&threads[2], NULL, threadMain3, NULL)) {
|
||||
perror("pthread_create");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
qApp->exec();
|
||||
|
||||
for (i=0;i<3;i++) {
|
||||
pthread_join(threads[i], NULL);
|
||||
}
|
||||
exit(0);
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
#include "WaterfallWidget.h"
|
||||
#include "Spectrogramplot.h"
|
||||
#include "Lineplot.h"
|
||||
#include "Events.h"
|
||||
|
||||
#include <qlayout.h>
|
||||
#include <qpushbutton.h>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
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,127 @@
|
||||
/**
|
||||
* \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.
|
||||
*/
|
||||
|
||||
#include "Waterfallplot.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <qapplication.h>
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
|
||||
#define PI 3.14159265358979323846
|
||||
|
||||
using namespace std;
|
||||
|
||||
void *threadMain1(void *arg) {
|
||||
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);
|
||||
usleep(1000);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *threadMain2(void *arg) {
|
||||
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);
|
||||
usleep(1000);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *threadMain3(void *arg) {
|
||||
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);
|
||||
usleep(1000);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int argc2 = 1;
|
||||
char* argv2[] = { const_cast<char *>("Waterfallplot_Init_Test"), NULL };
|
||||
QApplication a(argc2, argv2);
|
||||
pthread_t threads[3];
|
||||
int i;
|
||||
|
||||
if (pthread_create(&threads[0], NULL, threadMain1, NULL)) {
|
||||
perror("pthread_create");
|
||||
exit(-1);
|
||||
}
|
||||
if (pthread_create(&threads[1], NULL, threadMain2, NULL)) {
|
||||
perror("pthread_create");
|
||||
exit(-1);
|
||||
}
|
||||
if (pthread_create(&threads[2], NULL, threadMain3, NULL)) {
|
||||
perror("pthread_create");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
qApp->exec();
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
pthread_join(threads[i], NULL);
|
||||
}
|
||||
exit(0);
|
||||
|
||||
}
|
@ -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,65 +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 SCRAMBLING_
|
||||
#define SCRAMBLING_
|
||||
|
||||
#include "lte/sequence.h"
|
||||
#include "lte/base.h"
|
||||
|
||||
/* Scrambling has no state */
|
||||
void scrambling_bit(sequence_t *s, char *data);
|
||||
void scrambling_float(sequence_t *s, float *data);
|
||||
int scrambling_float_offset(sequence_t *s, float *data, int offset, int len);
|
||||
|
||||
|
||||
/* High-level API */
|
||||
|
||||
/* channel integer values */
|
||||
#define PDSCH 0 /* also PUSCH */
|
||||
#define PCFICH 1
|
||||
#define PDCCH 2
|
||||
#define PBCH 3
|
||||
#define PMCH 4
|
||||
#define PUCCH 5
|
||||
|
||||
typedef struct {
|
||||
sequence_t seq[NSUBFRAMES_X_FRAME];
|
||||
}scrambling_t;
|
||||
|
||||
typedef struct {
|
||||
scrambling_t obj;
|
||||
struct scrambling_init {
|
||||
int hard;
|
||||
int q;
|
||||
int cell_id;
|
||||
int nrnti;
|
||||
int nMBSFN;
|
||||
int channel;
|
||||
int nof_symbols; // 7 normal 6 extended
|
||||
} init;
|
||||
void *input; // input type may be char or float depending on hard
|
||||
int in_len;
|
||||
struct scrambling_ctrl_in {
|
||||
int subframe;
|
||||
} ctrl_in;
|
||||
void *output;
|
||||
int out_len;
|
||||
}scrambling_hl;
|
||||
|
||||
#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 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,56 +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 SYNC_
|
||||
#define SYNC_
|
||||
|
||||
#include "pss.h"
|
||||
#include "sss.h"
|
||||
#include "sfo.h"
|
||||
|
||||
enum sync_pss_det { ABSOLUTE, PEAK_MEAN};
|
||||
|
||||
typedef struct {
|
||||
pss_synch_t pss[3]; // One for each N_id_2
|
||||
sss_synch_t sss[3]; // One for each N_id_2
|
||||
enum sync_pss_det pss_mode;
|
||||
float threshold;
|
||||
float peak_to_avg;
|
||||
int force_N_id_2;
|
||||
int N_id_2;
|
||||
int N_id_1;
|
||||
int slot_id;
|
||||
float cfo;
|
||||
}sync_t;
|
||||
|
||||
int sync_run(sync_t *q, cf_t *input, int read_offset);
|
||||
float sync_get_cfo(sync_t *q);
|
||||
void sync_pss_det_absolute(sync_t *q);
|
||||
void sync_pss_det_peakmean(sync_t *q);
|
||||
void sync_force_N_id_2(sync_t *q, int force_N_id_2);
|
||||
int sync_get_slot_id(sync_t *q);
|
||||
float sync_get_peak_to_avg(sync_t *q);
|
||||
int sync_get_N_id_2(sync_t *q);
|
||||
int sync_get_N_id_1(sync_t *q);
|
||||
int sync_get_cell_id(sync_t *q);
|
||||
void sync_set_threshold(sync_t *q, float threshold);
|
||||
int sync_init(sync_t *q, int frame_size);
|
||||
void sync_free(sync_t *q);
|
||||
|
||||
#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
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue