progressing C versions of coh psk modem and associated tools
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 7 Apr 2015 01:10:08 +0000 (01:10 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 7 Apr 2015 01:10:08 +0000 (01:10 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@2104 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/src/CMakeLists.txt
codec2-dev/src/codec2_cohpsk.h
codec2-dev/src/cohpsk.c
codec2-dev/src/cohpsk_demod.c [new file with mode: 0644]
codec2-dev/src/cohpsk_get_test_bits.c [new file with mode: 0644]
codec2-dev/src/cohpsk_mod.c [new file with mode: 0644]

index 6ea9d755354c4e4488d4546f3d4ee533e86f0194..1cc1cc0b51f424ec939cc26cb66e6fc35863c38b 100644 (file)
@@ -165,6 +165,7 @@ set(CODEC2_SRCS
     postfilter.c
     sine.c
     codec2.c
+    cohpsk.c
     fifo.c
     fdmdv.c
     fm.c
@@ -191,6 +192,7 @@ set(CODEC2_PUBLIC_HEADERS
     golay23.h
     codec2.h
     codec2_fdmdv.h
+    codec2_cohpsk.h
     codec2_fm.h
     codec2_fifo.h
     comp.h
@@ -255,6 +257,15 @@ target_link_libraries(freedv_rx ${CMAKE_REQUIRED_LIBRARIES} codec2)
 add_executable(fm_demod fm_demod.c fm.c)
 target_link_libraries(fm_demod ${CMAKE_REQUIRED_LIBRARIES})
 
+add_executable(cohpsk_mod cohpsk_mod.c)
+target_link_libraries(cohpsk_mod ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(cohpsk_demod cohpsk_demod.c)
+target_link_libraries(cohpsk_demod ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(cohpsk_get_test_bits cohpsk_get_test_bits.c)
+target_link_libraries(cohpsk_get_test_bits ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
 install(TARGETS codec2 EXPORT codec2-config
     LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
     ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
index 8fdad615209d06c063c4b693912704804fe62987..2f94c5319e326775e1c2c154f913e268437a7cc6 100644 (file)
@@ -28,9 +28,9 @@
 #ifndef __CODEC2_COHPSK__
 #define __CODEC2_COHPSK__
 
-#define COHPSK_BITS_PER_FRAME    32               /* hard coded for now */
-#define COHPSK_NC                               /* hard coded for now */
-#define COHPSK_SAMPLES_PER_FRAME (NSYMROWPILOT*M)
+#define COHPSK_BITS_PER_FRAME     32              /* hard coded for now */
+#define COHPSK_NC                  4              /* hard coded for now */
+#define COHPSK_SAMPLES_PER_FRAME 960
 
 #include "comp.h"
 #include "codec2_fdmdv.h"
index 277712f77d35e5696985a73840f0ec53480c4ce0..647d84b5664b2f5f9eeeef5ed6f3d1dfa1f6ccea 100644 (file)
@@ -38,7 +38,6 @@
 #include <math.h>
 
 #include "codec2_cohpsk.h"
-#include "test_bits.h"
 #include "cohpsk_defs.h"
 #include "cohpsk_internal.h"
 #include "fdmdv_internal.h"
@@ -79,6 +78,8 @@ struct COHPSK *cohpsk_create(void)
     int            r,c,p,i;
     float          freq_hz;
 
+    assert(COHPSK_SAMPLES_PER_FRAME == M*NSYMROWPILOT);
+
     coh = (struct COHPSK*)malloc(sizeof(struct COHPSK));
     if (coh == NULL)
         return NULL;
diff --git a/codec2-dev/src/cohpsk_demod.c b/codec2-dev/src/cohpsk_demod.c
new file mode 100644 (file)
index 0000000..b4bbed3
--- /dev/null
@@ -0,0 +1,97 @@
+/*---------------------------------------------------------------------------*\
+                                                                             
+  FILE........: cohpsk_demod.c
+  AUTHOR......: David Rowe  
+  DATE CREATED: April 6 2015
+                                                                             
+  Given an input file of raw file (8kHz, 16 bit shorts) of COHPSK modem samples,
+  outputs a file of bits (note one bit per int, not compressed).
+                                                                             
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 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, 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 <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+
+#include "codec2_cohpsk.h"
+
+int main(int argc, char *argv[])
+{
+    FILE          *fin, *fout;
+    struct COHPSK *cohpsk;
+    int           rx_bits[COHPSK_BITS_PER_FRAME];
+    COMP          rx_fdm[COHPSK_SAMPLES_PER_FRAME];
+    short         rx_fdm_scaled[COHPSK_SAMPLES_PER_FRAME];
+    int           frames, reliable_sync_bit;
+    int           i;
+
+    if (argc < 3) {
+       printf("usage: %s InputModemRawFile OutputOneBitPerIntFile\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 modem sample file: %s: %s.\n",
+         argv[1], 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[2], strerror(errno));
+       exit(1);
+    }
+
+    cohpsk = cohpsk_create();
+
+    frames = 0;
+
+    while(fread(rx_fdm_scaled, sizeof(short), COHPSK_SAMPLES_PER_FRAME, fin) == COHPSK_SAMPLES_PER_FRAME) {
+       frames++;
+
+       /* scale and demod */
+
+       for(i=0; i<COHPSK_SAMPLES_PER_FRAME; i++) {
+           rx_fdm[i].real = rx_fdm_scaled[i]/FDMDV_SCALE;
+            rx_fdm[i].imag = 0.0;
+        }
+
+       cohpsk_demod(cohpsk, rx_bits, &reliable_sync_bit, rx_fdm);
+
+       fwrite(rx_bits, sizeof(int), COHPSK_BITS_PER_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); 
+    }
+
+    fclose(fin);
+    fclose(fout);
+    cohpsk_destroy(cohpsk);
+
+    return 0;
+}
diff --git a/codec2-dev/src/cohpsk_get_test_bits.c b/codec2-dev/src/cohpsk_get_test_bits.c
new file mode 100644 (file)
index 0000000..d54be81
--- /dev/null
@@ -0,0 +1,83 @@
+/*---------------------------------------------------------------------------*\
+                                                                             
+  FILE........: cohpsk_put_test_bits.c
+  AUTHOR......: David Rowe  
+  DATE CREATED: April 2015
+                                                                             
+  Generates a file of test bits, useful for input to cohpsk_mod.
+
+\*---------------------------------------------------------------------------*/
+
+
+/*
+  Copyright (C) 2015 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, 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 <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+
+#include "codec2_cohpsk.h"
+#include "test_bits_coh.h"
+
+int main(int argc, char *argv[])
+{
+    FILE         *fout;
+    int           tx_bits[COHPSK_BITS_PER_FRAME];
+    int           numBits, nFrames, n;
+    int           *ptest_bits_coh, *ptest_bits_coh_end;
+
+    if (argc < 2) {
+       printf("usage: %s OutputOneBitPerIntFile numBits\n", argv[0]);
+       exit(1);
+    }
+
+    if (strcmp(argv[1], "-") == 0) fout = stdout;
+    else if ( (fout = fopen(argv[1],"wb")) == NULL ) {
+       fprintf(stderr, "Error opening output file: %s: %s.\n",
+         argv[1], strerror(errno));
+       exit(1);
+    }
+
+    ptest_bits_coh = (int*)test_bits_coh;
+    ptest_bits_coh_end = (int*)test_bits_coh + sizeof(test_bits_coh)/sizeof(int);
+    numBits = atoi(argv[2]);
+    nFrames = numBits/COHPSK_BITS_PER_FRAME;
+
+    for(n=0; n<nFrames; n++) {
+
+        memcpy(tx_bits, ptest_bits_coh, sizeof(int)*COHPSK_BITS_PER_FRAME);
+        ptest_bits_coh += COHPSK_BITS_PER_FRAME;
+        if (ptest_bits_coh >= ptest_bits_coh_end) {
+            ptest_bits_coh = (int*)test_bits_coh;
+        }
+
+       fwrite(tx_bits, sizeof(int), COHPSK_BITS_PER_FRAME, fout);
+       /* if this is in a pipeline, we probably don't want the usual
+          buffering to occur */
+
+        if (fout == stdout) fflush(stdout);
+    }
+
+    fclose(fout);
+
+    return 0;
+}
+
diff --git a/codec2-dev/src/cohpsk_mod.c b/codec2-dev/src/cohpsk_mod.c
new file mode 100644 (file)
index 0000000..2aa054e
--- /dev/null
@@ -0,0 +1,96 @@
+/*---------------------------------------------------------------------------*\
+                                                                             
+  FILE........: cohpsk_mod.c
+  AUTHOR......: David Rowe  
+  DATE CREATED: April 5 2015
+                                                                             
+  Given an input file of bits (note one bit per int, not compressed),
+  outputs a raw file (8kHz, 16 bit shorts) of COHPSK modem samples
+  ready to send over a HF radio channel.
+                                                                             
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 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, 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 <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+
+#include "codec2_cohpsk.h"
+
+int main(int argc, char *argv[])
+{
+    FILE          *fin, *fout;
+    struct COHPSK *cohpsk;
+    int           tx_bits[COHPSK_BITS_PER_FRAME];
+    COMP          tx_fdm[COHPSK_SAMPLES_PER_FRAME];
+    short         tx_fdm_scaled[COHPSK_SAMPLES_PER_FRAME];
+    int           frames;
+    int           i;
+
+    if (argc < 3) {
+       printf("usage: %s InputOneBitPerIntFile OutputModemRawFile\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: %s: %s.\n",
+         argv[1], strerror(errno));
+       exit(1);
+    }
+
+    if (strcmp(argv[2], "-") == 0) fout = stdout;
+    else if ( (fout = fopen(argv[2],"wb")) == NULL ) {
+       fprintf(stderr, "Error opening output modem sample file: %s: %s.\n",
+         argv[2], strerror(errno));
+       exit(1);
+    }
+
+    cohpsk = cohpsk_create();
+
+    frames = 0;
+
+    while(fread(tx_bits, sizeof(int), COHPSK_BITS_PER_FRAME, fin) == COHPSK_BITS_PER_FRAME) {
+       frames++;
+
+       cohpsk_mod(cohpsk, tx_fdm, tx_bits);
+
+       /* scale and save to disk as shorts */
+
+       for(i=0; i<COHPSK_SAMPLES_PER_FRAME; i++)
+           tx_fdm_scaled[i] = FDMDV_SCALE * tx_fdm[i].real;
+
+       fwrite(tx_fdm_scaled, sizeof(short), COHPSK_SAMPLES_PER_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);         
+    }
+
+    fclose(fin);
+    fclose(fout);
+    cohpsk_destroy(cohpsk);
+
+    return 0;
+}