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)
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)
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
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)
$(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
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:
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)
@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@
--- /dev/null
+/*---------------------------------------------------------------------------*\
+
+ 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;
+}
--- /dev/null
+/*---------------------------------------------------------------------------*\
+
+ 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;
+}