forked from sdr/gr-osmosdr
Compare commits
31 Commits
Author | SHA1 | Date |
---|---|---|
Robert Ghilduta | 821fdb3822 | |
Robert Ghilduta | 038a26501c | |
Robert Ghilduta | 95b1025b01 | |
Robert Ghilduta | bfdc4d917c | |
Robert Ghilduta | 34daf86ec3 | |
Ryan Tucker | a343cc208b | |
Robert Ghilduta | f6a8992856 | |
Eric Wild | 6a22db7568 | |
Eric Wild | 6b11b02947 | |
Eric Wild | a309841752 | |
Eric Wild | 09e72004fe | |
Eric Wild | e13c2e4e1c | |
Vadim Yanitskiy | 9c58e8a991 | |
Ron Economos | a100eb024c | |
Ron Economos | ba755e113e | |
Eric Wild | 7e955ad284 | |
Eric Wild | 64781cc652 | |
Clayton Smith | c7012949e1 | |
Clayton Smith | 1f724162e1 | |
Matt Mills | f88dc7df2f | |
Matt Mills | 0d727b3ef8 | |
Clayton Smith | 159885f9e6 | |
Gwenhael Goavec-Merou | cffef690f2 | |
Clayton Smith | c3187ab875 | |
Clayton Smith | bc629b03fe | |
Adrian Chadd | 9b386707d8 | |
Csaba Sipos | dc82ffd1f8 | |
Clayton Smith | fe03d83703 | |
Clayton Smith | 2d504bde50 | |
Clayton Smith | e5bee0820f | |
Eric Wild | 90c3d5b555 |
|
@ -0,0 +1,4 @@
|
|||
/.vscode/*
|
||||
/build/*
|
||||
*.pyc
|
||||
*.pyo
|
|
@ -21,8 +21,8 @@
|
|||
# Project setup
|
||||
########################################################################
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
include(GNUInstallDirs)
|
||||
project(gr-osmosdr CXX C)
|
||||
include(GNUInstallDirs)
|
||||
enable_testing()
|
||||
|
||||
#policy setup
|
||||
|
@ -41,7 +41,8 @@ set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
|
|||
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules)
|
||||
|
||||
# Find GNURadio (pmt and runtime are core, always included)
|
||||
find_package(Gnuradio "3.8" REQUIRED COMPONENTS blocks fft filter)
|
||||
include(FindPkgConfig)
|
||||
find_package(Gnuradio "3.9" REQUIRED COMPONENTS blocks fft filter)
|
||||
|
||||
# Set the version information here
|
||||
set(VERSION_MAJOR 0)
|
||||
|
@ -62,15 +63,7 @@ if((CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR
|
|||
add_definitions(-fvisibility-inlines-hidden)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
else()
|
||||
message(WARNING "C++ standard could not be set because compiler is not GNU, Clang or MSVC.")
|
||||
endif()
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
# Misc options
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR
|
||||
|
@ -116,6 +109,11 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
|||
add_definitions(/arch:AVX)
|
||||
add_definitions(-DUSE_AVX)
|
||||
endif()
|
||||
# boost feels like using lib pragmas to link to libs,
|
||||
# but the boost libs might not even be in the (default) lib search path
|
||||
add_definitions(-DBOOST_ALL_NO_LIB)
|
||||
# macro turns std::min into errors...
|
||||
add_definitions(-DNOMINMAX)
|
||||
endif()
|
||||
|
||||
########################################################################
|
||||
|
@ -165,9 +163,7 @@ message (STATUS " Found Volk: ${Volk_FOUND}")
|
|||
# Hardware drivers
|
||||
####################
|
||||
|
||||
#find_package(LibOsmoSDR)
|
||||
find_package(LibRTLSDR)
|
||||
#find_package(LibMiriSDR)
|
||||
if(ENABLE_NONFREE)
|
||||
find_package(LibSDRplay)
|
||||
endif(ENABLE_NONFREE)
|
||||
|
@ -175,29 +171,21 @@ find_package(LibHackRF)
|
|||
find_package(LibAIRSPY)
|
||||
find_package(LibAIRSPYHF)
|
||||
find_package(LibbladeRF)
|
||||
find_package(GnuradioFCDPP)
|
||||
find_package(GnuradioFuncube)
|
||||
find_package(SoapySDR NO_MODULE)
|
||||
find_package(LibFreeSRP)
|
||||
find_package(LibXTRX)
|
||||
find_package(Doxygen)
|
||||
|
||||
# Python
|
||||
##########
|
||||
|
||||
find_package(PythonLibs 3)
|
||||
find_package(SWIG)
|
||||
|
||||
if(SWIG_FOUND)
|
||||
message(STATUS "Minimum SWIG version required is 1.3.31")
|
||||
set(SWIG_VERSION_CHECK FALSE)
|
||||
if("${SWIG_VERSION}" VERSION_GREATER "1.3.30")
|
||||
set(SWIG_VERSION_CHECK TRUE)
|
||||
endif()
|
||||
endif(SWIG_FOUND)
|
||||
find_package(pybind11)
|
||||
|
||||
GR_REGISTER_COMPONENT("Python support" ENABLE_PYTHON
|
||||
PYTHONLIBS_FOUND
|
||||
SWIG_FOUND
|
||||
SWIG_VERSION_CHECK
|
||||
pybind11_FOUND
|
||||
)
|
||||
|
||||
########################################################################
|
||||
|
@ -265,7 +253,6 @@ add_custom_target(uninstall
|
|||
add_subdirectory(include/osmosdr)
|
||||
add_subdirectory(lib)
|
||||
if(ENABLE_PYTHON)
|
||||
add_subdirectory(swig)
|
||||
add_subdirectory(python)
|
||||
add_subdirectory(grc)
|
||||
add_subdirectory(apps)
|
||||
|
|
8
README
8
README
|
@ -1,12 +1,9 @@
|
|||
While primarily being developed for the OsmoSDR hardware, this block
|
||||
as well supports:
|
||||
|
||||
* FUNcube Dongle through libgnuradio-fcd
|
||||
* FUNcube Dongle Pro+ through gr-fcdproplus
|
||||
* sysmocom OsmoSDR Devices through libosmosdr
|
||||
* FUNcube Dongle / Pro+ through gr-funcube
|
||||
* RTL2832U based DVB-T dongles through librtlsdr
|
||||
* RTL-TCP spectrum server (see librtlsdr project)
|
||||
* MSi2500 based DVB-T dongles through libmirisdr
|
||||
* SDRplay RSP through SDRplay API library
|
||||
* gnuradio .cfile input through libgnuradio-blocks
|
||||
* RFSPACE SDR-IQ, SDR-IP, NetSDR (incl. X2 option)
|
||||
|
@ -15,7 +12,8 @@ as well supports:
|
|||
* Great Scott Gadgets HackRF through libhackrf
|
||||
* Nuand LLC bladeRF through libbladeRF library
|
||||
* Ettus USRP Devices through Ettus UHD library
|
||||
* Fairwaves UmTRX through Fairwaves' fork of UHD
|
||||
* Fairwaves UmTRX through Fairwaves' module for UHD
|
||||
* Fairwaves XTRX through libxtrx
|
||||
* Red Pitaya SDR transceiver (http://bazaar.redpitaya.com)
|
||||
* FreeSRP through libfreesrp
|
||||
|
||||
|
|
|
@ -30,6 +30,6 @@ GR_PYTHON_INSTALL(
|
|||
osmocom_fft
|
||||
# osmocom_siggen
|
||||
osmocom_siggen_nogui
|
||||
osmocom_spectrum_sense
|
||||
# osmocom_spectrum_sense
|
||||
DESTINATION ${GR_RUNTIME_DIR}
|
||||
)
|
||||
|
|
|
@ -24,7 +24,7 @@ import osmosdr
|
|||
from gnuradio import blocks
|
||||
from gnuradio import gr
|
||||
from gnuradio import eng_notation
|
||||
from gnuradio.filter import firdes
|
||||
from gnuradio.fft import window
|
||||
from gnuradio.eng_option import eng_option
|
||||
from optparse import OptionParser
|
||||
from functools import partial
|
||||
|
@ -238,16 +238,19 @@ class app_top_block(gr.top_block, Qt.QMainWindow):
|
|||
self.iq_balance_mag = 0
|
||||
self.iq_balance_pha = 0
|
||||
|
||||
# see https://github.com/gnuradio/gnuradio/issues/5175 - 3.9 has a backport of pyqwidget, but 3.10 does not.
|
||||
check_qwidget = lambda : self.scope.pyqwidget() if "pyqwidget" in dir(self.scope) else self.scope.qwidget()
|
||||
|
||||
if options.fosphor:
|
||||
from gnuradio import fosphor
|
||||
self.scope = fosphor.qt_sink_c()
|
||||
self.scope.set_frequency_range(0, input_rate)
|
||||
self.scope_win = sip.wrapinstance(self.scope.pyqwidget(), Qt.QWidget)
|
||||
self.scope_win = sip.wrapinstance(check_qwidget(), Qt.QWidget)
|
||||
self.scope_win.setMinimumSize(800, 300)
|
||||
elif options.waterfall:
|
||||
self.scope = qtgui.waterfall_sink_c(
|
||||
options.fft_size,
|
||||
wintype=firdes.WIN_BLACKMAN_hARRIS,
|
||||
wintype=window.WIN_BLACKMAN_hARRIS,
|
||||
fc=0,
|
||||
bw=input_rate,
|
||||
name="",
|
||||
|
@ -256,7 +259,7 @@ class app_top_block(gr.top_block, Qt.QMainWindow):
|
|||
self.scope.enable_grid(False)
|
||||
self.scope.enable_axis_labels(True)
|
||||
self.scope.set_intensity_range(-100, 20)
|
||||
self.scope_win = sip.wrapinstance(self.scope.pyqwidget(), Qt.QWidget)
|
||||
self.scope_win = sip.wrapinstance(check_qwidget(), Qt.QWidget)
|
||||
self.scope_win.setMinimumSize(800, 420)
|
||||
|
||||
elif options.oscilloscope:
|
||||
|
@ -266,13 +269,13 @@ class app_top_block(gr.top_block, Qt.QMainWindow):
|
|||
name="",
|
||||
nconnections=1
|
||||
)
|
||||
self.scope_win = sip.wrapinstance(self.scope.pyqwidget(), Qt.QWidget)
|
||||
self.scope_win = sip.wrapinstance(check_qwidget(), Qt.QWidget)
|
||||
self.scope_win.setMinimumSize(800, 600)
|
||||
|
||||
elif options.qtgui:
|
||||
self.scope = qtgui.sink_c(
|
||||
options.fft_size,
|
||||
wintype=firdes.WIN_BLACKMAN_hARRIS,
|
||||
wintype=window.WIN_BLACKMAN_hARRIS,
|
||||
fc=0,
|
||||
bw=input_rate,
|
||||
name="",
|
||||
|
@ -281,20 +284,20 @@ class app_top_block(gr.top_block, Qt.QMainWindow):
|
|||
plottime=True,
|
||||
plotconst=True
|
||||
)
|
||||
self.scope_win = sip.wrapinstance(self.scope.pyqwidget(), Qt.QWidget)
|
||||
self.scope_win = sip.wrapinstance(check_qwidget(), Qt.QWidget)
|
||||
self.scope.set_update_time(1.0/10)
|
||||
self.scope_win.setMinimumSize(800, 600)
|
||||
|
||||
else:
|
||||
self.scope = qtgui.freq_sink_c(
|
||||
fftsize=options.fft_size,
|
||||
wintype=firdes.WIN_BLACKMAN_hARRIS,
|
||||
wintype=window.WIN_BLACKMAN_hARRIS,
|
||||
fc=0,
|
||||
bw=input_rate,
|
||||
name="",
|
||||
nconnections=1
|
||||
)
|
||||
self.scope_win = sip.wrapinstance(self.scope.pyqwidget(), Qt.QWidget)
|
||||
self.scope_win = sip.wrapinstance(check_qwidget(), Qt.QWidget)
|
||||
self.scope.disable_legend()
|
||||
self.scope_win.setMinimumSize(800, 420)
|
||||
|
||||
|
|
|
@ -483,7 +483,7 @@ def main():
|
|||
app.MainLoop()
|
||||
|
||||
except RuntimeError, e:
|
||||
print e
|
||||
print(e)
|
||||
sys.exit(1)
|
||||
|
||||
# Make sure to create the top block (tb) within a function: That code
|
||||
|
|
|
@ -46,7 +46,7 @@ from gnuradio import blocks
|
|||
from gnuradio import filter
|
||||
from gnuradio import analog
|
||||
from gnuradio import digital
|
||||
from gnuradio import gr, gru, eng_notation
|
||||
from gnuradio import gr, eng_notation
|
||||
from gnuradio.gr.pubsub import pubsub
|
||||
from gnuradio.eng_option import eng_option
|
||||
from optparse import OptionParser
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
if(NOT GNURADIO_FCDPP_FOUND)
|
||||
pkg_check_modules (GNURADIO_FCDPP_PKG libgnuradio-fcdproplus)
|
||||
find_path(GNURADIO_FCDPP_INCLUDE_DIRS NAMES fcdproplus/api.h
|
||||
PATHS
|
||||
${GNURADIO_FCDPP_PKG_INCLUDE_DIRS}
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
find_library(GNURADIO_FCDPP_LIBRARIES NAMES gnuradio-fcdproplus
|
||||
PATHS
|
||||
${GNURADIO_FCDPP_PKG_LIBRARY_DIRS}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
)
|
||||
|
||||
if(GNURADIO_FCDPP_INCLUDE_DIRS AND GNURADIO_FCDPP_LIBRARIES)
|
||||
set(GNURADIO_FCDPP_FOUND TRUE CACHE INTERNAL "gnuradio-fcdproplus found")
|
||||
message(STATUS "Found gnuradio-fcdproplus: ${GNURADIO_FCDPP_INCLUDE_DIRS}, ${GNURADIO_FCDPP_LIBRARIES}")
|
||||
else(GNURADIO_FCDPP_INCLUDE_DIRS AND GNURADIO_FCDPP_LIBRARIES)
|
||||
set(GNURADIO_FCDPP_FOUND FALSE CACHE INTERNAL "gnuradio-fcdproplus found")
|
||||
message(STATUS "gnuradio-fcdproplus not found.")
|
||||
endif(GNURADIO_FCDPP_INCLUDE_DIRS AND GNURADIO_FCDPP_LIBRARIES)
|
||||
|
||||
mark_as_advanced(GNURADIO_FCDPP_LIBRARIES GNURADIO_FCDPP_INCLUDE_DIRS)
|
||||
|
||||
endif(NOT GNURADIO_FCDPP_FOUND)
|
|
@ -0,0 +1,27 @@
|
|||
if(NOT GNURADIO_FUNCUBE_FOUND)
|
||||
pkg_check_modules (GNURADIO_FUNCUBE_PKG libgnuradio-funcube)
|
||||
find_path(GNURADIO_FUNCUBE_INCLUDE_DIRS NAMES funcube/api.h
|
||||
PATHS
|
||||
${GNURADIO_FUNCUBE_PKG_INCLUDE_DIRS}
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
find_library(GNURADIO_FUNCUBE_LIBRARIES NAMES gnuradio-funcube
|
||||
PATHS
|
||||
${GNURADIO_FUNCUBE_PKG_LIBRARY_DIRS}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
)
|
||||
|
||||
if(GNURADIO_FUNCUBE_INCLUDE_DIRS AND GNURADIO_FUNCUBE_LIBRARIES)
|
||||
set(GNURADIO_FUNCUBE_FOUND TRUE CACHE INTERNAL "gnuradio-funcube found")
|
||||
message(STATUS "Found gnuradio-funcube: ${GNURADIO_FUNCUBE_INCLUDE_DIRS}, ${GNURADIO_FUNCUBE_LIBRARIES}")
|
||||
else(GNURADIO_FUNCUBE_INCLUDE_DIRS AND GNURADIO_FUNCUBE_LIBRARIES)
|
||||
set(GNURADIO_FUNCUBE_FOUND FALSE CACHE INTERNAL "gnuradio-funcube found")
|
||||
message(STATUS "gnuradio-funcube not found.")
|
||||
endif(GNURADIO_FUNCUBE_INCLUDE_DIRS AND GNURADIO_FUNCUBE_LIBRARIES)
|
||||
|
||||
mark_as_advanced(GNURADIO_FUNCUBE_LIBRARIES GNURADIO_FUNCUBE_INCLUDE_DIRS)
|
||||
|
||||
endif(NOT GNURADIO_FUNCUBE_FOUND)
|
|
@ -1,4 +1,6 @@
|
|||
INCLUDE(FindPkgConfig)
|
||||
if(NOT PKG_CONFIG_FOUND)
|
||||
INCLUDE(FindPkgConfig)
|
||||
endif()
|
||||
PKG_CHECK_MODULES(PC_LIBAIRSPY libairspy)
|
||||
|
||||
FIND_PATH(
|
||||
|
@ -20,5 +22,5 @@ FIND_LIBRARY(
|
|||
)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBAIRSPY DEFAULT_MSG LIBAIRSPY_LIBRARIES LIBAIRSPY_INCLUDE_DIRS)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibAIRSPY DEFAULT_MSG LIBAIRSPY_LIBRARIES LIBAIRSPY_INCLUDE_DIRS)
|
||||
MARK_AS_ADVANCED(LIBAIRSPY_LIBRARIES LIBAIRSPY_INCLUDE_DIRS)
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
INCLUDE(FindPkgConfig)
|
||||
if(NOT PKG_CONFIG_FOUND)
|
||||
INCLUDE(FindPkgConfig)
|
||||
endif()
|
||||
PKG_CHECK_MODULES(PC_LIBAIRSPYHF libairspyhf)
|
||||
|
||||
FIND_PATH(
|
||||
|
@ -20,5 +22,5 @@ FIND_LIBRARY(
|
|||
)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBAIRSPYHF DEFAULT_MSG LIBAIRSPYHF_LIBRARIES LIBAIRSPYHF_INCLUDE_DIRS)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibAIRSPYHF DEFAULT_MSG LIBAIRSPYHF_LIBRARIES LIBAIRSPYHF_INCLUDE_DIRS)
|
||||
MARK_AS_ADVANCED(LIBAIRSPYHF_LIBRARIES LIBAIRSPYHF_INCLUDE_DIRS)
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
INCLUDE(FindPkgConfig)
|
||||
if(NOT PKG_CONFIG_FOUND)
|
||||
INCLUDE(FindPkgConfig)
|
||||
endif()
|
||||
PKG_CHECK_MODULES(PC_LIBHACKRF libhackrf)
|
||||
|
||||
FIND_PATH(
|
||||
|
@ -20,6 +22,6 @@ FIND_LIBRARY(
|
|||
)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBHACKRF DEFAULT_MSG LIBHACKRF_LIBRARIES LIBHACKRF_INCLUDE_DIRS)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibHackRF DEFAULT_MSG LIBHACKRF_LIBRARIES LIBHACKRF_INCLUDE_DIRS)
|
||||
MARK_AS_ADVANCED(LIBHACKRF_LIBRARIES LIBHACKRF_INCLUDE_DIRS)
|
||||
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
if(NOT LIBMIRISDR_FOUND)
|
||||
pkg_check_modules (LIBMIRISDR_PKG libmirisdr)
|
||||
find_path(LIBMIRISDR_INCLUDE_DIRS NAMES mirisdr.h
|
||||
PATHS
|
||||
${LIBMIRISDR_PKG_INCLUDE_DIRS}
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
find_library(LIBMIRISDR_LIBRARIES NAMES mirisdr
|
||||
PATHS
|
||||
${LIBMIRISDR_PKG_LIBRARY_DIRS}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
)
|
||||
|
||||
if(LIBMIRISDR_INCLUDE_DIRS AND LIBMIRISDR_LIBRARIES)
|
||||
set(LIBMIRISDR_FOUND TRUE CACHE INTERNAL "libmirisdr found")
|
||||
message(STATUS "Found libmirisdr: ${LIBMIRISDR_INCLUDE_DIRS}, ${LIBMIRISDR_LIBRARIES}")
|
||||
else(LIBMIRISDR_INCLUDE_DIRS AND LIBMIRISDR_LIBRARIES)
|
||||
set(LIBMIRISDR_FOUND FALSE CACHE INTERNAL "libmirisdr found")
|
||||
message(STATUS "libmirisdr not found.")
|
||||
endif(LIBMIRISDR_INCLUDE_DIRS AND LIBMIRISDR_LIBRARIES)
|
||||
|
||||
mark_as_advanced(LIBMIRISDR_LIBRARIES LIBMIRISDR_INCLUDE_DIRS)
|
||||
|
||||
endif(NOT LIBMIRISDR_FOUND)
|
|
@ -1,27 +0,0 @@
|
|||
if(NOT LIBOSMOSDR_FOUND)
|
||||
pkg_check_modules (LIBOSMOSDR_PKG libosmosdr)
|
||||
find_path(LIBOSMOSDR_INCLUDE_DIRS NAMES osmosdr.h
|
||||
PATHS
|
||||
${LIBOSMOSDR_PKG_INCLUDE_DIRS}
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
find_library(LIBOSMOSDR_LIBRARIES NAMES osmosdr
|
||||
PATHS
|
||||
${LIBOSMOSDR_PKG_LIBRARY_DIRS}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
)
|
||||
|
||||
if(LIBOSMOSDR_INCLUDE_DIRS AND LIBOSMOSDR_LIBRARIES)
|
||||
set(LIBOSMOSDR_FOUND TRUE CACHE INTERNAL "libosmosdr found")
|
||||
message(STATUS "Found libosmosdr: ${LIBOSMOSDR_INCLUDE_DIRS}, ${LIBOSMOSDR_LIBRARIES}")
|
||||
else(LIBOSMOSDR_INCLUDE_DIRS AND LIBOSMOSDR_LIBRARIES)
|
||||
set(LIBOSMOSDR_FOUND FALSE CACHE INTERNAL "libosmosdr found")
|
||||
message(STATUS "libosmosdr not found.")
|
||||
endif(LIBOSMOSDR_INCLUDE_DIRS AND LIBOSMOSDR_LIBRARIES)
|
||||
|
||||
mark_as_advanced(LIBOSMOSDR_LIBRARIES LIBOSMOSDR_INCLUDE_DIRS)
|
||||
|
||||
endif(NOT LIBOSMOSDR_FOUND)
|
|
@ -0,0 +1,27 @@
|
|||
if(NOT LIBXTRX_FOUND)
|
||||
pkg_check_modules (LIBXTRX_PKG libxtrx)
|
||||
find_path(LIBXTRX_INCLUDE_DIRS NAMES xtrx_api.h
|
||||
PATHS
|
||||
${LIBXTRX_PKG_INCLUDE_DIRS}
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
find_library(LIBXTRX_LIBRARIES NAMES xtrx
|
||||
PATHS
|
||||
${LIBXTRX_PKG_LIBRARY_DIRS}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
)
|
||||
|
||||
if(LIBXTRX_INCLUDE_DIRS AND LIBXTRX_LIBRARIES)
|
||||
set(LIBXTRX_FOUND TRUE CACHE INTERNAL "libxtrx found")
|
||||
message(STATUS "Found libxtrx: ${LIBXTRX_INCLUDE_DIRS}, ${LIBXTRX_LIBRARIES}")
|
||||
else(LIBXTRX_INCLUDE_DIRS AND LIBXTRX_LIBRARIES)
|
||||
set(LIBXTRX_FOUND FALSE CACHE INTERNAL "libxtrx found")
|
||||
message(STATUS "libxtrx not found.")
|
||||
endif(LIBXTRX_INCLUDE_DIRS AND LIBXTRX_LIBRARIES)
|
||||
|
||||
mark_as_advanced(LIBXTRX_LIBRARIES LIBXTRX_INCLUDE_DIRS)
|
||||
|
||||
endif(NOT LIBXTRX_FOUND)
|
|
@ -1,5 +1,9 @@
|
|||
if(NOT LIBBLADERF_FOUND)
|
||||
pkg_check_modules (LIBBLADERF_PKG libbladeRF)
|
||||
if (LIBBLADERF_PKG_FOUND AND LIBBLADERF_PKG_VERSION VERSION_LESS "2")
|
||||
message( FATAL_ERROR "Install version 2 or greater of libbladeRF."
|
||||
" Current version ( ${LIBBLADERF_PKG_VERSION} ) is out of date." )
|
||||
endif()
|
||||
find_path(LIBBLADERF_INCLUDE_DIRS NAMES libbladeRF.h
|
||||
PATHS
|
||||
${LIBBLADERF_PKG_INCLUDE_DIRS}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef PYDOC_MACROS_H
|
||||
#define PYDOC_MACROS_H
|
||||
|
||||
#define __EXPAND(x) x
|
||||
#define __COUNT(_1, _2, _3, _4, _5, _6, _7, COUNT, ...) COUNT
|
||||
#define __VA_SIZE(...) __EXPAND(__COUNT(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1))
|
||||
#define __CAT1(a, b) a##b
|
||||
#define __CAT2(a, b) __CAT1(a, b)
|
||||
#define __DOC1(n1) __doc_##n1
|
||||
#define __DOC2(n1, n2) __doc_##n1##_##n2
|
||||
#define __DOC3(n1, n2, n3) __doc_##n1##_##n2##_##n3
|
||||
#define __DOC4(n1, n2, n3, n4) __doc_##n1##_##n2##_##n3##_##n4
|
||||
#define __DOC5(n1, n2, n3, n4, n5) __doc_##n1##_##n2##_##n3##_##n4##_##n5
|
||||
#define __DOC6(n1, n2, n3, n4, n5, n6) __doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6
|
||||
#define __DOC7(n1, n2, n3, n4, n5, n6, n7) \
|
||||
__doc_##n1##_##n2##_##n3##_##n4##_##n5##_##n6##_##n7
|
||||
#define DOC(...) __EXPAND(__EXPAND(__CAT2(__DOC, __VA_SIZE(__VA_ARGS__)))(__VA_ARGS__))
|
||||
|
||||
#endif // PYDOC_MACROS_H
|
|
@ -2,34 +2,22 @@
|
|||
# Copyright 2010-2012 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file was generated by gr_modtool, a tool from the GNU Radio framework
|
||||
# This file is a part of gr-osmosdr
|
||||
# This file is a part of gnuradio
|
||||
#
|
||||
# GNU Radio is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
#
|
||||
# GNU Radio is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GNU Radio; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
"""
|
||||
Creates the swig_doc.i SWIG interface file.
|
||||
Execute using: python swig_doc.py xml_path outputfilename
|
||||
Updates the *pydoc_h files for a module
|
||||
Execute using: python update_pydoc.py xml_path outputfilename
|
||||
|
||||
The file instructs SWIG to transfer the doxygen comments into the
|
||||
The file instructs Pybind11 to transfer the doxygen comments into the
|
||||
python docstrings.
|
||||
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import sys, time
|
||||
import os, sys, time, glob, re, json
|
||||
from argparse import ArgumentParser
|
||||
|
||||
from doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile
|
||||
from doxyxml import DoxyOther, base
|
||||
|
@ -87,6 +75,7 @@ def utoascii(text):
|
|||
return ''
|
||||
out = text.encode('ascii', 'replace')
|
||||
# swig will require us to replace blackslash with 4 backslashes
|
||||
# TODO: evaluate what this should be for pybind11
|
||||
out = out.replace(b'\\', b'\\\\\\\\')
|
||||
out = out.replace(b'"', b'\\"').decode('ascii')
|
||||
return str(out)
|
||||
|
@ -115,7 +104,7 @@ def format_params(parameteritems):
|
|||
entry_templ = '%feature("docstring") {name} "{docstring}"'
|
||||
def make_entry(obj, name=None, templ="{description}", description=None, params=[]):
|
||||
"""
|
||||
Create a docstring entry for a swig interface file.
|
||||
Create a docstring key/value pair, where the key is the object name.
|
||||
|
||||
obj - a doxyxml object from which documentation will be extracted.
|
||||
name - the name of the C object (defaults to obj.name())
|
||||
|
@ -126,6 +115,8 @@ def make_entry(obj, name=None, templ="{description}", description=None, params=[
|
|||
"""
|
||||
if name is None:
|
||||
name=obj.name()
|
||||
if hasattr(obj,'_parse_data') and hasattr(obj._parse_data,'definition'):
|
||||
name=obj._parse_data.definition.split(' ')[-1]
|
||||
if "operator " in name:
|
||||
return ''
|
||||
if description is None:
|
||||
|
@ -134,56 +125,28 @@ def make_entry(obj, name=None, templ="{description}", description=None, params=[
|
|||
description += '\n\n'
|
||||
description += utoascii(format_params(params))
|
||||
docstring = templ.format(description=description)
|
||||
if not docstring:
|
||||
return ''
|
||||
return entry_templ.format(
|
||||
name=name,
|
||||
docstring=docstring,
|
||||
)
|
||||
|
||||
|
||||
def make_func_entry(func, name=None, description=None, params=None):
|
||||
"""
|
||||
Create a function docstring entry for a swig interface file.
|
||||
|
||||
func - a doxyxml object from which documentation will be extracted.
|
||||
name - the name of the C object (defaults to func.name())
|
||||
description - if this optional variable is set then it's value is
|
||||
used as the description instead of extracting it from func.
|
||||
params - a parameter list that overrides using func.params.
|
||||
"""
|
||||
#if params is None:
|
||||
# params = func.params
|
||||
#params = [prm.declname for prm in params]
|
||||
#if params:
|
||||
# sig = "Params: (%s)" % ", ".join(params)
|
||||
#else:
|
||||
# sig = "Params: (NONE)"
|
||||
#templ = "{description}\n\n" + sig
|
||||
#return make_entry(func, name=name, templ=utoascii(templ),
|
||||
# description=description)
|
||||
return make_entry(func, name=name, description=description, params=params)
|
||||
return {name: docstring}
|
||||
|
||||
|
||||
def make_class_entry(klass, description=None, ignored_methods=[], params=None):
|
||||
"""
|
||||
Create a class docstring for a swig interface file.
|
||||
Create a class docstring key/value pair.
|
||||
"""
|
||||
if params is None:
|
||||
params = klass.params
|
||||
output = []
|
||||
output.append(make_entry(klass, description=description, params=params))
|
||||
output = {}
|
||||
output.update(make_entry(klass, description=description, params=params))
|
||||
for func in klass.in_category(DoxyFunction):
|
||||
if func.name() not in ignored_methods:
|
||||
name = klass.name() + '::' + func.name()
|
||||
output.append(make_func_entry(func, name=name))
|
||||
return "\n\n".join(output)
|
||||
output.update(make_entry(func, name=name))
|
||||
return output
|
||||
|
||||
|
||||
def make_block_entry(di, block):
|
||||
"""
|
||||
Create class and function docstrings of a gnuradio block for a
|
||||
swig interface file.
|
||||
Create class and function docstrings of a gnuradio block
|
||||
"""
|
||||
descriptions = []
|
||||
# Get the documentation associated with the class.
|
||||
|
@ -208,18 +171,16 @@ def make_block_entry(di, block):
|
|||
super_description = "\n\n".join(descriptions)
|
||||
# Associate the combined description with the class and
|
||||
# the make function.
|
||||
output = []
|
||||
output.append(make_class_entry(block, description=super_description))
|
||||
output.append(make_func_entry(make_func, description=super_description,
|
||||
output = {}
|
||||
output.update(make_class_entry(block, description=super_description))
|
||||
output.update(make_entry(make_func, description=super_description,
|
||||
params=block.params))
|
||||
return "\n\n".join(output)
|
||||
return output
|
||||
|
||||
def make_block2_entry(di, block):
|
||||
"""
|
||||
Create class and function docstrings of a new style gnuradio block for a
|
||||
swig interface file.
|
||||
Create class and function docstrings of a new style gnuradio block
|
||||
"""
|
||||
descriptions = []
|
||||
# For new style blocks all the relevant documentation should be
|
||||
# associated with the 'make' method.
|
||||
class_description = combine_descriptions(block)
|
||||
|
@ -228,28 +189,21 @@ def make_block2_entry(di, block):
|
|||
description = class_description + "\n\nConstructor Specific Documentation:\n\n" + make_description
|
||||
# Associate the combined description with the class and
|
||||
# the make function.
|
||||
output = []
|
||||
output.append(make_class_entry(
|
||||
output = {}
|
||||
output.update(make_class_entry(
|
||||
block, description=description,
|
||||
ignored_methods=['make'], params=make_func.params))
|
||||
makename = block.name() + '::make'
|
||||
output.append(make_func_entry(
|
||||
output.update(make_entry(
|
||||
make_func, name=makename, description=description,
|
||||
params=make_func.params))
|
||||
return "\n\n".join(output)
|
||||
return output
|
||||
|
||||
def make_swig_interface_file(di, swigdocfilename, custom_output=None):
|
||||
def get_docstrings_dict(di, custom_output=None):
|
||||
|
||||
output = ["""
|
||||
/*
|
||||
* This file was automatically generated using swig_doc.py.
|
||||
*
|
||||
* Any changes to it will be lost next time it is regenerated.
|
||||
*/
|
||||
"""]
|
||||
|
||||
if custom_output is not None:
|
||||
output.append(custom_output)
|
||||
output = {}
|
||||
if custom_output:
|
||||
output.update(custom_output)
|
||||
|
||||
# Create docstrings for the blocks.
|
||||
blocks = di.in_category(Block)
|
||||
|
@ -262,7 +216,7 @@ def make_swig_interface_file(di, swigdocfilename, custom_output=None):
|
|||
# Don't want to risk writing to output twice.
|
||||
if make_func.name() not in make_funcs:
|
||||
make_funcs.add(make_func.name())
|
||||
output.append(make_block_entry(di, block))
|
||||
output.update(make_block_entry(di, block))
|
||||
except block.ParsingError:
|
||||
sys.stderr.write('Parsing error for block {0}\n'.format(block.name()))
|
||||
raise
|
||||
|
@ -274,7 +228,7 @@ def make_swig_interface_file(di, swigdocfilename, custom_output=None):
|
|||
# Don't want to risk writing to output twice.
|
||||
if make_func_name not in make_funcs:
|
||||
make_funcs.add(make_func_name)
|
||||
output.append(make_block2_entry(di, block))
|
||||
output.update(make_block2_entry(di, block))
|
||||
except block.ParsingError:
|
||||
sys.stderr.write('Parsing error for block {0}\n'.format(block.name()))
|
||||
raise
|
||||
|
@ -285,7 +239,7 @@ def make_swig_interface_file(di, swigdocfilename, custom_output=None):
|
|||
if f.name() not in make_funcs and not f.name().startswith('std::')]
|
||||
for f in funcs:
|
||||
try:
|
||||
output.append(make_func_entry(f))
|
||||
output.update(make_entry(f))
|
||||
except f.ParsingError:
|
||||
sys.stderr.write('Parsing error for function {0}\n'.format(f.name()))
|
||||
|
||||
|
@ -296,37 +250,97 @@ def make_swig_interface_file(di, swigdocfilename, custom_output=None):
|
|||
if k.name() not in block_names and not k.name().startswith('std::')]
|
||||
for k in klasses:
|
||||
try:
|
||||
output.append(make_class_entry(k))
|
||||
output.update(make_class_entry(k))
|
||||
except k.ParsingError:
|
||||
sys.stderr.write('Parsing error for class {0}\n'.format(k.name()))
|
||||
|
||||
# Docstrings are not created for anything that is not a function or a class.
|
||||
# If this excludes anything important please add it here.
|
||||
|
||||
output = "\n\n".join(output)
|
||||
return output
|
||||
|
||||
swig_doc = open(swigdocfilename, 'w')
|
||||
swig_doc.write(output)
|
||||
swig_doc.close()
|
||||
def sub_docstring_in_pydoc_h(pydoc_files, docstrings_dict, output_dir, filter_str=None):
|
||||
if filter_str:
|
||||
docstrings_dict = {k: v for k, v in docstrings_dict.items() if k.startswith(filter_str)}
|
||||
|
||||
with open(os.path.join(output_dir,'docstring_status'),'w') as status_file:
|
||||
|
||||
for pydoc_file in pydoc_files:
|
||||
if filter_str:
|
||||
filter_str2 = "::".join((filter_str,os.path.split(pydoc_file)[-1].split('_pydoc_template.h')[0]))
|
||||
docstrings_dict2 = {k: v for k, v in docstrings_dict.items() if k.startswith(filter_str2)}
|
||||
else:
|
||||
docstrings_dict2 = docstrings_dict
|
||||
|
||||
|
||||
|
||||
file_in = open(pydoc_file,'r').read()
|
||||
for key, value in docstrings_dict2.items():
|
||||
file_in_tmp = file_in
|
||||
try:
|
||||
doc_key = key.split("::")
|
||||
# if 'gr' in doc_key:
|
||||
# doc_key.remove('gr')
|
||||
doc_key = '_'.join(doc_key)
|
||||
regexp = r'(__doc_{} =\sR\"doc\()[^)]*(\)doc\")'.format(doc_key)
|
||||
regexp = re.compile(regexp, re.MULTILINE)
|
||||
|
||||
(file_in, nsubs) = regexp.subn(r'\1'+value+r'\2', file_in, count=1)
|
||||
if nsubs == 1:
|
||||
status_file.write("PASS: " + pydoc_file + "\n")
|
||||
except KeyboardInterrupt:
|
||||
raise KeyboardInterrupt
|
||||
except: # be permissive, TODO log, but just leave the docstring blank
|
||||
status_file.write("FAIL: " + pydoc_file + "\n")
|
||||
file_in = file_in_tmp
|
||||
|
||||
output_pathname = os.path.join(output_dir, os.path.basename(pydoc_file).replace('_template.h','.h'))
|
||||
# FIXME: Remove this debug print
|
||||
print('output docstrings to {}'.format(output_pathname))
|
||||
with open(output_pathname,'w') as file_out:
|
||||
file_out.write(file_in)
|
||||
|
||||
def copy_docstring_templates(pydoc_files, output_dir):
|
||||
with open(os.path.join(output_dir,'docstring_status'),'w') as status_file:
|
||||
for pydoc_file in pydoc_files:
|
||||
file_in = open(pydoc_file,'r').read()
|
||||
output_pathname = os.path.join(output_dir, os.path.basename(pydoc_file).replace('_template.h','.h'))
|
||||
# FIXME: Remove this debug print
|
||||
print('copy docstrings to {}'.format(output_pathname))
|
||||
with open(output_pathname,'w') as file_out:
|
||||
file_out.write(file_in)
|
||||
status_file.write("DONE")
|
||||
|
||||
def argParse():
|
||||
"""Parses commandline args."""
|
||||
desc='Scrape the doxygen generated xml for docstrings to insert into python bindings'
|
||||
parser = ArgumentParser(description=desc)
|
||||
|
||||
parser.add_argument("function", help="Operation to perform on docstrings", choices=["scrape","sub","copy"])
|
||||
|
||||
parser.add_argument("--xml_path")
|
||||
parser.add_argument("--bindings_dir")
|
||||
parser.add_argument("--output_dir")
|
||||
parser.add_argument("--json_path")
|
||||
parser.add_argument("--filter", default=None)
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Parse command line options and set up doxyxml.
|
||||
err_msg = "Execute using: python swig_doc.py xml_path outputfilename"
|
||||
if len(sys.argv) != 3:
|
||||
raise Exception(err_msg)
|
||||
xml_path = sys.argv[1]
|
||||
swigdocfilename = sys.argv[2]
|
||||
di = DoxyIndex(xml_path)
|
||||
args = argParse()
|
||||
if args.function.lower() == 'scrape':
|
||||
di = DoxyIndex(args.xml_path)
|
||||
docstrings_dict = get_docstrings_dict(di)
|
||||
with open(args.json_path, 'w') as fp:
|
||||
json.dump(docstrings_dict, fp)
|
||||
elif args.function.lower() == 'sub':
|
||||
with open(args.json_path, 'r') as fp:
|
||||
docstrings_dict = json.load(fp)
|
||||
pydoc_files = glob.glob(os.path.join(args.bindings_dir,'*_pydoc_template.h'))
|
||||
sub_docstring_in_pydoc_h(pydoc_files, docstrings_dict, args.output_dir, args.filter)
|
||||
elif args.function.lower() == 'copy':
|
||||
pydoc_files = glob.glob(os.path.join(args.bindings_dir,'*_pydoc_template.h'))
|
||||
copy_docstring_templates(pydoc_files, args.output_dir)
|
||||
|
||||
# gnuradio.gr.msq_queue.insert_tail and delete_head create errors unless docstrings are defined!
|
||||
# This is presumably a bug in SWIG.
|
||||
#msg_q = di.get_member(u'gr_msg_queue', DoxyClass)
|
||||
#insert_tail = msg_q.get_member(u'insert_tail', DoxyFunction)
|
||||
#delete_head = msg_q.get_member(u'delete_head', DoxyFunction)
|
||||
output = []
|
||||
#output.append(make_func_entry(insert_tail, name='gr_py_msg_queue__insert_tail'))
|
||||
#output.append(make_func_entry(delete_head, name='gr_py_msg_queue__delete_head'))
|
||||
custom_output = "\n\n".join(output)
|
||||
|
||||
# Generate the docstrings interface file.
|
||||
make_swig_interface_file(di, swigdocfilename, custom_output=custom_output)
|
||||
|
|
@ -157,10 +157,8 @@ documentation: |-
|
|||
While primarily being developed for the OsmoSDR hardware, this block as well supports:
|
||||
|
||||
% if sourk == 'source':
|
||||
* sysmocom OsmoSDR Devices through libosmosdr
|
||||
* RTL2832U based DVB-T dongles through librtlsdr
|
||||
* RTL-TCP spectrum server (see librtlsdr project)
|
||||
* MSi2500 based DVB-T dongles through libmirisdr
|
||||
* SDRplay RSP devices through SDRplay library
|
||||
* gnuradio .cfile input through libgnuradio-blocks
|
||||
* RFSPACE SDR-IQ, SDR-IP, NetSDR (incl. X2 option)
|
||||
|
@ -173,7 +171,8 @@ documentation: |-
|
|||
* Great Scott Gadgets HackRF through libhackrf
|
||||
* Nuand LLC bladeRF through libbladeRF library
|
||||
* Ettus USRP Devices through Ettus UHD library
|
||||
* Fairwaves UmTRX through Fairwaves' fork of UHD
|
||||
* Fairwaves XTRX through libxtrx
|
||||
* Fairwaves UmTRX through Fairwaves' module for UHD
|
||||
* Red Pitaya SDR transceiver (http://bazaar.redpitaya.com)
|
||||
* FreeSRP through libfreesrp library
|
||||
|
||||
|
@ -192,13 +191,11 @@ documentation: |-
|
|||
Lines ending with ... mean it's possible to bind devices together by specifying multiple device arguments separated with a space.
|
||||
|
||||
% if sourk == 'source':
|
||||
miri=0[,buffers=32] ...
|
||||
rtl=serial_number ...
|
||||
rtl=0[,rtl_xtal=28.8e6][,tuner_xtal=28.8e6] ...
|
||||
rtl=1[,buffers=32][,buflen=N*512] ...
|
||||
rtl=2[,direct_samp=0|1|2][,offset_tune=0|1][,bias=0|1] ...
|
||||
rtl_tcp=127.0.0.1:1234[,psize=16384][,direct_samp=0|1|2][,offset_tune=0|1][,bias=0|1] ...
|
||||
osmosdr=0[,buffers=32][,buflen=N*512] ...
|
||||
file='/path/to/your file',rate=1e6[,freq=100e6][,repeat=true][,throttle=true] ...
|
||||
netsdr=127.0.0.1[:50000][,nchan=2]
|
||||
sdr-ip=127.0.0.1[:50000]
|
||||
|
@ -214,6 +211,7 @@ documentation: |-
|
|||
hackrf=0[,buffers=32][,bias=0|1][,bias_tx=0|1]
|
||||
bladerf=0[,tamer=internal|external|external_1pps][,smb=25e6]
|
||||
uhd[,serial=...][,lo_offset=0][,mcr=52e6][,nchan=2][,subdev='\\\\'B:0 A:0\\\\''] ...
|
||||
xtrx
|
||||
|
||||
Num Channels:
|
||||
Selects the total number of channels in this multi-device configuration. Required when specifying multiple device arguments.
|
||||
|
|
|
@ -38,7 +38,7 @@ class sink;
|
|||
class OSMOSDR_API sink : virtual public gr::hier_block2
|
||||
{
|
||||
public:
|
||||
typedef boost::shared_ptr< sink > sptr;
|
||||
typedef std::shared_ptr< sink > sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of sink.
|
||||
|
|
|
@ -38,7 +38,7 @@ class source;
|
|||
class OSMOSDR_API source : virtual public gr::hier_block2
|
||||
{
|
||||
public:
|
||||
typedef boost::shared_ptr< source > sptr;
|
||||
typedef std::shared_ptr< source > sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of source.
|
||||
|
@ -63,6 +63,7 @@ public:
|
|||
*
|
||||
* \param seek_point sample offset in file
|
||||
* \param whence one of SEEK_SET, SEEK_CUR, SEEK_END (man fseek)
|
||||
* \param chan the channel index 0 to N-1
|
||||
* \return true on success
|
||||
*/
|
||||
virtual bool seek( long seek_point, int whence, size_t chan = 0 ) = 0;
|
||||
|
|
|
@ -44,7 +44,7 @@ endif()
|
|||
#this appends all unnamed implicit macro args!
|
||||
MACRO (APPEND_LIB_LIST)
|
||||
SET (gr_osmosdr_libs "${gr_osmosdr_libs};${ARGN}" CACHE INTERNAL "lib list")
|
||||
ENDMACRO (APPEND_INTERNAL_LIST)
|
||||
ENDMACRO (APPEND_LIB_LIST)
|
||||
|
||||
set(gr_osmosdr_libs "" CACHE INTERNAL "lib that accumulates link targets")
|
||||
|
||||
|
@ -135,18 +135,10 @@ if(ENABLE_IQBALANCE)
|
|||
APPEND_LIB_LIST( gnuradio::gnuradio-iqbalance)
|
||||
endif(ENABLE_IQBALANCE)
|
||||
|
||||
########################################################################
|
||||
# Setup OsmoSDR component
|
||||
########################################################################
|
||||
#GR_REGISTER_COMPONENT("sysmocom OsmoSDR" ENABLE_OSMOSDR LIBOSMOSDR_FOUND)
|
||||
#if(ENABLE_OSMOSDR)
|
||||
# add_subdirectory(osmosdr)
|
||||
#endif(ENABLE_OSMOSDR)
|
||||
|
||||
########################################################################
|
||||
# Setup FCD component
|
||||
########################################################################
|
||||
GR_REGISTER_COMPONENT("FUNcube Dongle" ENABLE_FCD GNURADIO_FCDPP_FOUND)
|
||||
GR_REGISTER_COMPONENT("FUNcube Dongle" ENABLE_FCD GNURADIO_FUNCUBE_FOUND)
|
||||
if(ENABLE_FCD)
|
||||
add_subdirectory(fcd)
|
||||
endif(ENABLE_FCD)
|
||||
|
@ -183,14 +175,6 @@ if(ENABLE_UHD)
|
|||
add_subdirectory(uhd)
|
||||
endif(ENABLE_UHD)
|
||||
|
||||
########################################################################
|
||||
# Setup MiriSDR component
|
||||
########################################################################
|
||||
#GR_REGISTER_COMPONENT("Osmocom MiriSDR" ENABLE_MIRI LIBMIRISDR_FOUND)
|
||||
#if(ENABLE_MIRI)
|
||||
# add_subdirectory(miri)
|
||||
#endif(ENABLE_MIRI)
|
||||
|
||||
########################################################################
|
||||
# Setup SDRplay component
|
||||
########################################################################
|
||||
|
@ -265,6 +249,14 @@ if(ENABLE_FREESRP)
|
|||
add_subdirectory(freesrp)
|
||||
endif(ENABLE_FREESRP)
|
||||
|
||||
########################################################################
|
||||
# Setup XTRX component
|
||||
########################################################################
|
||||
GR_REGISTER_COMPONENT("XTRX SDR" ENABLE_XTRX LIBXTRX_FOUND)
|
||||
if(ENABLE_XTRX)
|
||||
add_subdirectory(xtrx)
|
||||
endif(ENABLE_XTRX)
|
||||
|
||||
########################################################################
|
||||
# Setup configuration file
|
||||
########################################################################
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
class airspy_source_c;
|
||||
|
||||
/*
|
||||
* We use boost::shared_ptr's instead of raw pointers for all access
|
||||
* We use std::shared_ptr's instead of raw pointers for all access
|
||||
* to gr::blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues. This is especially helpful in our hybrid
|
||||
|
@ -44,9 +44,9 @@ class airspy_source_c;
|
|||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
* As a convention, the _sptr suffix indicates a std::shared_ptr
|
||||
*/
|
||||
typedef boost::shared_ptr<airspy_source_c> airspy_source_c_sptr;
|
||||
typedef std::shared_ptr<airspy_source_c> airspy_source_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of airspy_source_c.
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
class airspyhf_source_c;
|
||||
|
||||
typedef boost::shared_ptr<airspyhf_source_c> airspyhf_source_c_sptr;
|
||||
typedef std::shared_ptr<airspyhf_source_c> airspyhf_source_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of airspyhf_source_c.
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <ciso646>
|
||||
|
||||
typedef std::map< std::string, std::string > dict_t;
|
||||
|
@ -38,7 +37,7 @@ typedef std::pair< std::string, std::string > pair_t;
|
|||
inline std::string dict_to_args_string( const dict_t &d )
|
||||
{
|
||||
std::string out;
|
||||
BOOST_FOREACH(const pair_t pair, d)
|
||||
for (const pair_t pair : d)
|
||||
{
|
||||
if (not out.empty()) out += ",";
|
||||
out += pair.first + "='" + pair.second + "'";
|
||||
|
@ -54,7 +53,7 @@ inline std::vector< std::string > args_to_vector( const std::string &args )
|
|||
typedef boost::tokenizer< boost::escaped_list_separator<char> > tokenizer_t;
|
||||
tokenizer_t tokens(args, separator);
|
||||
|
||||
BOOST_FOREACH(std::string token, tokens)
|
||||
for (std::string token : tokens)
|
||||
result.push_back(token);
|
||||
|
||||
return result;
|
||||
|
@ -68,7 +67,7 @@ inline std::vector< std::string > params_to_vector( const std::string ¶ms )
|
|||
typedef boost::tokenizer< boost::escaped_list_separator<char> > tokenizer_t;
|
||||
tokenizer_t tokens(params, separator);
|
||||
|
||||
BOOST_FOREACH(std::string token, tokens)
|
||||
for (std::string token : tokens)
|
||||
result.push_back(token);
|
||||
|
||||
return result;
|
||||
|
@ -98,7 +97,7 @@ inline dict_t params_to_dict( const std::string ¶ms )
|
|||
dict_t result;
|
||||
|
||||
std::vector< std::string > param_list = params_to_vector( params );
|
||||
BOOST_FOREACH(std::string param, param_list)
|
||||
for (std::string param : param_list)
|
||||
{
|
||||
pair_t pair = param_to_pair( param );
|
||||
std::string value = pair.second;
|
||||
|
@ -124,7 +123,7 @@ inline gr::io_signature::sptr args_to_io_signature( const std::string &args )
|
|||
size_t dev_nchan = 0;
|
||||
std::vector< std::string > arg_list = args_to_vector( args );
|
||||
|
||||
BOOST_FOREACH( std::string arg, arg_list )
|
||||
for (std::string arg : arg_list)
|
||||
{
|
||||
if ( arg.find( "numchan=" ) == 0 ) // try to parse global nchan value
|
||||
{
|
||||
|
@ -141,7 +140,7 @@ inline gr::io_signature::sptr args_to_io_signature( const std::string &args )
|
|||
|
||||
// try to parse device specific nchan values, assume 1 channel if none given
|
||||
|
||||
BOOST_FOREACH( std::string arg, arg_list )
|
||||
for (std::string arg : arg_list)
|
||||
{
|
||||
dict_t dict = params_to_dict(arg);
|
||||
if (dict.count("nchan"))
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#include <string>
|
||||
|
||||
#include <boost/assign.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
|
@ -50,7 +49,7 @@ static size_t const STREAM_TIMEOUT_MS = 3000;
|
|||
using namespace boost::assign;
|
||||
|
||||
std::mutex bladerf_common::_devs_mutex;
|
||||
std::list<std::weak_ptr<struct bladerf>> bladerf_common::_devs;
|
||||
std::list<std::weak_ptr<struct bladerf> > bladerf_common::_devs;
|
||||
|
||||
/* name for system-wide gain (which is not its own libbladeRF gain stage) */
|
||||
static const char *SYSTEM_GAIN_NAME = "system";
|
||||
|
@ -134,7 +133,7 @@ size_t num_streams(bladerf_channel_layout layout)
|
|||
* Public methods
|
||||
******************************************************************************/
|
||||
bladerf_common::bladerf_common() :
|
||||
_dev(NULL),
|
||||
_dev(std::shared_ptr<struct bladerf>()),
|
||||
_pfx("[bladeRF common] "),
|
||||
_failures(0),
|
||||
_num_buffers(NUM_BUFFERS),
|
||||
|
@ -498,7 +497,7 @@ int bladerf_common::channel2rfport(bladerf_channel ch)
|
|||
bladerf_channel bladerf_common::chan2channel(bladerf_direction direction,
|
||||
size_t chan)
|
||||
{
|
||||
BOOST_FOREACH(bladerf_channel_map::value_type &i, _chanmap) {
|
||||
for (bladerf_channel_map::value_type &i : _chanmap) {
|
||||
bladerf_channel ch = i.first;
|
||||
if (
|
||||
(i.second == (int)chan) && (
|
||||
|
@ -642,7 +641,7 @@ osmosdr::freq_range_t bladerf_common::filter_bandwidths(bladerf_channel ch)
|
|||
0.75, 0.875, 1.25, 1.375, 1.5, 1.92, 2.5,
|
||||
2.75, 3, 3.5, 4.375, 5, 6, 7, 10, 14;
|
||||
|
||||
BOOST_FOREACH( double half_bw, half_bandwidths )
|
||||
for (double half_bw : half_bandwidths)
|
||||
bandwidths += osmosdr::range_t( half_bw * 2e6 );
|
||||
#else
|
||||
|
||||
|
@ -1108,7 +1107,7 @@ bladerf_sptr bladerf_common::open(std::string const &device_name)
|
|||
/* Add the device handle to our cache */
|
||||
bladerf_sptr dev = bladerf_sptr(raw_dev, bladerf_common::close);
|
||||
|
||||
_devs.push_back(static_cast<std::weak_ptr<struct bladerf>>(dev));
|
||||
_devs.push_back(static_cast<std::weak_ptr<struct bladerf> >(dev));
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
@ -1116,7 +1115,7 @@ bladerf_sptr bladerf_common::open(std::string const &device_name)
|
|||
void bladerf_common::close(void *dev)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_devs_mutex);
|
||||
std::list<std::weak_ptr<struct bladerf>>::iterator it(_devs.begin());
|
||||
std::list<std::weak_ptr<struct bladerf> >::iterator it(_devs.begin());
|
||||
|
||||
/* Prune expired entries from device cache */
|
||||
while (it != _devs.end()) {
|
||||
|
@ -1136,7 +1135,7 @@ bladerf_sptr bladerf_common::get_cached_device(struct bladerf_devinfo devinfo)
|
|||
int status;
|
||||
struct bladerf_devinfo other_devinfo;
|
||||
|
||||
BOOST_FOREACH(std::weak_ptr<struct bladerf> dev, _devs) {
|
||||
for (std::weak_ptr<struct bladerf> dev : _devs) {
|
||||
status = bladerf_get_devinfo(bladerf_sptr(dev).get(), &other_devinfo);
|
||||
if (status < 0) {
|
||||
BLADERF_THROW_STATUS(status, "Failed to get devinfo for cached device");
|
||||
|
@ -1199,7 +1198,7 @@ void bladerf_common::print_device_info()
|
|||
bool bladerf_common::is_antenna_valid(bladerf_direction dir,
|
||||
const std::string &antenna)
|
||||
{
|
||||
BOOST_FOREACH(std::string ant, get_antennas(dir)) {
|
||||
for (std::string ant : get_antennas(dir)) {
|
||||
if (antenna == ant) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -287,7 +287,7 @@ private:
|
|||
* Private members
|
||||
****************************************************************************/
|
||||
static std::mutex _devs_mutex; /**< mutex for access to _devs */
|
||||
static std::list<std::weak_ptr<struct bladerf>> _devs; /**< dev cache */
|
||||
static std::list<std::weak_ptr<struct bladerf> > _devs; /**< dev cache */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
}
|
||||
|
||||
/* Changed enums/defines */
|
||||
#define BLADERF_GAIN_DEFAULT BLADERF_GAIN_AUTOMATIC
|
||||
#define BLADERF_GAIN_DEFAULT BLADERF_GAIN_MANUAL
|
||||
#define BLADERF_GAIN_MGC BLADERF_GAIN_MANUAL
|
||||
#define BLADERF_RX_MUX_BASEBAND BLADERF_RX_MUX_BASEBAND_LMS
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ bladerf_sink_c::bladerf_sink_c(const std::string &args) :
|
|||
}
|
||||
|
||||
/* Initialize channel <-> antenna map */
|
||||
BOOST_FOREACH(std::string ant, get_antennas()) {
|
||||
for (std::string ant : get_antennas()) {
|
||||
_chanmap[str2channel(ant)] = -1;
|
||||
}
|
||||
|
||||
|
@ -174,11 +174,9 @@ bool bladerf_sink_c::start()
|
|||
|
||||
for (size_t ch = 0; ch < get_max_channels(); ++ch) {
|
||||
bladerf_channel brfch = BLADERF_CHANNEL_TX(ch);
|
||||
if (get_channel_enable(brfch)) {
|
||||
status = bladerf_enable_module(_dev.get(), brfch, true);
|
||||
if (status != 0) {
|
||||
BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
|
||||
}
|
||||
status = bladerf_enable_module(_dev.get(), brfch, get_channel_enable(brfch));
|
||||
if (status != 0) {
|
||||
BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -210,11 +208,9 @@ bool bladerf_sink_c::stop()
|
|||
|
||||
for (size_t ch = 0; ch < get_max_channels(); ++ch) {
|
||||
bladerf_channel brfch = BLADERF_CHANNEL_TX(ch);
|
||||
if (get_channel_enable(brfch)) {
|
||||
status = bladerf_enable_module(_dev.get(), brfch, false);
|
||||
if (status != 0) {
|
||||
BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
|
||||
}
|
||||
status = bladerf_enable_module(_dev.get(), brfch, get_channel_enable(brfch));
|
||||
if (status != 0) {
|
||||
BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,7 +325,7 @@ int bladerf_sink_c::transmit_with_tags(int16_t const *samples,
|
|||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(gr::tag_t tag, tags) {
|
||||
for (gr::tag_t tag : tags) {
|
||||
// Upon seeing an SOB tag, update our offset. We'll TX the start of the
|
||||
// burst when we see an EOB or at the end of this function - whichever
|
||||
// occurs first.
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
class bladerf_sink_c;
|
||||
|
||||
/*
|
||||
* We use boost::shared_ptr's instead of raw pointers for all access
|
||||
* We use std::shared_ptr's instead of raw pointers for all access
|
||||
* to gr_blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues. This is especially helpful in our hybrid
|
||||
|
@ -38,9 +38,9 @@ class bladerf_sink_c;
|
|||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
* As a convention, the _sptr suffix indicates a std::shared_ptr
|
||||
*/
|
||||
typedef boost::shared_ptr<bladerf_sink_c> bladerf_sink_c_sptr;
|
||||
typedef std::shared_ptr<bladerf_sink_c> bladerf_sink_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of bladerf_sink_c.
|
||||
|
|
|
@ -144,7 +144,7 @@ bladerf_source_c::bladerf_source_c(const std::string &args) :
|
|||
}
|
||||
|
||||
/* Initialize channel <-> antenna map */
|
||||
BOOST_FOREACH(std::string ant, get_antennas()) {
|
||||
for (std::string ant : get_antennas()) {
|
||||
_chanmap[str2channel(ant)] = -1;
|
||||
}
|
||||
|
||||
|
@ -180,7 +180,7 @@ bladerf_source_c::bladerf_source_c(const std::string &args) :
|
|||
|
||||
bool bladerf_source_c::is_antenna_valid(const std::string &antenna)
|
||||
{
|
||||
BOOST_FOREACH(std::string ant, get_antennas()) {
|
||||
for (std::string ant : get_antennas()) {
|
||||
if (antenna == ant) {
|
||||
return true;
|
||||
}
|
||||
|
@ -230,11 +230,9 @@ bool bladerf_source_c::start()
|
|||
|
||||
for (size_t ch = 0; ch < get_max_channels(); ++ch) {
|
||||
bladerf_channel brfch = BLADERF_CHANNEL_RX(ch);
|
||||
if (get_channel_enable(brfch)) {
|
||||
status = bladerf_enable_module(_dev.get(), brfch, true);
|
||||
if (status != 0) {
|
||||
BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
|
||||
}
|
||||
status = bladerf_enable_module(_dev.get(), brfch, get_channel_enable(brfch));
|
||||
if (status != 0) {
|
||||
BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -344,7 +342,7 @@ int bladerf_source_c::work(int noutput_items,
|
|||
memcpy(out[0], _32fcbuf, sizeof(gr_complex) * noutput_items);
|
||||
}
|
||||
|
||||
return noutput_items;
|
||||
return noutput_items/(get_num_channels());
|
||||
}
|
||||
|
||||
osmosdr::meta_range_t bladerf_source_c::get_sample_rates()
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
class bladerf_source_c;
|
||||
|
||||
/*
|
||||
* We use boost::shared_ptr's instead of raw pointers for all access
|
||||
* We use std::shared_ptr's instead of raw pointers for all access
|
||||
* to gr_blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues. This is especially helpful in our hybrid
|
||||
|
@ -38,9 +38,9 @@ class bladerf_source_c;
|
|||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
* As a convention, the _sptr suffix indicates a std::shared_ptr
|
||||
*/
|
||||
typedef boost::shared_ptr<bladerf_source_c> bladerf_source_c_sptr;
|
||||
typedef std::shared_ptr<bladerf_source_c> bladerf_source_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of bladerf_source_c.
|
||||
|
|
|
@ -4,13 +4,11 @@
|
|||
#define GR_OSMOSDR_VERSION "@VERSION@"
|
||||
#define GR_OSMOSDR_LIBVER "@LIBVER@"
|
||||
|
||||
#cmakedefine ENABLE_OSMOSDR
|
||||
#cmakedefine ENABLE_FCD
|
||||
#cmakedefine ENABLE_FILE
|
||||
#cmakedefine ENABLE_RTL
|
||||
#cmakedefine ENABLE_RTL_TCP
|
||||
#cmakedefine ENABLE_UHD
|
||||
#cmakedefine ENABLE_MIRI
|
||||
#cmakedefine ENABLE_SDRPLAY
|
||||
#cmakedefine ENABLE_HACKRF
|
||||
#cmakedefine ENABLE_BLADERF
|
||||
|
@ -20,6 +18,7 @@
|
|||
#cmakedefine ENABLE_SOAPY
|
||||
#cmakedefine ENABLE_REDPITAYA
|
||||
#cmakedefine ENABLE_FREESRP
|
||||
#cmakedefine ENABLE_XTRX
|
||||
|
||||
//provide NAN define for MSVC older than VC12
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1800)
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
#include <osmosdr/device.h>
|
||||
#include <stdexcept>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <algorithm>
|
||||
#include <mutex>
|
||||
|
@ -30,10 +29,6 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_OSMOSDR
|
||||
#include <osmosdr_src_c.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FCD
|
||||
#include <fcd_source_c.h>
|
||||
#endif
|
||||
|
@ -54,10 +49,6 @@
|
|||
#include <uhd_source_c.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MIRI
|
||||
#include <miri_source_c.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_SDRPLAY
|
||||
#include <sdrplay_source_c.h>
|
||||
#endif
|
||||
|
@ -108,7 +99,7 @@ device_t::device_t(const std::string &args)
|
|||
{
|
||||
dict_t dict = params_to_dict(args);
|
||||
|
||||
BOOST_FOREACH( dict_t::value_type &entry, dict )
|
||||
for (dict_t::value_type &entry : dict)
|
||||
(*this)[entry.first] = entry.second;
|
||||
}
|
||||
|
||||
|
@ -118,7 +109,7 @@ std::string device_t::to_pp_string(void) const
|
|||
|
||||
std::stringstream ss;
|
||||
ss << "Device Address:" << std::endl;
|
||||
BOOST_FOREACH(const device_t::value_type &entry, *this) {
|
||||
for (const device_t::value_type &entry : *this) {
|
||||
ss << boost::format(" %s: %s") % entry.first % entry.second << std::endl;
|
||||
}
|
||||
return ss.str();
|
||||
|
@ -128,7 +119,7 @@ std::string device_t::to_string(void) const
|
|||
{
|
||||
std::stringstream ss;
|
||||
size_t count = 0;
|
||||
BOOST_FOREACH(const device_t::value_type &entry, *this) {
|
||||
for (const device_t::value_type &entry : *this) {
|
||||
std::string value = entry.second;
|
||||
if (value.find(" ") != std::string::npos)
|
||||
value = "'" + value + "'";
|
||||
|
@ -150,56 +141,48 @@ devices_t device::find(const device_t &hint)
|
|||
|
||||
devices_t devices;
|
||||
|
||||
#ifdef ENABLE_OSMOSDR
|
||||
BOOST_FOREACH( std::string dev, osmosdr_src_c::get_devices() )
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_FCD
|
||||
BOOST_FOREACH( std::string dev, fcd_source_c::get_devices() )
|
||||
for (std::string dev : fcd_source_c::get_devices())
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_RTL
|
||||
BOOST_FOREACH( std::string dev, rtl_source_c::get_devices() )
|
||||
for (std::string dev : rtl_source_c::get_devices())
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_UHD
|
||||
BOOST_FOREACH( std::string dev, uhd_source_c::get_devices() )
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_MIRI
|
||||
BOOST_FOREACH( std::string dev, miri_source_c::get_devices() )
|
||||
for (std::string dev : uhd_source_c::get_devices())
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_SDRPLAY
|
||||
BOOST_FOREACH( std::string dev, sdrplay_source_c::get_devices() )
|
||||
for (std::string dev : sdrplay_source_c::get_devices())
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_BLADERF
|
||||
BOOST_FOREACH( std::string dev, bladerf_source_c::get_devices() )
|
||||
for (std::string dev : bladerf_source_c::get_devices())
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_HACKRF
|
||||
BOOST_FOREACH( std::string dev, hackrf_source_c::get_devices() )
|
||||
for (std::string dev : hackrf_source_c::get_devices())
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_RFSPACE
|
||||
BOOST_FOREACH( std::string dev, rfspace_source_c::get_devices( fake ) )
|
||||
for (std::string dev : rfspace_source_c::get_devices( fake ))
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_AIRSPY
|
||||
BOOST_FOREACH( std::string dev, airspy_source_c::get_devices() )
|
||||
for (std::string dev : airspy_source_c::get_devices())
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_AIRSPYHF
|
||||
BOOST_FOREACH( std::string dev, airspyhf_source_c::get_devices() )
|
||||
for (std::string dev : airspyhf_source_c::get_devices())
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_FREESRP
|
||||
BOOST_FOREACH( std::string dev, freesrp_source_c::get_devices() )
|
||||
for (std::string dev : freesrp_source_c::get_devices())
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_SOAPY
|
||||
BOOST_FOREACH( std::string dev, soapy_source_c::get_devices() )
|
||||
for (std::string dev : soapy_source_c::get_devices())
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
|
||||
|
@ -208,15 +191,15 @@ devices_t device::find(const device_t &hint)
|
|||
* in a graphical interface etc... */
|
||||
|
||||
#ifdef ENABLE_RTL_TCP
|
||||
BOOST_FOREACH( std::string dev, rtl_tcp_source_c::get_devices( fake ) )
|
||||
for (std::string dev : rtl_tcp_source_c::get_devices( fake ))
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_REDPITAYA
|
||||
BOOST_FOREACH( std::string dev, redpitaya_source_c::get_devices( fake ) )
|
||||
for (std::string dev : redpitaya_source_c::get_devices( fake ))
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
#ifdef ENABLE_FILE
|
||||
BOOST_FOREACH( std::string dev, file_source_c::get_devices( fake ) )
|
||||
for (std::string dev : file_source_c::get_devices( fake ))
|
||||
devices.push_back( device_t(dev) );
|
||||
#endif
|
||||
|
||||
|
|
|
@ -23,11 +23,11 @@
|
|||
|
||||
target_include_directories(gnuradio-osmosdr PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${GNURADIO_FCDPP_INCLUDE_DIRS}
|
||||
${GNURADIO_FUNCUBE_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
APPEND_LIB_LIST(
|
||||
${GNURADIO_FCDPP_LIBRARIES}
|
||||
${GNURADIO_FUNCUBE_LIBRARIES}
|
||||
)
|
||||
|
||||
list(APPEND gr_osmosdr_srcs
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include <sstream>
|
||||
|
||||
#include <boost/assign.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <gnuradio/io_signature.h>
|
||||
|
||||
|
@ -144,7 +143,7 @@ fcd_source_c::fcd_source_c(const std::string &args) :
|
|||
|
||||
if ( FUNCUBE_V1 == _type )
|
||||
{
|
||||
_src_v1 = gr::fcdproplus::fcd::make( dev_name );
|
||||
_src_v1 = gr::funcube::fcd::make( dev_name );
|
||||
connect( _src_v1, 0, self(), 0 );
|
||||
|
||||
set_gain( 20, "LNA" );
|
||||
|
@ -153,7 +152,7 @@ fcd_source_c::fcd_source_c(const std::string &args) :
|
|||
|
||||
if ( FUNCUBE_V2 == _type )
|
||||
{
|
||||
_src_v2 = gr::fcdproplus::fcdproplus::make( dev_name );
|
||||
_src_v2 = gr::funcube::fcdpp::make( dev_name );
|
||||
connect( _src_v2, 0, self(), 0 );
|
||||
|
||||
set_gain( 1, "LNA" );
|
||||
|
@ -171,7 +170,7 @@ std::vector< std::string > fcd_source_c::get_devices()
|
|||
int id = 0;
|
||||
std::vector< std::string > devices;
|
||||
|
||||
BOOST_FOREACH( device_t dev, _get_devices() )
|
||||
for (device_t dev : _get_devices())
|
||||
{
|
||||
std::string args = "fcd=" + boost::lexical_cast< std::string >( id++ );
|
||||
|
||||
|
@ -238,10 +237,10 @@ osmosdr::freq_range_t fcd_source_c::get_freq_range( size_t chan )
|
|||
double fcd_source_c::set_center_freq( double freq, size_t chan )
|
||||
{
|
||||
if ( FUNCUBE_V1 == _type )
|
||||
_src_v1->set_freq( float(freq) );
|
||||
_src_v1->set_freq( freq );
|
||||
|
||||
if ( FUNCUBE_V2 == _type )
|
||||
_src_v2->set_freq( float(freq) );
|
||||
_src_v2->set_freq( freq );
|
||||
|
||||
_freq = freq;
|
||||
|
||||
|
|
|
@ -22,14 +22,14 @@
|
|||
|
||||
#include <gnuradio/hier_block2.h>
|
||||
|
||||
#include <fcdproplus/fcd.h>
|
||||
#include <fcdproplus/fcdproplus.h>
|
||||
#include <funcube/fcd.h>
|
||||
#include <funcube/fcdpp.h>
|
||||
|
||||
#include "source_iface.h"
|
||||
|
||||
class fcd_source_c;
|
||||
|
||||
typedef boost::shared_ptr< fcd_source_c > fcd_source_c_sptr;
|
||||
typedef std::shared_ptr< fcd_source_c > fcd_source_c_sptr;
|
||||
|
||||
fcd_source_c_sptr make_fcd_source_c( const std::string & args = "" );
|
||||
|
||||
|
@ -81,10 +81,10 @@ public:
|
|||
|
||||
private:
|
||||
dongle_type _type;
|
||||
gr::fcdproplus::fcd::sptr _src_v1;
|
||||
gr::fcdproplus::fcdproplus::sptr _src_v2;
|
||||
gr::funcube::fcd::sptr _src_v1;
|
||||
gr::funcube::fcdpp::sptr _src_v2;
|
||||
double _lna_gain, _mix_gain, _bb_gain, _freq;
|
||||
int _correct;
|
||||
double _correct;
|
||||
};
|
||||
|
||||
#endif // FCD_SOURCE_C_H
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
class file_sink_c;
|
||||
|
||||
typedef boost::shared_ptr< file_sink_c > file_sink_c_sptr;
|
||||
typedef std::shared_ptr< file_sink_c > file_sink_c_sptr;
|
||||
|
||||
file_sink_c_sptr make_file_sink_c( const std::string & args = "" );
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
class file_source_c;
|
||||
|
||||
typedef boost::shared_ptr< file_source_c > file_source_c_sptr;
|
||||
typedef std::shared_ptr< file_source_c > file_source_c_sptr;
|
||||
|
||||
file_source_c_sptr make_file_source_c( const std::string & args = "" );
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
class freesrp_sink_c;
|
||||
|
||||
/*
|
||||
* We use boost::shared_ptr's instead of raw pointers for all access
|
||||
* We use std::shared_ptr's instead of raw pointers for all access
|
||||
* to gr_blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues. This is especially helpful in our hybrid
|
||||
|
@ -47,9 +47,9 @@ class freesrp_sink_c;
|
|||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
* As a convention, the _sptr suffix indicates a std::shared_ptr
|
||||
*/
|
||||
typedef boost::shared_ptr<freesrp_sink_c> freesrp_sink_c_sptr;
|
||||
typedef std::shared_ptr<freesrp_sink_c> freesrp_sink_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of freesrp_sink_c.
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
class freesrp_source_c;
|
||||
|
||||
/*
|
||||
* We use boost::shared_ptr's instead of raw pointers for all access
|
||||
* We use std::shared_ptr's instead of raw pointers for all access
|
||||
* to gr_blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues. This is especially helpful in our hybrid
|
||||
|
@ -48,9 +48,9 @@ class freesrp_source_c;
|
|||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
* As a convention, the _sptr suffix indicates a std::shared_ptr
|
||||
*/
|
||||
typedef boost::shared_ptr<freesrp_source_c> freesrp_source_c_sptr;
|
||||
typedef std::shared_ptr<freesrp_source_c> freesrp_source_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of freesrp_source_c.
|
||||
|
|
|
@ -37,6 +37,7 @@ hackrf_common::hackrf_common(const std::string &args) :
|
|||
_center_freq(0),
|
||||
_freq_corr(0),
|
||||
_auto_gain(false),
|
||||
_requested_bandwidth(0),
|
||||
_bandwidth(0),
|
||||
_bias(false),
|
||||
_started(false)
|
||||
|
@ -339,6 +340,7 @@ double hackrf_common::set_bandwidth( double bandwidth, size_t chan )
|
|||
int ret;
|
||||
// osmosdr::freq_range_t bandwidths = get_bandwidth_range( chan );
|
||||
|
||||
_requested_bandwidth = bandwidth;
|
||||
if ( bandwidth == 0.0 ) /* bandwidth of 0 means automatic filter selection */
|
||||
bandwidth = _sample_rate * 0.75; /* select narrower filters to prevent aliasing */
|
||||
|
||||
|
@ -411,9 +413,10 @@ bool hackrf_common::get_bias()
|
|||
void hackrf_common::start()
|
||||
{
|
||||
_started = true;
|
||||
set_bandwidth(get_bandwidth());
|
||||
set_center_freq(get_center_freq());
|
||||
set_sample_rate(get_sample_rate());
|
||||
if (_requested_bandwidth != 0)
|
||||
set_bandwidth(get_bandwidth());
|
||||
set_gain(get_gain());
|
||||
set_bias(get_bias());
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ private:
|
|||
double _freq_corr;
|
||||
bool _auto_gain;
|
||||
double _amp_gain;
|
||||
double _requested_bandwidth;
|
||||
double _bandwidth;
|
||||
bool _bias;
|
||||
bool _started;
|
||||
|
|
|
@ -45,7 +45,7 @@ typedef struct circular_buffer
|
|||
} circular_buffer_t;
|
||||
|
||||
/*
|
||||
* We use boost::shared_ptr's instead of raw pointers for all access
|
||||
* We use std::shared_ptr's instead of raw pointers for all access
|
||||
* to gr::blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues. This is especially helpful in our hybrid
|
||||
|
@ -53,9 +53,9 @@ typedef struct circular_buffer
|
|||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
* As a convention, the _sptr suffix indicates a std::shared_ptr
|
||||
*/
|
||||
typedef boost::shared_ptr<hackrf_sink_c> hackrf_sink_c_sptr;
|
||||
typedef std::shared_ptr<hackrf_sink_c> hackrf_sink_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of hackrf_sink_c.
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
|
||||
#include <gnuradio/io_signature.h>
|
||||
|
||||
|
@ -203,8 +204,15 @@ int hackrf_source_c::work( int noutput_items,
|
|||
{
|
||||
std::unique_lock<std::mutex> lock(_buf_mutex);
|
||||
|
||||
while (_buf_used < 3 && running) // collect at least 3 buffers
|
||||
_buf_cond.wait( lock );
|
||||
while (_buf_used < 3 && running) { // collect at least 3 buffers
|
||||
_buf_cond.wait_for( lock , std::chrono::milliseconds(100));
|
||||
|
||||
// Re-check whether the device has closed or stopped streaming
|
||||
if ( _dev.get() )
|
||||
running = (hackrf_is_streaming( _dev.get() ) == HACKRF_TRUE);
|
||||
else
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! running )
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
class hackrf_source_c;
|
||||
|
||||
/*
|
||||
* We use boost::shared_ptr's instead of raw pointers for all access
|
||||
* We use std::shared_ptr's instead of raw pointers for all access
|
||||
* to gr::blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues. This is especially helpful in our hybrid
|
||||
|
@ -42,9 +42,9 @@ class hackrf_source_c;
|
|||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
* As a convention, the _sptr suffix indicates a std::shared_ptr
|
||||
*/
|
||||
typedef boost::shared_ptr<hackrf_source_c> hackrf_source_c_sptr;
|
||||
typedef std::shared_ptr<hackrf_source_c> hackrf_source_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of hackrf_source_c.
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
# Copyright 2012 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of gr-osmosdr
|
||||
#
|
||||
# gr-osmosdr is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# gr-osmosdr is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with gr-osmosdr; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
########################################################################
|
||||
# This file included, use CMake directory variables
|
||||
########################################################################
|
||||
|
||||
target_include_directories(gnuradio-osmosdr PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${LIBMIRISDR_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
APPEND_LIB_LIST(
|
||||
${LIBMIRISDR_LIBRARIES}
|
||||
)
|
||||
|
||||
list(APPEND gr_osmosdr_srcs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/miri_source_c.cc
|
||||
)
|
||||
set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
|
|
@ -1,451 +0,0 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2012 Dimitri Stolnikov <horiz0n@gmx.net>
|
||||
* Copyright 2012 Steve Markgraf <steve@steve-m.de>
|
||||
*
|
||||
* GNU Radio is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Radio is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* config.h is generated by configure. It contains the results
|
||||
* of probing for features, options etc. It should be the first
|
||||
* file included in your .cc file.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "miri_source_c.h"
|
||||
#include <gnuradio/io_signature.h>
|
||||
|
||||
#include <boost/assign.hpp>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <mirisdr.h>
|
||||
|
||||
#include "arg_helpers.h"
|
||||
|
||||
using namespace boost::assign;
|
||||
|
||||
#define BUF_SIZE 2304 * 8 * 2
|
||||
#define BUF_NUM 15
|
||||
#define BUF_SKIP 1 // buffers to skip due to garbage
|
||||
|
||||
#define BYTES_PER_SAMPLE 4 // mirisdr device delivers 16 bit signed IQ data
|
||||
// containing 12 bits of information
|
||||
|
||||
/*
|
||||
* Create a new instance of miri_source_c and return
|
||||
* a boost shared_ptr. This is effectively the public constructor.
|
||||
*/
|
||||
miri_source_c_sptr
|
||||
make_miri_source_c (const std::string &args)
|
||||
{
|
||||
return gnuradio::get_initial_sptr(new miri_source_c (args));
|
||||
}
|
||||
|
||||
/*
|
||||
* Specify constraints on number of input and output streams.
|
||||
* This info is used to construct the input and output signatures
|
||||
* (2nd & 3rd args to gr::block's constructor). The input and
|
||||
* output signatures are used by the runtime system to
|
||||
* check that a valid number and type of inputs and outputs
|
||||
* are connected to this block. In this case, we accept
|
||||
* only 0 input and 1 output.
|
||||
*/
|
||||
static const int MIN_IN = 0; // mininum number of input streams
|
||||
static const int MAX_IN = 0; // maximum number of input streams
|
||||
static const int MIN_OUT = 1; // minimum number of output streams
|
||||
static const int MAX_OUT = 1; // maximum number of output streams
|
||||
|
||||
/*
|
||||
* The private constructor
|
||||
*/
|
||||
miri_source_c::miri_source_c (const std::string &args)
|
||||
: gr::sync_block ("miri_source_c",
|
||||
gr::io_signature::make(MIN_IN, MAX_IN, sizeof (gr_complex)),
|
||||
gr::io_signature::make(MIN_OUT, MAX_OUT, sizeof (gr_complex))),
|
||||
_running(true),
|
||||
_auto_gain(false),
|
||||
_skipped(0)
|
||||
{
|
||||
int ret;
|
||||
unsigned int dev_index = 0;
|
||||
|
||||
dict_t dict = params_to_dict(args);
|
||||
|
||||
if (dict.count("miri"))
|
||||
dev_index = boost::lexical_cast< unsigned int >( dict["miri"] );
|
||||
|
||||
_buf_num = _buf_head = _buf_used = _buf_offset = 0;
|
||||
_samp_avail = BUF_SIZE / BYTES_PER_SAMPLE;
|
||||
|
||||
if (dict.count("buffers"))
|
||||
_buf_num = boost::lexical_cast< unsigned int >( dict["buffers"] );
|
||||
|
||||
if (0 == _buf_num)
|
||||
_buf_num = BUF_NUM;
|
||||
|
||||
if ( BUF_NUM != _buf_num ) {
|
||||
std::cerr << "Using " << _buf_num << " buffers of size " << BUF_SIZE << "."
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
if ( dev_index >= mirisdr_get_device_count() )
|
||||
throw std::runtime_error("Wrong mirisdr device index given.");
|
||||
|
||||
std::cerr << "Using device #" << dev_index << ": "
|
||||
<< mirisdr_get_device_name(dev_index)
|
||||
<< std::endl;
|
||||
|
||||
_dev = NULL;
|
||||
ret = mirisdr_open( &_dev, dev_index );
|
||||
if (ret < 0)
|
||||
throw std::runtime_error("Failed to open mirisdr device.");
|
||||
#if 0
|
||||
ret = mirisdr_set_sample_rate( _dev, 500000 );
|
||||
if (ret < 0)
|
||||
throw std::runtime_error("Failed to set default samplerate.");
|
||||
|
||||
ret = mirisdr_set_tuner_gain_mode(_dev, int(!_auto_gain));
|
||||
if (ret < 0)
|
||||
throw std::runtime_error("Failed to enable manual gain mode.");
|
||||
#endif
|
||||
ret = mirisdr_reset_buffer( _dev );
|
||||
if (ret < 0)
|
||||
throw std::runtime_error("Failed to reset usb buffers.");
|
||||
|
||||
_buf = (unsigned short **) malloc(_buf_num * sizeof(unsigned short *));
|
||||
_buf_lens = (unsigned int *) malloc(_buf_num * sizeof(unsigned int));
|
||||
|
||||
if (_buf && _buf_lens) {
|
||||
for(unsigned int i = 0; i < _buf_num; ++i)
|
||||
_buf[i] = (unsigned short *) malloc(BUF_SIZE);
|
||||
}
|
||||
|
||||
_thread = gr::thread::thread(_mirisdr_wait, this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
miri_source_c::~miri_source_c ()
|
||||
{
|
||||
if (_dev) {
|
||||
_running = false;
|
||||
mirisdr_cancel_async( _dev );
|
||||
_thread.join();
|
||||
mirisdr_close( _dev );
|
||||
_dev = NULL;
|
||||
}
|
||||
|
||||
if (_buf) {
|
||||
for(unsigned int i = 0; i < _buf_num; ++i) {
|
||||
free(_buf[i]);
|
||||
}
|
||||
|
||||
free(_buf);
|
||||
_buf = NULL;
|
||||
free(_buf_lens);
|
||||
_buf_lens = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void miri_source_c::_mirisdr_callback(unsigned char *buf, uint32_t len, void *ctx)
|
||||
{
|
||||
miri_source_c *obj = (miri_source_c *)ctx;
|
||||
obj->mirisdr_callback(buf, len);
|
||||
}
|
||||
|
||||
void miri_source_c::mirisdr_callback(unsigned char *buf, uint32_t len)
|
||||
{
|
||||
if (_skipped < BUF_SKIP) {
|
||||
_skipped++;
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( _buf_mutex );
|
||||
|
||||
if (len > BUF_SIZE)
|
||||
throw std::runtime_error("Buffer too small.");
|
||||
|
||||
int buf_tail = (_buf_head + _buf_used) % _buf_num;
|
||||
memcpy(_buf[buf_tail], buf, len);
|
||||
_buf_lens[buf_tail] = len;
|
||||
|
||||
if (_buf_used == _buf_num) {
|
||||
std::cerr << "O" << std::flush;
|
||||
_buf_head = (_buf_head + 1) % _buf_num;
|
||||
} else {
|
||||
_buf_used++;
|
||||
}
|
||||
}
|
||||
|
||||
_buf_cond.notify_one();
|
||||
}
|
||||
|
||||
void miri_source_c::_mirisdr_wait(miri_source_c *obj)
|
||||
{
|
||||
obj->mirisdr_wait();
|
||||
}
|
||||
|
||||
void miri_source_c::mirisdr_wait()
|
||||
{
|
||||
int ret = mirisdr_read_async( _dev, _mirisdr_callback, (void *)this, _buf_num, BUF_SIZE );
|
||||
|
||||
_running = false;
|
||||
|
||||
if ( ret != 0 )
|
||||
std::cerr << "mirisdr_read_async returned with " << ret << std::endl;
|
||||
|
||||
_buf_cond.notify_one();
|
||||
}
|
||||
|
||||
int miri_source_c::work( int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items )
|
||||
{
|
||||
gr_complex *out = (gr_complex *)output_items[0];
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lock( _buf_mutex );
|
||||
|
||||
while (_buf_used < 3 && _running) // collect at least 3 buffers
|
||||
_buf_cond.wait( lock );
|
||||
}
|
||||
|
||||
if (!_running)
|
||||
return WORK_DONE;
|
||||
|
||||
short *buf = (short *)_buf[_buf_head] + _buf_offset;
|
||||
|
||||
if (noutput_items <= _samp_avail) {
|
||||
for (int i = 0; i < noutput_items; i++)
|
||||
*out++ = gr_complex( float(*(buf + i * 2 + 0)) * (1.0f/4096.0f),
|
||||
float(*(buf + i * 2 + 1)) * (1.0f/4096.0f) );
|
||||
|
||||
_buf_offset += noutput_items * 2;
|
||||
_samp_avail -= noutput_items;
|
||||
} else {
|
||||
for (int i = 0; i < _samp_avail; i++)
|
||||
*out++ = gr_complex( float(*(buf + i * 2 + 0)) * (1.0f/4096.0f),
|
||||
float(*(buf + i * 2 + 1)) * (1.0f/4096.0f) );
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( _buf_mutex );
|
||||
|
||||
_buf_head = (_buf_head + 1) % _buf_num;
|
||||
_buf_used--;
|
||||
}
|
||||
|
||||
buf = (short *)_buf[_buf_head];
|
||||
|
||||
int remaining = noutput_items - _samp_avail;
|
||||
|
||||
for (int i = 0; i < remaining; i++)
|
||||
*out++ = gr_complex( float(*(buf + i * 2 + 0)) * (1.0f/4096.0f),
|
||||
float(*(buf + i * 2 + 1)) * (1.0f/4096.0f) );
|
||||
|
||||
_buf_offset = remaining * 2;
|
||||
_samp_avail = (_buf_lens[_buf_head] / BYTES_PER_SAMPLE) - remaining;
|
||||
}
|
||||
|
||||
return noutput_items;
|
||||
}
|
||||
|
||||
std::vector<std::string> miri_source_c::get_devices()
|
||||
{
|
||||
std::vector<std::string> devices;
|
||||
|
||||
for (unsigned int i = 0; i < mirisdr_get_device_count(); i++) {
|
||||
std::string args = "miri=" + boost::lexical_cast< std::string >( i );
|
||||
args += ",label='" + std::string(mirisdr_get_device_name( i )) + "'";
|
||||
devices.push_back( args );
|
||||
}
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
size_t miri_source_c::get_num_channels()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
osmosdr::meta_range_t miri_source_c::get_sample_rates()
|
||||
{
|
||||
osmosdr::meta_range_t range;
|
||||
|
||||
range += osmosdr::range_t( 8000000 ); // known to work
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
double miri_source_c::set_sample_rate(double rate)
|
||||
{
|
||||
if (_dev) {
|
||||
mirisdr_set_sample_rate( _dev, (uint32_t)rate );
|
||||
}
|
||||
|
||||
return get_sample_rate();
|
||||
}
|
||||
|
||||
double miri_source_c::get_sample_rate()
|
||||
{
|
||||
if (_dev)
|
||||
return (double)mirisdr_get_sample_rate( _dev );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
osmosdr::freq_range_t miri_source_c::get_freq_range( size_t chan )
|
||||
{
|
||||
osmosdr::freq_range_t range;
|
||||
|
||||
range += osmosdr::range_t( 150e3, 30e6 ); /* LW/MW/SW (150 kHz - 30 MHz) */
|
||||
range += osmosdr::range_t( 64e6, 108e6 ); /* VHF Band II (64 - 108 MHz) */
|
||||
range += osmosdr::range_t( 162e6, 240e6 ); /* Band III (162 - 240 MHz) */
|
||||
range += osmosdr::range_t( 470e6, 960e6 ); /* Band IV/V (470 - 960 MHz) */
|
||||
range += osmosdr::range_t( 1450e6, 1675e6 ); /* L-Band (1450 - 1675 MHz) */
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
double miri_source_c::set_center_freq( double freq, size_t chan )
|
||||
{
|
||||
if (_dev)
|
||||
mirisdr_set_center_freq( _dev, (uint32_t)freq );
|
||||
|
||||
return get_center_freq( chan );
|
||||
}
|
||||
|
||||
double miri_source_c::get_center_freq( size_t chan )
|
||||
{
|
||||
if (_dev)
|
||||
return (double)mirisdr_get_center_freq( _dev );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
double miri_source_c::set_freq_corr( double ppm, size_t chan )
|
||||
{
|
||||
return get_freq_corr( chan );
|
||||
}
|
||||
|
||||
double miri_source_c::get_freq_corr( size_t chan )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<std::string> miri_source_c::get_gain_names( size_t chan )
|
||||
{
|
||||
std::vector< std::string > gains;
|
||||
|
||||
gains += "LNA";
|
||||
|
||||
return gains;
|
||||
}
|
||||
|
||||
osmosdr::gain_range_t miri_source_c::get_gain_range( size_t chan )
|
||||
{
|
||||
osmosdr::gain_range_t range;
|
||||
|
||||
if (_dev) {
|
||||
int count = mirisdr_get_tuner_gains(_dev, NULL);
|
||||
if (count > 0) {
|
||||
int* gains = new int[ count ];
|
||||
count = mirisdr_get_tuner_gains(_dev, gains);
|
||||
for (int i = 0; i < count; i++)
|
||||
range += osmosdr::range_t( gains[i] / 10.0 );
|
||||
delete[] gains;
|
||||
}
|
||||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
osmosdr::gain_range_t miri_source_c::get_gain_range( const std::string & name, size_t chan )
|
||||
{
|
||||
return get_gain_range( chan );
|
||||
}
|
||||
|
||||
bool miri_source_c::set_gain_mode( bool automatic, size_t chan )
|
||||
{
|
||||
if (_dev) {
|
||||
if (!mirisdr_set_tuner_gain_mode(_dev, int(!automatic))) {
|
||||
_auto_gain = automatic;
|
||||
}
|
||||
}
|
||||
|
||||
return get_gain_mode(chan);
|
||||
}
|
||||
|
||||
bool miri_source_c::get_gain_mode( size_t chan )
|
||||
{
|
||||
return _auto_gain;
|
||||
}
|
||||
|
||||
double miri_source_c::set_gain( double gain, size_t chan )
|
||||
{
|
||||
osmosdr::gain_range_t rf_gains = miri_source_c::get_gain_range( chan );
|
||||
|
||||
if (_dev) {
|
||||
mirisdr_set_tuner_gain( _dev, int(rf_gains.clip(gain) * 10.0) );
|
||||
}
|
||||
|
||||
return get_gain( chan );
|
||||
}
|
||||
|
||||
double miri_source_c::set_gain( double gain, const std::string & name, size_t chan)
|
||||
{
|
||||
return set_gain( gain, chan );
|
||||
}
|
||||
|
||||
double miri_source_c::get_gain( size_t chan )
|
||||
{
|
||||
if ( _dev )
|
||||
return ((double)mirisdr_get_tuner_gain( _dev )) / 10.0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
double miri_source_c::get_gain( const std::string & name, size_t chan )
|
||||
{
|
||||
return get_gain( chan );
|
||||
}
|
||||
|
||||
std::vector< std::string > miri_source_c::get_antennas( size_t chan )
|
||||
{
|
||||
std::vector< std::string > antennas;
|
||||
|
||||
antennas += get_antenna( chan );
|
||||
|
||||
return antennas;
|
||||
}
|
||||
|
||||
std::string miri_source_c::set_antenna( const std::string & antenna, size_t chan )
|
||||
{
|
||||
return get_antenna( chan );
|
||||
}
|
||||
|
||||
std::string miri_source_c::get_antenna( size_t chan )
|
||||
{
|
||||
return "RX";
|
||||
}
|
|
@ -1,135 +0,0 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2012 Dimitri Stolnikov <horiz0n@gmx.net>
|
||||
*
|
||||
* GNU Radio is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Radio is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#ifndef INCLUDED_MIRI_SOURCE_C_H
|
||||
#define INCLUDED_MIRI_SOURCE_C_H
|
||||
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
#include <gnuradio/thread/thread.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#include "source_iface.h"
|
||||
|
||||
class miri_source_c;
|
||||
typedef struct mirisdr_dev mirisdr_dev_t;
|
||||
|
||||
/*
|
||||
* We use boost::shared_ptr's instead of raw pointers for all access
|
||||
* to gr::blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues. This is especially helpful in our hybrid
|
||||
* C++ / Python system.
|
||||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
*/
|
||||
typedef boost::shared_ptr<miri_source_c> miri_source_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of miri_source_c.
|
||||
*
|
||||
* To avoid accidental use of raw pointers, miri_source_c's
|
||||
* constructor is private. make_miri_source_c is the public
|
||||
* interface for creating new instances.
|
||||
*/
|
||||
miri_source_c_sptr make_miri_source_c (const std::string & args = "");
|
||||
|
||||
/*!
|
||||
* \brief Provides a stream of complex samples.
|
||||
* \ingroup block
|
||||
*/
|
||||
class miri_source_c :
|
||||
public gr::sync_block,
|
||||
public source_iface
|
||||
{
|
||||
private:
|
||||
// The friend declaration allows make_miri_source_c to
|
||||
// access the private constructor.
|
||||
|
||||
friend miri_source_c_sptr make_miri_source_c (const std::string & args);
|
||||
|
||||
/*!
|
||||
* \brief Provides a stream of complex samples.
|
||||
*/
|
||||
miri_source_c (const std::string & args); // private constructor
|
||||
|
||||
public:
|
||||
~miri_source_c (); // public destructor
|
||||
|
||||
int work( int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items );
|
||||
|
||||
static std::vector< std::string > get_devices();
|
||||
|
||||
size_t get_num_channels( void );
|
||||
|
||||
osmosdr::meta_range_t get_sample_rates( void );
|
||||
double set_sample_rate( double rate );
|
||||
double get_sample_rate( void );
|
||||
|
||||
osmosdr::freq_range_t get_freq_range( size_t chan = 0 );
|
||||
double set_center_freq( double freq, size_t chan = 0 );
|
||||
double get_center_freq( size_t chan = 0 );
|
||||
double set_freq_corr( double ppm, size_t chan = 0 );
|
||||
double get_freq_corr( size_t chan = 0 );
|
||||
|
||||
std::vector<std::string> get_gain_names( size_t chan = 0 );
|
||||
osmosdr::gain_range_t get_gain_range( size_t chan = 0 );
|
||||
osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 );
|
||||
bool set_gain_mode( bool automatic, size_t chan = 0 );
|
||||
bool get_gain_mode( size_t chan = 0 );
|
||||
double set_gain( double gain, size_t chan = 0 );
|
||||
double set_gain( double gain, const std::string & name, size_t chan = 0 );
|
||||
double get_gain( size_t chan = 0 );
|
||||
double get_gain( const std::string & name, size_t chan = 0 );
|
||||
|
||||
std::vector< std::string > get_antennas( size_t chan = 0 );
|
||||
std::string set_antenna( const std::string & antenna, size_t chan = 0 );
|
||||
std::string get_antenna( size_t chan = 0 );
|
||||
|
||||
private:
|
||||
static void _mirisdr_callback(unsigned char *buf, uint32_t len, void *ctx);
|
||||
void mirisdr_callback(unsigned char *buf, uint32_t len);
|
||||
static void _mirisdr_wait(miri_source_c *obj);
|
||||
void mirisdr_wait();
|
||||
|
||||
mirisdr_dev_t *_dev;
|
||||
gr::thread::thread _thread;
|
||||
unsigned short **_buf;
|
||||
unsigned int *_buf_lens;
|
||||
unsigned int _buf_num;
|
||||
unsigned int _buf_head;
|
||||
unsigned int _buf_used;
|
||||
std::mutex _buf_mutex;
|
||||
std::condition_variable _buf_cond;
|
||||
bool _running;
|
||||
|
||||
unsigned int _buf_offset;
|
||||
int _samp_avail;
|
||||
|
||||
bool _auto_gain;
|
||||
unsigned int _skipped;
|
||||
};
|
||||
|
||||
#endif /* INCLUDED_MIRI_SOURCE_C_H */
|
|
@ -1,533 +0,0 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2012 Dimitri Stolnikov <horiz0n@gmx.net>
|
||||
*
|
||||
* GNU Radio is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Radio is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* config.h is generated by configure. It contains the results
|
||||
* of probing for features, options etc. It should be the first
|
||||
* file included in your .cc file.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "osmosdr_src_c.h"
|
||||
#include <gnuradio/io_signature.h>
|
||||
|
||||
#include <boost/assign.hpp>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <osmosdr.h>
|
||||
|
||||
#include "arg_helpers.h"
|
||||
|
||||
using namespace boost::assign;
|
||||
|
||||
#define BUF_LEN (16 * 32 * 512) /* must be multiple of 512 */
|
||||
#define BUF_NUM 15
|
||||
#define BUF_SKIP 1 // buffers to skip due to garbage
|
||||
|
||||
#define BYTES_PER_SAMPLE 4 // osmosdr device delivers 16 bit signed IQ data
|
||||
|
||||
/*
|
||||
* Create a new instance of osmosdr_src_c and return
|
||||
* a boost shared_ptr. This is effectively the public constructor.
|
||||
*/
|
||||
osmosdr_src_c_sptr
|
||||
osmosdr_make_src_c (const std::string &args)
|
||||
{
|
||||
return gnuradio::get_initial_sptr(new osmosdr_src_c (args));
|
||||
}
|
||||
|
||||
/*
|
||||
* The private constructor
|
||||
*/
|
||||
osmosdr_src_c::osmosdr_src_c (const std::string &args)
|
||||
: gr::sync_block ("osmosdr_src_c",
|
||||
gr::io_signature::make(0, 0, sizeof (gr_complex)),
|
||||
gr::io_signature::make(1, 1, sizeof (gr_complex)) ),
|
||||
_dev(NULL),
|
||||
_buf(NULL),
|
||||
_running(true),
|
||||
_auto_gain(false),
|
||||
_if_gain(0),
|
||||
_skipped(0)
|
||||
{
|
||||
int ret;
|
||||
unsigned int dev_index = 0;
|
||||
|
||||
dict_t dict = params_to_dict(args);
|
||||
|
||||
if (dict.count("osmosdr"))
|
||||
dev_index = boost::lexical_cast< unsigned int >( dict["osmosdr"] );
|
||||
|
||||
_buf_num = _buf_len = _buf_head = _buf_used = _buf_offset = 0;
|
||||
|
||||
if (dict.count("buffers"))
|
||||
_buf_num = boost::lexical_cast< unsigned int >( dict["buffers"] );
|
||||
|
||||
if (dict.count("buflen"))
|
||||
_buf_len = boost::lexical_cast< unsigned int >( dict["buflen"] );
|
||||
|
||||
if (0 == _buf_num)
|
||||
_buf_num = BUF_NUM;
|
||||
|
||||
if (0 == _buf_len || _buf_len % 512 != 0) /* len must be multiple of 512 */
|
||||
_buf_len = BUF_LEN;
|
||||
|
||||
if ( BUF_NUM != _buf_num || BUF_LEN != _buf_len ) {
|
||||
std::cerr << "Using " << _buf_num << " buffers of size " << _buf_len << "."
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
_samp_avail = _buf_len / BYTES_PER_SAMPLE;
|
||||
|
||||
if ( dev_index >= osmosdr_get_device_count() )
|
||||
throw std::runtime_error("Wrong osmosdr device index given.");
|
||||
|
||||
std::cerr << "Using device #" << dev_index << ": "
|
||||
<< osmosdr_get_device_name(dev_index)
|
||||
<< std::endl;
|
||||
|
||||
_dev = NULL;
|
||||
ret = osmosdr_open( &_dev, dev_index );
|
||||
if (ret < 0)
|
||||
throw std::runtime_error("Failed to open osmosdr device.");
|
||||
|
||||
ret = osmosdr_set_fpga_iq_swap(_dev, 0);
|
||||
if (ret < 0)
|
||||
throw std::runtime_error("Failed to disable IQ swapping.");
|
||||
|
||||
ret = osmosdr_set_sample_rate( _dev, 500000 );
|
||||
if (ret < 0)
|
||||
throw std::runtime_error("Failed to set default samplerate.");
|
||||
|
||||
ret = osmosdr_set_tuner_gain_mode(_dev, int(!_auto_gain));
|
||||
if (ret < 0)
|
||||
throw std::runtime_error("Failed to enable manual gain mode.");
|
||||
|
||||
ret = osmosdr_reset_buffer( _dev );
|
||||
if (ret < 0)
|
||||
throw std::runtime_error("Failed to reset usb buffers.");
|
||||
|
||||
set_if_gain( 24 ); /* preset to a reasonable default (non-GRC use case) */
|
||||
|
||||
_buf = (unsigned short **) malloc(_buf_num * sizeof(unsigned short *));
|
||||
|
||||
if (_buf) {
|
||||
for(unsigned int i = 0; i < _buf_num; ++i)
|
||||
_buf[i] = (unsigned short *) malloc(_buf_len);
|
||||
}
|
||||
|
||||
_thread = gr::thread::thread(_osmosdr_wait, this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Our virtual destructor.
|
||||
*/
|
||||
osmosdr_src_c::~osmosdr_src_c ()
|
||||
{
|
||||
if (_dev) {
|
||||
_running = false;
|
||||
osmosdr_cancel_async( _dev );
|
||||
_thread.join();
|
||||
osmosdr_close( _dev );
|
||||
_dev = NULL;
|
||||
}
|
||||
|
||||
if (_buf) {
|
||||
for(unsigned int i = 0; i < _buf_num; ++i) {
|
||||
free(_buf[i]);
|
||||
}
|
||||
|
||||
free(_buf);
|
||||
_buf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void osmosdr_src_c::_osmosdr_callback(unsigned char *buf, uint32_t len, void *ctx)
|
||||
{
|
||||
osmosdr_src_c *obj = (osmosdr_src_c *)ctx;
|
||||
obj->osmosdr_callback(buf, len);
|
||||
}
|
||||
|
||||
void osmosdr_src_c::osmosdr_callback(unsigned char *buf, uint32_t len)
|
||||
{
|
||||
if (_skipped < BUF_SKIP) {
|
||||
_skipped++;
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( _buf_mutex );
|
||||
|
||||
int buf_tail = (_buf_head + _buf_used) % _buf_num;
|
||||
memcpy(_buf[buf_tail], buf, len);
|
||||
|
||||
if (_buf_used == _buf_num) {
|
||||
std::cerr << "O" << std::flush;
|
||||
_buf_head = (_buf_head + 1) % _buf_num;
|
||||
} else {
|
||||
_buf_used++;
|
||||
}
|
||||
}
|
||||
|
||||
_buf_cond.notify_one();
|
||||
}
|
||||
|
||||
void osmosdr_src_c::_osmosdr_wait(osmosdr_src_c *obj)
|
||||
{
|
||||
obj->osmosdr_wait();
|
||||
}
|
||||
|
||||
void osmosdr_src_c::osmosdr_wait()
|
||||
{
|
||||
int ret = osmosdr_read_async( _dev, _osmosdr_callback, (void *)this, _buf_num, _buf_len );
|
||||
|
||||
_running = false;
|
||||
|
||||
if ( ret != 0 )
|
||||
std::cerr << "osmosdr_read_async returned with " << ret << std::endl;
|
||||
|
||||
_buf_cond.notify_one();
|
||||
}
|
||||
|
||||
int osmosdr_src_c::work( int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items )
|
||||
{
|
||||
gr_complex *out = (gr_complex *)output_items[0];
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lock( _buf_mutex );
|
||||
|
||||
while (_buf_used < 3 && _running) // collect at least 3 buffers
|
||||
_buf_cond.wait( lock );
|
||||
}
|
||||
|
||||
if (!_running)
|
||||
return WORK_DONE;
|
||||
|
||||
short *buf = (short *)_buf[_buf_head] + _buf_offset;
|
||||
|
||||
if (noutput_items <= _samp_avail) {
|
||||
for (int i = 0; i < noutput_items; i++)
|
||||
*out++ = gr_complex( float(*(buf + i * 2 + 0)) * (1.0f/32767.5f),
|
||||
float(*(buf + i * 2 + 1)) * (1.0f/32767.5f) );
|
||||
|
||||
_buf_offset += noutput_items * 2;
|
||||
_samp_avail -= noutput_items;
|
||||
} else {
|
||||
for (int i = 0; i < _samp_avail; i++)
|
||||
*out++ = gr_complex( float(*(buf + i * 2 + 0)) * (1.0f/32767.5f),
|
||||
float(*(buf + i * 2 + 1)) * (1.0f/32767.5f) );
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( _buf_mutex );
|
||||
|
||||
_buf_head = (_buf_head + 1) % _buf_num;
|
||||
_buf_used--;
|
||||
}
|
||||
|
||||
buf = (short *)_buf[_buf_head];
|
||||
|
||||
int remaining = noutput_items - _samp_avail;
|
||||
|
||||
for (int i = 0; i < remaining; i++)
|
||||
*out++ = gr_complex( float(*(buf + i * 2 + 0)) * (1.0f/32767.5f),
|
||||
float(*(buf + i * 2 + 1)) * (1.0f/32767.5f) );
|
||||
|
||||
_buf_offset = remaining * 2;
|
||||
_samp_avail = (_buf_len / BYTES_PER_SAMPLE) - remaining;
|
||||
}
|
||||
|
||||
return noutput_items;
|
||||
}
|
||||
|
||||
std::vector<std::string> osmosdr_src_c::get_devices()
|
||||
{
|
||||
std::vector< std::string > devices;
|
||||
char buffer[256];
|
||||
|
||||
for (unsigned int i = 0; i < osmosdr_get_device_count(); i++) {
|
||||
std::string args = "osmosdr=" + boost::lexical_cast< std::string >( i );
|
||||
|
||||
std::string label = std::string(osmosdr_get_device_name( i ));
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
osmosdr_get_device_usb_strings( i, NULL, NULL, buffer );
|
||||
std::string serial = std::string(buffer);
|
||||
|
||||
if (serial.length())
|
||||
label += " " + serial;
|
||||
|
||||
args += ",label='" + label + + "'";
|
||||
|
||||
devices.push_back( args );
|
||||
}
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
size_t osmosdr_src_c::get_num_channels()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
osmosdr::meta_range_t osmosdr_src_c::get_sample_rates()
|
||||
{
|
||||
osmosdr::meta_range_t range;
|
||||
|
||||
if (_dev) {
|
||||
int count = osmosdr_get_sample_rates(_dev, NULL);
|
||||
if (count > 0) {
|
||||
uint32_t* rates = new uint32_t[ count ];
|
||||
count = osmosdr_get_sample_rates(_dev, rates);
|
||||
for (int i = 0; i < count; i++)
|
||||
range += osmosdr::range_t( rates[i] );
|
||||
delete[] rates;
|
||||
}
|
||||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
double osmosdr_src_c::set_sample_rate(double rate)
|
||||
{
|
||||
if (_dev) {
|
||||
osmosdr_set_sample_rate( _dev, (uint32_t)rate );
|
||||
}
|
||||
|
||||
return get_sample_rate();
|
||||
}
|
||||
|
||||
double osmosdr_src_c::get_sample_rate()
|
||||
{
|
||||
if (_dev)
|
||||
return (double)osmosdr_get_sample_rate( _dev );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
osmosdr::freq_range_t osmosdr_src_c::get_freq_range( size_t chan )
|
||||
{
|
||||
osmosdr::freq_range_t range;
|
||||
|
||||
/* there is a (temperature dependent) gap between 1100 to 1250 MHz */
|
||||
range += osmosdr::range_t( 52e6, 2.2e9 );
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
double osmosdr_src_c::set_center_freq( double freq, size_t chan )
|
||||
{
|
||||
if (_dev)
|
||||
osmosdr_set_center_freq( _dev, (uint32_t)freq );
|
||||
|
||||
return get_center_freq( chan );
|
||||
}
|
||||
|
||||
double osmosdr_src_c::get_center_freq( size_t chan )
|
||||
{
|
||||
if (_dev)
|
||||
return (double)osmosdr_get_center_freq( _dev );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
double osmosdr_src_c::set_freq_corr( double ppm, size_t chan )
|
||||
{
|
||||
return get_freq_corr( chan );
|
||||
}
|
||||
|
||||
double osmosdr_src_c::get_freq_corr( size_t chan )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<std::string> osmosdr_src_c::get_gain_names( size_t chan )
|
||||
{
|
||||
std::vector< std::string > names;
|
||||
|
||||
names += "LNA";
|
||||
names += "IF";
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
osmosdr::gain_range_t osmosdr_src_c::get_gain_range( size_t chan )
|
||||
{
|
||||
osmosdr::gain_range_t range;
|
||||
|
||||
if (_dev) {
|
||||
int count = osmosdr_get_tuner_gains(_dev, NULL);
|
||||
if (count > 0) {
|
||||
int* gains = new int[ count ];
|
||||
count = osmosdr_get_tuner_gains(_dev, gains);
|
||||
for (int i = 0; i < count; i++)
|
||||
range += osmosdr::range_t( gains[i] / 10.0 );
|
||||
delete[] gains;
|
||||
}
|
||||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
osmosdr::gain_range_t osmosdr_src_c::get_gain_range( const std::string & name, size_t chan )
|
||||
{
|
||||
if ( "IF" == name ) {
|
||||
return osmosdr::gain_range_t(3, 56, 1);
|
||||
}
|
||||
|
||||
return get_gain_range( chan );
|
||||
}
|
||||
|
||||
bool osmosdr_src_c::set_gain_mode( bool automatic, size_t chan )
|
||||
{
|
||||
if (_dev) {
|
||||
if (!osmosdr_set_tuner_gain_mode(_dev, int(!automatic))) {
|
||||
_auto_gain = automatic;
|
||||
}
|
||||
}
|
||||
|
||||
return get_gain_mode(chan);
|
||||
}
|
||||
|
||||
bool osmosdr_src_c::get_gain_mode( size_t chan )
|
||||
{
|
||||
return _auto_gain;
|
||||
}
|
||||
|
||||
double osmosdr_src_c::set_gain( double gain, size_t chan )
|
||||
{
|
||||
osmosdr::gain_range_t rf_gains = osmosdr_src_c::get_gain_range( chan );
|
||||
|
||||
if (_dev) {
|
||||
osmosdr_set_tuner_gain( _dev, int(rf_gains.clip(gain) * 10.0) );
|
||||
}
|
||||
|
||||
return get_gain( chan );
|
||||
}
|
||||
|
||||
double osmosdr_src_c::set_gain( double gain, const std::string & name, size_t chan)
|
||||
{
|
||||
if ( "IF" == name ) {
|
||||
return set_if_gain( gain, chan );
|
||||
}
|
||||
|
||||
return set_gain( gain, chan );
|
||||
}
|
||||
|
||||
double osmosdr_src_c::get_gain( size_t chan )
|
||||
{
|
||||
if ( _dev )
|
||||
return ((double)osmosdr_get_tuner_gain( _dev )) / 10.0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
double osmosdr_src_c::get_gain( const std::string & name, size_t chan )
|
||||
{
|
||||
if ( "IF" == name ) {
|
||||
return _if_gain;
|
||||
}
|
||||
|
||||
return get_gain( chan );
|
||||
}
|
||||
|
||||
double osmosdr_src_c::set_if_gain(double gain, size_t chan)
|
||||
{
|
||||
std::vector< osmosdr::gain_range_t > if_gains;
|
||||
|
||||
if_gains += osmosdr::gain_range_t(-3, 6, 9);
|
||||
if_gains += osmosdr::gain_range_t(0, 9, 3);
|
||||
if_gains += osmosdr::gain_range_t(0, 9, 3);
|
||||
if_gains += osmosdr::gain_range_t(0, 2, 1);
|
||||
if_gains += osmosdr::gain_range_t(3, 15, 3);
|
||||
if_gains += osmosdr::gain_range_t(3, 15, 3);
|
||||
|
||||
std::map< int, double > gains;
|
||||
|
||||
/* initialize with min gains */
|
||||
for (unsigned int i = 0; i < if_gains.size(); i++) {
|
||||
gains[ i + 1 ] = if_gains[ i ].start();
|
||||
}
|
||||
|
||||
for (int i = if_gains.size() - 1; i >= 0; i--) {
|
||||
osmosdr::gain_range_t range = if_gains[ i ];
|
||||
|
||||
double error = gain;
|
||||
|
||||
for( double g = range.start(); g <= range.stop(); g += range.step() ) {
|
||||
|
||||
double sum = 0;
|
||||
for (int j = 0; j < int(gains.size()); j++) {
|
||||
if ( i == j )
|
||||
sum += g;
|
||||
else
|
||||
sum += gains[ j + 1 ];
|
||||
}
|
||||
|
||||
double err = abs(gain - sum);
|
||||
if (err < error) {
|
||||
error = err;
|
||||
gains[ i + 1 ] = g;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
std::cerr << gain << " => "; double sum = 0;
|
||||
for (unsigned int i = 0; i < gains.size(); i++) {
|
||||
sum += gains[ i + 1 ];
|
||||
std::cerr << gains[ i + 1 ] << " ";
|
||||
}
|
||||
std::cerr << " = " << sum << std::endl;
|
||||
#endif
|
||||
if (_dev) {
|
||||
for (unsigned int stage = 1; stage <= gains.size(); stage++) {
|
||||
osmosdr_set_tuner_if_gain( _dev, stage, int(gains[ stage ] * 10.0));
|
||||
}
|
||||
}
|
||||
|
||||
_if_gain = gain;
|
||||
return gain;
|
||||
}
|
||||
|
||||
std::vector< std::string > osmosdr_src_c::get_antennas( size_t chan )
|
||||
{
|
||||
std::vector< std::string > antennas;
|
||||
|
||||
antennas += get_antenna( chan );
|
||||
|
||||
return antennas;
|
||||
}
|
||||
|
||||
std::string osmosdr_src_c::set_antenna( const std::string & antenna, size_t chan )
|
||||
{
|
||||
return get_antenna( chan );
|
||||
}
|
||||
|
||||
std::string osmosdr_src_c::get_antenna( size_t chan )
|
||||
{
|
||||
return "RX";
|
||||
}
|
|
@ -1,140 +0,0 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2012 Dimitri Stolnikov <horiz0n@gmx.net>
|
||||
*
|
||||
* GNU Radio is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Radio is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#ifndef INCLUDED_OSMOSDR_SRC_C_H
|
||||
#define INCLUDED_OSMOSDR_SRC_C_H
|
||||
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
#include <gnuradio/thread/thread.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
#include "source_iface.h"
|
||||
|
||||
class osmosdr_src_c;
|
||||
typedef struct osmosdr_dev osmosdr_dev_t;
|
||||
|
||||
/*
|
||||
* We use boost::shared_ptr's instead of raw pointers for all access
|
||||
* to gr::blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues. This is especially helpful in our hybrid
|
||||
* C++ / Python system.
|
||||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
*/
|
||||
typedef boost::shared_ptr<osmosdr_src_c> osmosdr_src_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of osmosdr_src_c.
|
||||
*
|
||||
* To avoid accidental use of raw pointers, osmosdr_src_c's
|
||||
* constructor is private. osmosdr_make_src_c is the public
|
||||
* interface for creating new instances.
|
||||
*/
|
||||
osmosdr_src_c_sptr osmosdr_make_src_c (const std::string & args = "");
|
||||
|
||||
/*!
|
||||
* \brief Provides a stream of complex samples.
|
||||
* \ingroup block
|
||||
*
|
||||
* \sa sink for a version that subclasses gr::hier_block2.
|
||||
*/
|
||||
class osmosdr_src_c :
|
||||
public gr::sync_block,
|
||||
public source_iface
|
||||
{
|
||||
private:
|
||||
// The friend declaration allows osmosdr_make_src_c to
|
||||
// access the private constructor.
|
||||
|
||||
friend osmosdr_src_c_sptr osmosdr_make_src_c (const std::string & args);
|
||||
|
||||
/*!
|
||||
* \brief Provides a stream of complex samples.
|
||||
*/
|
||||
osmosdr_src_c (const std::string & args); // private constructor
|
||||
|
||||
public:
|
||||
~osmosdr_src_c (); // public destructor
|
||||
|
||||
int work( int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items );
|
||||
|
||||
static std::vector< std::string > get_devices();
|
||||
|
||||
size_t get_num_channels( void );
|
||||
|
||||
osmosdr::meta_range_t get_sample_rates( void );
|
||||
double set_sample_rate( double rate );
|
||||
double get_sample_rate( void );
|
||||
|
||||
osmosdr::freq_range_t get_freq_range( size_t chan = 0 );
|
||||
double set_center_freq( double freq, size_t chan = 0 );
|
||||
double get_center_freq( size_t chan = 0 );
|
||||
double set_freq_corr( double ppm, size_t chan = 0 );
|
||||
double get_freq_corr( size_t chan = 0 );
|
||||
|
||||
std::vector<std::string> get_gain_names( size_t chan = 0 );
|
||||
osmosdr::gain_range_t get_gain_range( size_t chan = 0 );
|
||||
osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 );
|
||||
bool set_gain_mode( bool automatic, size_t chan = 0 );
|
||||
bool get_gain_mode( size_t chan = 0 );
|
||||
double set_gain( double gain, size_t chan = 0 );
|
||||
double set_gain( double gain, const std::string & name, size_t chan = 0 );
|
||||
double get_gain( size_t chan = 0 );
|
||||
double get_gain( const std::string & name, size_t chan = 0 );
|
||||
|
||||
double set_if_gain( double gain, size_t chan = 0 );
|
||||
|
||||
std::vector< std::string > get_antennas( size_t chan = 0 );
|
||||
std::string set_antenna( const std::string & antenna, size_t chan = 0 );
|
||||
std::string get_antenna( size_t chan = 0 );
|
||||
|
||||
private:
|
||||
static void _osmosdr_callback(unsigned char *buf, uint32_t len, void *ctx);
|
||||
void osmosdr_callback(unsigned char *buf, uint32_t len);
|
||||
static void _osmosdr_wait(osmosdr_src_c *obj);
|
||||
void osmosdr_wait();
|
||||
|
||||
osmosdr_dev_t *_dev;
|
||||
gr::thread::thread _thread;
|
||||
unsigned short **_buf;
|
||||
unsigned int _buf_num;
|
||||
unsigned int _buf_len;
|
||||
unsigned int _buf_head;
|
||||
unsigned int _buf_used;
|
||||
std::mutex _buf_mutex;
|
||||
std::condition_variable _buf_cond;
|
||||
bool _running;
|
||||
|
||||
unsigned int _buf_offset;
|
||||
int _samp_avail;
|
||||
|
||||
bool _auto_gain;
|
||||
double _if_gain;
|
||||
unsigned int _skipped;
|
||||
};
|
||||
|
||||
#endif /* INCLUDED_OSMOSDR_SRC_C_H */
|
|
@ -18,7 +18,6 @@
|
|||
#include <osmosdr/ranges.h>
|
||||
#include <stdexcept>
|
||||
#include <boost/math/special_functions/round.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
|
@ -102,7 +101,7 @@ meta_range_t::meta_range_t(
|
|||
double meta_range_t::start(void) const{
|
||||
check_meta_range_monotonic(*this);
|
||||
double min_start = this->front().start();
|
||||
BOOST_FOREACH(const range_t &r, (*this)){
|
||||
for (const range_t &r : (*this)){
|
||||
min_start = std::min(min_start, r.start());
|
||||
}
|
||||
return min_start;
|
||||
|
@ -111,7 +110,7 @@ double meta_range_t::start(void) const{
|
|||
double meta_range_t::stop(void) const{
|
||||
check_meta_range_monotonic(*this);
|
||||
double max_stop = this->front().stop();
|
||||
BOOST_FOREACH(const range_t &r, (*this)){
|
||||
for (const range_t &r : (*this)){
|
||||
max_stop = std::max(max_stop, r.stop());
|
||||
}
|
||||
return max_stop;
|
||||
|
@ -121,7 +120,7 @@ double meta_range_t::step(void) const{
|
|||
check_meta_range_monotonic(*this);
|
||||
std::vector<double> non_zero_steps;
|
||||
range_t last = this->front();
|
||||
BOOST_FOREACH(const range_t &r, (*this)){
|
||||
for (const range_t &r : (*this)){
|
||||
//steps at each range
|
||||
if (r.step() > 0) non_zero_steps.push_back(r.step());
|
||||
//and steps in-between ranges
|
||||
|
@ -137,7 +136,7 @@ double meta_range_t::step(void) const{
|
|||
double meta_range_t::clip(double value, bool clip_step) const{
|
||||
check_meta_range_monotonic(*this);
|
||||
double last_stop = this->front().stop();
|
||||
BOOST_FOREACH(const range_t &r, (*this)){
|
||||
for (const range_t &r : (*this)){
|
||||
//in-between ranges, clip to nearest
|
||||
if (value < r.start()){
|
||||
return (std::abs(value - r.start()) < std::abs(value - last_stop))?
|
||||
|
@ -157,7 +156,7 @@ double meta_range_t::clip(double value, bool clip_step) const{
|
|||
std::vector<double> meta_range_t::values() const {
|
||||
std::vector<double> values;
|
||||
|
||||
BOOST_FOREACH(const range_t &r, (*this)) {
|
||||
for (const range_t &r : (*this)) {
|
||||
if (r.start() != r.stop()) {
|
||||
if ( r.step() == 0 ) {
|
||||
values.push_back( r.start() );
|
||||
|
@ -177,7 +176,7 @@ std::vector<double> meta_range_t::values() const {
|
|||
|
||||
const std::string meta_range_t::to_pp_string(void) const{
|
||||
std::stringstream ss;
|
||||
BOOST_FOREACH(const range_t &r, (*this)){
|
||||
for (const range_t &r : (*this)){
|
||||
ss << r.to_pp_string() << std::endl;
|
||||
}
|
||||
return ss.str();
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
class redpitaya_sink_c;
|
||||
|
||||
typedef boost::shared_ptr< redpitaya_sink_c > redpitaya_sink_c_sptr;
|
||||
typedef std::shared_ptr< redpitaya_sink_c > redpitaya_sink_c_sptr;
|
||||
|
||||
redpitaya_sink_c_sptr make_redpitaya_sink_c( const std::string & args = "" );
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
class redpitaya_source_c;
|
||||
|
||||
typedef boost::shared_ptr< redpitaya_source_c > redpitaya_source_c_sptr;
|
||||
typedef std::shared_ptr< redpitaya_source_c > redpitaya_source_c_sptr;
|
||||
|
||||
redpitaya_source_c_sptr make_redpitaya_source_c( const std::string & args = "" );
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifndef USE_ASIO
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
@ -35,7 +34,6 @@
|
|||
#include <netinet/udp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
@ -54,9 +52,6 @@
|
|||
#include <boost/format.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#ifdef USE_ASIO
|
||||
#include <boost/asio/deadline_timer.hpp>
|
||||
#endif
|
||||
|
||||
#include <gnuradio/io_signature.h>
|
||||
|
||||
|
@ -64,9 +59,6 @@
|
|||
#include "rfspace_source_c.h"
|
||||
|
||||
using namespace boost::assign;
|
||||
#ifdef USE_ASIO
|
||||
using boost::asio::deadline_timer;
|
||||
#endif
|
||||
|
||||
#define DEFAULT_HOST "127.0.0.1" /* We assume a running "siqs" from CuteSDR project */
|
||||
#define DEFAULT_PORT 50000
|
||||
|
@ -102,15 +94,8 @@ rfspace_source_c::rfspace_source_c (const std::string &args)
|
|||
gr::io_signature::make (MIN_IN, MAX_IN, sizeof (gr_complex)),
|
||||
gr::io_signature::make (MIN_OUT, MAX_OUT, sizeof (gr_complex))),
|
||||
_radio(RADIO_UNKNOWN),
|
||||
#ifdef USE_ASIO
|
||||
_io_service(),
|
||||
_resolver(_io_service),
|
||||
_t(_io_service),
|
||||
_u(_io_service),
|
||||
#else
|
||||
_tcp(-1),
|
||||
_udp(-1),
|
||||
#endif
|
||||
_usb(-1),
|
||||
_running(false),
|
||||
_keep_running(false),
|
||||
|
@ -239,30 +224,6 @@ rfspace_source_c::rfspace_source_c (const std::string &args)
|
|||
/* SDR-IP 4.4.4 Data Output UDP IP and Port Address */
|
||||
/* NETSDR 4.4.3 Data Output UDP IP and Port Address */
|
||||
|
||||
#ifdef USE_ASIO
|
||||
|
||||
tcp::resolver::query query(tcp::v4(), host.c_str(), port_str.c_str());
|
||||
tcp::resolver::iterator iterator = _resolver.resolve(query);
|
||||
|
||||
boost::system::error_code ec;
|
||||
|
||||
boost::asio::connect(_t, iterator, ec);
|
||||
if ( ec )
|
||||
throw std::runtime_error(ec.message() + " (" + host + ":" + port_str + ")");
|
||||
|
||||
_u.open(udp::v4(), ec);
|
||||
if ( ec )
|
||||
throw std::runtime_error(ec.message());
|
||||
|
||||
_u.bind(udp::endpoint(udp::v4(), DEFAULT_PORT), ec);
|
||||
if ( ec )
|
||||
throw std::runtime_error(ec.message());
|
||||
|
||||
_u.set_option(udp::socket::reuse_address(true));
|
||||
_t.set_option(udp::socket::reuse_address(true));
|
||||
|
||||
#else
|
||||
|
||||
if ( (_tcp = socket(AF_INET, SOCK_STREAM, 0) ) < 0)
|
||||
{
|
||||
throw std::runtime_error("Could not create TCP socket");
|
||||
|
@ -339,8 +300,6 @@ rfspace_source_c::rfspace_source_c (const std::string &args)
|
|||
throw std::runtime_error("Bind of UDP socket failed: " + std::string(strerror(errno)));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* Wait 10 ms before sending queries to device (required for networked radios). */
|
||||
|
@ -506,10 +465,8 @@ rfspace_source_c::rfspace_source_c (const std::string &args)
|
|||
*/
|
||||
rfspace_source_c::~rfspace_source_c ()
|
||||
{
|
||||
#ifndef USE_ASIO
|
||||
close(_tcp);
|
||||
close(_udp);
|
||||
#endif
|
||||
|
||||
if ( RFSPACE_SDR_IQ == _radio )
|
||||
{
|
||||
|
@ -600,11 +557,6 @@ bool rfspace_source_c::transaction( const unsigned char *cmd, size_t size,
|
|||
{
|
||||
std::lock_guard<std::mutex> lock(_tcp_lock);
|
||||
|
||||
#ifdef USE_ASIO
|
||||
_t.write_some( boost::asio::buffer(cmd, size) );
|
||||
|
||||
rx_bytes = _t.read_some( boost::asio::buffer(data, sizeof(data)) );
|
||||
#else
|
||||
if ( write(_tcp, cmd, size) != (int)size )
|
||||
return false;
|
||||
|
||||
|
@ -624,7 +576,6 @@ bool rfspace_source_c::transaction( const unsigned char *cmd, size_t size,
|
|||
return false;
|
||||
|
||||
rx_bytes = 2 + length; /* header + payload */
|
||||
#endif
|
||||
}
|
||||
|
||||
response.resize( rx_bytes );
|
||||
|
@ -852,10 +803,6 @@ int rfspace_source_c::work( int noutput_items,
|
|||
return noutput_items;
|
||||
}
|
||||
|
||||
#ifdef USE_ASIO
|
||||
udp::endpoint ep;
|
||||
size_t rx_bytes = _u.receive_from( boost::asio::buffer(data, sizeof(data)), ep );
|
||||
#else
|
||||
struct sockaddr_in sa_in; /* remote address */
|
||||
socklen_t addrlen = sizeof(sa_in); /* length of addresses */
|
||||
ssize_t rx_bytes = recvfrom(_udp, data, sizeof(data), 0, (struct sockaddr *)&sa_in, &addrlen);
|
||||
|
@ -864,7 +811,6 @@ int rfspace_source_c::work( int noutput_items,
|
|||
std::cerr << "recvfrom returned " << rx_bytes << std::endl;
|
||||
return WORK_DONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define HEADER_SIZE 2
|
||||
#define SEQNUM_SIZE 2
|
||||
|
@ -892,11 +838,7 @@ int rfspace_source_c::work( int noutput_items,
|
|||
if ( diff > 1 )
|
||||
{
|
||||
std::cerr << "Lost " << diff << " packets from "
|
||||
#ifdef USE_ASIO
|
||||
<< ep
|
||||
#else
|
||||
<< inet_ntoa(sa_in.sin_addr) << ":" << ntohs(sa_in.sin_port)
|
||||
#endif
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
|
@ -977,48 +919,11 @@ typedef struct
|
|||
uint16_t port;
|
||||
} unit_t;
|
||||
|
||||
#ifdef USE_ASIO
|
||||
static void handle_receive( const boost::system::error_code& ec,
|
||||
std::size_t length,
|
||||
boost::system::error_code* out_ec,
|
||||
std::size_t* out_length )
|
||||
{
|
||||
*out_ec = ec;
|
||||
*out_length = length;
|
||||
}
|
||||
|
||||
static void handle_timer( const boost::system::error_code& ec,
|
||||
boost::system::error_code* out_ec )
|
||||
{
|
||||
*out_ec = boost::asio::error::timed_out;
|
||||
}
|
||||
#endif
|
||||
|
||||
static std::vector < unit_t > discover_netsdr()
|
||||
{
|
||||
std::vector < unit_t > units;
|
||||
|
||||
#ifdef USE_ASIO
|
||||
boost::system::error_code ec;
|
||||
boost::asio::io_service ios;
|
||||
udp::socket socket(ios);
|
||||
deadline_timer timer(ios);
|
||||
|
||||
timer.expires_at(boost::posix_time::pos_infin);
|
||||
|
||||
socket.open(udp::v4(), ec);
|
||||
|
||||
if ( ec )
|
||||
return units;
|
||||
|
||||
socket.bind(udp::endpoint(udp::v4(), DISCOVER_CLIENT_PORT), ec);
|
||||
|
||||
if ( ec )
|
||||
return units;
|
||||
|
||||
socket.set_option(udp::socket::reuse_address(true));
|
||||
socket.set_option(boost::asio::socket_base::broadcast(true));
|
||||
#else
|
||||
int sock;
|
||||
|
||||
if ( (sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0 )
|
||||
|
@ -1058,7 +963,6 @@ static std::vector < unit_t > discover_netsdr()
|
|||
close(sock);
|
||||
return units;
|
||||
}
|
||||
#endif
|
||||
discover_common_msg_t tx_msg;
|
||||
memset( (void *)&tx_msg, 0, sizeof(discover_common_msg_t) );
|
||||
|
||||
|
@ -1067,64 +971,18 @@ static std::vector < unit_t > discover_netsdr()
|
|||
tx_msg.key[0] = KEY0;
|
||||
tx_msg.key[1] = KEY1;
|
||||
tx_msg.op = MSG_REQ;
|
||||
#ifdef USE_ASIO
|
||||
udp::endpoint ep(boost::asio::ip::address_v4::broadcast(), DISCOVER_SERVER_PORT);
|
||||
socket.send_to(boost::asio::buffer(&tx_msg, sizeof(tx_msg)), ep);
|
||||
#else
|
||||
sendto(sock, &tx_msg, sizeof(tx_msg), 0, (struct sockaddr *)&peer_sa, sizeof(peer_sa));
|
||||
#endif
|
||||
while ( true )
|
||||
{
|
||||
std::size_t rx_bytes = 0;
|
||||
unsigned char data[1024*2];
|
||||
|
||||
#ifdef USE_ASIO
|
||||
// Set up the variables that receive the result of the asynchronous
|
||||
// operation. The error code is set to would_block to signal that the
|
||||
// operation is incomplete. Asio guarantees that its asynchronous
|
||||
// operations will never fail with would_block, so any other value in
|
||||
// ec indicates completion.
|
||||
ec = boost::asio::error::would_block;
|
||||
|
||||
// Start the asynchronous receive operation. The handle_receive function
|
||||
// used as a callback will update the ec and rx_bytes variables.
|
||||
socket.async_receive( boost::asio::buffer(data, sizeof(data)),
|
||||
boost::bind(handle_receive, _1, _2, &ec, &rx_bytes) );
|
||||
|
||||
// Set a deadline for the asynchronous operation.
|
||||
timer.expires_from_now( boost::posix_time::milliseconds(10) );
|
||||
|
||||
// Start an asynchronous wait on the timer. The handle_timer function
|
||||
// used as a callback will update the ec variable.
|
||||
timer.async_wait( boost::bind(handle_timer, _1, &ec) );
|
||||
|
||||
// Reset the io_service in preparation for a subsequent run_one() invocation.
|
||||
ios.reset();
|
||||
|
||||
// Block until at least one asynchronous operation has completed.
|
||||
do ios.run_one(); while ( ec == boost::asio::error::would_block );
|
||||
|
||||
if ( boost::asio::error::timed_out == ec ) /* timer was first to complete */
|
||||
{
|
||||
// Please note that cancel() has portability issues on some versions of
|
||||
// Microsoft Windows, and it may be necessary to use close() instead.
|
||||
// Consult the documentation for cancel() for further information.
|
||||
socket.cancel();
|
||||
|
||||
break;
|
||||
}
|
||||
else /* socket was first to complete */
|
||||
{
|
||||
timer.cancel();
|
||||
}
|
||||
#else
|
||||
socklen_t addrlen = sizeof(peer_sa); /* length of addresses */
|
||||
int nbytes = recvfrom(sock, data, sizeof(data), 0, (struct sockaddr *)&peer_sa, &addrlen);
|
||||
if ( nbytes <= 0 )
|
||||
break;
|
||||
|
||||
rx_bytes = nbytes;
|
||||
#endif
|
||||
|
||||
if ( rx_bytes >= sizeof(discover_common_msg_t) )
|
||||
{
|
||||
|
@ -1151,11 +1009,7 @@ static std::vector < unit_t > discover_netsdr()
|
|||
}
|
||||
}
|
||||
}
|
||||
#ifdef USE_ASIO
|
||||
socket.close(ec);
|
||||
#else
|
||||
close(sock);
|
||||
#endif
|
||||
|
||||
return units;
|
||||
}
|
||||
|
@ -1296,7 +1150,7 @@ std::vector<std::string> rfspace_source_c::get_devices( bool fake )
|
|||
|
||||
std::vector < unit_t > units = discover_netsdr();
|
||||
|
||||
BOOST_FOREACH( unit_t u, units )
|
||||
for (unit_t u : units)
|
||||
{
|
||||
// std::cerr << u.name << " " << u.sn << " " << u.addr << ":" << u.port
|
||||
// << std::endl;
|
||||
|
@ -1310,7 +1164,7 @@ std::vector<std::string> rfspace_source_c::get_devices( bool fake )
|
|||
|
||||
units = discover_sdr_iq();
|
||||
|
||||
BOOST_FOREACH( unit_t u, units )
|
||||
for (unit_t u : units)
|
||||
{
|
||||
// std::cerr << u.name << " " << u.sn << " " << u.addr << ":" << u.port
|
||||
// << std::endl;
|
||||
|
|
|
@ -20,11 +20,6 @@
|
|||
#ifndef INCLUDED_RFSPACE_SOURCE_C_H
|
||||
#define INCLUDED_RFSPACE_SOURCE_C_H
|
||||
|
||||
//#define USE_ASIO
|
||||
|
||||
#ifdef USE_ASIO
|
||||
#include <boost/asio.hpp>
|
||||
#endif
|
||||
#include <gnuradio/thread/thread.h>
|
||||
#include <gnuradio/block.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
@ -36,10 +31,6 @@
|
|||
|
||||
#include "osmosdr/ranges.h"
|
||||
#include "source_iface.h"
|
||||
#ifdef USE_ASIO
|
||||
using boost::asio::ip::tcp;
|
||||
using boost::asio::ip::udp;
|
||||
#endif
|
||||
class rfspace_source_c;
|
||||
|
||||
#ifndef SOCKET
|
||||
|
@ -47,7 +38,7 @@ class rfspace_source_c;
|
|||
#endif
|
||||
|
||||
/*
|
||||
* We use boost::shared_ptr's instead of raw pointers for all access
|
||||
* We use std::shared_ptr's instead of raw pointers for all access
|
||||
* to gr_blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues. This is especially helpful in our hybrid
|
||||
|
@ -55,9 +46,9 @@ class rfspace_source_c;
|
|||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
* As a convention, the _sptr suffix indicates a std::shared_ptr
|
||||
*/
|
||||
typedef boost::shared_ptr<rfspace_source_c> rfspace_source_c_sptr;
|
||||
typedef std::shared_ptr<rfspace_source_c> rfspace_source_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of rfspace_source_c.
|
||||
|
@ -144,15 +135,8 @@ private: /* members */
|
|||
|
||||
radio_type _radio;
|
||||
|
||||
#ifdef USE_ASIO
|
||||
boost::asio::io_service _io_service;
|
||||
tcp::resolver _resolver;
|
||||
tcp::socket _t;
|
||||
udp::socket _u;
|
||||
#else
|
||||
SOCKET _tcp;
|
||||
SOCKET _udp;
|
||||
#endif
|
||||
int _usb;
|
||||
bool _running;
|
||||
bool _keep_running;
|
||||
|
|
|
@ -35,7 +35,7 @@ class rtl_source_c;
|
|||
typedef struct rtlsdr_dev rtlsdr_dev_t;
|
||||
|
||||
/*
|
||||
* We use boost::shared_ptr's instead of raw pointers for all access
|
||||
* We use std::shared_ptr's instead of raw pointers for all access
|
||||
* to gr::blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues. This is especially helpful in our hybrid
|
||||
|
@ -43,9 +43,9 @@ typedef struct rtlsdr_dev rtlsdr_dev_t;
|
|||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
* As a convention, the _sptr suffix indicates a std::shared_ptr
|
||||
*/
|
||||
typedef boost::shared_ptr<rtl_source_c> rtl_source_c_sptr;
|
||||
typedef std::shared_ptr<rtl_source_c> rtl_source_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of rtl_source_c.
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
class rtl_tcp_source_c;
|
||||
|
||||
typedef boost::shared_ptr< rtl_tcp_source_c > rtl_tcp_source_c_sptr;
|
||||
typedef std::shared_ptr< rtl_tcp_source_c > rtl_tcp_source_c_sptr;
|
||||
|
||||
rtl_tcp_source_c_sptr make_rtl_tcp_source_c( const std::string & args = "" );
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ enum rtlsdr_tuner {
|
|||
};
|
||||
|
||||
class rtl_tcp_source_f;
|
||||
typedef boost::shared_ptr<rtl_tcp_source_f> rtl_tcp_source_f_sptr;
|
||||
typedef std::shared_ptr<rtl_tcp_source_f> rtl_tcp_source_f_sptr;
|
||||
|
||||
rtl_tcp_source_f_sptr make_rtl_tcp_source_f (
|
||||
size_t itemsize,
|
||||
|
|
|
@ -36,7 +36,7 @@ class sdrplay_source_c;
|
|||
typedef struct sdrplay_dev sdrplay_dev_t;
|
||||
|
||||
/*
|
||||
* We use boost::shared_ptr's instead of raw pointers for all access
|
||||
* We use std::shared_ptr's instead of raw pointers for all access
|
||||
* to gr::blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues. This is especially helpful in our hybrid
|
||||
|
@ -44,9 +44,9 @@ typedef struct sdrplay_dev sdrplay_dev_t;
|
|||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
* As a convention, the _sptr suffix indicates a std::shared_ptr
|
||||
*/
|
||||
typedef boost::shared_ptr<sdrplay_source_c> sdrplay_source_c_sptr;
|
||||
typedef std::shared_ptr<sdrplay_source_c> sdrplay_source_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of sdrplay_source_c.
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
class sink_iface
|
||||
{
|
||||
public:
|
||||
virtual ~sink_iface() = default;
|
||||
|
||||
/*!
|
||||
* Get the number of channels the underlying radio hardware offers.
|
||||
* \return the number of available channels
|
||||
|
@ -201,6 +203,7 @@ public:
|
|||
|
||||
/*!
|
||||
* Select the active antenna of the underlying radio hardware.
|
||||
* \param antenna the antenna name
|
||||
* \param chan the channel index 0 to N-1
|
||||
* \return the actual antenna's name
|
||||
*/
|
||||
|
|
105
lib/sink_impl.cc
105
lib/sink_impl.cc
|
@ -48,6 +48,9 @@
|
|||
#ifdef ENABLE_FREESRP
|
||||
#include <freesrp_sink_c.h>
|
||||
#endif
|
||||
#ifdef ENABLE_XTRX
|
||||
#include "xtrx_sink_c.h"
|
||||
#endif
|
||||
#ifdef ENABLE_FILE
|
||||
#include "file_sink_c.h"
|
||||
#endif
|
||||
|
@ -99,6 +102,9 @@ sink_impl::sink_impl( const std::string &args )
|
|||
#ifdef ENABLE_FREESRP
|
||||
dev_types.push_back("freesrp");
|
||||
#endif
|
||||
#ifdef ENABLE_XTRX
|
||||
dev_types.push_back("xtrx");
|
||||
#endif
|
||||
#ifdef ENABLE_FILE
|
||||
dev_types.push_back("file");
|
||||
#endif
|
||||
|
@ -107,13 +113,13 @@ sink_impl::sink_impl( const std::string &args )
|
|||
<< GR_OSMOSDR_VERSION << " (" << GR_OSMOSDR_LIBVER << ") "
|
||||
<< "gnuradio " << gr::version() << std::endl;
|
||||
std::cerr << "built-in sink types: ";
|
||||
BOOST_FOREACH(std::string dev_type, dev_types)
|
||||
for (std::string dev_type : dev_types)
|
||||
std::cerr << dev_type << " ";
|
||||
std::cerr << std::endl;
|
||||
|
||||
BOOST_FOREACH(std::string arg, arg_list) {
|
||||
for (std::string arg : arg_list) {
|
||||
dict_t dict = params_to_dict(arg);
|
||||
BOOST_FOREACH(std::string dev_type, dev_types) {
|
||||
for (std::string dev_type : dev_types) {
|
||||
if ( dict.count( dev_type ) ) {
|
||||
device_specified = true;
|
||||
break;
|
||||
|
@ -124,36 +130,40 @@ sink_impl::sink_impl( const std::string &args )
|
|||
if ( ! device_specified ) {
|
||||
std::vector< std::string > dev_list;
|
||||
#ifdef ENABLE_UHD
|
||||
BOOST_FOREACH( std::string dev, uhd_sink_c::get_devices() )
|
||||
for (std::string dev : uhd_sink_c::get_devices())
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
#ifdef ENABLE_BLADERF
|
||||
BOOST_FOREACH( std::string dev, bladerf_sink_c::get_devices() )
|
||||
for (std::string dev : bladerf_sink_c::get_devices())
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
#ifdef ENABLE_HACKRF
|
||||
BOOST_FOREACH( std::string dev, hackrf_sink_c::get_devices() )
|
||||
for (std::string dev : hackrf_sink_c::get_devices())
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
#ifdef ENABLE_SOAPY
|
||||
BOOST_FOREACH( std::string dev, soapy_sink_c::get_devices() )
|
||||
for (std::string dev : soapy_sink_c::get_devices())
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
#ifdef ENABLE_REDPITAYA
|
||||
BOOST_FOREACH( std::string dev, redpitaya_sink_c::get_devices() )
|
||||
for (std::string dev : redpitaya_sink_c::get_devices())
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
#ifdef ENABLE_FREESRP
|
||||
BOOST_FOREACH( std::string dev, freesrp_sink_c::get_devices() )
|
||||
for (std::string dev : freesrp_sink_c::get_devices())
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
#ifdef ENABLE_XTRX
|
||||
for (std::string dev : xtrx_sink_c::get_devices())
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
#ifdef ENABLE_FILE
|
||||
BOOST_FOREACH( std::string dev, file_sink_c::get_devices() )
|
||||
for (std::string dev : file_sink_c::get_devices())
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
|
||||
// std::cerr << std::endl;
|
||||
// BOOST_FOREACH( std::string dev, dev_list )
|
||||
// for (std::string dev : dev_list)
|
||||
// std::cerr << "'" << dev << "'" << std::endl;
|
||||
|
||||
if ( dev_list.size() )
|
||||
|
@ -162,12 +172,12 @@ sink_impl::sink_impl( const std::string &args )
|
|||
throw std::runtime_error("No supported devices found (check the connection and/or udev rules).");
|
||||
}
|
||||
|
||||
BOOST_FOREACH(std::string arg, arg_list) {
|
||||
for (std::string arg : arg_list) {
|
||||
|
||||
dict_t dict = params_to_dict(arg);
|
||||
|
||||
// std::cerr << std::endl;
|
||||
// BOOST_FOREACH( dict_t::value_type &entry, dict )
|
||||
// for (dict_t::value_type &entry : dict)
|
||||
// std::cerr << "'" << entry.first << "' = '" << entry.second << "'" << std::endl;
|
||||
|
||||
sink_iface *iface = NULL;
|
||||
|
@ -209,6 +219,12 @@ sink_impl::sink_impl( const std::string &args )
|
|||
block = sink; iface = sink.get();
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_XTRX
|
||||
if ( dict.count("xtrx") ) {
|
||||
xtrx_sink_c_sptr sink = make_xtrx_sink_c( arg );
|
||||
block = sink; iface = sink.get();
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_FILE
|
||||
if ( dict.count("file") ) {
|
||||
file_sink_c_sptr sink = make_file_sink_c( arg );
|
||||
|
@ -229,13 +245,20 @@ sink_impl::sink_impl( const std::string &args )
|
|||
|
||||
if (!_devs.size())
|
||||
throw std::runtime_error("No devices specified via device arguments.");
|
||||
|
||||
/* Populate the _gain and _gain_mode arrays with the hardware state */
|
||||
for ( sink_iface *dev : _devs )
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++) {
|
||||
_gain_mode[dev_chan] = dev->get_gain_mode(dev_chan);
|
||||
_gain[dev_chan] = dev->get_gain(dev_chan);
|
||||
}
|
||||
}
|
||||
|
||||
size_t sink_impl::get_num_channels()
|
||||
{
|
||||
size_t channels = 0;
|
||||
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
channels += dev->get_num_channels();
|
||||
|
||||
return channels;
|
||||
|
@ -263,7 +286,7 @@ double sink_impl::set_sample_rate(double rate)
|
|||
if (_devs.empty())
|
||||
throw std::runtime_error(NO_DEVICES_MSG);
|
||||
#endif
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
sample_rate = dev->set_sample_rate(rate);
|
||||
|
||||
_sample_rate = sample_rate;
|
||||
|
@ -288,7 +311,7 @@ double sink_impl::get_sample_rate()
|
|||
osmosdr::freq_range_t sink_impl::get_freq_range( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_freq_range( dev_chan );
|
||||
|
@ -299,7 +322,7 @@ osmosdr::freq_range_t sink_impl::get_freq_range( size_t chan )
|
|||
double sink_impl::set_center_freq( double freq, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ ) {
|
||||
if ( _center_freq[ chan ] != freq ) {
|
||||
|
@ -314,7 +337,7 @@ double sink_impl::set_center_freq( double freq, size_t chan )
|
|||
double sink_impl::get_center_freq( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_center_freq( dev_chan );
|
||||
|
@ -325,7 +348,7 @@ double sink_impl::get_center_freq( size_t chan )
|
|||
double sink_impl::set_freq_corr( double ppm, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ ) {
|
||||
if ( _freq_corr[ chan ] != ppm ) {
|
||||
|
@ -340,7 +363,7 @@ double sink_impl::set_freq_corr( double ppm, size_t chan )
|
|||
double sink_impl::get_freq_corr( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_freq_corr( dev_chan );
|
||||
|
@ -351,7 +374,7 @@ double sink_impl::get_freq_corr( size_t chan )
|
|||
std::vector<std::string> sink_impl::get_gain_names( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_gain_names( dev_chan );
|
||||
|
@ -362,7 +385,7 @@ std::vector<std::string> sink_impl::get_gain_names( size_t chan )
|
|||
osmosdr::gain_range_t sink_impl::get_gain_range( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_gain_range( dev_chan );
|
||||
|
@ -373,7 +396,7 @@ osmosdr::gain_range_t sink_impl::get_gain_range( size_t chan )
|
|||
osmosdr::gain_range_t sink_impl::get_gain_range( const std::string & name, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_gain_range( name, dev_chan );
|
||||
|
@ -384,7 +407,7 @@ osmosdr::gain_range_t sink_impl::get_gain_range( const std::string & name, size_
|
|||
bool sink_impl::set_gain_mode( bool automatic, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ ) {
|
||||
if ( _gain_mode[ chan ] != automatic ) {
|
||||
|
@ -402,7 +425,7 @@ bool sink_impl::set_gain_mode( bool automatic, size_t chan )
|
|||
bool sink_impl::get_gain_mode( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_gain_mode( dev_chan );
|
||||
|
@ -413,7 +436,7 @@ bool sink_impl::get_gain_mode( size_t chan )
|
|||
double sink_impl::set_gain( double gain, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ ) {
|
||||
if ( _gain[ chan ] != gain ) {
|
||||
|
@ -428,7 +451,7 @@ double sink_impl::set_gain( double gain, size_t chan )
|
|||
double sink_impl::set_gain( double gain, const std::string & name, size_t chan)
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->set_gain( gain, name, dev_chan );
|
||||
|
@ -439,7 +462,7 @@ double sink_impl::set_gain( double gain, const std::string & name, size_t chan)
|
|||
double sink_impl::get_gain( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_gain( dev_chan );
|
||||
|
@ -450,7 +473,7 @@ double sink_impl::get_gain( size_t chan )
|
|||
double sink_impl::get_gain( const std::string & name, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_gain( name, dev_chan );
|
||||
|
@ -461,7 +484,7 @@ double sink_impl::get_gain( const std::string & name, size_t chan )
|
|||
double sink_impl::set_if_gain( double gain, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ ) {
|
||||
if ( _if_gain[ chan ] != gain ) {
|
||||
|
@ -476,7 +499,7 @@ double sink_impl::set_if_gain( double gain, size_t chan )
|
|||
double sink_impl::set_bb_gain( double gain, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ ) {
|
||||
if ( _bb_gain[ chan ] != gain ) {
|
||||
|
@ -491,7 +514,7 @@ double sink_impl::set_bb_gain( double gain, size_t chan )
|
|||
std::vector< std::string > sink_impl::get_antennas( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_antennas( dev_chan );
|
||||
|
@ -502,7 +525,7 @@ std::vector< std::string > sink_impl::get_antennas( size_t chan )
|
|||
std::string sink_impl::set_antenna( const std::string & antenna, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ ) {
|
||||
if ( _antenna[ chan ] != antenna ) {
|
||||
|
@ -517,7 +540,7 @@ std::string sink_impl::set_antenna( const std::string & antenna, size_t chan )
|
|||
std::string sink_impl::get_antenna( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_antenna( dev_chan );
|
||||
|
@ -528,7 +551,7 @@ std::string sink_impl::get_antenna( size_t chan )
|
|||
void sink_impl::set_dc_offset( const std::complex<double> &offset, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
dev->set_dc_offset( offset, dev_chan );
|
||||
|
@ -537,7 +560,7 @@ void sink_impl::set_dc_offset( const std::complex<double> &offset, size_t chan )
|
|||
void sink_impl::set_iq_balance( const std::complex<double> &balance, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
dev->set_iq_balance( balance, dev_chan );
|
||||
|
@ -546,7 +569,7 @@ void sink_impl::set_iq_balance( const std::complex<double> &balance, size_t chan
|
|||
double sink_impl::set_bandwidth( double bandwidth, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ ) {
|
||||
if ( _bandwidth[ chan ] != bandwidth || 0.0f == bandwidth ) {
|
||||
|
@ -561,7 +584,7 @@ double sink_impl::set_bandwidth( double bandwidth, size_t chan )
|
|||
double sink_impl::get_bandwidth( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_bandwidth( dev_chan );
|
||||
|
@ -572,7 +595,7 @@ double sink_impl::get_bandwidth( size_t chan )
|
|||
osmosdr::freq_range_t sink_impl::get_bandwidth_range( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_bandwidth_range( dev_chan );
|
||||
|
@ -665,7 +688,7 @@ void sink_impl::set_time_now(const osmosdr::time_spec_t &time_spec, size_t mboar
|
|||
|
||||
void sink_impl::set_time_next_pps(const osmosdr::time_spec_t &time_spec)
|
||||
{
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
{
|
||||
dev->set_time_next_pps( time_spec );
|
||||
}
|
||||
|
@ -673,7 +696,7 @@ void sink_impl::set_time_next_pps(const osmosdr::time_spec_t &time_spec)
|
|||
|
||||
void sink_impl::set_time_unknown_pps(const osmosdr::time_spec_t &time_spec)
|
||||
{
|
||||
BOOST_FOREACH( sink_iface *dev, _devs )
|
||||
for (sink_iface *dev : _devs)
|
||||
{
|
||||
dev->set_time_unknown_pps( time_spec );
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ std::vector<std::string> soapy_sink_c::get_devices()
|
|||
{
|
||||
std::vector<std::string> result;
|
||||
int i = 0;
|
||||
BOOST_FOREACH(SoapySDR::Kwargs kw, SoapySDR::Device::enumerate())
|
||||
for (SoapySDR::Kwargs kw : SoapySDR::Device::enumerate())
|
||||
{
|
||||
kw["soapy"] = boost::lexical_cast<std::string>(i++);
|
||||
result.push_back(dict_to_args_string(kw));
|
||||
|
@ -124,12 +124,12 @@ osmosdr::meta_range_t soapy_sink_c::get_sample_rates( void )
|
|||
{
|
||||
osmosdr::meta_range_t result;
|
||||
#ifdef SOAPY_SDR_API_HAS_GET_SAMPLE_RATE_RANGE
|
||||
BOOST_FOREACH(const SoapySDR::Range &r, _device->getSampleRateRange(SOAPY_SDR_TX, 0))
|
||||
for (const SoapySDR::Range &r : _device->getSampleRateRange(SOAPY_SDR_TX, 0))
|
||||
{
|
||||
result.push_back(osmosdr::range_t(r.minimum(), r.maximum()));
|
||||
}
|
||||
#else
|
||||
BOOST_FOREACH(const double rate, _device->listSampleRates(SOAPY_SDR_TX, 0))
|
||||
for (const double rate : _device->listSampleRates(SOAPY_SDR_TX, 0))
|
||||
{
|
||||
result.push_back(osmosdr::range_t(rate));
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ double soapy_sink_c::get_sample_rate( void )
|
|||
osmosdr::freq_range_t soapy_sink_c::get_freq_range( size_t chan)
|
||||
{
|
||||
osmosdr::meta_range_t result;
|
||||
BOOST_FOREACH(const SoapySDR::Range r, _device->getFrequencyRange(SOAPY_SDR_TX, 0))
|
||||
for (const SoapySDR::Range r : _device->getFrequencyRange(SOAPY_SDR_TX, 0))
|
||||
{
|
||||
result.push_back(osmosdr::range_t(r.minimum(), r.maximum()));
|
||||
}
|
||||
|
@ -309,12 +309,12 @@ osmosdr::freq_range_t soapy_sink_c::get_bandwidth_range( size_t chan)
|
|||
{
|
||||
osmosdr::meta_range_t result;
|
||||
#ifdef SOAPY_SDR_API_HAS_GET_BANDWIDTH_RANGE
|
||||
BOOST_FOREACH(const SoapySDR::Range &r, _device->getBandwidthRange(SOAPY_SDR_TX, 0))
|
||||
for (const SoapySDR::Range &r : _device->getBandwidthRange(SOAPY_SDR_TX, 0))
|
||||
{
|
||||
result.push_back(osmosdr::range_t(r.minimum(), r.maximum()));
|
||||
}
|
||||
#else
|
||||
BOOST_FOREACH(const double bw, _device->listBandwidths(SOAPY_SDR_TX, 0))
|
||||
for (const double bw : _device->listBandwidths(SOAPY_SDR_TX, 0))
|
||||
{
|
||||
result.push_back(osmosdr::range_t(bw));
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace SoapySDR
|
|||
}
|
||||
|
||||
/*
|
||||
* We use boost::shared_ptr's instead of raw pointers for all access
|
||||
* We use std::shared_ptr's instead of raw pointers for all access
|
||||
* to gr_blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues. This is especially helpful in our hybrid
|
||||
|
@ -44,9 +44,9 @@ namespace SoapySDR
|
|||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
* As a convention, the _sptr suffix indicates a std::shared_ptr
|
||||
*/
|
||||
typedef boost::shared_ptr<soapy_sink_c> soapy_sink_c_sptr;
|
||||
typedef std::shared_ptr<soapy_sink_c> soapy_sink_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of soapy_sink_c.
|
||||
|
|
|
@ -113,7 +113,7 @@ std::vector<std::string> soapy_source_c::get_devices()
|
|||
{
|
||||
std::vector<std::string> result;
|
||||
int i = 0;
|
||||
BOOST_FOREACH(SoapySDR::Kwargs kw, SoapySDR::Device::enumerate())
|
||||
for (SoapySDR::Kwargs kw : SoapySDR::Device::enumerate())
|
||||
{
|
||||
kw["soapy"] = boost::lexical_cast<std::string>(i++);
|
||||
result.push_back(dict_to_args_string(kw));
|
||||
|
@ -130,12 +130,12 @@ osmosdr::meta_range_t soapy_source_c::get_sample_rates( void )
|
|||
{
|
||||
osmosdr::meta_range_t result;
|
||||
#ifdef SOAPY_SDR_API_HAS_GET_SAMPLE_RATE_RANGE
|
||||
BOOST_FOREACH(const SoapySDR::Range &r, _device->getSampleRateRange(SOAPY_SDR_RX, 0))
|
||||
for (const SoapySDR::Range &r : _device->getSampleRateRange(SOAPY_SDR_RX, 0))
|
||||
{
|
||||
result.push_back(osmosdr::range_t(r.minimum(), r.maximum()));
|
||||
}
|
||||
#else
|
||||
BOOST_FOREACH(const double rate, _device->listSampleRates(SOAPY_SDR_RX, 0))
|
||||
for (const double rate : _device->listSampleRates(SOAPY_SDR_RX, 0))
|
||||
{
|
||||
result.push_back(osmosdr::range_t(rate));
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ double soapy_source_c::get_sample_rate( void )
|
|||
osmosdr::freq_range_t soapy_source_c::get_freq_range( size_t chan )
|
||||
{
|
||||
osmosdr::meta_range_t result;
|
||||
BOOST_FOREACH(const SoapySDR::Range r, _device->getFrequencyRange(SOAPY_SDR_RX, 0))
|
||||
for (const SoapySDR::Range r : _device->getFrequencyRange(SOAPY_SDR_RX, 0))
|
||||
{
|
||||
result.push_back(osmosdr::range_t(r.minimum(), r.maximum()));
|
||||
}
|
||||
|
@ -338,12 +338,12 @@ osmosdr::freq_range_t soapy_source_c::get_bandwidth_range( size_t chan )
|
|||
{
|
||||
osmosdr::meta_range_t result;
|
||||
#ifdef SOAPY_SDR_API_HAS_GET_BANDWIDTH_RANGE
|
||||
BOOST_FOREACH(const SoapySDR::Range &r, _device->getBandwidthRange(SOAPY_SDR_RX, 0))
|
||||
for (const SoapySDR::Range &r : _device->getBandwidthRange(SOAPY_SDR_RX, 0))
|
||||
{
|
||||
result.push_back(osmosdr::range_t(r.minimum(), r.maximum()));
|
||||
}
|
||||
#else
|
||||
BOOST_FOREACH(const double bw, _device->listBandwidths(SOAPY_SDR_RX, 0))
|
||||
for (const double bw : _device->listBandwidths(SOAPY_SDR_RX, 0))
|
||||
{
|
||||
result.push_back(osmosdr::range_t(bw));
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace SoapySDR
|
|||
}
|
||||
|
||||
/*
|
||||
* We use boost::shared_ptr's instead of raw pointers for all access
|
||||
* We use std::shared_ptr's instead of raw pointers for all access
|
||||
* to gr_blocks (and many other data structures). The shared_ptr gets
|
||||
* us transparent reference counting, which greatly simplifies storage
|
||||
* management issues. This is especially helpful in our hybrid
|
||||
|
@ -44,9 +44,9 @@ namespace SoapySDR
|
|||
*
|
||||
* See http://www.boost.org/libs/smart_ptr/smart_ptr.htm
|
||||
*
|
||||
* As a convention, the _sptr suffix indicates a boost::shared_ptr
|
||||
* As a convention, the _sptr suffix indicates a std::shared_ptr
|
||||
*/
|
||||
typedef boost::shared_ptr<soapy_source_c> soapy_source_c_sptr;
|
||||
typedef std::shared_ptr<soapy_source_c> soapy_source_c_sptr;
|
||||
|
||||
/*!
|
||||
* \brief Return a shared_ptr to a new instance of soapy_source_c.
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
class source_iface
|
||||
{
|
||||
public:
|
||||
virtual ~source_iface() = default;
|
||||
|
||||
/*!
|
||||
* Get the number of channels the underlying radio hardware offers.
|
||||
* \return the number of available channels
|
||||
|
@ -43,6 +45,7 @@ public:
|
|||
*
|
||||
* \param seek_point sample offset in file
|
||||
* \param whence one of SEEK_SET, SEEK_CUR, SEEK_END (man fseek)
|
||||
* \param chan the channel index 0 to N-1
|
||||
* \return true on success
|
||||
*/
|
||||
virtual bool seek( long seek_point, int whence, size_t chan = 0 ) { return false; }
|
||||
|
@ -210,6 +213,7 @@ public:
|
|||
|
||||
/*!
|
||||
* Select the active antenna of the underlying radio hardware.
|
||||
* \param antenna the antenna name
|
||||
* \param chan the channel index 0 to N-1
|
||||
* \return the actual antenna's name
|
||||
*/
|
||||
|
|
|
@ -32,10 +32,6 @@
|
|||
#include <gnuradio/blocks/throttle.h>
|
||||
#include <gnuradio/constants.h>
|
||||
|
||||
#ifdef ENABLE_OSMOSDR
|
||||
#include <osmosdr_src_c.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FCD
|
||||
#include <fcd_source_c.h>
|
||||
#endif
|
||||
|
@ -56,10 +52,6 @@
|
|||
#include <uhd_source_c.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MIRI
|
||||
#include <miri_source_c.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_SDRPLAY
|
||||
#include <sdrplay_source_c.h>
|
||||
#endif
|
||||
|
@ -96,6 +88,10 @@
|
|||
#include <freesrp_source_c.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_XTRX
|
||||
#include <xtrx_source_c.h>
|
||||
#endif
|
||||
|
||||
#include "arg_helpers.h"
|
||||
#include "source_impl.h"
|
||||
|
||||
|
@ -128,9 +124,6 @@ source_impl::source_impl( const std::string &args )
|
|||
#ifdef ENABLE_FILE
|
||||
dev_types.push_back("file");
|
||||
#endif
|
||||
#ifdef ENABLE_OSMOSDR
|
||||
dev_types.push_back("osmosdr");
|
||||
#endif
|
||||
#ifdef ENABLE_FCD
|
||||
dev_types.push_back("fcd");
|
||||
#endif
|
||||
|
@ -143,9 +136,6 @@ source_impl::source_impl( const std::string &args )
|
|||
#ifdef ENABLE_UHD
|
||||
dev_types.push_back("uhd");
|
||||
#endif
|
||||
#ifdef ENABLE_MIRI
|
||||
dev_types.push_back("miri");
|
||||
#endif
|
||||
#ifdef ENABLE_SDRPLAY
|
||||
dev_types.push_back("sdrplay");
|
||||
#endif
|
||||
|
@ -172,12 +162,15 @@ source_impl::source_impl( const std::string &args )
|
|||
#endif
|
||||
#ifdef ENABLE_FREESRP
|
||||
dev_types.push_back("freesrp");
|
||||
#endif
|
||||
#ifdef ENABLE_XTRX
|
||||
dev_types.push_back("xtrx");
|
||||
#endif
|
||||
std::cerr << "gr-osmosdr "
|
||||
<< GR_OSMOSDR_VERSION << " (" << GR_OSMOSDR_LIBVER << ") "
|
||||
<< "gnuradio " << gr::version() << std::endl;
|
||||
std::cerr << "built-in source types: ";
|
||||
BOOST_FOREACH(std::string dev_type, dev_types)
|
||||
for (std::string dev_type : dev_types)
|
||||
std::cerr << dev_type << " ";
|
||||
std::cerr << std::endl;
|
||||
|
||||
|
@ -188,9 +181,9 @@ source_impl::source_impl( const std::string &args )
|
|||
dev_types.push_back("cloudiq");
|
||||
#endif
|
||||
|
||||
BOOST_FOREACH(std::string arg, arg_list) {
|
||||
for (std::string arg : arg_list) {
|
||||
dict_t dict = params_to_dict(arg);
|
||||
BOOST_FOREACH(std::string dev_type, dev_types) {
|
||||
for (std::string dev_type : dev_types) {
|
||||
if ( dict.count( dev_type ) ) {
|
||||
device_specified = true;
|
||||
break;
|
||||
|
@ -200,65 +193,61 @@ source_impl::source_impl( const std::string &args )
|
|||
|
||||
if ( ! device_specified ) {
|
||||
std::vector< std::string > dev_list;
|
||||
#ifdef ENABLE_OSMOSDR
|
||||
BOOST_FOREACH( std::string dev, osmosdr_src_c::get_devices() )
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
#ifdef ENABLE_FCD
|
||||
BOOST_FOREACH( std::string dev, fcd_source_c::get_devices() )
|
||||
for (std::string dev : fcd_source_c::get_devices())
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
#ifdef ENABLE_RTL
|
||||
BOOST_FOREACH( std::string dev, rtl_source_c::get_devices() )
|
||||
for (std::string dev : rtl_source_c::get_devices())
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
#ifdef ENABLE_UHD
|
||||
BOOST_FOREACH( std::string dev, uhd_source_c::get_devices() )
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
#ifdef ENABLE_MIRI
|
||||
BOOST_FOREACH( std::string dev, miri_source_c::get_devices() )
|
||||
for (std::string dev : uhd_source_c::get_devices())
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
#ifdef ENABLE_SDRPLAY
|
||||
BOOST_FOREACH( std::string dev, sdrplay_source_c::get_devices() )
|
||||
for (std::string dev : sdrplay_source_c::get_devices())
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
#ifdef ENABLE_BLADERF
|
||||
BOOST_FOREACH( std::string dev, bladerf_source_c::get_devices() )
|
||||
for (std::string dev : bladerf_source_c::get_devices())
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
#ifdef ENABLE_RFSPACE
|
||||
BOOST_FOREACH( std::string dev, rfspace_source_c::get_devices() )
|
||||
for (std::string dev : rfspace_source_c::get_devices())
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
#ifdef ENABLE_HACKRF
|
||||
BOOST_FOREACH( std::string dev, hackrf_source_c::get_devices() )
|
||||
for (std::string dev : hackrf_source_c::get_devices())
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
#ifdef ENABLE_AIRSPY
|
||||
BOOST_FOREACH( std::string dev, airspy_source_c::get_devices() )
|
||||
for (std::string dev : airspy_source_c::get_devices())
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
#ifdef ENABLE_AIRSPYHF
|
||||
BOOST_FOREACH( std::string dev, airspyhf_source_c::get_devices() )
|
||||
for (std::string dev : airspyhf_source_c::get_devices())
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
#ifdef ENABLE_SOAPY
|
||||
BOOST_FOREACH( std::string dev, soapy_source_c::get_devices() )
|
||||
for (std::string dev : soapy_source_c::get_devices())
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
#ifdef ENABLE_REDPITAYA
|
||||
BOOST_FOREACH( std::string dev, redpitaya_source_c::get_devices() )
|
||||
for (std::string dev : redpitaya_source_c::get_devices())
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
#ifdef ENABLE_FREESRP
|
||||
BOOST_FOREACH( std::string dev, freesrp_source_c::get_devices() )
|
||||
for (std::string dev : freesrp_source_c::get_devices())
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
#ifdef ENABLE_XTRX
|
||||
for (std::string dev : xtrx_source_c::get_devices())
|
||||
dev_list.push_back( dev );
|
||||
#endif
|
||||
|
||||
// std::cerr << std::endl;
|
||||
// BOOST_FOREACH( std::string dev, dev_list )
|
||||
// for (std::string dev : dev_list)
|
||||
// std::cerr << "'" << dev << "'" << std::endl;
|
||||
|
||||
if ( dev_list.size() )
|
||||
|
@ -267,24 +256,17 @@ source_impl::source_impl( const std::string &args )
|
|||
throw std::runtime_error("No supported devices found (check the connection and/or udev rules).");
|
||||
}
|
||||
|
||||
BOOST_FOREACH(std::string arg, arg_list) {
|
||||
for (std::string arg : arg_list) {
|
||||
|
||||
dict_t dict = params_to_dict(arg);
|
||||
|
||||
// std::cerr << std::endl;
|
||||
// BOOST_FOREACH( dict_t::value_type &entry, dict )
|
||||
// for (dict_t::value_type &entry : dict)
|
||||
// std::cerr << "'" << entry.first << "' = '" << entry.second << "'" << std::endl;
|
||||
|
||||
source_iface *iface = NULL;
|
||||
gr::basic_block_sptr block;
|
||||
|
||||
#ifdef ENABLE_OSMOSDR
|
||||
if ( dict.count("osmosdr") ) {
|
||||
osmosdr_src_c_sptr src = osmosdr_make_src_c( arg );
|
||||
block = src; iface = src.get();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_FCD
|
||||
if ( dict.count("fcd") ) {
|
||||
fcd_source_c_sptr src = make_fcd_source_c( arg );
|
||||
|
@ -320,13 +302,6 @@ source_impl::source_impl( const std::string &args )
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MIRI
|
||||
if ( dict.count("miri") ) {
|
||||
miri_source_c_sptr src = make_miri_source_c( arg );
|
||||
block = src; iface = src.get();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_SDRPLAY
|
||||
if ( dict.count("sdrplay") ) {
|
||||
sdrplay_source_c_sptr src = make_sdrplay_source_c( arg );
|
||||
|
@ -394,6 +369,13 @@ source_impl::source_impl( const std::string &args )
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_XTRX
|
||||
if ( dict.count("xtrx") ) {
|
||||
xtrx_source_c_sptr src = make_xtrx_source_c( arg );
|
||||
block = src; iface = src.get();
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( iface != NULL && long(block.get()) != 0 ) {
|
||||
_devs.push_back( iface );
|
||||
|
||||
|
@ -421,13 +403,20 @@ source_impl::source_impl( const std::string &args )
|
|||
|
||||
if (!_devs.size())
|
||||
throw std::runtime_error("No devices specified via device arguments.");
|
||||
|
||||
/* Populate the _gain and _gain_mode arrays with the hardware state */
|
||||
for ( source_iface *dev : _devs )
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++) {
|
||||
_gain_mode[dev_chan] = dev->get_gain_mode(dev_chan);
|
||||
_gain[dev_chan] = dev->get_gain(dev_chan);
|
||||
}
|
||||
}
|
||||
|
||||
size_t source_impl::get_num_channels()
|
||||
{
|
||||
size_t channels = 0;
|
||||
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
channels += dev->get_num_channels();
|
||||
|
||||
return channels;
|
||||
|
@ -436,7 +425,7 @@ size_t source_impl::get_num_channels()
|
|||
bool source_impl::seek( long seek_point, int whence, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->seek( seek_point, whence, dev_chan );
|
||||
|
@ -466,12 +455,12 @@ double source_impl::set_sample_rate(double rate)
|
|||
if (_devs.empty())
|
||||
throw std::runtime_error(NO_DEVICES_MSG);
|
||||
#endif
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
sample_rate = dev->set_sample_rate(rate);
|
||||
|
||||
#ifdef HAVE_IQBALANCE
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs ) {
|
||||
for (source_iface *dev : _devs) {
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++) {
|
||||
if ( channel < _iq_opt.size() ) {
|
||||
gr::iqbalance::optimize_c *opt = _iq_opt[channel];
|
||||
|
@ -509,7 +498,7 @@ double source_impl::get_sample_rate()
|
|||
osmosdr::freq_range_t source_impl::get_freq_range( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_freq_range( dev_chan );
|
||||
|
@ -520,7 +509,7 @@ osmosdr::freq_range_t source_impl::get_freq_range( size_t chan )
|
|||
double source_impl::set_center_freq( double freq, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ ) {
|
||||
if ( _center_freq[ chan ] != freq ) {
|
||||
|
@ -535,7 +524,7 @@ double source_impl::set_center_freq( double freq, size_t chan )
|
|||
double source_impl::get_center_freq( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_center_freq( dev_chan );
|
||||
|
@ -546,7 +535,7 @@ double source_impl::get_center_freq( size_t chan )
|
|||
double source_impl::set_freq_corr( double ppm, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ ) {
|
||||
if ( _freq_corr[ chan ] != ppm ) {
|
||||
|
@ -561,7 +550,7 @@ double source_impl::set_freq_corr( double ppm, size_t chan )
|
|||
double source_impl::get_freq_corr( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_freq_corr( dev_chan );
|
||||
|
@ -572,7 +561,7 @@ double source_impl::get_freq_corr( size_t chan )
|
|||
std::vector<std::string> source_impl::get_gain_names( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_gain_names( dev_chan );
|
||||
|
@ -583,7 +572,7 @@ std::vector<std::string> source_impl::get_gain_names( size_t chan )
|
|||
osmosdr::gain_range_t source_impl::get_gain_range( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_gain_range( dev_chan );
|
||||
|
@ -594,7 +583,7 @@ osmosdr::gain_range_t source_impl::get_gain_range( size_t chan )
|
|||
osmosdr::gain_range_t source_impl::get_gain_range( const std::string & name, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_gain_range( name, dev_chan );
|
||||
|
@ -605,7 +594,7 @@ osmosdr::gain_range_t source_impl::get_gain_range( const std::string & name, siz
|
|||
bool source_impl::set_gain_mode( bool automatic, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ ) {
|
||||
if ( _gain_mode[ chan ] != automatic ) {
|
||||
|
@ -623,7 +612,7 @@ bool source_impl::set_gain_mode( bool automatic, size_t chan )
|
|||
bool source_impl::get_gain_mode( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_gain_mode( dev_chan );
|
||||
|
@ -634,7 +623,7 @@ bool source_impl::get_gain_mode( size_t chan )
|
|||
double source_impl::set_gain( double gain, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ ) {
|
||||
if ( _gain[ chan ] != gain ) {
|
||||
|
@ -649,7 +638,7 @@ double source_impl::set_gain( double gain, size_t chan )
|
|||
double source_impl::set_gain( double gain, const std::string & name, size_t chan)
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->set_gain( gain, name, dev_chan );
|
||||
|
@ -660,7 +649,7 @@ double source_impl::set_gain( double gain, const std::string & name, size_t chan
|
|||
double source_impl::get_gain( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_gain( dev_chan );
|
||||
|
@ -671,7 +660,7 @@ double source_impl::get_gain( size_t chan )
|
|||
double source_impl::get_gain( const std::string & name, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_gain( name, dev_chan );
|
||||
|
@ -682,7 +671,7 @@ double source_impl::get_gain( const std::string & name, size_t chan )
|
|||
double source_impl::set_if_gain( double gain, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ ) {
|
||||
if ( _if_gain[ chan ] != gain ) {
|
||||
|
@ -697,7 +686,7 @@ double source_impl::set_if_gain( double gain, size_t chan )
|
|||
double source_impl::set_bb_gain( double gain, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ ) {
|
||||
if ( _bb_gain[ chan ] != gain ) {
|
||||
|
@ -712,7 +701,7 @@ double source_impl::set_bb_gain( double gain, size_t chan )
|
|||
std::vector< std::string > source_impl::get_antennas( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_antennas( dev_chan );
|
||||
|
@ -723,7 +712,7 @@ std::vector< std::string > source_impl::get_antennas( size_t chan )
|
|||
std::string source_impl::set_antenna( const std::string & antenna, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ ) {
|
||||
if ( _antenna[ chan ] != antenna ) {
|
||||
|
@ -738,7 +727,7 @@ std::string source_impl::set_antenna( const std::string & antenna, size_t chan )
|
|||
std::string source_impl::get_antenna( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_antenna( dev_chan );
|
||||
|
@ -749,7 +738,7 @@ std::string source_impl::get_antenna( size_t chan )
|
|||
void source_impl::set_dc_offset_mode( int mode, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
dev->set_dc_offset_mode( mode, dev_chan );
|
||||
|
@ -758,7 +747,7 @@ void source_impl::set_dc_offset_mode( int mode, size_t chan )
|
|||
void source_impl::set_dc_offset( const std::complex<double> &offset, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
dev->set_dc_offset( offset, dev_chan );
|
||||
|
@ -768,7 +757,7 @@ void source_impl::set_iq_balance_mode( int mode, size_t chan )
|
|||
{
|
||||
size_t channel = 0;
|
||||
#ifdef HAVE_IQBALANCE
|
||||
BOOST_FOREACH( source_iface *dev, _devs ) {
|
||||
for (source_iface *dev : _devs) {
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++) {
|
||||
if ( chan == channel++ ) {
|
||||
if ( chan < _iq_opt.size() && chan < _iq_fix.size() ) {
|
||||
|
@ -798,7 +787,7 @@ void source_impl::set_iq_balance_mode( int mode, size_t chan )
|
|||
}
|
||||
}
|
||||
#else
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->set_iq_balance_mode( mode, dev_chan );
|
||||
|
@ -809,7 +798,7 @@ void source_impl::set_iq_balance( const std::complex<double> &balance, size_t ch
|
|||
{
|
||||
size_t channel = 0;
|
||||
#ifdef HAVE_IQBALANCE
|
||||
BOOST_FOREACH( source_iface *dev, _devs ) {
|
||||
for (source_iface *dev : _devs) {
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++) {
|
||||
if ( chan == channel++ ) {
|
||||
if ( chan < _iq_opt.size() && chan < _iq_fix.size() ) {
|
||||
|
@ -825,7 +814,7 @@ void source_impl::set_iq_balance( const std::complex<double> &balance, size_t ch
|
|||
}
|
||||
}
|
||||
#else
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->set_iq_balance( balance, dev_chan );
|
||||
|
@ -835,7 +824,7 @@ void source_impl::set_iq_balance( const std::complex<double> &balance, size_t ch
|
|||
double source_impl::set_bandwidth( double bandwidth, size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ ) {
|
||||
if ( _bandwidth[ chan ] != bandwidth || 0.0f == bandwidth ) {
|
||||
|
@ -850,7 +839,7 @@ double source_impl::set_bandwidth( double bandwidth, size_t chan )
|
|||
double source_impl::get_bandwidth( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_bandwidth( dev_chan );
|
||||
|
@ -861,7 +850,7 @@ double source_impl::get_bandwidth( size_t chan )
|
|||
osmosdr::freq_range_t source_impl::get_bandwidth_range( size_t chan )
|
||||
{
|
||||
size_t channel = 0;
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++)
|
||||
if ( chan == channel++ )
|
||||
return dev->get_bandwidth_range( dev_chan );
|
||||
|
@ -954,7 +943,7 @@ void source_impl::set_time_now(const osmosdr::time_spec_t &time_spec, size_t mbo
|
|||
|
||||
void source_impl::set_time_next_pps(const osmosdr::time_spec_t &time_spec)
|
||||
{
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
{
|
||||
dev->set_time_next_pps( time_spec );
|
||||
}
|
||||
|
@ -962,7 +951,7 @@ void source_impl::set_time_next_pps(const osmosdr::time_spec_t &time_spec)
|
|||
|
||||
void source_impl::set_time_unknown_pps(const osmosdr::time_spec_t &time_spec)
|
||||
{
|
||||
BOOST_FOREACH( source_iface *dev, _devs )
|
||||
for (source_iface *dev : _devs)
|
||||
{
|
||||
dev->set_time_unknown_pps( time_spec );
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/assign.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
|
@ -71,7 +70,7 @@ uhd_sink_c::uhd_sink_c(const std::string &args) :
|
|||
_lo_offset = boost::lexical_cast< double >( dict["lo_offset"] );
|
||||
|
||||
std::string arguments; // rebuild argument string without internal arguments
|
||||
BOOST_FOREACH( dict_t::value_type &entry, dict )
|
||||
for (dict_t::value_type &entry : dict)
|
||||
{
|
||||
if ( "cpu_format" == entry.first ||
|
||||
"otw_format" == entry.first ||
|
||||
|
@ -135,7 +134,7 @@ std::vector< std::string > uhd_sink_c::get_devices()
|
|||
std::vector< std::string > devices;
|
||||
|
||||
uhd::device_addr_t hint;
|
||||
BOOST_FOREACH(const uhd::device_addr_t &dev, uhd::device::find(hint))
|
||||
for (const uhd::device_addr_t &dev : uhd::device::find(hint))
|
||||
{
|
||||
std::string args = "uhd," + dev.to_string();
|
||||
|
||||
|
@ -190,7 +189,7 @@ osmosdr::meta_range_t uhd_sink_c::get_sample_rates( void )
|
|||
{
|
||||
osmosdr::meta_range_t rates;
|
||||
|
||||
BOOST_FOREACH( uhd::range_t rate, _snk->get_samp_rates() )
|
||||
for (uhd::range_t rate : _snk->get_samp_rates())
|
||||
rates += osmosdr::range_t( rate.start(), rate.stop(), rate.step() );
|
||||
|
||||
return rates;
|
||||
|
@ -211,7 +210,7 @@ osmosdr::freq_range_t uhd_sink_c::get_freq_range( size_t chan )
|
|||
{
|
||||
osmosdr::freq_range_t range;
|
||||
|
||||
BOOST_FOREACH( uhd::range_t freq, _snk->get_freq_range(chan) )
|
||||
for (uhd::range_t freq : _snk->get_freq_range(chan))
|
||||
range += osmosdr::range_t( freq.start(), freq.stop(), freq.step() );
|
||||
|
||||
return range;
|
||||
|
@ -260,7 +259,7 @@ osmosdr::gain_range_t uhd_sink_c::get_gain_range( size_t chan )
|
|||
{
|
||||
osmosdr::gain_range_t range;
|
||||
|
||||
BOOST_FOREACH( uhd::range_t gain, _snk->get_gain_range(chan) )
|
||||
for (uhd::range_t gain : _snk->get_gain_range(chan))
|
||||
range += osmosdr::range_t( gain.start(), gain.stop(), gain.step() );
|
||||
|
||||
return range;
|
||||
|
@ -270,7 +269,7 @@ osmosdr::gain_range_t uhd_sink_c::get_gain_range( const std::string & name, size
|
|||
{
|
||||
osmosdr::gain_range_t range;
|
||||
|
||||
BOOST_FOREACH( uhd::range_t gain, _snk->get_gain_range(name, chan) )
|
||||
for (uhd::range_t gain : _snk->get_gain_range(name, chan))
|
||||
range += osmosdr::range_t( gain.start(), gain.stop(), gain.step() );
|
||||
|
||||
return range;
|
||||
|
@ -351,7 +350,7 @@ osmosdr::freq_range_t uhd_sink_c::get_bandwidth_range( size_t chan )
|
|||
{
|
||||
osmosdr::freq_range_t bandwidths;
|
||||
|
||||
BOOST_FOREACH( uhd::range_t bw, _snk->get_bandwidth_range(chan) )
|
||||
for (uhd::range_t bw : _snk->get_bandwidth_range(chan))
|
||||
bandwidths += osmosdr::range_t( bw.start(), bw.stop(), bw.step() );
|
||||
|
||||
return bandwidths;
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
class uhd_sink_c;
|
||||
|
||||
typedef boost::shared_ptr< uhd_sink_c > uhd_sink_c_sptr;
|
||||
typedef std::shared_ptr< uhd_sink_c > uhd_sink_c_sptr;
|
||||
|
||||
uhd_sink_c_sptr make_uhd_sink_c(const std::string &args = "");
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/assign.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
|
@ -72,7 +71,7 @@ uhd_source_c::uhd_source_c(const std::string &args) :
|
|||
_lo_offset = boost::lexical_cast< double >( dict["lo_offset"] );
|
||||
|
||||
std::string arguments; // rebuild argument string without internal arguments
|
||||
BOOST_FOREACH( dict_t::value_type &entry, dict )
|
||||
for (dict_t::value_type &entry : dict)
|
||||
{
|
||||
if ( "cpu_format" == entry.first ||
|
||||
"otw_format" == entry.first ||
|
||||
|
@ -136,7 +135,7 @@ std::vector< std::string > uhd_source_c::get_devices()
|
|||
std::vector< std::string > devices;
|
||||
|
||||
uhd::device_addr_t hint;
|
||||
BOOST_FOREACH(const uhd::device_addr_t &dev, uhd::device::find(hint))
|
||||
for (const uhd::device_addr_t &dev : uhd::device::find(hint))
|
||||
{
|
||||
std::string args = "uhd," + dev.to_string();
|
||||
|
||||
|
@ -191,7 +190,7 @@ osmosdr::meta_range_t uhd_source_c::get_sample_rates( void )
|
|||
{
|
||||
osmosdr::meta_range_t rates;
|
||||
|
||||
BOOST_FOREACH( uhd::range_t rate, _src->get_samp_rates() )
|
||||
for (uhd::range_t rate : _src->get_samp_rates())
|
||||
rates += osmosdr::range_t( rate.start(), rate.stop(), rate.step() );
|
||||
|
||||
return rates;
|
||||
|
@ -212,7 +211,7 @@ osmosdr::freq_range_t uhd_source_c::get_freq_range( size_t chan )
|
|||
{
|
||||
osmosdr::freq_range_t range;
|
||||
|
||||
BOOST_FOREACH( uhd::range_t freq, _src->get_freq_range(chan) )
|
||||
for (uhd::range_t freq : _src->get_freq_range(chan))
|
||||
range += osmosdr::range_t( freq.start(), freq.stop(), freq.step() );
|
||||
|
||||
return range;
|
||||
|
@ -261,7 +260,7 @@ osmosdr::gain_range_t uhd_source_c::get_gain_range( size_t chan )
|
|||
{
|
||||
osmosdr::gain_range_t range;
|
||||
|
||||
BOOST_FOREACH( uhd::range_t gain, _src->get_gain_range(chan) )
|
||||
for (uhd::range_t gain : _src->get_gain_range(chan))
|
||||
range += osmosdr::range_t( gain.start(), gain.stop(), gain.step() );
|
||||
|
||||
return range;
|
||||
|
@ -271,7 +270,7 @@ osmosdr::gain_range_t uhd_source_c::get_gain_range( const std::string & name, si
|
|||
{
|
||||
osmosdr::gain_range_t range;
|
||||
|
||||
BOOST_FOREACH( uhd::range_t gain, _src->get_gain_range(name, chan) )
|
||||
for (uhd::range_t gain : _src->get_gain_range(name, chan))
|
||||
range += osmosdr::range_t( gain.start(), gain.stop(), gain.step() );
|
||||
|
||||
return range;
|
||||
|
@ -383,7 +382,7 @@ osmosdr::freq_range_t uhd_source_c::get_bandwidth_range( size_t chan )
|
|||
{
|
||||
osmosdr::freq_range_t bandwidths;
|
||||
|
||||
BOOST_FOREACH( uhd::range_t bw, _src->get_bandwidth_range(chan) )
|
||||
for (uhd::range_t bw : _src->get_bandwidth_range(chan))
|
||||
bandwidths += osmosdr::range_t( bw.start(), bw.stop(), bw.step() );
|
||||
|
||||
return bandwidths;
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
class uhd_source_c;
|
||||
|
||||
typedef boost::shared_ptr< uhd_source_c > uhd_source_c_sptr;
|
||||
typedef std::shared_ptr< uhd_source_c > uhd_source_c_sptr;
|
||||
|
||||
uhd_source_c_sptr make_uhd_source_c(const std::string &args = "");
|
||||
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
# Copyright 2012 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of gr-osmosdr
|
||||
# This file is part of GNU Radio
|
||||
#
|
||||
# gr-osmosdr is free software; you can redistribute it and/or modify
|
||||
# GNU Radio is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# gr-osmosdr is distributed in the hope that it will be useful,
|
||||
# GNU Radio is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with gr-osmosdr; see the file COPYING. If not, write to
|
||||
# along with GNU Radio; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
|
@ -23,14 +23,17 @@
|
|||
|
||||
target_include_directories(gnuradio-osmosdr PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${LIBOSMOSDR_INCLUDE_DIRS}
|
||||
${LIBXTRX_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
APPEND_LIB_LIST(
|
||||
${LIBOSMOSDR_LIBRARIES}
|
||||
${LIBXTRX_LIBRARIES}
|
||||
)
|
||||
|
||||
list(APPEND gr_osmosdr_srcs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/osmosdr_src_c.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/xtrx_obj.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/xtrx_source_c.cc
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/xtrx_sink_c.cc
|
||||
)
|
||||
|
||||
set(gr_osmosdr_srcs ${gr_osmosdr_srcs} PARENT_SCOPE)
|
|
@ -0,0 +1,138 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2017 Sergey Kostanbaev <sergey.kostanbaev@fairwaves.co>
|
||||
*
|
||||
* GNU Radio is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Radio is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#include "xtrx_obj.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
static std::map<std::string, xtrx_obj_sptr> s_objects;
|
||||
|
||||
xtrx_obj_sptr xtrx_obj::get(const char* xtrx_dev,
|
||||
unsigned loglevel,
|
||||
bool lmsreset)
|
||||
{
|
||||
std::map<std::string, xtrx_obj_sptr>::iterator i;
|
||||
std::string name(xtrx_dev);
|
||||
|
||||
i = s_objects.find(name);
|
||||
if (i == s_objects.end()) {
|
||||
// No such object
|
||||
s_objects[name].reset(new xtrx_obj(name, loglevel, lmsreset));
|
||||
}
|
||||
|
||||
return s_objects[name];
|
||||
}
|
||||
|
||||
void xtrx_obj::clear_all()
|
||||
{
|
||||
s_objects.clear();
|
||||
}
|
||||
|
||||
std::vector<std::string> xtrx_obj::get_devices()
|
||||
{
|
||||
std::vector<std::string> devices;
|
||||
// TODO
|
||||
devices.push_back("/dev/xtrx0");
|
||||
return devices;
|
||||
}
|
||||
|
||||
|
||||
xtrx_obj::xtrx_obj(const std::string &path, unsigned loglevel, bool lmsreset)
|
||||
: _run(false)
|
||||
, _vio(0)
|
||||
, _sink_rate(0)
|
||||
, _sink_master(0)
|
||||
, _source_rate(0)
|
||||
, _source_master(0)
|
||||
, _flags(0)
|
||||
{
|
||||
unsigned xtrxflag = (loglevel & XTRX_O_LOGLVL_MASK) | ((lmsreset) ? XTRX_O_RESET : 0);
|
||||
std::cerr << "xtrx_obj::xtrx_obj = " << xtrxflag << std::endl;
|
||||
|
||||
int res = xtrx_open_string(path.c_str(), &_obj);
|
||||
if (res < 0) {
|
||||
std::stringstream message;
|
||||
message << "Couldn't open " ": Error: " << -res;
|
||||
|
||||
throw std::runtime_error( message.str() );
|
||||
}
|
||||
|
||||
_devices = res;
|
||||
}
|
||||
|
||||
double xtrx_obj::set_smaplerate(double rate, double master, bool sink, unsigned flags)
|
||||
{
|
||||
boost::mutex::scoped_lock lock(mtx);
|
||||
|
||||
if (sink) {
|
||||
_sink_rate = rate;
|
||||
_sink_master = master;
|
||||
} else {
|
||||
_source_rate = rate;
|
||||
_source_master = master;
|
||||
}
|
||||
_flags |= flags | XTRX_SAMPLERATE_FORCE_UPDATE;
|
||||
|
||||
if (_sink_master != 0 && _source_master != 0 && _sink_master != _source_master) {
|
||||
std::stringstream message;
|
||||
message << "Can't operate on diferrent master settings for XTRX sink and source"
|
||||
" sink_master " << _sink_master << " source_master" << _source_master;
|
||||
|
||||
throw std::runtime_error( message.str() );
|
||||
}
|
||||
|
||||
double rxrate = 0, txrate = 0;
|
||||
double actmaster = (_source_master > 0) ? _source_master : _sink_master;
|
||||
int res = xtrx_set_samplerate(_obj,
|
||||
actmaster,
|
||||
_source_rate,
|
||||
_sink_rate,
|
||||
_flags,
|
||||
NULL,
|
||||
&rxrate,
|
||||
&txrate);
|
||||
if (res) {
|
||||
std::cerr << "Unable to set samplerate, error=" << res << std::endl;
|
||||
if (sink)
|
||||
return _sink_rate;
|
||||
return _source_rate;
|
||||
}
|
||||
|
||||
if (_vio) {
|
||||
xtrx_val_set(_obj, XTRX_TRX, XTRX_CH_AB, XTRX_LMS7_VIO, _vio);
|
||||
}
|
||||
|
||||
if (sink)
|
||||
return txrate;
|
||||
return rxrate;
|
||||
}
|
||||
|
||||
xtrx_obj::~xtrx_obj()
|
||||
{
|
||||
if (_obj) {
|
||||
if (_run) {
|
||||
//boost::mutex::scoped_lock lock(mtx);
|
||||
xtrx_stop(_obj, XTRX_TRX);
|
||||
}
|
||||
xtrx_close(_obj);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2017 Sergey Kostanbaev <sergey.kostanbaev@fairwaves.co>
|
||||
*
|
||||
* GNU Radio is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Radio is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#ifndef XTRX_OBJ_H
|
||||
#define XTRX_OBJ_H
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <xtrx_api.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
class xtrx_obj;
|
||||
|
||||
typedef std::shared_ptr<xtrx_obj> xtrx_obj_sptr;
|
||||
|
||||
class xtrx_obj
|
||||
{
|
||||
public:
|
||||
xtrx_obj(const std::string& path, unsigned loglevel, bool lmsreset);
|
||||
~xtrx_obj();
|
||||
|
||||
static std::vector<std::string> get_devices();
|
||||
|
||||
static xtrx_obj_sptr get(const char* xtrx_dev,
|
||||
unsigned loglevel,
|
||||
bool lmsreset);
|
||||
static void clear_all();
|
||||
|
||||
xtrx_dev* dev() { return _obj; }
|
||||
unsigned dev_count() { return _devices; }
|
||||
|
||||
double set_smaplerate(double rate, double master, bool sink, unsigned flags);
|
||||
|
||||
void set_vio(unsigned vio) { _vio = vio; }
|
||||
|
||||
boost::mutex mtx;
|
||||
protected:
|
||||
xtrx_dev* _obj;
|
||||
bool _run;
|
||||
unsigned _vio;
|
||||
|
||||
double _sink_rate;
|
||||
double _sink_master;
|
||||
double _source_rate;
|
||||
double _source_master;
|
||||
|
||||
unsigned _flags;
|
||||
unsigned _devices;
|
||||
};
|
||||
|
||||
#endif // XTRX_OBJ_H
|
|
@ -0,0 +1,505 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2016,2017 Sergey Kostanbaev <sergey.kostanbaev@fairwaves.co>
|
||||
*
|
||||
* GNU Radio is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Radio is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
|
||||
#include <boost/assign.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <gnuradio/blocks/deinterleave.h>
|
||||
#include <gnuradio/blocks/float_to_complex.h>
|
||||
|
||||
#include "xtrx_sink_c.h"
|
||||
|
||||
#include "arg_helpers.h"
|
||||
|
||||
static const int max_burstsz = 4096;
|
||||
using namespace boost::assign;
|
||||
|
||||
xtrx_sink_c_sptr make_xtrx_sink_c(const std::string &args)
|
||||
{
|
||||
return gnuradio::get_initial_sptr(new xtrx_sink_c(args));
|
||||
}
|
||||
|
||||
static size_t parse_nchan(const std::string &args)
|
||||
{
|
||||
size_t nchan = 1;
|
||||
|
||||
dict_t dict = params_to_dict(args);
|
||||
|
||||
if (dict.count("nchan"))
|
||||
nchan = boost::lexical_cast< size_t >( dict["nchan"] );
|
||||
|
||||
if (nchan < 1)
|
||||
nchan = 1;
|
||||
|
||||
return nchan;
|
||||
}
|
||||
|
||||
xtrx_sink_c::xtrx_sink_c(const std::string &args) :
|
||||
gr::sync_block("xtrx_sink_c",
|
||||
gr::io_signature::make(parse_nchan(args),
|
||||
parse_nchan(args),
|
||||
sizeof(gr_complex)),
|
||||
gr::io_signature::make(0, 0, 0)),
|
||||
_sample_flags(0),
|
||||
_rate(0),
|
||||
_master(0),
|
||||
_freq(0),
|
||||
_corr(0),
|
||||
_bandwidth(0),
|
||||
_dsp(0),
|
||||
_auto_gain(false),
|
||||
_otw(XTRX_WF_16),
|
||||
_mimo_mode(false),
|
||||
_gain_tx(0),
|
||||
_channels(parse_nchan(args)),
|
||||
_ts(8192),
|
||||
_swap_ab(false),
|
||||
_swap_iq(false),
|
||||
_tdd(false),
|
||||
_allow_dis(false),
|
||||
_dev("")
|
||||
{
|
||||
|
||||
dict_t dict = params_to_dict(args);
|
||||
|
||||
if (dict.count("master")) {
|
||||
_master = boost::lexical_cast< double >( dict["master"]);
|
||||
}
|
||||
|
||||
std::cerr << args.c_str() << std::endl;
|
||||
|
||||
int loglevel = 4;
|
||||
if (dict.count("loglevel")) {
|
||||
loglevel = boost::lexical_cast< int >( dict["loglevel"] );
|
||||
}
|
||||
|
||||
bool lmsreset = 0;
|
||||
if (dict.count("lmsreset")) {
|
||||
lmsreset = boost::lexical_cast< bool >( dict["lmsreset"] );
|
||||
}
|
||||
|
||||
if (dict.count("txdelay")) {
|
||||
_ts += 8192 * boost::lexical_cast< int >( dict["txdelay"] );
|
||||
}
|
||||
|
||||
if (dict.count("allowdis")) {
|
||||
_allow_dis = boost::lexical_cast< bool >( dict["allowdis"] );
|
||||
}
|
||||
|
||||
if (dict.count("swap_ab")) {
|
||||
_swap_ab = true;
|
||||
std::cerr << "xtrx_sink_c: swap AB channels";
|
||||
}
|
||||
|
||||
if (dict.count("swap_iq")) {
|
||||
_swap_iq = true;
|
||||
std::cerr << "xtrx_sink_c: swap IQ";
|
||||
}
|
||||
|
||||
if (dict.count("sfl")) {
|
||||
_sample_flags = boost::lexical_cast< unsigned >( dict["sfl"] );
|
||||
}
|
||||
|
||||
if (dict.count("tdd")) {
|
||||
_tdd = true;
|
||||
std::cerr << "xtrx_sink_c: TDD mode";
|
||||
}
|
||||
|
||||
if (dict.count("dsp")) {
|
||||
_dsp = boost::lexical_cast< double >( dict["dsp"] );
|
||||
std::cerr << "xtrx_sink_c: DSP:" << _dsp;
|
||||
}
|
||||
|
||||
if (dict.count("dev")) {
|
||||
_dev = dict["dev"];
|
||||
std::cerr << "xtrx_sink_c: XTRX device: %s" << _dev.c_str();
|
||||
}
|
||||
|
||||
_xtrx = xtrx_obj::get(_dev.c_str(), loglevel, lmsreset);
|
||||
if (_xtrx->dev_count() * 2 == _channels) {
|
||||
_mimo_mode = true;
|
||||
} else if (_xtrx->dev_count() != _channels) {
|
||||
throw std::runtime_error("Number of requested channels != number of devices");
|
||||
}
|
||||
if (dict.count("refclk")) {
|
||||
xtrx_set_ref_clk(_xtrx->dev(), boost::lexical_cast< unsigned >( dict["refclk"] ), XTRX_CLKSRC_INT);
|
||||
}
|
||||
if (dict.count("extclk")) {
|
||||
xtrx_set_ref_clk(_xtrx->dev(), boost::lexical_cast< unsigned >( dict["extclk"] ), XTRX_CLKSRC_EXT);
|
||||
}
|
||||
|
||||
std::cerr << "xtrx_sink_c::xtrx_sink_c()" << std::endl;
|
||||
set_alignment(32);
|
||||
set_output_multiple(max_burstsz);
|
||||
}
|
||||
|
||||
xtrx_sink_c::~xtrx_sink_c()
|
||||
{
|
||||
std::cerr << "xtrx_sink_c::~xtrx_sink_c()" << std::endl;
|
||||
}
|
||||
|
||||
std::string xtrx_sink_c::name()
|
||||
{
|
||||
return "GrLibXTRX";
|
||||
}
|
||||
|
||||
size_t xtrx_sink_c::get_num_channels( void )
|
||||
{
|
||||
return input_signature()->max_streams();
|
||||
}
|
||||
|
||||
osmosdr::meta_range_t xtrx_sink_c::get_sample_rates( void )
|
||||
{
|
||||
osmosdr::meta_range_t range;
|
||||
range += osmosdr::range_t( 1000000, 160000000, 1 );
|
||||
return range;
|
||||
}
|
||||
|
||||
double xtrx_sink_c::set_sample_rate( double rate )
|
||||
{
|
||||
std::cerr << "Set sample rate " << rate << std::endl;
|
||||
_rate = _xtrx->set_smaplerate(rate, _master, true, _sample_flags);
|
||||
return get_sample_rate();
|
||||
}
|
||||
|
||||
double xtrx_sink_c::get_sample_rate( void )
|
||||
{
|
||||
return _rate;
|
||||
}
|
||||
|
||||
osmosdr::freq_range_t xtrx_sink_c::get_freq_range( size_t chan )
|
||||
{
|
||||
osmosdr::freq_range_t range;
|
||||
range += osmosdr::range_t( double(0.03e9), double(3.8e9), 1); // as far as we know
|
||||
return range;
|
||||
}
|
||||
|
||||
double xtrx_sink_c::set_center_freq( double freq, size_t chan )
|
||||
{
|
||||
boost::mutex::scoped_lock lock(_xtrx->mtx);
|
||||
|
||||
_freq = freq;
|
||||
double corr_freq = (freq)*(1.0 + (_corr) * 0.000001);
|
||||
|
||||
std::cerr << "TX Set freq " << freq << std::endl;
|
||||
xtrx_channel_t xchan = (xtrx_channel_t)(XTRX_CH_A << chan);
|
||||
|
||||
int res = xtrx_tune_ex(_xtrx->dev(), (_tdd) ? XTRX_TUNE_TX_AND_RX_TDD : XTRX_TUNE_TX_FDD, xchan, corr_freq - _dsp, &_freq);
|
||||
if (res) {
|
||||
std::cerr << "Unable to deliver frequency " << corr_freq << std::endl;
|
||||
}
|
||||
|
||||
res = xtrx_tune_ex(_xtrx->dev(), XTRX_TUNE_BB_TX, xchan, _dsp, NULL);
|
||||
return get_center_freq(chan);
|
||||
}
|
||||
|
||||
double xtrx_sink_c::get_center_freq( size_t chan )
|
||||
{
|
||||
return _freq + _dsp;
|
||||
}
|
||||
|
||||
double xtrx_sink_c::set_freq_corr( double ppm, size_t chan )
|
||||
{
|
||||
_corr = ppm;
|
||||
|
||||
set_center_freq(_freq, chan);
|
||||
|
||||
return get_freq_corr( chan );
|
||||
}
|
||||
|
||||
double xtrx_sink_c::get_freq_corr( size_t chan )
|
||||
{
|
||||
return _corr;
|
||||
}
|
||||
|
||||
|
||||
static const std::vector<std::string> s_lna_list = boost::assign::list_of("TX");
|
||||
|
||||
std::vector<std::string> xtrx_sink_c::get_gain_names( size_t chan )
|
||||
{
|
||||
return s_lna_list;
|
||||
}
|
||||
|
||||
osmosdr::gain_range_t xtrx_sink_c::get_gain_range( size_t chan )
|
||||
{
|
||||
return get_gain_range("TX", chan);
|
||||
}
|
||||
|
||||
osmosdr::gain_range_t xtrx_sink_c::get_gain_range( const std::string & name, size_t chan )
|
||||
{
|
||||
osmosdr::gain_range_t range;
|
||||
range += osmosdr::range_t( -31, 0, 1 );
|
||||
return range;
|
||||
}
|
||||
|
||||
bool xtrx_sink_c::set_gain_mode( bool automatic, size_t chan )
|
||||
{
|
||||
_auto_gain = automatic;
|
||||
return get_gain_mode(chan);
|
||||
}
|
||||
|
||||
bool xtrx_sink_c::get_gain_mode( size_t chan )
|
||||
{
|
||||
return _auto_gain;
|
||||
}
|
||||
|
||||
double xtrx_sink_c::set_gain( double gain, size_t chan )
|
||||
{
|
||||
return set_gain(gain, "TX", chan);
|
||||
}
|
||||
|
||||
double xtrx_sink_c::set_gain( double igain, const std::string & name, size_t chan )
|
||||
{
|
||||
boost::mutex::scoped_lock lock(_xtrx->mtx);
|
||||
|
||||
osmosdr::gain_range_t gains = xtrx_sink_c::get_gain_range( name, chan );
|
||||
double gain = gains.clip(igain);
|
||||
double actual_gain;
|
||||
|
||||
std::cerr << "Set TX gain: " << igain << std::endl;
|
||||
|
||||
int res = xtrx_set_gain(_xtrx->dev(), (xtrx_channel_t)(XTRX_CH_A << chan),
|
||||
XTRX_TX_PAD_GAIN, gain, &actual_gain);
|
||||
if (res) {
|
||||
std::cerr << "Unable to set gain `" << name.c_str() << "`; err=" << res << std::endl;
|
||||
}
|
||||
|
||||
_gain_tx = actual_gain;
|
||||
return actual_gain;
|
||||
}
|
||||
|
||||
double xtrx_sink_c::get_gain( size_t chan )
|
||||
{
|
||||
return get_gain("TX");
|
||||
}
|
||||
|
||||
double xtrx_sink_c::get_gain( const std::string & name, size_t chan )
|
||||
{
|
||||
return _gain_tx;
|
||||
}
|
||||
|
||||
double xtrx_sink_c::set_bandwidth( double bandwidth, size_t chan )
|
||||
{
|
||||
boost::mutex::scoped_lock lock(_xtrx->mtx);
|
||||
std::cerr << "Set bandwidth " << bandwidth << " chan " << chan << std::endl;
|
||||
|
||||
if (bandwidth <= 0.0) {
|
||||
bandwidth = get_sample_rate() * 0.75;
|
||||
if (bandwidth < 0.5e6) {
|
||||
bandwidth = 0.5e6;
|
||||
}
|
||||
}
|
||||
|
||||
int res = xtrx_tune_tx_bandwidth(_xtrx->dev(),
|
||||
(xtrx_channel_t)(XTRX_CH_A << chan),
|
||||
bandwidth, &_bandwidth);
|
||||
if (res) {
|
||||
std::cerr << "Can't set bandwidth: " << res << std::endl;
|
||||
}
|
||||
return get_bandwidth(chan);
|
||||
}
|
||||
|
||||
double xtrx_sink_c::get_bandwidth( size_t chan )
|
||||
{
|
||||
return _bandwidth;
|
||||
}
|
||||
|
||||
|
||||
static const std::map<std::string, xtrx_antenna_t> s_ant_map = boost::assign::map_list_of
|
||||
("AUTO", XTRX_TX_AUTO)
|
||||
("B1", XTRX_TX_H)
|
||||
("B2", XTRX_TX_W)
|
||||
("TXH", XTRX_TX_H)
|
||||
("TXW", XTRX_TX_W)
|
||||
;
|
||||
static const std::map<xtrx_antenna_t, std::string> s_ant_map_r = boost::assign::map_list_of
|
||||
(XTRX_TX_H, "TXH")
|
||||
(XTRX_TX_W, "TXW")
|
||||
(XTRX_TX_AUTO, "AUTO")
|
||||
;
|
||||
|
||||
static xtrx_antenna_t get_ant_type(const std::string& name)
|
||||
{
|
||||
std::map<std::string, xtrx_antenna_t>::const_iterator it;
|
||||
|
||||
it = s_ant_map.find(name);
|
||||
if (it != s_ant_map.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return XTRX_TX_AUTO;
|
||||
}
|
||||
|
||||
static const std::vector<std::string> s_ant_list = boost::assign::list_of
|
||||
("AUTO")("TXH")("TXW")
|
||||
;
|
||||
|
||||
|
||||
std::vector< std::string > xtrx_sink_c::get_antennas( size_t chan )
|
||||
{
|
||||
return s_ant_list;
|
||||
}
|
||||
|
||||
std::string xtrx_sink_c::set_antenna( const std::string & antenna, size_t chan )
|
||||
{
|
||||
boost::mutex::scoped_lock lock(_xtrx->mtx);
|
||||
_ant = get_ant_type(antenna);
|
||||
|
||||
std::cerr << "Set antenna " << antenna << std::endl;
|
||||
|
||||
int res = xtrx_set_antenna_ex(_xtrx->dev(),
|
||||
(xtrx_channel_t)(XTRX_CH_A << chan),
|
||||
_ant);
|
||||
if (res) {
|
||||
std::cerr << "Can't set antenna: " << antenna << std::endl;
|
||||
}
|
||||
return get_antenna( chan );
|
||||
}
|
||||
|
||||
std::string xtrx_sink_c::get_antenna( size_t chan )
|
||||
{
|
||||
return s_ant_map_r.find(_ant)->second;
|
||||
}
|
||||
|
||||
void xtrx_sink_c::tag_process(int ninput_items)
|
||||
{
|
||||
std::sort(_tags.begin(), _tags.end(), gr::tag_t::offset_compare);
|
||||
|
||||
const uint64_t samp0_count = this->nitems_read(0);
|
||||
uint64_t max_count = samp0_count + ninput_items;
|
||||
|
||||
bool found_time_tag = false;
|
||||
for (const gr::tag_t &my_tag : _tags) {
|
||||
const uint64_t my_tag_count = my_tag.offset;
|
||||
const pmt::pmt_t &key = my_tag.key;
|
||||
const pmt::pmt_t &value = my_tag.value;
|
||||
|
||||
if (my_tag_count >= max_count) {
|
||||
break;
|
||||
} else if(pmt::equal(key, TIME_KEY)) {
|
||||
//if (my_tag_count != samp0_count) {
|
||||
// max_count = my_tag_count;
|
||||
// break;
|
||||
//}
|
||||
found_time_tag = true;
|
||||
//_metadata.has_time_spec = true;
|
||||
//_metadata.time_spec = ::uhd::time_spec_t
|
||||
// (pmt::to_uint64(pmt::tuple_ref(value, 0)),
|
||||
// pmt::to_double(pmt::tuple_ref(value, 1)));
|
||||
uint64_t seconds = pmt::to_uint64(pmt::tuple_ref(value, 0));
|
||||
double fractional = pmt::to_double(pmt::tuple_ref(value, 1));
|
||||
|
||||
std::cerr << "TX_TIME: " << seconds << ":" << fractional << std::endl;
|
||||
}
|
||||
} // end for
|
||||
|
||||
if (found_time_tag) {
|
||||
//_metadata.has_time_spec = true;
|
||||
}
|
||||
}
|
||||
|
||||
int xtrx_sink_c::work (int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
int ninput_items = noutput_items;
|
||||
const uint64_t samp0_count = nitems_read(0);
|
||||
get_tags_in_range(_tags, 0, samp0_count, samp0_count + ninput_items);
|
||||
if (!_tags.empty())
|
||||
tag_process(ninput_items);
|
||||
|
||||
xtrx_send_ex_info_t nfo;
|
||||
nfo.samples = noutput_items;
|
||||
nfo.buffer_count = input_items.size();
|
||||
nfo.buffers = &input_items[0];
|
||||
nfo.flags = XTRX_TX_DONT_BUFFER;
|
||||
if (!_allow_dis)
|
||||
nfo.flags |= XTRX_TX_NO_DISCARD;
|
||||
nfo.ts = _ts;
|
||||
nfo.timeout = 0;
|
||||
|
||||
int res = xtrx_send_sync_ex(_xtrx->dev(), &nfo);
|
||||
if (res) {
|
||||
std::cerr << "Err: " << res << std::endl;
|
||||
|
||||
std::stringstream message;
|
||||
message << "xtrx_send_burst_sync error: " << -res;
|
||||
throw std::runtime_error( message.str() );
|
||||
}
|
||||
|
||||
_ts += noutput_items;
|
||||
for (unsigned i = 0; i < input_items.size(); i++) {
|
||||
consume(i, noutput_items);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool xtrx_sink_c::start()
|
||||
{
|
||||
boost::mutex::scoped_lock lock(_xtrx->mtx);
|
||||
|
||||
xtrx_run_params_t params;
|
||||
xtrx_run_params_init(¶ms);
|
||||
|
||||
params.dir = XTRX_TX;
|
||||
if (!_mimo_mode)
|
||||
params.tx.flags |= XTRX_RSP_SISO_MODE;
|
||||
|
||||
if (_swap_ab)
|
||||
params.tx.flags |= XTRX_RSP_SWAP_AB;
|
||||
|
||||
if (_swap_iq)
|
||||
params.tx.flags |= XTRX_RSP_SWAP_IQ;
|
||||
|
||||
params.tx.hfmt = XTRX_IQ_FLOAT32;
|
||||
params.tx.wfmt = _otw;
|
||||
params.tx.chs = XTRX_CH_AB;
|
||||
params.tx.paketsize = 0;
|
||||
params.rx_stream_start = 256*1024;
|
||||
|
||||
int res = xtrx_run_ex(_xtrx->dev(), ¶ms);
|
||||
if (res) {
|
||||
std::cerr << "Got error: " << res << std::endl;
|
||||
}
|
||||
|
||||
return res == 0;
|
||||
}
|
||||
|
||||
bool xtrx_sink_c::stop()
|
||||
{
|
||||
boost::mutex::scoped_lock lock(_xtrx->mtx);
|
||||
|
||||
//TODO:
|
||||
std::cerr << "xtrx_sink_c::stop()" << std::endl;
|
||||
int res = xtrx_stop(_xtrx->dev(), XTRX_TX);
|
||||
if (res) {
|
||||
std::cerr << "Got error: " << res << std::endl;
|
||||
}
|
||||
|
||||
return res == 0;
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2016 Sergey Kostanabev <sergey.kostanbaev@fairwaves.co>
|
||||
*
|
||||
* GNU Radio is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Radio is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef XTRX_SINK_C_H
|
||||
#define XTRX_SINK_C_H
|
||||
|
||||
#include <gnuradio/block.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
#include "sink_iface.h"
|
||||
#include "xtrx_obj.h"
|
||||
|
||||
|
||||
static const pmt::pmt_t SOB_KEY = pmt::string_to_symbol("tx_sob");
|
||||
static const pmt::pmt_t EOB_KEY = pmt::string_to_symbol("tx_eob");
|
||||
static const pmt::pmt_t TIME_KEY = pmt::string_to_symbol("tx_time");
|
||||
static const pmt::pmt_t FREQ_KEY = pmt::string_to_symbol("tx_freq");
|
||||
static const pmt::pmt_t COMMAND_KEY = pmt::string_to_symbol("tx_command");
|
||||
|
||||
class xtrx_sink_c;
|
||||
|
||||
typedef std::shared_ptr< xtrx_sink_c > xtrx_sink_c_sptr;
|
||||
|
||||
xtrx_sink_c_sptr make_xtrx_sink_c( const std::string & args = "" );
|
||||
|
||||
class xtrx_sink_c :
|
||||
public gr::sync_block,
|
||||
public sink_iface
|
||||
{
|
||||
private:
|
||||
friend xtrx_sink_c_sptr make_xtrx_sink_c(const std::string &args);
|
||||
|
||||
xtrx_sink_c(const std::string &args);
|
||||
|
||||
public:
|
||||
~xtrx_sink_c();
|
||||
|
||||
std::string name();
|
||||
|
||||
static std::vector< std::string > get_devices( bool fake = false ) { return xtrx_obj::get_devices(); }
|
||||
|
||||
size_t get_num_channels( void );
|
||||
|
||||
osmosdr::meta_range_t get_sample_rates( void );
|
||||
double set_sample_rate( double rate );
|
||||
double get_sample_rate( void );
|
||||
|
||||
osmosdr::freq_range_t get_freq_range( size_t chan = 0 );
|
||||
double set_center_freq( double freq, size_t chan = 0 );
|
||||
double get_center_freq( size_t chan = 0 );
|
||||
double set_freq_corr( double ppm, size_t chan = 0 );
|
||||
double get_freq_corr( size_t chan = 0 );
|
||||
|
||||
std::vector<std::string> get_gain_names( size_t chan = 0 );
|
||||
osmosdr::gain_range_t get_gain_range( size_t chan = 0 );
|
||||
osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 );
|
||||
bool set_gain_mode( bool automatic, size_t chan = 0 );
|
||||
bool get_gain_mode( size_t chan = 0 );
|
||||
double set_gain( double gain, size_t chan = 0 );
|
||||
double set_gain( double gain, const std::string & name, size_t chan = 0 );
|
||||
double get_gain( size_t chan = 0 );
|
||||
double get_gain( const std::string & name, size_t chan = 0 );
|
||||
|
||||
std::vector< std::string > get_antennas( size_t chan = 0 );
|
||||
std::string set_antenna( const std::string & antenna, size_t chan = 0 );
|
||||
std::string get_antenna( size_t chan = 0 );
|
||||
|
||||
double set_bandwidth( double bandwidth, size_t chan = 0 );
|
||||
double get_bandwidth( size_t chan = 0 );
|
||||
|
||||
int work (int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items);
|
||||
|
||||
bool start();
|
||||
bool stop();
|
||||
|
||||
void tag_process(int ninput_items);
|
||||
|
||||
private:
|
||||
xtrx_obj_sptr _xtrx;
|
||||
std::vector<gr::tag_t> _tags;
|
||||
|
||||
unsigned _sample_flags;
|
||||
double _rate;
|
||||
double _master;
|
||||
double _freq;
|
||||
double _corr;
|
||||
double _bandwidth;
|
||||
double _dsp;
|
||||
bool _auto_gain;
|
||||
|
||||
xtrx_wire_format_t _otw;
|
||||
bool _mimo_mode;
|
||||
|
||||
int _gain_tx;
|
||||
|
||||
unsigned _channels;
|
||||
xtrx_antenna_t _ant;
|
||||
|
||||
uint64_t _ts;
|
||||
|
||||
bool _swap_ab;
|
||||
bool _swap_iq;
|
||||
|
||||
bool _tdd;
|
||||
bool _allow_dis;
|
||||
|
||||
std::string _dev;
|
||||
};
|
||||
|
||||
#endif // xtrx_sink_c_H
|
|
@ -0,0 +1,583 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2016,2017 Sergey Kostanbaev <sergey.kostanbaev@fairwaves.co>
|
||||
*
|
||||
* GNU Radio is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Radio is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
|
||||
#include <boost/assign.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <gnuradio/blocks/deinterleave.h>
|
||||
#include <gnuradio/blocks/float_to_complex.h>
|
||||
|
||||
#include "xtrx_source_c.h"
|
||||
|
||||
#include "arg_helpers.h"
|
||||
|
||||
using namespace boost::assign;
|
||||
|
||||
|
||||
xtrx_source_c_sptr make_xtrx_source_c(const std::string &args)
|
||||
{
|
||||
return gnuradio::get_initial_sptr(new xtrx_source_c(args));
|
||||
}
|
||||
|
||||
static size_t parse_nchan(const std::string &args)
|
||||
{
|
||||
size_t nchan = 1;
|
||||
|
||||
dict_t dict = params_to_dict(args);
|
||||
|
||||
if (dict.count("nchan"))
|
||||
nchan = boost::lexical_cast< size_t >( dict["nchan"] );
|
||||
|
||||
if (nchan < 1)
|
||||
nchan = 1;
|
||||
|
||||
return nchan;
|
||||
}
|
||||
|
||||
xtrx_source_c::xtrx_source_c(const std::string &args) :
|
||||
gr::sync_block("xtrx_source_c",
|
||||
gr::io_signature::make(0, 0, 0),
|
||||
gr::io_signature::make(parse_nchan(args),
|
||||
parse_nchan(args),
|
||||
sizeof(gr_complex))),
|
||||
_sample_flags(0),
|
||||
_rate(0),
|
||||
_master(0),
|
||||
_freq(0),
|
||||
_corr(0),
|
||||
_bandwidth(0),
|
||||
_auto_gain(false),
|
||||
_otw(XTRX_WF_16),
|
||||
_mimo_mode(false),
|
||||
_gain_lna(0),
|
||||
_gain_tia(0),
|
||||
_gain_pga(0),
|
||||
_channels(parse_nchan(args)),
|
||||
_swap_ab(false),
|
||||
_swap_iq(false),
|
||||
_loopback(false),
|
||||
_tdd(false),
|
||||
_fbctrl(false),
|
||||
_timekey(false),
|
||||
_dsp(0)
|
||||
{
|
||||
_id = pmt::string_to_symbol(args);
|
||||
|
||||
dict_t dict = params_to_dict(args);
|
||||
|
||||
if (dict.count("otw_format")) {
|
||||
const std::string& otw = dict["otw_format"];
|
||||
if (otw == "sc16" || otw == "16") {
|
||||
_otw = XTRX_WF_16;
|
||||
} else if (otw == "sc12" || otw == "12") {
|
||||
_otw = XTRX_WF_12;
|
||||
} else if (otw == "sc8" || otw == "8") {
|
||||
_otw = XTRX_WF_8;
|
||||
} else {
|
||||
throw std::runtime_error("Parameter `otw_format` should be {sc16,sc12,sc8}");
|
||||
}
|
||||
}
|
||||
|
||||
if (dict.count("master")) {
|
||||
_master = boost::lexical_cast< double >( dict["master"]);
|
||||
}
|
||||
|
||||
std::cerr << args.c_str() << std::endl;
|
||||
|
||||
int loglevel = 4;
|
||||
if (dict.count("loglevel")) {
|
||||
loglevel = boost::lexical_cast< int >( dict["loglevel"] );
|
||||
}
|
||||
|
||||
bool lmsreset = 0;
|
||||
if (dict.count("lmsreset")) {
|
||||
lmsreset = boost::lexical_cast< bool >( dict["lmsreset"] );
|
||||
}
|
||||
|
||||
if (dict.count("fbctrl")) {
|
||||
_fbctrl = boost::lexical_cast< bool >( dict["fbctrl"] );
|
||||
}
|
||||
|
||||
if (dict.count("swap_ab")) {
|
||||
_swap_ab = true;
|
||||
std::cerr << "xtrx_source_c: swap AB channels";
|
||||
}
|
||||
|
||||
if (dict.count("swap_iq")) {
|
||||
_swap_iq = true;
|
||||
std::cerr << "xtrx_source_c: swap IQ";
|
||||
}
|
||||
|
||||
if (dict.count("sfl")) {
|
||||
_sample_flags = boost::lexical_cast< unsigned >( dict["sfl"] );
|
||||
}
|
||||
|
||||
if (dict.count("loopback")) {
|
||||
_loopback = true;
|
||||
std::cerr << "xtrx_source_c: loopback";
|
||||
}
|
||||
|
||||
if (dict.count("tdd")) {
|
||||
_tdd = true;
|
||||
std::cerr << "xtrx_source_c: TDD mode";
|
||||
}
|
||||
|
||||
if (dict.count("dsp")) {
|
||||
_dsp = boost::lexical_cast< double >( dict["dsp"] );
|
||||
std::cerr << "xtrx_source_c: DSP:" << _dsp;
|
||||
}
|
||||
|
||||
if (dict.count("dev")) {
|
||||
_dev = dict["dev"];
|
||||
std::cerr << "xtrx_source_c: XTRX device: %s" << _dev.c_str();
|
||||
}
|
||||
|
||||
_xtrx = xtrx_obj::get(_dev.c_str(), loglevel, lmsreset);
|
||||
if (_xtrx->dev_count() * 2 == _channels) {
|
||||
_mimo_mode = true;
|
||||
} else if (_xtrx->dev_count() != _channels) {
|
||||
throw std::runtime_error("Number of requested channels != number of devices");
|
||||
}
|
||||
|
||||
if (dict.count("refclk")) {
|
||||
xtrx_set_ref_clk(_xtrx->dev(), boost::lexical_cast< unsigned >( dict["refclk"] ), XTRX_CLKSRC_INT);
|
||||
}
|
||||
if (dict.count("extclk")) {
|
||||
xtrx_set_ref_clk(_xtrx->dev(), boost::lexical_cast< unsigned >( dict["extclk"] ), XTRX_CLKSRC_EXT);
|
||||
}
|
||||
|
||||
if (dict.count("vio")) {
|
||||
unsigned vio = boost::lexical_cast< unsigned >( dict["vio"] );
|
||||
_xtrx->set_vio(vio);
|
||||
}
|
||||
|
||||
if (dict.count("dac")) {
|
||||
unsigned dac = boost::lexical_cast< unsigned >( dict["dac"] );
|
||||
xtrx_val_set(_xtrx->dev(), XTRX_TRX, XTRX_CH_ALL, XTRX_VCTCXO_DAC_VAL, dac);
|
||||
}
|
||||
|
||||
if (dict.count("pmode")) {
|
||||
unsigned pmode = boost::lexical_cast< unsigned >( dict["pmode"] );
|
||||
xtrx_val_set(_xtrx->dev(), XTRX_TRX, XTRX_CH_ALL, XTRX_LMS7_PWR_MODE, pmode);
|
||||
}
|
||||
|
||||
if (dict.count("timekey")) {
|
||||
_timekey = boost::lexical_cast< bool >( dict["timekey"] );
|
||||
}
|
||||
|
||||
std::cerr << "xtrx_source_c::xtrx_source_c()" << std::endl;
|
||||
set_alignment(32);
|
||||
if (_otw == XTRX_WF_16) {
|
||||
if (_mimo_mode)
|
||||
set_output_multiple(4096);
|
||||
else
|
||||
set_output_multiple(8192);
|
||||
} else if (_otw == XTRX_WF_8) {
|
||||
if (_mimo_mode)
|
||||
set_output_multiple(8192);
|
||||
else
|
||||
set_output_multiple(16384);
|
||||
}
|
||||
}
|
||||
|
||||
xtrx_source_c::~xtrx_source_c()
|
||||
{
|
||||
std::cerr << "xtrx_source_c::~xtrx_source_c()" << std::endl;
|
||||
}
|
||||
|
||||
std::string xtrx_source_c::name()
|
||||
{
|
||||
return "GrLibXTRX";
|
||||
}
|
||||
|
||||
size_t xtrx_source_c::get_num_channels( void )
|
||||
{
|
||||
return output_signature()->max_streams();
|
||||
}
|
||||
|
||||
osmosdr::meta_range_t xtrx_source_c::get_sample_rates( void )
|
||||
{
|
||||
osmosdr::meta_range_t range;
|
||||
range += osmosdr::range_t( 200000, 160000000, 1 );
|
||||
return range;
|
||||
}
|
||||
|
||||
double xtrx_source_c::set_sample_rate( double rate )
|
||||
{
|
||||
std::cerr << "Set sample rate " << rate << std::endl;
|
||||
_rate = _xtrx->set_smaplerate(rate, _master, false, _sample_flags);
|
||||
return get_sample_rate();
|
||||
}
|
||||
|
||||
double xtrx_source_c::get_sample_rate( void )
|
||||
{
|
||||
return _rate;
|
||||
}
|
||||
|
||||
osmosdr::freq_range_t xtrx_source_c::get_freq_range( size_t chan )
|
||||
{
|
||||
osmosdr::freq_range_t range;
|
||||
range += osmosdr::range_t( double(0.03e9), double(3.8e9), 1); // as far as we know
|
||||
return range;
|
||||
}
|
||||
|
||||
double xtrx_source_c::set_center_freq( double freq, size_t chan )
|
||||
{
|
||||
boost::mutex::scoped_lock lock(_xtrx->mtx);
|
||||
|
||||
_freq = freq;
|
||||
double corr_freq = (freq)*(1.0 + (_corr) * 0.000001);
|
||||
|
||||
if (_tdd)
|
||||
return get_center_freq(chan);
|
||||
|
||||
xtrx_channel_t xchan = (xtrx_channel_t)(XTRX_CH_A << chan);
|
||||
|
||||
std::cerr << "Set freq " << freq << std::endl;
|
||||
|
||||
int res = xtrx_tune_ex(_xtrx->dev(), XTRX_TUNE_RX_FDD, xchan, corr_freq - _dsp, &_freq);
|
||||
if (res) {
|
||||
std::cerr << "Unable to deliver frequency " << corr_freq << std::endl;
|
||||
}
|
||||
|
||||
res = xtrx_tune_ex(_xtrx->dev(), XTRX_TUNE_BB_RX, xchan, _dsp, NULL);
|
||||
|
||||
return get_center_freq(chan);
|
||||
}
|
||||
|
||||
double xtrx_source_c::get_center_freq( size_t chan )
|
||||
{
|
||||
return _freq;
|
||||
}
|
||||
|
||||
double xtrx_source_c::set_freq_corr( double ppm, size_t chan )
|
||||
{
|
||||
_corr = ppm;
|
||||
|
||||
set_center_freq(_freq, chan);
|
||||
|
||||
return get_freq_corr( chan );
|
||||
}
|
||||
|
||||
double xtrx_source_c::get_freq_corr( size_t chan )
|
||||
{
|
||||
return _corr;
|
||||
}
|
||||
|
||||
static const std::map<std::string, xtrx_gain_type_t> s_lna_map = boost::assign::map_list_of
|
||||
("LNA", XTRX_RX_LNA_GAIN)
|
||||
("TIA", XTRX_RX_TIA_GAIN)
|
||||
("PGA", XTRX_RX_PGA_GAIN)
|
||||
("LB", XTRX_RX_LB_GAIN)
|
||||
;
|
||||
|
||||
static xtrx_gain_type_t get_gain_type(const std::string& name)
|
||||
{
|
||||
std::map<std::string, xtrx_gain_type_t>::const_iterator it;
|
||||
|
||||
it = s_lna_map.find(name);
|
||||
if (it != s_lna_map.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return XTRX_RX_LNA_GAIN;
|
||||
}
|
||||
|
||||
static const std::vector<std::string> s_lna_list = boost::assign::list_of
|
||||
("LNA")("TIA")("PGA")("LB")
|
||||
;
|
||||
|
||||
std::vector<std::string> xtrx_source_c::get_gain_names( size_t chan )
|
||||
{
|
||||
return s_lna_list;
|
||||
}
|
||||
|
||||
osmosdr::gain_range_t xtrx_source_c::get_gain_range( size_t chan )
|
||||
{
|
||||
return get_gain_range("LNA", chan);
|
||||
}
|
||||
|
||||
osmosdr::gain_range_t xtrx_source_c::get_gain_range( const std::string & name, size_t chan )
|
||||
{
|
||||
osmosdr::gain_range_t range;
|
||||
|
||||
if (name == "LNA") {
|
||||
range += osmosdr::range_t( 0, 24, 3 );
|
||||
range += osmosdr::range_t( 25, 30, 1 );
|
||||
} else if (name == "TIA") {
|
||||
range += osmosdr::range_t( 0 );
|
||||
range += osmosdr::range_t( 9 );
|
||||
range += osmosdr::range_t( 12 );
|
||||
} else if (name == "PGA") {
|
||||
range += osmosdr::range_t( -12.5, 12.5, 1 );
|
||||
} else if (name == "LB") {
|
||||
range += osmosdr::range_t( -40, 0, 1 );
|
||||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
bool xtrx_source_c::set_gain_mode( bool automatic, size_t chan )
|
||||
{
|
||||
_auto_gain = automatic;
|
||||
return get_gain_mode(chan);
|
||||
}
|
||||
|
||||
bool xtrx_source_c::get_gain_mode( size_t chan )
|
||||
{
|
||||
return _auto_gain;
|
||||
}
|
||||
|
||||
double xtrx_source_c::set_gain( double gain, size_t chan )
|
||||
{
|
||||
return set_gain(gain, "LNA", chan);
|
||||
}
|
||||
|
||||
double xtrx_source_c::set_gain( double igain, const std::string & name, size_t chan )
|
||||
{
|
||||
boost::mutex::scoped_lock lock(_xtrx->mtx);
|
||||
|
||||
osmosdr::gain_range_t gains = xtrx_source_c::get_gain_range( name, chan );
|
||||
double gain = gains.clip(igain);
|
||||
double actual_gain;
|
||||
xtrx_gain_type_t gt = get_gain_type(name);
|
||||
|
||||
std::cerr << "Set gain " << name << " (" << gt << "): " << igain << std::endl;
|
||||
|
||||
int res = xtrx_set_gain(_xtrx->dev(), (xtrx_channel_t)(XTRX_CH_A << chan),
|
||||
gt, gain, &actual_gain);
|
||||
if (res) {
|
||||
std::cerr << "Unable to set gain `" << name.c_str() << "`; err=" << res << std::endl;
|
||||
}
|
||||
|
||||
switch (gt) {
|
||||
case XTRX_RX_LNA_GAIN: _gain_lna = actual_gain; break;
|
||||
case XTRX_RX_TIA_GAIN: _gain_tia = actual_gain; break;
|
||||
case XTRX_RX_PGA_GAIN: _gain_pga = actual_gain; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return actual_gain;
|
||||
}
|
||||
|
||||
double xtrx_source_c::get_gain( size_t chan )
|
||||
{
|
||||
return get_gain("LNA");
|
||||
}
|
||||
|
||||
double xtrx_source_c::get_gain( const std::string & name, size_t chan )
|
||||
{
|
||||
xtrx_gain_type_t gt = get_gain_type(name);
|
||||
switch (gt) {
|
||||
case XTRX_RX_LNA_GAIN: return _gain_lna;
|
||||
case XTRX_RX_TIA_GAIN: return _gain_tia;
|
||||
case XTRX_RX_PGA_GAIN: return _gain_pga;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
double xtrx_source_c::set_if_gain(double gain, size_t chan)
|
||||
{
|
||||
return set_gain(gain, "PGA", chan);
|
||||
}
|
||||
|
||||
double xtrx_source_c::set_bandwidth( double bandwidth, size_t chan )
|
||||
{
|
||||
boost::mutex::scoped_lock lock(_xtrx->mtx);
|
||||
std::cerr << "Set bandwidth " << bandwidth << " chan " << chan << std::endl;
|
||||
|
||||
if (bandwidth <= 0.0) {
|
||||
bandwidth = get_sample_rate() * 0.75;
|
||||
if (bandwidth < 0.5e6) {
|
||||
bandwidth = 0.5e6;
|
||||
}
|
||||
}
|
||||
|
||||
int res = xtrx_tune_rx_bandwidth(_xtrx->dev(), (xtrx_channel_t)(XTRX_CH_A << chan),
|
||||
bandwidth, &_bandwidth);
|
||||
if (res) {
|
||||
std::cerr << "Can't set bandwidth: " << res << std::endl;
|
||||
}
|
||||
return get_bandwidth(chan);
|
||||
}
|
||||
|
||||
double xtrx_source_c::get_bandwidth( size_t chan )
|
||||
{
|
||||
return _bandwidth;
|
||||
}
|
||||
|
||||
osmosdr::freq_range_t xtrx_source_c::get_bandwidth_range( size_t chan )
|
||||
{
|
||||
return osmosdr::freq_range_t(500e3, 140e6, 0);
|
||||
}
|
||||
|
||||
|
||||
static const std::map<std::string, xtrx_antenna_t> s_ant_map = boost::assign::map_list_of
|
||||
("AUTO", XTRX_RX_AUTO)
|
||||
("RXL", XTRX_RX_L)
|
||||
("RXH", XTRX_RX_H)
|
||||
("RXW", XTRX_RX_W)
|
||||
("RXL_LB", XTRX_RX_L_LB)
|
||||
("RXW_LB", XTRX_RX_W_LB)
|
||||
;
|
||||
static const std::map<xtrx_antenna_t, std::string> s_ant_map_r = boost::assign::map_list_of
|
||||
(XTRX_RX_AUTO, "AUTO")
|
||||
(XTRX_RX_L, "RXL")
|
||||
(XTRX_RX_H, "RXH")
|
||||
(XTRX_RX_W, "RXW")
|
||||
(XTRX_RX_L_LB, "RXL_LB")
|
||||
(XTRX_RX_W_LB, "RXW_LB")
|
||||
;
|
||||
|
||||
static xtrx_antenna_t get_ant_type(const std::string& name)
|
||||
{
|
||||
std::map<std::string, xtrx_antenna_t>::const_iterator it;
|
||||
|
||||
it = s_ant_map.find(name);
|
||||
if (it != s_ant_map.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return XTRX_RX_AUTO;
|
||||
}
|
||||
|
||||
static const std::vector<std::string> s_ant_list = boost::assign::list_of
|
||||
("AUTO")("RXL")("RXH")("RXW")
|
||||
;
|
||||
|
||||
|
||||
std::vector< std::string > xtrx_source_c::get_antennas( size_t chan )
|
||||
{
|
||||
return s_ant_list;
|
||||
}
|
||||
|
||||
std::string xtrx_source_c::set_antenna( const std::string & antenna, size_t chan )
|
||||
{
|
||||
boost::mutex::scoped_lock lock(_xtrx->mtx);
|
||||
_ant = get_ant_type(antenna);
|
||||
|
||||
std::cerr << "Set antenna " << antenna << " type:" << _ant << std::endl;
|
||||
|
||||
int res = xtrx_set_antenna_ex(_xtrx->dev(), (xtrx_channel_t)(XTRX_CH_A << chan),
|
||||
_ant);
|
||||
if (res) {
|
||||
std::cerr << "Can't set antenna: " << antenna << std::endl;
|
||||
}
|
||||
return get_antenna( chan );
|
||||
}
|
||||
|
||||
std::string xtrx_source_c::get_antenna( size_t chan )
|
||||
{
|
||||
return s_ant_map_r.find(_ant)->second;
|
||||
}
|
||||
|
||||
int xtrx_source_c::work (int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
xtrx_recv_ex_info_t ri;
|
||||
ri.samples = noutput_items;
|
||||
ri.buffer_count = output_items.size();
|
||||
ri.buffers = &output_items[0];
|
||||
ri.flags = RCVEX_DONT_INSER_ZEROS | RCVEX_DROP_OLD_ON_OVERFLOW;
|
||||
ri.timeout = 1000;
|
||||
|
||||
int res = xtrx_recv_sync_ex(_xtrx->dev(), &ri);
|
||||
if (res) {
|
||||
std::stringstream message;
|
||||
message << "xtrx_recv_sync error: " << -res;
|
||||
throw std::runtime_error( message.str() );
|
||||
}
|
||||
|
||||
if (_timekey) {
|
||||
uint64_t seconds = (ri.out_first_sample / _rate);
|
||||
double fractional = (ri.out_first_sample - (uint64_t)(_rate * seconds)) / _rate;
|
||||
|
||||
//std::cerr << "Time " << seconds << ":" << fractional << std::endl;
|
||||
const pmt::pmt_t val = pmt::make_tuple
|
||||
(pmt::from_uint64(seconds),
|
||||
pmt::from_double(fractional));
|
||||
for(size_t i = 0; i < output_items.size(); i++) {
|
||||
this->add_item_tag(i, nitems_written(0), TIME_KEY,
|
||||
val, _id);
|
||||
this->add_item_tag(i, nitems_written(0), RATE_KEY,
|
||||
pmt::from_double(_rate), _id);
|
||||
this->add_item_tag(i, nitems_written(0), FREQ_KEY,
|
||||
pmt::from_double(this->get_center_freq(i)), _id);
|
||||
}
|
||||
}
|
||||
return ri.out_samples;
|
||||
}
|
||||
|
||||
bool xtrx_source_c::start()
|
||||
{
|
||||
boost::mutex::scoped_lock lock(_xtrx->mtx);
|
||||
|
||||
xtrx_run_params_t params;
|
||||
xtrx_run_params_init(¶ms);
|
||||
|
||||
params.dir = XTRX_RX;
|
||||
if (!_mimo_mode)
|
||||
params.rx.flags |= XTRX_RSP_SISO_MODE;
|
||||
|
||||
if (_swap_ab)
|
||||
params.rx.flags |= XTRX_RSP_SWAP_AB;
|
||||
|
||||
if (_swap_iq)
|
||||
params.rx.flags |= XTRX_RSP_SWAP_IQ;
|
||||
|
||||
params.rx.hfmt = XTRX_IQ_FLOAT32;
|
||||
params.rx.wfmt = _otw;
|
||||
params.rx.chs = XTRX_CH_AB;
|
||||
params.rx.paketsize = 0;
|
||||
params.rx_stream_start = 256*1024;
|
||||
|
||||
params.nflags = (_loopback) ? XTRX_RUN_DIGLOOPBACK : 0;
|
||||
|
||||
int res = xtrx_run_ex(_xtrx->dev(), ¶ms);
|
||||
if (res) {
|
||||
std::cerr << "Got error: " << res << std::endl;
|
||||
}
|
||||
|
||||
res = xtrx_tune_ex(_xtrx->dev(), XTRX_TUNE_BB_RX, XTRX_CH_ALL, _dsp, NULL);
|
||||
|
||||
return res == 0;
|
||||
}
|
||||
|
||||
bool xtrx_source_c::stop()
|
||||
{
|
||||
boost::mutex::scoped_lock lock(_xtrx->mtx);
|
||||
//TODO:
|
||||
std::cerr << "xtrx_source_c::stop()" << std::endl;
|
||||
int res = xtrx_stop(_xtrx->dev(), XTRX_RX);
|
||||
if (res) {
|
||||
std::cerr << "Got error: " << res << std::endl;
|
||||
}
|
||||
|
||||
return res == 0;
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2016,2017 Sergey Kostanbaev <sergey.kostanbaev@fairwaves.co>
|
||||
*
|
||||
* GNU Radio is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Radio is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#ifndef XTRX_SOURCE_C_H
|
||||
#define XTRX_SOURCE_C_H
|
||||
|
||||
#include <gnuradio/block.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
#include "source_iface.h"
|
||||
#include "xtrx_obj.h"
|
||||
|
||||
static const pmt::pmt_t TIME_KEY = pmt::string_to_symbol("rx_time");
|
||||
static const pmt::pmt_t RATE_KEY = pmt::string_to_symbol("rx_rate");
|
||||
static const pmt::pmt_t FREQ_KEY = pmt::string_to_symbol("rx_freq");
|
||||
|
||||
class xtrx_source_c;
|
||||
|
||||
typedef std::shared_ptr< xtrx_source_c > xtrx_source_c_sptr;
|
||||
|
||||
xtrx_source_c_sptr make_xtrx_source_c( const std::string & args = "" );
|
||||
|
||||
class xtrx_source_c :
|
||||
public gr::sync_block,
|
||||
public source_iface
|
||||
{
|
||||
private:
|
||||
friend xtrx_source_c_sptr make_xtrx_source_c(const std::string &args);
|
||||
|
||||
xtrx_source_c(const std::string &args);
|
||||
|
||||
public:
|
||||
~xtrx_source_c();
|
||||
|
||||
std::string name();
|
||||
|
||||
static std::vector< std::string > get_devices( bool fake = false ) { return xtrx_obj::get_devices(); }
|
||||
|
||||
size_t get_num_channels( void );
|
||||
|
||||
osmosdr::meta_range_t get_sample_rates( void );
|
||||
double set_sample_rate( double rate );
|
||||
double get_sample_rate( void );
|
||||
|
||||
osmosdr::freq_range_t get_freq_range( size_t chan = 0 );
|
||||
double set_center_freq( double freq, size_t chan = 0 );
|
||||
double get_center_freq( size_t chan = 0 );
|
||||
double set_freq_corr( double ppm, size_t chan = 0 );
|
||||
double get_freq_corr( size_t chan = 0 );
|
||||
|
||||
std::vector<std::string> get_gain_names( size_t chan = 0 );
|
||||
osmosdr::gain_range_t get_gain_range( size_t chan = 0 );
|
||||
osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 );
|
||||
bool set_gain_mode( bool automatic, size_t chan = 0 );
|
||||
bool get_gain_mode( size_t chan = 0 );
|
||||
double set_gain( double gain, size_t chan = 0 );
|
||||
double set_gain( double gain, const std::string & name, size_t chan = 0 );
|
||||
double get_gain( size_t chan = 0 );
|
||||
double get_gain( const std::string & name, size_t chan = 0 );
|
||||
|
||||
double set_if_gain( double gain, size_t chan = 0 );
|
||||
|
||||
std::vector< std::string > get_antennas( size_t chan = 0 );
|
||||
std::string set_antenna( const std::string & antenna, size_t chan = 0 );
|
||||
std::string get_antenna( size_t chan = 0 );
|
||||
|
||||
double set_bandwidth( double bandwidth, size_t chan = 0 );
|
||||
double get_bandwidth( size_t chan = 0 );
|
||||
osmosdr::freq_range_t get_bandwidth_range( size_t chan = 0);
|
||||
|
||||
int work (int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items);
|
||||
|
||||
bool start();
|
||||
bool stop();
|
||||
|
||||
private:
|
||||
xtrx_obj_sptr _xtrx;
|
||||
pmt::pmt_t _id;
|
||||
|
||||
unsigned _sample_flags;
|
||||
double _rate;
|
||||
double _master;
|
||||
double _freq;
|
||||
double _corr;
|
||||
double _bandwidth;
|
||||
bool _auto_gain;
|
||||
|
||||
xtrx_wire_format_t _otw;
|
||||
bool _mimo_mode;
|
||||
|
||||
int _gain_lna;
|
||||
int _gain_tia;
|
||||
int _gain_pga;
|
||||
|
||||
unsigned _channels;
|
||||
xtrx_antenna_t _ant;
|
||||
|
||||
bool _swap_ab;
|
||||
bool _swap_iq;
|
||||
bool _loopback;
|
||||
bool _tdd;
|
||||
bool _fbctrl;
|
||||
bool _timekey;
|
||||
|
||||
double _dsp;
|
||||
std::string _dev;
|
||||
};
|
||||
|
||||
#endif // XTRX_SOURCE_C_H
|
|
@ -1,21 +1,10 @@
|
|||
# Copyright 2011 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of gr-osmosdr
|
||||
# This file was generated by gr_modtool, a tool from the GNU Radio framework
|
||||
# This file is a part of gr-osmosdr
|
||||
#
|
||||
# gr-osmosdr is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
#
|
||||
# gr-osmosdr is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with gr-osmosdr; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
########################################################################
|
||||
# Include python install macros
|
||||
|
@ -25,6 +14,8 @@ if(NOT PYTHONINTERP_FOUND)
|
|||
return()
|
||||
endif()
|
||||
|
||||
add_subdirectory(bindings)
|
||||
|
||||
########################################################################
|
||||
# Install python sources
|
||||
########################################################################
|
||||
|
@ -40,4 +31,3 @@ GR_PYTHON_INSTALL(
|
|||
include(GrTest)
|
||||
|
||||
set(GR_TEST_TARGET_DEPS gnuradio-osmosdr)
|
||||
set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig)
|
||||
|
|
|
@ -1,25 +1,24 @@
|
|||
#
|
||||
# Copyright 2008,2009 Free Software Foundation, Inc.
|
||||
#
|
||||
# This application is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This application is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
#
|
||||
|
||||
# The presence of this file turns this directory into a Python package
|
||||
|
||||
'''
|
||||
This is the GNU Radio OsmoSDR module.
|
||||
This is the GNU Radio OSMOSDR module. Place your Python package
|
||||
description here (python/__init__.py).
|
||||
'''
|
||||
import os
|
||||
|
||||
from .osmosdr_swig import *
|
||||
# import pybind11 generated symbols into the osmosdr namespace
|
||||
try:
|
||||
from .osmosdr_python import *
|
||||
except ImportError:
|
||||
dirname, filename = os.path.split(os.path.abspath(__file__))
|
||||
__path__.append(os.path.join(dirname, "bindings"))
|
||||
from .osmosdr_python import *
|
||||
|
||||
# import any pure python here
|
||||
#
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
# Copyright 2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
#
|
||||
|
||||
GR_PYTHON_CHECK_MODULE_RAW(
|
||||
"pygccxml"
|
||||
"import pygccxml"
|
||||
PYGCCXML_FOUND
|
||||
)
|
||||
|
||||
include(GrPybind)
|
||||
|
||||
########################################################################
|
||||
# Python Bindings
|
||||
########################################################################
|
||||
|
||||
list(APPEND osmosdr_python_files
|
||||
device_python.cc
|
||||
sink_python.cc
|
||||
source_python.cc
|
||||
ranges_python.cc
|
||||
time_spec_python.cc
|
||||
python_bindings.cc)
|
||||
|
||||
GR_PYBIND_MAKE_OOT(osmosdr
|
||||
../..
|
||||
gr::osmosdr
|
||||
"${osmosdr_python_files}")
|
||||
|
||||
install(TARGETS osmosdr_python DESTINATION ${GR_PYTHON_DIR}/osmosdr COMPONENT pythonapi)
|
|
@ -0,0 +1,53 @@
|
|||
import warnings
|
||||
import argparse
|
||||
import os
|
||||
from gnuradio.bindtool import BindingGenerator
|
||||
import pathlib
|
||||
import sys
|
||||
|
||||
parser = argparse.ArgumentParser(description='Bind a GR Out of Tree Block')
|
||||
parser.add_argument('--module', type=str,
|
||||
help='Name of gr module containing file to bind (e.g. fft digital analog)')
|
||||
|
||||
parser.add_argument('--output_dir', default='/tmp',
|
||||
help='Output directory of generated bindings')
|
||||
parser.add_argument('--prefix', help='Prefix of Installed GNU Radio')
|
||||
parser.add_argument('--src', help='Directory of gnuradio source tree',
|
||||
default=os.path.dirname(os.path.abspath(__file__))+'/../../..')
|
||||
|
||||
parser.add_argument(
|
||||
'--filename', help="File to be parsed")
|
||||
|
||||
parser.add_argument(
|
||||
'--include', help='Additional Include Dirs, separated', default=(), nargs='+')
|
||||
|
||||
parser.add_argument(
|
||||
'--status', help='Location of output file for general status (used during cmake)', default=None
|
||||
)
|
||||
parser.add_argument(
|
||||
'--flag_automatic', default='0'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--flag_pygccxml', default='0'
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
prefix = args.prefix
|
||||
output_dir = args.output_dir
|
||||
includes = args.include
|
||||
name = args.module
|
||||
|
||||
namespace = [name]
|
||||
prefix_include_root = name
|
||||
|
||||
|
||||
with warnings.catch_warnings():
|
||||
warnings.filterwarnings("ignore", category=DeprecationWarning)
|
||||
|
||||
bg = BindingGenerator(prefix, namespace,
|
||||
prefix_include_root, output_dir, addl_includes=','.join(args.include), catch_exceptions=False, write_json_output=False, status_output=args.status,
|
||||
flag_automatic=True if args.flag_automatic.lower() in [
|
||||
'1', 'true'] else False,
|
||||
flag_pygccxml=True if args.flag_pygccxml.lower() in ['1', 'true'] else False)
|
||||
bg.gen_file_binding(args.filename)
|
|
@ -0,0 +1,27 @@
|
|||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
#include <osmosdr/device.h>
|
||||
|
||||
void bind_device(py::module& m)
|
||||
{
|
||||
using device_t = ::osmosdr::device_t;
|
||||
|
||||
py::class_<device_t>(m, "device_t")
|
||||
.def(py::init<std::string&>(), py::arg("args") = "")
|
||||
.def("to_pp_string", &device_t::to_pp_string)
|
||||
.def("to_string", &device_t::to_string);
|
||||
|
||||
|
||||
using devices_t = ::osmosdr::devices_t;
|
||||
|
||||
py::class_<devices_t>(m, "devices_t");
|
||||
|
||||
|
||||
using device = ::osmosdr::device;
|
||||
|
||||
py::class_<device>(m, "device")
|
||||
.def_static("find", &device::find, py::arg("hint") = device_t());
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
This directory stores templates for docstrings that are scraped from the include header files for each block
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* Copyright 2020 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU Radio
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
*/
|
||||
#include "pydoc_macros.h"
|
||||
#define D(...) DOC(osmosdr, __VA_ARGS__ )
|
||||
/*
|
||||
This file contains placeholders for docstrings for the Python bindings.
|
||||
Do not edit! These were automatically extracted during the binding process
|
||||
and will be overwritten during the build process
|
||||
*/
|
||||
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_sink_0 = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_sink_1 = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_make = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_num_channels = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_sample_rates = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_set_sample_rate = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_sample_rate = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_freq_range = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_set_center_freq = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_center_freq = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_set_freq_corr = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_freq_corr = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_gain_names = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_gain_range_0 = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_gain_range_1 = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_set_gain_mode = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_gain_mode = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_set_gain_0 = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_set_gain_1 = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_gain_0 = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_gain_1 = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_set_if_gain = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_set_bb_gain = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_antennas = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_set_antenna = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_antenna = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_set_dc_offset = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_set_iq_balance = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_set_bandwidth = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_bandwidth = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_bandwidth_range = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_set_time_source = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_time_source = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_time_sources = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_set_clock_source = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_clock_source = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_clock_sources = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_clock_rate = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_set_clock_rate = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_time_now = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_get_time_last_pps = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_set_time_now = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_set_time_next_pps = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_sink_set_time_unknown_pps = R"doc()doc";
|
||||
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* Copyright 2020 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU Radio
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
*/
|
||||
#include "pydoc_macros.h"
|
||||
#define D(...) DOC(osmosdr, __VA_ARGS__ )
|
||||
/*
|
||||
This file contains placeholders for docstrings for the Python bindings.
|
||||
Do not edit! These were automatically extracted during the binding process
|
||||
and will be overwritten during the build process
|
||||
*/
|
||||
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_source_0 = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_source_1 = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_make = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_num_channels = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_seek = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_sample_rates = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_set_sample_rate = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_sample_rate = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_freq_range = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_set_center_freq = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_center_freq = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_set_freq_corr = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_freq_corr = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_gain_names = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_gain_range_0 = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_gain_range_1 = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_set_gain_mode = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_gain_mode = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_set_gain_0 = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_set_gain_1 = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_gain_0 = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_gain_1 = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_set_if_gain = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_set_bb_gain = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_antennas = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_set_antenna = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_antenna = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_set_dc_offset_mode = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_set_dc_offset = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_set_iq_balance_mode = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_set_iq_balance = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_set_bandwidth = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_bandwidth = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_bandwidth_range = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_set_time_source = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_time_source = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_time_sources = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_set_clock_source = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_clock_source = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_clock_sources = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_clock_rate = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_set_clock_rate = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_time_now = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_get_time_last_pps = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_set_time_now = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_set_time_next_pps = R"doc()doc";
|
||||
|
||||
|
||||
static const char *__doc_osmosdr_source_set_time_unknown_pps = R"doc()doc";
|
||||
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
# Utilities for reading values in header files
|
||||
|
||||
from argparse import ArgumentParser
|
||||
import re
|
||||
|
||||
|
||||
class PybindHeaderParser:
|
||||
def __init__(self, pathname):
|
||||
with open(pathname,'r') as f:
|
||||
self.file_txt = f.read()
|
||||
|
||||
def get_flag_automatic(self):
|
||||
# p = re.compile(r'BINDTOOL_GEN_AUTOMATIC\(([^\s])\)')
|
||||
# m = p.search(self.file_txt)
|
||||
m = re.search(r'BINDTOOL_GEN_AUTOMATIC\(([^\s])\)', self.file_txt)
|
||||
if (m and m.group(1) == '1'):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def get_flag_pygccxml(self):
|
||||
# p = re.compile(r'BINDTOOL_USE_PYGCCXML\(([^\s])\)')
|
||||
# m = p.search(self.file_txt)
|
||||
m = re.search(r'BINDTOOL_USE_PYGCCXML\(([^\s])\)', self.file_txt)
|
||||
if (m and m.group(1) == '1'):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def get_header_filename(self):
|
||||
# p = re.compile(r'BINDTOOL_HEADER_FILE\(([^\s]*)\)')
|
||||
# m = p.search(self.file_txt)
|
||||
m = re.search(r'BINDTOOL_HEADER_FILE\(([^\s]*)\)', self.file_txt)
|
||||
if (m):
|
||||
return m.group(1)
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_header_file_hash(self):
|
||||
# p = re.compile(r'BINDTOOL_HEADER_FILE_HASH\(([^\s]*)\)')
|
||||
# m = p.search(self.file_txt)
|
||||
m = re.search(r'BINDTOOL_HEADER_FILE_HASH\(([^\s]*)\)', self.file_txt)
|
||||
if (m):
|
||||
return m.group(1)
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_flags(self):
|
||||
return f'{self.get_flag_automatic()};{self.get_flag_pygccxml()};{self.get_header_filename()};{self.get_header_file_hash()};'
|
||||
|
||||
|
||||
|
||||
def argParse():
|
||||
"""Parses commandline args."""
|
||||
desc='Reads the parameters from the comment block in the pybind files'
|
||||
parser = ArgumentParser(description=desc)
|
||||
|
||||
parser.add_argument("function", help="Operation to perform on comment block of pybind file", choices=["flag_auto","flag_pygccxml","header_filename","header_file_hash","all"])
|
||||
parser.add_argument("pathname", help="Pathname of pybind c++ file to read, e.g. blockname_python.cc")
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Parse command line options and set up doxyxml.
|
||||
args = argParse()
|
||||
|
||||
pbhp = PybindHeaderParser(args.pathname)
|
||||
|
||||
if args.function == "flag_auto":
|
||||
print(pbhp.get_flag_automatic())
|
||||
elif args.function == "flag_pygccxml":
|
||||
print(pbhp.get_flag_pygccxml())
|
||||
elif args.function == "header_filename":
|
||||
print(pbhp.get_header_filename())
|
||||
elif args.function == "header_file_hash":
|
||||
print(pbhp.get_header_file_hash())
|
||||
elif args.function == "all":
|
||||
print(pbhp.get_flags())
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright 2020 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU Radio
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
*/
|
||||
|
||||
#include <pybind11/pybind11.h>
|
||||
|
||||
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
|
||||
#include <numpy/arrayobject.h>
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
// Headers for binding functions
|
||||
/**************************************/
|
||||
// The following comment block is used for
|
||||
// gr_modtool to insert function prototypes
|
||||
// Please do not delete
|
||||
/**************************************/
|
||||
// BINDING_FUNCTION_PROTOTYPES(
|
||||
void bind_sink(py::module& m);
|
||||
void bind_source(py::module& m);
|
||||
// ) END BINDING_FUNCTION_PROTOTYPES
|
||||
|
||||
void bind_device(py::module& m);
|
||||
void bind_ranges(py::module& m);
|
||||
void bind_time_spec(py::module& m);
|
||||
|
||||
|
||||
// We need this hack because import_array() returns NULL
|
||||
// for newer Python versions.
|
||||
// This function is also necessary because it ensures access to the C API
|
||||
// and removes a warning.
|
||||
void* init_numpy()
|
||||
{
|
||||
import_array();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PYBIND11_MODULE(osmosdr_python, m)
|
||||
{
|
||||
// Initialize the numpy C API
|
||||
// (otherwise we will see segmentation faults)
|
||||
init_numpy();
|
||||
|
||||
// Allow access to base block methods
|
||||
py::module::import("gnuradio.gr");
|
||||
|
||||
/**************************************/
|
||||
// The following comment block is used for
|
||||
// gr_modtool to insert binding function calls
|
||||
// Please do not delete
|
||||
/**************************************/
|
||||
// BINDING_FUNCTION_CALLS(
|
||||
bind_sink(m);
|
||||
bind_source(m);
|
||||
// ) END BINDING_FUNCTION_CALLS
|
||||
|
||||
bind_device(m);
|
||||
bind_ranges(m);
|
||||
bind_time_spec(m);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#include <pybind11/pybind11.h>
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
#include <osmosdr/ranges.h>
|
||||
|
||||
void bind_ranges(py::module& m)
|
||||
{
|
||||
m.attr("ALL_MBOARDS") = ::osmosdr::ALL_MBOARDS;
|
||||
m.attr("ALL_CHANS") = ::osmosdr::ALL_CHANS;
|
||||
|
||||
|
||||
using range_t = ::osmosdr::range_t;
|
||||
|
||||
py::class_<range_t>(m, "range_t")
|
||||
.def(py::init<double>(), py::arg("value") = 0)
|
||||
.def(py::init<double, double, double>(), py::arg("start"), py::arg("stop"), py::arg("step") = 0)
|
||||
.def("start", &range_t::start)
|
||||
.def("stop", &range_t::stop)
|
||||
.def("step", &range_t::step)
|
||||
.def("to_pp_string", &range_t::to_pp_string);
|
||||
|
||||
|
||||
using meta_range_t = ::osmosdr::meta_range_t;
|
||||
|
||||
py::class_<meta_range_t>(m, "meta_range_t")
|
||||
.def(py::init())
|
||||
.def(py::init<double, double, double>(), py::arg("start"), py::arg("stop"), py::arg("step") = 0)
|
||||
.def("start", &meta_range_t::start)
|
||||
.def("stop", &meta_range_t::stop)
|
||||
.def("step", &meta_range_t::step)
|
||||
.def("clip", &meta_range_t::clip, py::arg("value"), py::arg("clip_step") = false)
|
||||
.def("values", &meta_range_t::values)
|
||||
.def("to_pp_string", &meta_range_t::to_pp_string);
|
||||
}
|
|
@ -0,0 +1,320 @@
|
|||
/*
|
||||
* Copyright 2020 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU Radio
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
*/
|
||||
|
||||
/***********************************************************************************/
|
||||
/* This file is automatically generated using bindtool and can be manually edited */
|
||||
/* The following lines can be configured to regenerate this file during cmake */
|
||||
/* If manual edits are made, the following tags should be modified accordingly. */
|
||||
/* BINDTOOL_GEN_AUTOMATIC(1) */
|
||||
/* BINDTOOL_USE_PYGCCXML(0) */
|
||||
/* BINDTOOL_HEADER_FILE(sink.h) */
|
||||
/* BINDTOOL_HEADER_FILE_HASH(d4331eb8a19b7a2aa4ed0100039f7a0e) */
|
||||
/***********************************************************************************/
|
||||
|
||||
#include <pybind11/complex.h>
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
#include <osmosdr/sink.h>
|
||||
// pydoc.h is automatically generated in the build directory
|
||||
#include <sink_pydoc.h>
|
||||
|
||||
void bind_sink(py::module& m)
|
||||
{
|
||||
|
||||
using sink = ::osmosdr::sink;
|
||||
|
||||
|
||||
py::class_<sink, gr::hier_block2,
|
||||
std::shared_ptr<sink>>(m, "sink", D(sink))
|
||||
|
||||
.def(py::init(&sink::make),
|
||||
py::arg("args") = "",
|
||||
D(sink,make)
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.def("get_num_channels",&sink::get_num_channels,
|
||||
D(sink,get_num_channels)
|
||||
)
|
||||
|
||||
|
||||
.def("get_sample_rates",&sink::get_sample_rates,
|
||||
D(sink,get_sample_rates)
|
||||
)
|
||||
|
||||
|
||||
.def("set_sample_rate",&sink::set_sample_rate,
|
||||
py::arg("rate"),
|
||||
D(sink,set_sample_rate)
|
||||
)
|
||||
|
||||
|
||||
.def("get_sample_rate",&sink::get_sample_rate,
|
||||
D(sink,get_sample_rate)
|
||||
)
|
||||
|
||||
|
||||
.def("get_freq_range",&sink::get_freq_range,
|
||||
py::arg("chan") = 0,
|
||||
D(sink,get_freq_range)
|
||||
)
|
||||
|
||||
|
||||
.def("set_center_freq",&sink::set_center_freq,
|
||||
py::arg("freq"),
|
||||
py::arg("chan") = 0,
|
||||
D(sink,set_center_freq)
|
||||
)
|
||||
|
||||
|
||||
.def("get_center_freq",&sink::get_center_freq,
|
||||
py::arg("chan") = 0,
|
||||
D(sink,get_center_freq)
|
||||
)
|
||||
|
||||
|
||||
.def("set_freq_corr",&sink::set_freq_corr,
|
||||
py::arg("ppm"),
|
||||
py::arg("chan") = 0,
|
||||
D(sink,set_freq_corr)
|
||||
)
|
||||
|
||||
|
||||
.def("get_freq_corr",&sink::get_freq_corr,
|
||||
py::arg("chan") = 0,
|
||||
D(sink,get_freq_corr)
|
||||
)
|
||||
|
||||
|
||||
.def("get_gain_names",&sink::get_gain_names,
|
||||
py::arg("chan") = 0,
|
||||
D(sink,get_gain_names)
|
||||
)
|
||||
|
||||
|
||||
.def("get_gain_range",(osmosdr::gain_range_t (sink::*)(size_t))&sink::get_gain_range,
|
||||
py::arg("chan") = 0,
|
||||
D(sink,get_gain_range,0)
|
||||
)
|
||||
|
||||
|
||||
.def("get_gain_range",(osmosdr::gain_range_t (sink::*)(std::string const &, size_t))&sink::get_gain_range,
|
||||
py::arg("name"),
|
||||
py::arg("chan") = 0,
|
||||
D(sink,get_gain_range,1)
|
||||
)
|
||||
|
||||
|
||||
.def("set_gain_mode",&sink::set_gain_mode,
|
||||
py::arg("automatic"),
|
||||
py::arg("chan") = 0,
|
||||
D(sink,set_gain_mode)
|
||||
)
|
||||
|
||||
|
||||
.def("get_gain_mode",&sink::get_gain_mode,
|
||||
py::arg("chan") = 0,
|
||||
D(sink,get_gain_mode)
|
||||
)
|
||||
|
||||
|
||||
.def("set_gain",(double (sink::*)(double, size_t))&sink::set_gain,
|
||||
py::arg("gain"),
|
||||
py::arg("chan") = 0,
|
||||
D(sink,set_gain,0)
|
||||
)
|
||||
|
||||
|
||||
.def("set_gain",(double (sink::*)(double, std::string const &, size_t))&sink::set_gain,
|
||||
py::arg("gain"),
|
||||
py::arg("name"),
|
||||
py::arg("chan") = 0,
|
||||
D(sink,set_gain,1)
|
||||
)
|
||||
|
||||
|
||||
.def("get_gain",(double (sink::*)(size_t))&sink::get_gain,
|
||||
py::arg("chan") = 0,
|
||||
D(sink,get_gain,0)
|
||||
)
|
||||
|
||||
|
||||
.def("get_gain",(double (sink::*)(std::string const &, size_t))&sink::get_gain,
|
||||
py::arg("name"),
|
||||
py::arg("chan") = 0,
|
||||
D(sink,get_gain,1)
|
||||
)
|
||||
|
||||
|
||||
.def("set_if_gain",&sink::set_if_gain,
|
||||
py::arg("gain"),
|
||||
py::arg("chan") = 0,
|
||||
D(sink,set_if_gain)
|
||||
)
|
||||
|
||||
|
||||
.def("set_bb_gain",&sink::set_bb_gain,
|
||||
py::arg("gain"),
|
||||
py::arg("chan") = 0,
|
||||
D(sink,set_bb_gain)
|
||||
)
|
||||
|
||||
|
||||
.def("get_antennas",&sink::get_antennas,
|
||||
py::arg("chan") = 0,
|
||||
D(sink,get_antennas)
|
||||
)
|
||||
|
||||
|
||||
.def("set_antenna",&sink::set_antenna,
|
||||
py::arg("antenna"),
|
||||
py::arg("chan") = 0,
|
||||
D(sink,set_antenna)
|
||||
)
|
||||
|
||||
|
||||
.def("get_antenna",&sink::get_antenna,
|
||||
py::arg("chan") = 0,
|
||||
D(sink,get_antenna)
|
||||
)
|
||||
|
||||
|
||||
.def("set_dc_offset",&sink::set_dc_offset,
|
||||
py::arg("offset"),
|
||||
py::arg("chan") = 0,
|
||||
D(sink,set_dc_offset)
|
||||
)
|
||||
|
||||
|
||||
.def("set_iq_balance",&sink::set_iq_balance,
|
||||
py::arg("balance"),
|
||||
py::arg("chan") = 0,
|
||||
D(sink,set_iq_balance)
|
||||
)
|
||||
|
||||
|
||||
.def("set_bandwidth",&sink::set_bandwidth,
|
||||
py::arg("bandwidth"),
|
||||
py::arg("chan") = 0,
|
||||
D(sink,set_bandwidth)
|
||||
)
|
||||
|
||||
|
||||
.def("get_bandwidth",&sink::get_bandwidth,
|
||||
py::arg("chan") = 0,
|
||||
D(sink,get_bandwidth)
|
||||
)
|
||||
|
||||
|
||||
.def("get_bandwidth_range",&sink::get_bandwidth_range,
|
||||
py::arg("chan") = 0,
|
||||
D(sink,get_bandwidth_range)
|
||||
)
|
||||
|
||||
|
||||
.def("set_time_source",&sink::set_time_source,
|
||||
py::arg("source"),
|
||||
py::arg("mboard") = 0,
|
||||
D(sink,set_time_source)
|
||||
)
|
||||
|
||||
|
||||
.def("get_time_source",&sink::get_time_source,
|
||||
py::arg("mboard"),
|
||||
D(sink,get_time_source)
|
||||
)
|
||||
|
||||
|
||||
.def("get_time_sources",&sink::get_time_sources,
|
||||
py::arg("mboard"),
|
||||
D(sink,get_time_sources)
|
||||
)
|
||||
|
||||
|
||||
.def("set_clock_source",&sink::set_clock_source,
|
||||
py::arg("source"),
|
||||
py::arg("mboard") = 0,
|
||||
D(sink,set_clock_source)
|
||||
)
|
||||
|
||||
|
||||
.def("get_clock_source",&sink::get_clock_source,
|
||||
py::arg("mboard"),
|
||||
D(sink,get_clock_source)
|
||||
)
|
||||
|
||||
|
||||
.def("get_clock_sources",&sink::get_clock_sources,
|
||||
py::arg("mboard"),
|
||||
D(sink,get_clock_sources)
|
||||
)
|
||||
|
||||
|
||||
.def("get_clock_rate",&sink::get_clock_rate,
|
||||
py::arg("mboard") = 0,
|
||||
D(sink,get_clock_rate)
|
||||
)
|
||||
|
||||
|
||||
.def("set_clock_rate",&sink::set_clock_rate,
|
||||
py::arg("rate"),
|
||||
py::arg("mboard") = 0,
|
||||
D(sink,set_clock_rate)
|
||||
)
|
||||
|
||||
|
||||
.def("get_time_now",&sink::get_time_now,
|
||||
py::arg("mboard") = 0,
|
||||
D(sink,get_time_now)
|
||||
)
|
||||
|
||||
|
||||
.def("get_time_last_pps",&sink::get_time_last_pps,
|
||||
py::arg("mboard") = 0,
|
||||
D(sink,get_time_last_pps)
|
||||
)
|
||||
|
||||
|
||||
.def("set_time_now",&sink::set_time_now,
|
||||
py::arg("time_spec"),
|
||||
py::arg("mboard") = 0,
|
||||
D(sink,set_time_now)
|
||||
)
|
||||
|
||||
|
||||
.def("set_time_next_pps",&sink::set_time_next_pps,
|
||||
py::arg("time_spec"),
|
||||
D(sink,set_time_next_pps)
|
||||
)
|
||||
|
||||
|
||||
.def("set_time_unknown_pps",&sink::set_time_unknown_pps,
|
||||
py::arg("time_spec"),
|
||||
D(sink,set_time_unknown_pps)
|
||||
)
|
||||
|
||||
;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,342 @@
|
|||
/*
|
||||
* Copyright 2020 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU Radio
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
*/
|
||||
|
||||
/***********************************************************************************/
|
||||
/* This file is automatically generated using bindtool and can be manually edited */
|
||||
/* The following lines can be configured to regenerate this file during cmake */
|
||||
/* If manual edits are made, the following tags should be modified accordingly. */
|
||||
/* BINDTOOL_GEN_AUTOMATIC(1) */
|
||||
/* BINDTOOL_USE_PYGCCXML(0) */
|
||||
/* BINDTOOL_HEADER_FILE(source.h) */
|
||||
/* BINDTOOL_HEADER_FILE_HASH(d1a3d9ea3d815fe4f18acc3eef21f1b6) */
|
||||
/***********************************************************************************/
|
||||
|
||||
#include <pybind11/complex.h>
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
#include <osmosdr/source.h>
|
||||
// pydoc.h is automatically generated in the build directory
|
||||
#include <source_pydoc.h>
|
||||
|
||||
void bind_source(py::module& m)
|
||||
{
|
||||
|
||||
using source = ::osmosdr::source;
|
||||
|
||||
|
||||
py::class_<source, gr::hier_block2,
|
||||
std::shared_ptr<source>>(m, "source", D(source))
|
||||
|
||||
.def(py::init(&source::make),
|
||||
py::arg("args") = "",
|
||||
D(source,make)
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.def("get_num_channels",&source::get_num_channels,
|
||||
D(source,get_num_channels)
|
||||
)
|
||||
|
||||
|
||||
.def("seek",&source::seek,
|
||||
py::arg("seek_point"),
|
||||
py::arg("whence"),
|
||||
py::arg("chan") = 0,
|
||||
D(source,seek)
|
||||
)
|
||||
|
||||
|
||||
.def("get_sample_rates",&source::get_sample_rates,
|
||||
D(source,get_sample_rates)
|
||||
)
|
||||
|
||||
|
||||
.def("set_sample_rate",&source::set_sample_rate,
|
||||
py::arg("rate"),
|
||||
D(source,set_sample_rate)
|
||||
)
|
||||
|
||||
|
||||
.def("get_sample_rate",&source::get_sample_rate,
|
||||
D(source,get_sample_rate)
|
||||
)
|
||||
|
||||
|
||||
.def("get_freq_range",&source::get_freq_range,
|
||||
py::arg("chan") = 0,
|
||||
D(source,get_freq_range)
|
||||
)
|
||||
|
||||
|
||||
.def("set_center_freq",&source::set_center_freq,
|
||||
py::arg("freq"),
|
||||
py::arg("chan") = 0,
|
||||
D(source,set_center_freq)
|
||||
)
|
||||
|
||||
|
||||
.def("get_center_freq",&source::get_center_freq,
|
||||
py::arg("chan") = 0,
|
||||
D(source,get_center_freq)
|
||||
)
|
||||
|
||||
|
||||
.def("set_freq_corr",&source::set_freq_corr,
|
||||
py::arg("ppm"),
|
||||
py::arg("chan") = 0,
|
||||
D(source,set_freq_corr)
|
||||
)
|
||||
|
||||
|
||||
.def("get_freq_corr",&source::get_freq_corr,
|
||||
py::arg("chan") = 0,
|
||||
D(source,get_freq_corr)
|
||||
)
|
||||
|
||||
|
||||
.def("get_gain_names",&source::get_gain_names,
|
||||
py::arg("chan") = 0,
|
||||
D(source,get_gain_names)
|
||||
)
|
||||
|
||||
|
||||
.def("get_gain_range",(osmosdr::gain_range_t (source::*)(size_t))&source::get_gain_range,
|
||||
py::arg("chan") = 0,
|
||||
D(source,get_gain_range,0)
|
||||
)
|
||||
|
||||
|
||||
.def("get_gain_range",(osmosdr::gain_range_t (source::*)(std::string const &, size_t))&source::get_gain_range,
|
||||
py::arg("name"),
|
||||
py::arg("chan") = 0,
|
||||
D(source,get_gain_range,1)
|
||||
)
|
||||
|
||||
|
||||
.def("set_gain_mode",&source::set_gain_mode,
|
||||
py::arg("automatic"),
|
||||
py::arg("chan") = 0,
|
||||
D(source,set_gain_mode)
|
||||
)
|
||||
|
||||
|
||||
.def("get_gain_mode",&source::get_gain_mode,
|
||||
py::arg("chan") = 0,
|
||||
D(source,get_gain_mode)
|
||||
)
|
||||
|
||||
|
||||
.def("set_gain",(double (source::*)(double, size_t))&source::set_gain,
|
||||
py::arg("gain"),
|
||||
py::arg("chan") = 0,
|
||||
D(source,set_gain,0)
|
||||
)
|
||||
|
||||
|
||||
.def("set_gain",(double (source::*)(double, std::string const &, size_t))&source::set_gain,
|
||||
py::arg("gain"),
|
||||
py::arg("name"),
|
||||
py::arg("chan") = 0,
|
||||
D(source,set_gain,1)
|
||||
)
|
||||
|
||||
|
||||
.def("get_gain",(double (source::*)(size_t))&source::get_gain,
|
||||
py::arg("chan") = 0,
|
||||
D(source,get_gain,0)
|
||||
)
|
||||
|
||||
|
||||
.def("get_gain",(double (source::*)(std::string const &, size_t))&source::get_gain,
|
||||
py::arg("name"),
|
||||
py::arg("chan") = 0,
|
||||
D(source,get_gain,1)
|
||||
)
|
||||
|
||||
|
||||
.def("set_if_gain",&source::set_if_gain,
|
||||
py::arg("gain"),
|
||||
py::arg("chan") = 0,
|
||||
D(source,set_if_gain)
|
||||
)
|
||||
|
||||
|
||||
.def("set_bb_gain",&source::set_bb_gain,
|
||||
py::arg("gain"),
|
||||
py::arg("chan") = 0,
|
||||
D(source,set_bb_gain)
|
||||
)
|
||||
|
||||
|
||||
.def("get_antennas",&source::get_antennas,
|
||||
py::arg("chan") = 0,
|
||||
D(source,get_antennas)
|
||||
)
|
||||
|
||||
|
||||
.def("set_antenna",&source::set_antenna,
|
||||
py::arg("antenna"),
|
||||
py::arg("chan") = 0,
|
||||
D(source,set_antenna)
|
||||
)
|
||||
|
||||
|
||||
.def("get_antenna",&source::get_antenna,
|
||||
py::arg("chan") = 0,
|
||||
D(source,get_antenna)
|
||||
)
|
||||
|
||||
|
||||
.def("set_dc_offset_mode",&source::set_dc_offset_mode,
|
||||
py::arg("mode"),
|
||||
py::arg("chan") = 0,
|
||||
D(source,set_dc_offset_mode)
|
||||
)
|
||||
|
||||
|
||||
.def("set_dc_offset",&source::set_dc_offset,
|
||||
py::arg("offset"),
|
||||
py::arg("chan") = 0,
|
||||
D(source,set_dc_offset)
|
||||
)
|
||||
|
||||
|
||||
.def("set_iq_balance_mode",&source::set_iq_balance_mode,
|
||||
py::arg("mode"),
|
||||
py::arg("chan") = 0,
|
||||
D(source,set_iq_balance_mode)
|
||||
)
|
||||
|
||||
|
||||
.def("set_iq_balance",&source::set_iq_balance,
|
||||
py::arg("balance"),
|
||||
py::arg("chan") = 0,
|
||||
D(source,set_iq_balance)
|
||||
)
|
||||
|
||||
|
||||
.def("set_bandwidth",&source::set_bandwidth,
|
||||
py::arg("bandwidth"),
|
||||
py::arg("chan") = 0,
|
||||
D(source,set_bandwidth)
|
||||
)
|
||||
|
||||
|
||||
.def("get_bandwidth",&source::get_bandwidth,
|
||||
py::arg("chan") = 0,
|
||||
D(source,get_bandwidth)
|
||||
)
|
||||
|
||||
|
||||
.def("get_bandwidth_range",&source::get_bandwidth_range,
|
||||
py::arg("chan") = 0,
|
||||
D(source,get_bandwidth_range)
|
||||
)
|
||||
|
||||
|
||||
.def("set_time_source",&source::set_time_source,
|
||||
py::arg("source"),
|
||||
py::arg("mboard") = 0,
|
||||
D(source,set_time_source)
|
||||
)
|
||||
|
||||
|
||||
.def("get_time_source",&source::get_time_source,
|
||||
py::arg("mboard"),
|
||||
D(source,get_time_source)
|
||||
)
|
||||
|
||||
|
||||
.def("get_time_sources",&source::get_time_sources,
|
||||
py::arg("mboard"),
|
||||
D(source,get_time_sources)
|
||||
)
|
||||
|
||||
|
||||
.def("set_clock_source",&source::set_clock_source,
|
||||
py::arg("source"),
|
||||
py::arg("mboard") = 0,
|
||||
D(source,set_clock_source)
|
||||
)
|
||||
|
||||
|
||||
.def("get_clock_source",&source::get_clock_source,
|
||||
py::arg("mboard"),
|
||||
D(source,get_clock_source)
|
||||
)
|
||||
|
||||
|
||||
.def("get_clock_sources",&source::get_clock_sources,
|
||||
py::arg("mboard"),
|
||||
D(source,get_clock_sources)
|
||||
)
|
||||
|
||||
|
||||
.def("get_clock_rate",&source::get_clock_rate,
|
||||
py::arg("mboard") = 0,
|
||||
D(source,get_clock_rate)
|
||||
)
|
||||
|
||||
|
||||
.def("set_clock_rate",&source::set_clock_rate,
|
||||
py::arg("rate"),
|
||||
py::arg("mboard") = 0,
|
||||
D(source,set_clock_rate)
|
||||
)
|
||||
|
||||
|
||||
.def("get_time_now",&source::get_time_now,
|
||||
py::arg("mboard") = 0,
|
||||
D(source,get_time_now)
|
||||
)
|
||||
|
||||
|
||||
.def("get_time_last_pps",&source::get_time_last_pps,
|
||||
py::arg("mboard") = 0,
|
||||
D(source,get_time_last_pps)
|
||||
)
|
||||
|
||||
|
||||
.def("set_time_now",&source::set_time_now,
|
||||
py::arg("time_spec"),
|
||||
py::arg("mboard") = 0,
|
||||
D(source,set_time_now)
|
||||
)
|
||||
|
||||
|
||||
.def("set_time_next_pps",&source::set_time_next_pps,
|
||||
py::arg("time_spec"),
|
||||
D(source,set_time_next_pps)
|
||||
)
|
||||
|
||||
|
||||
.def("set_time_unknown_pps",&source::set_time_unknown_pps,
|
||||
py::arg("time_spec"),
|
||||
D(source,set_time_unknown_pps)
|
||||
)
|
||||
|
||||
;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/operators.h>
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
#include <osmosdr/time_spec.h>
|
||||
|
||||
void bind_time_spec(py::module& m)
|
||||
{
|
||||
using time_spec_t = ::osmosdr::time_spec_t;
|
||||
|
||||
py::class_<time_spec_t>(m, "time_spec_t")
|
||||
.def_static("get_system_time", &time_spec_t::get_system_time)
|
||||
.def(py::init<double>(), py::arg("secs") = 0)
|
||||
.def(py::init<time_t, double>(), py::arg("full_secs"), py::arg("frac_secs") = 0)
|
||||
.def(py::init<time_t, long, double>(), py::arg("full_secs"), py::arg("tick_count"), py::arg("tick_rate"))
|
||||
.def_static("from_ticks", &time_spec_t::from_ticks, py::arg("ticks"), py::arg("tick_rate"))
|
||||
.def("get_tick_count", &time_spec_t::get_tick_count, py::arg("tick_rate"))
|
||||
.def("to_ticks", &time_spec_t::to_ticks, py::arg("tick_rate"))
|
||||
.def("get_real_secs", &time_spec_t::get_real_secs)
|
||||
.def("get_full_secs", &time_spec_t::get_full_secs)
|
||||
.def("get_frac_secs", &time_spec_t::get_frac_secs)
|
||||
.def(py::self + py::self)
|
||||
.def(py::self += py::self)
|
||||
.def(py::self - py::self)
|
||||
.def(py::self -= py::self)
|
||||
.def(py::self == py::self)
|
||||
.def(py::self != py::self)
|
||||
.def(py::self < py::self)
|
||||
.def(py::self > py::self)
|
||||
.def(py::self <= py::self)
|
||||
.def(py::self >= py::self);
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
# Copyright 2011 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of gr-osmosdr
|
||||
#
|
||||
# gr-osmosdr is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# gr-osmosdr is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with gr-osmosdr; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
########################################################################
|
||||
# Include swig generation macros
|
||||
########################################################################
|
||||
find_package(SWIG)
|
||||
find_package(PythonLibs 3)
|
||||
if(NOT SWIG_FOUND OR NOT PYTHONLIBS_FOUND)
|
||||
return()
|
||||
endif()
|
||||
include(GrSwig)
|
||||
include(GrPython)
|
||||
|
||||
########################################################################
|
||||
# Setup swig generation
|
||||
########################################################################
|
||||
set(GR_SWIG_INCLUDE_DIRS $<TARGET_PROPERTY:gnuradio::runtime_swig,INTERFACE_INCLUDE_DIRECTORIES>)
|
||||
set(GR_SWIG_TARGET_DEPS gnuradio::runtime_swig)
|
||||
|
||||
set(GR_SWIG_LIBRARIES gnuradio-osmosdr)
|
||||
|
||||
set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/osmosdr_swig_doc.i)
|
||||
set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../include/osmosdr)
|
||||
|
||||
GR_SWIG_MAKE(osmosdr_swig osmosdr_swig.i)
|
||||
|
||||
########################################################################
|
||||
# Install the build swig module
|
||||
########################################################################
|
||||
GR_SWIG_INSTALL(TARGETS osmosdr_swig DESTINATION ${GR_PYTHON_DIR}/osmosdr)
|
||||
|
||||
########################################################################
|
||||
# Install swig .i files for development
|
||||
########################################################################
|
||||
install(
|
||||
FILES
|
||||
osmosdr_swig.i
|
||||
${CMAKE_CURRENT_BINARY_DIR}/osmosdr_swig_doc.i
|
||||
DESTINATION ${GR_INCLUDE_DIR}/osmosdr/swig
|
||||
)
|
|
@ -1,82 +0,0 @@
|
|||
/* -*- c++ -*- */
|
||||
|
||||
#define OSMOSDR_API
|
||||
|
||||
// suppress Warning 319: No access specifier given for base class 'boost::noncopyable' (ignored).
|
||||
#pragma SWIG nowarn=319
|
||||
|
||||
%include "gnuradio.i" // the common stuff
|
||||
|
||||
//load generated python docstrings
|
||||
%include "osmosdr_swig_doc.i"
|
||||
|
||||
%{
|
||||
#include "osmosdr/device.h"
|
||||
#include "osmosdr/source.h"
|
||||
#include "osmosdr/sink.h"
|
||||
%}
|
||||
|
||||
// Workaround for a SWIG 2.0.4 bug with templates. Probably needs to be looked in to.
|
||||
%{
|
||||
#if PY_VERSION_HEX >= 0x03020000
|
||||
# define SWIGPY_SLICE_ARG(obj) ((PyObject*) (obj))
|
||||
#else
|
||||
# define SWIGPY_SLICE_ARG(obj) ((PySliceObject*) (obj))
|
||||
#endif
|
||||
%}
|
||||
|
||||
%template(string_vector_t) std::vector<std::string>;
|
||||
|
||||
//%template(size_vector_t) std::vector<size_t>;
|
||||
|
||||
%include <osmosdr/pimpl.h>
|
||||
|
||||
%ignore osmosdr::device_t::operator[]; //ignore warnings about %extend
|
||||
|
||||
%template(string_string_dict_t) std::map<std::string, std::string>; //define before device
|
||||
%template(devices_t) std::vector<osmosdr::device_t>;
|
||||
%include <osmosdr/device.h>
|
||||
|
||||
//%extend std::map<std::string, std::string>{
|
||||
// std::string __getitem__(std::string key) {return (*self)[key];}
|
||||
// void __setitem__(std::string key, std::string val) {(*self)[key] = val;}
|
||||
//};
|
||||
|
||||
%template(range_vector_t) std::vector<osmosdr::range_t>; //define before range
|
||||
%include <osmosdr/ranges.h>
|
||||
|
||||
%include <osmosdr/time_spec.h>
|
||||
|
||||
%extend osmosdr::time_spec_t{
|
||||
osmosdr::time_spec_t __add__(const osmosdr::time_spec_t &what)
|
||||
{
|
||||
osmosdr::time_spec_t temp = *self;
|
||||
temp += what;
|
||||
return temp;
|
||||
}
|
||||
osmosdr::time_spec_t __sub__(const osmosdr::time_spec_t &what)
|
||||
{
|
||||
osmosdr::time_spec_t temp = *self;
|
||||
temp -= what;
|
||||
return temp;
|
||||
}
|
||||
};
|
||||
|
||||
%define OSMOSDR_SWIG_BLOCK_MAGIC2(PKG, BASE_NAME)
|
||||
%template(BASE_NAME ## _sptr) boost::shared_ptr<PKG ## :: ## BASE_NAME>;
|
||||
%pythoncode %{
|
||||
BASE_NAME ## _sptr.__repr__ = lambda self: "<gr_block %s (%d)>" % (self.name(), self.unique_id())
|
||||
BASE_NAME = BASE_NAME.make;
|
||||
%}
|
||||
%enddef
|
||||
|
||||
%include "osmosdr/source.h"
|
||||
%include "osmosdr/sink.h"
|
||||
|
||||
OSMOSDR_SWIG_BLOCK_MAGIC2(osmosdr,source);
|
||||
OSMOSDR_SWIG_BLOCK_MAGIC2(osmosdr,sink);
|
||||
|
||||
%{
|
||||
static const size_t ALL_MBOARDS = osmosdr::ALL_MBOARDS;
|
||||
%}
|
||||
//static const size_t ALL_MBOARDS;
|
Loading…
Reference in New Issue