Monday, April 09, 2012

Adventures in Platform Independence

So I have this nice program developed that will allow us to transmit compressed communications audio over an Internet link.  It will be part of a remote Internet receiver that will support W1HQ, the club station at ARRL, Newington, CT.

The program came together fairly easily, using old-fashioned Linux / C programming, together with the Speex and Portaudio libraries.  The sending program runs on an ARM-based Beagleboard card, and the receiving side should run on any Linux box running Ubuntu or your favorite Linux distro.

Along with the audio software, there is an independent rig control function using Python, wxWidgets, and Hamlib.  That should run nicely on Linux, Windows, or what-have-you.

Since our W1HQ crew really needs to keep their Windows station computer, we do need to make the audio receive software run under Windows, along with rig control.  That's where today's lesson begins.

Porting to Windows!

The problem of porting Linux C code to Windows is the subject of a lot of Internet discussion.  It needs to be done frequently, but the process is not simple.  For one thing, the programming tools are rather different.  While the basic principles are the same, all the details are different.  In Windows you generally code within a complex IDE system (Interactive Development Environment).  Managing libraries, dealing with the graphic user interface, and even finding useful "help" files are all a challenge. But the killer, for me, is the unavoidable fact that the underlying operating system just does things differently from Linux.  This shows up in many ways, but my problem specifically was dealing with Internet communications (sockets).

I looked at 3 approaches, before finding a solution that might work for us:
  1. Visual C++ and Visual Studio.  This is Microsoft's preferred development system, using the big IDE model.  Fortunately, there is a free "express" version that might work for us.  I could get the Portaudio and Speex libraries to compile, but the socket programming model seems to require serious recoding work.  It would be possible, but it's almost like starting from scratch.  Furthermore, we'd end up with  Windows source code and Linux source code that would have to be maintained in parallel.
  2. CygwinCygwin is software that runs under Windows and provides a Linux command line interface.  Compiling with gcc works in Linux style, so that's good.  However, there is no support for Linux sockets model, so it's no help in the end.
  3. MinGWMinGW does not provide a full Linux run environment, but it has a number of features that help you compile Linux code to run under Windows.  Compiling the libraries is no problem, but still there is no sockets compatibility.
Not Porting to Windows!

The only solution I've found that won't require investing time in Windows C programming, is to virtualize the problem.  That is, set up a virtual Linux PC inside our Windows box using the free Oracle VirtualBox.  A good modern PC should have enough horsepower for this.  (We'll see about the W1HQ machine!)  Once this is set up, you can run all the code the way it was meant to be run.  The price to be paid is 4-8 GB of disk space and 300-500 MB of RAM.  Since our needs on the Linux side are very modest, we may be able to pare down the memory requirements substantially.

VirtualBox runs the audio software fine under Windows 7 on my home machine.

Update 9/8/2012:  VirtualBox works nicely, but it has a large footprint on any average size computer, so it's probably too much to run at W1HQ without an upgrade.  RAM upgrades are cheap, but it's probably worth another look at Windows coding.  I've simplified the audio transport to use UDP, so there's probably less OS dependency.  We'll see.