initial version of dec enc and dec working, just passing through data at this stage
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 4 Mar 2013 04:37:51 +0000 (04:37 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 4 Mar 2013 04:37:51 +0000 (04:37 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1187 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/src/Makefile.am
codec2-dev/src/Makefile.in
codec2-dev/src/fec_dec.c [new file with mode: 0644]
codec2-dev/src/fec_enc.c [new file with mode: 0644]

index 11799026ddc1029eb6fe8f1d6483f82ecd9f8a7d..80f77a9c10dfcaec03b6ec6af8d78aca2c11e9ce 100644 (file)
@@ -146,7 +146,8 @@ libcodec2_la_LDFLAGS = $(LIBS)
 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
+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
 
 c2demo_SOURCES = c2demo.c
 c2demo_LDADD = $(lib_LTLIBRARIES) 
@@ -182,3 +183,10 @@ fdmdv_interleave_LDFLAGS = $(LIBS)
 insert_errors_SOURCES =  insert_errors.c
 insert_errors_LDFLAGS = $(LIBS)
 
+fec_enc_SOURCES =  fec_enc.c
+fec_enc_LDADD = $(lib_LTLIBRARIES) 
+fec_enc_LDFLAGS = $(LIBS)
+
+fec_dec_SOURCES =  fec_dec.c
+fec_dec_LDADD = $(lib_LTLIBRARIES) 
+fec_dec_LDFLAGS = $(LIBS)
index 1ac003c33f7d485d076897dd4bdc5b648eb1e115..3cd9ace634c62835e7534a79ec0b66095552cc48 100644 (file)
@@ -42,7 +42,8 @@ noinst_PROGRAMS = generate_codebook$(EXEEXT) genlspdtcb$(EXEEXT)
 bin_PROGRAMS = c2demo$(EXEEXT) c2enc$(EXEEXT) c2dec$(EXEEXT) \
        c2sim$(EXEEXT) fdmdv_get_test_bits$(EXEEXT) fdmdv_mod$(EXEEXT) \
        fdmdv_demod$(EXEEXT) fdmdv_put_test_bits$(EXEEXT) \
-       fdmdv_interleave$(EXEEXT) insert_errors$(EXEEXT)
+       fdmdv_interleave$(EXEEXT) insert_errors$(EXEEXT) \
+       fec_enc$(EXEEXT) fec_dec$(EXEEXT)
 subdir = src
 DIST_COMMON = $(library_include_HEADERS) $(srcdir)/Makefile.am \
        $(srcdir)/Makefile.in
@@ -109,6 +110,12 @@ am_fdmdv_put_test_bits_OBJECTS = fdmdv_put_test_bits.$(OBJEXT) \
        fdmdv.$(OBJEXT) kiss_fft.$(OBJEXT)
 fdmdv_put_test_bits_OBJECTS = $(am_fdmdv_put_test_bits_OBJECTS)
 fdmdv_put_test_bits_LDADD = $(LDADD)
+am_fec_dec_OBJECTS = fec_dec.$(OBJEXT)
+fec_dec_OBJECTS = $(am_fec_dec_OBJECTS)
+fec_dec_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_fec_enc_OBJECTS = fec_enc.$(OBJEXT)
+fec_enc_OBJECTS = $(am_fec_enc_OBJECTS)
+fec_enc_DEPENDENCIES = $(am__DEPENDENCIES_1)
 generate_codebook_SOURCES = generate_codebook.c
 generate_codebook_OBJECTS = generate_codebook.$(OBJEXT)
 generate_codebook_LDADD = $(LDADD)
@@ -133,13 +140,15 @@ SOURCES = $(libcodec2_la_SOURCES) $(c2dec_SOURCES) $(c2demo_SOURCES) \
        $(c2enc_SOURCES) $(c2sim_SOURCES) $(fdmdv_demod_SOURCES) \
        $(fdmdv_get_test_bits_SOURCES) $(fdmdv_interleave_SOURCES) \
        $(fdmdv_mod_SOURCES) $(fdmdv_put_test_bits_SOURCES) \
-       generate_codebook.c genlspdtcb.c $(insert_errors_SOURCES)
+       $(fec_dec_SOURCES) $(fec_enc_SOURCES) generate_codebook.c \
+       genlspdtcb.c $(insert_errors_SOURCES)
 DIST_SOURCES = $(libcodec2_la_SOURCES) $(c2dec_SOURCES) \
        $(c2demo_SOURCES) $(c2enc_SOURCES) $(c2sim_SOURCES) \
        $(fdmdv_demod_SOURCES) $(fdmdv_get_test_bits_SOURCES) \
        $(fdmdv_interleave_SOURCES) $(fdmdv_mod_SOURCES) \
-       $(fdmdv_put_test_bits_SOURCES) generate_codebook.c \
-       genlspdtcb.c $(insert_errors_SOURCES)
+       $(fdmdv_put_test_bits_SOURCES) $(fec_dec_SOURCES) \
+       $(fec_enc_SOURCES) generate_codebook.c genlspdtcb.c \
+       $(insert_errors_SOURCES)
 library_includeHEADERS_INSTALL = $(INSTALL_HEADER)
 HEADERS = $(library_include_HEADERS)
 ETAGS = etags
@@ -376,6 +385,12 @@ fdmdv_interleave_SOURCES = fdmdv_interleave.c
 fdmdv_interleave_LDFLAGS = $(LIBS)
 insert_errors_SOURCES = insert_errors.c
 insert_errors_LDFLAGS = $(LIBS)
+fec_enc_SOURCES = fec_enc.c
+fec_enc_LDADD = $(lib_LTLIBRARIES) 
+fec_enc_LDFLAGS = $(LIBS)
+fec_dec_SOURCES = fec_dec.c
+fec_dec_LDADD = $(lib_LTLIBRARIES) 
+fec_dec_LDFLAGS = $(LIBS)
 all: all-am
 
 .SUFFIXES:
@@ -500,6 +515,12 @@ fdmdv_mod$(EXEEXT): $(fdmdv_mod_OBJECTS) $(fdmdv_mod_DEPENDENCIES)
 fdmdv_put_test_bits$(EXEEXT): $(fdmdv_put_test_bits_OBJECTS) $(fdmdv_put_test_bits_DEPENDENCIES) 
        @rm -f fdmdv_put_test_bits$(EXEEXT)
        $(LINK) $(fdmdv_put_test_bits_LDFLAGS) $(fdmdv_put_test_bits_OBJECTS) $(fdmdv_put_test_bits_LDADD) $(LIBS)
+fec_dec$(EXEEXT): $(fec_dec_OBJECTS) $(fec_dec_DEPENDENCIES) 
+       @rm -f fec_dec$(EXEEXT)
+       $(LINK) $(fec_dec_LDFLAGS) $(fec_dec_OBJECTS) $(fec_dec_LDADD) $(LIBS)
+fec_enc$(EXEEXT): $(fec_enc_OBJECTS) $(fec_enc_DEPENDENCIES) 
+       @rm -f fec_enc$(EXEEXT)
+       $(LINK) $(fec_enc_LDFLAGS) $(fec_enc_OBJECTS) $(fec_enc_LDADD) $(LIBS)
 generate_codebook$(EXEEXT): $(generate_codebook_OBJECTS) $(generate_codebook_DEPENDENCIES) 
        @rm -f generate_codebook$(EXEEXT)
        $(LINK) $(generate_codebook_LDFLAGS) $(generate_codebook_OBJECTS) $(generate_codebook_LDADD) $(LIBS)
@@ -527,6 +548,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdmdv_interleave.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdmdv_mod.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdmdv_put_test_bits.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fec_dec.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fec_enc.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generate_codebook.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genlspdtcb.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/insert_errors.Po@am__quote@
diff --git a/codec2-dev/src/fec_dec.c b/codec2-dev/src/fec_dec.c
new file mode 100644 (file)
index 0000000..86c5b3d
--- /dev/null
@@ -0,0 +1,160 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fec_dec.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 4 march 2013
+
+  FEC decoder for data from modem containing compressed Codec 2 data
+  and FEC.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "codec2.h"
+#include "codec2_fdmdv.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+int main(int argc, char *argv[])
+{
+    void          *codec2, *fdmdv;
+    FILE          *fin;
+    FILE          *fout;
+    int            bits_per_input_frame, bytes_per_input_frame;
+    unsigned char *packed_input_bits;
+    int           *unpacked_input_bits;
+    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;
+
+    if (argc < 3) {
+       printf("%s InputFromModemWithFECFile OutputToCodec2File\n", argv[0]);
+       exit(1);
+    }
+
+    if (strcmp(argv[1], "-")  == 0) fin = stdin;
+    else if ( (fin = fopen(argv[1],"rb")) == NULL ) {
+       fprintf(stderr, "Error opening input file from Demod: %s: %s.\n",
+         argv[2], strerror(errno));
+       exit(1);
+    }
+
+    if (strcmp(argv[2], "-") == 0) fout = stdout;
+    else if ( (fout = fopen(argv[2],"wb")) == NULL ) {
+       fprintf(stderr, "Error opening output file to Codec : %s: %s.\n",
+         argv[3], strerror(errno));
+       exit(1);
+    }
+
+    /* input parameters and buffers. Note data is split into two 20ms
+       frames for transmission over modem. */
+
+    Nc = 20;
+    fdmdv = fdmdv_create(Nc);
+
+    bits_per_input_frame = 2*fdmdv_bits_per_frame(fdmdv);
+    bytes_per_input_frame = bits_per_input_frame / 8;
+    assert((bits_per_input_frame % 8) == 0); /* make sure integer number of bytes per frame */
+
+    packed_input_bits = (unsigned char*)malloc(bytes_per_input_frame*sizeof(char));
+    assert(packed_input_bits != NULL);
+    unpacked_input_bits = (int*)malloc(bits_per_input_frame*sizeof(int));
+    assert(unpacked_input_bits != NULL);
+
+    /* 
+       Output parameters and buffers.
+    */
+
+    mode = CODEC2_MODE_1400;
+    codec2 = codec2_create(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 */
+
+    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);
+
+    /* main loop */
+
+    while(fread(packed_input_bits, sizeof(char), bytes_per_input_frame, fin) == (size_t)bytes_per_input_frame) {
+
+       /* unpack bits, MSB first */
+
+       bit = 7; byte = 0;
+       for(i=0; i<bits_per_input_frame; i++) {
+           unpacked_input_bits[i] = (packed_input_bits[byte] >> bit) & 0x1;
+           bit--;
+           if (bit < 0) {
+               bit = 7;
+               byte++;
+           }
+       }
+       assert(byte == bytes_per_input_frame);
+
+        for(i=0; i<bits_per_output_frame; i++)
+            unpacked_output_bits[i] = unpacked_input_bits[i];
+
+        /* pack bits, MSB first  */
+
+        bit = 7; byte = 0;
+        memset(packed_output_bits, 0, bytes_per_output_frame);
+        for(i=0; i<bits_per_output_frame; i++) {
+            packed_output_bits[byte] |= (unpacked_output_bits[i] << bit);
+            bit--;
+            if (bit < 0) {
+                bit = 7;
+                byte++;
+            }
+        }
+        assert(byte == bytes_per_output_frame);
+        
+       fwrite(packed_output_bits, sizeof(char), bytes_per_output_frame, fout);
+
+       /* if this is in a pipeline, we probably don't want the usual
+           buffering to occur */
+
+        if (fout == stdout) fflush(stdout);
+        if (fin == stdin) fflush(stdin);         
+    }
+
+    codec2_destroy(codec2);
+    fdmdv_destroy(fdmdv);
+
+    free(packed_input_bits);
+    free(unpacked_input_bits);
+    free(packed_output_bits);
+    free(unpacked_output_bits);
+
+    fclose(fin);
+    fclose(fout);
+
+    return 0;
+}
diff --git a/codec2-dev/src/fec_enc.c b/codec2-dev/src/fec_enc.c
new file mode 100644 (file)
index 0000000..109ae4e
--- /dev/null
@@ -0,0 +1,165 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fec_enc.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 4 march 2013
+
+  Encodes compressed Codec 2 data using FEC.  This initial version
+  assumes 1400 bit/s Codec 2 input data (56 bit, 40ms frames), with 80
+  bit frame outpout, suitable for 20 carrier, 2000 bit/s modem.  In
+  future other experimental schemes may be supported.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "codec2.h"
+#include "codec2_fdmdv.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+int main(int argc, char *argv[])
+{
+    void          *codec2, *fdmdv;
+    FILE          *fin;
+    FILE          *fout;
+    int            bits_per_input_frame, bytes_per_input_frame;
+    unsigned char *packed_input_bits;
+    int           *unpacked_input_bits;
+    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;
+
+    if (argc < 3) {
+       printf("%s InputFromCodecFile OutputToModemWithFECFile\n", argv[0]);
+       exit(1);
+    }
+
+    if (strcmp(argv[1], "-")  == 0) fin = stdin;
+    else if ( (fin = fopen(argv[1],"rb")) == NULL ) {
+       fprintf(stderr, "Error opening input file from Codec: %s: %s.\n",
+         argv[2], strerror(errno));
+       exit(1);
+    }
+
+    if (strcmp(argv[2], "-") == 0) fout = stdout;
+    else if ( (fout = fopen(argv[2],"wb")) == NULL ) {
+       fprintf(stderr, "Error opening output file : %s: %s.\n",
+         argv[3], strerror(errno));
+       exit(1);
+    }
+
+    /* input parameters and buffers */
+
+    mode = CODEC2_MODE_1400;
+    codec2 = codec2_create(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 */
+
+    packed_input_bits = (unsigned char*)malloc(bytes_per_input_frame*sizeof(char));
+    assert(packed_input_bits != NULL);
+    unpacked_input_bits = (int*)malloc(bits_per_input_frame*sizeof(int));
+    assert(unpacked_input_bits != NULL);
+
+    /* 
+       Output parameters and buffers.  Data is split into two 20ms
+       frames for transmission over modem, but this doesn't really
+       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 */
+
+    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);
+
+    /* main loop */
+
+    while(fread(packed_input_bits, sizeof(char), bytes_per_input_frame, fin) == (size_t)bytes_per_input_frame) {
+
+       /* unpack bits, MSB first */
+
+       bit = 7; byte = 0;
+       for(i=0; i<bits_per_input_frame; i++) {
+           unpacked_input_bits[i] = (packed_input_bits[byte] >> bit) & 0x1;
+           bit--;
+           if (bit < 0) {
+               bit = 7;
+               byte++;
+           }
+       }
+       assert(byte == bytes_per_input_frame);
+
+        for(i=0; i<bits_per_input_frame; i++)
+            unpacked_output_bits[i] = unpacked_input_bits[i];
+        for(i=bits_per_input_frame; i<bits_per_output_frame; i++)
+            unpacked_output_bits[i] = 1;
+
+        /* pack bits, MSB first  */
+
+        bit = 7; byte = 0;
+        memset(packed_output_bits, 0, bytes_per_output_frame);
+        for(i=0; i<bits_per_output_frame; i++) {
+            packed_output_bits[byte] |= (unpacked_output_bits[i] << bit);
+            bit--;
+            if (bit < 0) {
+                bit = 7;
+                byte++;
+            }
+        }
+        assert(byte == bytes_per_output_frame);
+        
+       fwrite(packed_output_bits, sizeof(char), bytes_per_output_frame, fout);
+
+       /* if this is in a pipeline, we probably don't want the usual
+           buffering to occur */
+
+        if (fout == stdout) fflush(stdout);
+        if (fin == stdin) fflush(stdin);         
+    }
+
+    codec2_destroy(codec2);
+    fdmdv_destroy(fdmdv);
+
+    free(packed_input_bits);
+    free(unpacked_input_bits);
+    free(packed_output_bits);
+    free(unpacked_output_bits);
+
+    fclose(fin);
+    fclose(fout);
+
+    return 0;
+}