Replace swig with pybind11 for gr3.9 master compat

Signed-off-by: Eric Wild <ewild@sysmocom.de>
This commit is contained in:
Matt Mills 2020-10-29 18:28:13 -06:00 committed by Eric Wild
parent 159885f9e6
commit 0d727b3ef8
17 changed files with 1354 additions and 285 deletions

View File

@ -41,7 +41,7 @@ set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules) list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules)
# Find GNURadio (pmt and runtime are core, always included) # Find GNURadio (pmt and runtime are core, always included)
find_package(Gnuradio "3.8" REQUIRED COMPONENTS blocks fft filter) find_package(Gnuradio "3.9" REQUIRED COMPONENTS blocks fft filter)
# Set the version information here # Set the version information here
set(VERSION_MAJOR 0) set(VERSION_MAJOR 0)
@ -188,20 +188,11 @@ find_package(Doxygen)
########## ##########
find_package(PythonLibs 3) find_package(PythonLibs 3)
find_package(SWIG) find_package(pybind11)
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)
GR_REGISTER_COMPONENT("Python support" ENABLE_PYTHON GR_REGISTER_COMPONENT("Python support" ENABLE_PYTHON
PYTHONLIBS_FOUND PYTHONLIBS_FOUND
SWIG_FOUND pybind11_FOUND
SWIG_VERSION_CHECK
) )
######################################################################## ########################################################################
@ -269,7 +260,6 @@ add_custom_target(uninstall
add_subdirectory(include/osmosdr) add_subdirectory(include/osmosdr)
add_subdirectory(lib) add_subdirectory(lib)
if(ENABLE_PYTHON) if(ENABLE_PYTHON)
add_subdirectory(swig)
add_subdirectory(python) add_subdirectory(python)
add_subdirectory(grc) add_subdirectory(grc)
add_subdirectory(apps) add_subdirectory(apps)

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. # Copyright 2010-2012 Free Software Foundation, Inc.
# #
# This file was generated by gr_modtool, a tool from the GNU Radio framework # 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 # SPDX-License-Identifier: GPL-3.0-or-later
# 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.
# #
""" """
Creates the swig_doc.i SWIG interface file. Updates the *pydoc_h files for a module
Execute using: python swig_doc.py xml_path outputfilename 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. 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 DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile
from doxyxml import DoxyOther, base from doxyxml import DoxyOther, base
@ -87,6 +75,7 @@ def utoascii(text):
return '' return ''
out = text.encode('ascii', 'replace') out = text.encode('ascii', 'replace')
# swig will require us to replace blackslash with 4 backslashes # 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'\\\\\\\\')
out = out.replace(b'"', b'\\"').decode('ascii') out = out.replace(b'"', b'\\"').decode('ascii')
return str(out) return str(out)
@ -115,7 +104,7 @@ def format_params(parameteritems):
entry_templ = '%feature("docstring") {name} "{docstring}"' entry_templ = '%feature("docstring") {name} "{docstring}"'
def make_entry(obj, name=None, templ="{description}", description=None, params=[]): 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. obj - a doxyxml object from which documentation will be extracted.
name - the name of the C object (defaults to obj.name()) 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: if name is None:
name=obj.name() 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: if "operator " in name:
return '' return ''
if description is None: if description is None:
@ -134,56 +125,28 @@ def make_entry(obj, name=None, templ="{description}", description=None, params=[
description += '\n\n' description += '\n\n'
description += utoascii(format_params(params)) description += utoascii(format_params(params))
docstring = templ.format(description=description) docstring = templ.format(description=description)
if not docstring:
return ''
return entry_templ.format(
name=name,
docstring=docstring,
)
return {name: 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)
def make_class_entry(klass, description=None, ignored_methods=[], params=None): 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: if params is None:
params = klass.params params = klass.params
output = [] output = {}
output.append(make_entry(klass, description=description, params=params)) output.update(make_entry(klass, description=description, params=params))
for func in klass.in_category(DoxyFunction): for func in klass.in_category(DoxyFunction):
if func.name() not in ignored_methods: if func.name() not in ignored_methods:
name = klass.name() + '::' + func.name() name = klass.name() + '::' + func.name()
output.append(make_func_entry(func, name=name)) output.update(make_entry(func, name=name))
return "\n\n".join(output) return output
def make_block_entry(di, block): def make_block_entry(di, block):
""" """
Create class and function docstrings of a gnuradio block for a Create class and function docstrings of a gnuradio block
swig interface file.
""" """
descriptions = [] descriptions = []
# Get the documentation associated with the class. # Get the documentation associated with the class.
@ -208,18 +171,16 @@ def make_block_entry(di, block):
super_description = "\n\n".join(descriptions) super_description = "\n\n".join(descriptions)
# Associate the combined description with the class and # Associate the combined description with the class and
# the make function. # the make function.
output = [] output = {}
output.append(make_class_entry(block, description=super_description)) output.update(make_class_entry(block, description=super_description))
output.append(make_func_entry(make_func, description=super_description, output.update(make_entry(make_func, description=super_description,
params=block.params)) params=block.params))
return "\n\n".join(output) return output
def make_block2_entry(di, block): def make_block2_entry(di, block):
""" """
Create class and function docstrings of a new style gnuradio block for a Create class and function docstrings of a new style gnuradio block
swig interface file.
""" """
descriptions = []
# For new style blocks all the relevant documentation should be # For new style blocks all the relevant documentation should be
# associated with the 'make' method. # associated with the 'make' method.
class_description = combine_descriptions(block) 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 description = class_description + "\n\nConstructor Specific Documentation:\n\n" + make_description
# Associate the combined description with the class and # Associate the combined description with the class and
# the make function. # the make function.
output = [] output = {}
output.append(make_class_entry( output.update(make_class_entry(
block, description=description, block, description=description,
ignored_methods=['make'], params=make_func.params)) ignored_methods=['make'], params=make_func.params))
makename = block.name() + '::make' makename = block.name() + '::make'
output.append(make_func_entry( output.update(make_entry(
make_func, name=makename, description=description, make_func, name=makename, description=description,
params=make_func.params)) 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 = [""" output = {}
/* if custom_output:
* This file was automatically generated using swig_doc.py. output.update(custom_output)
*
* Any changes to it will be lost next time it is regenerated.
*/
"""]
if custom_output is not None:
output.append(custom_output)
# Create docstrings for the blocks. # Create docstrings for the blocks.
blocks = di.in_category(Block) 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. # Don't want to risk writing to output twice.
if make_func.name() not in make_funcs: if make_func.name() not in make_funcs:
make_funcs.add(make_func.name()) make_funcs.add(make_func.name())
output.append(make_block_entry(di, block)) output.update(make_block_entry(di, block))
except block.ParsingError: except block.ParsingError:
sys.stderr.write('Parsing error for block {0}\n'.format(block.name())) sys.stderr.write('Parsing error for block {0}\n'.format(block.name()))
raise raise
@ -274,7 +228,7 @@ def make_swig_interface_file(di, swigdocfilename, custom_output=None):
# Don't want to risk writing to output twice. # Don't want to risk writing to output twice.
if make_func_name not in make_funcs: if make_func_name not in make_funcs:
make_funcs.add(make_func_name) make_funcs.add(make_func_name)
output.append(make_block2_entry(di, block)) output.update(make_block2_entry(di, block))
except block.ParsingError: except block.ParsingError:
sys.stderr.write('Parsing error for block {0}\n'.format(block.name())) sys.stderr.write('Parsing error for block {0}\n'.format(block.name()))
raise 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::')] if f.name() not in make_funcs and not f.name().startswith('std::')]
for f in funcs: for f in funcs:
try: try:
output.append(make_func_entry(f)) output.update(make_entry(f))
except f.ParsingError: except f.ParsingError:
sys.stderr.write('Parsing error for function {0}\n'.format(f.name())) 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::')] if k.name() not in block_names and not k.name().startswith('std::')]
for k in klasses: for k in klasses:
try: try:
output.append(make_class_entry(k)) output.update(make_class_entry(k))
except k.ParsingError: except k.ParsingError:
sys.stderr.write('Parsing error for class {0}\n'.format(k.name())) 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. # Docstrings are not created for anything that is not a function or a class.
# If this excludes anything important please add it here. # If this excludes anything important please add it here.
output = "\n\n".join(output) return output
swig_doc = open(swigdocfilename, 'w') def sub_docstring_in_pydoc_h(pydoc_files, docstrings_dict, output_dir, filter_str=None):
swig_doc.write(output) if filter_str:
swig_doc.close() 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__": if __name__ == "__main__":
# Parse command line options and set up doxyxml. # Parse command line options and set up doxyxml.
err_msg = "Execute using: python swig_doc.py xml_path outputfilename" args = argParse()
if len(sys.argv) != 3: if args.function.lower() == 'scrape':
raise Exception(err_msg) di = DoxyIndex(args.xml_path)
xml_path = sys.argv[1] docstrings_dict = get_docstrings_dict(di)
swigdocfilename = sys.argv[2] with open(args.json_path, 'w') as fp:
di = DoxyIndex(xml_path) 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

@ -1,21 +1,10 @@
# Copyright 2011 Free Software Foundation, Inc. # 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 # SPDX-License-Identifier: GPL-3.0-or-later
# 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 python install macros # Include python install macros
@ -25,6 +14,8 @@ if(NOT PYTHONINTERP_FOUND)
return() return()
endif() endif()
add_subdirectory(bindings)
######################################################################## ########################################################################
# Install python sources # Install python sources
######################################################################## ########################################################################
@ -40,4 +31,3 @@ GR_PYTHON_INSTALL(
include(GrTest) include(GrTest)
set(GR_TEST_TARGET_DEPS gnuradio-osmosdr) 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. # Copyright 2008,2009 Free Software Foundation, Inc.
# #
# This application is free software; you can redistribute it and/or modify # SPDX-License-Identifier: GPL-3.0-or-later
# 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.
# #
# The presence of this file turns this directory into a Python package # 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,30 @@
# 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
sink_python.cc
source_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 @@
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(gr,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(gr,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,57 @@
/*
* 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
// 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
}

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(574373c3c7682569b0fd7eea577739da) */
/***********************************************************************************/
#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

@ -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) std::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;