octave and C versions of modem in sync
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 25 Jun 2014 05:56:56 +0000 (05:56 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 25 Jun 2014 05:56:56 +0000 (05:56 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1708 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/fdmdv.m
codec2-dev/octave/tfdmdv.m
codec2-dev/src/fdmdv.c
codec2-dev/unittest/tfdmdv.c

index a092a54e3ccb24732ae5ebeaef628e81f461ab69..15fa128a1b3e442a36f71a5256f3c535cf1c2430 100644 (file)
@@ -44,6 +44,8 @@ global snr_coeff;
 global Nph;
        Nph = 9;        % number of symbols to estimate phase over
                        % must be odd number as we take centre symbol
+global Nsync_mem = 6
+global sync_uw = [1 -1 1 -1 1 -1];
 
 % root raised cosine (Root Nyquist) filter 
 
@@ -312,7 +314,7 @@ function [foff imax pilot_lpf_out S] = lpf_peak_pick(pilot_baseband, pilot_lpf,
   % LPF cutoff 200Hz, so we can handle max +/- 200 Hz freq offset
 
   pilot_lpf(1:Npilotlpf-nin) = pilot_lpf(nin+1:Npilotlpf);
-  k = Npilotcoeff+1;
+  k = Npilotbaseband-nin+1;;
   for i = Npilotlpf-nin+1:Npilotlpf
     pilot_lpf(i) = pilot_baseband(k-Npilotcoeff+1:k) * pilot_coeff';
     k++;
@@ -524,38 +526,60 @@ function [rx_bits sync_bit f_err phase_difference] = psk_to_bits(prev_rx_symbols
 
   phase_difference = zeros(Nc+1,1);
   for c=1:Nc 
-    norm = 1/(1E-6+abs(prev_rx_symbols(c)));  
-    phase_difference(c) = prev_rx_symbols(c) .* conj(prev_rx_symbols(c)) * norm;
+     norm = 1/(1E-6+abs(prev_rx_symbols(c)));  
+     phase_difference(c) = rx_symbols(c) .* conj(prev_rx_symbols(c)) * norm;
   end
 
   for c=1:Nc
+    phase_difference(c) *= exp(j*pi/4);
 
-    % determine index of constellation point received 0,1,...,m-1
+    if m == 4
 
-    index = floor(angle(phase_difference(c))*m/(2*pi) + 0.5);
+        % to get a good match between C and Octave during start up use same as C code
+
+        d = phase_difference(c);
+        if (real(d) >= 0) && (imag(d) >= 0)
+          msb = 0; lsb = 0;
+        end
+        if (real(d) < 0) && (imag(d) >= 0)
+          msb = 0; lsb = 1;
+        end
+        if (real(d) < 0) && (imag(d) < 0)
+          msb = 1; lsb = 1;
+        end
+        if (real(d) >= 0) && (imag(d) < 0)
+          msb = 1; lsb = 0;
+        end
+          
+        rx_bits(2*(c-1)+1) = msb;
+        rx_bits(2*c) = lsb;
+    else
+      % determine index of constellation point received 0,1,...,m-1
 
-    if index < 0
-      index += m;
-    end
+      index = floor(angle(phase_difference(c))*m/(2*pi) + 0.5);
 
-    % map to decimal version of bits encoded in symbol
+      if index < 0
+        index += m;
+      end
 
-    if m == 4
-      bits_decimal = m4_binary_to_gray(index+1);
-    else
-      bits_decimal = m8_binary_to_gray(index+1);
-    end
-    
-    % convert back to an array of received bits
+      % map to decimal version of bits encoded in symbol
 
-    for i=1:Nb
-      if bitand(bits_decimal, 2.^(Nb-i))
-        rx_bits((c-1)*Nb+i) = 1;
+      if m == 4
+        bits_decimal = m4_binary_to_gray(index+1);
       else
-        rx_bits((c-1)*Nb+i) = 0;
+        bits_decimal = m8_binary_to_gray(index+1);
+      end
+    
+      % convert back to an array of received bits
+
+      for i=1:Nb
+        if bitand(bits_decimal, 2.^(Nb-i))
+          rx_bits((c-1)*Nb+i) = 1;
+        else
+          rx_bits((c-1)*Nb+i) = 0;
+        end
       end
     end
-
   end
 
   assert(length(rx_bits) == Nc*Nb);
@@ -574,7 +598,7 @@ function [rx_bits sync_bit f_err phase_difference] = psk_to_bits(prev_rx_symbols
 
   % extra pi/4 rotation as we need for snr_update and scatter diagram
   
-  phase_difference *= exp(j*pi/4);
+  phase_difference(Nc+1) *= exp(j*pi/4);
   
 endfunction
 
@@ -836,89 +860,69 @@ endfunction
 % then switch to a more robust tracking algorithm.  If we lose sync we switch
 % back to acquire mode for fast-requisition.
 
-function [entered_track track state bad_sync] = freq_state(sync_bit, state, bad_sync)
+function [sync reliable_sync_bit state timer sync_mem] = freq_state(sync_bit, state, timer, sync_mem)
+  global Nsync_mem;
+  global sync_uw;
 
-  entered_track = 0;
+  % look for 6 symbol (120ms) 010101 of sync sequence
 
-  % acquire state, look for 6 symbol 010101 sequence from sync bit
+  unique_word = 0;
+  for i=1:Nsync_mem-1
+    sync_mem(i) = sync_mem(i+1);
+  end
+  sync_mem(Nsync_mem) = 1 - 2*sync_bit;
+  corr = 0;
+  for i=1:Nsync_mem
+    corr += sync_mem(i)*sync_uw(i);
+  end
+  if abs(corr) == Nsync_mem
+    unique_word = 1;
+  end
+  reliable_sync_bit = (abs(corr) == Nsync_mem);
+  
+  % iterate state machine
 
   next_state = state;
   if state == 0
-    if sync_bit == 0
+    if unique_word
       next_state = 1;
+      timer = 0;
     end        
   end
   if state == 1
-    if sync_bit == 1
-      next_state = 2;
+    if unique_word
+      timer++;
+      if timer == 25       % sync has been good for 500ms
+        next_state = 2;
+      end
     else 
       next_state = 0;
     end        
   end
-  if state == 2
-    if sync_bit == 0
+  if state == 2            % good sync state
+    if unique_word == 0
+      timer = 0;
       next_state = 3;
-    else 
-      next_state = 0;
-    end        
-  end
-  if state == 3
-    if sync_bit == 1
-      next_state = 4;
-    else 
-      next_state = 0;
-    end        
-  end
-  if state == 4
-    if sync_bit == 0
-      next_state = 5;
-    else 
-      next_state = 0;
-    end        
+    end
   end
-  if state == 5
-    if sync_bit == 1
-      entered_track = 1;
-      next_state = 6;
-      bad_sync = 0;
+  if state == 3            % tenative bad  state, but could be a fade
+    if unique_word
+      next_state = 2;
     else 
-      next_state = 0;
-    end        
-  end
-
-  % states 6 and above are track mode, make sure we keep getting 0101 sync bit sequence
-
-  if state == 6
-    next_state = 7;
-    if sync_bit == 0
-      bad_sync = 0;
-    else
-      bad_sync++;
-      if bad_sync > 2
+      timer++;
+      if timer == 50       % wait for 1000ms in case sync comes back  
         next_state = 0;
       end
     end        
   end
 
-  if state == 7
-    next_state = 6;
-    if sync_bit == 1
-      bad_sync = 0;
-    else
-      bad_sync++;
-      if bad_sync > 2
-        next_state = 0;
-      end
-    end        
-  end
-
-  %printf("state: %d  next_state: %d  sync_bit: %d bad_sync: %d\n", state, next_state, sync_bit, bad_sync);
-
+  %printf("corr: % -d state: %d next_state: %d uw: %d timer: %d\n", corr, state, next_state, unique_word, timer);
   state = next_state;
-  if state >= 6
-    track = 1;
+
+  if state
+    sync = 1;
   else
-    track = 0;
+    sync = 0;
   end
 endfunction
 
@@ -1077,10 +1081,10 @@ global Mpilotfft      = 256;
 global Npilotcoeff;                                      % number of pilot LPF coeffs
        Npilotcoeff    = 30;                              
 global pilot_coeff;
-       pilot_coeff    = fir1(Npilotcoeff-1, 100/(Fs/2))';% 200Hz LPF
+       pilot_coeff    = fir1(Npilotcoeff-1, 200/(Fs/2))';% 200Hz LPF
 global Npilotbaseband = Npilotcoeff + M + M/P;           % number of pilot baseband samples reqd for pilot LPF
 global Npilotlpf;                                        % number of symbols we DFT pilot over, pilot est window
-       Npilotlpf      = 8*M;
+       Npilotlpf      = 4*M;
 
 % pilot LUT, used for copy of pilot at rx
   
@@ -1093,8 +1097,10 @@ global prev_pilot_lut_index;
 
 % Freq offset estimator states 
 
+if 0
 global bpf;
        bpf = zeros(1, Nbpf);                            % BPF pilot input samples
+end
 global pilot_baseband1;
 global pilot_baseband2;
 pilot_baseband1 = zeros(1, Npilotbaseband);             % pilot baseband samples
index 86907f28009cf164b13ade0280d77a6524d03eee..2638021451dd7dd69e5bd5e6388ed3d81c63afbc 100644 (file)
@@ -9,6 +9,7 @@
 % Version 2
 %
 
+more off
 NumCarriers = 14;
 fdmdv; % load modem code
  
@@ -21,14 +22,17 @@ frames = 25;
 prev_tx_symbols = ones(Nc+1,1);
 prev_rx_symbols = ones(Nc+1,1);
 foff_phase_rect = 1;
-coarse_fine = 0;
-fest_state = 0;
 channel = [];
 channel_count = 0;
 next_nin = M;
 sig_est = zeros(Nc+1,1);
 noise_est = zeros(Nc+1,1);
 
+sync = 0;
+fest_state = 0;
+fest_timer = 0;
+sync_mem = zeros(1,Nsync_mem);
+
 % Octave outputs we want to collect for comparison to C version
 
 tx_bits_log = [];
@@ -52,7 +56,7 @@ phase_difference_log = [];
 rx_symbols_log = [];
 rx_bits_log = []; 
 sync_bit_log = [];  
-coarse_fine_log = [];
+sync_log = [];  
 nin_log = [];
 sig_est_log = [];
 noise_est_log = [];
@@ -60,7 +64,7 @@ noise_est_log = [];
 % adjust this if the screen is getting a bit cluttered
 
 global no_plot_list;
-no_plot_list = [1 2 3 4 5 6 7 8 12];
+no_plot_list = [1 2 3 4 5 6 7 8 11 12 16];
 
 for f=1:frames
 
@@ -78,16 +82,7 @@ for f=1:frames
 
   % channel
 
-  nin = next_nin;
-  %nin = 120;
-  %nin = M;
-  %if (f == 3)
-  %  nin = 120;
-  %elseif (f == 4)
-  %  nin = 200;
-  %else
-  %  nin = M;
-  %end
+  %nin = next_nin;
   nin = M;
   channel = [channel real(tx_fdm)];
   channel_count += M;
@@ -100,8 +95,6 @@ for f=1:frames
   [pilot prev_pilot pilot_lut_index prev_pilot_lut_index] = get_pilot(pilot_lut_index, prev_pilot_lut_index, nin);
 
   [foff_coarse S1 S2] = rx_est_freq_offset(rx_fdm, pilot, prev_pilot, nin);
-  foff_coarse = 0;
-  sync = 0;
   if sync == 0
     foff = foff_coarse;
   end
@@ -158,8 +151,8 @@ for f=1:frames
 
   % freq est state machine
 
-  [sync fest_state] = freq_state(sync_bit, fest_state);
-  sync_log = [coarse_fine_log sync];
+  [sync reliable_sync_bit fest_state fest_timer sync_mem] = freq_state(sync_bit, fest_state, fest_timer, sync_mem);
+  sync_log = [sync_log sync];
 end
 
 % Compare to the output from the C version
@@ -176,9 +169,9 @@ function stem_sig_and_error(plotnum, subplotnum, sig, error, titlestr, axisvec)
   end
   figure(plotnum)
   subplot(subplotnum)
-  stem(sig,'g;C version;');
+  stem(sig,'g;Octave version;');
   hold on;
-  stem(error,'r;Error between C and Octave;');
+  stem(error,'r;Octave - C version (hopefully 0);');
   hold off;
   if nargin == 6
     axis(axisvec);
@@ -195,9 +188,9 @@ function plot_sig_and_error(plotnum, subplotnum, sig, error, titlestr, axisvec)
 
   figure(plotnum)
   subplot(subplotnum)
-  plot(sig,'g;C version;');
+  plot(sig,'g;Octave version;');
   hold on;
-  plot(error,'r;Error between C and Octave;');
+  plot(error,'r;Octave - C version (hopefully 0);');
   hold off;
   if nargin == 6
     axis(axisvec);
@@ -252,7 +245,7 @@ plot_sig_and_error(9, 211, foff_coarse_log, foff_coarse_log - foff_coarse_log_c,
 plot_sig_and_error(9, 212, foff_fine_log, foff_fine_log - foff_fine_log_c, 'Fine Freq Offset' )
 
 plot_sig_and_error(10, 211, foff_log, foff_log - foff_log_c, 'Freq Offset' )
-plot_sig_and_error(10, 212, sync_log, sync_log - sync_log_c, 'Freq Est Coarse(0) Fine(1)', [1 frames -0.5 1.5] )
+plot_sig_and_error(10, 212, sync_log, sync_log - sync_log_c, 'Sync & Freq Est Coarse(0) Fine(1)', [1 frames -1.5 1.5] )
 
 c=15;
 plot_sig_and_error(11, 211, real(rx_baseband_log(c,:)), real(rx_baseband_log(c,:) - rx_baseband_log_c(c,:)), 'Rx baseband real' )
@@ -273,7 +266,7 @@ c = 12;
 plot_sig_and_error(16, 211, sig_est_log(c,:), sig_est_log(c,:) - sig_est_log_c(c,:), 'sig est for SNR' )
 plot_sig_and_error(16, 212, noise_est_log(c,:), noise_est_log(c,:) - noise_est_log_c(c,:), 'noise est for SNR' )
 
-f=2;
+f=12;
 
 stem_sig_and_error(13, 211, real(rx_symbols_log(:,f)), real(rx_symbols_log(:,f) - rx_symbols_log_c(:,f)), 'rx symbols real' )
 stem_sig_and_error(13, 212, imag(rx_symbols_log(:,f)), imag(rx_symbols_log(:,f) - rx_symbols_log_c(:,f)), 'rx symbols imag' )
index e58924da217f0fa6721940f379459d6c1a2195b3..255f209e90729e235cfe101fb86f40e7cf07f297 100644 (file)
@@ -1215,7 +1215,7 @@ int freq_state(int *reliable_sync_bit, int sync_bit, int *state, int *timer, int
         corr += sync_mem[i]*sync_uw[i];
     if (abs(corr) == NSYNC_MEM)
         unique_word = 1;
-    *reliable_sync_bit = (corr == NSYNC_MEM);
+    *reliable_sync_bit = (abs(corr) == NSYNC_MEM);
 
     /* iterate state machine */
 
@@ -1227,7 +1227,7 @@ int freq_state(int *reliable_sync_bit, int sync_bit, int *state, int *timer, int
             *timer = 0;
         }
        break;
-    case 1:                  /* tentative sync state         */
+    case 1:                   /* tentative sync state         */
        if (unique_word) {
             (*timer)++;
             if (*timer == 25) /* sync has been good for 500ms */
index 256ae55675429b99c6a53f1f1f102aaf7b442460..cb6bf1483f9d589214b026fd2e4882f0b99c7152 100644 (file)
@@ -11,7 +11,6 @@
                                                                              
 \*---------------------------------------------------------------------------*/
 
-
 /*
   Copyright (C) 2012 David Rowe
 
@@ -159,11 +158,9 @@ int main(int argc, char *argv[])
        /* freq offset estimation and correction */
 
        foff_coarse = rx_est_freq_offset(fdmdv, rx_fdm, nin);
-        foff_coarse = 0;
-        fdmdv->sync = 0;
        if (fdmdv->sync == 0)
            fdmdv->foff = foff_coarse;
-       fdmdv_freq_shift(rx_fdm_fcorr, rx_fdm, foff_coarse, &fdmdv->foff_phase_rect, nin);
+       fdmdv_freq_shift(rx_fdm_fcorr, rx_fdm, -fdmdv->foff, &fdmdv->foff_phase_rect, nin);
        
        /* baseband processing */