two path freq offset est/sync proto working OK with BER a bit high, little more work...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 5 May 2015 09:15:52 +0000 (09:15 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 5 May 2015 09:15:52 +0000 (09:15 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@2124 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/cohpsk.m
codec2-dev/octave/tcohpsk.m
codec2-dev/octave/test_foff.m

index c6a02e13b8c84fba4005b40135cf66a84df40008..f5ccd4332dc5c11caf9356fb2185f9b95edc40af 100644 (file)
@@ -589,6 +589,21 @@ function [next_sync cohpsk] = coarse_freq_offset_est(cohpsk, fdmdv, ch_fdm_frame
 endfunction
 
 
+function [ch_symb rx_timing rx_filt rx_baseband afdmdv] = rate_Fs_rx_processing(afdmdv, rx_fdm_frame_bb, nsymb, nin)
+    M = afdmdv.M;
+
+    for r=1:nsymb
+      % downconvert each FDM carrier to Nc separate baseband signals
+
+      [rx_baseband afdmdv] = fdm_downconvert(afdmdv, rx_fdm_frame_bb(1+(r-1)*M:r*M), nin);
+      [rx_filt afdmdv] = rx_filter(afdmdv, rx_baseband, nin);
+      [rx_onesym rx_timing env afdmdv] = rx_est_timing(afdmdv, rx_filt, nin);     
+
+      ch_symb(r,:) = rx_onesym;
+    end
+endfunction
+
+
 function ct_symb_buf = update_ct_symb_buf(ct_symb_buf, ch_symb, Nct_sym_buf, Nsymbrowpilot)
 
   % update memory in symbol buffer
@@ -724,7 +739,7 @@ function acohpsk = fine_freq_correct(acohpsk, sync, next_sync);
       ct_symb_ff_buf(3:acohpsk.Nsymbrowpilot+2,:) = acohpsk.ct_symb_buf(acohpsk.ct+3:acohpsk.ct+acohpsk.Nsymbrowpilot+2,:);
       for r=3:acohpsk.Nsymbrowpilot+2
         acohpsk.ff_phase *= acohpsk.ff_rect';
-       ct_symb_ff_buf(r,:) *= acohpsk.ff_phase;
+        ct_symb_ff_buf(r,:) *= acohpsk.ff_phase;
       end
   end
 
index d401766cbd40f6691481ae6c95905c24d2546a22..bc039750107136d12545509438afa26dcae7b8f2 100644 (file)
@@ -22,10 +22,10 @@ randn('state',1);
 
 % test parameters ----------------------------------------------------------
 
-frames = 100;
-foff = 100;
+frames = 10;
+foff = 0;
 dfoff = 0;
-EsNodB = 10;
+EsNodB = 8;
 fading_en = 0;
 hf_delay_ms = 2;
 compare_with_c = 0;
@@ -39,6 +39,9 @@ Nc = 4;
 Nd = 2;
 framesize = 32;
 
+afdmdv.Nsym = 2;
+afdmdv.Nt = 3;
+
 % FDMDV init ---------------------------------------------------------------
 
 afdmdv.Fs = 8000;
@@ -47,7 +50,7 @@ afdmdv.Rs = Rs;
 afdmdv.M  = afdmdv.Fs/afdmdv.Rs;
 afdmdv.tx_filter_memory = zeros(afdmdv.Nc+1, Nfilter);
 afdmdv.Nfilter =  Nfilter;
-afdmdv.gt_alpha5_root = gt_alpha5_root;
+afdmdv.gt_alpha5_root = gen_rn_coeffs(0.5, 1/Fs, Rs, afdmdv.Nsym, afdmdv.M);
 afdmdv.Fsep = 75;
 afdmdv.phase_tx = ones(afdmdv.Nc+1,1);
 freq_hz = afdmdv.Fsep*( -Nc*Nd/2 - 0.5 + (1:Nc*Nd) );
@@ -65,12 +68,10 @@ afdmdv.rxdec_lpf_mem = zeros(1,afdmdv.Nrxdec-1+M);
 
 P = afdmdv.P = 4;
 afdmdv.phase_rx = ones(afdmdv.Nc+1,1);
-afdmdv.Nsym = 6;
 afdmdv.Nfilter = afdmdv.Nsym*afdmdv.M;
 afdmdv.rx_fdm_mem = zeros(1,afdmdv.Nfilter + afdmdv.M);
 Q = afdmdv.Q = afdmdv.M/4;
 
-afdmdv.Nt = 5;
 afdmdv.rx_filter_mem_timing = zeros(afdmdv.Nc+1, afdmdv.Nt*afdmdv.P);
 afdmdv.Nfiltertiming = afdmdv.M + afdmdv.Nfilter + afdmdv.M;
 
@@ -93,6 +94,8 @@ acohpsk = symbol_rate_init(acohpsk);
 acohpsk.Ndft = 1024;
 acohpsk.f_est = afdmdv.Fcentre;
 
+ch_fdm_frame_buf = zeros(1, 2*acohpsk.Nsymbrowpilot*M);
+
 % -----------------------------------------------------------
 
 tx_bits_log = [];
@@ -136,8 +139,8 @@ ch_fdm_delay = zeros(1, acohpsk.Nsymbrowpilot*M + nhfdelay);
 
 % main loop --------------------------------------------------------------------
 
-for i=1:frames
-  acohpsk.frame = i;
+for f=1:frames
+  acohpsk.frame = f;
   tx_bits = tx_bits_coh(ptx_bits_coh:ptx_bits_coh+framesize-1);
   ptx_bits_coh += framesize;
   if ptx_bits_coh > length(tx_bits_coh)
@@ -202,47 +205,64 @@ for i=1:frames
   % Demod ----------------------------------------------------------------------
   %
 
-  % Coarse Freq offset estimation
+  % store two frames of received samples so we can rewind if we get a good candidate
+
+  ch_fdm_frame_buf(1:acohpsk.Nsymbrowpilot*M) = ch_fdm_frame_buf(acohpsk.Nsymbrowpilot*M+1:2*acohpsk.Nsymbrowpilot*M);
+  ch_fdm_frame_buf(acohpsk.Nsymbrowpilot*M+1:2*acohpsk.Nsymbrowpilot*M) = ch_fdm_frame;
 
   next_sync = sync;
-  
-  [next_sync acohpsk] = coarse_freq_offset_est(acohpsk, afdmdv, ch_fdm_frame, sync, next_sync);
   nin = M;
 
-  % shift entire FDM signal to 0 Hz
-  [rx_fdm_frame_bb afdmdv.fbb_phase_rx] = freq_shift(ch_fdm_frame, -acohpsk.f_est, Fs, afdmdv.fbb_phase_rx);
-  rx_fdm_frame_bb_log = [rx_fdm_frame_bb_log rx_fdm_frame_bb];
+  % if out of sync do Initial Freq offset estimation over last two frames
 
-  % sample rate demod processing
+  if (sync == 0) & (f>1)
 
-  ch_symb = zeros(acohpsk.Nsymbrowpilot, Nc*Nd);
-  for r=1:acohpsk.Nsymbrowpilot
+    % we are out of sync so reset f_est and process two frames to clean out memories
 
-    % downconvert each FDM carrier to Nc separate baseband signals
+    acohpsk.f_est = Fcentre;
+    [rx_fdm_frame_bb afdmdv.fbb_phase_rx] = freq_shift(ch_fdm_frame_buf, -acohpsk.f_est, Fs, afdmdv.fbb_phase_rx);
+    [ch_symb rx_timing rx_filt rx_baseband afdmdv] = rate_Fs_rx_processing(afdmdv, rx_fdm_frame_bb, 2*acohpsk.Nsymbrowpilot, nin);
+    acohpsk.ct_symb_buf = update_ct_symb_buf(acohpsk.ct_symb_buf, ch_symb, acohpsk.Nct_sym_buf, acohpsk.Nsymbrowpilot);
+    [next_sync acohpsk] = frame_sync_fine_freq_est(acohpsk, ch_symb, sync, next_sync);
 
-    [rx_baseband afdmdv] = fdm_downconvert(afdmdv, rx_fdm_frame_bb(1+(r-1)*M:r*M), nin);
-    rx_baseband_log = [rx_baseband_log rx_baseband];
+    if next_sync == 1
 
-    [rx_filt afdmdv] = rx_filter(afdmdv, rx_baseband, nin);
+      % we've found a sync candidate!
+      % re-process last two frames with adjusted f_est then check again
 
-    rx_filt_log = [rx_filt_log rx_filt];
+      acohpsk.f_est -= acohpsk.f_fine_est;
 
-    [rx_onesym rx_timing env afdmdv] = rx_est_timing(afdmdv, rx_filt, nin);     
-    rx_timing_log = [rx_timing_log rx_timing];
+      printf("  [%d] trying sync and f_est: %f\n", f, acohpsk.f_est);
 
-    ch_symb(r,:) = rx_onesym;
+      [rx_fdm_frame_bb afdmdv.fbb_phase_rx] = freq_shift(ch_fdm_frame_buf, -acohpsk.f_est, Fs, afdmdv.fbb_phase_rx);
+      [ch_symb rx_timing rx_filt rx_baseband afdmdv] = rate_Fs_rx_processing(afdmdv, rx_fdm_frame_bb, 2*acohpsk.Nsymbrowpilot, nin);
+      acohpsk.ct_symb_buf = update_ct_symb_buf(acohpsk.ct_symb_buf, ch_symb, acohpsk.Nct_sym_buf, acohpsk.Nsymbrowpilot);
+      [next_sync acohpsk] = frame_sync_fine_freq_est(acohpsk, ch_symb(acohpsk.Nsymbrowpilot+1:2*acohpsk.Nsymbrowpilot,:), sync, next_sync);
+
+      if next_sync == 1
+        % OK we are in sync!
+        % demodulate first frame (demod completed below)
+
+        printf("  [%d] in sync!\n", f);
+        acohpsk.ct_symb_ff_buf(1:acohpsk.Nsymbrowpilot+2,:) = acohpsk.ct_symb_buf(acohpsk.ct+1:acohpsk.ct+acohpsk.Nsymbrowpilot+2,:);
+      end
+    end  
   end
-  
-  ch_symb_log = [ch_symb_log; ch_symb];
 
-  % coarse timing (frame sync) and initial fine freq est ---------------------------------------------
-  
-  [next_sync acohpsk] = frame_sync_fine_freq_est(acohpsk, ch_symb, sync, next_sync);
-  acohpsk = fine_freq_correct(acohpsk, sync, next_sync);
-  ct_symb_ff_log = [ct_symb_ff_log; acohpsk.ct_symb_ff_buf(1:acohpsk.Nsymbrowpilot,:)];
+  % If in sync just do sample rate processing on latest frame
+
+  if sync == 1
+    [rx_fdm_frame_bb afdmdv.fbb_phase_rx] = freq_shift(ch_fdm_frame, -acohpsk.f_est, Fs, afdmdv.fbb_phase_rx);
+    [ch_symb rx_timing rx_filt rx_baseband afdmdv] = rate_Fs_rx_processing(afdmdv, rx_fdm_frame_bb, acohpsk.Nsymbrowpilot, nin);
+    acohpsk.ct_symb_buf = update_ct_symb_buf(acohpsk.ct_symb_buf, ch_symb, acohpsk.Nct_sym_buf, acohpsk.Nsymbrowpilot);
 
-  if (sync == 4) || (next_sync == 4)  
+    acohpsk.ct_symb_ff_buf(1:2,:) = acohpsk.ct_symb_ff_buf(acohpsk.Nsymbrowpilot+1:acohpsk.Nsymbrowpilot+2,:);
+    acohpsk.ct_symb_ff_buf(3:acohpsk.Nsymbrowpilot+2,:) = acohpsk.ct_symb_buf(acohpsk.ct+3:acohpsk.ct+acohpsk.Nsymbrowpilot+2,:);
+  end
+
+  % if we are in sync complete demodulation with symbol rate processing
+
+  if (next_sync == 1) || (sync == 1)
     [rx_symb rx_bits rx_symb_linear amp_ phi_ EsNo_] = qpsk_symbols_to_bits(acohpsk, acohpsk.ct_symb_ff_buf);
     rx_symb_log = [rx_symb_log; rx_symb];
     rx_amp_log = [rx_amp_log; amp_];
@@ -252,20 +272,32 @@ for i=1:frames
     ratio_log = [ratio_log acohpsk.ratio];
 
     % BER stats
-
-    error_positions = xor(prev_tx_bits2, rx_bits);
+    %size(rx_bits)
+    %size(prev_tx_bits2)
+    %error_positions = xor(prev_tx_bits2, rx_bits);
+    error_positions = xor(prev_tx_bits, rx_bits);
     Nerrs  += sum(error_positions);
     nerr_log = [nerr_log sum(error_positions)];
     Tbits += length(error_positions);
+    printf("\r  [%d]", f);
   end
 
+   
+  %rx_fdm_frame_bb_log = [rx_fdm_frame_bb_log rx_fdm_frame_bb];
+  %rx_baseband_log = [rx_baseband_log rx_baseband];
+  %rx_filt_log = [rx_filt_log rx_filt];
+  %rx_timing_log = [rx_timing_log rx_timing];
+  %ch_symb_log = [ch_symb_log; ch_symb];
+  % TODO ct_symb_ff_log = [ct_symb_ff_log; acohpsk.ct_symb_ff_buf(1:acohpsk.Nsymbrowpilot,:)];
+
+
   if sync == 0
     Nerrs = 0;
     Tbits = 0;
     nerr_log = [];
   end
 
-  % printf("f: %d sync: %d next_sync: %d\n", i, sync, next_sync);
+  % printf("f: %d sync: %d next_sync: %d\n", f, sync, next_sync);
   [sync acohpsk] = sync_state_machine(acohpsk, sync, next_sync);
 
   prev_tx_bits2 = prev_tx_bits;
@@ -274,7 +306,7 @@ for i=1:frames
 end
 
 ber = Nerrs/Tbits;
-printf("EsNodB: %4.1f ber..: %4.3f Nerrs..: %d Tbits..: %d\n", EsNodB, ber, Nerrs, Tbits);
+printf("\nEsNodB: %4.1f ber..: %4.3f Nerrs..: %d Tbits..: %d\n", EsNodB, ber, Nerrs, Tbits);
 
 if compare_with_c
 
index 3ef860318ec31cb4489de64f687304bac6c38412..242bad4e208c0a2d96d6c26f6c3631c1e1f138cf 100644 (file)
@@ -13,19 +13,6 @@ autotest;
 rand('state',1); 
 randn('state',1);
 
-function [ch_symb rx_timing rx_filt rx_baseband afdmdv] = rate_Fs_rx_processing(afdmdv, rx_fdm_frame_bb, nsymb, nin)
-    M = afdmdv.M;
-
-    for r=1:nsymb
-      % downconvert each FDM carrier to Nc separate baseband signals
-
-      [rx_baseband afdmdv] = fdm_downconvert(afdmdv, rx_fdm_frame_bb(1+(r-1)*M:r*M), nin);
-      [rx_filt afdmdv] = rx_filter(afdmdv, rx_baseband, nin);
-      [rx_onesym rx_timing env afdmdv] = rx_est_timing(afdmdv, rx_filt, nin);     
-
-      ch_symb(r,:) = rx_onesym;
-    end
-endfunction
  
 % Core function for testing frequency offset estimator.  Performs one test
 
@@ -204,7 +191,7 @@ function sim_out = freq_off_est_test(sim_in)
        % rewind and re-process last few frames with f_est
 
        acohpsk.f_est -= acohpsk.f_fine_est;
-       printf("  [%d] trying sync cand f_est: %f\n", f, acohpsk.f_est);
+       printf("  [%d] trying sync and f_est: %f\n", f, acohpsk.f_est);
        [rx_fdm_frame_bb afdmdv.fbb_phase_rx] = freq_shift(ch_fdm_frame_buf, -acohpsk.f_est, Fs, afdmdv.fbb_phase_rx);
        [ch_symb rx_timing rx_filt rx_baseband afdmdv] = rate_Fs_rx_processing(afdmdv, rx_fdm_frame_bb, 2*acohpsk.Nsymbrowpilot, nin);
        acohpsk.ct_symb_buf = update_ct_symb_buf(acohpsk.ct_symb_buf, ch_symb, acohpsk.Nct_sym_buf, acohpsk.Nsymbrowpilot);
@@ -214,7 +201,7 @@ function sim_out = freq_off_est_test(sim_in)
 
        if (next_sync == 1)
          printf("  [%d] in sync!\n", f);
-         freq_offset_log = [freq_offset_log Fcentre+foff-acohpsk.f_est,];
+         freq_offset_log = [freq_offset_log Fcentre+foff-acohpsk.f_est];
          sync_time_log = [sync_time_log f-sync_start];
          next_sync = 0; sync_start = f;
        end
@@ -236,11 +223,11 @@ endfunction
 
 
 function freq_off_est_test_single
-  sim_in.frames    = 100;
-  sim_in.EsNodB    = 12;
-  sim_in.foff      = 20;
+  sim_in.frames    = 10;
+  sim_in.EsNodB    = 100;
+  sim_in.foff      = 10;
   sim_in.dfoff     = 0;
-  sim_in.fading_en = 1;
+  sim_in.fading_en = 0;
 
   sim_out = freq_off_est_test(sim_in);
 
@@ -267,10 +254,10 @@ endfunction
 function [freq_off_log EsNodBSet] = freq_off_est_test_curves
   EsNodBSet = [20 12 8];
 
-  sim_in.frames    = 10;
+  sim_in.frames    = 100;
   sim_in.foff      = -20;
   sim_in.dfoff     = 0;
-  sim_in.fading_en = 0;
+  sim_in.fading_en = 1;
   freq_off_log = 1E6*ones(sim_in.frames, length(EsNodBSet) );
   sync_time_log = 1E6*ones(sim_in.frames, length(EsNodBSet) );