coh psk demod phase correction starting to do something sensible, still to complete...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 14 Mar 2015 06:40:03 +0000 (06:40 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 14 Mar 2015 06:40:03 +0000 (06:40 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@2073 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/cohpsk.m
codec2-dev/octave/tcohpsk.m
codec2-dev/src/codec2_cohpsk.h
codec2-dev/src/cohpsk.c
codec2-dev/src/cohpsk_defs.h
codec2-dev/src/cohpsk_internal.h [new file with mode: 0644]
codec2-dev/src/comp_prim.h [new file with mode: 0644]
codec2-dev/src/fdmdv.c
codec2-dev/src/fm.c
codec2-dev/unittest/CMakeLists.txt
codec2-dev/unittest/tcohpsk.c

index 20f4a5d7ec210b52eb81e8e4559031957be79001..ac5b0f7a15328eb187e86c0e64dab8ef958671d2 100644 (file)
@@ -88,7 +88,7 @@ function sim_in = symbol_rate_init(sim_in)
     sim_in.pilot = pilot;
     sim_in.tx_pilot_buf = [pilot; pilot; pilot];
     if sim_in.do_write_pilot_file
-      write_pilot_file(pilot, Nsymbrowpilot, Ns, Nsymbrow, Npilotsframe, Nc);
+      write_pilot_file(pilot, Nsymbrowpilot, Ns, Np, Nsymbrow, Npilotsframe, Nc);
     end
 
     % Init LDPC --------------------------------------------------------------------
@@ -127,7 +127,7 @@ endfunction
 
 % Symbol rate processing for tx side (modulator) -------------------------------------------------------
 
-function [tx_symb tx_bits prev_sym_tx] = symbol_rate_tx(sim_in, tx_bits, code_param, prev_sym_tx)
+function [tx_symb tx_bits prev_sym_tx] = bits_to_qpsk_symbols(sim_in, tx_bits, code_param, prev_sym_tx)
     ldpc_code     = sim_in.ldpc_code;
     rate          = sim_in.ldpc_code_rate;
     framesize     = sim_in.framesize;
@@ -436,16 +436,17 @@ function [spread spread_2ms hf_gain] = init_hf_model(Fs, Rs, nsam)
 endfunction
 
 
-function write_pilot_file(pilot, Nsymbrowpilot, Ns, Nsymrow, Npilotsframe, Nc);
+function write_pilot_file(pilot, Nsymbrowpilot, Ns, Np, Nsymrow, Npilotsframe, Nc);
 
   filename = sprintf("../src/cohpsk_defs.h", Npilotsframe, Nc);
   f=fopen(filename,"wt");
   fprintf(f,"/* Generated by write_pilot_file() Octave function */\n\n");
   fprintf(f,"#define NSYMROW      %d   /* number of data symbols for each row (i.e. each carrier) */\n", Nsymrow);
-  fprintf(f,"#define NS           %d   /* number of data symbols between pilots */\n", Ns);
-  fprintf(f,"#define NPILOTSFRAME %d   /* number of pilot symbols of each row */\n", Npilotsframe);
-  fprintf(f,"#define PILOTS_NC    %d   /* number of carriers in coh modem */\n\n", Nc);
-  fprintf(f,"#define NSYMROWPILOT %d   /* length of row after pilots inserted */\n\n", Nsymbrowpilot);
+  fprintf(f,"#define NS           %d   /* number of data symbols between pilots                   */\n", Ns);
+  fprintf(f,"#define NP           %d   /* number of pilots to use for channel est                 */\n", Np);
+  fprintf(f,"#define NPILOTSFRAME %d   /* number of pilot symbols of each row                     */\n", Npilotsframe);
+  fprintf(f,"#define PILOTS_NC    %d   /* number of carriers in coh modem                         */\n\n", Nc);
+  fprintf(f,"#define NSYMROWPILOT %d   /* length of row after pilots inserted                     */\n\n", Nsymbrowpilot);
   fclose(f);
 
   filename = sprintf("../src/pilots_coh.h", Npilotsframe, Nc);
@@ -566,7 +567,7 @@ function sim_out = ber_test(sim_in)
               tx_bits = round(rand(1,framesize));                       
             end
 
-            [s_ch tx_bits prev_sym_tx] = symbol_rate_tx(sim_in, tx_bits, code_param, prev_sym_tx);
+            [s_ch tx_bits prev_sym_tx] = bits_to_qpsk_symbols(sim_in, tx_bits, code_param, prev_sym_tx);
    
             tx_bits_buf(1:framesize) = tx_bits_buf(framesize+1:2*framesize);
             tx_bits_buf(framesize+1:2*framesize) = tx_bits;
index 2c6e95270d655f7e59485ef6eb693f650d5ed163..89ebaba75b0450b10646a8fc4d4202ca0e143e37 100644 (file)
@@ -20,11 +20,30 @@ framesize = 160;
 load ../build_linux/unittest/tcohpsk_out.txt
 
 sim_in = standard_init();
+sim_in.framesize = 160;
+sim_in.ldpc_code = 0;
+sim_in.ldpc_code_rate = 1;
+sim_in.Nc               = 4;
+sim_in.Rs               = 50;
+sim_in.Ns               = 4;
+sim_in.Np               = 2;
+sim_in.Nchip            = 1;
+sim_in.modulation       = 'qpsk';
+sim_in.do_write_pilot_file = 0;
+sim_in = symbol_rate_init(sim_in);
+
+rand('state',1); 
 tx_bits = round(rand(1,framesize));
 tx_bits_log = [];
+tx_symb_log = [];
 for i=1:frames
   tx_bits_log = [tx_bits_log tx_bits];
+  [tx_symb tx_bits prev_tx_sym] = bits_to_qpsk_symbols(sim_in, tx_bits, [], []);
+  tx_symb_log = [tx_symb_log; tx_symb];
 end
 
-stem_sig_and_error(1, 211, tx_bits_log_c(1:n), tx_bits_log(1:n) - tx_bits_log_c(1:n), 'tx bits', [1 n -1.5 1.5])
+stem_sig_and_error(1, 111, tx_bits_log_c(1:n), tx_bits_log(1:n) - tx_bits_log_c(1:n), 'tx bits', [1 n -1.5 1.5])
+stem_sig_and_error(2, 211, real(tx_symb_log_c(1:n)), real(tx_symb_log(1:n) - tx_symb_log_c(1:n)), 'tx symb re', [1 n -1.5 1.5])
+stem_sig_and_error(2, 212, imag(tx_symb_log_c(1:n)), imag(tx_symb_log(1:n) - tx_symb_log_c(1:n)), 'tx symb im', [1 n -1.5 1.5])
 check(tx_bits_log, tx_bits_log_c, 'tx_bits');
+check(tx_symb_log, tx_symb_log_c, 'tx_symb');
index 1ee3a2802ffee2d455caebd5f33ab6ef3a66876a..cef44627e7746f232b1fc28db9b48d09b633ef34 100644 (file)
 
 #include "comp.h"
 
-void bits_to_qpsk_symbols(COMP tx_symb[][COHPSK_NC], int tx_bits[], int framesize);
+struct COHPSK;
+
+struct COHPSK *cohpsk_create(void);
+void cohpsk_destroy(struct COHPSK *coh);
+void bits_to_qpsk_symbols(COMP tx_symb[][COHPSK_NC], int tx_bits[], int nbits);
+void qpsk_symbols_to_bits(struct COHPSK *coh, int rx_bits[], COMP rx_symb[][COHPSK_NC]);
 
 #endif
index 81e8e9e2e71393986926a6078b859e0f3b7c1627..32dc29b94d044b13bb099a994497bbbd377439a9 100644 (file)
@@ -45,7 +45,9 @@
 #include "codec2_cohpsk.h"
 #include "test_bits.h"
 #include "cohpsk_defs.h"
+#include "cohpsk_internal.h"
 #include "pilots_coh.h"
+#include "comp_prim.h"
 
 static COMP qpsk_mod[] = {
     { 1.0, 0.0},
@@ -60,24 +62,71 @@ static COMP qpsk_mod[] = {
 
 \*---------------------------------------------------------------------------*/
 
+/*--------------------------------------------------------------------------* \
+                                                       
+  FUNCTION....: cohpsk_create       
+  AUTHOR......: David Rowe                           
+  DATE CREATED: Marcg 2015 
+
+  Create and initialise an instance of the modem.  Returns a pointer
+  to the modem states or NULL on failure.  One set of states is
+  sufficient for a full duplex modem.
+
+\*---------------------------------------------------------------------------*/
+
+struct COHPSK *cohpsk_create(void)
+{
+    struct COHPSK *coh;
+
+    coh = (struct COHPSK*)malloc(sizeof(struct COHPSK));
+    if (coh == NULL)
+        return NULL;
+
+    /* set up buffer of 3 frames of tx pilot symbols */
+
+    memcpy(&coh->tx_pilot_buf[0][0], pilots_coh, sizeof(pilots_coh));
+    memcpy(&coh->tx_pilot_buf[NPILOTSFRAME][0], pilots_coh, sizeof(pilots_coh));
+    memcpy(&coh->tx_pilot_buf[2*NPILOTSFRAME][0], pilots_coh, sizeof(pilots_coh));
+
+    return coh;
+}
+
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: cohpsk_destroy      
+  AUTHOR......: David Rowe                           
+  DATE CREATED: March 2015
+
+  Destroy an instance of the modem.
+
+\*---------------------------------------------------------------------------*/
+
+void cohpsk_destroy(struct COHPSK *coh)
+{
+    assert(coh != NULL);
+    free(coh);
+}
+
+
 /*---------------------------------------------------------------------------*\
                                                        
   FUNCTION....: bits_to_qpsk_symbols()      
   AUTHOR......: David Rowe                           
   DATE CREATED: March 2015
 
-  Maps bits to parallel DQPSK symbols and inserts pilot symbols.
+  Rate Rs modulator.  Maps bits to parallel DQPSK symbols and inserts pilot symbols.
 
 \*---------------------------------------------------------------------------*/
 
-void bits_to_qpsk_symbols(COMP tx_symb[][PILOTS_NC], int tx_bits[], int framesize)
+void bits_to_qpsk_symbols(COMP tx_symb[][PILOTS_NC], int tx_bits[], int nbits)
 {
     COMP tx_symb_data[NSYMROW][PILOTS_NC];
     int   i, r, c, p_r, data_r;
     short bits;
 
     assert(COHPSK_NC == PILOTS_NC);
-    assert((NSYMROW*PILOTS_NC)*2 == framesize);
+    assert((NSYMROW*PILOTS_NC)*2 == nbits);
  
     /*
       Organise QPSK symbols into a NSYMBROWS rows by PILOTS_NC cols matrix,
@@ -112,7 +161,6 @@ void bits_to_qpsk_symbols(COMP tx_symb[][PILOTS_NC], int tx_bits[], int framesiz
         for(i=0; i<NS; data_r++,r++,i++) {
             for(c=0; c<PILOTS_NC; c++) {
                 tx_symb[r][c] = tx_symb_data[data_r][c];
-                //printf("r: %d c: %d data_r: %d %r %r\n", r, c, data_r, tx_symb[r][c]);
             }
         }
     }
@@ -121,3 +169,95 @@ void bits_to_qpsk_symbols(COMP tx_symb[][PILOTS_NC], int tx_bits[], int framesiz
     assert(data_r == NSYMROW);
     assert(r == NSYMROWPILOT);
 }
+
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: bits_to_qpsk_symbols()      
+  AUTHOR......: David Rowe                           
+  DATE CREATED: March 2015
+
+  Rate Rs demodulator. Extract pilot symbols and estimate amplitude and phase
+  of each carrier.  Correct phase of data symbols and convert to bits.
+
+\*---------------------------------------------------------------------------*/
+
+void qpsk_symbols_to_bits(struct COHPSK *coh, int rx_bits[], COMP rx_symb[][COHPSK_NC])
+{
+    int   st, en, r, c, i, p_r, data_r;
+    COMP  ch_est, rot, pi_on_4;
+
+    pi_on_4.real = cosf(M_PI/4); pi_on_4.imag = sinf(M_PI/4);
+
+    /* extract pilot and data symbols into 3 frame buffers */
+
+    for (r=0, p_r=2*NPILOTSFRAME, data_r=2*NSYMROW; r<NSYMROWPILOT; p_r++) {
+
+        printf("r: %d data_r: %d\n", r, data_r);
+        /* copy row of pilots onto end of pilot buffer */
+
+        for(c=0; c<PILOTS_NC; c++) {
+            coh->rx_pilot_buf[p_r][c] = rx_symb[r][c];
+            //printf("  %d %d %f %f", p_r, c, coh->rx_pilot_buf[p_r][c].real, coh->rx_pilot_buf[p_r][c].imag);
+        }
+        //printf("\n");
+        r++;
+
+        //printf("r: %d data_r: %d\n", r, data_r);
+        /* copy NS rows of data symbols onto end of data symbol buffer */
+
+        for(i=0; i<NS; data_r++,r++,i++) {
+            for(c=0; c<PILOTS_NC; c++)
+                coh->rx_symb_buf[data_r][c] = rx_symb[r][c];
+        }
+    }
+
+    /* estimate channel amplitude and phase and correct data symbols in middle of buffer */
+
+    for (r=0, data_r=NSYMROW; r<NSYMROW; r++, data_r) {
+
+        /* pilots to use for correcting data_r-th symbol */
+
+        st = NPILOTSFRAME + floor(r/NS) - floor(NP/2) + 1;
+        en = st + NP - 1;
+        assert(st >= 0);
+        assert(en < 3*NPILOTSFRAME);
+
+        printf("r: %d data_r: %d st: %d en: %d\n", r, data_r, st, en);
+
+        /* iterate over all of the carriers */
+
+        for (c=0; c<PILOTS_NC; c++) {
+
+            /* estimate channel */
+
+            ch_est.real = 0.0; ch_est.imag = 0.0;
+            for (i=st; i<=en; i++)
+                ch_est = cadd(ch_est, fcmult(coh->tx_pilot_buf[i][c], coh->rx_pilot_buf[i][c]));
+            ch_est = fcmult(1.0/NP, ch_est);
+            coh->phi_[r][c] = atan2(ch_est.imag,ch_est.real);
+            coh->amp_[r][c] = cabsolute(ch_est);
+
+            /* correct phase */
+
+            rot.real = cosf(coh->phi_[r][c]); rot.imag = -sinf(coh->phi_[r][c]);
+            coh->rx_symb_buf[data_r][c] = cmult(coh->rx_symb_buf[data_r][c], rot);
+
+            /* demodulate */
+
+            i = c*NSYMROW + r;
+            rot = cmult(rx_symb[data_r][c], pi_on_4);
+            rx_bits[2*i]   = rot.real < 0;
+            rx_bits[2*i+1] = rot.imag < 0;
+
+            printf("  c: %d ch_est: %f %f phi_: %f amp_: %f\n",c,  ch_est.real, ch_est.imag, coh->phi_[r][c], coh->amp_[r][c]);
+        }
+        //exit(0);
+    }
+
+    /* shift buffers */
+
+    memcpy(&coh->rx_pilot_buf[0][0], &coh->rx_pilot_buf[NPILOTSFRAME][0], sizeof(COMP)*2*NPILOTSFRAME*PILOTS_NC);
+    memcpy(&coh->rx_symb_buf[0][0], &coh->rx_symb_buf[NSYMROW][0], sizeof(COMP)*2*NSYMROW*PILOTS_NC);
+
+}
index 69ab16621af35145075a68cbc64c2205d8025ebc..ff00b33130d9222457d17e06c71d62cd6d05284b 100644 (file)
@@ -1,9 +1,10 @@
 /* Generated by write_pilot_file() Octave function */
 
 #define NSYMROW      20   /* number of data symbols for each row (i.e. each carrier) */
-#define NS           4   /* number of data symbols between pilots */
-#define NPILOTSFRAME 5   /* number of pilot symbols of each row */
-#define PILOTS_NC    4   /* number of carriers in coh modem */
+#define NS           4   /* number of data symbols between pilots                   */
+#define NP           2   /* number of pilots to use for channel est                 */
+#define NPILOTSFRAME 5   /* number of pilot symbols of each row                     */
+#define PILOTS_NC    4   /* number of carriers in coh modem                         */
 
-#define NSYMROWPILOT 25   /* length of row after pilots inserted */
+#define NSYMROWPILOT 25   /* length of row after pilots inserted                     */
 
diff --git a/codec2-dev/src/cohpsk_internal.h b/codec2-dev/src/cohpsk_internal.h
new file mode 100644 (file)
index 0000000..354e7e4
--- /dev/null
@@ -0,0 +1,39 @@
+/*---------------------------------------------------------------------------*\
+                                                                             
+  FILE........: cohpsk_internal.h
+  AUTHOR......: David Rowe
+  DATE CREATED: March 2015
+                                                                             
+  Functions that implement a coherent PSK FDM modem.
+                                                               
+\*---------------------------------------------------------------------------*/
+
+/*
+  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.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/>.
+*/
+
+#ifndef __COHPSK_INTERNAL__
+#define __COHPSK_INTERNAL__
+
+struct COHPSK {
+    float tx_pilot_buf[3*NPILOTSFRAME][PILOTS_NC];      /* 3 frames of tx pilot symbols                          */
+    COMP  rx_pilot_buf[3*NPILOTSFRAME][PILOTS_NC];      /* 3 frames of rx piloy symbols                          */
+    COMP  rx_symb_buf[3*NSYMROW][PILOTS_NC];            /* 3 frames of rx data symbols                           */
+    float phi_[NSYMROW][PILOTS_NC];                     /* phase estimates for this frame of rx data symbols     */
+    float amp_[NSYMROW][PILOTS_NC];                     /* amplitude estimates for this frame of rx data symbols */
+};
+
+#endif
diff --git a/codec2-dev/src/comp_prim.h b/codec2-dev/src/comp_prim.h
new file mode 100644 (file)
index 0000000..8d86ac7
--- /dev/null
@@ -0,0 +1,92 @@
+/*---------------------------------------------------------------------------*\
+                                                                             
+  FILE........: comp_prim.h
+  AUTHOR......: David Rowe                                                          
+  DATE CREATED: Marh 2015
+                                                                             
+  Complex number maths primitives.
+                                                                             
+\*---------------------------------------------------------------------------*/
+
+/*
+  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.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/>.
+*/
+
+#ifndef __COMP_PRIM__
+#define __COMP_PRIM__
+
+/*---------------------------------------------------------------------------*\
+                                                                             
+                               FUNCTIONS
+
+\*---------------------------------------------------------------------------*/
+
+static COMP cneg(COMP a)
+{
+    COMP res;
+
+    res.real = -a.real;
+    res.imag = -a.imag;
+
+    return res;
+}
+
+static COMP cconj(COMP a)
+{
+    COMP res;
+
+    res.real = a.real;
+    res.imag = -a.imag;
+
+    return res;
+}
+
+static COMP cmult(COMP a, COMP b)
+{
+    COMP res;
+
+    res.real = a.real*b.real - a.imag*b.imag;
+    res.imag = a.real*b.imag + a.imag*b.real;
+
+    return res;
+}
+
+static COMP fcmult(float a, COMP b)
+{
+    COMP res;
+
+    res.real = a*b.real;
+    res.imag = a*b.imag;
+
+    return res;
+}
+
+static COMP cadd(COMP a, COMP b)
+{
+    COMP res;
+
+    res.real = a.real + b.real;
+    res.imag = a.imag + b.imag;
+
+    return res;
+}
+
+static float cabsolute(COMP a)
+{
+    return sqrtf(powf(a.real, 2.0) + powf(a.imag, 2.0));
+}
+
+#endif
index e96a1cbce552b6928e8c3f138c9aa9bbb9ccd739..931adabe7be303897588d3b067191bd7dd8a444d 100644 (file)
@@ -39,6 +39,7 @@
 
 #include "fdmdv_internal.h"
 #include "codec2_fdmdv.h"
+#include "comp_prim.h"
 #include "rn.h"
 #include "rxdec_coeff.h"
 #include "test_bits.h"
@@ -54,68 +55,7 @@ static int sync_uw[] = {1,-1,1,-1,1,-1};
 #define printf gdb_stdio_printf
 #endif
 
-/*---------------------------------------------------------------------------*\
-                                                                             
-                               FUNCTIONS
-
-\*---------------------------------------------------------------------------*/
-
-static COMP cneg(COMP a)
-{
-    COMP res;
-
-    res.real = -a.real;
-    res.imag = -a.imag;
-
-    return res;
-}
-
-static COMP cconj(COMP a)
-{
-    COMP res;
-
-    res.real = a.real;
-    res.imag = -a.imag;
-
-    return res;
-}
-
-static COMP cmult(COMP a, COMP b)
-{
-    COMP res;
-
-    res.real = a.real*b.real - a.imag*b.imag;
-    res.imag = a.real*b.imag + a.imag*b.real;
-
-    return res;
-}
-
-static COMP fcmult(float a, COMP b)
-{
-    COMP res;
-
-    res.real = a*b.real;
-    res.imag = a*b.imag;
-
-    return res;
-}
-
-static COMP cadd(COMP a, COMP b)
-{
-    COMP res;
-
-    res.real = a.real + b.real;
-    res.imag = a.imag + b.imag;
-
-    return res;
-}
-
-static float cabsolute(COMP a)
-{
-    return sqrtf(powf(a.real, 2.0) + powf(a.imag, 2.0));
-}
-
-/*---------------------------------------------------------------------------*\
+/*--------------------------------------------------------------------------* \
                                                        
   FUNCTION....: fdmdv_create        
   AUTHOR......: David Rowe                           
index 8d5e5be0e27adbe90a67823c1d5c72223aa0788b..18f0a5328a9efb8c7d13c60890f2d7845c1120aa 100644 (file)
@@ -48,6 +48,7 @@
 
 #include "codec2_fm.h"
 #include "fm_fir_coeff.h"
+#include "comp_prim.h"
 
 /*---------------------------------------------------------------------------*\
                                                                              
 
 \*---------------------------------------------------------------------------*/
 
-static COMP cconj(COMP a)
-{
-    COMP res;
-
-    res.real = a.real;
-    res.imag = -a.imag;
-
-    return res;
-}
-
-static COMP cmult(COMP a, COMP b)
-{
-    COMP res;
-
-    res.real = a.real*b.real - a.imag*b.imag;
-    res.imag = a.real*b.imag + a.imag*b.real;
-
-    return res;
-}
-
-static COMP fcmult(float a, COMP b)
-{
-    COMP res;
-
-    res.real = a*b.real;
-    res.imag = a*b.imag;
-
-    return res;
-}
-
-static float cabsolute(COMP a)
-{
-    return sqrtf(powf(a.real, 2.0) + powf(a.imag, 2.0));
-}
-
 /*---------------------------------------------------------------------------*\
                                                        
   FUNCTION....: fm_create           
index 1743a80bade70eadc87e1d67afb7fcb869dacfba..7d1e98cb592471e02620a3a7cf1250adb3069c61 100644 (file)
@@ -52,7 +52,7 @@ add_executable(tfdmdv tfdmdv.c ../src/fdmdv.c ../src/kiss_fft.c ../src/octave.c)
 target_link_libraries(tfdmdv codec2)
 
 add_executable(tcohpsk tcohpsk.c ../src/cohpsk.c ../src/octave.c)
-target_link_libraries(tcohpsk)
+target_link_libraries(tcohpsk codec2)
 
 add_executable(t16_8 t16_8.c ../src/fdmdv.c ../src/kiss_fft.c)
 target_link_libraries(t16_8 codec2)
index 5550a2076fee5a1909a50f0163f879c31050e6fa..08c295cb99cf43e5f89db9f568cdf5cbcfde1eda 100644 (file)
@@ -38,6 +38,7 @@
 #include "codec2_fdmdv.h"
 #include "codec2_cohpsk.h"
 #include "cohpsk_defs.h"
+#include "cohpsk_internal.h"
 #include "test_bits_coh.h"
 #include "octave.h"
 
 
 int main(int argc, char *argv[])
 {
-    int           tx_bits[COHPSK_BITS_PER_FRAME];
-    COMP          tx_symbols[NSYMROWPILOT][PILOTS_NC];
+    struct COHPSK *coh;
+    int            tx_bits[COHPSK_BITS_PER_FRAME];
+    COMP           tx_symb[NSYMROWPILOT][PILOTS_NC];
+    int            rx_bits[COHPSK_BITS_PER_FRAME];
     
-    int           tx_bits_log[COHPSK_BITS_PER_FRAME*FRAMES];
-    COMP          tx_symbols_log[NSYMROWPILOT*FRAMES][PILOTS_NC];
+    int            tx_bits_log[COHPSK_BITS_PER_FRAME*FRAMES];
+    COMP           tx_symb_log[NSYMROWPILOT*FRAMES][PILOTS_NC];
+
+    float          rx_amp_log[NSYMROW*FRAMES][PILOTS_NC];
+    float          rx_phi_log[NSYMROW*FRAMES][PILOTS_NC];
+    int            rx_bits_log[COHPSK_BITS_PER_FRAME*FRAMES];
                                           
-    FILE         *fout;
-    int           f, r,c,rx_sym_log_r;
+    FILE          *fout;
+    int            f, r, c, log_r, log_data_r;
+
+    coh = cohpsk_create();
+    assert(coh != NULL);
 
-    rx_sym_log_r=0;
+    log_r = log_data_r= 0;
 
     memcpy(tx_bits, test_bits_coh, sizeof(int)*COHPSK_BITS_PER_FRAME);
 
     for(f=0; f<FRAMES; f++) {
         
        /* --------------------------------------------------------*\
-                                 Modulator
+                                 Modem
        \*---------------------------------------------------------*/
 
-       bits_to_qpsk_symbols(tx_symbols, (int*)tx_bits, COHPSK_BITS_PER_FRAME);
+       bits_to_qpsk_symbols(tx_symb, (int*)tx_bits, COHPSK_BITS_PER_FRAME);
+        qpsk_symbols_to_bits(coh, rx_bits, tx_symb);
 
        /* --------------------------------------------------------*\
                               Log each vector 
        \*---------------------------------------------------------*/
 
        memcpy(&tx_bits_log[COHPSK_BITS_PER_FRAME*f], tx_bits, sizeof(int)*COHPSK_BITS_PER_FRAME);
-       for(r=0; r<NSYMROWPILOT; r++, rx_sym_log_r++) {
+       for(r=0; r<NSYMROWPILOT; r++, log_r++) {
             for(c=0; c<PILOTS_NC; c++) 
-               tx_symbols_log[rx_sym_log_r][c] = tx_symbols[r][c]; 
+               tx_symb_log[log_r][c] = tx_symb[r][c]; 
         }
-       assert(rx_sym_log_r <= NSYMROWPILOT*FRAMES);
-    }
 
+       for(r=0; r<NSYMROW; r++, log_data_r++) {
+            for(c=0; c<PILOTS_NC; c++) {
+               rx_amp_log[log_data_r][c] = coh->amp_[r][c]; 
+               rx_phi_log[log_data_r][c] = coh->phi_[r][c]; 
+            }
+        }
+       memcpy(&rx_bits_log[COHPSK_BITS_PER_FRAME*f], rx_bits, sizeof(int)*COHPSK_BITS_PER_FRAME);
+
+       assert(log_r <= NSYMROWPILOT*FRAMES);
+       assert(log_data_r <= NSYMROW*FRAMES);
+    }
 
     /*---------------------------------------------------------*\
                Dump logs to Octave file for evaluation 
@@ -89,9 +109,13 @@ int main(int argc, char *argv[])
     assert(fout != NULL);
     fprintf(fout, "# Created by tcohpsk.c\n");
     octave_save_int(fout, "tx_bits_log_c", tx_bits_log, 1, COHPSK_BITS_PER_FRAME*FRAMES);
-    octave_save_complex(fout, "tx_symbols_log_c", (COMP*)tx_symbols_log, NSYMROWPILOT*FRAMES, PILOTS_NC, PILOTS_NC);  
+    octave_save_complex(fout, "tx_symb_log_c", (COMP*)tx_symb_log, NSYMROWPILOT*FRAMES, PILOTS_NC, PILOTS_NC);  
+    octave_save_complex(fout, "rx_amp_log_c", (COMP*)rx_amp_log, NSYMROW*FRAMES, PILOTS_NC, PILOTS_NC);  
+    octave_save_complex(fout, "rx_phi_log_c", (COMP*)rx_phi_log, NSYMROW*FRAMES, PILOTS_NC, PILOTS_NC);  
     fclose(fout);
 
+    cohpsk_destroy(coh);
+
     return 0;
 }