starting coherent PSK C port and test framework, compiles OK but not tested
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 11 Mar 2015 06:46:22 +0000 (06:46 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 11 Mar 2015 06:46:22 +0000 (06:46 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@2065 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/fsk.m
codec2-dev/octave/test_ldpc.m
codec2-dev/src/codec2_cohpsk.h [new file with mode: 0644]
codec2-dev/src/cohpsk.c [new file with mode: 0644]
codec2-dev/src/cohpsk_defs.h [new file with mode: 0644]
codec2-dev/src/fdmdv.c
codec2-dev/src/fdmdv_internal.h
codec2-dev/src/pilots_coh.h [new file with mode: 0644]
codec2-dev/src/test_bits_coh.h [new file with mode: 0644]
codec2-dev/unittest/CMakeLists.txt
codec2-dev/unittest/tcohpsk.c [new file with mode: 0644]

index 74fee23f5baa7316cd587129769dc4916b7d1623..d91ba30366d9e2875ef34319c9a9c8db8f7b21e4 100644 (file)
@@ -110,6 +110,7 @@ function sim_out = fsk_ber_test(sim_in)
       printf("EbNo: %f Eb: %f var No: %f EbNo (meas): %f\n", 
       EbNo, var(tx)*Ts/Fs, var(noise)/Fs, (var(tx)*Ts/Fs)/(var(noise)/Fs));
     end
+    save fsk tx_bits rx
 
     % Optional AFSK over FM demodulator
 
@@ -233,12 +234,12 @@ function run_fsk_curves
 end
 
 function run_fsk_single
-  sim_in.fmark     = 1200;
-  sim_in.fspace    = 2200;
-  sim_in.Rs        = 1200;
-  sim_in.nsym      = 1200;
-  sim_in.EbNodB    = 16;
-  sim_in.fm        = 1;
+  sim_in.fmark     = 1000;
+  sim_in.fspace    = 2000;
+  sim_in.Rs        = 1000;
+  sim_in.nsym      = 2000;
+  sim_in.EbNodB    = 7;
+  sim_in.fm        = 0;
   sim_in.verbose   = 1;
 
   fsk_sim = fsk_ber_test(sim_in);
index f64727496231767724869b067512f87c11fe6c84..603c009618e446144775735d5855f21665346e85 100644 (file)
@@ -22,6 +22,7 @@
 
 rand('state',1); 
 randn('state',1);
+graphics_toolkit ("gnuplot");
 
 1;
 
@@ -50,7 +51,7 @@ function [tx_symb tx_bits prev_sym_tx] = symbol_rate_tx(sim_in, tx_bits, code_pa
     % data and parity bits are on separate carriers
 
     tx_symb = zeros(Nsymbrow,Nc);
-
+    
     for c=1:Nc
       for r=1:Nsymbrow
         i = (c-1)*Nsymbrow + r;
@@ -59,7 +60,7 @@ function [tx_symb tx_bits prev_sym_tx] = symbol_rate_tx(sim_in, tx_bits, code_pa
     end
     %tx_symb = zeros(Nsymbrow,Nc);
 
-    % Optionally insert pilots, one every Ns data symbols
+    % insert pilots, one every Ns data symbols
 
     tx_symb_pilot = zeros(Nsymbrowpilot, Nc);
             
@@ -171,6 +172,53 @@ function [spread spread_2ms hf_gain] = init_hf_model(Fs, Rs, nsam)
 endfunction
 
 
+function write_pilot_file(pilot, Nsymbrowpilot, Ns, 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);
+  fclose(f);
+
+  filename = sprintf("../src/pilots_coh.h", Npilotsframe, Nc);
+  f=fopen(filename,"wt");
+  fprintf(f,"/* Generated by write_pilot_file() Octave function */\n\n");
+  fprintf(f,"float pilots_coh[][PILOTS_NC]={\n");
+  for r=1:Npilotsframe
+    fprintf(f, "  {");
+    for c=1:Nc-1
+      fprintf(f, "  %f,", pilot(r, c));
+    end
+    if r < Npilotsframe
+      fprintf(f, "  %f},\n", pilot(r, Nc));
+    else
+      fprintf(f, "  %f}\n};", pilot(r, Nc));
+    end
+  end
+  fclose(f);
+endfunction
+
+
+% Save test bits frame to a text file in the form of a C array
+
+function test_bits_coh_file(test_bits_coh)
+
+  f=fopen("test_bits_coh.h","wt");
+  fprintf(f,"/* Generated by test_bits_coh_file() Octave function */\n\n");
+  fprintf(f,"const int test_bits_coh[]={\n");
+  for m=1:length(test_bits_coh)-1
+    fprintf(f,"  %d,\n",test_bits_coh(m));
+  endfor
+  fprintf(f,"  %d\n};\n",test_bits_coh(length(test_bits_coh)));
+  fclose(f);
+
+endfunction
+
+
 % init function for symbol rate processing
 
 function sim_in = symbol_rate_init(sim_in)
@@ -223,10 +271,13 @@ function sim_in = symbol_rate_init(sim_in)
 
     % pilot sequence is used for phase and amplitude estimation, and frame sync
 
-    pilot = 1 - 2*(rand(Npilotsframe,Nc) > 0.5);
+    pilot = 1 - 2*(rand(Npilotsframe,Nc) > 0.5)
     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);
+    end
+
     % Init LDPC --------------------------------------------------------------------
 
     if ldpc_code
@@ -256,6 +307,7 @@ function sim_in = symbol_rate_init(sim_in)
         sim_in.code_param = code_param;
     else
         sim_in.rate = 1;
+        sim_in.code_param = [];
     end
 endfunction
 
@@ -334,7 +386,7 @@ function [rx_symb rx_bits rx_symb_linear amp_linear amp_ phi_ EsNo_ prev_sym_rx
         if verbose > 2
           printf("% 4.3f ", phi_(r,c))
         end
-        rx_symb(r,c) *= exp(-j*phi_(r,c));
+        rx_symb(r,c) *= exp(-j*phi_(r,c));
       end
 
       if verbose > 2
@@ -810,21 +862,25 @@ function test_single
   sim_in.verbose          = 1;
   sim_in.plot_scatter     = 1;
 
-  sim_in.framesize        = 576;
-  sim_in.Nc               = 9;
+  sim_in.framesize        = 160;
+  sim_in.Nc               = 4;
   sim_in.Rs               = 50;
   sim_in.Ns               = 4;
   sim_in.Np               = 2;
   sim_in.Nchip            = 1;
-  sim_in.ldpc_code_rate   = 0.5;
-  sim_in.ldpc_code        = 1;
+% sim_in.ldpc_code_rate   = 0.5;
+% sim_in.ldpc_code        = 1;
+  sim_in.ldpc_code_rate   = 1;
+  sim_in.ldpc_code        = 0;
 
   sim_in.Ntrials          = 20;
-  sim_in.Esvec            = 10; 
-  sim_in.hf_sim           = 1;
+  sim_in.Esvec            = 100
+  sim_in.hf_sim           = 0;
   sim_in.hf_mag_only      = 0;
   sim_in.modulation       = 'qpsk';
 
+  sim_in.do_write_pilot_file = 1;
+
   sim_qpsk_hf             = ber_test(sim_in);
 
   fep=fopen("errors_450.bin","wb"); fwrite(fep, sim_qpsk_hf.ldpc_errors_log, "short"); fclose(fep);
@@ -838,14 +894,14 @@ function rate_Fs_tx(tx_filename)
   sim_in.verbose          = 1;
   sim_in.plot_scatter     = 1;
 
-  sim_in.framesize        = 576;
-  sim_in.Nc               = 9;
+  sim_in.framesize        = 160;
+  sim_in.Nc               = 4;
   sim_in.Rs               = 50;
   sim_in.Ns               = 4;
   sim_in.Np               = 2;
   sim_in.Nchip            = 1;
-  sim_in.ldpc_code_rate   = 0.5;
-  sim_in.ldpc_code        = 1;
+  sim_in.ldpc_code_rate   = 1;
+  sim_in.ldpc_code        = 0;
 
   sim_in.Ntrials          = 20;
   sim_in.Esvec            = 7; 
@@ -930,7 +986,7 @@ function rate_Fs_tx(tx_filename)
   Ascale = 2000;
   figure(1);
   clf;
-  plot(Ascale*tx_fdm(1:800))
+  plot(Ascale*tx_fdm(1:8000))
 
   ftx=fopen(tx_filename,"wb"); fwrite(ftx, Ascale*real(tx_fdm), "short"); fclose(ftx);
 
@@ -943,14 +999,14 @@ function rate_Fs_rx(rx_filename)
   sim_in.verbose          = 1;
   sim_in.plot_scatter     = 1;
 
-  sim_in.framesize        = 576;
-  sim_in.Nc               = 9;
+  sim_in.framesize        = 160;
+  sim_in.Nc               = 4;
   sim_in.Rs               = 50;
   sim_in.Ns               = 4;
   sim_in.Np               = 4;
   sim_in.Nchip            = 1;
-  sim_in.ldpc_code_rate   = 0.5;
-  sim_in.ldpc_code        = 1;
+  sim_in.ldpc_code_rate   = 1;
+  sim_in.ldpc_code        = 0;
 
   sim_in.Ntrials          = 10;
   sim_in.Esvec            = 40; 
@@ -1015,7 +1071,7 @@ function rate_Fs_rx(rx_filename)
 
   printf("Freq offset and coarse timing est...\n");
   [f_max max_s_Fs] = test_freq_off_est(rx_filename, 1,5*6400);
-  %f_max = 0; max_s_Fs = 4;
+  f_max = 0; max_s_Fs = 4;
   max_s = floor(max_s_Fs/M + 6);
 
   printf("Downconverting...\n");
@@ -1114,19 +1170,21 @@ function rate_Fs_rx(rx_filename)
       errors_log = [errors_log error_positions];
       Nerrs_log = [Nerrs_log Nerrs];
 
-      % LDPC decode
+      if sim_in.ldpc_code
+        % LDPC decode
             
-      detected_data = ldpc_dec(code_param, sim_in.max_iterations, sim_in.demod_type, sim_in.decoder_type, ...
-                               rx_symb_linear, min(100,EsNo_), amp_linear);
-      error_positions = xor(detected_data(1:framesize*rate), tx_bits(1:framesize*rate) );
-      Nerrs = sum(error_positions);
-      ldpc_Nerrs_log = [ldpc_Nerrs_log Nerrs];
-      ldpc_errors_log = [ldpc_errors_log error_positions];
-      if Nerrs
-        Ferrsldpc++;
+        detected_data = ldpc_dec(code_param, sim_in.max_iterations, sim_in.demod_type, sim_in.decoder_type, ...
+                                 rx_symb_linear, min(100,EsNo_), amp_linear);
+        error_positions = xor(detected_data(1:framesize*rate), tx_bits(1:framesize*rate) );
+        Nerrs = sum(error_positions);
+        ldpc_Nerrs_log = [ldpc_Nerrs_log Nerrs];
+        ldpc_errors_log = [ldpc_errors_log error_positions];
+        if Nerrs
+          Ferrsldpc++;
+        end
+        Terrsldpc += Nerrs;
+        Tbitsldpc += framesize*rate;
       end
-      Terrsldpc += Nerrs;
-      Tbitsldpc += framesize*rate;
     end
   end
 
@@ -1135,9 +1193,11 @@ function rate_Fs_rx(rx_filename)
          EsNo_av, mean(EsNo_to_SNR(10*log10(EsNo__log))),
          Terrs,
          Terrs/Tbits, 0.5*erfc(sqrt(EsNo/2)), av_tx_pwr);
-  printf("\n LDPC: Terrs: %d BER: %4.2f Ferrs: %d FER: %4.2f\n", 
-         Terrsldpc, Terrsldpc/Tbitsldpc, Ferrsldpc, Ferrsldpc/Ntrials);
+  if sim_in.ldpc_code
+    printf("\n LDPC: Terrs: %d BER: %4.2f Ferrs: %d FER: %4.2f\n", 
+           Terrsldpc, Terrsldpc/Tbitsldpc, Ferrsldpc, Ferrsldpc/Ntrials);
+  end
+
   figure(3);
   clf;
   scat = rx_symb_log .* exp(j*pi/4);
@@ -1151,10 +1211,12 @@ function rate_Fs_rx(rx_filename)
   stem(Nerrs_log)
   axis([0 Ntrials+1 0 max(Nerrs_log)+1])
   title('Uncoded Errors/Frame');
-  subplot(212)
-  stem(ldpc_Nerrs_log)
-  axis([0 Ntrials+1 0 max(ldpc_Nerrs_log)+1])
-  title('Coded Errors/Frame');
+  if sim_in.ldpc_code
+    subplot(212)
+    stem(ldpc_Nerrs_log)
+    axis([0 Ntrials+1 0 max(ldpc_Nerrs_log)+1])
+    title('Coded Errors/Frame');
+  end
 
   figure(5)
   clf
@@ -1262,13 +1324,22 @@ function snr = EsNo_to_SNR(EsNo)
   snr = interp1([20 11.8 9.0 6.7 4.9 3.3 -10], [ 3 3 0 -3 -6 -9 -9], EsNo);
 endfunction
 
+function gen_test_bits()
+  sim_in = standard_init();
+  framesize = 160;
+  tx_bits = round(rand(1,framesize));
+  test_bits_coh_file(tx_bits);
+endfunction
+
 % Start simulations ---------------------------------------
 
 more off;
 %test_curves();
-%test_single();
+test_single();
 %rate_Fs_tx("tx_zero.raw");
-%rate_Fs_tx("tx_950.raw");
-rate_Fs_rx("tx_-4dB.wav")
-%rate_Fs_rx("mel010.wav")
+%rate_Fs_tx("tx.raw");
+%rate_Fs_rx("tx_-4dB.wav")
+%rate_Fs_rx("tx.raw")
 %test_freq_off_est("tx.raw",40,6400)
+%gen_test_bits();
+
diff --git a/codec2-dev/src/codec2_cohpsk.h b/codec2-dev/src/codec2_cohpsk.h
new file mode 100644 (file)
index 0000000..1ee3a28
--- /dev/null
@@ -0,0 +1,38 @@
+/*---------------------------------------------------------------------------*\
+                                                                             
+  FILE........: cohpsk.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 __CODEC2_COHPSK__
+#define __CODEC2_COHPSK__
+
+#define COHPSK_BITS_PER_FRAME 160             /* hard coded for now */
+#define COHPSK_NC               4             /* hard coded for now */
+
+#include "comp.h"
+
+void bits_to_qpsk_symbols(COMP tx_symb[][COHPSK_NC], int tx_bits[], int framesize);
+
+#endif
diff --git a/codec2-dev/src/cohpsk.c b/codec2-dev/src/cohpsk.c
new file mode 100644 (file)
index 0000000..4653095
--- /dev/null
@@ -0,0 +1,121 @@
+/*---------------------------------------------------------------------------*\
+                                                                             
+  FILE........: cohpsk.c
+  AUTHOR......: David Rowe
+  DATE CREATED: March 2015
+                                                                             
+  Functions that implement a coherent PSK FDM modem.
+        
+  TODO:
+    [ ] matching octave function bits_to_dqpsk_symbols()
+    [ ] framework for test program and octave UT
+    [ ] testframe used by both Octave and C
+                                                               
+\*---------------------------------------------------------------------------*/
+
+/*
+  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/>.
+*/
+
+/*---------------------------------------------------------------------------*\
+                                                                             
+                               INCLUDES
+
+\*---------------------------------------------------------------------------*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include "codec2_cohpsk.h"
+#include "test_bits.h"
+#include "cohpsk_defs.h"
+#include "pilots_coh.h"
+
+static COMP qpsk_mod[] = {
+    { 1.0, 0.0},
+    { 0.0, 1.0},
+    { 0.0,-1.0},
+    {-1.0, 0.0}
+};
+    
+/*---------------------------------------------------------------------------*\
+                                                                             
+                               FUNCTIONS
+
+\*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: bits_to_qpsk_symbols()      
+  AUTHOR......: David Rowe                           
+  DATE CREATED: March 2015
+
+  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)
+{
+    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);
+    /*
+      Organise QPSK symbols into a NSYMBROWS rows by PILOTS_NC cols matrix,
+      each column is a carrier, time flows down the rows......
+
+      Note: the "& 0x1" prevents and non binary tx_bits[] screwing up
+      our lives.  Call me defensive.
+    */
+
+    for(c=0; c<PILOTS_NC; c++) {
+        for(r=0; r<NSYMROW; r++) {
+            i = c*NSYMROW + r;
+            bits = (tx_bits[2*i]&0x1)<<1 | (tx_bits[2*i+1]&0x1);          
+            tx_symb_data[r][c] = qpsk_mod[bits];
+        }
+    }
+
+    /* "push" in rows of Nc pilots, one row every NS data symbols */
+            
+    for (r=0, p_r=0, data_r=0; p_r<NPILOTSFRAME; p_r++) {
+
+        /* row of pilots */
+
+        for(c=0; c<PILOTS_NC; c++) {
+            tx_symb[r][c].real = pilots_coh[p_r][c];
+            tx_symb[r][c].imag = 0.0;
+        }
+        r++;
+
+        /* NS rows of data symbols */
+
+        for(i=0; i<NS; data_r++,r++) {
+            for(c=0; c<PILOTS_NC; c++)
+                tx_symb[r][c] = tx_symb_data[data_r][c];
+        }
+    }
+
+    assert(p_r == NPILOTSFRAME);
+    assert(data_r == NSYMROW);
+    assert(r == NSYMROWPILOT);
+}
diff --git a/codec2-dev/src/cohpsk_defs.h b/codec2-dev/src/cohpsk_defs.h
new file mode 100644 (file)
index 0000000..69ab166
--- /dev/null
@@ -0,0 +1,9 @@
+/* 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 NSYMROWPILOT 25   /* length of row after pilots inserted */
+
index ca6f6aef221e48b02024c5f414aee88b642718a5..e96a1cbce552b6928e8c3f138c9aa9bbb9ccd739 100644 (file)
@@ -305,7 +305,7 @@ void fdmdv_get_test_bits(struct FDMDV *f, int tx_bits[])
        if (f->current_test_bit > (f->ntest_bits-1))
            f->current_test_bit = 0;
     }
- }
+}
 
 float fdmdv_get_fsep(struct FDMDV *f)
 {
index 97011e8d9de415d177ff51ec2b87d0b0408964ad..4476aea0c1830b3d7e7da8c7107a63ff7f15f674 100644 (file)
@@ -1,7 +1,7 @@
 /*---------------------------------------------------------------------------*\
                                                                              
   FILE........: fdmdv_internal.h
-  AUTHOR......: David Rowe                                                          
+  AUTHOR......: David Rowe
   DATE CREATED: April 16 2012
                                                                              
   Header file for FDMDV internal functions, exposed via this header
diff --git a/codec2-dev/src/pilots_coh.h b/codec2-dev/src/pilots_coh.h
new file mode 100644 (file)
index 0000000..e5e1deb
--- /dev/null
@@ -0,0 +1,9 @@
+/* Generated by write_pilot_file() Octave function */
+
+float pilots_coh[][PILOTS_NC]={
+  {  1.000000,  1.000000,  -1.000000,  -1.000000},
+  {  -1.000000,  -1.000000,  1.000000,  1.000000},
+  {  -1.000000,  -1.000000,  -1.000000,  -1.000000},
+  {  1.000000,  1.000000,  1.000000,  -1.000000},
+  {  1.000000,  1.000000,  1.000000,  1.000000}
+};
\ No newline at end of file
diff --git a/codec2-dev/src/test_bits_coh.h b/codec2-dev/src/test_bits_coh.h
new file mode 100644 (file)
index 0000000..2420ea8
--- /dev/null
@@ -0,0 +1,164 @@
+/* Generated by test_bits_coh_file() Octave function */
+
+const int test_bits_coh[]={
+  0,
+  1,
+  1,
+  0,
+  0,
+  0,
+  1,
+  1,
+  0,
+  0,
+  1,
+  0,
+  1,
+  0,
+  0,
+  1,
+  0,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  0,
+  1,
+  1,
+  1,
+  1,
+  1,
+  0,
+  0,
+  1,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  0,
+  1,
+  1,
+  1,
+  1,
+  1,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  0,
+  1,
+  0,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  0,
+  0,
+  1,
+  1,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  0,
+  0,
+  0,
+  1,
+  0,
+  0,
+  1,
+  0,
+  0,
+  0,
+  1,
+  0,
+  0,
+  1,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1,
+  1,
+  0,
+  1,
+  1,
+  0,
+  0,
+  0,
+  1,
+  0,
+  1,
+  1,
+  1,
+  0,
+  1
+};
index 31910c2c1cf5c3f411bb444acc2d2c444bc26b7c..1743a80bade70eadc87e1d67afb7fcb869dacfba 100644 (file)
@@ -51,6 +51,9 @@ target_link_libraries(scalarlsptest codec2)
 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)
+
 add_executable(t16_8 t16_8.c ../src/fdmdv.c ../src/kiss_fft.c)
 target_link_libraries(t16_8 codec2)
 
diff --git a/codec2-dev/unittest/tcohpsk.c b/codec2-dev/unittest/tcohpsk.c
new file mode 100644 (file)
index 0000000..96e4ac3
--- /dev/null
@@ -0,0 +1,95 @@
+/*---------------------------------------------------------------------------*\
+                                                                             
+  FILE........: tcopskv.c
+  AUTHOR......: David Rowe  
+  DATE CREATED: March 2015
+                                                                             
+  Tests for the C version of the cohernet PSK FDM modem.  This program
+  outputs a file of Octave vectors that are loaded and automatically
+  tested against the Octave version of the modem by the Octave script
+  tcohpsk.m
+                                                                             
+\*---------------------------------------------------------------------------*/
+
+/*
+  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 "fdmdv_internal.h"
+#include "codec2_fdmdv.h"
+#include "codec2_cohpsk.h"
+#include "cohpsk_defs.h"
+#include "test_bits_coh.h"
+#include "octave.h"
+
+#define FRAMES 35
+#define CHANNEL_BUF_SIZE (10*M)
+
+int main(int argc, char *argv[])
+{
+    int           tx_bits[COHPSK_BITS_PER_FRAME];
+    COMP          tx_symbols[NSYMROWPILOT][PILOTS_NC];
+    
+    int           tx_bits_log[COHPSK_BITS_PER_FRAME*FRAMES];
+    COMP          tx_symbols_log[NSYMROWPILOT*FRAMES][PILOTS_NC];
+                                          
+    FILE         *fout;
+    int           f, r,c,rx_sym_log_r;
+
+    rx_sym_log_r=0;
+
+    for(f=0; f<FRAMES; f++) {
+        
+       /* --------------------------------------------------------*\
+                                 Modulator
+       \*---------------------------------------------------------*/
+
+       bits_to_qpsk_symbols(tx_symbols, (int*)test_bits_coh, sizeof(test_bits_coh));
+
+       /* --------------------------------------------------------*\
+                              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(c=0; c<PILOTS_NC; c++) 
+               tx_symbols_log[rx_sym_log_r][c] = tx_symbols[r][c]; 
+        }
+       assert(rx_sym_log_r <= NSYMROWPILOT*FRAMES);
+    }
+
+
+    /*---------------------------------------------------------*\
+               Dump logs to Octave file for evaluation 
+                      by tcohpsk.m Octave script
+    \*---------------------------------------------------------*/
+
+    fout = fopen("tcohpsk_out.txt","wt");
+    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);  
+    fclose(fout);
+
+    return 0;
+}
+