From 03239d46f2c8fd8e7f4d9f8f156b72d4fe5087eb Mon Sep 17 00:00:00 2001 From: drowe67 Date: Mon, 26 Nov 2012 00:23:24 +0000 Subject: [PATCH] first pass with data, can send messages and printf to screen. Need to think about silence thresholds/time outs git-svn-id: https://svn.code.sf.net/p/freetel/code@1069 01035d8c-6547-0410-b346-abe4f91aad63 --- fdmdv2/src/Makefile.linux | 6 +- fdmdv2/src/Makefile.win32 | 5 +- fdmdv2/src/fdmdv2_defines.h | 2 + fdmdv2/src/fdmdv2_main.cpp | 192 ++++++++++++++++++++++++++---------- fdmdv2/src/varicode.c | 112 ++++++++++++++------- fdmdv2/src/varicode.h | 8 +- 6 files changed, 230 insertions(+), 95 deletions(-) diff --git a/fdmdv2/src/Makefile.linux b/fdmdv2/src/Makefile.linux index 89f1c845..54da7727 100644 --- a/fdmdv2/src/Makefile.linux +++ b/fdmdv2/src/Makefile.linux @@ -28,9 +28,10 @@ fdmdv2_plot_waterfall_linux.o \ fdmdv2_pa_wrapper.o \ dlg_audiooptions.o \ dlg_comports.o \ -dlg_filter.o +dlg_filter.o \ +varicode.o -HDRS = dlg_audiooptions.h dlg_comports.h dlg_filter.h fdmdv2_main.h fdmdv2_defines.h fdmdv2_plot.h fdmdv2_plot_scalar.h fdmdv2_plot_waterfall_linux.h fdmdv2_plot_scatter.h fdmdv2_plot_spectrum.h fdmdv2_pa_wrapper.h topFrame.h +HDRS = dlg_audiooptions.h dlg_comports.h dlg_filter.h fdmdv2_main.h fdmdv2_defines.h fdmdv2_plot.h fdmdv2_plot_scalar.h fdmdv2_plot_waterfall_linux.h fdmdv2_plot_scatter.h fdmdv2_plot_spectrum.h fdmdv2_pa_wrapper.h topFrame.h varicode.h all: freedv @@ -40,7 +41,6 @@ freedv: $(OBJS) %.o: %.cpp $(HDRS) Makefile.linux g++ $(CPP_FLAGS) -c $< -o $@ - clean: rm -f *.o fdmdv2 diff --git a/fdmdv2/src/Makefile.win32 b/fdmdv2/src/Makefile.win32 index dbb99974..7735a056 100644 --- a/fdmdv2/src/Makefile.win32 +++ b/fdmdv2/src/Makefile.win32 @@ -28,9 +28,10 @@ fdmdv2_plot_waterfall_linux.o \ fdmdv2_pa_wrapper.o \ dlg_audiooptions.o \ dlg_comports.o \ -dlg_filter.o +dlg_filter.o \ +varicode.o -HDRS = dlg_audiooptions.h dlg_comports.h dlg_filter.h fdmdv2_main.h fdmdv2_defines.h fdmdv2_plot.h fdmdv2_plot_scalar.h fdmdv2_plot_waterfall_linux.h fdmdv2_plot_scatter.h fdmdv2_plot_spectrum.h fdmdv2_pa_wrapper.h topFrame.h dlg_audiooptions.h topFrame.h +HDRS = dlg_audiooptions.h dlg_comports.h dlg_filter.h fdmdv2_main.h fdmdv2_defines.h fdmdv2_plot.h fdmdv2_plot_scalar.h fdmdv2_plot_waterfall_linux.h fdmdv2_plot_scatter.h fdmdv2_plot_spectrum.h fdmdv2_pa_wrapper.h topFrame.h dlg_audiooptions.h topFrame.h varicode.h all: freedv diff --git a/fdmdv2/src/fdmdv2_defines.h b/fdmdv2/src/fdmdv2_defines.h index 00dc1253..7492d19d 100644 --- a/fdmdv2/src/fdmdv2_defines.h +++ b/fdmdv2/src/fdmdv2_defines.h @@ -69,7 +69,9 @@ #define SNRSLOW_BETA 0.5 // time constant for slow SNR for display +// Data #define MAX_TXID 1024 +#define SILENCE_THRESHOLD 100 enum { diff --git a/fdmdv2/src/fdmdv2_main.cpp b/fdmdv2/src/fdmdv2_main.cpp index c8201eb7..74dd90e4 100644 --- a/fdmdv2/src/fdmdv2_main.cpp +++ b/fdmdv2/src/fdmdv2_main.cpp @@ -48,7 +48,10 @@ int g_analog; int g_split; int g_tx; float g_snr; -char g_txid[MAX_TXID]; + +// sending and receiving data +struct FIFO *g_txDataInFifo; +struct VARICODE_DEC g_varicode_dec_states; // tx/rx processing states int g_nRxIn = FDMDV_NOM_SAMPLES_PER_FRAME; @@ -89,12 +92,6 @@ float g_TxFreqOffsetHz; COMP g_TxFreqOffsetPhaseRect; COMP g_TxFreqOffsetFreqRect; -// DRs debug variables, will be cleaned up eventually -int cb_cnt, cb1, cb2; -int mute_mic = 0; -int sc1, sc2; -int g_outfifo2_empty; - // experimental mutex to make sound card callbacks mutually exclusive // TODO: review code and see if we need this any more, as fifos should // now be thread safe @@ -382,6 +379,11 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent) g_tx = 0; g_split = 0; + // data states + + g_txDataInFifo = fifo_create(MAX_TXID*VARICODE_MAX_BITS); + varicode_decode_init(&g_varicode_dec_states); + } //------------------------------------------------------------------------- @@ -733,8 +735,20 @@ void MainFrame::OnTogBtnRxID(wxCommandEvent& event) void MainFrame::OnTogBtnTxID(wxCommandEvent& event) { wxString txid = m_txtCtrlTx->GetValue(); - strncpy(g_txid, (const char*) txid.mb_str(wxConvUTF8), MAX_TXID-1); - printf("MainFrame::OnTogBtnTxID, sending: %s\n", g_txid); + char txid2[MAX_TXID]; + strncpy(txid2, (const char*) txid.mb_str(wxConvUTF8), MAX_TXID-1); + + // varicode encode and write to tx data fifo + + short varicode[MAX_TXID*VARICODE_MAX_BITS]; + int nout = varicode_encode(varicode, txid2, MAX_TXID*VARICODE_MAX_BITS, strlen(txid2)); + printf("tx varicode: "); + for(int i=0; i peak) + peak = input_buf[i]; + } + + // voice/data flag is a spare bit in 1400 bit/s frame that + // codec defines + + data_flag_index = codec2_get_spare_bit_index(c2); + assert(data_flag_index != -1); // not supported for all rates + + // if there is low speech energy and data to send, then send data frame + + if ((peak < SILENCE_THRESHOLD) && fifo_used(g_txDataInFifo)) { + printf("sending data ...\n"); + + // we have to handle the case where we might not have a whole + // frame of data to send, in that case pad with zeros + + for(i=0; i> bit) & 0x1; - bit--; - if (bit < 0) { - bit = 7; - byte++; + //printf("tx data bits: "); + //for(i=0; i> bit) & 0x1; + bit--; + if (bit < 0) { + bit = 7; + byte++; + } + } + assert(byte == BYTES_PER_CODEC_FRAME); + + bits[data_flag_index] = 0; } - assert(byte == BYTES_PER_CODEC_FRAME); /* modulate even and odd frames */ @@ -2070,9 +2165,6 @@ int MainFrame::txCallback( wxMutexLocker lock(g_mutexProtectingCallbackData); - if (cb_cnt) - printf("cb2: already in a callback\n"); - cb_cnt++; if (statusFlags) printf("cb2 statusFlags: 0x%x\n", (int)statusFlags); @@ -2118,8 +2210,6 @@ int MainFrame::txCallback( } } #endif - //printf("end cb2\n"); - cb_cnt--; return paContinue; } diff --git a/fdmdv2/src/varicode.c b/fdmdv2/src/varicode.c index 165f9b33..95ffc8a5 100644 --- a/fdmdv2/src/varicode.c +++ b/fdmdv2/src/varicode.c @@ -30,14 +30,13 @@ #include "varicode.h" #include "varicode_table.h" -#define VARICODE_MAX_BITS (10+2) /* 10 bits for code plus 2 0 bits for inter-character space */ /* output is an unpacked array of bits of maximum size max_out. Note unpacked arrays are a more suitable form for modulator input. */ -int varicode_encode(int varicode_out[], char ascii_in[], int max_out, int n_in) { +int varicode_encode(short varicode_out[], char ascii_in[], int max_out, int n_in) { int n_out, index, n_zeros, v_len; unsigned short byte1, byte2, packed; @@ -83,62 +82,75 @@ int varicode_encode(int varicode_out[], char ascii_in[], int max_out, int n_in) void varicode_decode_init(struct VARICODE_DEC *dec_states) { + dec_states->state = 0; dec_states->n_zeros = 0; dec_states->v_len = 0; dec_states->packed = 0; } -static int decode_one_bit(struct VARICODE_DEC *s, char *single_ascii, int varicode_in) +static int decode_one_bit(struct VARICODE_DEC *s, char *single_ascii, short varicode_in) { int found, i; unsigned short byte1, byte2; - if (varicode_in) { - s->packed |= (0x8000 >> s->v_len); - s->n_zeros = 0; - } - else { - s->n_zeros++; + //printf("decode_one_bit : state: %d varicode_in: %d packed: 0x%x n_zeros: %d\n", + // s->state, varicode_in, s->packed, s->n_zeros); + + if (s->state == 0) { + if (!varicode_in) + return 0; + else + s->state = 1; } - s->v_len++; - found = 0; + if (s->state == 1) { + if (varicode_in) { + s->packed |= (0x8000 >> s->v_len); + s->n_zeros = 0; + } + else { + s->n_zeros++; + } + s->v_len++; + + found = 0; - /* end of character code */ + /* end of character code */ - if (s->n_zeros == 2) { - if (s->v_len) { - byte1 = s->packed >> 8; - byte2 = s->packed & 0xff; + if (s->n_zeros == 2) { + if (s->v_len) { + byte1 = s->packed >> 8; + byte2 = s->packed & 0xff; - /* run thru table but note with bit errors means we might - not actually find a match */ + /* run thru table but note with bit errors means we might + not actually find a match */ - for(i=0; i<128; i++) { - if ((byte1 == varicode_table[2*i]) && (byte2 == varicode_table[2*i+1])) { - found = 1; - *single_ascii = i; + for(i=0; i<128; i++) { + if ((byte1 == varicode_table[2*i]) && (byte2 == varicode_table[2*i+1])) { + found = 1; + *single_ascii = i; + } } } + varicode_decode_init(s); } - varicode_decode_init(s); - } - /* code can run too long if we have a bit error */ + /* code can run too long if we have a bit error */ + + if (s->v_len > VARICODE_MAX_BITS) + varicode_decode_init(s); + } - if (s->v_len > VARICODE_MAX_BITS) - varicode_decode_init(s); - return found; } -int varicode_decode(struct VARICODE_DEC *dec_states, char ascii_out[], int varicode_in[], int max_out, int n_in) { +int varicode_decode(struct VARICODE_DEC *dec_states, char ascii_out[], short varicode_in[], int max_out, int n_in) { int output, n_out; char single_ascii; n_out = 0; - printf("varicode_decode: n_in: %d\n", n_in); + //printf("varicode_decode: n_in: %d\n", n_in); while(n_in && (n_out < max_out)) { output = decode_one_bit(dec_states, &single_ascii, *varicode_in); @@ -157,7 +169,7 @@ int varicode_decode(struct VARICODE_DEC *dec_states, char ascii_out[], int varic #ifdef VARICODE_UNITTEST int main(void) { char *ascii_in; - int *varicode; + short *varicode; int i, n_varicode_bits_out, n_ascii_chars_out, length, half; char *ascii_out; struct VARICODE_DEC dec_states; @@ -165,23 +177,27 @@ int main(void) { length = sizeof(varicode_table)/2; ascii_in = (char*)malloc(length); - varicode = (int*)malloc(VARICODE_MAX_BITS*sizeof(int)*length); + varicode = (short*)malloc(VARICODE_MAX_BITS*sizeof(short)*length); ascii_out = (char*)malloc(length); + // 1. test all Varicode codes ------------------------------------------------------------- + for(i=0; i