C version modified to have UW distributed across frame, works OK, should hopefully...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 8 May 2018 21:33:51 +0000 (21:33 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 8 May 2018 21:33:51 +0000 (21:33 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@3586 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/src/interldpc.c
codec2-dev/src/ofdm.c
codec2-dev/src/ofdm_demod.c
codec2-dev/src/ofdm_internal.h
codec2-dev/src/test_bits_ofdm.h

index 718452810ec10f3ab64ca3d2099325d324800047..49322deb1e9e5049a9633850cbf71fc7f8e5d049 100644 (file)
@@ -188,6 +188,30 @@ int count_errors(int tx_bits[], char rx_bits[], int n) {
 }
 
 
+#ifdef NOT_USED
+/* UW never changes so we can pre-load tx_symbols with modulated UW */
+
+void build_modulated_uw(struct OFDM *ofdm, complex float tx_symbols[], uint8_t txt_bits[])
+{
+    int  uw_txt_bits[OFDM_NUWBITS+OFDM_NTXTBITS];
+    COMP uw_txt_syms[(OFDM_NUWBITS+OFDM_NTXTBITS)/OFDM_BPS];
+    int i,j;
+
+    for(i=0; i<OFDM_NUWBITS; i++) {
+        uw_txt_bits[i] = ofdm->tx_uw[i];
+    }
+    /* clear txt bits for now, they can be added in later */
+    for(j=0; j<OFDM_NTXTBITS; j++,i++) {
+        uw_txt_bits[i] = txt_bits[j];
+        //fprintf(stderr, "txt_bits[%d] = %d\n", j, txt_bits[j]);
+    }    
+    qpsk_modulate_frame(uw_txt_syms, uw_txt_bits, (OFDM_NUWBITS+OFDM_NTXTBITS)/OFDM_BPS);
+    for(i=0; i<(OFDM_NUWBITS+OFDM_NTXTBITS)/OFDM_BPS; i++) {
+        tx_symbols[i] = uw_txt_syms[i].real + I * uw_txt_syms[i].imag;
+    }
+}
+#endif
+
 /* 
    Given an array of tx_bits, LDPC encodes, interleaves, and OFDM
    modulates.
@@ -207,9 +231,8 @@ void ofdm_ldpc_interleave_tx(struct OFDM *ofdm, struct LDPC *ldpc, complex float
     COMP coded_symbols[interleave_frames*coded_syms_per_frame];
     COMP coded_symbols_inter[interleave_frames*coded_syms_per_frame];
     int Nsamperframe = ofdm_get_samples_per_frame();
-    complex float tx_symbols[(OFDM_NUWBITS+OFDM_NTXTBITS)/OFDM_BPS + coded_syms_per_frame];
-    int i,j;
+    complex float tx_symbols[OFDM_BITSPERFRAME/OFDM_BPS];
+    int j;
     
     for (j=0; j<interleave_frames; j++) {
         ldpc_encode_frame(ldpc, codeword, &tx_bits[j*data_bits_per_frame]);
@@ -217,34 +240,9 @@ void ofdm_ldpc_interleave_tx(struct OFDM *ofdm, struct LDPC *ldpc, complex float
     }
     gp_interleave_comp(coded_symbols_inter, coded_symbols, interleave_frames*coded_syms_per_frame);
     for (j=0; j<interleave_frames; j++) {            
-        /* todo: we don't need to build modulated UW every time, just txt bits */
-        build_modulated_uw(ofdm, tx_symbols, &txt_bits[OFDM_NTXTBITS*j]);
-        for(i=0; i<coded_syms_per_frame; i++) {
-            tx_symbols[(OFDM_NUWBITS+OFDM_NTXTBITS)/OFDM_BPS+i] = coded_symbols_inter[j*coded_syms_per_frame+i].real
-                + I * coded_symbols_inter[j*coded_syms_per_frame+i].imag;
-        }
+        ofdm_assemble_modem_frame(tx_symbols, &coded_symbols_inter[j*coded_syms_per_frame], &txt_bits[OFDM_NTXTBITS*j]);
         ofdm_txframe(ofdm, &tx_sams[j*Nsamperframe], tx_symbols);
     }
 }
 
-/* UW never changes so we can pre-load tx_symbols with modulated UW */
 
-void build_modulated_uw(struct OFDM *ofdm, complex float tx_symbols[], uint8_t txt_bits[])
-{
-    int  uw_txt_bits[OFDM_NUWBITS+OFDM_NTXTBITS];
-    COMP uw_txt_syms[(OFDM_NUWBITS+OFDM_NTXTBITS)/OFDM_BPS];
-    int i,j;
-
-    for(i=0; i<OFDM_NUWBITS; i++) {
-        uw_txt_bits[i] = ofdm->tx_uw[i];
-    }
-    /* clear txt bits for now, they can be added in later */
-    for(j=0; j<OFDM_NTXTBITS; j++,i++) {
-        uw_txt_bits[i] = txt_bits[j];
-        //fprintf(stderr, "txt_bits[%d] = %d\n", j, txt_bits[j]);
-    }    
-    qpsk_modulate_frame(uw_txt_syms, uw_txt_bits, (OFDM_NUWBITS+OFDM_NTXTBITS)/OFDM_BPS);
-    for(i=0; i<(OFDM_NUWBITS+OFDM_NTXTBITS)/OFDM_BPS; i++) {
-        tx_symbols[i] = uw_txt_syms[i].real + I * uw_txt_syms[i].imag;
-    }
-}
index 562991b3d643f75c49d1979d6ee7503b47aae92d..4c886847ab79d612e5c5d1180bb09e63e11282a2 100644 (file)
@@ -79,10 +79,17 @@ static const char pilotvalues[] = {
 };
 
 /*
- * Unique word used to verify we have modem frame sync
+ * A Unique Word (UW) used to verify we have modem frame sync when we
+ * try a candidate coarse timing and freq offset.  The UW bits/symbols
+ * are distributed through the modem frame using the index (ind)
+ * tables below.  The indexes in uw_nd_sym [] and uw_ind are Octave
+ * start from 1 format, subtract 1 to index C arrays.
  */
 
-static const int tx_uw[] = {1,0,0,1,0,1,0,0,1,0};
+static const int tx_uw[]          = {0,0,0,0,0,0,0,0,0,0};            /* UW bits    */
+static complex float tx_uw_syms[] = {1.0f,1.0f,1.0f,1.0f,1.0f};       /* UW QPSK symbols */
+static const int uw_ind[]         = {19,20,37,38,55,56,73,74,91,92};  /* index in modem frame of UW bits */
+static const int uw_ind_sym[]     = {10,19,28,37,46};                 /* index into modem frame of UW symbols */
 
 /* Functions -------------------------------------------------------------------*/
 
@@ -1213,3 +1220,77 @@ void ofdm_get_demod_stats(struct OFDM *ofdm, struct MODEM_STATS *stats)
     }
 }
 
+
+/* Assemble modem frame from UW, payload symbols, and txt bits */
+
+void ofdm_assemble_modem_frame(complex float modem_frame[],
+                               COMP    payload_syms[],
+                               uint8_t txt_bits[])
+{
+  int Nsymsperframe = OFDM_BITSPERFRAME/OFDM_BPS;
+  int Nuwsyms = OFDM_NUWBITS/OFDM_BPS;
+  int Ntxtsyms = OFDM_NTXTBITS/OFDM_BPS;
+
+  int s,p=0,u=0;
+
+  for (s=0; s<Nsymsperframe-Ntxtsyms; s++) {
+      if ((u < Nuwsyms) && (s == (uw_ind_sym[u]-1))) {
+          modem_frame[s] = tx_uw_syms[u++];
+      } else {
+          modem_frame[s] = payload_syms[p].real + payload_syms[p].imag * I;
+          p++;
+      }
+  }
+  assert(u == Nuwsyms);
+  assert(p == (Nsymsperframe-Nuwsyms-Ntxtsyms));
+
+  int t; int dibit[2];
+
+  for (t=0; s<Nsymsperframe; s++,t+=OFDM_BPS) {
+      dibit[0] = txt_bits[t+1] & 0x1;
+      dibit[1] = txt_bits[t] & 0x1;
+      modem_frame[s] = qpsk_mod(dibit);
+  }
+  assert(t == OFDM_NTXTBITS);
+}
+
+
+void ofdm_disassemble_modem_frame(struct OFDM   *ofdm,
+                                  int            rx_uw[],
+                                  COMP           codeword_syms[],
+                                  float          codeword_amps[],
+                                  int            txt_bits[])
+{
+  int Nsymsperframe = OFDM_BITSPERFRAME/OFDM_BPS;
+  int Nuwsyms = OFDM_NUWBITS/OFDM_BPS;
+  int Ntxtsyms = OFDM_NTXTBITS/OFDM_BPS;
+  int dibit[2];
+  
+  int s,p=0,u=0;
+
+  for (s=0; s<Nsymsperframe-Ntxtsyms; s++) {
+      if ((u < Nuwsyms) && (s == (uw_ind_sym[u]-1))) {
+          qpsk_demod(ofdm->rx_np[s], dibit);
+          rx_uw[OFDM_BPS*u]   = dibit[1];
+          rx_uw[OFDM_BPS*u+1] = dibit[0];
+          u++;
+      } else {
+          codeword_syms[p].real = crealf(ofdm->rx_np[s]);
+          codeword_syms[p].imag = cimagf(ofdm->rx_np[s]);
+          codeword_amps[p] = ofdm->rx_amp[s];
+          p++;
+      }
+  }
+  assert(u == Nuwsyms);
+  assert(p == (Nsymsperframe-Nuwsyms-Ntxtsyms));
+
+  int t;
+
+  for (t=0; s<Nsymsperframe; s++,t+=OFDM_BPS) {
+      qpsk_demod(ofdm->rx_np[s], dibit);
+      txt_bits[t]   = dibit[1];
+      txt_bits[t+1] = dibit[0];
+  }
+  assert(t == OFDM_NTXTBITS);
+}
+
index 0ee5f0d445e6ac9823ebda475799fed9de00bf49..e60f6c8ac8b828fceab49650ed06d7f63ac1ed82 100644 (file)
@@ -181,6 +181,7 @@ int main(int argc, char *argv[])
     int    rx_bits[Nbitsperframe];
     char   rx_bits_char[Nbitsperframe];
     int    rx_uw[OFDM_NUWBITS];
+    int    txt_bits[OFDM_NTXTBITS];
     f = 0; Nerrs = Terrs = Tbits = Terrs2 = Tbits2 = Terrs_coded = Tbits_coded = frame_count = 0;
 
     float EsNo = 3;
@@ -188,6 +189,8 @@ int main(int argc, char *argv[])
 
     float snr_est_smoothed_dB = 0.0;
 
+    COMP  payload_syms[coded_syms_per_frame];
+    float payload_amps[coded_syms_per_frame];
     COMP  codeword_symbols[interleave_frames*coded_syms_per_frame];
     float codeword_amps[interleave_frames*coded_syms_per_frame];
     for (i=0; i<interleave_frames*coded_syms_per_frame; i++) {
@@ -212,6 +215,7 @@ int main(int argc, char *argv[])
         
         if ((strcmp(ofdm->sync_state,"synced") == 0) || (strcmp(ofdm->sync_state,"trial") == 0) ) {
             ofdm_demod(ofdm, rx_bits, rxbuf_in);
+            ofdm_disassemble_modem_frame(ofdm, rx_uw, payload_syms, payload_amps, txt_bits);
             
             if (llr_en) {
                 
@@ -229,13 +233,11 @@ int main(int argc, char *argv[])
                     codeword_amps[i] = codeword_amps[j];
                 }
 
-                /* newest symbols at end of buffer (uses final i from last loop), note we 
-                   change COMP formats from what modem uses internally */
+                /* newest symbols at end of buffer (uses final i from last loop) */
                 
-                for(i=(interleave_frames-1)*coded_syms_per_frame,j=(OFDM_NUWBITS+OFDM_NTXTBITS)/OFDM_BPS; i<interleave_frames*coded_syms_per_frame; i++,j++) {
-                    codeword_symbols[i].real = crealf(ofdm->rx_np[j]);
-                    codeword_symbols[i].imag = cimagf(ofdm->rx_np[j]);
-                    codeword_amps[i] = ofdm->rx_amp[j];
+                for(i=(interleave_frames-1)*coded_syms_per_frame,j=0; i<interleave_frames*coded_syms_per_frame; i++,j++) {
+                    codeword_symbols[i] = payload_syms[j];
+                    codeword_amps[i]    = payload_amps[j];
                 }
                
                 /* run de-interleaver */
@@ -295,12 +297,6 @@ int main(int argc, char *argv[])
                 fwrite(rx_bits_char, sizeof(char), Nbitsperframe, fout);
             }
 
-            /* extract Unique Word bits */
-
-            for(i=0; i<OFDM_NUWBITS; i++) {
-                rx_uw[i] = rx_bits[i];
-            }
-
             /* optional error counting on uncoded data in non-LDPC testframe mode */
             
             if (testframes && (ldpc_en == 0)) {
index 119dd51359a880061dce4e17eda4469051f659b9..32dd6a77f66214cb1a5655fed5c8cdf99d72aac4 100644 (file)
@@ -34,6 +34,7 @@ extern "C" {
 
 #include <complex.h>
 #include <stdbool.h>
+#include <stdint.h>
 
 #include "codec2_ofdm.h"
 
@@ -155,7 +156,12 @@ struct OFDM {
 complex float qpsk_mod(int *);
 void qpsk_demod(complex float, int *);
 void ofdm_txframe(struct OFDM *, complex float tx_samples[OFDM_SAMPLESPERFRAME], complex float tx_symbols_lin[]);
-
+void ofdm_assemble_modem_frame(complex float modem_frame[], COMP payload_syms[], uint8_t txt_bits[]);
+void ofdm_disassemble_modem_frame(struct OFDM   *ofdm,
+                                  int            rx_uw[],
+                                  COMP           codeword_syms[],
+                                  float          codeword_amps[],
+                                  int            txt_bits[]);
 #ifdef __cplusplus
 }
 #endif
index 423626e51461eb4a236705fd1b7bbe51647201bd..9dacb51453de6a7f15b313e05bfe07ba0af1d79e 100644 (file)
@@ -2,29 +2,17 @@
 
 const int test_bits_ofdm[]={
   1,
-  0,
-  0,
   1,
   0,
   1,
-  0,
-  0,
   1,
   0,
-  0,
-  0,
-  0,
-  0,
-  1,
   1,
   0,
-  1,
-  1,
   0,
   1,
   0,
   0,
-  1,
   0,
   0,
   0,
@@ -53,6 +41,8 @@ const int test_bits_ofdm[]={
   0,
   0,
   0,
+  0,
+  0,
   1,
   0,
   0,
@@ -66,6 +56,8 @@ const int test_bits_ofdm[]={
   1,
   0,
   0,
+  0,
+  0,
   1,
   1,
   1,
@@ -82,6 +74,8 @@ const int test_bits_ofdm[]={
   1,
   0,
   0,
+  0,
+  0,
   1,
   0,
   0,
@@ -100,6 +94,8 @@ const int test_bits_ofdm[]={
   0,
   0,
   0,
+  0,
+  0,
   1,
   0,
   0,
@@ -238,7 +234,11 @@ const int test_bits_ofdm[]={
   0,
   0,
   0,
-  1
+  1,
+  0,
+  0,
+  0,
+  0
 };
 
 const int payload_data_bits[]={