tofdm passing with Demod2D and Somap functions, good progress towards LDPC integration
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 12 Apr 2018 23:12:25 +0000 (23:12 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 12 Apr 2018 23:12:25 +0000 (23:12 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@3472 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/tofdm.m
codec2-dev/src/CMakeLists.txt
codec2-dev/src/mpdecode_core.c
codec2-dev/src/mpdecode_core.h
codec2-dev/src/ofdm_demod.c
codec2-dev/src/ofdm_internal.h
codec2-dev/unittest/CMakeLists.txt
codec2-dev/unittest/tofdm.c

index 7e9eb586021daa636619a9a5fcda8d12cb33d95d..264e2b7006bdfddf777c72752fd14520cc211444 100644 (file)
@@ -5,13 +5,26 @@
 
 % ------------------------------------------------------------------
 
-Nframes = 30;
+Nframes = 3;
 sample_clock_offset_ppm = 100;
 foff_hz = 0.5;
 
 more off; format;
 ofdm_lib;
 autotest;
+ldpc
+
+% attempt to start up CML, path will be different on your machine
+
+path_to_cml = '/home/david/Desktop/cml/mex';
+addpath(path_to_cml);
+cml_support = 0;
+if exist("Somap") == 0
+  printf("Can't find CML mex directory so we won't run those tests for now...\n");
+else
+  printf("OK found CML mex directory so will add those tests...\n");
+  cml_support = 1;
+end
 
 % ---------------------------------------------------------------------
 % Run Octave version 
@@ -64,6 +77,12 @@ if states.timing_en == 0
   states.sample_point = Ncp;
 end
 
+if cml_support
+  Nuwtxtsymbolsperframe = (states.Nuwbits+states.Ntxtbits)/bps;
+  S_matrix = [1, j, -j, -1];
+  EsNo = 10;
+  symbol_likelihood_log = bit_likelihood_log = [];
+end
 
 for f=1:Nframes
 
@@ -97,6 +116,16 @@ for f=1:Nframes
   sample_point_log = [sample_point_log; states.sample_point];
   rx_np_log = [rx_np_log arx_np];
   rx_bits_log = [rx_bits_log rx_bits];
+
+  % Optional testing of LDPC functions
+
+  if cml_support
+    symbol_likelihood = Demod2D(arx_np(Nuwtxtsymbolsperframe+1:end), S_matrix, EsNo, arx_amp(Nuwtxtsymbolsperframe+1:end));
+    bit_likelihood = Somap(symbol_likelihood);
+    [m n] = size(symbol_likelihood);
+    symbol_likelihood_log = [symbol_likelihood_log; reshape(symbol_likelihood,m*n,1)];
+    bit_likelihood_log = [bit_likelihood_log; bit_likelihood'];
+  end
   
 end
 
@@ -171,4 +200,6 @@ check(coarse_foff_est_hz_log, coarse_foff_est_hz_log_c, 'coarse_foff_est_hz');
 check(sample_point_log, sample_point_log_c, 'sample_point');
 check(foff_hz_log, foff_hz_log_c, 'foff_est_hz');
 check(rx_bits_log, rx_bits_log_c, 'rx_bits');
+check(symbol_likelihood_log, symbol_likelihood_log_c, 'symbol_likelihood_log');
+check(bit_likelihood_log, bit_likelihood_log_c, 'bit_likelihood_log');
 
index b9b761c4b78d1ab784dfd63fba13cb9dc00babdd..b071a9a5260546bc038e4d6b09b976695c45f4f9 100644 (file)
@@ -340,7 +340,7 @@ target_link_libraries(ofdm_put_test_bits ${CMAKE_REQUIRED_LIBRARIES} codec2)
 add_executable(ofdm_mod ofdm_mod.c)
 target_link_libraries(ofdm_mod ${CMAKE_REQUIRED_LIBRARIES} codec2)
 
-add_executable(ofdm_demod ofdm_demod.c octave.c)
+add_executable(ofdm_demod ofdm_demod.c octave.c mpdecode_core.c)
 target_link_libraries(ofdm_demod ${CMAKE_REQUIRED_LIBRARIES} codec2)
 
 add_executable(fmfsk_mod fmfsk_mod.c)
index 9faf31b30b067d4f5f531a293e392aa308ba5ddc..28d1609bbbdfb0a698fc9e595625439694812fb6 100644 (file)
@@ -729,22 +729,26 @@ void sd_to_llr(double llr[], double sd[], int n) {
 
 
 /*
-   output[] is symbol likelihood
+   Determine symbol likelihood from received QPSK symbols.
 
-   Note we assume fading[] is real, it is also possible to compute
-   with complex fading.
+   Notes:
+
+   1) We assume fading[] is real, it is also possible to compute
+      with complex fading, see CML library Demod2D.c source code.
+   2) Using doubles, as experience with FSK in drs232_ldpc.c showed
+      doubles were required to obtain the same answers as Octave.
 */
 
-void Demod2D(float  symbol_likelihood[],       /* output, M*number_symbols              */
-             COMP   r[],                       /* received QPSK symbols, number_symbols */
-             COMP   S_matrix[],                /* constellation of size M               */
-             float  EsNo,
-             float  fading[],                  /* real fading values, number_symbols    */
-             int    number_symbols)
+void Demod2D(double  symbol_likelihood[],       /* output, M*number_symbols              */
+             COMP    r[],                       /* received QPSK symbols, number_symbols */
+             COMP    S_matrix[],                /* constellation of size M               */
+             float   EsNo,
+             float   fading[],                  /* real fading values, number_symbols    */
+             int     number_symbols)
 {
     int     M=4;
     int     i,j;
-    float   tempsr, tempsi, Er, Ei;
+    double  tempsr, tempsi, Er, Ei;
 
     /* determine output */
   
@@ -755,20 +759,22 @@ void Demod2D(float  symbol_likelihood[],       /* output, M*number_symbols
             Er = r[i].real - tempsr;
             Ei = r[i].imag - tempsi;
             symbol_likelihood[i*M+j] = -EsNo*(Er*Er+Ei*Ei);
+            //printf("symbol_likelihood[%d][%d] = %f\n", i,j,symbol_likelihood[i*M+j]);
         }
+        //exit(0);
     }
 
 }
 
 
-void Somap(float  bit_likelihood[],      /* number_bits, bps*number_symbols */
-           float  symbol_likelihood[],   /* M*number_symbols                */
-           int    number_symbols)
+void Somap(double  bit_likelihood[],      /* number_bits, bps*number_symbols */
+           double  symbol_likelihood[],   /* M*number_symbols                */
+           int     number_symbols)
 {
-    int   M=2, bps = 2;
-    int   n,i,j,k,mask;
-    float num[bps], den[bps];
-    float metric;
+    int    M=4, bps = 2;
+    int    n,i,j,k,mask;
+    double num[bps], den[bps];
+    double metric;
 
     for (n=0; n<number_symbols; n++) { /* loop over symbols */
         for (k=0;k<bps;k++) {
@@ -803,6 +809,7 @@ void Somap(float  bit_likelihood[],      /* number_bits, bps*number_symbols */
     }
 }
 
+
 int extract_output(char out_char[], int DecodedBits[], int ParityCheckCount[], int max_iter, int CodeLength, int NumberParityBits) {
     int i, j;
 
index 308a930d54b98a51669cbf4d10717ce3984715bf..82d27a443b33910cea5a7a00c815f6f8cdd0af72 100644 (file)
@@ -31,8 +31,8 @@ int run_ldpc_decoder(struct LDPC *ldpc, char out_char[], double input[], int *pa
 
 void sd_to_llr(double llr[], double sd[], int n);
 
-void Demod2D(float symbol_likelihood[], COMP r[], COMP S_matrix[], float EsNo, float fading[], int number_symbols);
-void SomapDemod2D(float bit_likelihood[], float symbol_likelihood[]);
+void Demod2D(double symbol_likelihood[], COMP r[], COMP S_matrix[], float EsNo, float fading[], int number_symbols);
+void Somap(double bit_likelihood[], double symbol_likelihood[], int number_symbols);
 
 struct v_node {
   int degree;
index 6dd1f011c3f4d3d09abc7af4145722f4f9957aef..8905e23645492f94c8114ab6a20e20007ad0868e 100644 (file)
 #define NDISCARD 20               /* BER2measure disctrds first 20 frames */
 #define CODED_BITSPERFRAME 224    /* number of LDPC codeword bits/frame   */
 
-/* QPSK constellation for symbol likelihood calculations */
-
-static COMP S_matrix[] = {
-    { 1.0f,  0.0f},
-    { 0.0f,  1.0f},
-    { 0.0f, -1.0f},
-    {-1.0f,  0.0f}
-};
-         
 int opt_exists(char *argv[], int argc, char opt[]) {
     int i;
     for (i=0; i<argc; i++) {
index dcd99b8ad73cfbf43b63f006b9ef8f577bee29e2..aeda31751f66a6c54ef111bce9f61d426c6b6ef4 100644 (file)
@@ -135,6 +135,15 @@ struct OFDM {
     int sync_end;
 };
 
+/* QPSK constellation for symbol likelihood calculations */
+
+static COMP S_matrix[] = {
+    { 1.0f,  0.0f},
+    { 0.0f,  1.0f},
+    { 0.0f, -1.0f},
+    {-1.0f,  0.0f}
+};
+         
 #ifdef __cplusplus
 }
 #endif
index e5c12be83565deccbcfe4a6a8b1d885178ccdd3a..60796edf05ae8a95b71565b62092fa37c4b812de 100644 (file)
@@ -52,7 +52,7 @@ add_executable(tdeframer tdeframer.c)
 target_link_libraries(tdeframer m codec2)
 
 add_definitions(-DMODEMPROBE_ENABLE -DXXXXX)
-add_executable(tofdm tofdm.c ../src/ofdm.c ../src/octave.c ../src/kiss_fft.c ../src/modem_probe.c)
+add_executable(tofdm tofdm.c ../src/ofdm.c ../src/octave.c ../src/kiss_fft.c ../src/modem_probe.c ../src/mpdecode_core.c)
 target_link_libraries(tofdm m)
 
 add_executable(tfreedv_data_channel tfreedv_data_channel.c)
index 18f440f45c093628bb7ffec9c8dc8ccb22660a56..13659868b2f280a91581a14d162521c6af8afafd 100644 (file)
 #include "octave.h"
 #include "test_bits_ofdm.h"
 #include "comp_prim.h"
+#include "mpdecode_core.h"
 
-#define NFRAMES 30
+#define NFRAMES                   3
 #define SAMPLE_CLOCK_OFFSET_PPM 100
-#define FOFF_HZ 0.5f
+#define FOFF_HZ                 0.5f
 
-#define ASCALE  (2E5*1.1491/2.0) /* scale from shorts back to floats */
+#define ASCALE  (2E5*1.1491/2.0)  /* scale from shorts back to floats */
+
+#define CODED_BITSPERFRAME 224    /* number of LDPC codeword bits/frame   */
 
 /*---------------------------------------------------------------------------*\
 
@@ -147,7 +150,9 @@ int main(int argc, char *argv[])
     float          timing_mx_log[NFRAMES];
     float          coarse_foff_est_hz_log[NFRAMES];
     int            sample_point_log[NFRAMES];
-
+    float          symbol_likelihood_log[ (CODED_BITSPERFRAME/OFDM_BPS) * (1<<OFDM_BPS) * NFRAMES];
+    float          bit_likelihood_log[CODED_BITSPERFRAME * NFRAMES];        
+        
     FILE          *fout;
     int            f,i,j;
 
@@ -259,6 +264,8 @@ int main(int argc, char *argv[])
         }
         #endif
 
+        /* uncoded OFDM modem ---------------------------------------*/
+        
         ofdm_demod(ofdm, rx_bits, rxbuf_in);
         
         #ifdef TESTING_FILE
@@ -271,6 +278,26 @@ int main(int argc, char *argv[])
         printf("f: %d Nerr: %d\n", f, Nerrs);
         #endif
         
+        /* LDPC functions --------------------------------------*/
+
+        double symbol_likelihood[ (CODED_BITSPERFRAME/OFDM_BPS) * (1<<OFDM_BPS) ];
+        double bit_likelihood[CODED_BITSPERFRAME];
+        float EsNo = 10;
+        
+        /* first few symbols are used for UW and txt bits, find start of (224,112) LDPC codeword */
+
+        assert((OFDM_NUWBITS+OFDM_NTXTBITS+CODED_BITSPERFRAME) == OFDM_BITSPERFRAME);
+
+        COMP ldpc_codeword_symbols[(CODED_BITSPERFRAME/OFDM_BPS)];
+        for(i=0, j=(OFDM_NUWBITS+OFDM_NTXTBITS)/OFDM_BPS; i<(CODED_BITSPERFRAME/OFDM_BPS); i++,j++) {
+            ldpc_codeword_symbols[i].real = crealf(ofdm->rx_np[j]);
+            ldpc_codeword_symbols[i].imag = cimagf(ofdm->rx_np[j]);
+        }
+        float *ldpc_codeword_symbol_amps = &ofdm->rx_amp[(OFDM_NUWBITS+OFDM_NTXTBITS)/OFDM_BPS];
+                
+        Demod2D(symbol_likelihood, ldpc_codeword_symbols, S_matrix, EsNo, ldpc_codeword_symbol_amps,  CODED_BITSPERFRAME/OFDM_BPS);
+        Somap(bit_likelihood, symbol_likelihood, CODED_BITSPERFRAME/OFDM_BPS);
+
         /* rx vector logging -----------------------------------*/
 
         assert(nin_tot < samples_per_frame*NFRAMES);
@@ -313,6 +340,13 @@ int main(int argc, char *argv[])
         sample_point_log[f] = ofdm->sample_point + 1; /* offset by 1 to match Octave */
 
         memcpy(&rx_bits_log[OFDM_BITSPERFRAME*f], rx_bits, sizeof(rx_bits));
+
+        for(i=0; i<(CODED_BITSPERFRAME/OFDM_BPS) * (1<<OFDM_BPS); i++) {
+            symbol_likelihood_log[ (CODED_BITSPERFRAME/OFDM_BPS) * (1<<OFDM_BPS) * f + i] = symbol_likelihood[i];
+        }
+        for(i=0; i<CODED_BITSPERFRAME; i++) {
+            bit_likelihood_log[CODED_BITSPERFRAME*f + i] =  bit_likelihood[i];
+        }
     }
 
     /*---------------------------------------------------------*\
@@ -341,6 +375,8 @@ int main(int argc, char *argv[])
     octave_save_int(fout, "sample_point_log_c", sample_point_log, NFRAMES, 1);
     octave_save_complex(fout, "rx_np_log_c", (COMP*)rx_np_log, 1, OFDM_ROWSPERFRAME*OFDM_NC*NFRAMES, OFDM_ROWSPERFRAME*OFDM_NC*NFRAMES);
     octave_save_int(fout, "rx_bits_log_c", rx_bits_log, 1, OFDM_BITSPERFRAME*NFRAMES);
+    octave_save_float(fout, "symbol_likelihood_log_c", symbol_likelihood_log, (CODED_BITSPERFRAME/OFDM_BPS) * (1<<OFDM_BPS) * NFRAMES, 1, 1);
+    octave_save_float(fout, "bit_likelihood_log_c", bit_likelihood_log, CODED_BITSPERFRAME * NFRAMES, 1, 1);
     fclose(fout);
 
     ofdm_destroy(ofdm);