Pothos & Python questions

711 views
Skip to first unread message

davi...@comcast.net

unread,
Jun 2, 2016, 3:46:00 PM6/2/16
to Pothos Users
Hi Josh,

I'm sending this to the user group as it may be of interest to others.

I've been working on a C++ block to demodulate a certain signal and have been using the Pothos GUI to test it with file data and my RTL-SDR.  That is going fine and for the next part of my project I want to use Python (with QT or PyGTK) to create a stand-alone GUI application for collecting this signal (rather than running a flow diagram inside the Pothos GUI).

In searching the web, I have seen some GNURadio-based applications that use this technique.  I've looked through the Pothos web site but haven't found information or examples of how to do this using Pothos.

Specifically I'm looking to find out how to:
1.  Instantiate and inter-connect Pothos blocks from a Python program.

2.  Set parameters on the blocks from a Python program (for instance, set the frequency on the SDR Source block).

3.  Get data from my block back to the Python program.  For example, my demodulator block generates strings of decoded text that I would like to display in a scrolling text window (like FLDigi or MultiPSK does).  Right now that text just goes to the Pothos GUI message window (using cout).  I guess I am looking for something that would be analogous to a callback function.

Are these kinds of functions supported by Pothos?  Do you have (or could you generate) examples of how to implement these functions from a Python program?

Thanks for the help,
    Jim Davis

Josh Blum

unread,
Jun 2, 2016, 6:49:52 PM6/2/16
to davi...@comcast.net, Pothos Users
Hey Jim,

>
> Specifically I'm looking to find out how to:
> 1. Instantiate and inter-connect Pothos blocks from a Python program.

I just made a simple example, check it out:
https://github.com/pothosware/pothos-python/blob/master/Pothos/TestTopology.py

>
> 2. Set parameters on the blocks from a Python program (for instance, set
> the frequency on the SDR Source block).

Just like the feeder in the TestTopology example, you can make normal
function calls on the block once instantiated:

source = reg.callProxy("/sdr/source", "complex_float32", [0])
source.setupDevice({"driver":"rtl:})
source.setupStream({})
source.setSampleRate(1e6)

>
> 3. Get data from my block back to the Python program. For example, my
> demodulator block generates strings of decoded text that I would like to
> display in a scrolling text window (like FLDigi or MultiPSK does). Right
> now that text just goes to the Pothos GUI message window (using cout). I
> guess I am looking for something that would be analogous to a callback
> function.

In this case I would make a block in python whose work() function
accepts input from the upstream decoder block and does something with it.

In the TestTopology example, the MessageForwarder block intercepts and
prints something from the upstream block.

>
> Are these kinds of functions supported by Pothos? Do you have (or could
> you generate) examples of how to implement these functions from a Python
> program?
>

I found some minor issues making this example, I don't think it will be
a big hindrance here, but they are on my radar to improve:

* https://github.com/pothosware/pothos-python/issues/12
* https://github.com/pothosware/pothos-python/issues/11

Let me know if this TestTopology example works for you or if there is
something that I can clarify. Thanks!

-josh

davi...@comcast.net

unread,
Jun 2, 2016, 8:18:43 PM6/2/16
to Pothos Users

Thanks for the example & hints - that should get me started.  Hopefully I'll have some time over the weekend to try some things out.  I'll   let you know how it goes.

Jim D

davi...@comcast.net

unread,
Jun 3, 2016, 7:21:35 PM6/3/16
to Pothos Users
Hi Josh,
Before embarking on my Python application, I decided to update using the newest installer - I figured I might as well get the latest updates as I'm planning to use Python 3.5.

I downloaded and ran the PothosSDR-2016.05.22-vc14-x64.exe installer - it completed normally and I was able to run the soapyrtlutil comands to find my device.  I also saw the note to run the GnuRadioHelper script so I did that.  

I've run GnuRadioHelper a couple of times and get the following error:

========================================
== Checks failed summary
========================================
IMPORT_GR:      DLL load failed with error code -1073741795

========================================
== Fixing problems
========================================
Handling issues for IMPORT_GR...
Error: GNURadio modules missing from PYTHONPATH

Current search path:
  * C:\Program Files\PothosSDR\bin
  * C:\Program Files\PothosSDR\lib\site-packages
  * C:\Program Files\PothosSDR\lib\python2.7\site-packages
  * C:\Windows\system32\python27.zip
  * c:\python27\DLLs
  * c:\python27\lib
  * c:\python27\lib\plat-win
  * c:\python27\lib\lib-tk
  * c:\python27
  * c:\python27\lib\site-packages
  * c:\python27\lib\site-packages\gtk-2.0
  * c:\python27\lib\site-packages\wx-3.0-msw

Current PYTHONPATH: 'C:\Program Files\PothosSDR\lib\site-packages;C:\Program Fil
es\PothosSDR\lib\python2.7\site-packages'

The PYTHONPATH for the current user has been modified
Open a new command window and re-run this script...

Changes made! Please re-run this script in a new terminal.


This happens each time I run the script.

Also, when I open the PothosGUI some of blocks are missing - looks like they are mostly blocks from GnuRadio.  I get these messages in the GUI message window for one of my flow diagrams (that used to work):

[23:09:50.885400] PothosGui.GraphBlock.init: Cant find block factory with path: '/gr/filter/freq_xlating_fir_filter'

[23:09:50.911400] PothosGui.GraphBlock.init: Cant find block factory with path: '/gr/blocks/complex_to_real'

[23:09:51.011400] PothosGui.GraphBlock.init: Cant find block factory with path: '/gr/blocks/complex_to_real'

[23:09:51.020400] PothosGui.GraphBlock.init: Cant find block factory with path: '/gr/filter/fir_filter'



So once again I think I have missed a key step in installing stuff.  Any thoughts as to how I can recover?

Thanks,
   Jim 

Josh Blum

unread,
Jun 3, 2016, 8:16:07 PM6/3/16
to pothos...@googlegroups.com


On 06/03/2016 04:21 PM, davi...@comcast.net wrote:
> Hi Josh,
> Before embarking on my Python application, I decided to update using the
> newest installer - I figured I might as well get the latest updates as I'm
> planning to use Python 3.5.
>
> I downloaded and ran the *PothosSDR-2016.05.22-vc14-x64.exe* installer - it
> completed normally and I was able to run the soapyrtlutil comands to find
> my device. I also saw the note to run the GnuRadioHelper script so I did
> that.
>
> I've run GnuRadioHelper a couple of times and get the following error:
>
> ========================================
> == Checks failed summary
> ========================================
> IMPORT_GR: DLL load failed with error code -1073741795
>

I'm guessing that there is a missing DLL thats needed by GNURadio. That
would explain the loading problems and the python import issue.

Can you run dependency walker on gnuradio-runtime.dll and see if
something obvious stands out?

-josh

davi...@comcast.net

unread,
Jun 4, 2016, 9:29:55 AM6/4/16
to Pothos Users, jo...@joshknows.com

Dependency walker lists several dlls that it can't find for gnuradio-runtime.dll.   I attached a screen capture.


Jim


gnuruntime.png

Josh Blum

unread,
Jun 4, 2016, 3:31:55 PM6/4/16
to davi...@comcast.net, Pothos Users
Hey Jim,

Looks like I can repeat this for the vc14 installer, but not the vc12.
I'm not sure exactly what happened but I think some things goofed up by
accident while debugging that stayed in my build directory and made it
into the installer. I'm cleaning everything and rebuilding a new vc14
installer and I will see how it fairs on a clean system first.

Thanks,
-josh

Josh Blum

unread,
Jun 4, 2016, 8:13:43 PM6/4/16
to davi...@comcast.net, Pothos Users
Ignore my last response. I narrowed it down to volk.dll. It looks like
volk got built with some architecture specific flags that only work on
certain PCs with AVX support. It was fixed on maint as far as I can
tell, so I am rebuilding now and I will see what happens.

-josh

Josh Blum

unread,
Jun 5, 2016, 12:54:49 AM6/5/16
to davi...@comcast.net, Pothos Users
Sorry for the flood of emails. There is a new installer uploaded. I'm
now using the maint branch of volk -- perhaps thats the better way to
go. And the reason thtat msvc2013 build didnt have the issue is because
it didnt support the newer AVX flags which were making the binary
incompatible.

Also I took care of those two python issues mentioned before. So its
possible to just use Pothos.Topology and Pothos.BlockRegistry (which is
more pythonic looking). I updated the example for this on master, but
the binaries still have the older code.

-josh

davi...@comcast.net

unread,
Jun 5, 2016, 9:33:58 AM6/5/16
to Pothos Users, davi...@comcast.net, jo...@joshknows.com

Hi Josh,

Thanks for looking into this problem.  I'll download the new installer and let you know how it goes.  It may be a couple of days before I have time to do very much - I'm taking my youngest to college orientation today/tomorrow.

Jim 

davi...@comcast.net

unread,
Jun 11, 2016, 3:06:15 PM6/11/16
to Pothos Users, davi...@comcast.net, jo...@joshknows.com
Hi Josh,

I've been using the new installer and generally it seems to be working well - I'm not seeing the problems with the GnuRadio blocks. I have noticed one thing that may or may not be issues that you may want to look at.

    When I close the PothosGui, it leaves a couple of processes running that I have to terminate using the Windows Task Manager.  There are two processes that remain running:  PothosGui.exe and PothosUtil.exe. In debugging my block I use the following sequence: do some debugging, close the PothosGui, make my changes, rebuild, reinstall the block, and restart PothosGUI to try the new version.  The reinstall step was failing with the error that "another program had the file open".  When I manually end the two "leftover" processes the installation of the block works.

    This happens even if I open the PothosGUI without any flowdiagram loaded and then close the PothosGUI. I don't remember seeing this with the previous version that I was using (installer PothosSDR-2016.01.29-vc14-x64.exe).

  I haven't had a chance this week to try the running the TestTopology example from Python but I hope to play around with it this weekend.

Jim D

Josh Blum

unread,
Jun 12, 2016, 2:09:34 AM6/12/16
to davi...@comcast.net, Pothos Users

>
> When I close the PothosGui, it leaves a couple of processes running
> that I have to terminate using the Windows Task Manager. There are two
> processes that remain running: PothosGui.exe and PothosUtil.exe. In
> debugging my block I use the following sequence: do some debugging, close
> the PothosGui, make my changes, rebuild, reinstall the block, and restart
> PothosGUI to try the new version. The reinstall step was failing with the
> error that "another program had the file open". When I manually end the
> two "leftover" processes the installation of the block works.

Hey Jim,

I think that there is some threads or connections left open when the GUI
closes. Something isnt being cleaned up in the right order. I think this
was mentioned on the freebsd thread, and I'm suspecting something fishy
as well on linux. So I'm taking a look at this...

I was thinking about adding a reload feature to the gui. It should
definitely be possible to unload and reload the plugins, albeit a bit of
a dance of careful coordination -- I think it will be a good way to
properly fix the clean shutdown of the gui as well.

This will also be useful for development, although it will be
interesting to get working on windows. When a dll plugin is loaded it
cant be overwritten on windows. Unix seems to let you do that by
reference counting the open files.

-josh

davi...@comcast.net

unread,
Jun 23, 2016, 9:41:50 PM6/23/16
to Pothos Users, davi...@comcast.net, jo...@joshknows.com


Hi Josh,

I have made more progress and now have a Python program that creates & runs my topology.  As you suggested, I've added an output port to my decoder block and created a Python class to receive the messages from my decoder block (based on the MessageForwarder block in your TestTopology example).  

My Python class receives the messages generated by my decoder block like this:

    def work(self):
        if self.input(0).hasMessage():
            msg = self.input(0).popMessage()
            print('%s' %msg)


For each received message "<class Pothos::Object>" is printed. I'd like to get the contents of the message (a string) inside the work() function but I can't quite figure out how to do that.  I understand how your example got all the messages from the CollectorSink but I would like to handle each message as it is received.

I found some C examples (like in the Collector_Sink) and it seems like I need to do something like "msgStr = msg.extract()" but I haven't found a Python example showing how to make extract() return a string.

Can you point me to anything that shows how to use the various methods for a message (like .type() and .extract()) from Python?  I looked through the various include files but didn't find anything.

Thanks,
    Jim D

Josh Blum

unread,
Jun 24, 2016, 2:14:49 AM6/24/16
to davi...@comcast.net, Pothos Users

>
> Can you point me to anything that shows how to use the various methods for
> a message (like .type() and .extract()) from Python? I looked through the
> various include files but didn't find anything.
>

Hey Jim,

It was actually a bug that I had noticed while doing this example. And
its fixed now on the master branch. So you should get the native python
data type - no conversions or special calls or anything like that.

https://github.com/pothosware/pothos-python/issues/11

https://github.com/pothosware/pothos-python/commit/7759969a539ecb6b31da7374bfe365c8c8795fb9

I suppose I ought to tag and rebuild the installer this weekend, but if
you find it faster, you can probably build and install pothos-python on
top of the existing install. Its just a cmake project and all of the
dependencies should be present (pothos and python).

Hope that helps!
-josh

davi...@comcast.net

unread,
Jun 24, 2016, 8:25:44 PM6/24/16
to Pothos Users, davi...@comcast.net, jo...@joshknows.com
Hi Josh,

I downloaded the updated pothos-python source and rebuilt it.  I noticed one issue - when I tried to build it for RelWithDebInfo, I got a linking error that python35_d.lib was not found.  So I built the release versions and used the cmake_install.cmake script to copy the files to the PothosSDR folder.  I did some googling and it looks like the debug library isn't included in the Python install - I'll have to work on getting that installed.

I ran my Python application (without making any changes from yesterday) - it ran like before so I think that I built/installed the pothos-python correctly.

Next I updated the work() function in my application to try to get the text string from the message:

    def work(self):
        if self.input(0).hasMessage():
            msg = self.input(0).popMessage()
            print('%s' %msg)
            msgStr = msg.extract()
            print('%s' %msgStr)

When I run the application, I get this printout for each received message:

<class Pothos::Object>

2016-06-24 19:59:11 Pothos.Block.work: /blocks/python_block: Proxy Exception Mes

sage: Proxy Handle Call Error: ManagedProxyHandle::call(extract): no available c

alls :<class Pothos::Object>

 

So I think that I am still not understanding how to use the extract() and other methods associated with the message object.  Or I didn't actually build the pothos-python correctly.


I am building using Visual Studio 14 x64 and the Anaconda Python 3.5 distribution.


Any thoughts (or examples) that would help me?


Thanks,

   Jim 






Josh Blum

unread,
Jun 25, 2016, 2:55:31 AM6/25/16
to davi...@comcast.net, Pothos Users


On 06/24/2016 05:25 PM, davi...@comcast.net wrote:
> Hi Josh,
>
> I downloaded the updated pothos-python source and rebuilt it. I noticed
> one issue - when I tried to build it for RelWithDebInfo, I got a linking
> error that python35_d.lib was not found. So I built the release versions
> and used the cmake_install.cmake script to copy the files to the PothosSDR
> folder. I did some googling and it looks like the debug library isn't
> included in the Python install - I'll have to work on getting that
> installed.

FWIW, I have never built with the debug python. I don't know why its
picking it up by default. If it helps, these are my python settings for
the installer, and you may want to set similar variables:

* https://github.com/pothosware/PothosSDR/blob/master/SetupPython.cmake#L15

And how it gets passed to cmake:

* https://github.com/pothosware/PothosSDR/blob/master/BuildPothos.cmake#L282

>
> So I think that I am still not understanding how to use the extract() and
> other methods associated with the message object. Or I didn't actually
> build the pothos-python correctly.

Do make sure that the files are replaced in both the site-packages and
the modules folder:

* lib\python3.5\site-packages\Pothos\* and
* lib\Pothos\modules\proxy\environment\PythonSupport.dll

>
>
> I am building using Visual Studio 14 x64 and the Anaconda Python 3.5
> distribution.
>
>
> Any thoughts (or examples) that would help me?

If it is installed correctly, you should be able to run this example:
https://github.com/pothosware/pothos-python/blob/master/Pothos/TestTopology.py

and get the output (which is pretty much what you are looking for)

msg hello
msg world
msg 123
["hello", "world", 123]

I will be uploading an installer tomorrow. I was just about to now, but
I'm waiting on a small CubicSDR fix to be merged first.
-josh

>
>
> Thanks,
>
> Jim
>
>
>
>
>
>

davi...@comcast.net

unread,
Jun 26, 2016, 6:48:53 PM6/26/16
to Pothos Users, davi...@comcast.net, jo...@joshknows.com
Hi Josh,

I've downloaded the new installer and things are better now.  I can run your TestTopology application and get the expected results that you indicated.  So I must have messed something up trying to build & install the pothos-python modules.

I guess I'm going to have to talk to some of the smart young SW engineers at work and have them give me a CMake tutorial :)  

Thanks for the installer update.

Jim D

davi...@comcast.net

unread,
Jul 2, 2016, 8:10:57 PM7/2/16
to Pothos Users, davi...@comcast.net, jo...@joshknows.com


Hi Josh,

I have got the receiving of data from my decoder block in my Python application sorted out.  I had an error in my block where I was setting up the text string to be sent on the output port. That's all working using a BinaryFileSource to provide a test signal to some filters and my decoder block.

So I am moving on to using the SDRSource block to get real data from my RTL SDR.  The SDRSource block gets created and set up but when the topology.commit() function gets called I get the following error:

Proxy Exception Message: Framework Topology Connect Error: Pothos::Topology::commit(): Framework Topology Connect Error: /sdr/source.activate(): Exception: SDRSource::activate(): device not ready

In the python.exe command window, the message "Found Rafael Micro R820T tuner" is printed twice (I also see this message in the PothosGUI window when I use the SDRSource block there).  If I change the driver name in the setupDevice() call, then those messages don't get displayed.  This seems to indicate that the RTL device is present.  The device works fine in the PothosGUI and with SDR#.

When I run the SoapySDRUtil it gives this output:

C:\Program Files\PothosSDR\bin>SoapySDRUtil.exe --find
######################################################
## Soapy SDR -- the SDR abstraction library
######################################################

Win32; Microsoft Visual C++ version 14.0; Boost_106000; UHD_003.009.004-0-g2b5a8
8bb

Found Rafael Micro R820T tuner
Found device 0
  default_input = True
  default_output = True
  device_id = 0
  driver = audio
  label = Default Device

Found device 1
  default_input = False
  default_output = False
  device_id = 5
  driver = audio
  label = CABLE Output (VB-Audio Virtual Cable)

Found device 2
  default_input = False
  default_output = False
  device_id = 6
  driver = audio
  label = Stereo Mix (Realtek High Definition Audio)

Found device 3
  available = Yes
  driver = rtlsdr
  label = Generic RTL2832U OEM :: 00000001
  manufacturer = Realtek
  product = RTL2838UHIDIR
  rtl = 0
  serial = 00000001
  tuner = Rafael Micro R820T

Found device 4
  driver = s9c


I attached the simple Python program that I am using to try to get the SDRSource running.  It sets up the SDRSource, connects a Python block to the output port, and should receive data on an input port.

I've tried rebooting, disconnecting/reconnecting USB to the RTL-SDR, and checked in TaskManager that nothing else is running that could be using the device.  None of that has helped - can you offer any suggestions?

Thanks, 
   Jim D



TestFrontEnd.py

Josh Blum

unread,
Jul 2, 2016, 10:00:21 PM7/2/16
to davi...@comcast.net, Pothos Users


On 07/02/2016 05:10 PM, davi...@comcast.net wrote:
>
>
> Hi Josh,
>
> I have got the receiving of data from my decoder block in my Python
> application sorted out. I had an error in my block where I was setting up
> the text string to be sent on the output port. That's all working using a
> BinaryFileSource to provide a test signal to some filters and my decoder
> block.
>
> So I am moving on to using the SDRSource block to get real data from my RTL
> SDR. The SDRSource block gets created and set up but when the
> topology.commit() function gets called I get the following error:
>
> *Proxy Exception Message: Framework Topology Connect Error:
> Pothos::Topology::commit(): Framework Topology Connect Error:
> /sdr/source.activate(): Exception: SDRSource::activate(): device not ready*
>
> In the python.exe command window, the message "Found Rafael Micro R820T
> tuner" is printed twice (I also see this message in the PothosGUI window
> when I use the SDRSource block there). If I change the driver name in the
> setupDevice() call, then those messages don't get displayed. This seems to
> indicate that the RTL device is present. The device works fine in the
> PothosGUI and with SDR#.


Hey Jim,

I think I know whats going on. The SDR blocks do something a little
funny. They make the device in the background as to not block anything
if some devices have a really long setup time or experience a timeout.
The condition that the setup has completed is not checked until the
topology is actually forced to run (in this case when commit is called).
If you opened the GUI and clicked activate too fast, the same thing
could happen.

So... The quick fix is to sleep a little before calling commit. Or if
commit throws, sleep a little and try again. Give that a shot!

In related news, I have been revisiting the threading in the SDR blocks
for this and other reasons. So I'm glad that you pointed this out so I
can make this a configurable sort of optimization. I think when
scripting with the SDR blocks they should work exactly the way you
expect by default, which is blocking calls and no background stuff. And
I would like to make sure thats an option among other things.

-josh

davi...@comcast.net

unread,
Jul 3, 2016, 8:16:43 PM7/3/16
to Pothos Users, davi...@comcast.net, jo...@joshknows.com
Hi Josh,

Inserting a 2 second sleep before the call to commit() did the trick.  I hadn't noticed before but when I watched carefully the commit() exception was actually being displayed slightly before "Found R820T tuner" messages (they come up in separate windows so I wasn't correlating the sequence). After including the sleep() I am able to get data flowing out of the SDRSource reliably.

As usual, a little progress has led to another question.  For my R820T device, I need to include a frequency correction of 78 ppm.  In the PothosGUI, I set this by entering {"OFFSET":-78} in the TuneArgs parameter in the Channels tab of the SDRSource block.

How do I set the ppm correction from Python?  I haven't found a setTunerArgs() function (or something like that) that I can call. Without setting the ppm correction, all of my tune frequency settings are off.
 
I did some searching and found GNURadio example that used the OsmosdrSource - that has a set_freq_corr() method to set the ppm correction.

Thanks for the continuing help,
   Jim D 
 

Josh Blum

unread,
Jul 3, 2016, 9:33:48 PM7/3/16
to davi...@comcast.net, Pothos Users


On 07/03/2016 05:16 PM, davi...@comcast.net wrote:
>
>>
>> Hi Josh,
>
>
> Inserting a 2 second sleep before the call to commit() did the trick. I
> hadn't noticed before but when I watched carefully the commit() exception
> was actually being displayed slightly before "Found R820T tuner" messages
> (they come up in separate windows so I wasn't correlating the sequence).
> After including the sleep() I am able to get data flowing out of the
> SDRSource reliably.
>

Glad to hear it.

> As usual, a little progress has led to another question. For my R820T
> device, I need to include a frequency correction of 78 ppm. In the
> PothosGUI, I set this by entering {"OFFSET":-78} in the TuneArgs parameter
> in the Channels tab of the SDRSource block.
>
> How do I set the ppm correction from Python? I haven't found a
> setTunerArgs() function (or something like that) that I can call. Without
> setting the ppm correction, all of my tune frequency settings are off.

We ended up calling it "CORR". So I think you can use {"CORR":-78} in
the tune args. Or you can make the call source.setFrequency0("CORR", 78)
to set just that "CORR" component individually.

Reference:
https://github.com/pothosware/SoapyRTLSDR/blob/master/Settings.cpp#L349

-josh

davi...@comcast.net

unread,
Jul 4, 2016, 7:58:45 PM7/4/16
to Pothos Users, davi...@comcast.net, jo...@joshknows.com
Hi Josh,

The pointer to that Setting.cpp file is helpful - I hadn't found that file previously!  I've added setting the CORR value to my application.

Now that I have the SDRSource running reliably, I've hit a new snag with the FreqXlatingFirFIlter block that I am trying to use as a tune/filter/decimate down converter.  I've had it working in the PothosGUI but can't quite get it to work from a Python application.

To debug this I've created a small Python application (attached) that:
     - Sets up the SDRSource for a 1.008 sample rate and tunes to 162.5 MHz
     - Create a FirFilterDesigner block for a Low Pass, Raised Cosine filter with an upper frequency of 24 kHz and 101 taps.
     - Creates a FreqXlatingFirFilter with a decimation of 42 (output sample rate of 24 kHz) and connects it to the SDRSource output port
     - Connects the tapsChanged signal of the Filter Designer to the set_taps slot of the FreqXlatingFirFilter
     - Connects a FreqDemod block and an AudioSink to the output of the FreqXlatingFirFilter (so that I can hear the FM signal)

Locally we have NOAA weather radio FM broadcast stations at 162.4 and 162.45 MHz (good strong signals).  So I need to tune the FreqXlatingFilter to -100,000 or -50,000 Hz to hear those two signals.

I created this same topology in the PothosGUI (see attached flow diagram) and it works.  The audio sounds a little "gurgly" because the FreqXlatingFilter output sample rate isn't exactly 22.05 kHz but it is completely intelligible.

When I run the Python application, the weather broadcast audio can just barely be heard through the static.  It seems like the FreqXlatingFilter taps are not getting set by the FilterDesigner.  As an experiment, I removed the tapsChanged signal connection in the PothosGUI flow diagram.  This produced the same effect when I ran the flow diagram - the audio was very faint with a lot of static.

Another thing I noticed was that when I changed the FreqXlatingFilter center frequency (in the PothosGUI) from -100,000 to -50,000 while the flow diagram was running the same audio issue would occur (lots of static, very faint signal audio).  When I went into the FIR Designer and changed the number of taps (just deleted and retyped the 101 value in the properties panel), the audio was heard clearly again.

So it seems like something is not quite right with setting the taps for the FreqXlatingFirFilter - any thoughts?

Thanks,
   Jim D
VHF_XlatFilterTest.py
FreqXlatingFilterFlowdiagram.png

Josh Blum

unread,
Jul 4, 2016, 8:59:24 PM7/4/16
to davi...@comcast.net, Pothos Users

>
> I created this same topology in the PothosGUI (see attached flow diagram)
> and it works. The audio sounds a little "gurgly" because the
> FreqXlatingFilter output sample rate isn't exactly 22.05 kHz but it is
> completely intelligible.
>
> When I run the Python application, the weather broadcast audio can just
> barely be heard through the static. It seems like the FreqXlatingFilter
> taps are not getting set by the FilterDesigner. As an experiment, I
> removed the tapsChanged signal connection in the PothosGUI flow diagram.
> This produced the same effect when I ran the flow diagram - the audio was
> very faint with a lot of static.

I'm not sure, but it might be worthwhile to connect the message printer
to the setTaps signal as well. A print of the taps when they are being
applied might be a very helpful debug tool.

>
> Another thing I noticed was that when I changed the FreqXlatingFilter
> center frequency (in the PothosGUI) from -100,000 to -50,000 while the flow
> diagram was running the same audio issue would occur (lots of static, very
> faint signal audio). When I went into the FIR Designer and changed the
> number of taps (just deleted and retyped the 101 value in the properties
> panel), the audio was heard clearly again.

I agree that is odd. Changing the number of taps is forcing a
recalculation and re-application, but the filter should not need that
when the center frequency is changed. I dont remember it misbehaving in
this demo:
https://github.com/pothosware/pothos-demos/wiki/Filter-Design#freq-translating-filter

>
> So it seems like something is not quite right with setting the taps for the
> FreqXlatingFirFilter - any thoughts?

A few things:

After the topology.commit() call, the design should be active and you
have the thread context. The wait is more for unit tests, but you do
need to wait or sleep somehow as to next exit the app. Anyway, you
should move the xlatFirFilterDesBlk.setNumTaps (101) to after the
commit, otherwise it isnt going to trigger another taps to be emitted.

Exporting is becoming a thing. So I just finished a feature so the gui
can export to a JSON topology (without the gui stuff) that can be run
from the command line with PothosUtil --run-topology. And given this, it
should be possible to convert this format to lets a python topology or
C++ -- which could also be compiled/run. Or would stand as an example,
sanity check, or place to copy/paste snippets from. I could see it being
a useful feature here for things like this.

Unrelated to the issue, but you should be able to use the
Pothos.BlockRegistry and Pothos.Topology classes now to neaten the code
a bit like the example.
https://github.com/pothosware/pothos-python/blob/master/Pothos/TestTopology.py
This is in the latest installer now with those other fixes we ran into.

-josh

>
> Thanks,
> Jim D
>

davi...@comcast.net

unread,
Jul 6, 2016, 8:56:56 PM7/6/16
to Pothos Users, davi...@comcast.net, jo...@joshknows.com
Hi Josh,

I did some more experimenting - haven't found a way to make it work yet but I have learned a little more.

1. I hooked up the MessageDebug block to the tapsChanged output of the FilterDesigner.  The taps get printed after the topology.commit() call or when setNumTaps() is called to recalculate the taps.  That seems to be as expected.  (BTW - thanks for the tip on the MessageDebug block. I hadn't noticed it before and I think it will be very helpful to me.)

2. The taps message printout has a sequence of 101 (or whatever I use in setNumTaps) of floating point numbers (a single float per tap, not complex pairs).  This also seems as expected.

3. I cut and pasted the 101 tap values in a "xlatFilterTaps" list in my Python program, commented out creating & connecting the FilterDesigner, and passed the xlatFilterTaps into the FreqXlatingFirFilter block when I created it as follows:

    freqXlatFirFilterBlk = registry.callProxy("/gr/filter/freq_xlating_fir_filter", 
                                              "freq_xlating_fir_filter_ccf", 
                                              xlatDecimation, xlatFilterTaps, 0, frontEndSampleRate)

This didn't make any difference in the audio - I can still hear the FM weather broadcast faintly under the static.

I also tried using [1] as the list of taps when creating the FreqXlatingFirFilter and then calling set_taps(xlatFilterTaps) after the topology.commit() call.  Also no change in the audio.

4.  I added the statement "theTaps = freqXlatFirFilterBlk.taps()" after the set_taps(xlatFilterTaps) call and then printed theTaps.  This returns the 101 tap values that I set.  So it seems like the taps are getting set when I call set_taps() directly.

5.  I added using & connecting the FilterDesigner back into my Python program.  I read back and printed theTaps (like in number 4 above) after calling setNumTaps(101) - the 101 values were printed as expected.


So it looks like the Filter Designer is sending the tapsChanged message to the FreqXlatingFilter block correctly and the Filter block has received & stored the taps.

I'm wondering if I am creating the FreqXlatingFirFilter correctly (number 3 above).  I believe that I should be using the "_ccf" version as I have complex input, complex output, and float taps.  Could it be that I need to do something different to create the filter block? Or is something not getting passed correctly from Python to the GNUradio FreqXlating filter block - maybe its expecting non-float taps?

Thanks again for all the help!

  Jim D

Josh Blum

unread,
Jul 7, 2016, 12:41:31 AM7/7/16
to davi...@comcast.net, Pothos Users

>
>
> So it looks like the Filter Designer is sending the tapsChanged message to
> the FreqXlatingFilter block correctly and the Filter block has received &
> stored the taps.
>
> I'm wondering if I am creating the FreqXlatingFirFilter correctly (number 3
> above). I believe that I should be using the "_ccf" version as I have
> complex input, complex output, and float taps. Could it be that I need to
> do something different to create the filter block? Or is something not
> getting passed correctly from Python to the GNUradio FreqXlating filter
> block - maybe its expecting non-float taps?
>

It looks like in terms of processing the freq_xlating_fir_filter_ccc and
freq_xlating_fir_filter_ccf are identical since they both use complex
taps internally. Its worth trying _ccc since the working code uses it,
but I dont see any difference with the demo when switching to ccf.

It feels a bit like flying blind. Can you try connecting a binary file
sink to some of the outputs like the sdr source or filter output and
plotting the output (like with matplotlib, or even pothos file source ->
plotter) to see if anything looks obviously strange or different?

-josh

davi...@comcast.net

unread,
Jul 7, 2016, 8:52:53 PM7/7/16
to Pothos Users, davi...@comcast.net, jo...@joshknows.com

Josh,

I captured the data out of the SDRSource and played it back into a periodogram (see attached image).  It turns out that NOAA weather broadcast at 162.4 that I am using as a test signal is actually showing up at 162.387 MHz (about 13 kHz off).  So when I tune the FreqXlatingFilter for 162.4, I don't really have the signal in the filter passband - hence the poor quality audio.

When I tune the FreqXlatingFilter with an offset corresponding to 162.387, I hear the weather broadcast just fine.  So this whole problem is a frequency offset issue (and has nothing to do with the FreqXlatingFIlter & filter taps)

When I run using the PothosGUI flow diagram that does the same thing (that was in a message a couple of days ago), the signal is displayed at 162.4 in the periodogram.  Also, if I use SDR# (with the same 78 ppm correction applied) the signal is displayed at 162.4 MHz.

So now I think that I may have some additional parameters that I need to set up for the SDRSource block when I create it in my Python application.  Here is how I am currently configuring the SDRSource block:

    # Create the SDR Source block
    sdrSourceBlk = registry.callProxy("/sdr/source", "complex_float32", [0])
    sdrSourceBlk.setupDevice({"driver":"rtlsdr"})
    sdrSourceBlk.setupStream({})
    sdrSourceBlk.setSampleRate(frontEndSampleRate)     # 1.008e6 Hz
    sdrSourceBlk.setFrequency0("CORR", 78)
    sdrSourceBlk.setFrequency(centerFreqHz)                 # 162.5e6 Hz
    sdrSourceBlk.setGainMode(True)
    sdrSourceBlk.setGain(30.0)                                      # probably don't need this for AGC but it shouldn't matter

As far as I can tell, these settings match the settings I'm using in the PothosGui flow diagram (which doesn't have the frequency offset problem).  Are there any other parameters that I should be setting?


Thanks,
   Jim 
SDRSourceData.png

Josh Blum

unread,
Jul 8, 2016, 12:41:05 PM7/8/16
to davi...@comcast.net, Pothos Users

>
> So now I think that I may have some additional parameters that I need to
> set up for the SDRSource block when I create it in my Python application.
> Here is how I am currently configuring the SDRSource block:
>
> # Create the SDR Source block
> sdrSourceBlk = registry.callProxy("/sdr/source", "complex_float32", [0])
> sdrSourceBlk.setupDevice({"driver":"rtlsdr"})
> sdrSourceBlk.setupStream({})
> sdrSourceBlk.setSampleRate(frontEndSampleRate) # 1.008e6 Hz
> sdrSourceBlk.setFrequency0("CORR", 78)
> sdrSourceBlk.setFrequency(centerFreqHz) # 162.5e6 Hz

Hey Jim,

Can you try swapping these two tune calls. I'm concerned that
setFrequency() overwrites the correction because its meant to perform an
overall tuning of all elements in the chain. This is most useful when
the tune algorithm sets a cordic to compensate for any frequency error
in tuning the LO. But it looks like it caused some confusion here.

* So this would work because setFrequency0 with "CORR" will overwrite
anything set by the first call to setFrequency().

sdrSourceBlk.setFrequency(centerFreqHz)
sdrSourceBlk.setFrequency0("CORR", 78)

* Or this would work as well in any order, because it sets both
components individually:

sdrSourceBlk.setFrequency0("RF", centerFreqHz)
sdrSourceBlk.setFrequency0("CORR", 78)


* And this should do it in one call. The default tuning algorithm will
apply the specified value rather than try to tune it to something:

sdrSourceBlk.setFrequency(centerFreqHz, {"CORR", 78})

Anyway, I think thats the problem, so I hope this code snippet makes the
difference. I think we need to think harder about overloading the
setFrequency() is SoapyRTLSDR as to not touch the correction value like
this since its not in Hz anyway.

-josh

davi...@comcast.net

unread,
Jul 8, 2016, 8:13:37 PM7/8/16
to Pothos Users, davi...@comcast.net, jo...@joshknows.com
Hi Josh,

Just for fun, I tried all three of your suggestions.

Case 1.  Swapping the order of the calls to:

    sdrSourceBlk.setFrequency(centerFreqHz)
    sdrSourceBlk.setFrequency0("CORR", 78)

    Worked and I got good audio at the expected frequency!! 

Case 2:  Using setFrequency0() for both calls:
 
   sdrSourceBlk.setFrequency0("RF", centerFreqHz)
   sdrSourceBlk.setFrequency0("CORR", 78)
    
       Also worked and provided good audio!! 
 
Case 3.  Setting both frequency & correction in one call 
    sdrSourceBlk.setFrequency(centerFreqHz, {"CORR", 78})

  This one threw an exception:
 
    2016-07-08 19:27:34 SDRBlock: call setFrequency threw: Framework Block Call Not Found: Pothos::Block::call(setFrequency): method match failed


I think I am going to use option 2 - one of the things my application is eventually going to do is step through a list of frequencies looking for signal activity.  So using the setFrequency0() method I can set the correction once at the beginning of the program and then just tune to the various center frequencies as needed.

I think that the way of setting the correction value is a little odd.  It would seem to be more similar to the other SDRSource parameters (and other blocks) to have a "setCorrection()" and a "getCorrection()" method.  

So now I am truly dangerous :)  - I have all the individual snippets (SDR tuning, FreqXlating down conversion, audio, my decoder block, and a way to receive data from my block) to put my whole signal chain together in a Python program.  Then I can start working on the Qt GUI to control it and display the data.

Thanks again for your help with my questions.  I am really having a lot of fun with the Pothosware - it's a nice package with a lot of capabilities. Having migrated from being a software engineer (in the '80s & '90s) to now working as a systems integration & test engineer, the availability of the USB SDR devices has given me a reason to get back into writing code again (at least in the evenings & on weekends!).

Jim D
 

Josh Blum

unread,
Jul 9, 2016, 1:46:01 AM7/9/16
to davi...@comcast.net, Pothos Users

> Case 3. Setting both frequency & correction in one call
>
>> sdrSourceBlk.setFrequency(centerFreqHz, {"CORR", 78})
>>
>> This one threw an exception:
>
>
>> 2016-07-08 19:27:34 SDRBlock: call setFrequency threw: Framework Block
>> Call Not Found: Pothos::Block::call(setFrequency): method match failed
>>

Oops. It was supposed to be a python dictionary {"CORR": 78}. Apparently
its a set in python without curly braces and no colons.

>
>
> I think I am going to use option 2 - one of the things my application is
> eventually going to do is step through a list of frequencies looking for
> signal activity. So using the setFrequency0() method I can set the
> correction once at the beginning of the program and then just tune to the
> various center frequencies as needed.
>
> I think that the way of setting the correction value is a little odd. It
> would seem to be more similar to the other SDRSource parameters (and other
> blocks) to have a "setCorrection()" and a "getCorrection()" method.

I do agree that its a little odd. It got thrown in with the tuning API
and its good that there is a way, but its awkward. I want to see how
some other devices expose their fine freq tuning, because this could
motivate a generic addition in the front-end corrections API.

>
> So now I am truly dangerous :) - I have all the individual snippets (SDR
> tuning, FreqXlating down conversion, audio, my decoder block, and a way to
> receive data from my block) to put my whole signal chain together in a
> Python program. Then I can start working on the Qt GUI to control it and
> display the data.
>

Hope to see it when its ready :-)

> Thanks again for your help with my questions. I am really having a lot of
> fun with the Pothosware - it's a nice package with a lot of capabilities.
> Having migrated from being a software engineer (in the '80s & '90s) to now
> working as a systems integration & test engineer, the availability of the
> USB SDR devices has given me a reason to get back into writing code again
> (at least in the evenings & on weekends!).

Sounds great!
-josh
Reply all
Reply to author
Forward
0 new messages