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})
|
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
||||||
message(FATAL_ERROR "Prevented in-tree build. This is bad practice.")
|
message(FATAL_ERROR "Prevented in-tree build. This is bad practice.")
|
||||||
endif(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
endif(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
||||||
|
|
||||||
cmake_minimum_required (VERSION 2.6)
|
|
||||||
project (osldlib)
|
|
||||||
|
|
||||||
|
|
||||||
# The version number.
|
########################################################################
|
||||||
set (OSLDLIB_VERSION_MAJOR 0)
|
# Project setup
|
||||||
set (OSLDLIB_VERSION_MINOR 0)
|
########################################################################
|
||||||
|
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})
|
ENDMACRO (APPEND_INTERNAL_LIST)
|
||||||
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)
|
|
||||||
|
|
||||||
option(DEBUG "Compiles with debugging symbols and no optimizations" OFF)
|
|
||||||
|
|
||||||
if(DEBUG)
|
########################################################################
|
||||||
message("-- Configuring debugging CFLAGS")
|
# Print summary
|
||||||
set(CFDEB "-O0 -g -rdynamic")
|
########################################################################
|
||||||
else()
|
MESSAGE(STATUS "Using install prefix: ${CMAKE_INSTALL_PREFIX}")
|
||||||
set(CFDEB "-O2")
|
MESSAGE(STATUS "Building for version: ${VERSION}")
|
||||||
endif()
|
|
||||||
|
|
||||||
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(lte)
|
||||||
add_subdirectory(lib)
|
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})
|
|
||||||
|
|
||||||
find_package(UHD)
|
|
||||||
|
|
||||||
|
add_executable(ll_example ll_example.c)
|
||||||
|
target_link_libraries(ll_example lte)
|
||||||
|
|
||||||
set(LIBRARIES osld m ${FFTWS_LIBRARIES})
|
|
||||||
|
|
||||||
|
#################################################################
|
||||||
|
# Applications
|
||||||
|
#################################################################
|
||||||
|
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include)
|
add_executable(synch_file synch_file.c)
|
||||||
|
target_link_libraries(synch_file lte)
|
||||||
|
|
||||||
add_executable(hl_example hl_example.c)
|
|
||||||
target_link_libraries(hl_example ${LIBRARIES})
|
|
||||||
|
|
||||||
add_executable(ll_example ll_example.c)
|
#################################################################
|
||||||
target_link_libraries(ll_example ${LIBRARIES})
|
# Check if UHD C-API and Graphics library are available
|
||||||
|
#################################################################
|
||||||
|
|
||||||
add_executable(synch_test synch_test.c)
|
LIST(FIND OPTIONAL_LIBS cuhd CUHD_FIND)
|
||||||
target_link_libraries(synch_test ${LIBRARIES})
|
LIST(FIND OPTIONAL_LIBS graphics GRAPHICS_FIND)
|
||||||
|
|
||||||
add_executable(equalizer_test equalizer_test.c)
|
#################################################################
|
||||||
target_link_libraries(equalizer_test ${LIBRARIES})
|
# These two can be compiled without UHD or graphics support
|
||||||
|
#################################################################
|
||||||
|
|
||||||
add_executable(viterbi_test viterbi_test.c)
|
add_executable(pbch_ue pbch_ue.c)
|
||||||
target_link_libraries(viterbi_test ${LIBRARIES})
|
target_link_libraries(pbch_ue lte)
|
||||||
|
|
||||||
add_executable(cell_search cell_search.c)
|
add_executable(pbch_enodeb pbch_enodeb.c)
|
||||||
target_link_libraries(cell_search ${LIBRARIES})
|
target_link_libraries(pbch_enodeb lte)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
include_directories(${UHD_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/../uhd)
|
IF(${GRAPHICS_FIND} EQUAL -1)
|
||||||
add_executable(rssi_scan_usrp rssi_scan_usrp.c ../uhd/uhd_imp.cpp ../uhd/uhd_utils.c)
|
SET_TARGET_PROPERTIES(pbch_ue PROPERTIES COMPILE_DEFINITIONS "DISABLE_GRAPHICS")
|
||||||
target_link_libraries(rssi_scan_usrp ${LIBRARIES} ${UHD_LIBRARIES})
|
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)
|
||||||
|
|
||||||
|
|
||||||
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})
|
|
||||||
|
|
||||||
|
#################################################################
|
||||||
|
# These examples need the UHD driver
|
||||||
|
#################################################################
|
||||||
|
|
||||||
include_directories(${UHD_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/../uhd)
|
IF(${CUHD_FIND} GREATER -1)
|
||||||
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_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 )
|
||||||
|
|
||||||
|
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