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)
fec_dec_SOURCES = fec_dec.c golay23.c
fec_dec_LDADD = $(lib_LTLIBRARIES)
fec_dec_LDFLAGS = $(LIBS)
+
#include "codec2_fdmdv.h"
-#define MAX_INTERLEAVER 1024
+#define MAX_INTERLEAVER 10000
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));
#include <string.h>
#include <errno.h>
+#define MODE_1600 0
+#define MODE_1850 1
+#define MODE_2000 2
+
int main(int argc, char *argv[])
{
void *codec2, *fdmdv;
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);
}
/* 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);
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 */
byte++;
}
}
- assert(byte == bytes_per_input_frame);
#ifdef TEST
/* Some test bit errors (not comprehesnive) */
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<bits_per_output_frame+11; i++) {
- recd_codeword <<= 1;
- recd_codeword |= unpacked_input_bits[i];
- }
- codeword1 = golay23_decode(recd_codeword);
- //fprintf(stderr, "received codeword1: 0x%x decoded codeword1: 0x%x\n", recd_codeword, codeword1);
+ 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<bits_per_output_frame+11; i++) {
+ recd_codeword <<= 1;
+ recd_codeword |= unpacked_input_bits[i];
+ }
+ codeword1 = golay23_decode(recd_codeword);
+ //codeword1 = recd_codeword;
+ //fprintf(stderr, "received codeword1: 0x%x decoded codeword1: 0x%x\n", recd_codeword, codeword1);
- for(i=0; i<12; i++) {
- unpacked_output_bits[i] = codeword1 >> (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<bits_per_output_frame+11+11; i++) {
+ recd_codeword <<= 1;
+ recd_codeword |= unpacked_input_bits[i];
+ }
+ codeword2 = golay23_decode(recd_codeword);
+ //codeword2 = 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)) & 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<bits_per_output_frame; i++)
+ unpacked_output_bits[i] = unpacked_input_bits[i];
}
- for(i=bits_per_output_frame+11; i<bits_per_output_frame+11+11; i++) {
- recd_codeword <<= 1;
- recd_codeword |= unpacked_input_bits[i];
+
+ if (mode == MODE_1600) {
+ 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<bits_per_output_frame+11; i++) {
+ recd_codeword <<= 1;
+ recd_codeword |= unpacked_input_bits[i];
+ }
+ codeword1 = golay23_decode(recd_codeword);
+ //codeword1 = recd_codeword;
+ //fprintf(stderr, "received codeword1: 0x%x decoded codeword1: 0x%x\n", recd_codeword, codeword1);
+
+ for(i=0; i<bits_per_output_frame; i++)
+ unpacked_output_bits[i] = unpacked_input_bits[i];
+
+ for(i=0; i<8; i++) {
+ unpacked_output_bits[i] = (codeword1 >> (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<bits_per_output_frame+11; i++) {
+ recd_codeword <<= 1;
+ recd_codeword |= unpacked_input_bits[i];
+ }
+ codeword1 = golay23_decode(recd_codeword);
+ //codeword1 = recd_codeword;
+ //fprintf(stderr, "received codeword1: 0x%x decoded codeword1: 0x%x\n", recd_codeword, codeword1);
+
+ recd_codeword = 0;
+ for(i=16; i<28; i++) {
+ recd_codeword <<= 1;
+ recd_codeword |= unpacked_input_bits[i];
+ }
+ for(i=bits_per_output_frame+11; i<bits_per_output_frame+11+11; i++) {
+ recd_codeword <<= 1;
+ recd_codeword |= unpacked_input_bits[i];
+ }
+ codeword2 = golay23_decode(recd_codeword);
+ fprintf(stderr, "received codeword2: 0x%x decoded codeword2: 0x%x\n", recd_codeword, codeword2);
+
+ for(i=0; i<bits_per_output_frame; i++)
+ unpacked_output_bits[i] = unpacked_input_bits[i];
+
+ for(i=0; i<8; i++) {
+ unpacked_output_bits[i] = (codeword1 >> (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<bits_per_output_frame; i++)
- unpacked_output_bits[i] = unpacked_input_bits[i];
-
/* pack bits, MSB first */
bit = 7; byte = 0;
byte++;
}
}
- assert(byte == bytes_per_output_frame);
fwrite(packed_output_bits, sizeof(char), bytes_per_output_frame, fout);
#include <string.h>
#include <errno.h>
+#define MODE_1600 0
+#define MODE_1850 1
+#define MODE_2000 2
+
int main(int argc, char *argv[])
{
void *codec2, *fdmdv;
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);
}
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);
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 */
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<bits_per_input_frame; i++)
+ unpacked_output_bits[i] = unpacked_input_bits[i];
+ for(j=0; i<bits_per_input_frame+11; i++,j++) {
+ unpacked_output_bits[i] = (codeword1 >> (10-j)) & 0x1;
+ }
+ for(j=0; i<bits_per_input_frame+11+11; i++,j++) {
+ unpacked_output_bits[i] = (codeword2 >> (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<bits_per_input_frame; i++)
- unpacked_output_bits[i] = unpacked_input_bits[i];
- for(j=0; i<bits_per_input_frame+11; i++,j++) {
- unpacked_output_bits[i] = (codeword1 >> (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<bits_per_input_frame; i++)
+ unpacked_output_bits[i] = unpacked_input_bits[i];
+ for(j=0; i<bits_per_input_frame+11; i++,j++) {
+ unpacked_output_bits[i] = (codeword1 >> (10-j)) & 0x1;
+ unpacked_output_bits[i+11] = (codeword2 >> (10-j)) & 0x1;
+ }
+ for(i=bits_per_input_frame+11+11; i<bits_per_output_frame; i++)
+ unpacked_output_bits[i] = 0;
}
- for(j=0; i<bits_per_input_frame+11+11; i++,j++) {
- unpacked_output_bits[i] = (codeword2 >> (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<bits_per_input_frame; i++)
+ unpacked_output_bits[i] = unpacked_input_bits[i];
+ for(j=0; i<bits_per_input_frame+11; i++,j++) {
+ unpacked_output_bits[i] = (codeword1 >> (10-j)) & 0x1;
+ }
}
/* pack bits, MSB first */
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)];
}
#include <string.h>
#include <errno.h>
-// 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;
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);
}
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;
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);