Skip to main content

Cocoa Radio Alpha testing

I've been working on a stand-alone software defined radio (SDR) application for Mac OS on-and-off for a few months, and I think it's good enough now to encourage people to test it and provide feedback. Though it's possible, of course, to do everything my app does in GNU Radio, it's much more convenient to have a dedicated app. Especially because this app uses a lot less CPU thanGNU Radio.

This video shows the basic operation of the user interface:

And this one shows an 'inside peek' at what happens to the signal inside of the application. In normal usage, the waterfall display won't do this, but it's an interesting effect:

There are still many, many bugs, but it should be enough to play around with.I've been able to listen to broadcast FM radio for some time using the app.There is no squelch control, that's on the list of things to add. Also, it's possible to get audio buffer under runs. It's likely caused by slight differences in the clock rate of the rtl-sdr dongle and the audio device that you're using.

If you notice any bugs, or have specific issues that you would like addressed, please create an issue on the github page. Also, if you are able to contribute, please let me know. I'm obviously in need of some GUI assistance!

One word of advice, don't try to change the modulation type using the drop-down menu, it doesn't work! :)

Again, code is available at github, as is an application binary.

Compiling GnuRadio 3.3.0 on Mountain Lion

Fixing all the little issues with this process took me days, so I apologize if it's a complicated and multi-step process. These steps worked for me, hopefully they work for you too, but YMMV.

First of all, it is vital that you don't have the macports boost 1.50installed. There is a problem with that version where the x86_64 version of the library isn't compiled. This is mentioned in an earlier post, and the mac ports trac entry ishere.

The easiest way to begin is to install boost 1.49 then run "sudo port install gnuradio-core" and let macports install all of the pre-requisite packages (you may need to perform the fix I mentioned in that earlier post to fix netpbm) .When it finally gets to gnuradio-core, it will fail. Now, what you need to do is:

$sudo port edit gnuradio-core

Follow the instructions, again in that earlier post (update 2).

$sudo port clean gnuradio-core
$sudo port -n install gnuradio-core
--> Computing dependencies for gnuradio-core
--> Fetching archive for gnuradio-core
--> Attempting to fetch gnuradio-core-3.3.0_0+python26.darwin_12.x86_64.tbz2 from http://packages.macports.org/gnuradio-core
--> Fetching distfiles for gnuradio-core
--> Verifying checksum(s) for gnuradio-core
--> Extracting gnuradio-core
--> Applying patches to gnuradio-core
--> Configuring gnuradio-core

THIS IS IMPORTANT!: Cancel (control-c) when it says "Configuring gnuradio-core." At this point, we need to hand-edit the configure script in the gnuradio source directory. The reason for this is because some of the assembler code in gnuradio uses 32-bit only opcodes. When compiling for 64-bitmachines they generate errors. It's necessary for them to be compiled differently. Luckily, when Lion was released, a fix was devised and added to macports. The same exact fix (in principle) should work for Mountain Lion.But, in the configure script, the change looks for Lion and doesn't detectMountain Lion. We just need to change the test to detect Mountain Lion. The difference is only the version of darwin used. This information is in this trac.

$cd /opt/local/var/macports/build/
$ls    <cd to the long directory that ends with science_gnuradio-core>
$cd gnuradio-core/work/gnuradio-3.3.0
$sudo vi configure

Once editing the configure script, search for darwin*10* or darwin*11*. This is easy if you hit the forward slash and type darwin\\*1

The region of interest should look like this (the numbers are the linenumbers):

20154     *darwin*11*)
20155 # The cast to long int works around a bug in the HP C Compiler
20156 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
20157 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
20158 # This bug is HP SR number 8606223364.

Change the *darwin*11* (or *darwin*10* ) to: *darwin*12*

Close the vi session by hitting <esc> then : then type wq and <enter>.

Now, run "sudo port -n install gnuradio-core". Make sure that you DO NOT clean the package. This will destroy our edited configure script.

When that finishes (hopefully it does!) you should be all set! You'll probably want to install gnuradio-companion as well as gnuradio-audio-osx.

If you have any problems or questions, let me know in the comments.

Using softshell with GNURadio

It has been a little while since I released the very early code for Softshell (not that the code has advanced much), and I've received a few requests for a bit more information about how it's intended to be used.

I admit that I hacked it together very quickly so that I could make some basic use of the rtl-sdr dongles on my mac. To be very clear, Softshell does no actual SDR itself. You can really look at it more like a driver for the rtl-sdr. Softshell opens a connection to the rtl device, allows you to tune its internal oscillator, and puts the data on the network.

To start, install the rtl device in your USB port, then open Softshell.

Freshly opened

If you see a similar window, it means that Softshell has found your device(the ezcap in this case). It is, perhaps, a good time to mention that I've only ported the tuner code for the Elonics E4000 tuner. Click the "Open"button to have the program open the connection to the device. If it detects that you have the E4000 the "Tuner type" field will be filled in with "Elonics E4000."

Once this is done, changes to the sample rate and center frequency will take effect with the "Update" button is clicked. The Center frequency is provided in Hz.

Now, that's all fine and good, but you're just tuning the device. To actually get the data out of it, you need to setup the network settings. Choose a port number for Softshell to listen to, I use "12345," and click the "Running"checkbox.

Finally, in GnuRadio, you need to use a "TCP Source" block setup as a client with the same port number you used before.

Setting up GnuRadio to work with Softshell

Once that's done you should be up & running. Note that, natively, the rtl device actually outputs unsigned bytes and that Softshell converts these to floats centered around zero. Some GnuRadio examples include the blocks that perform this conversion. If you come across this, just remove those blocks.

Good luck! Please feel free to comment with any questions or issues!

Macports compilation problems with CLANG (netpbm)

I've been struggling with this for a few days, so hopefully this post saves some people from headaches.

Some packages in macports fail to compile using CLANG. The reasons are varied, but inline assembler is a common reason. The trick to getting them to work is using a different compiler. LLVM-GCC seems to be a good choice.

The macports guide for choosing compilers isn't as clear as I would like.After some googling, I learned that you can edit the port file using macports.

sudo port edit netpbm

This command opens the port file for that package in vi (or maybe your default editor, if different) and lets you make changes. The compiler is set by theTCL variable ${configure.compiler} which is set thusly:

configure.compiler llvm-gcc-4.2

Once this changes is made, clean and re-attempt the port:

sudo port clean netpbm
sudo port install netpbm

And it should work. It did for me. At least, you can use these series of steps to try different compilers out to see which one works.

Update:

To compile the gnuradio-gruel library, it may be necessary to downgrade to boost version 1.49 if you have version 1.50 installed. For some reason, the x86-64 version of the libraries aren't build with the new version of boost. Here is the trac entry.

Update 2:

While compiling the gnuradio-core package, a failure occurs. The log entry is, unfortunately, not helpful:

:info:build make[6]: Leaving directory `/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_science_gnuradio-core/gnuradio-core/work/gnuradio-3.3.0/gnuradio-core/src/lib/filter'
:info:build make[5]: *** [all] Error 2

However, if you navigate to that folder and run make (as sudo, because the files are owned by macports) you get a more helpful result:

libtool: 
compile: /usr/bin/clang -DHAVE_CONFIG_H -I. -I../../../.. -I/opt/local/include -I/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_science_gnuradio-core/gnuradio-core/work/gnuradio-3.3.0/gnuradio-core/src/lib/runtime -I/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_science_gnuradio-core/gnuradio-core/work/gnuradio-3.3.0/gnuradio-core/src/lib/general -I/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_science_gnuradio-core/gnuradio-core/work/gnuradio-3.3.0/gnuradio-core/src/lib/general -I/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_science_gnuradio-core/gnuradio-core/work/gnuradio-3.3.0/gnuradio-core/src/lib/gengen -I/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_science_gnuradio-core/gnuradio-core/work/gnuradio-3.3.0/gnuradio-core/src/lib/gengen -I/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_science_gnuradio-core/gnuradio-core/work/gnuradio-3.3.0/gnuradio-core/src/lib/filter -I/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_science_gnuradio-core/gnuradio-core/work/gnuradio-3.3.0/gnuradio-core/src/lib/filter -I/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_science_gnuradio-core/gnuradio-core/work/gnuradio-3.3.0/gnuradio-core/src/lib/missing -I/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_science_gnuradio-core/gnuradio-core/work/gnuradio-3.3.0/gnuradio-core/src/lib/reed-solomon -I/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_science_gnuradio-core/gnuradio-core/work/gnuradio-3.3.0/gnuradio-core/src/lib/viterbi -I/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_science_gnuradio-core/gnuradio-core/work/gnuradio-3.3.0/gnuradio-core/src/lib/io -I/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_science_gnuradio-core/gnuradio-core/work/gnuradio-3.3.0/gnuradio-core/src/lib/g72x -I/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_science_gnuradio-core/gnuradio-core/work/gnuradio-3.3.0/gnuradio-core/src/lib/swig -I/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_science_gnuradio-core/gnuradio-core/work/gnuradio-3.3.0/gnuradio-core/src/lib/hier -I/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_science_gnuradio-core/gnuradio-core/work/gnuradio-3.3.0/gnuradio-core/src/lib/swig -I/opt/local/include -I/opt/local/include -I/opt/local/include -I/opt/local/include -I/opt/local/include -pipe -O2 -arch x86_64 -MT float_dotprod_sse.lo -MD -MP -MF .deps/float_dotprod_sse.Tpo -c float_dotprod_sse.S -fno-common -DPIC -o .libs/float_dotprod_sse.o    
float_dotprod_sse.S:57:2: 
error: unknown directive     .version "01.01″
     ^    make[1]: *** [float_dotprod_sse.lo] 
Error 1   
make: *** [all] Error 2

It's about here that you realize that you're dealing with assembler. Ick.Apparently, the .version directive isn't supported. I tried commenting the mout, but when gnuradio is finally built, I get SEGFAULTs from the filter methods. I don't think it's a coincidence that we're in the filter directory and this is the dot product source file.

Here, again, I tried the compiler 'trick'. No dice. This time, however, the error changed:

float_dotprod_sse.S:63:suffix or operands invalid for `push'
float_dotprod_sse.S:163:suffix or operands invalid for `pop'

A quick google later, and it turns out that when you compile assembly code designed for a 32 bit machine on 64 bit, the assembler doesn't know what to do with some of the instructions. The solution is to add -m32 to the compile command line.

Unfortunately, all this code is compiled with -arch x86_64 (the opposite of the -m32 flag!). If I removed -arch x86_64 and added -m32 it worked. Now what to do Unfortunately, I'm stuck for now… ideas?

Riding mower repair

"Well, there's your problem!"

This is waaay out of left field for this blog, but I've spent the last week or so working on this project, so I figure I should describe it.

In the list few weeks, my engine in my ride-on power has been burning tons of oil. It would smoke a bit all the time, but after a while, it would bog down and unleash a massive cloud of blue smoke. I read some forums and things online to try to get an idea of what was happening. Many people said that it was caused by the crank case breather. I figured this would be an easy thing to try. When I went to the small engine store (Willamette Saw) they said that it was almost guaranteed to be the head gasket. Bummer. I came back the next day with the engine model number, and got a new gasket.

You can see the tons of oil swirling around in the air filter housing. What I think was happening is that the head gasket leak was pressuring the crankcase, which was causing the blower to expel lots of air and oil into the housing. When it overflowed, it would pour into the intake causing the huge smoke cloud.

It doesn't get much clearer than that!

Once I got all the covers and stuff off of the engine, the cylinder head came off very easily. It's painfully obvious that this was a blown head gasket, and that the combustion gasses were leaking into the crank case. It's bizarre how thin the gasket is in this location, and that it's really far away from any bolts.

Visible oil in the cylinder.

In addition to the obvious gasket leak, there was a ton of oil in the cylinder. There had to have been at least a table spoon of oil just sitting there in the cylinder. I mopped most of it up before taking the picture, unfortunately. Changing the gasket was really easy. It's important that you clean off all the old gasket and make sure that the mating surfaces are clean and smooth.

AAAAAARRRRRRGGGGGGHHHHHHH!!!!!

I know that it's fairly important to correctly torque the bolts when installing the cylinder head, and I attempted to find information online about the proper torque value. I read somewhere that it was supposed to be set to 55ft./lbs. It's not. Don't do it. That is a TON of torque. In attempting to install the bolts I realized this, and kept backing it off. However, one of the bolts broke anyway.

Hellooo down there!

I friend of mine insisted that I try to remove the bolt (yes, I was going to leave it), and lent me his ez-outs. It can be very difficult to drill into a hardened bolt, especially deep in a hole without destroying the threads. I saw a cool technique somewhere on the internet for drilling down the center of a bolt, so I used the opportunity to try it.

Center drilling a bolt

The trick to drilling down the center of a bolt is using a drill-press and a well-secured vise. Chuck the bit into the drill chuck, but upside-down, then lower it into the vise. It's easiest if you have an x-y stage type of vise.With the bit in the jaws of the vise, secure it. Now, chuck the bolt into the drill press and drill the hole. It's a kinda fun process. I did my best to keep the bit clean and lubricated.

Successfully center-drilled bolt

It should work great, it did for me. I also used a counter sinking bit to de-burr both sides of the bolt. Also, before starting this whole process, I ground off all the markings on the top of the bolt so the drill bit didn't wander around the surface.

Drill bit through the bolt spacer

Spacer installed into the bolt hole

As expected, the spacer fit the bolt hole perfectly, and the bit fit perfectly as well. I was ready to go! What could go wrong?

D'oh!

Well, crap. I hadn't anticipated that. There was no way I was going to get the drill chuck into that space. This sucks. I was hoping that I could get the bolt out without taking the head back off the block. But it became clear that there was no other way to do it.

Well, that's a bit easier to get.

With the head off, getting the bolt was trivial. That's nice. However, I had to buy another head gasket, so that was a bummer. Once the bolt was replaced,I was able to find the proper torque (220 in/lbs.) which is about 18 ft./lbs. This turned out to be just about perfect. The engine has some serious compression now! I also had to adjust the valve rocker clearance. Now the mower's running like a champ!

2012 Solar eclipse

2012 Solar Eclipse

During this solar eclipse, I was lucky to be near the path of the full eclipse. I'm just north of the ideal path. Anyway, it was cloudy here in Oregon, so my pictures aren't great. I hope you enjoy them.

Softshell pre-alpha

Softshell works!

Basic functionality of Softshell works! In the image above, you can see the app (Cocoa-rtl-sdr is the old name) on the right. I didn't even have the text boxes wired in yet for the sample rate and center frequency, because I was so excited that it was working. The samples from the receiver are transported into GNU radio over TCP where a simple FFT is being performed. Notice that all the extra blocks needed for the original rtl-sdr aren't needed, because I'm doing all of the uchar to float conversion inside of Softshell.

The code that's available on GitHub was hacked together with some network code that I can't release right now, but I'm going to move it over to code that I can use soon.

Update:

Here's a pre-compiled application for those that don't feel like compiling it:

Softshell-alpha

Weird return value discrepancies between Softshell and RTL-SDR

I've made significant progress porting over the rtl-sdr code. I added printfs to every function that interfaces with the USB port so that I can compare what happens. Everything seems normal, up until the gainControl function. Once there, the returns from my application are usually about one digit off of the rtl-sdr code. If anyone has any ideas, I'd love to hear them!

Link to the comparison spreadsheet.

Softshell, the MacOS RTL-SDR driver

For the uninitiated, a few months ago one of the developers in the V4L (video for linux)/DVB (digital video broadcasting) team, AnttiPalosaari, discovered that this cheap video tuner dongle could be used as a software defined radio. Since then, it has developed a HUGE following! The team over at osmocom helped to package the driver into a separate executable. The application seems to work well, and even compiles on the mac. The problem is, though, that you have to install the libusb library for it to work. It's not hard to do, but you have to install mac ports, then install libusb. What a pain.

Most of the active discussion about rtl-sdr appears to be happening at the RTLSDR subreddit.

RTL SDR compatible dongle

The idea behind Softshell is to port the osmocom rtl-sdr code into a nativeCocoa application that doesn't need libusb. I've published the code to github, but it's still very early in the development process.

This post is just meant as a heads-up for anyone with Objective-C experience and an interest.