[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
*/
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);
/* 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;
}
#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
}
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 */
}
}
}
+/*---------------------------------------------------------------------------*\
+
+ 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; c<OFDM_NC; c++) {
+ for (r=0; r<OFDM_ROWSPERFRAME; r++) {
+ complex float rot = ofdm->rx_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);
+ }
+ }
+}