From 5e5d26ed9717ada1b371eb9193979415a8b83036 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Sun, 1 Jun 2014 05:55:23 +0000 Subject: [PATCH] refactored varicode impl and api, freedv links with it ok, need to hook up option for new code 2 variant git-svn-id: https://svn.code.sf.net/p/freetel/code@1622 01035d8c-6547-0410-b346-abe4f91aad63 --- fdmdv2/src/fdmdv2_main.cpp | 4 +- fdmdv2/src/varicode.c | 359 ++++++++++++++++++++++-------------- fdmdv2/src/varicode.h | 7 +- fdmdv2/src/varicode_table.h | 7 +- 4 files changed, 235 insertions(+), 142 deletions(-) diff --git a/fdmdv2/src/fdmdv2_main.cpp b/fdmdv2/src/fdmdv2_main.cpp index e85ba276..bca6bcad 100644 --- a/fdmdv2/src/fdmdv2_main.cpp +++ b/fdmdv2/src/fdmdv2_main.cpp @@ -450,7 +450,7 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent) // data states g_txDataInFifo = fifo_create(MAX_CALLSIGN*VARICODE_MAX_BITS); g_rxDataOutFifo = fifo_create(MAX_CALLSIGN*VARICODE_MAX_BITS); - varicode_decode_init(&g_varicode_dec_states); + varicode_decode_init(&g_varicode_dec_states, 1); sox_biquad_start(); golay23_init(); @@ -898,7 +898,7 @@ void MainFrame::OnTimer(wxTimerEvent &evt) // varicode encode and write to tx data fifo short varicode[MAX_CALLSIGN*VARICODE_MAX_BITS]; - int nout = varicode_encode(varicode, callsigncr, MAX_CALLSIGN*VARICODE_MAX_BITS, strlen(callsign)+1); + int nout = varicode_encode(varicode, callsigncr, MAX_CALLSIGN*VARICODE_MAX_BITS, strlen(callsign)+1, 1); fifo_write(g_txDataInFifo, varicode, nout); //printf("Callsign sending: %s nout: %d\n", callsign, nout); } diff --git a/fdmdv2/src/varicode.c b/fdmdv2/src/varicode.c index c7b6d676..9bfb5dca 100644 --- a/fdmdv2/src/varicode.c +++ b/fdmdv2/src/varicode.c @@ -36,36 +36,73 @@ output is an unpacked array of bits of maximum size max_out. Note unpacked arrays are a more suitable form for modulator input. - longcode == 1 varicode table that covers entire ASCII char set - longcode == 0 is the short, more efficient table, which covers a subset of the ASCII char set. Unknown - chars are replaced with spaces. This mode works with two bits at a time. + Code 1 covers the entire ASCII char set. */ -int varicode_encode(short varicode_out[], char ascii_in[], int max_out, int n_in, int long_code) { - int n_out, index, n_zeros, v_len, i; +int varicode_encode1(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; n_out = 0; while(n_in && (n_out < max_out)) { - if (long_code) { - assert((unsigned int)(*ascii_in) < 128); + assert((unsigned int)(*ascii_in) < 128); - index = 2*(unsigned int)(*ascii_in); - byte1 = long_varicode_table[index]; - byte2 = long_varicode_table[index+1]; - packed = (byte1 << 8) + byte2; + index = 2*(unsigned int)(*ascii_in); + byte1 = varicode_table1[index]; + byte2 = varicode_table1[index+1]; + packed = (byte1 << 8) + byte2; + + //printf("n_in: %d ascii_in: %c index: %d packed 0x%x\n", n_in, *ascii_in, index, packed); + ascii_in++; + + n_zeros = 0; + v_len = 0; + while ((n_zeros < 2) && (n_out < max_out) && (v_len <= VARICODE_MAX_BITS)) { + if (packed & 0x8000) { + *varicode_out = 1; + n_zeros = 0; + } + else { + *varicode_out = 0; + n_zeros++; + } + //printf("packed: 0x%x *varicode_out: %d n_zeros: %d v_len: %d\n", packed, *varicode_out, n_zeros,v_len ); + packed <<= 1; + varicode_out++; + n_out++; + v_len++; } - else { + assert(v_len <= VARICODE_MAX_BITS); + + n_in--; + } + + return n_out; +} + + +/* + Code 2 covers a subset, but is more efficient that Code 1 (282 + compared to 1315 bits on unittest) Unsupported characters are + replaced by spaces. We encode/decode two bits at a time. +*/ - packed = short_varicode_table[0]; // default to space if char not found +int varicode_encode2(short varicode_out[], char ascii_in[], int max_out, int n_in) { + int n_out, n_zeros, v_len, i; + unsigned short packed; + + n_out = 0; + + while(n_in && (n_out < max_out)) { + + packed = varicode_table2[0]; // default to space if char not found - // see if our character exists - for(i=0; istate = 0; dec_states->n_zeros = 0; dec_states->v_len = 0; dec_states->packed = 0; + dec_states->code_num = code_num; } -static int decode_one_bit(struct VARICODE_DEC *s, char *single_ascii, short varicode_in1, short varicode_in2, int long_code) + +/* Code 1 decode function, accepts one bit at a time */ + +static int decode_one_bit(struct VARICODE_DEC *s, char *single_ascii, short varicode_in, int long_code) { int found, i; unsigned short byte1, byte2; @@ -138,45 +177,21 @@ static int decode_one_bit(struct VARICODE_DEC *s, char *single_ascii, short vari // s->state, varicode_in, s->packed, s->n_zeros); if (s->state == 0) { - if (long_code) { - if (!varicode_in1) - return 0; - else - s->state = 1; - } - else { - if (!(varicode_in1 || varicode_in2)) - return 0; - else - s->state = 1; - } - + if (!varicode_in) + return 0; + else + s->state = 1; } if (s->state == 1) { - if (long_code) { - if (varicode_in1) { - s->packed |= (0x8000 >> s->v_len); - s->n_zeros = 0; - } - else { - s->n_zeros++; - } - s->v_len++; + if (varicode_in) { + s->packed |= (0x8000 >> s->v_len); + s->n_zeros = 0; } else { - if (varicode_in1) - s->packed |= (0x8000 >> s->v_len); - if (varicode_in2) - s->packed |= (0x4000 >> s->v_len); - if (varicode_in1 || varicode_in2) - s->n_zeros = 0; - else - s->n_zeros+=2; - - s->v_len+=2; + s->n_zeros++; } - + s->v_len++; found = 0; /* end of character code */ @@ -187,41 +202,90 @@ static int decode_one_bit(struct VARICODE_DEC *s, char *single_ascii, short vari byte1 = s->packed >> 8; //printf("looking for byte1 : 0x%x ... ", byte1); - if (long_code) { - byte2 = s->packed & 0xff; - - for(i=0; i<128; i++) { - if ((byte1 == long_varicode_table[2*i]) && (byte2 == long_varicode_table[2*i+1])) { - found = 1; - *single_ascii = i; - } + byte2 = s->packed & 0xff; + + for(i=0; i<128; i++) { + if ((byte1 == varicode_table1[2*i]) && (byte2 == varicode_table1[2*i+1])) { + found = 1; + *single_ascii = i; } } - else { - for(i=0; icode_num); + } + + /* code can run too long if we have a bit error */ + + if (s->v_len > VARICODE_MAX_BITS) + varicode_decode_init(s, s->code_num); + } + + return found; +} + + +/* Code 2 decode function, accepts two bits at a time */ + +static int decode_two_bits(struct VARICODE_DEC *s, char *single_ascii, short varicode_in1, short varicode_in2) +{ + int found, i; + unsigned short byte1; + + //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_in1 || varicode_in2)) + return 0; + else + s->state = 1; + } + + if (s->state == 1) { + if (varicode_in1) + s->packed |= (0x8000 >> s->v_len); + if (varicode_in2) + s->packed |= (0x4000 >> s->v_len); + if (varicode_in1 || varicode_in2) + s->n_zeros = 0; + else + s->n_zeros+=2; + + s->v_len+=2; + + found = 0; + + /* end of character code */ + + if (s->n_zeros == 2) { + if (s->v_len) { + /* run thru table but note with bit errors we might not actually find a match */ + + byte1 = s->packed >> 8; + //printf("looking for byte1 : 0x%x ... ", byte1); + for(i=0; icode_num); } /* code can run too long if we have a bit error */ if (s->v_len > VARICODE_MAX_BITS) - varicode_decode_init(s); + varicode_decode_init(s, s->code_num); } return found; } -int varicode_decode(struct VARICODE_DEC *dec_states, char ascii_out[], short varicode_in[], int max_out, int n_in, int long_code) { + +int varicode_decode1(struct VARICODE_DEC *dec_states, char ascii_out[], short varicode_in[], int max_out, int n_in) { int output, n_out; char single_ascii; @@ -230,16 +294,9 @@ int varicode_decode(struct VARICODE_DEC *dec_states, char ascii_out[], short var //printf("varicode_decode: n_in: %d\n", n_in); while(n_in && (n_out < max_out)) { - if (long_code) { - output = decode_one_bit(dec_states, &single_ascii, varicode_in[0], 0, long_code); - varicode_in++; - n_in--; - } - else { - output = decode_one_bit(dec_states, &single_ascii, varicode_in[0], varicode_in[1], long_code); - varicode_in +=2; - n_in -= 2; - } + output = decode_one_bit(dec_states, &single_ascii, varicode_in[0], 0); + varicode_in++; + n_in--; if (output) { *ascii_out++ = single_ascii; @@ -251,21 +308,53 @@ int varicode_decode(struct VARICODE_DEC *dec_states, char ascii_out[], short var } +int varicode_decode2(struct VARICODE_DEC *dec_states, char ascii_out[], short varicode_in[], int max_out, int n_in) { + int output, n_out; + char single_ascii; + + //assert((n_in % 2) == 0); /* code always processes two bits at a time */ + n_out = 0; + + //printf("varicode_decode: n_in: %d\n", n_in); + + while(n_in && (n_out < max_out)) { + output = decode_two_bits(dec_states, &single_ascii, varicode_in[0], varicode_in[1]); + varicode_in +=2; + n_in -= 2; + + if (output) { + *ascii_out++ = single_ascii; + n_out++; + } + } + + return n_out; +} + + +int varicode_decode(struct VARICODE_DEC *dec_states, char ascii_out[], short varicode_in[], int max_out, int n_in) { + if (dec_states->code_num == 1) + return varicode_decode1(dec_states, ascii_out, varicode_in, max_out, n_in); + else + return varicode_decode2(dec_states, ascii_out, varicode_in, max_out, n_in); +} + + #ifdef VARICODE_UNITTEST -void test_varicode(int long_code) { +void test_varicode(int code_num) { char *ascii_in; short *varicode; int i, n_varicode_bits_out, n_ascii_chars_out, length, half; char *ascii_out; struct VARICODE_DEC dec_states; - if (long_code) { + if (code_num == 1) { printf("long code:\n"); - length = sizeof(long_varicode_table)/2; + length = sizeof(varicode_table1)/2; } else { printf("short code:\n"); - length = sizeof(short_varicode_table)/2; + length = sizeof(varicode_table2)/2; } //length = 10; ascii_in = (char*)malloc(length); @@ -274,31 +363,31 @@ void test_varicode(int long_code) { // 1. test all Varicode codes ------------------------------------------------------------- - if (long_code) { + if (code_num == 1) { for(i=0; i