Compare commits

...

31 Commits

Author SHA1 Message Date
Robert Ghilduta 821fdb3822 bladeRF: convert to using std instead of boost for shared_ptr 2022-06-10 16:30:49 +02:00
Robert Ghilduta 038a26501c bladeRF: minor fixups to keep clang happy 2022-06-10 16:30:49 +02:00
Robert Ghilduta 95b1025b01 bladeRF: calculate number of samples based on stream count 2022-06-10 16:30:49 +02:00
Robert Ghilduta bfdc4d917c bladeRF: enable and disable each channel 2022-06-10 16:30:49 +02:00
Robert Ghilduta 34daf86ec3 bladeRF: set default gain mode to manual 2022-06-10 16:30:49 +02:00
Ryan Tucker a343cc208b source/sink_impl: query hardware for gains on init
Instead of guessing, query the device to populate _gain_mode and _gain.
2022-06-10 16:30:49 +02:00
Robert Ghilduta f6a8992856 bladeRF: check libbladeRF version before compiling 2022-06-10 16:30:49 +02:00
Eric Wild 6a22db7568 switch to gr-funcube
due to deprecation, see https://osmocom.org/issues/5445
2022-06-10 16:30:49 +02:00
Eric Wild 6b11b02947 fix missing sink/source iface destructor 2022-06-10 16:30:49 +02:00
Eric Wild a309841752 osmocom_fft: make it work with gr >= 3.9 qwidget/pyqwidget
This should fix it for both versions
2022-06-10 16:30:49 +02:00
Eric Wild 09e72004fe default to c++11
GR needs it anyway..
2022-06-10 16:28:52 +02:00
Eric Wild e13c2e4e1c add a reasonable .gitignore 2022-06-10 16:28:52 +02:00
Vadim Yanitskiy 9c58e8a991 apps/osmocom_siggen: fix missing parentheses in call to print 2022-05-14 14:50:48 +03:00
Ron Economos a100eb024c Remove Doxygen warnings.
Signed-off-by: Ron Economos <w6rz@comcast.net>
Signed-off-by: Eric Wild <ewild@sysmocom.de>
2021-01-28 22:15:52 +01:00
Ron Economos ba755e113e Remove CMake warnings.
Signed-off-by: Ron Economos <w6rz@comcast.net>
Signed-off-by: Eric Wild <ewild@sysmocom.de>
2021-01-28 22:15:47 +01:00
Eric Wild 7e955ad284 apps: fix up guiles siggen for 3.9 2021-01-27 02:43:25 +01:00
Eric Wild 64781cc652 disable spectrum sense for now
feval was removed in gr commit 0249f7ce0cf5173b946b936c5cd66380afc8bf92
2021-01-27 02:43:25 +01:00
Clayton Smith c7012949e1 Use the new namespace for FFT windows
Signed-off-by: Eric Wild <ewild@sysmocom.de>
2021-01-18 21:16:22 +01:00
Clayton Smith 1f724162e1 Add Python bindings
Signed-off-by: Eric Wild <ewild@sysmocom.de>
2021-01-18 21:16:17 +01:00
Matt Mills f88dc7df2f Fix docstrings in python bindings for gr namespace
Signed-off-by: Eric Wild <ewild@sysmocom.de>
2021-01-18 21:16:11 +01:00
Matt Mills 0d727b3ef8 Replace swig with pybind11 for gr3.9 master compat
Signed-off-by: Eric Wild <ewild@sysmocom.de>
2021-01-18 21:16:05 +01:00
Clayton Smith 159885f9e6 Replace boost::shared_ptr with std::shared_ptr
Signed-off-by: Eric Wild <ewild@sysmocom.de>
2021-01-18 21:15:57 +01:00
Gwenhael Goavec-Merou cffef690f2 lib/xtrx: add missing libraries
Linking to the libxtrx libs got lost while merging
the xtrx support, which led to runtime issues when trying to use it.

Signed-off-by: Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
Signed-off-by: Eric Wild <ewild@sysmocom.de>
2021-01-17 23:08:55 +01:00
Clayton Smith c3187ab875 xtrx: remove BOOST_FOREACH and obsolete API call
All instances of BOOST_FOREACH were removed in an earlier commit, but it
was reintroduced when xtrx support was merged. I removed BOOST_FOREACH
again here.

Also, xtrx support fails to build because it relies on the
xtrx_open_list function, which was removed from the xtrx API in 2019. It
was replaced with xtrx_open_string.

I don't have xtrx hardware, so I've only tested that gr-osmosdr compiles
with these changes.

Signed-off-by: Eric Wild <ewild@sysmocom.de>
2021-01-10 19:31:59 +01:00
Clayton Smith bc629b03fe hackrf: fix bandwidth setting
The T/R switching code added in ae2253c516
fails to set custom filter bandwidths because it sets bandwidth and
sample rate in the wrong order. As noted in the documentation for
hackrf_set_sample_rate: "If you want to override the baseband filter
selection, you must do so after setting the sample rate."

To solve this problem I moved the set_bandwidth call after
set_sample_rate. It was also necessary to skip the call if a custom
bandwidth was not requested.

Signed-off-by: Eric Wild <ewild@sysmocom.de>
2021-01-04 22:27:53 +01:00
Adrian Chadd 9b386707d8 Fix hackrf receive hangs by checking before each lock wait
Fix receive path hangs if another thread closes down the hackrf
receive whilst this buffer receive function is waiting to be
woken up.

Now:

* Sleep for up to 100ms each time waiting for the cond to be kicked;
* Check whether streaming is still enabled each time rather than
  only when the function is entered.

This fixes hangs where consumers like gqrx via gnuradio
will do a stop_rx/start_rx very quickly to change something, and
the buffer receive path is waiting for a buffer.

Signed-off-by: Eric Wild <ewild@sysmocom.de>
2020-12-18 13:22:24 +01:00
Csaba Sipos dc82ffd1f8 add xtrx support
Signed-off-by: Eric Wild <ewild@sysmocom.de>
2020-11-19 01:41:05 +01:00
Clayton Smith fe03d83703 Remove disabled OsmoSDR and MiriSDR code
OsmoSDR and MiriSDR support was disabled in v0.2.1 because the hardware
is rare and obsolete. I think it would be useful to completely remove
the associated code, since this will reduce the future maintenance
burden for gr-osmosdr.

Signed-off-by: Eric Wild <ewild@sysmocom.de>
2020-11-01 00:12:56 +01:00
Clayton Smith 2d504bde50 rfspace: Remove broken asio code
Asio sockets were replaced with native BSD sockets in
e1b699fda0, and the old code was placed
behind #ifdef USE_ASIO. Subsequent commits soon broke the asio code.
Since it's been broken for a long time, I doubt anyone is using it, so
it makes sense to remove it.

Signed-off-by: Eric Wild <ewild@sysmocom.de>
2020-11-01 00:06:28 +01:00
Clayton Smith e5bee0820f Replace BOOST_FOREACH with range-based for loops
Range-based for loops are available since C++11. Using them reduces
gr-osmosdr's dependence on Boost. Here I've done the replacement using a
global search-and-replace.

Signed-off-by: Eric Wild <ewild@sysmocom.de>
2020-11-01 00:04:27 +01:00
Eric Wild 90c3d5b555 fix windows build 2020-10-31 23:56:26 +01:00
96 changed files with 3441 additions and 2193 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/.vscode/*
/build/*
*.pyc
*.pyo

View File

@ -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
View File

@ -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

View File

@ -30,6 +30,6 @@ GR_PYTHON_INSTALL(
osmocom_fft
# osmocom_siggen
osmocom_siggen_nogui
osmocom_spectrum_sense
# osmocom_spectrum_sense
DESTINATION ${GR_RUNTIME_DIR}
)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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}

View File

@ -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

View File

@ -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)

View File

@ -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.

View File

@ -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.

View File

@ -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;

View File

@ -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
########################################################################

View 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.

View File

@ -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.

View File

@ -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 &params )
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 &params )
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"))

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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()

View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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 = "" );

View File

@ -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 = "" );

View File

@ -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.

View File

@ -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.

View File

@ -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());
}

View File

@ -104,6 +104,7 @@ private:
double _freq_corr;
bool _auto_gain;
double _amp_gain;
double _requested_bandwidth;
double _bandwidth;
bool _bias;
bool _started;

View File

@ -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.

View File

@ -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 )

View File

@ -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.

View File

@ -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)

View File

@ -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";
}

View File

@ -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 */

View File

@ -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";
}

View File

@ -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 */

View File

@ -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();

View File

@ -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 = "" );

View File

@ -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 = "" );

View File

@ -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;

View File

@ -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;

View File

@ -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.

View File

@ -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 = "" );

View File

@ -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,

View File

@ -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.

View File

@ -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
*/

View File

@ -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 );
}

View File

@ -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));
}

View File

@ -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.

View File

@ -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));
}

View File

@ -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.

View File

@ -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
*/

View File

@ -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 );
}

View File

@ -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;

View File

@ -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 = "");

View File

@ -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;

View File

@ -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 = "");

View File

@ -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)

138
lib/xtrx/xtrx_obj.cc Normal file
View File

@ -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);
}
}

68
lib/xtrx/xtrx_obj.h Normal file
View File

@ -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

505
lib/xtrx/xtrx_sink_c.cc Normal file
View File

@ -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(&params);
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(), &params);
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;
}

129
lib/xtrx/xtrx_sink_c.h Normal file
View File

@ -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

583
lib/xtrx/xtrx_source_c.cc Normal file
View File

@ -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(&params);
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(), &params);
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;
}

127
lib/xtrx/xtrx_source_c.h Normal file
View File

@ -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

View File

@ -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)

View File

@ -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
#

View File

@ -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)

View File

View File

@ -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)

View File

@ -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());
}

View File

@ -0,0 +1 @@
This directory stores templates for docstrings that are scraped from the include header files for each block

View File

@ -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";

View File

@ -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";

View File

@ -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())

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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)
)
;
}

View File

@ -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)
)
;
}

View File

@ -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);
}

View File

@ -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
)

View File

@ -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;