added acquisition function ofdm_search_sync to C and Octave and tofdm framewor, todsm...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 24 Mar 2018 22:25:52 +0000 (22:25 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 24 Mar 2018 22:25:52 +0000 (22:25 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@3432 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/ofdm_lib.m
codec2-dev/octave/ofdm_rx.m
codec2-dev/octave/ofdm_tx.m
codec2-dev/src/ofdm.c
codec2-dev/src/ofdm_mod.c
codec2-dev/unittest/tofdm.c

index 2cf282bcb74fb2f2d8c96bb0b1884e0167e39f90..38452686e62a7c9788b604a2672b9f7886df120e 100644 (file)
@@ -202,7 +202,10 @@ function states = ofdm_init(bps, Rs, Tcp, Ns, Nc)
   states.foff_est_hz = 0;
   states.sample_point = states.timing_est = 1;
   states.nin = states.Nsamperframe;
-
+  states.timing_valid = 0;
+  states.timing_mx = 0;
+  states.coarse_foff_est_hz = 0;
+  
   % generate OFDM pilot symbol, used for timing and freq offset est
 
   rate_fs_pilot_samples = states.pilots * W/states.M;
@@ -219,6 +222,10 @@ function states = ofdm_init(bps, Rs, Tcp, Ns, Nc)
   states.rate = 1.0;
   states.ldpc_en = 0;
 
+  % init some output states for logging
+  
+  states.rx_sym = zeros(1+Ns+1+1, Nc+2);
+
 endfunction
 
 
@@ -289,6 +296,46 @@ function tx = ofdm_txframe(states, tx_sym_lin)
 endfunction
 
 
+% ----------------------------------------------------------------------------------
+% ofdm_sync_search - attempts to find coarse sync parameters for modem initial sync
+% ----------------------------------------------------------------------------------
+
+function [timing_valid states] = ofdm_sync_search(states, rxbuf_in)
+  ofdm_load_const;
+
+  % insert latest input samples into rxbuf so it is primed for when we have to call ofdm_demod()
+
+  states.rxbuf(1:Nrxbuf-states.nin) = states.rxbuf(states.nin+1:Nrxbuf);
+  states.rxbuf(Nrxbuf-states.nin+1:Nrxbuf) = rxbuf_in;
+
+  % Attempt coarse timing estimate (i.e. detect start of frame)
+
+  st = M+Ncp + Nsamperframe + 1; en = st + 2*Nsamperframe; 
+  [ct_est foff_est timing_valid timing_mx] = coarse_sync(states, states.rxbuf(st:en), states.rate_fs_pilot_samples);
+  if states.verbose
+    printf("   ct_est: %4d foff_est: %3.1f timing_valid: %d timing_mx: %d\n", ct_est, foff_est, timing_valid, timing_mx);
+  end
+
+  if timing_valid
+    % potential candidate found ....
+
+    % calculate number of samples we need on next buffer to get into sync
+
+    states.nin = Nsamperframe + ct_est - 1;
+
+    % reset modem states
+
+    states.sample_point = states.timing_est = 1;
+    states.foff_est_hz = foff_est;
+  else
+    states.nin = Nsamperframe;
+  end
+  states.timing_valid = timing_valid;
+  states.timing_mx = timing_mx;
+  states.coarse_foff_est_hz = foff_est;
+endfunction
+
+
 % ------------------------------------------
 % ofdm_demod - Demodulates one frame of bits
 % ------------------------------------------
index ccd854c720401712892743e386baa1c562ee20b0..e8785598ef8114a1bb63f3fd28b361e7ebf282b1 100644 (file)
@@ -74,66 +74,34 @@ function ofdm_rx(filename, error_pattern_filename)
     end
     prx += states.nin;
 
-    printf("  states.nin: %d\n", states.nin);
-    [rx_bits states aphase_est_pilot_log arx_np arx_amp] = ofdm_demod(states, rxbuf_in);
-
-    errors = xor(tx_bits, rx_bits);
-    Nerrs = sum(errors);
-    aber = Nerrs/Nbitsperframe;
-    
-    frame_count++;
-
-    printf("f: %d state: %s Nerrs: %d aber: %3.2f\n", f, state, Nerrs, aber);
-
+    printf("f: %d state: %s nin: %d\n", f, state, nin);
     % If looking for sync: check raw BER on frame just received
     % against all possible positions in the interleaver frame.
 
     % iterate state machine ------------------------------------
 
     next_state = state;
-    if strcmp(state,'searching')  
 
-      % If looking for sync: check raw BER on frame just received
-      % against all possible positions in the interleaver frame.
+    if strcmp(state,'searching') 
+      [timing_valid states] = ofdm_sync_search(states, rxbuf_in);
 
-      if aber < 0.1
+      if timing_valid
         next_state = 'synced';
-        % make sure we get an interleave frame with correct freq offset
-        % note this introduces a lot of delay, a better idea would be to
-        % run demod again from interleave_frames back with now-known freq offset
-      end
-    end
-
-    if strcmp(state,'synced')  
-      if Nerrs/Nbitsperframe > 0.2
-        %next_state = 'searching';
       end
     end
+        
+    if strcmp(state,'synced')
 
-    state = next_state;
-
-    if strcmp(state,'searching') 
-
-      % still searching? Attempt coarse timing estimate (i.e. detect start of frame)
-
-      st = M+Ncp + Nsamperframe + 1; en = st + 2*Nsamperframe; 
-      [ct_est foff_est] = coarse_sync(states, states.rxbuf(st:en), states.rate_fs_pilot_samples);
-      if states.verbose
-        printf("   Nerrs: %d ct_est: %4d foff_est: %3.1f\n", Nerrs, ct_est, foff_est);
-      end
-
-      % calculate number of samples we need on next buffer to get into sync
-     
-      states.nin = Nsamperframe + ct_est - 1;
-      
-      % reset modem states
+      printf("  states.nin: %d\n", states.nin);
+      [rx_bits states aphase_est_pilot_log arx_np arx_amp] = ofdm_demod(states, rxbuf_in);
 
-      states.sample_point = states.timing_est = 1;
-      states.foff_est_hz = foff_est;
-    end
+      errors = xor(tx_bits, rx_bits);
+      Nerrs = sum(errors);
+      aber = Nerrs/Nbitsperframe;
     
-    if strcmp(state,'synced')
-
+      frame_count++;
+     
       % we are in sync so log states
 
       rx_np_log = [rx_np_log arx_np];
@@ -150,6 +118,9 @@ function ofdm_rx(filename, error_pattern_filename)
         Tbits += Nbitsperframe;
       end
     end
+
+    state = next_state;
+
   end
 
   printf("BER..: %5.4f Tbits: %5d Terrs: %5d\n", Terrs/Tbits, Tbits, Terrs);
index 174743e5a4e72695a55510566eb23a9a2836c585..67cd5658382032af37333a235c13209001e69943 100644 (file)
@@ -9,7 +9,7 @@
  
   i) 10 seconds, AWGN channel at Eb/No=3dB
 
-    octave:4> ofdm_tx('awgn_ebno_3dB_700d.raw', 10,3);
+    octave:4> ofdm_tx('awgn_ebno_3dB_700d.raw', 10, 3);
 
   ii) 10 seconds, HF channel at Eb/No=6dB
 
index bc87943a38b7b912e1d2bdb651f09c29e3092502..f110c5de1446c85d91aa247c02320c8b443b86b4 100644 (file)
@@ -163,7 +163,7 @@ static int coarse_sync(struct OFDM *ofdm, complex float *rx, int length, float *
 
     complex float acc =  0.0f + 0.0f * I;
     for (i = 0; i < length; i++) {
-        acc += rx[i] * conjf(rx[i]);
+        acc += crealf(rx[i]) * crealf(rx[i]) + cimagf(rx[i]) * cimagf(rx[i]);
     }
             
     av_level = 2.0*sqrt(ofdm->timing_norm*crealf(acc)/length) + 1E-12;
@@ -243,7 +243,7 @@ static int coarse_sync(struct OFDM *ofdm, complex float *rx, int length, float *
  */
 
 static void ofdm_txframe(struct OFDM *ofdm, complex float tx[OFDM_SAMPLESPERFRAME],
-        complex float *tx_sym_lin) {
+    complex float *tx_sym_lin) {
     complex float aframe[OFDM_NS][OFDM_NC + 2];
     complex float asymbol[OFDM_M];
     complex float asymbol_cp[OFDM_M + OFDM_NCP];
@@ -355,6 +355,17 @@ struct OFDM *ofdm_create(const struct OFDM_CONFIG * config) {
         }
     }
 
+    for (i = 0; i < OFDM_ROWSPERFRAME*OFDM_NC; i++) {
+        ofdm->rx_np[i] = 0.0f + 0.0f * I;
+    }
+    
+    for (i = 0; i < OFDM_ROWSPERFRAME; i++) {
+        for (j = 0; j < OFDM_NC; j++) {
+            ofdm->aphase_est_pilot_log[OFDM_NC*i+j] = 0.0f + 0.0f * I;
+            ofdm->rx_amp[OFDM_NC*i+j] = 0.0f + 0.0f * I;
+        }
+    }
+
     /* default settings of options and states */
 
     ofdm->verbose = 0;
@@ -490,6 +501,61 @@ void ofdm_mod(struct OFDM *ofdm, COMP result[OFDM_SAMPLESPERFRAME], const int *t
     }
 }
 
+
+/*
+ * ----------------------------------------------------------------------------------
+ * ofdm_sync_search - attempts to find coarse sync parameters for modem initial sync
+ * ----------------------------------------------------------------------------------
+ */
+
+int ofdm_sync_search(struct OFDM *ofdm, COMP *rxbuf_in)
+{
+    int i,j;
+    
+    /* insert latest input samples into rxbuf so it is primed for when
+       we have to call ofdm_demod() */
+
+    for (i = 0, j = ofdm->nin; i < (OFDM_RXBUF - ofdm->nin); i++, j++) {
+        ofdm->rxbuf[i] = ofdm->rxbuf[j];
+    }
+
+    /* insert latest input samples onto tail of rxbuf */
+
+    for (i = (OFDM_RXBUF - ofdm->nin), j = 0; i < OFDM_RXBUF; i++, j++) {
+        ofdm->rxbuf[i] = rxbuf_in[j].real + rxbuf_in[j].imag * I;
+    }
+
+    /* Attempt coarse timing estimate (i.e. detect start of frame) */
+
+    int st = OFDM_M + OFDM_NCP + OFDM_SAMPLESPERFRAME;
+    int en = st + 2*OFDM_SAMPLESPERFRAME; 
+    int ct_est = coarse_sync(ofdm,  &ofdm->rxbuf[st], (en - st), &ofdm->coarse_foff_est_hz);
+    if (ofdm->verbose) {
+        fprintf(stderr, "   ct_est: %4d foff_est: %3.1f timing_valid: %d timing_mx: %f\n",
+                ct_est, ofdm->coarse_foff_est_hz, ofdm->timing_valid, ofdm->timing_mx);
+    }
+
+    if (ofdm->timing_valid) {
+        /* potential candidate found .... */
+
+        /* calculate number of samples we need on next buffer to get into sync */
+
+       ofdm->nin = OFDM_SAMPLESPERFRAME + ct_est;
+
+       /* reset modem states */
+
+       ofdm->sample_point = ofdm->timing_est = 0;
+       ofdm->foff_est_hz = ofdm->coarse_foff_est_hz;
+    }
+    else {
+        ofdm->nin = OFDM_SAMPLESPERFRAME;
+    }
+
+    return ofdm->timing_valid;
+}
+
+
+
 /*
  * ------------------------------------------
  * ofdm_demod - Demodulates one frame of bits
index 67735c9827855be72414ad37b486fa297c5c11b4..626d0ac8dfc731c3eaf8684825d0fbf9d6104bae 100644 (file)
@@ -64,18 +64,18 @@ int main(int argc, char *argv[])
 
     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);
+        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);
+        fprintf(stderr, "Error opening output modem sample file: %s: %s.\n",
+                argv[2], strerror(errno));
+        exit(1);
     }
-
+    
     ofdm = ofdm_create(OFDM_CONFIG_700D);
     assert(ofdm != NULL);
     int Nbitsperframe = ofdm_get_bits_per_frame(ofdm);
index ce97a9aade128e28eda168cc40a69d6c352c165d..19aeda991939f4e90a33cce5c5f14f38b3d4d6d0 100644 (file)
@@ -149,11 +149,13 @@ int main(int argc, char *argv[])
     int            sample_point_log[NFRAMES];
 
     FILE          *fout;
-    int            f,i,j;
+    int            f,i,j, state, next_state;
 
     ofdm = ofdm_create(OFDM_CONFIG_700D);
     assert(ofdm != NULL);
 
+    state = OFDM_SEARCH;
+    
     /* Main Loop ---------------------------------------------------------------------*/
 
     for(f=0; f<NFRAMES; f++) {
@@ -219,7 +221,7 @@ int main(int argc, char *argv[])
     #endif
     
     for(f=0; f<NFRAMES; f++) {
-        /* For initial testng, timing est is off, so nin is always
+        /* For initial testing, timing est is off, so nin is always
            fixed.  TODO: we need a constant for rxbuf_in[] size that
            is the maximum possible nin */
 
@@ -256,7 +258,18 @@ int main(int argc, char *argv[])
         }
         ofdm_demod(ofdm, rx_bits, rx);
         #else
-        ofdm_demod(ofdm, rx_bits, rxbuf_in);
+        next_state = state;
+        switch(state) {
+        case OFDM_SEARCH:
+            if (ofdm_sync_search(ofdm, rxbuf_in)) {
+                next_state = OFDM_SYNCED;
+            }
+            break;
+        case OFDM_SYNCED:
+            ofdm_demod(ofdm, rx_bits, rxbuf_in);
+            break;
+        }
+        state = next_state;
         #endif
         
         int Nerrs = 0;