From 0df9cd1ec4fda0602d5be52de9854dd0cf015b59 Mon Sep 17 00:00:00 2001 From: baobrien Date: Wed, 6 Apr 2016 02:34:26 +0000 Subject: [PATCH] 2400A&2400B now properly frame and deframe protocol bits; freedv_rx and freedv_tx now have callbacks for protocol bits git-svn-id: https://svn.code.sf.net/p/freetel/code@2772 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/src/freedv_api.c | 30 +++++++++++++--------------- codec2-dev/src/freedv_api.h | 2 +- codec2-dev/src/freedv_api_internal.h | 2 +- codec2-dev/src/freedv_rx.c | 10 +++++++++- codec2-dev/src/freedv_tx.c | 27 ++++++++++++++++--------- codec2-dev/src/freedv_vhf_framing.c | 12 +++++------ 6 files changed, 49 insertions(+), 34 deletions(-) diff --git a/codec2-dev/src/freedv_api.c b/codec2-dev/src/freedv_api.c index e5b6c3fb..d8706ee7 100644 --- a/codec2-dev/src/freedv_api.c +++ b/codec2-dev/src/freedv_api.c @@ -349,7 +349,7 @@ static void freedv_tx_fsk_voice(struct freedv *f, short mod_out[]) { int i; float *tx_float; /* To hold on to modulated samps from fsk/fmfsk */ uint8_t vc_bits[2]; /* Varicode bits for 2400 framing */ - + uint8_t proto_bits[3]; /* Prococol bits for 2400 framing */ /* 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 */ @@ -371,10 +371,13 @@ static void freedv_tx_fsk_voice(struct freedv *f, short mod_out[]) { } /* 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{ + if(f->freedv_get_next_proto != NULL){ + (*f->freedv_get_next_proto)(f->proto_callback_state,(char*)proto_bits); + fvhff_frame_bits(FREEDV_VHF_FRAME_A,(uint8_t*)(f->tx_bits),(uint8_t*)(f->packed_codec_bits),proto_bits,vc_bits); + }else 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,vc_bits); + }else { + fvhff_frame_bits(FREEDV_VHF_FRAME_A,(uint8_t*)(f->tx_bits),(uint8_t*)(f->packed_codec_bits),NULL,NULL); } /* Allocate floating point buffer for FSK mod */ @@ -441,10 +444,10 @@ void freedv_tx(struct freedv *f, short mod_out[], short speech_in[]) { * to comptx */ if((f->mode == FREEDV_MODE_2400A) || (f->mode == FREEDV_MODE_2400B)){ - #ifndef CORTEX_M4 +#ifndef CORTEX_M4 codec2_encode(f->codec2, f->packed_codec_bits, speech_in); freedv_tx_fsk_voice(f, mod_out); - #endif +#endif }else{ freedv_comptx(f, tx_fdm, speech_in); for(i=0; in_nom_modem_samples; i++) @@ -589,7 +592,6 @@ static void freedv_comptx_fdmdv_700(struct freedv *f, COMP mod_out[]) { //fprintf(stderr, "%d %d\n", j+data_flag_index+k, f->codec_bits[j+data_flag_index+k]); f->nvaricode_bits--; } - if (f->nvaricode_bits == 0) { /* get new char and encode */ char s[2]; @@ -600,9 +602,7 @@ static void freedv_comptx_fdmdv_700(struct freedv *f, COMP mod_out[]) { } } } - } - /* optionally ovwerwrite the codec bits with test frames */ if (f->test_frames) { @@ -634,13 +634,10 @@ void freedv_comptx(struct freedv *f, COMP mod_out[], short speech_in[]) { (f->mode == FREEDV_MODE_2400B)); if (f->mode == FREEDV_MODE_1600) { - codec2_encode(f->codec2, f->packed_codec_bits, speech_in); - freedv_comptx_fdmdv_1600(f, mod_out); } - #ifndef CORTEX_M4 if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B)) { bits_per_codec_frame = codec2_bits_per_frame(f->codec2); @@ -651,7 +648,6 @@ void freedv_comptx(struct freedv *f, COMP mod_out[], short speech_in[]) { codec2_encode(f->codec2, f->packed_codec_bits + j * bytes_per_codec_frame, speech_in); speech_in += codec2_samples_per_frame(f->codec2); } - freedv_comptx_fdmdv_700(f, mod_out); } /* 2400 A and B are handled by the real-mode TX */ @@ -779,12 +775,14 @@ int freedv_nin(struct freedv *f) { int freedv_rx(struct freedv *f, short speech_out[], short demod_in[]) { assert(f != NULL); COMP rx_fdm[f->n_max_modem_samples]; - float rx_float[f->n_max_modem_samples]; int i; int nin = freedv_nin(f); assert(nin <= f->n_max_modem_samples); #ifndef CORTEX_M4 + /* Moved inside of cortex_m4 ifdef to silence unused var warning */ + float rx_float[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; ifmfsk,(uint8_t*)f->tx_bits,demod_in); f->nin = fmfsk_nin(f->fmfsk); } - /* TODO: Protocol and varicode bits */ + if(fvhff_deframe_bits(f->deframer,f->packed_codec_bits,proto_bits,vc_bits,(uint8_t*)f->tx_bits)){ /* Decode varicode text */ for(i=0; i<2; i++){ @@ -834,7 +832,7 @@ int freedv_floatrx_fsk_2400(struct freedv *f, float demod_in[], int *valid) { (*f->freedv_put_next_rx_char)(f->callback_state, ascii_out); } } - /* Pass proto bits on if callback is present */ + /* Pass proto bits on down if callback is present */ if( f->freedv_put_next_proto != NULL){ (*f->freedv_put_next_proto)(f->proto_callback_state,(char*)proto_bits); } diff --git a/codec2-dev/src/freedv_api.h b/codec2-dev/src/freedv_api.h index c95de56c..44bc66a7 100644 --- a/codec2-dev/src/freedv_api.h +++ b/codec2-dev/src/freedv_api.h @@ -56,7 +56,7 @@ typedef void (*freedv_calback_error_pattern) /* Called when a frame containing protocol data is decoded */ typedef void (*freedv_callback_protorx)(void *, char *); /* Called when a frame containing protocol data is to be sent */ -typedef char * (*freedv_callback_prototx)(void *); +typedef void (*freedv_callback_prototx)(void *, char *); /* Data packet callbacks */ /* Called when a packet has been received */ diff --git a/codec2-dev/src/freedv_api_internal.h b/codec2-dev/src/freedv_api_internal.h index 0a0cfe31..b25e5811 100644 --- a/codec2-dev/src/freedv_api_internal.h +++ b/codec2-dev/src/freedv_api_internal.h @@ -128,7 +128,7 @@ struct freedv { /* user defined functions to produce and consume protocol bits */ /* Protocol bits are packed MSB-first */ void (*freedv_put_next_proto)(void *callback_state, char *proto_bits_packed); - void (*freedv_get_next_proto)(void *callback_state); + void (*freedv_get_next_proto)(void *callback_state, char *proto_bits_packed); void *proto_callback_state; int n_protocol_bits; }; diff --git a/codec2-dev/src/freedv_rx.c b/codec2-dev/src/freedv_rx.c index 3380a50d..210ff4fa 100644 --- a/codec2-dev/src/freedv_rx.c +++ b/codec2-dev/src/freedv_rx.c @@ -49,7 +49,14 @@ struct my_callback_state { void my_put_next_rx_char(void *callback_state, char c) { struct my_callback_state* pstate = (struct my_callback_state*)callback_state; if (pstate->ftxt != NULL) { - fprintf(pstate->ftxt, "%c", c); + fprintf(pstate->ftxt, "text msg: %c\n", c); + } +} + +void my_put_next_rx_proto(void *callback_state,char *proto_bits){ + struct my_callback_state* pstate = (struct my_callback_state*)callback_state; + if (pstate->ftxt != NULL) { + fprintf(pstate->ftxt, "proto chars: %.*s\n",2, proto_bits); } } @@ -123,6 +130,7 @@ int main(int argc, char *argv[]) { assert(ftxt != NULL); my_cb_state.ftxt = ftxt; freedv_set_callback_txt(freedv, &my_put_next_rx_char, NULL, &my_cb_state); + freedv_set_callback_protocol(freedv, &my_put_next_rx_proto, NULL, &my_cb_state); /* Note we need to work out how many samples demod needs on each call (nin). This is used to adjust for differences in the tx and rx diff --git a/codec2-dev/src/freedv_tx.c b/codec2-dev/src/freedv_tx.c index ff4d31e0..5a6aeaaf 100644 --- a/codec2-dev/src/freedv_tx.c +++ b/codec2-dev/src/freedv_tx.c @@ -36,6 +36,7 @@ struct my_callback_state { char tx_str[80]; char *ptx_str; + int calls; }; char my_get_next_tx_char(void *callback_state) { @@ -49,6 +50,12 @@ char my_get_next_tx_char(void *callback_state) { return c; } +void my_get_next_proto(void *callback_state,char *proto_bits){ + struct my_callback_state* cb_states = (struct my_callback_state*)(callback_state); + snprintf(proto_bits,3,"%2d",cb_states->calls); + cb_states->calls = cb_states->calls + 1; +} + int main(int argc, char *argv[]) { FILE *fin, *fout; short *speech_in; @@ -60,9 +67,9 @@ int main(int argc, char *argv[]) { int n_nom_modem_samples; if (argc < 4) { - printf("usage: %s 1600|700|700B|2400A|2400B InputRawSpeechFile OutputModemRawFile [--testframes]\n", argv[0]); - printf("e.g %s 1600 hts1a.raw hts1a_fdmdv.raw\n", argv[0]); - exit(1); + printf("usage: %s 1600|700|700B|2400A|2400B InputRawSpeechFile OutputModemRawFile [--testframes]\n", argv[0]); + printf("e.g %s 1600 hts1a.raw hts1a_fdmdv.raw\n", argv[0]); + exit(1); } mode = -1; @@ -80,16 +87,14 @@ int main(int argc, char *argv[]) { if (strcmp(argv[2], "-") == 0) fin = stdin; else if ( (fin = fopen(argv[2],"rb")) == NULL ) { - fprintf(stderr, "Error opening input raw speech sample file: %s: %s.\n", - argv[2], strerror(errno)); - exit(1); + fprintf(stderr, "Error opening input raw speech sample file: %s: %s.\n", argv[2], strerror(errno)); + exit(1); } if (strcmp(argv[3], "-") == 0) fout = stdout; else if ( (fout = fopen(argv[3],"wb")) == NULL ) { - fprintf(stderr, "Error opening output modem sample file: %s: %s.\n", - argv[3], strerror(errno)); - exit(1); + fprintf(stderr, "Error opening output modem sample file: %s: %s.\n", argv[3], strerror(errno)); + exit(1); } freedv = freedv_open(mode); @@ -112,7 +117,11 @@ int main(int argc, char *argv[]) { sprintf(my_cb_state.tx_str, "cq cq cq hello world\r"); my_cb_state.ptx_str = my_cb_state.tx_str; + my_cb_state.calls = 0; freedv_set_callback_txt(freedv, NULL, &my_get_next_tx_char, &my_cb_state); + + /* set up callback for protocol bits */ + freedv_set_callback_protocol(freedv, NULL, &my_get_next_proto, &my_cb_state); /* OK main loop */ diff --git a/codec2-dev/src/freedv_vhf_framing.c b/codec2-dev/src/freedv_vhf_framing.c index 8362b2ac..19905bf6 100644 --- a/codec2-dev/src/freedv_vhf_framing.c +++ b/codec2-dev/src/freedv_vhf_framing.c @@ -88,12 +88,6 @@ void fvhff_frame_bits( int frame_type, for(i=0; i<96; i++) bits_out[i] = A_blank[i]; - /* Fill in varicode bits, if present */ - if(vc_in!=NULL){ - bits_out[90] = vc_in[0]; - bits_out[91] = vc_in[1]; - } - /* Fill in protocol bits, if present */ if(proto_in!=NULL){ ibit = 0; @@ -110,6 +104,12 @@ void fvhff_frame_bits( int frame_type, } } + /* Fill in varicode bits, if present */ + if(vc_in!=NULL){ + bits_out[90] = vc_in[0]; + bits_out[91] = vc_in[1]; + } + /* Fill in codec2 bits, present or not */ ibit = 0; for(i=16; i<40; i++){ /* First half */ -- 2.25.1