From: drowe67 Date: Fri, 13 Jan 2017 21:28:44 +0000 (+0000) Subject: FreeDV 700C mode working X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=e76d94680d2cea85d64a4c9fdfa4ba63873c816d;p=freetel-svn-tracking.git FreeDV 700C mode working git-svn-id: https://svn.code.sf.net/p/freetel/code@2968 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/src/codec2_cohpsk.h b/codec2-dev/src/codec2_cohpsk.h index 3a021720..b64cde84 100644 --- a/codec2-dev/src/codec2_cohpsk.h +++ b/codec2-dev/src/codec2_cohpsk.h @@ -53,7 +53,7 @@ void cohpsk_get_demod_stats(struct COHPSK *cohpsk, struct MODEM_STATS *stats); void cohpsk_set_verbose(struct COHPSK *coh, int verbose); void cohpsk_get_test_bits(struct COHPSK *coh, int rx_bits[]); void cohpsk_put_test_bits(struct COHPSK *coh, int *state, short error_pattern[], - int *bit_errors, char rx_bits_sd[]); + int *bit_errors, char rx_bits[]); int cohpsk_error_pattern_size(void); void cohpsk_set_frame(struct COHPSK *coh, int frame); void fdmdv_freq_shift_coh(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, float Fs, diff --git a/codec2-dev/src/freedv_api.c b/codec2-dev/src/freedv_api.c index 6d14af85..2cc9bf8e 100644 --- a/codec2-dev/src/freedv_api.c +++ b/codec2-dev/src/freedv_api.c @@ -78,7 +78,8 @@ struct freedv *freedv_open(int mode) { if ((mode != FREEDV_MODE_1600) && (mode != FREEDV_MODE_700) && (mode != FREEDV_MODE_700B) && (mode != FREEDV_MODE_2400A) && - (mode != FREEDV_MODE_2400B) && (mode != FREEDV_MODE_800XA)) + (mode != FREEDV_MODE_2400B) && (mode != FREEDV_MODE_800XA) && + (mode != FREEDV_MODE_700C)) return NULL; f = (struct freedv*)malloc(sizeof(struct freedv)); @@ -120,13 +121,23 @@ struct freedv *freedv_open(int mode) { } #ifndef CORTEX_M4 - if ((mode == FREEDV_MODE_700) || (mode == FREEDV_MODE_700B)) { + if ((mode == FREEDV_MODE_700) || (mode == FREEDV_MODE_700B) || (mode == FREEDV_MODE_700C)) { f->snr_squelch_thresh = 0.0; f->squelch_en = 0; - if (mode == FREEDV_MODE_700) + switch(mode) { + case FREEDV_MODE_700: codec2_mode = CODEC2_MODE_700; - else + break; + case FREEDV_MODE_700B: codec2_mode = CODEC2_MODE_700B; + break; + case FREEDV_MODE_700C: + codec2_mode = CODEC2_MODE_700C; + break; + default: + assert(0); + } + f->cohpsk = cohpsk_create(); f->nin = COHPSK_NOM_SAMPLES_PER_FRAME; f->n_nat_modem_samples = COHPSK_NOM_SAMPLES_PER_FRAME; // native modem samples as used by the modem @@ -257,7 +268,7 @@ struct freedv *freedv_open(int mode) { nbyte = nbyte*2; nbit = 8*nbyte; f->n_codec_bits = nbit; - } else { /* ((mode == FREEDV_MODE_700) || (mode == FREEDV_MODE_700B)) */ + } else { /* ((mode == FREEDV_MODE_700) || (mode == FREEDV_MODE_700B) || (mode == FREEDV_MODE_700C)) */ f->n_speech_samples = 2*codec2_samples_per_frame(f->codec2); f->n_codec_bits = 2*codec2_bits_per_frame(f->codec2); nbit = f->n_codec_bits; @@ -271,14 +282,14 @@ struct freedv *freedv_open(int mode) { f->packed_codec_bits = (unsigned char*)malloc(nbyte*sizeof(char)); if (mode == FREEDV_MODE_1600) f->codec_bits = (int*)malloc(nbit*sizeof(int)); - if ((mode == FREEDV_MODE_700) || (mode == FREEDV_MODE_700B)) + if ((mode == FREEDV_MODE_700) || (mode == FREEDV_MODE_700B) || (mode == FREEDV_MODE_700C)) f->codec_bits = (int*)malloc(COHPSK_BITS_PER_FRAME*sizeof(int)); /* Note: VHF Framer/deframer goes directly from packed codec/vc/proto bits to filled frame */ if ((f->packed_codec_bits == NULL) || (f->codec_bits == NULL)) return NULL; - if ((mode == FREEDV_MODE_700) || (mode == FREEDV_MODE_700B)) { // change modem rates to 8000 sps + if ((mode == FREEDV_MODE_700) || (mode == FREEDV_MODE_700B) || (mode == FREEDV_MODE_700C) ) { // change modem rates to 8000 sps f->ptFilter7500to8000 = (struct quisk_cfFilter *)malloc(sizeof(struct quisk_cfFilter)); f->ptFilter8000to7500 = (struct quisk_cfFilter *)malloc(sizeof(struct quisk_cfFilter)); quisk_filt_cfInit(f->ptFilter8000to7500, quiskFilt120t480, sizeof(quiskFilt120t480)/sizeof(float)); @@ -321,10 +332,10 @@ void freedv_close(struct freedv *freedv) { if (freedv->mode == FREEDV_MODE_1600) fdmdv_destroy(freedv->fdmdv); #ifndef CORTEX_M4 - if (freedv->mode == FREEDV_MODE_700) + if ((freedv->mode == FREEDV_MODE_700) || (freedv->mode == FREEDV_MODE_700B) || (freedv->mode == FREEDV_MODE_700C)) cohpsk_destroy(freedv->cohpsk); #endif - if (freedv->mode == FREEDV_MODE_2400A || freedv->mode == FREEDV_MODE_800XA){ + if ((freedv->mode == FREEDV_MODE_2400A) || (freedv->mode == FREEDV_MODE_800XA)){ fsk_destroy(freedv->fsk); fvhff_destroy_deframer(freedv->deframer); } @@ -485,8 +496,9 @@ void freedv_tx(struct freedv *f, short mod_out[], short speech_in[]) { COMP tx_fdm[f->n_nom_modem_samples]; int i; assert((f->mode == FREEDV_MODE_1600) || (f->mode == FREEDV_MODE_700) || - (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_2400A) || - (f->mode == FREEDV_MODE_2400B) || (f->mode == FREEDV_MODE_800XA)); + (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_700C) || + (f->mode == FREEDV_MODE_2400A) || (f->mode == FREEDV_MODE_2400B) || + (f->mode == FREEDV_MODE_800XA)); /* FSK and MEFSK/FMFSK modems work only on real samples. It's simpler to just * stick them in the real sample tx/rx functions than to add a comp->real converter @@ -632,10 +644,19 @@ static void freedv_comptx_fdmdv_700(struct freedv *f, COMP mod_out[]) { // spare bits in frame that codec defines. Use these spare // bits/frame to send txt messages - if (f->mode == FREEDV_MODE_700) + switch(f->mode) { + case FREEDV_MODE_700: nspare = 2; - else + break; + case FREEDV_MODE_700B: nspare = 1; // Just one spare bit for FREEDV_MODE_700B + break; + case FREEDV_MODE_700C: + nspare = 0; // and no spare bits for 700C atm + break; + default: + assert(0); + } data_flag_index = codec2_get_spare_bit_index(f->codec2); @@ -686,8 +707,8 @@ void freedv_comptx(struct freedv *f, COMP mod_out[], short speech_in[]) { short tx_real[f->n_nom_modem_samples]; assert((f->mode == FREEDV_MODE_1600) || (f->mode == FREEDV_MODE_700) || - (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_2400A) || - (f->mode == FREEDV_MODE_2400B)); + (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_700C) || + (f->mode == FREEDV_MODE_2400A) || (f->mode == FREEDV_MODE_2400B)); if (f->mode == FREEDV_MODE_1600) { codec2_encode(f->codec2, f->packed_codec_bits, speech_in); @@ -695,7 +716,7 @@ void freedv_comptx(struct freedv *f, COMP mod_out[], short speech_in[]) { } #ifndef CORTEX_M4 - if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B)) { + if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B)|| (f->mode == FREEDV_MODE_700C)) { bits_per_codec_frame = codec2_bits_per_frame(f->codec2); int bytes_per_codec_frame = (bits_per_codec_frame + 7) / 8; int codec_frames = f->n_codec_bits / bits_per_codec_frame; @@ -738,6 +759,7 @@ void freedv_codectx(struct freedv *f, short mod_out[], unsigned char *packed_cod #ifndef CORTEX_M4 case FREEDV_MODE_700: case FREEDV_MODE_700B: + case FREEDV_MODE_700C: freedv_comptx_fdmdv_700(f, tx_fdm); break; case FREEDV_MODE_2400A: @@ -772,7 +794,7 @@ int freedv_data_ntxframes (struct freedv *f){ } int freedv_nin(struct freedv *f) { - if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B)) + if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_700C)) // For mode 700, the input rate is 8000 sps, but the modem rate is 7500 sps // For mode 700, we request a larger number of Rx samples that will be decimated to f->nin samples return (16 * f->nin + f->ptFilter8000to7500->decim_index) / 15; @@ -844,9 +866,9 @@ int freedv_rx(struct freedv *f, short speech_out[], short demod_in[]) { return freedv_floatrx(f,speech_out,rx_float); } - if( (f->mode == FREEDV_MODE_1600) || (f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B)){ + if( (f->mode == FREEDV_MODE_1600) || (f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_700C)){ /* FDM RX happens with complex samps, so do that */ - COMP rx_fdm[f->n_max_modem_samples]; + COMP rx_fdm[f->n_max_modem_samples]; for(i=0; in_speech_samples; } - if( (f->mode == FREEDV_MODE_1600) || (f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B)){ + if( (f->mode == FREEDV_MODE_1600) || (f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_700C)){ COMP rx_fdm[f->n_max_modem_samples]; for(i=0; ifdmdv, &test_frame_sync, error_pattern, &bit_errors, &ntest_bits, &f->rx_bits[k*bits_per_fdmdv_frame]); if (test_frame_sync == 1) { @@ -1124,7 +1147,7 @@ static int freedv_comprx_fdmdv_700(struct freedv *f, COMP demod_in[], int *valid int data_flag_index, n_ascii, nspare; short abit[1]; char ascii_out; - float rx_bits[COHPSK_BITS_PER_FRAME]; + float rx_bits[COHPSK_BITS_PER_FRAME]; /* soft decn rx bits */ int sync; int frames; @@ -1142,8 +1165,9 @@ static int freedv_comprx_fdmdv_700(struct freedv *f, COMP demod_in[], int *valid for(i=0; inin; i++) demod_in[i] = fcmult(1.0/FDMDV_SCALE, demod_in[i]); - + cohpsk_demod(f->cohpsk, rx_bits, &sync, demod_in, &f->nin); + f->sync = sync; cohpsk_get_demod_stats(f->cohpsk, &f->stats); f->snr_est = f->stats.snr_est; @@ -1170,10 +1194,19 @@ static int freedv_comprx_fdmdv_700(struct freedv *f, COMP demod_in[], int *valid /* extract txt msg data bit(s) */ - if (f->mode == FREEDV_MODE_700) + switch(f->mode) { + case FREEDV_MODE_700: nspare = 2; - else - nspare = 1; + break; + case FREEDV_MODE_700B: + nspare = 1; // Just one spare bit for FREEDV_MODE_700B + break; + case FREEDV_MODE_700C: + nspare = 0; // and no spare bits for 700C atm + break; + default: + assert(0); + } for(k=0; kcohpsk, &f->test_frame_sync_state, error_pattern, &bit_errors, rx_bits); + char rx_bits_char[COHPSK_BITS_PER_FRAME]; + for(i=0; icohpsk, &f->test_frame_sync_state, error_pattern, &bit_errors, rx_bits_char); if (f->test_frame_sync_state) { f->total_bit_errors += bit_errors; f->total_bits += COHPSK_BITS_PER_FRAME; @@ -1226,7 +1262,6 @@ static int freedv_comprx_fdmdv_700(struct freedv *f, COMP demod_in[], int *valid } - /* no valid FreeDV signal - squelch output */ if (sync == 0) { @@ -1255,7 +1290,7 @@ int freedv_comprx(struct freedv *f, short speech_out[], COMP demod_in[]) { nout = freedv_comprx_fdmdv_1600(f, demod_in, &valid); } #ifndef CORTEX_M4 - if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B)) { + if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_700C)) { nout = freedv_comprx_fdmdv_700(f, demod_in, &valid); } #endif @@ -1297,7 +1332,7 @@ int freedv_codecrx(struct freedv *f, unsigned char *packed_codec_bits, short dem } } - if( (f->mode == FREEDV_MODE_1600) || (f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B)){ + if( (f->mode == FREEDV_MODE_1600) || (f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_700C)){ for(i=0; imode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B)) { + if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_700C)) { freedv_comprx_fdmdv_700(f, rx_fdm, &valid); } #endif @@ -1459,7 +1494,7 @@ void freedv_get_modem_stats(struct freedv *f, int *sync, float *snr_est) if (f->mode == FREEDV_MODE_1600) fdmdv_get_demod_stats(f->fdmdv, &f->stats); #ifndef CORTEX_M4 - if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B)) + if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_700C)) cohpsk_get_demod_stats(f->cohpsk, &f->stats); #endif if (sync) *sync = f->stats.sync; @@ -1578,7 +1613,7 @@ void freedv_get_modem_extended_stats(struct freedv *f, struct MODEM_STATS *stats memcpy(stats,&(f->stats),sizeof(struct MODEM_STATS)); #ifndef CORTEX_M4 - if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B)) + if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_700C)) cohpsk_get_demod_stats(f->cohpsk, stats); #endif } diff --git a/codec2-dev/src/freedv_rx.c b/codec2-dev/src/freedv_rx.c index 59d265e6..74b9edcd 100644 --- a/codec2-dev/src/freedv_rx.c +++ b/codec2-dev/src/freedv_rx.c @@ -105,7 +105,7 @@ int main(int argc, char *argv[]) { if (argc < 4) { - printf("usage: %s 1600|700|700B|2400A|2400B|800XA InputModemSpeechFile OutputSpeechRawFile [--test_frames] [--codecrx]\n", argv[0]); + printf("usage: %s 1600|700|700B|700C|2400A|2400B|800XA InputModemSpeechFile OutputSpeechRawFile [--test_frames] [--codecrx]\n", argv[0]); printf("e.g %s 1600 hts1a_fdmdv.raw hts1a_out.raw txtLogFile\n", argv[0]); exit(1); } @@ -117,6 +117,8 @@ int main(int argc, char *argv[]) { mode = FREEDV_MODE_700; if (!strcmp(argv[1],"700B")) mode = FREEDV_MODE_700B; + if (!strcmp(argv[1],"700C")) + mode = FREEDV_MODE_700C; if (!strcmp(argv[1],"2400A")) mode = FREEDV_MODE_2400A; if (!strcmp(argv[1],"2400B")) diff --git a/codec2-dev/src/freedv_tx.c b/codec2-dev/src/freedv_tx.c index 5565fb41..874a9b59 100644 --- a/codec2-dev/src/freedv_tx.c +++ b/codec2-dev/src/freedv_tx.c @@ -98,7 +98,7 @@ int main(int argc, char *argv[]) { int i; if (argc < 4) { - printf("usage: %s 1600|700|700B|2400A|2400B|800XA InputRawSpeechFile OutputModemRawFile [--testframes] [--codectx] [--datatx]\n", argv[0]); + printf("usage: %s 1600|700|700B|700C|2400A|2400B|800XA InputRawSpeechFile OutputModemRawFile [--testframes] [--codectx] [--datatx]\n", argv[0]); printf("e.g %s 1600 hts1a.raw hts1a_fdmdv.raw\n", argv[0]); exit(1); } @@ -110,6 +110,8 @@ int main(int argc, char *argv[]) { mode = FREEDV_MODE_700; if (!strcmp(argv[1],"700B")) mode = FREEDV_MODE_700B; + if (!strcmp(argv[1],"700C")) + mode = FREEDV_MODE_700C; if (!strcmp(argv[1],"2400A")){ mode = FREEDV_MODE_2400A; }