Testing the FreeDV API

James Ahlstrom (the author of the Quisk SDR software) submitted a patch for the FreeDV API to change the sample rate used for FreeDV 700 from the obscure 7500 Hz to a more useful 8000 Hz. FreeDV 700(B) mode uses the coherent PSK modem (COHPSK) which I spent the first six months of 2015 developing but haven’t written much about yet. This modem is responsible for much of the low SNR performance improvement of FreeDV 700(B) over 1600.

There were a couple of challenges with this patch:

  1. 8000 to 7500Hz is not a neat ratio.
  2. To accommodate differences in the tx and rx sample clocks, the demodulator has a time varying number of input samples. Occasionally the demodulator asks for a few more, or a few less samples.

On a personal note it’s really wonderful (and unusual) to have a high quality, challenging DSP patch submitted – thank you so much Jim!

I thought it would be worth documenting how I tested the patch; (i) so others can appreciate the magic of extremely long command line Linux DSP simulations and (ii) so I don’t forget it for next time. This blog is useful as my on-line log book as it’s search-able.

If anyone has any questions, just ask in the comments.

1/ I tested it with clock offsets of +5 and -5 Hz, e.g.
$ ./freedv_tx 700B ../../raw/ve9qrp.raw - --testframes | sox -t raw -r 8000 -s -2 - -t raw -r 7995 -s -2 -t raw - | ./freedv_rx 700B - /dev/null --testframes
bits: 78512 errors: 0 BER: 0.00

2/ Looking at freedv_rx_log.txt, I can see “nin” getting occasional low values:
frame: 1345 demod sync: 1 nin:640 demod snr: 21.25 dB bit errors: 0
frame: 1346 demod sync: 1 nin:613 demod snr: 21.38 dB bit errors: 0
frame: 1347 demod sync: 1 nin:640 demod snr: 21.57 dB bit errors: 0

That’s the demod asking for “a few less samples please” to accommodate for the sample clock offset. If something is going to go wrong, this is where it will be. However we can see sync is not lost and no bit errors introduced. CHECK

3/ Then I tested in an AWGN channel at an Eb/No of around 4dB, which for coherent PSK should give us a (Bit Error Rate) BER 1%. Lets throw in a 10Hz frequency offset as well:
$ ./freedv_tx 700B ../../raw/ve9qrp.raw - --testframes | sox -t raw -r 8000 -s -2 - -t raw -r 7995 -s -2 -t raw - | ./cohpsk_ch - - -22 10 0 1 | ./freedv_rx 700B - /dev/null --testframes
NodB: -22.00 foff: 10.00 Hz fading: 0 inclip: 1.00

peak pwr.....: 137.73
av input pwr.: 20.04
av pwr fading: 20.03
noise pwr....: 23.62
clipping.....: 0.00 %
PAPR (dB)....: 8.37 (target 7.00)
C/No (dB)....: 35.03
SNR3k........: 0.26
Eb/No(Rb=700): 4.82

bits: 78512 errors: 925 BER: 0.01

CHECK
4/ For comparison, the Fs=7500 Hz modem without the patch:
$ ./freedv_tx 700B ../../raw/ve9qrp.raw - --testframes | sox -t raw -r 7500 -s -2 - -t raw -r 7505 -s -2 -t raw - | ./cohpsk_ch - - -22 10 0 1 | ./freedv_rx 700B - /dev/null --testframes

NodB: -22.00 foff: 10.00 Hz fading: 0 inclip: 1.00
peak pwr.....: 136.33
av input pwr.: 20.06
av pwr fading: 20.05
noise pwr....: 23.62
clipping.....: 0.00 %
PAPR (dB)....: 8.32 (target 7.00)
C/No (dB)....: 35.03
SNR3k........: 0.26
Eb/No(Rb=700): 4.82

bits: 77952 errors: 1162 BER: 0.01
Ok so with the patch the modem gets better (less bit errors, 925 versus 1162)! Wellllll, I think it’s due to this line in cohpsk_ch.c where we work out the noise power:
/* N = var = NoFs */

No = pow(10.0, NodB/10.0);
variance = COHPSK_FS*No;

We scale the noise power according to Fs, which is still set to 7500Hz, despite our sample rate being raised to 8000Hz. So we are injecting a little less noise than we should be, lowering the BER. I need cohpsk_ch to test the core cohpsk modem (cohpsk_tx, cohpsk_rx) that runs at Fs=7500Hz AND freedv_tx/rx that now runs at Fs=8000Hz. So not sure how to handle this atm. Maybe a freedv_ch that rebuilds cohpsk_ch with FS #defined to 8000? Meh, worry about that later.

Now I need to refactor the FreeDV GUI program for these API changes…..

Reading Further

This blog post on Testing a FDMDV modem has some examples of nasty sample clock offsets caused by PC sound cards. The FDMDV modem is used for FreeDV 1600.