From: drowe67 Date: Mon, 18 Mar 2013 04:23:58 +0000 (+0000) Subject: new fec modes and interleaver for 1600 X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=53f255bfbf6d5530557062d55dce1a8091708976;p=freetel-svn-tracking.git new fec modes and interleaver for 1600 git-svn-id: https://svn.code.sf.net/p/freetel/code@1210 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/src/Makefile.am b/codec2-dev/src/Makefile.am index 1e856aaf..50370a80 100644 --- a/codec2-dev/src/Makefile.am +++ b/codec2-dev/src/Makefile.am @@ -147,7 +147,7 @@ library_includedir = $(prefix)/include library_include_HEADERS = codec2.h codec2_fdmdv.h codec2_fifo.h bin_PROGRAMS = c2demo c2enc c2dec c2sim fdmdv_get_test_bits fdmdv_mod fdmdv_demod \ -fdmdv_put_test_bits fdmdv_interleave insert_errors fec_enc fec_dec +fdmdv_put_test_bits fdmdv_interleave insert_errors fec_enc fec_dec c2demo_SOURCES = c2demo.c c2demo_LDADD = $(lib_LTLIBRARIES) @@ -190,3 +190,4 @@ fec_enc_LDFLAGS = $(LIBS) fec_dec_SOURCES = fec_dec.c golay23.c fec_dec_LDADD = $(lib_LTLIBRARIES) fec_dec_LDFLAGS = $(LIBS) + diff --git a/codec2-dev/src/fdmdv_interleave.c b/codec2-dev/src/fdmdv_interleave.c index 5e3aa643..beb98ecb 100644 --- a/codec2-dev/src/fdmdv_interleave.c +++ b/codec2-dev/src/fdmdv_interleave.c @@ -36,7 +36,7 @@ #include "codec2_fdmdv.h" -#define MAX_INTERLEAVER 1024 +#define MAX_INTERLEAVER 10000 int main(int argc, char *argv[]) { @@ -97,6 +97,7 @@ int main(int argc, char *argv[]) m = src_bit; fprintf(stderr, "Interleaver size m = %d interleave = %d\n", m, interleave); + assert((m%8) == 0); mpacked = m/8; packed_bits = (char*)malloc(mpacked*sizeof(char)); diff --git a/codec2-dev/src/fec_dec.c b/codec2-dev/src/fec_dec.c index 52912cbc..350b0119 100644 --- a/codec2-dev/src/fec_dec.c +++ b/codec2-dev/src/fec_dec.c @@ -36,6 +36,10 @@ #include #include +#define MODE_1600 0 +#define MODE_1850 1 +#define MODE_2000 2 + int main(int argc, char *argv[]) { void *codec2, *fdmdv; @@ -47,12 +51,12 @@ int main(int argc, char *argv[]) int bits_per_output_frame, bytes_per_output_frame; unsigned char *packed_output_bits; int *unpacked_output_bits; - int mode, Nc, bit, byte; - int i; + int codec2_mode, mode, Nc, bit, byte; + int i,j; int recd_codeword, codeword1, codeword2; if (argc < 3) { - printf("%s InputFromModemWithFECFile OutputToCodec2File\n", argv[0]); + printf("%s InputFromModemWithFECFile OutputToCodec2File [2000|1600]\n", argv[0]); exit(1); } @@ -73,7 +77,28 @@ int main(int argc, char *argv[]) /* input parameters and buffers. Note data is split into two 20ms frames for transmission over modem. */ - Nc = 20; + if ((argc != 4) || (strcmp(argv[3],"2000") == 0)) { + /* 2000 bit/s with FEC */ + mode = MODE_2000; + codec2_mode = CODEC2_MODE_1400; + Nc = 20; + } else if ((strcmp(argv[3],"1850") == 0)) { + /* 1850 bit/s with FEC */ + mode = MODE_1850; + codec2_mode = CODEC2_MODE_1300; + Nc = 20; + } + else if (strcmp(argv[3],"1600") == 0) { + /* 1600 bit/s with FEC (actually 1575 with one spare) */ + mode = MODE_1600; + codec2_mode = CODEC2_MODE_1300; + Nc = 16; + } + else { + fprintf(stderr, "Error in mode: %s. Must be 2000 or 1600\n", argv[3]); + exit(1); + } + fdmdv = fdmdv_create(Nc); bits_per_input_frame = 2*fdmdv_bits_per_frame(fdmdv); @@ -89,20 +114,18 @@ int main(int argc, char *argv[]) Output parameters and buffers. */ - mode = CODEC2_MODE_1400; - codec2 = codec2_create(mode); + codec2 = codec2_create(codec2_mode); bits_per_output_frame = codec2_bits_per_frame(codec2); - bytes_per_output_frame = bits_per_output_frame/8; - assert((bits_per_output_frame % 8) == 0); /* make sure integer number of bytes per frame */ + bytes_per_output_frame = (bits_per_output_frame+7)/8; packed_output_bits = (unsigned char*)malloc(bytes_per_output_frame*sizeof(char)); assert(packed_output_bits != NULL); unpacked_output_bits = (int*)malloc(bits_per_output_frame*sizeof(int)); assert(unpacked_output_bits != NULL); - // fprintf(stderr, "input bits: %d input_bytes: %d output_bits: %d output_bytes: %d\n", - // bits_per_input_frame, bytes_per_input_frame, bits_per_output_frame, bytes_per_output_frame); + fprintf(stderr, "input bits: %d input_bytes: %d output_bits: %d output_bytes: %d\n", + bits_per_input_frame, bytes_per_input_frame, bits_per_output_frame, bytes_per_output_frame); /* main loop */ @@ -121,7 +144,6 @@ int main(int argc, char *argv[]) byte++; } } - assert(byte == bytes_per_input_frame); #ifdef TEST /* Some test bit errors (not comprehesnive) */ @@ -129,47 +151,125 @@ int main(int argc, char *argv[]) unpacked_input_bits[23] = (unpacked_input_bits[23] ^ 1) & 0x1; #endif - /* decode first codeword */ + if (mode == MODE_2000) { + /* decode first codeword */ - recd_codeword = 0; - for(i=0; i<12; i++) { - recd_codeword <<= 1; - recd_codeword |= unpacked_input_bits[i]; - } - for(i=bits_per_output_frame; i> (22-i); - } + for(i=0; i<12; i++) { + unpacked_output_bits[i] = (codeword1 >> (22-i)) & 0x1; + } + + /* decode second codeword */ - /* decode second codeword */ + recd_codeword = 0; + for(i=12; i<24; i++) { + recd_codeword <<= 1; + recd_codeword |= unpacked_input_bits[i]; + } + for(i=bits_per_output_frame+11; i> (22-i)) & 0x1; + } - recd_codeword = 0; - for(i=12; i<24; i++) { - recd_codeword <<= 1; - recd_codeword |= unpacked_input_bits[i]; + /* unprotected bits */ + + for(i=24; i> (22-i)) & 0x1; + } + for(i=8,j=11; i<12; i++,j++) { + unpacked_output_bits[j] = (codeword1 >> (22-i)) & 0x1; + } } - codeword2 = golay23_decode(recd_codeword); - //fprintf(stderr, "received codeword2: 0x%x decoded codeword2: 0x%x\n", recd_codeword, codeword2); - for(i=0; i<12; i++) { - unpacked_output_bits[12+i] = codeword2 >> (22-i); + if (mode == MODE_1850) { + recd_codeword = 0; + for(i=0; i<8; i++) { + recd_codeword <<= 1; + recd_codeword |= unpacked_input_bits[i]; + } + for(i=11; i<15; i++) { + recd_codeword <<= 1; + recd_codeword |= unpacked_input_bits[i]; + } + for(i=bits_per_output_frame; i> (22-i)) & 0x1; + } + for(i=8,j=11; i<12; i++,j++) { + unpacked_output_bits[j] = (codeword1 >> (22-i)) & 0x1; + } + for(i=0,j=16; i<12; i++,j++) { + unpacked_output_bits[j] = (codeword2 >> (22-i)) & 0x1; + } + } - /* unprotected bits */ - - for(i=24; i #include +#define MODE_1600 0 +#define MODE_1850 1 +#define MODE_2000 2 + int main(int argc, char *argv[]) { void *codec2, *fdmdv; @@ -49,12 +53,12 @@ int main(int argc, char *argv[]) int bits_per_output_frame, bytes_per_output_frame; unsigned char *packed_output_bits; int *unpacked_output_bits; - int mode, Nc, bit, byte; + int codec2_mode, mode, Nc, bit, byte; int i,j; int data, codeword1, codeword2; if (argc < 3) { - printf("%s InputFromCodecFile OutputToModemWithFECFile\n", argv[0]); + printf("%s InputFromCodecFile OutputToModemWithFECFile [2000|1850|1600]\n", argv[0]); exit(1); } @@ -72,14 +76,34 @@ int main(int argc, char *argv[]) exit(1); } + if ((argc != 4) || (strcmp(argv[3],"2000") == 0)) { + /* 2000 bit/s with FEC */ + mode = MODE_2000; + codec2_mode = CODEC2_MODE_1400; + Nc = 20; + } else if ((strcmp(argv[3],"1850") == 0)) { + /* 1850 bit/s with FEC */ + mode = MODE_1850; + codec2_mode = CODEC2_MODE_1300; + Nc = 20; + } + else if (strcmp(argv[3],"1600") == 0) { + /* 1600 bit/s with FEC (actually 1575 with one spare) */ + mode = MODE_1600; + codec2_mode = CODEC2_MODE_1300; + Nc = 16; + } + else { + fprintf(stderr, "Error in mode: %s. Must be 2000, 1850, or 1600\n", argv[3]); + exit(1); + } + /* input parameters and buffers */ - mode = CODEC2_MODE_1400; - codec2 = codec2_create(mode); + codec2 = codec2_create(codec2_mode); bits_per_input_frame = codec2_bits_per_frame(codec2); - bytes_per_input_frame = bits_per_input_frame / 8; - assert((bits_per_input_frame % 8) == 0); /* make sure integer number of bytes per frame */ + bytes_per_input_frame = (bits_per_input_frame + 7)/8; packed_input_bits = (unsigned char*)malloc(bytes_per_input_frame*sizeof(char)); assert(packed_input_bits != NULL); @@ -92,20 +116,19 @@ int main(int argc, char *argv[]) bother us here, as fdmdv_mod takes care of that. */ - Nc = 20; fdmdv = fdmdv_create(Nc); bits_per_output_frame = 2*fdmdv_bits_per_frame(fdmdv); - bytes_per_output_frame = bits_per_output_frame/8; - assert((bits_per_output_frame % 8) == 0); /* make sure integer number of bytes per frame */ + bytes_per_output_frame = (bits_per_output_frame+7)/8; packed_output_bits = (unsigned char*)malloc(bytes_per_output_frame*sizeof(char)); assert(packed_output_bits != NULL); unpacked_output_bits = (int*)malloc(bits_per_output_frame*sizeof(int)); assert(unpacked_output_bits != NULL); - //fprintf(stderr, "input bits: %d input_bytes: %d output_bits: %d output_bytes: %d\n", - // bits_per_input_frame, bytes_per_input_frame, bits_per_output_frame, bytes_per_output_frame); + fprintf(stderr, "mode: %d Nc: %d\n", mode, Nc); + fprintf(stderr, "input bits: %d input_bytes: %d output_bits: %d output_bytes: %d\n", + bits_per_input_frame, bytes_per_input_frame, bits_per_output_frame, bytes_per_output_frame); /* main loop */ @@ -124,47 +147,126 @@ int main(int argc, char *argv[]) byte++; } } - assert(byte == bytes_per_input_frame); - /* add FEC ----------------------------------*/ + /* add FEC ---------------------------------------------------------*/ - /* Protect first 24 bits with (23,12) Golay Code. The first - 24 bits are the most sensitive, as they contain the - pitch/energy VQ and voicing bits. This uses 56 + 11 + 11 = - 78 bits, so we have two spare in 80 bit frame sent to - modem. */ + if (mode == MODE_2000) { + /* Protect first 24 bits with (23,12) Golay Code. The first + 24 bits are the most sensitive, as they contain the + pitch/energy VQ and voicing bits. This uses 56 + 11 + 11 = + 78 bits, so we have two spare in 80 bit frame sent to + modem. */ - /* first codeword */ + /* first codeword */ - data = 0; - for(i=0; i<12; i++) { - data <<= 1; - data |= unpacked_input_bits[i]; - } - codeword1 = golay23_encode(data); - //fprintf(stderr, "data1: 0x%x codeword1: 0x%x\n", data, codeword1); + data = 0; + for(i=0; i<12; i++) { + data <<= 1; + data |= unpacked_input_bits[i]; + } + codeword1 = golay23_encode(data); + //fprintf(stderr, "data1: 0x%x codeword1: 0x%x\n", data, codeword1); - /* second codeword */ + /* second codeword */ - data = 0; - for(i=12; i<24; i++) { - data <<= 1; - data |= unpacked_input_bits[i]; + data = 0; + for(i=12; i<24; i++) { + data <<= 1; + data |= unpacked_input_bits[i]; + } + codeword2 = golay23_encode(data); + //fprintf(stderr, "data: 0x%x codeword2: 0x%x\n", data, codeword2); + + /* now pack output frame with parity bits at end to make them + as far apart as possible from the data the protect. Parity + bits are LSB of the Golay codeword */ + + for(i=0; i> (10-j)) & 0x1; + } + for(j=0; i> (10-j)) & 0x1; + } } - codeword2 = golay23_encode(data); - //fprintf(stderr, "data: 0x%x codeword2: 0x%x\n", data, codeword2); - /* now pack output frame with parity bits at end to make them - as far apart as possible from the data the protect. Parity - bits are LSB of the Golay codeword */ + if (mode == MODE_1850) { - for(i=0; i> (10-j)) & 0x1; + /* Protect first 12 out of first 16 excitation bits with (23,12) Golay Code: + + 0,1,2,3: v[0]..v[1] + 4,5,6,7: MSB of pitch + 11,12,13,14: MSB of energy + + */ + + data = 0; + for(i=0; i<8; i++) { + data <<= 1; + data |= unpacked_input_bits[i]; + } + for(i=11; i<15; i++) { + data <<= 1; + data |= unpacked_input_bits[i]; + } + codeword1 = golay23_encode(data); + + /* Protect first 12 LSP bits with (23,12) Golay Code */ + + data = 0; + for(i=16; i<28; i++) { + data <<= 1; + data |= unpacked_input_bits[i]; + } + codeword2 = golay23_encode(data); + fprintf(stderr, "codeword2: 0x0%x\n", codeword2); + + /* now pack output frame with parity bits at end to make them + as far apart as possible from the data they protect. Parity + bits are LSB of the Golay codeword */ + + for(i=0; i> (10-j)) & 0x1; + unpacked_output_bits[i+11] = (codeword2 >> (10-j)) & 0x1; + } + for(i=bits_per_input_frame+11+11; i> (10-j)) & 0x1; + + if (mode == MODE_1600) { + + /* Protect first 12 out of first 16 excitation bits with (23,12) Golay Code: + + 0,1,2,3: v[0]..v[1] + 4,5,6,7: MSB of pitch + 11,12,13,14: MSB of energy + + */ + + + data = 0; + for(i=0; i<8; i++) { + data <<= 1; + data |= unpacked_input_bits[i]; + } + for(i=11; i<15; i++) { + data <<= 1; + data |= unpacked_input_bits[i]; + } + codeword1 = golay23_encode(data); + + /* now pack output frame with parity bits at end to make them + as far apart as possible from the data they protect. Parity + bits are LSB of the Golay codeword */ + + for(i=0; i> (10-j)) & 0x1; + } } /* pack bits, MSB first */ diff --git a/codec2-dev/src/golay23.c b/codec2-dev/src/golay23.c index da681b93..e325786a 100644 --- a/codec2-dev/src/golay23.c +++ b/codec2-dev/src/golay23.c @@ -263,6 +263,7 @@ int golay23_encode(int data) { int golay23_decode(int received_codeword) { assert(inited); + //printf("syndrome: 0x%x\n", get_syndrome(received_codeword)); return received_codeword ^= decoding_table[get_syndrome(received_codeword)]; } diff --git a/codec2-dev/src/insert_errors.c b/codec2-dev/src/insert_errors.c index 1d51db81..2a1877b1 100644 --- a/codec2-dev/src/insert_errors.c +++ b/codec2-dev/src/insert_errors.c @@ -36,11 +36,6 @@ #include #include -// This just assumes 1400 bit/s mode for now - -#define BITS_PER_FRAME 56 -#define BYTES_PER_FRAME 7 - int main(int argc, char *argv[]) { FILE *fin; @@ -50,9 +45,11 @@ int main(int argc, char *argv[]) unsigned char byte; short error; int errors, bits; + int bits_per_frame, bytes_per_frame; - if (argc < 3) { - printf("%s InputBitFile OutputBitFile ErrorFile [startBit endBit]\n", argv[0]); + if (argc < 4) { + printf("%s InputBitFile OutputBitFile ErrorFile bitsPerFrame [startBit endBit]\n", argv[0]); + printf("%s InputBitFile OutputBitFile BER\n", argv[0]); exit(1); } @@ -76,10 +73,14 @@ int main(int argc, char *argv[]) exit(1); } - start_bit = 0; end_bit = BITS_PER_FRAME; - if (argc == 6) { - start_bit = atoi(argv[4]); - end_bit = atoi(argv[5]); + bits_per_frame = atoi(argv[4]); + assert((bits_per_frame % 8) == 0); + bytes_per_frame = bits_per_frame/8; + + start_bit = 0; end_bit = bits_per_frame; + if (argc == 7) { + start_bit = atoi(argv[5]); + end_bit = atoi(argv[6]); } bit = 0; @@ -102,10 +103,13 @@ int main(int argc, char *argv[]) exit(0); } bit++; - if (bit == BITS_PER_FRAME) + if (bit == bits_per_frame) bit = 0; } fwrite(&byte, sizeof(char), 1, fout); + if (fout == stdout) fflush(stdout); + if (fin == stdin) fflush(stdin); + } fclose(fin);