Skip to content
Josh Blum edited this page Mar 31, 2013 · 1 revision
http://i.imgur.com/o5c6Z.png

Almost every aspect of the GRAS C++ API has Python bindings. So the GRAS API can be used as effectivly in Python as it is in C++. Further, IP written in either language can easily interoperate with the other; allowing users to easily cross language boundaries.

The best demonstration of this Python support is to see the coding guide. For every feature is a C++ example and a matching Python example: https://github.com/guruofquality/gras/wiki/Codeguide

Blocks in python

The goal is to allow the user to write blocks in 100% python.

The typical GNU Radio coding model is

  1. write signal processing in C++
  2. connect the flow graph in python

This is smart. Python is not fast, but efficient to code. C++ is faster, but more effort is required. But why not code the signal processing blocks themselves in python?

The benefits:

  • Quickly develop and debug your algorithm, before implementing it in C++.
  • If the processing can be handled in python, why not leave it in python?
  • Do work with external libraries with python bindings, like Numpy.

So, writing signal processing in python is a time saver at the very least, and doing so isn't necessarily going to be a performance issue.

Full API access

http://i.imgur.com/7hs3B.png

Using this feature, users can get access to all available API functionality in a typical C++ block. Users can:

  • Write a signal processing work() function that will be called by the scheduler
  • Access to standard block methods like configuration, item counts, produce, consume...
  • Access to stream tags, msgs, properties

Implementation

http://i.imgur.com/7hs3B.png

The block input and output signatures are specified as numpy dtypes. Numpy dtypes can represent any array structure of arbitrary complexity; and because of python's duck typing, the work arrays come to the user shaped/formatted by this signature. No typecasting, authoring a work() routine is incredibly strait-forward.

import gras

class Add2X(gras.Block):
    def __init__(self, sig):
        gras.Block.__init__(self,
            name = "Add2X",
            in_sig = [sig, sig],
            out_sig = [sig],
        )

    def work(self, ins, outs):
        nitems = min(*map(len, (ins[0], ins[1], outs[0])))
        outs[0][:nitems] = ins[0][:nitems] + ins[1][:nitems]
        self.consume(0, nitems)
        self.consume(1, nitems)
        self.produce(0, nitems)

See how simple it can be with these demo blocks used for testing purposes: https://github.com/guruofquality/gras/blob/master/tests/demo_blocks.py

Clone this wiki locally