int CODEC2_WIN32SUPPORT fdmdv_bits_per_frame(struct FDMDV *fdmdv_state);
void CODEC2_WIN32SUPPORT fdmdv_mod(struct FDMDV *fdmdv_state, COMP tx_fdm[], int tx_bits[], int *sync_bit);
-void CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv_state, int rx_bits[], int *sync_bit, COMP rx_fdm[], int *nin);
+void CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv_state, int rx_bits[], int *reliable_sync_bit, COMP rx_fdm[], int *nin);
void CODEC2_WIN32SUPPORT fdmdv_get_test_bits(struct FDMDV *fdmdv_state, int tx_bits[]);
int CODEC2_WIN32SUPPORT fdmdv_error_pattern_size(struct FDMDV *fdmdv_state);
\*---------------------------------------------------------------------------*/
-int freq_state(int sync_bit, int *state, int *timer, int *sync_mem)
+int freq_state(int *reliable_sync_bit, int sync_bit, int *state, int *timer, int *sync_mem)
{
int next_state, sync, unique_word, i, corr;
- /* look for 6 symbols (120ms) 010101 of sync sequence */
+ /* look for 6 symbols (120ms) 101010 of sync sequence */
unique_word = 0;
for(i=0; i<NSYNC_MEM-1; i++)
corr += sync_mem[i]*sync_uw[i];
if (abs(corr) == NSYNC_MEM)
unique_word = 1;
+ *reliable_sync_bit = (corr == NSYNC_MEM);
/* iterate state machine */
\*---------------------------------------------------------------------------*/
void CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[],
- int *sync_bit, COMP rx_fdm[], int *nin)
+ int *reliable_sync_bit, COMP rx_fdm[], int *nin)
{
float foff_coarse, foff_fine;
COMP rx_fdm_fcorr[M+M/P];
COMP rx_filt[NC+1][P+1];
COMP rx_symbols[NC+1];
float env[NT*P];
-
+ int sync_bit;
+
/* freq offset estimation and correction */
foff_coarse = rx_est_freq_offset(fdmdv, rx_fdm, *nin);
if (fdmdv->rx_timing < 0)
*nin -= M/P;
- foff_fine = qpsk_to_bits(rx_bits, sync_bit, fdmdv->Nc, fdmdv->phase_difference, fdmdv->prev_rx_symbols, rx_symbols,
+ foff_fine = qpsk_to_bits(rx_bits, &sync_bit, fdmdv->Nc, fdmdv->phase_difference, fdmdv->prev_rx_symbols, rx_symbols,
fdmdv->old_qpsk_mapping);
memcpy(fdmdv->prev_rx_symbols, rx_symbols, sizeof(COMP)*(fdmdv->Nc+1));
snr_update(fdmdv->sig_est, fdmdv->noise_est, fdmdv->Nc, fdmdv->phase_difference);
/* freq offset estimation state machine */
- fdmdv->sync = freq_state(*sync_bit, &fdmdv->fest_state, &fdmdv->timer, fdmdv->sync_mem);
+ fdmdv->sync = freq_state(reliable_sync_bit, sync_bit, &fdmdv->fest_state, &fdmdv->timer, fdmdv->sync_mem);
fdmdv->foff -= TRACK_COEFF*foff_fine;
}
short rx_fdm_scaled[FDMDV_MAX_SAMPLES_PER_FRAME];
int i, bit, byte, c;
int nin, nin_prev;
- int sync_bit;
- int state, next_state;
+ int sync_bit, reliable_sync_bit;
+ int sync;
int f;
FILE *foct = NULL;
struct FDMDV_STATS stats;
assert(rx_fdm_log != NULL);
f = 0;
- state = 0;
nin = FDMDV_NOM_SAMPLES_PER_FRAME;
rx_fdm_log_col_index = 0;
max_frames_reached = 0;
rx_fdm[i].imag = 0;
}
nin_prev = nin;
- fdmdv_demod(fdmdv, rx_bits, &sync_bit, rx_fdm, &nin);
+ fdmdv_demod(fdmdv, rx_bits, &reliable_sync_bit, rx_fdm, &nin);
/* log data for optional Octave dump */
max_frames_reached = 1;
}
- /* state machine to output codec bits only if we have a 0,1
- sync bit sequence */
+ if (reliable_sync_bit)
+ sync = 1;
+ //printf("sync_bit: %d reliable_sync_bit: %d sync: %d\n", sync_bit, reliable_sync_bit, sync);
- next_state = state;
- switch (state) {
- case 0:
- if (sync_bit == 0) {
- next_state = 1;
- memcpy(codec_bits, rx_bits, bits_per_fdmdv_frame*sizeof(int));
- }
- else
- next_state = 0;
- break;
- case 1:
- if (sync_bit == 1) {
- memcpy(&codec_bits[bits_per_fdmdv_frame], rx_bits, bits_per_fdmdv_frame*sizeof(int));
-
- /* pack bits, MSB received first */
-
- bit = 7; byte = 0;
- memset(packed_bits, 0, bytes_per_codec_frame);
- for(i=0; i<bits_per_codec_frame; i++) {
- packed_bits[byte] |= (codec_bits[i] << bit);
- bit--;
- if (bit < 0) {
- bit = 7;
- byte++;
- }
- }
- assert(byte == bytes_per_codec_frame);
-
- fwrite(packed_bits, sizeof(char), bytes_per_codec_frame, fout);
- }
- next_state = 0;
- break;
- }
- state = next_state;
+ if (sync == 0) {
+ memcpy(codec_bits, rx_bits, bits_per_fdmdv_frame*sizeof(int));
+ sync = 1;
+ }
+ else {
+ memcpy(&codec_bits[bits_per_fdmdv_frame], rx_bits, bits_per_fdmdv_frame*sizeof(int));
+
+ /* pack bits, MSB received first */
+
+ bit = 7; byte = 0;
+ memset(packed_bits, 0, bytes_per_codec_frame);
+ for(i=0; i<bits_per_codec_frame; i++) {
+ packed_bits[byte] |= (codec_bits[i] << bit);
+ bit--;
+ if (bit < 0) {
+ bit = 7;
+ byte++;
+ }
+ }
+ assert(byte == bytes_per_codec_frame);
+
+ fwrite(packed_bits, sizeof(char), bytes_per_codec_frame, fout);
+ sync = 0;
+ }
+
/* if this is in a pipeline, we probably don't want the usual
buffering to occur */
int nin);
float qpsk_to_bits(int rx_bits[], int *sync_bit, int Nc, COMP phase_difference[], COMP prev_rx_symbols[], COMP rx_symbols[], int old_qpsk_mapping);
void snr_update(float sig_est[], float noise_est[], int Nc, COMP phase_difference[]);
-int freq_state(int sync_bit, int *state, int *timer, int *sync_mem);
+int freq_state(int *reliable_sync_bit, int sync_bit, int *state, int *timer, int *sync_mem);
float calc_snr(int Nc, float sig_est[], float noise_est[]);
#endif