From 5cd05a0b4fc958d268dfda0a162653bac770da21 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Tue, 1 May 2018 00:40:43 +0000 Subject: [PATCH] added extended modem stats, hooked up SNR ests to freedv API for 700D git-svn-id: https://svn.code.sf.net/p/freetel/code@3542 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/src/codec2_ofdm.h | 2 ++ codec2-dev/src/freedv_api.c | 20 +++++++++++++------ codec2-dev/src/ofdm.c | 37 ++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/codec2-dev/src/codec2_ofdm.h b/codec2-dev/src/codec2_ofdm.h index 0d96aaff..82ef549c 100644 --- a/codec2-dev/src/codec2_ofdm.h +++ b/codec2-dev/src/codec2_ofdm.h @@ -38,6 +38,7 @@ extern "C" { #include #include "comp.h" +#include "modem_stats.h" /* Defines */ @@ -70,6 +71,7 @@ int ofdm_get_nin(struct OFDM *); int ofdm_get_samples_per_frame(void); int ofdm_get_max_samples_per_frame(void); int ofdm_get_bits_per_frame(struct OFDM *); +void ofdm_get_demod_stats(struct OFDM *ofdm, struct MODEM_STATS *stats); /* option setters */ diff --git a/codec2-dev/src/freedv_api.c b/codec2-dev/src/freedv_api.c index 882e032a..4955d076 100644 --- a/codec2-dev/src/freedv_api.c +++ b/codec2-dev/src/freedv_api.c @@ -1627,10 +1627,10 @@ static int freedv_comprx_700(struct freedv *f, COMP demod_in_8kHz[], int *valid) [X] in testframe mode count coded and uncoded errors [X] freedv getter for modem and interleaver sync [X] rms level the same as fdmdv - [ ] way to stay in sync and not resync automatically - [ ] SNR est, maybe from pilots, cohpsk have an example? + [X] way to stay in sync and not resync automatically + [X] SNR est, maybe from pilots, cohpsk have an example? [ ] error pattern support? - [ ] work out how to handle return of multiple interleaved frames over time + [X] work out how to handle return of multiple interleaved frames over time [ ] deal with out of sync returning nin samples, listening to analog audio when out of sync */ @@ -1687,6 +1687,9 @@ static int freedv_comprx_700d(struct freedv *f, COMP demod_in_8kHz[], int *valid if ((strcmp(ofdm->sync_state,"synced") == 0) || (strcmp(ofdm->sync_state,"trial") == 0) ) { ofdm_demod(ofdm, rx_bits, rxbuf_in); + fdmdv_get_demod_stats(f->fdmdv, &f->stats); + f->sync = 1; + f->snr_est = f->stats.snr_est; assert((OFDM_NUWBITS+OFDM_NTXTBITS+coded_bits_per_frame) == OFDM_BITSPERFRAME); @@ -1814,11 +1817,12 @@ static int freedv_comprx_700d(struct freedv *f, COMP demod_in_8kHz[], int *valid /* no valid FreeDV signal - squelch output */ - if (strcmp(ofdm->sync_state_interleaver,"synced")) { - //nout = freedv_nin(f); + int sync = !strcmp(ofdm->sync_state_interleaver,"synced") || !strcmp(ofdm->sync_state_interleaver,"synced"); + if (!sync) { if (f->squelch_en) { *valid = 0; } + f->snr_est = 0.0; } return nout; @@ -2254,8 +2258,12 @@ void freedv_get_modem_extended_stats(struct freedv *f, struct MODEM_STATS *stats } #ifndef CORTEX_M4 - if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_700C)) + if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_700C)) { cohpsk_get_demod_stats(f->cohpsk, stats); + } + if (f->mode == FREEDV_MODE_700D) { + ofdm_get_demod_stats(f->ofdm, stats); + } #endif } diff --git a/codec2-dev/src/ofdm.c b/codec2-dev/src/ofdm.c index 7877aace..18b0646e 100644 --- a/codec2-dev/src/ofdm.c +++ b/codec2-dev/src/ofdm.c @@ -439,6 +439,8 @@ struct OFDM *ofdm_create(const struct OFDM_CONFIG *config) { ofdm->timing_norm = (OFDM_M + OFDM_NCP) * acc; //fprintf(stderr, "timing_norm: %f\n", ofdm->timing_norm); + + ofdm->sig_var = ofdm->noise_var = 1.0; return ofdm; /* Success */ } @@ -1136,3 +1138,38 @@ void ofdm_set_sync(struct OFDM *ofdm, int sync_cmd) { } } +/*---------------------------------------------------------------------------*\ + + FUNCTION....: ofdm_get_demod_stats() + AUTHOR......: David Rowe + DATE CREATED: May 2018 + + Fills stats structure with a bunch of demod information. + +\*---------------------------------------------------------------------------*/ + +void ofdm_get_demod_stats(struct OFDM *ofdm, struct MODEM_STATS *stats) +{ + int c,r; + + stats->Nc = OFDM_NC; + assert(stats->Nc <= MODEM_STATS_NC_MAX); + + float snr_est = 10*log10((ofdm->sig_var/ofdm->noise_var)*OFDM_NC*OFDM_RS/3000); + stats->snr_est = 0.9*stats->snr_est + 0.1*snr_est; + + stats->sync = !strcpy(ofdm->sync_state, "synced") || !strcpy(ofdm->sync_state, "trial"); + stats->foff = ofdm->foff_est_hz; + stats->rx_timing = ofdm->timing_est; + stats->clock_offset = 0.0; /* TODO: work out sample clock offset */ + + assert(OFDM_ROWSPERFRAME <= MODEM_STATS_NR_MAX); + stats->nr = OFDM_ROWSPERFRAME; + for(c=0; crx_np[r*c] * (cosf(M_PI/4.0) + I*sinf(M_PI/4.0)); + stats->rx_symbols[r][c].real = crealf(rot); + stats->rx_symbols[r][c].imag = cimagf(rot); + } + } +} -- 2.25.1