Monday, 24 July 2017

Using FreeDV and SDR with ALSA Loopback

Introduction

FreeDV is a low bit-rate digital voice mode started by VK5DGR.  This software combines speech coding, error correction and modulation to digitally encode speech, generating a low bandwidth analog signal that is usually connected to a conventional amateur-radio transceiver.  How about using FreeDV with a SDR approach such as GNURadio plus a USRP (or similar device) - how should FreeDV be connected in this case?

Interfacing Options

One approach would use the FreeDV packages on the command line and simply pipe signals between software modules.  This can work very well (eg this example) but has the disadvantage that graphics and related GUI controls might be lost.

FreeDV running in a PC normally used 2 sound cards  - one for the mic/headphone connections and another for the low-bandwidth modulated signals.  GNURadio of course offers audio interfaces.  So we could imagine a PC with 3 sound cards, with the low-IF modulated signal from FreeDV output from SC#2 and then looped back into SC#3 as the GNURadio source. Apart from the extra hardware, that is not a good idea as the additional A/D and D/A operations would probably cause significant degradation.  But we can do the equivalent loopback operations within the PC using digital streams, as shown below.



Sample Implementation using ALSA Loopback

I thought it would be easy to setup the above on my Ubuntu 16.04, but it took a little longer than expected.  This approach uses the ALSA loopback device which is created by "sudo modprobe snd_aloop". You can see information about sound interfaces by using "aplay -L" or "arecord -L". This loopback contains multiple streams and to achieve the signal flow shown above, the loopbacks can be given names associated with specific card, device and subdevice numbers.  These names can then be used in FreeDV or GNURadio. (This page gives useful example information regarding ALSA device architecture.)

The loopback streams can be defined in the .asoundrc file.    I used the following:

# ALSA config in .asoundrc for freedv <> gnuradio audio streams
# We assume that the "Loopback" card exist and that for each
# subdevice, a signal input on device 1, comes out on device 2
# The mic and headphone interfaces are not included in this 
# file description - it should be possible to use standard names. 

# LB out #0 - to route freedv mod output to gnuradio input 
pcm.LB00 {
   type plug
   slave.pcm "hw:Loopback,0,0"
   }
# LB in #0
pcm.LB10 {
   type plug
   slave.pcm "hw:Loopback,1,0"
   }

# LB out #1 - to route gnuradio output to freedv mod input 
pcm.LB11 {
   type plug
   slave.pcm "hw:Loopback,1,1"
   }
pcm.LB01 {
   type plug
   slave.pcm "hw:Loopback,0,1"
   }

Let's assume you have FreeDV version 1.2 installed and running.  Use the "Audio Config" tool to setup connections shown in the figure below.   So select the LB01 device "from radio" under the Receive tab, and the LB10 device "to radio" under the Transmit tab.  Likewise the appropriate audio devices can be named in the grc setup.



This GNURadio diagram below shows a very simple audio loopback, with a variable amount of added noise. Notice that the audio source is setup with device name LB00 and the audio sink from GNURadio has device name LB11. During this simple test, with both FreeDV and GNURadio running,  the SNR can be varied and the effect observed in real-time on audio quality, sync etc

Of course for a real application the grc flow-graph below would be replaced by SSB transceiver processing, since that simply translates and interpolates the audio signal to a sampled signal suitable for the SDR interface.  I have a B200 USRP which I have used with GNURadio for initial SSB tests on 70 cm.  The next step will be to try my previous grc software with FreeDV.  (BTW GNURadio also includes a Codec2 module!)

Please Note
For reliable operation I had to stop PulseAudio while running the FreeDV/GNURadio test described above. Possibly there is a way of avoiding this.  Also note that "pulseaudio --kill" will respawn unless you adjust the default setting, e.g. with a .conf file that includes "autospawn=no".   It is probable that PulseAudio modules can be used instead of snd_aloop - I haven't explored that path.