#define OFDM_AMP_SCALE (2E5*1.1491/1.06) /* use to scale to 16 bit short */
#define OFDM_CLIP (32767*0.35) /* experimentally derived constant to reduce PAPR to about 8dB */
+#define OFDM_SYNC_UNSYNC 0 /* force sync state machine to lose sync, and search for new sync */
+#define OFDM_SYNC_AUTO 1 /* falls out of sync automatically */
+#define OFDM_SYNC_MANUAL 2 /* fall out of sync only under operator control */
struct OFDM;
void ofdm_set_foff_est_enable(struct OFDM *, bool);
void ofdm_set_phase_est_enable(struct OFDM *, bool);
void ofdm_set_off_est_hz(struct OFDM *, float);
+void ofdm_set_sync(struct OFDM *ofdm, int sync_cmd);
#ifdef __cplusplus
}
return -1;
}
+
+/*---------------------------------------------------------------------------* \
+
+ FUNCTIONS...: freedv_set_sync
+ AUTHOR......: David Rowe
+ DATE CREATED: May 2018
+
+ Extended control of sync state machines, especially for FreeDV 700D.
+ This mode is required to acquire sync up at very low SNRS. This is
+ difficult to implement, for example we may get a false sync, or the
+ state machine may fall out of sync by mistake during a long fade.
+
+ So with this API call we allow some operator assistance.
+
+ Ensure this is called inthe same thread as freedv_rx().
+
+\*---------------------------------------------------------------------------*/
+
+void freedv_set_sync(struct freedv *freedv, int sync_cmd) {
+ assert (freedv != NULL);
+
+ if (freedv->mode != FREEDV_MODE_700D) {
+ ofdm_set_sync(freedv->ofdm, sync_cmd);
+ }
+
+}
+
struct FSK * freedv_get_fsk(struct freedv *f){
return f->fsk;
}
#define FREEDV_MODE_700C 6
#define FREEDV_MODE_700D 7
+/* operator control of 700D state machine */
+
+#define FREEDV_SYNC_UNSYNC 0 /* force sync state machine to lose sync, and search for new sync */
+#define FREEDV_SYNC_AUTO 1 /* falls out of sync automatically */
+#define FREEDV_SYNC_MANUAL 2 /* fall out of sync only under operator control */
+
struct freedv;
/* advanced freedv open options rqd by some modes */
void freedv_set_data_header (struct freedv *freedv, unsigned char *header);
int freedv_set_alt_modem_samp_rate (struct freedv *freedv, int samp_rate);
void freedv_set_carrier_ampl (struct freedv *freedv, int c, float ampl);
+void freedv_set_sync (struct freedv *freedv, int sync_cmd);
// Get parameters -------------------------------------------------------------------------
ofdm->frame_count = 0;
ofdm->sync_start = 0;
ofdm->sync_end = 0;
+ ofdm->sync_mode = OFDM_SYNC_AUTO;
strcpy(ofdm->sync_state_interleaver,"search");
strcpy(ofdm->last_sync_state_interleaver,"search");
ofdm->sync_counter = 0;
}
- if (ofdm->sync_counter == 6) {
+ if ((ofdm->sync_mode == OFDM_SYNC_AUTO) && (ofdm->sync_counter == 6)) {
/* run of consective bad frames ... drop sync */
strcpy(next_state, "search");
strcpy(ofdm->sync_state_interleaver, "search");
strcpy(ofdm->sync_state, next_state);
}
+
+/*---------------------------------------------------------------------------* \
+
+ FUNCTIONS...: ofdm_set_sync
+ AUTHOR......: David Rowe
+ DATE CREATED: May 2018
+
+ Operator control of sync state machine. This mode is required to
+ acquire sync up at very low SNRS. This is difficult to implement,
+ for example we may get a false sync, or the state machine may fall
+ out of sync by mistake during a long fade.
+
+ So with this API call we allow some operator assistance.
+
+ Ensure this is called in the same thread as ofdm_sync_state_machine().
+
+\*---------------------------------------------------------------------------*/
+
+void ofdm_set_sync(struct OFDM *ofdm, int sync_cmd) {
+ assert (ofdm != NULL);
+
+ switch(sync_cmd) {
+ case OFDM_SYNC_UNSYNC:
+ /* force manual unsync, in case operator detects false sync,
+ which will cuase sync state machine to have another go at
+ sync */
+ strcpy(ofdm->sync_state, "search");
+ strcpy(ofdm->sync_state_interleaver, "search");
+ break;
+ case OFDM_SYNC_AUTO:
+ /* normal operating mode - sync state machine decides when to unsync */
+ ofdm->sync_mode = OFDM_SYNC_AUTO;
+ break;
+ case OFDM_SYNC_MANUAL:
+ /* allow sync state machine to sync, but not to unsync, the
+ operator will decide that manually */
+ ofdm->sync_mode = OFDM_SYNC_MANUAL;
+ break;
+ default:
+ assert(0);
+ }
+}
+
int frame_count;
int sync_start;
int sync_end;
+ int sync_mode;
/* interleaver sync state machine */