first pass at UW based sync - works really well, gives positive lock/false lock indic...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 7 Apr 2018 22:10:04 +0000 (22:10 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 7 Apr 2018 22:10:04 +0000 (22:10 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@3449 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/ofdm_lib.m
codec2-dev/octave/ofdm_rx.m
codec2-dev/octave/ofdm_tx.m

index b41b93c35ad565874bb4dbd4d5f97a828a2f1c74..a424c42ce42f089c715805fae3812718edb87d21 100644 (file)
@@ -48,7 +48,7 @@ endfunction
 % used for acquisition (coarse timing and freq offset), and fine
 % timing
 
-function [t_est foff_est timing_valid timing_mx1 timing_mx2] = coarse_sync(states, rx, rate_fs_pilot_samples)
+function [t_est foff_est timing_valid timing_mx] = coarse_sync(states, rx, rate_fs_pilot_samples)
     ofdm_load_const;
     Npsam = length(rate_fs_pilot_samples);
 
@@ -63,47 +63,25 @@ function [t_est foff_est timing_valid timing_mx1 timing_mx2] = coarse_sync(state
     % correlate with pilots at start and end of frame to determine timing offset
     
     for i=1:Ncorr
-      rx1      = rx(i:i+Npsam-1); rx2 = rx(i+Nsamperframe:i+Nsamperframe+Npsam-1);
-      corr_st  = rx1 * rate_fs_pilot_samples'; corr_en = rx2 * rate_fs_pilot_samples';
-      corr1(i)  = abs(corr_st + corr_en)/av_level;
-      corr2(i)  = (abs(corr_st) + abs(corr_en))/av_level;
+      rx1     = rx(i:i+Npsam-1); rx2 = rx(i+Nsamperframe:i+Nsamperframe+Npsam-1);
+      corr_st = rx1 * rate_fs_pilot_samples'; corr_en = rx2 * rate_fs_pilot_samples';
+      corr(i) = (abs(corr_st) + abs(corr_en))/av_level;
     end
 
-    [timing_mx1 t_est] = max(corr1);
-    [timing_mx2 t_est] = max(corr2);
-    timing_valid = timing_mx2 > timing_mx_thresh;
+    [timing_mx t_est] = max(corr);
+    timing_valid = timing_mx > timing_mx_thresh;
     
     if verbose > 2
-      printf("   mx1: %f mx2: %f timing_est: %d timing_valid: %d\n", timing_mx1, timing_mx2, timing_est, timing_valid);
+      printf("   mx: %f timing_est: %d timing_valid: %d\n", timing_mx, t_est, timing_valid);
     end
-    
-    #{
-    % original freq offset est code that never made it into C.  Have some concerns about CPU
-    % load of performing FFT, althout a smaller one could have been used with interpolation
-    % to get the peak
-    
-    C  = abs(fft(rx(t_est:t_est+Npsam-1) .* conj(rate_fs_pilot_samples), Fs));
-    C += abs(fft(rx(t_est+Nsamperframe:t_est+Nsamperframe+Npsam-1) .* conj(rate_fs_pilot_samples), Fs));
-
-    fmax = 30;
-    [mx_pos foff_est_pos] = max(C(1:fmax));
-    [mx_neg foff_est_neg] = max(C(Fs-fmax+1:Fs));
-
-    if mx_pos > mx_neg
-      foff_est = foff_est_pos - 1;
-    else
-      foff_est = foff_est_neg - fmax - 1;
-    end    
-    #}
-    
+        
     p1 = rx(t_est:t_est+Npsam/2-1) * rate_fs_pilot_samples(1:Npsam/2)';
     p2 = rx(t_est+Npsam/2:t_est+Npsam-1) * rate_fs_pilot_samples(Npsam/2+1:Npsam)';
     p3 = rx(t_est+Nsamperframe:t_est+Nsamperframe+Npsam/2-1) * rate_fs_pilot_samples(1:Npsam/2)';
     p4 = rx(t_est+Nsamperframe+Npsam/2:t_est+Nsamperframe+Npsam-1) * rate_fs_pilot_samples(Npsam/2+1:Npsam)';
     Fs1 = Fs/(Npsam/2);
     foff_est = Fs1*angle( (conj(p1)*p2 + conj(p3)*p4))/(2*pi);
-    
-    
+        
     if verbose > 1
       figure(7); clf;
       plot(abs(corr2))
@@ -127,20 +105,6 @@ function [t_est foff_est timing_valid timing_mx1 timing_mx2] = coarse_sync(state
       figure(11)
       plot([p1 p2; p3 p4], '+')
       
-      %axis([1 Ncorr 0 2])
-      #{
-      figure(8)
-      plot(C)
-      axis([0 200 0 0.4])
-      #}
-      #{
-      figure(9)
-      %rate_fs_pilot_samples
-      plot([p1 p2 p3 p4] ,'b+')
-      %plot(rate_fs_pilot_samples * rate_fs_pilot_samples' ,'b+')
-      axis([-0.2 0.2 -0.2 0.2])
-      %hold on; plot(rx(t_est+Nsamperframe:t_est+Npsam+Nsamperframe-1) .* rate_fs_pilot_samples','g+'); hold off;
-      #}
     end
 
 endfunction
@@ -320,9 +284,9 @@ function [timing_valid states] = ofdm_sync_search(states, 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_mx1 timing_mx2] = coarse_sync(states, states.rxbuf(st:en), states.rate_fs_pilot_samples);
+  [ct_est foff_est timing_valid timing_mx] = coarse_sync(states, states.rxbuf(st:en), states.rate_fs_pilot_samples);
   if verbose
-    printf("  mx1: %3.2f mx2: %3.2f coarse_foff: %4.1f\n", timing_mx1, timing_mx2, foff_est);
+    printf("  ct_est: %d mx: %3.2f coarse_foff: %4.1f\n", ct_est, timing_mx, foff_est);
   end
 
   if timing_valid
@@ -341,8 +305,7 @@ function [timing_valid states] = ofdm_sync_search(states, rxbuf_in)
   end
   
   states.timing_valid = timing_valid;
-  states.timing_mx1 = timing_mx1;
-  states.timing_mx2 = timing_mx2;
+  states.timing_mx = timing_mx;
   states.coarse_foff_est_hz = foff_est;
 endfunction
 
@@ -388,7 +351,7 @@ function [rx_bits states aphase_est_pilot_log rx_np rx_amp] = ofdm_demod(states,
     st = M+Ncp + Nsamperframe + 1 - floor(ftwindow_width/2) + (timing_est-1);
     en = st + Nsamperframe-1 + M+Ncp + ftwindow_width-1;
           
-    [ft_est coarse_foff_est_hz timing_valid timing_mx1 timing_mx2] = coarse_sync(states, rxbuf(st:en) .* exp(-j*woff_est*(st:en)), rate_fs_pilot_samples);
+    [ft_est coarse_foff_est_hz timing_valid timing_mx] = coarse_sync(states, rxbuf(st:en) .* exp(-j*woff_est*(st:en)), rate_fs_pilot_samples);
 
     if timing_valid
       timing_est = timing_est + ft_est - ceil(ftwindow_width/2);
@@ -401,7 +364,7 @@ function [rx_bits states aphase_est_pilot_log rx_np rx_amp] = ofdm_demod(states,
     end
     
     if verbose > 1
-      printf("  mx1: %3.2f mx2: %3.2f coarse_foff: %4.1f foff: %4.1f\n", timing_mx1, timing_mx2, coarse_foff_est_hz, foff_est_hz);
+      printf("  ft_est: %2d mx: %3.2f coarse_foff: %4.1f foff: %4.1f\n", ft_est, timing_mx, coarse_foff_est_hz, foff_est_hz);
     end
 
   end
@@ -526,8 +489,7 @@ function [rx_bits states aphase_est_pilot_log rx_np rx_amp] = ofdm_demod(states,
   states.rxbuf = rxbuf;
   states.nin = nin;
   states.timing_valid = timing_valid;
-  states.timing_mx1 = timing_mx1;
-  states.timing_mx2 = timing_mx2;
+  states.timing_mx = timing_mx;
   states.timing_est = timing_est;
   states.sample_point = sample_point;
   states.delta_t = delta_t;
index 3f28fdd8735f3c588494e119539b4ceb4cd6ca18..6df1082710984ba1861e0544d8c6f60a745a424c 100644 (file)
@@ -11,10 +11,10 @@ function ofdm_rx(filename, error_pattern_filename)
 
   % init modem
 
-  Ts = 0.018; Tcp = 0.002; Rs = 1/Ts; bps = 2; Nc = 16; Ns = 8;
+  Ts = 0.018; Tcp = 0.002; Rs = 1/Ts; bps = 2; Nc = 17; Ns = 8;
   states = ofdm_init(bps, Rs, Tcp, Ns, Nc);
   ofdm_load_const;
-  states.verbose = 2;
+  states.verbose = 0;
 
   % load real samples from file
 
@@ -44,7 +44,7 @@ function ofdm_rx(filename, error_pattern_filename)
   %states.rxbuf(Nrxbuf-nin+1:Nrxbuf) = rx(prx:nin);
   %prx += nin;
 
-  state = 'searching'; frame_count = 0; Nerrs = 0; sync_counter = 0;
+  state = 'searching'; frame_count = 0; Nerrs = 0; sync_counter = 0; uw_errors = 0;
   states.timing_mx1 = states.timing_mx2 = 1;
   
   % main loop ----------------------------------------------------------------
@@ -62,13 +62,7 @@ function ofdm_rx(filename, error_pattern_filename)
       rxbuf_in(1:lnew) = rx(prx:prx+lnew-1);
     end
     prx += states.nin;
-
-    ratio = states.timing_mx1/states.timing_mx2;
-    printf("f: %2d state: %-10s ratio: %3.2f %1d nin: %d Nerrs: %3d", f, state, ratio,  sync_counter, nin, Nerrs);
  
-    % 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;
@@ -77,14 +71,8 @@ function ofdm_rx(filename, error_pattern_filename)
       [timing_valid states] = ofdm_sync_search(states, rxbuf_in);
 
       if states.timing_valid
-        woff_est = 2*pi*states.foff_est_hz/Fs;
-        st = M+Ncp + Nsamperframe + 1; en = st + 2*Nsamperframe; 
-        [ct_est foff_est timing_valid timing_mx1 timing_mx2] = coarse_sync(states, states.rxbuf(st:en) .* exp(-j*woff_est*(st:en)), states.rate_fs_pilot_samples);
-        if states.verbose > 1
-          printf("  mx1: %3.2f mx2: %3.2f coarse_foff: %4.1f\n", timing_mx1, timing_mx2, foff_est);
-        end
-        %states.foff_est_hz += foff_est;
-        states.foff_est_hz = 0;
+        Nerrs_log = [];
+        Terrs = Tbits = frame_count = 0;
         sync_counter = 0;
         next_state = 'trial_sync';
       end
@@ -126,28 +114,21 @@ function ofdm_rx(filename, error_pattern_filename)
       end
 
       % freq offset est may be too far out, and has aliases every 1/Ts
-      
-      if (states.timing_mx1/states.timing_mx2 < 0.8)  || (abs(states.coarse_foff_est_hz) > 3)
+
+      uw_len = (Ns-1)*bps;
+      uw_errors = sum(xor(tx_bits(1:uw_len), rx_bits(1:uw_len)));
+      if (uw_errors > 3)
         sync_counter++;
-        #{
         if sync_counter == sync_counter_thresh
           next_state = 'searching';
           sync_counter = Nerrs = 0;
-
-          % print error stats for this sync period
-          
-          printf("\nBER..: %5.4f Tbits: %5d Terrs: %5d\n", Terrs/Tbits, Tbits, Terrs);
-
-          % reset BER stats
-          
-          Terrs = Tbits = frame_count = 0;
         end
-        #}
       else
         sync_counter = 0;
       end
     end
     
+    printf("f: %2d state: %-10s uw_errors: %2d %1d nin: %d Nerrs: %3d foff: %3.1f\n", f, state, uw_errors, sync_counter, nin, Nerrs,states.foff_est_hz);
     state = next_state;
   end
 
index 2262b4808baf522d268b149337d09a1bd36c9b7d..4241f031a3aae2adbb1d268410d5d05a9239727b 100644 (file)
@@ -22,7 +22,7 @@ function ofdm_tx(filename, Nsec, EbNodB=100, channel='awgn', freq_offset_Hz=0)
 
   % init modem
 
-  Ts = 0.018; Tcp = 0.002; Rs = 1/Ts; bps = 2; Nc = 16; Ns = 8;
+  Ts = 0.018; Tcp = 0.002; Rs = 1/Ts; bps = 2; Nc = 17; Ns = 8;
   states = ofdm_init(bps, Rs, Tcp, Ns, Nc);
   ofdm_load_const;
 
@@ -46,7 +46,7 @@ function ofdm_tx(filename, Nsec, EbNodB=100, channel='awgn', freq_offset_Hz=0)
   variance = 1/(M*EsNo/2);
   woffset = 2*pi*freq_offset_Hz/Fs;
 
-  SNRdB = EbNodB + 10*log10(700/3000);
+  SNRdB = EbNodB + 10*log10(Nc*bps*Rs/3000);
   printf("EbNo: %3.1f dB  SNR(3k) est: %3.1f dB  foff: %3.1fHz ", EbNodB, SNRdB, freq_offset_Hz);
 
   % set up HF model ---------------------------------------------------------------