Embedded FreeDV for Raspberry Pi

FreeDV is a program that implements a number of digital modes that may be used on the amateur bands.

You can read about it here https://freedv.org/

It’s based on a very elegant codec called codec2 http://www.rowetel.com/wordpress/?page_id=452 and Wikipedia has a good overview here https://en.wikipedia.org/wiki/Codec_2

FreeDV runs on a PC which works well if you have for example a USB connected rig or two sound cards. ALternatively you can buy a box that implements codec2 called the SM1000

Or you can build your own.

This has been the subject of a club project. The design was created by KK5JY and given the name ‘smalldv’ Information on it is here: http://www.kk5jy.net/smalldv-v1/


There are two parts to this project. The first is the hardware, the second the software. KK5JY’s page covers both but to make it easier to assemble, here are more detailed instructions on both. Dave G0BCU worked on the hardware, Dave G8KBB on the software.

The hardware

So first the hardware.

It’s based on 3 components:

  • A Raspberry PI (preferebly a Pi 4)
  • A cheap USB sound adapter
  • A daughter board for the PI

This is how the components are connected.

The interface board schematic is as follows. The main part of the circuit is the audio switching. In order to avoid the need for two sound cards, a relay is used to switch transmit and receive audio. This is driven from the PTT output.

The PTT input is a debounced button.

These plus the status lights are implemented on a small PCB as shown.

If you intend to build the board, here is a helpful aid.

Download this file and print it out. It contains scale layouts that can be placed over a piece of veroboard to assist assembly, together with the complete component list.


Please note that the software may change. We are looking at implementing a switch interface to select the mode (rather than a tablet or computer). Also trying to get newer modes to work. Watch this space….

.. and no, 2020 runs on the PI4 but not properly (yet).

To install and run the software you need to do this. The basic outline is on the smallDV page but these are some extra notes.

First please note that the details that follow assume that you have the full desktop version of Raspbian installed. It is also recommended that following a fresh install you update it by executing ‘sudo apt update’ and ‘sudo apt upgrade’ then ‘sudo apt-get update’ and ‘sudo apt-get upgrade’ for good measure.

If you do not have the full version with the graphical interface, then don’t bother installing freedv, don’t install Spyder and use nano as the editor. Also don’t forget you can still have the graphical interface on another computer – from the Pi command line execute “vncserver” then use vncviewer from the other computer.

Also, if you are not using the full version there will be a few bits missing – such as git. To install that (for example) execute sudo apt-get install git’

  1. install (or update) using “sudo apt-get install” the packages:
    1. build-essential
    2. build-essential cmake
    3. libsndfile1
    4. libsndfile1-dev
    5. libasound2-dev
  2. get a copy of RtAudio and unpack into a folder called ‘rtaudio’ in your home directory (~/rtaudio). To get it, follow the link from the smalldv webpage which takes you here: https://www.music.mcgill.ca/~gary/rtaudio/.
    Scroll down until you get to the latest release download and download it (at the time of writing that was version 5.1.0) . Don’t use git to get the files, you get the wrong set!
  3. build RtAudio by following the instructions in the file ‘install.txt’. For version 5.1.0 this involves executing ‘./configure’ followed by ‘make’ from within the rtaudio folder.
  4. execute ‘sudo make install’ to install rtaudio
  5. get, make and install freedv by executing ‘sudo apt-get install freedv’. (This is really only needed if you want freedv as well as smalldv but I suggest doing it).
  6. Get a copy of codec2 and unzip it to a folder in your home directory called codec2. Either follow the link from the smalldv website, that takes you here ( https://github.com/drowe67/codec2 ) or simply change directory to home ‘cd ~’ and execute ‘git clone https://github.com/drowe67/codec2.git’
  7. The file ‘Install’ gives build details. For latest version this was:
    1. cd ~/codec2
    2. mkdir build_linux
    3. cd build_linux
    4. cmake ../
    5. make
    6. sudo make install
  8. install the python 2.7 version of Spyder (the python IDE) via “Add/Remove Software” . The reason for this is that smalldv is built using python2 and if you need to debug anything it’s rather useful 🙂 . To do this, open Add/remove software (it’s under ‘Preferencies’ from the desktop). Then select “programming” and wait whilst it updates. Enter Spyder in the search box and hit return. Click on “Python IDE for scientists (Python 2)” to select it (make sure Python 2 not 3) then click “OK”. You will be prompted for the account password. Enter it and click OK.
  9. get the smalldv package and unpack into a folder called ‘smalldv’ in your home folder (~/smalldv). Follow this link to get it. http://www.kk5jy.net/smalldv-v1/Software/ . Scroll down to the bottom of the page and make sure you get the latest version.
  10. cd ~/smalldv
  11. make smalldv by executing ‘make’. If you get an error telling you that FREEDV_MODE_700 and FREEDV_MODE_700B are not declared on lines 107 and 109 of fdvcore.cc, comment out lines 107,108,109,110 in fdvcore.cc and try again (or if you are going to upgrade to 2020 mode as shown below, you might as well make the changes indicated below at this time instead)
  12. install smalldv with ‘sudo make install’
  13. execute the command ‘fdvcore -l’
  14. you may get an error on no default device – this is probably because you have no default audio input or output device set (right click on the audio icon on the right of the toolbar at the top of the screen) and click on your input sound device to set it as default.
  15. from the response note the name of your audio adapter (probably sometling like “USB PnP Sound Device” or “USB Audio Device” ignore “hw:” and any number after the comma and the comma itself.
  16. right click on smalldv and open it with Spyder. Locate the entry for the PCMdevice and set it to that name. Save the file.
  17. execute smalldv. Note that because this is a Python 2 program do this by executing from the command line “python2.7 smalldv”.
  18. If you get an error message saying that __main__ could not be found, you are not in the smalldv folder !
  19. You should get a message telling you “DEBUG: Moving to background…”
  20. It should now be running (look at the LEDs on the interface board).
  21. To talk to the program, install Telnet (sudo apt-get install telnet) then execute “telnet 5445”. You can now give it commands as per the smalldv page. Note that when running it ought to create a smalldv.ini file in the .config folder and remember settings that you change

Ok, now for a 2020 mode version.

To build for 2020, codec2 needs upgrading. The instructions below are copied from here: https://github.com/drowe67/codec2

Note that the following assumes codec2 is in ~/codec2, which should be the case.

Build LPCNet:

$ cd ~
$ git clone https://github.com/drowe67/LPCNet
$ cd LPCNet && mkdir build_linux && cd build_linux
$ cmake -DCODEC2_BUILD_DIR=~/codec2/build_linux ../
$ make
$ sudo make install

Now rebuild codec2 with LPCNet support:

$ cd ~/codec2/build_linux && rm -Rf *
$ cmake -DLPCNET_BUILD_DIR=~/LPCNet/build_linux ..
$ make
$ sudo make install

Now you need a tweaked version of smalldv. Make the following changes. Note that line numbers relate to the ORIGINAL file line numbers. Easiest way is to locate the file with the graphical interface file manager, right click, and edit it with Geany.

First to fdvcore.cc

At line 27 change this:
#ifdef FREEDV_MODE_700D
#define FDV_MODES “1600, 800XA, 700, 700B, 700C, 700D”
#define FDV_MODES “1600, 800XA, 700, 700B, 700C”

to this:

#ifdef FREEDV_MODE_2020
#define FDV_MODES “1600, 800XA, 700, 700B, 700C, 700D, 2020”
#ifdef FREEDV_MODE_700D
#define FDV_MODES “1600, 800XA, 700, 700B, 700C, 700D”
#define FDV_MODES “1600, 800XA, 700, 700B, 700C”

At line 106 change this:
if (!strcmp(argv[modemIndex],”700″))
modem = FREEDV_MODE_700;
if (!strcmp(argv[modemIndex],”700B”))
modem = FREEDV_MODE_700B;

to this:

#ifdef FREEDV_MODE_700
if (!strcmp(argv[modemIndex],”700″))
modem = FREEDV_MODE_700;
#ifdef FREEDV_MODE_700B
if (!strcmp(argv[modemIndex],”700B”))
modem = FREEDV_MODE_700B;
#ifdef FREEDV_MODE_2020
if (!strcmp(argv[modemIndex],”2020″))
modem = FREEDV_MODE_2020;

In smalldv:

At line 708 change this:
elif arg == ‘1600’ or arg == ‘700’ or arg == ‘700B’ or arg == ‘700C’ or arg == ‘700D’ or arg == ‘800XA’:

to this:

elif arg == ‘2020’ or arg == ‘1600’ or arg == ‘700’ or arg == ‘700B’ or arg == ‘700C’ or arg == ‘700D’ or arg == ‘800XA’:

At line 1117 change this:

if modem == ‘1600’ or modem == ‘700’ or modem == ‘700B’ or modem == ‘700C’ or modem == ‘700D’ or modem == ‘800XA’:

to this:

if modem == ‘2020’ or modem == ‘1600’ or modem == ‘700’ or modem == ‘700B’ or modem == ‘700C’ or modem == ‘700D’ or modem == ‘800XA’:

Now run ‘sudo ldconfig’ before you try to build or run smalldv or fdvcore.

Now rebuild smalldv (‘cd ~/smalldv’ then ‘make clean’ then ‘make’ and ‘sudo make install’)..

Comments are closed.