Embedded FreeDV

For the SM1000 development I need a way to embed the core functionality of a FreeDV “mode” in a simple library. A FreeDV “mode” is defined by the Codec 2 rate, the FEC, the frame structure, and the FDMDV modem waveform. Several modes have evolved over the past 18 months, and more are likely in the future. The current widely used mode (e.g. in the FreeDV GUI application) is known as “1600″ due to the bit rate.

Here is the simple C API I came up with:

struct freedv *freedv_open(int mode);
void freedv_close(struct freedv *freedv);
void freedv_tx(struct freedv *f, short mod_out[], short speech_in[]);
int freedv_nin(struct freedv *f);
int freedv_rx(struct freedv *f, short speech_out[], short demod_in[]);

Here is the header file freedv_api.h , C implementation freedv_api.c, and example transmitter and receiver programs.

It’s really easy to use from the command line:

$ ./freedv_tx ../../raw/hts1.raw - | ./freedv_rx - - | play -t raw -r 8000 -s -2 -

More examples are in the Codec 2 README.

The receive side is little tricky, as the number of input samples to the demodulator (and output samples from the codec) is time varying. You can see how that’s handled in this while loop:

    nin = freedv_nin(freedv);
    while(fread(demod_in, sizeof(short), nin, fin) == nin) {
        nout = freedv_rx(freedv, speech_out, demod_in);
        fwrite(speech_out, sizeof(short), nout, fout);
        nin = freedv_nin(freedv);

The demodulator works out how many samples it needs, to adjust for differences in the transmit and receive sample clocks (e.g. a few hundred ppm).

Transmit and receive of text characters is handled through call-back functions.

This API will be useful for “embedding” FreeDV into general purpose digital comms applications like fldigi, SDR radios, Android applications, custom embedded devices like the SM1000, or “headless” implementations of FreeDV on platforms like the Raspberry Pi. It needs hardware floating point and at least a 168MHz ARM4 (the SM1000 CPU).

SM1000 Update

OK, back to the SM1000 integration. Over the last week I have optimised the FDMDV modem by re-arranging the rx filtering. The modulator now takes 5ms and the demodulator 15ms (20ms total) for 40ms worth of data (200% real time). The modem optimisation work has also accelerated the code on x86 machines significantly.

Right now I’m working on drivers for the UI (switches and LEDs) so I can put it all together. Key tests include (i) everything operates OK in real time (ii) test the modem performance is OK through the SM1000 analog interfaces and (iii) test coverage of all of the hardware so we can kick off a Qty 100 beta run.

3 comments to Embedded FreeDV