From a3996e2c52841103383e61d11959c7988796cb64 Mon Sep 17 00:00:00 2001 From: baobrien Date: Sat, 20 Feb 2016 06:09:25 +0000 Subject: [PATCH] Further work on freedv 2400A/B git-svn-id: https://svn.code.sf.net/p/freetel/code@2704 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/octave/fmfsk.m | 4 +-- codec2-dev/src/fmfsk.c | 4 +-- codec2-dev/src/freedv_api.c | 40 ++++++++++++++++++++++++++--- codec2-dev/src/freedv_vhf_framing.c | 2 +- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/codec2-dev/octave/fmfsk.m b/codec2-dev/octave/fmfsk.m index 1d3cfabb..5f1e64fe 100644 --- a/codec2-dev/octave/fmfsk.m +++ b/codec2-dev/octave/fmfsk.m @@ -123,10 +123,10 @@ function [rx_bits states] = fmfsk_demod(states,rx) %If rx timing is too far out, ask for more or less sample the next time % around to even it all out next_nin = N; - if norm_rx_timing > .5; + if norm_rx_timing > 0; next_nin += Ts/2; end - if norm_rx_timing < -.5; + if norm_rx_timing < -.8; next_nin -= Ts/2; end diff --git a/codec2-dev/src/fmfsk.c b/codec2-dev/src/fmfsk.c index a80ad965..8e6b8ca3 100644 --- a/codec2-dev/src/fmfsk.c +++ b/codec2-dev/src/fmfsk.c @@ -215,9 +215,9 @@ void fmfsk_demod(struct FMFSK *fmfsk, uint8_t rx_bits[],float fmfsk_in[]){ /* Request fewer or greater samples next time, if fine timing is far * enough off. This also makes it possible to tolerate clock offsets */ next_nin = N; - if(norm_rx_timing > .5) + if(norm_rx_timing > 0) next_nin += Ts/2; - if(norm_rx_timing < -.5) + if(norm_rx_timing < -.8) next_nin -= Ts/2; fmfsk->nin = next_nin; diff --git a/codec2-dev/src/freedv_api.c b/codec2-dev/src/freedv_api.c index 29671bc7..f3362350 100644 --- a/codec2-dev/src/freedv_api.c +++ b/codec2-dev/src/freedv_api.c @@ -268,6 +268,12 @@ void freedv_close(struct freedv *freedv) { #ifndef CORTEX_M4 if (freedv->mode == FREEDV_MODE_700) cohpsk_destroy(freedv->cohpsk); + + if (freedv->mode == FREEDV_MODE_2400A) + fsk_destroy(freedv->fsk); + + if (freedv->mode == FREEDV_MODE_2400B) + fmfsk_destroy(freedv->fmfsk); #endif codec2_destroy(freedv->codec2); if (freedv->ptFilter8000to7500) { @@ -328,6 +334,7 @@ void freedv_tx(struct freedv *f, short mod_out[], short speech_in[]) { COMP tx_fdm[f->n_nom_modem_samples]; int i; float *tx_float; /* To hold on to modulated samps from fsk/fmfsk */ + uint8_t vc_bits[2]; /* Varicode bits for 2400 framing */ assert((f->mode == FREEDV_MODE_1600) || (f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_2400A) || @@ -339,8 +346,31 @@ void freedv_tx(struct freedv *f, short mod_out[], short speech_in[]) { if((f->mode == FREEDV_MODE_2400A) || (f->mode == FREEDV_MODE_2400B)){ codec2_encode(f->codec2, f->packed_codec_bits, speech_in); - /* TODO: add varicode/protocol insertion */ - fvhff_frame_bits(FREEDV_VHF_FRAME_A,(uint8_t*)(f->tx_bits),(uint8_t*)(f->packed_codec_bits),NULL,NULL); + /* Get varicode bits for TX and possibly ask for a new char */ + /* 2 bits per 2400A/B frame, so this has to be done twice */ + for(i=0;i<2;i++){ + if (f->nvaricode_bits) { + vc_bits[i] = f->tx_varicode_bits[f->varicode_bit_index++]; + f->nvaricode_bits--; + } + + if (f->nvaricode_bits == 0) { + /* get new char and encode */ + char s[2]; + if (f->freedv_get_next_tx_char != NULL) { + s[0] = (*f->freedv_get_next_tx_char)(f->callback_state); + f->nvaricode_bits = varicode_encode(f->tx_varicode_bits, s, VARICODE_MAX_BITS, 1, 1); + f->varicode_bit_index = 0; + } + } + } + + /* If the API user hasn't set up message callbacks, don't bother with varicode bits */ + if(f->freedv_get_next_tx_char == NULL){ + fvhff_frame_bits(FREEDV_VHF_FRAME_A,(uint8_t*)(f->tx_bits),(uint8_t*)(f->packed_codec_bits),NULL,NULL); + }else{ + fvhff_frame_bits(FREEDV_VHF_FRAME_A,(uint8_t*)(f->tx_bits),(uint8_t*)(f->packed_codec_bits),NULL,vc_bits); + } /* Allocate floating point buffer for FSK mod */ tx_float = alloca(sizeof(float)*f->n_nom_modem_samples); @@ -615,7 +645,6 @@ int freedv_rx(struct freedv *f, short speech_out[], short demod_in[]) { int nin = freedv_nin(f); assert(nin <= f->n_max_modem_samples); - /* FSK RX happens in real floats, so convert to those and call their demod here */ if( (f->mode == FREEDV_MODE_2400A) || (f->mode == FREEDV_MODE_2400B) ){ for(i=0; imode == FREEDV_MODE_2400A){ fsk_demod(f->fsk,(uint8_t*)f->tx_bits,demod_in); f->nin = fsk_nin(f->fsk); + f->stats.snr_est = f->fsk->EbNodB; + f->stats.clock_offset = f->fsk->ppm; }else{ fmfsk_demod(f->fmfsk,(uint8_t*)f->tx_bits,demod_in); f->nin = fmfsk_nin(f->fmfsk); @@ -659,11 +690,14 @@ int freedv_floatrx(struct freedv *f, short speech_out[], float demod_in[]) { /* Decode the codec data */ codec2_decode(f->codec2,speech_out,f->packed_codec_bits); f->sync = 1; + f->stats.sync = 1; } else { /* Fill with silence */ for(i=0;in_speech_samples;i++){ speech_out[i] = 0; } + f->sync = 0; + f->stats.sync = 0; } return f->n_speech_samples; }else { diff --git a/codec2-dev/src/freedv_vhf_framing.c b/codec2-dev/src/freedv_vhf_framing.c index d4a9ced7..5e839c3f 100644 --- a/codec2-dev/src/freedv_vhf_framing.c +++ b/codec2-dev/src/freedv_vhf_framing.c @@ -279,7 +279,7 @@ int fvhff_deframe_bits(struct freedv_vhf_deframer * def,uint8_t codec2_out[],uin /* Possibly set up frame-specific params here */ if(frame_type == FREEDV_VHF_FRAME_A){ uw_first_tol = 1; /* The UW bit-error tolerance for the first frame */ - uw_sync_tol = 1; /* The UW bit error tolerance for frames after sync */ + uw_sync_tol = 2; /* The UW bit error tolerance for frames after sync */ miss_tol = 5; /* How many UWs may be missed before going into the de-synced state */ }else{ return 0; -- 2.25.1