DIY remote kit for the IC-706 part 8: Improved audio client and server

In my last update I have posted a live demo of the IC-706 remote setup. This setup was using a gstreamer-based audio client and server, taking advantage of state of the art audio codec called Opus. This setup was working fine over reliable network connections; however, as soon as I got on a mobile network the simple gstreamer pipelines were no longer sufficient. So it was time to write a simple audio client and server pair that are better suited to handle network dropouts.

You may recall from earlier that I have decided to use a TCP connection between the client and the server. This is necessary if the client is behind a firewall. In a TCP connection the client opens a connection to the server and thus it doesn’t matter if the client is not visible from the outside. On the downside, TCP guarantees that packets are delivered and that they are delivered in the right order, which eventually leads to increasing latency when there are glitches in the connection.

There are virtually no limits for how long this latency can become. On a bad mobile connection it can quickly go up to 5-10 seconds which is clearly unusable for a real-time setup such as this one. One way to eliminate long latencies and keep certain level of robustness is to use asynchronous playback at the client side but limit the length of the playback buffer.

The length of the playback buffer is effectively the longest latency we will experience. But we don’t want to make it too short either because that will reduce the robustness of the playback when glitches occur. Right now I am testing with 480 ms buffer length and 200 ms playback threshold (i.e. required buffer fill to start playback). These numbers can be reduced for a robust connection /e.g. LAN) or even increased for very poor connections.

The frame length of the Opus encoder is set to 40 ms. This can go from 2.5 to 60 ms and so far 40 ms has given good results. I may try to reduce it later but as explained above, this is not the primary source for latency. In my experience a few hundred milliseconds of latency while driving is not a big deal. You wont sit and go crazy with the tuning dial anyway, would you? I found it much more convenient to use the channel button and tune in 1 kHz increments while looking for SSB stations. For CW a finer resolution can be necessary.

The audio server and client code is available in the Github repository of the project. They are separate applications running independently from the IC-706 control server and client. You can run them on pretty much anything with an audio interface that runs linux, or something else with a C compiler, portaudio and opus codec installed.

For now the audio interfacing is done using the Portaudio library. I may change that later because portaudio seems to have issues with async playback in certain configurations. But it’s a good choice for now that even makes the code portable to other operating systems.

On the photo below you can see the IC-706 and the server installed in the shack:

IC-706 remote server

And here is the test setup in my car (not a permanent solution ;-):

IC-706 remote client

You may notice the two switches on the box. They are physical switches to start and stop the audio and the control clients. This helps me perform a clean disconnect before removing power. Otherwise if the client just dies, the connection remains open indefinitely at the server end and the client may not be able to reconnect before I restart the server (right now the server is limited to a single connection at a time). Checking the switches and launching the clients are handled by a simple shell script loaded after boot.

Finally, here is the external 3G / 4G antenna I use for improved connection while driving:

Mobile antenna

The server has been running for more than two weeks now:

IC-706 remote server status

I have been driving around with the client for several days and I can tell you that this is a really cool way to get access to shortwaves while driving. I can’t wait to add TX support and to do the same with SDRs.