fdmdv.m and fdmdv.c passes all tfdmdv.m tests with linear interpolater, fdmdv_mem...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sun, 29 Jun 2014 05:36:14 +0000 (05:36 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sun, 29 Jun 2014 05:36:14 +0000 (05:36 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1715 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 d63b73de8db4fb654c31ce761e8d390762954fbc..aee46816c11d0e16d68c042116dcaedbf456b884 100644 (file)
@@ -354,22 +354,6 @@ function [foff S1 S2] = rx_est_freq_offset(rx_fdm, pilot, pilot_prev, nin)
   global pilot_baseband2;
   global pilot_lpf1;
   global pilot_lpf2;
-  global Nbpf;
-  global Nbpfcoeff;
-  global bpf_coeff;
-  global bpf;
-
-if 0
-  % Band Pass filter input so we have (mainly) just the pilots
-  
-  bpf(1:Nbpf-nin) = bpf(nin+1:Nbpf);
-  bpf(Nbpf-nin+1:Nbpf) = rx_fdm(1:nin);
-  k = 1;
-  for i = Nbpf-nin+1:Nbpf
-    rx_fdm_bpf(k) = bpf(i-(Nbpfcoeff-1):i) *  bpf_coeff';
-    k++;
-  end
-end
 
   % down convert latest nin samples of pilot by multiplying by ideal
   % BPSK pilot signal we have generated locally.  The peak of the DFT
@@ -397,12 +381,11 @@ endfunction
 
 % Estimate optimum timing offset, re-filter receive symbols
 
-function [rx_symbols rx_timing env] = rx_est_timing(rx_filt, rx_baseband, nin)
+function [rx_symbols rx_timing_M env] = rx_est_timing(rx_filt, nin)
   global M;
   global Nt;
   global Nc;
   global rx_filter_mem_timing;
-  global rx_baseband_mem_timing;
   global P;
   global Nfilter;
   global Nfiltertiming;
@@ -433,11 +416,8 @@ function [rx_symbols rx_timing env] = rx_est_timing(rx_filt, rx_baseband, nin)
 
   x = env * exp(-j*2*pi*(0:m-1)/P)';
   
-linear_interp = 1;
-
-if linear_interp
-
-  rx_timing = angle(x)*P/(2*pi) + P/4;
+  norm_rx_timing = angle(x)/(2*pi);
+  rx_timing = norm_rx_timing*P + P/4;
   if (rx_timing > P)
      rx_timing -= P;
   end
@@ -453,37 +433,12 @@ if linear_interp
   low_sample = floor(rx_timing);
   fract = rx_timing - low_sample;
   high_sample = ceil(rx_timing);
-  % printf("rx_timing: %f low_sample: %f high_sample: %f fract: %f\n", rx_timing, low_sample, high_sample, fract);
-
+  %printf("rx_timing: %f low_sample: %f high_sample: %f fract: %f\n", rx_timing, low_sample, high_sample, fract);
+  
   rx_symbols = rx_filter_mem_timing(:,low_sample)*(1-fract) + rx_filter_mem_timing(:,high_sample)*fract;
+  % rx_symbols = rx_filter_mem_timing(:,high_sample+1);
 
-else
-
-  % map phase to estimated optimum timing instant at rate M
-  % the M/4 part was adjusted by experiment, I know not why....
-
-  rx_timing = angle(x)*M/(2*pi) + M/4;
-  if (rx_timing > M)
-     rx_timing -= M;
-  end
-  if (rx_timing < -M)
-     rx_timing += M;
-  end
-
-  % rx_baseband_mem_timing contains M + Nfilter + M samples of the
-  % baseband signal at rate M this enables us to resample the filtered
-  % rx symbol with M sample precision once we have rx_timing
-
-  rx_baseband_mem_timing(:,1:Nfiltertiming-nin) = rx_baseband_mem_timing(:,nin+1:Nfiltertiming);
-  rx_baseband_mem_timing(:,Nfiltertiming-nin+1:Nfiltertiming) = rx_baseband;
-
-  % sample right in the middle of the timing estimator window, by filtering
-  % at rate M
-
-  s = round(rx_timing) + M;
-  rx_symbols = rx_baseband_mem_timing(:,s+1:s+Nfilter) * gt_alpha5_root';
-end
-
+  rx_timing_M = norm_rx_timing*M;
 endfunction
 
 
@@ -1094,15 +1049,6 @@ phase_rx = ones(Nc+1,1);
 
 % Freq offset estimator constants
 
-if 0
-global Nbpfcoeff;                                        % number of input BPF coeffs
-       Nbpfcoeff      = 100;                              
-global bpf_coeff;
-       bpf_coeff      = fir1(Nbpfcoeff-1, [Fcentre-100 Fcentre+100]/(Fs/2),'pass')';
-global Nbpf;
-       Nbpf           = Nbpfcoeff + M + M/P;             % number of pilot baseband samples reqd for pilot LPF
-end
-
 global Mpilotfft      = 256;
 
 global Npilotcoeff;                                      % number of pilot LPF coeffs
@@ -1124,10 +1070,6 @@ 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 2638021451dd7dd69e5bd5e6388ed3d81c63afbc..296ecf1ae7e2971c9e2b27089902d50d5badc7bb 100644 (file)
@@ -64,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 11 12 16];
+no_plot_list = [1 2 3 4 5 6 7 8 16];
 
 for f=1:frames
 
@@ -82,8 +82,10 @@ for f=1:frames
 
   % channel
 
-  %nin = next_nin;
-  nin = M;
+  nin = next_nin;
+
+  % nin = M;  % when debugging good idea to uncomment this to "open loop"
+
   channel = [channel real(tx_fdm)];
   channel_count += M;
   rx_fdm = channel(1:nin);
@@ -95,6 +97,9 @@ 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);
+
+  %sync = 0; % when debugging good idea to uncomment this to "open loop"
+
   if sync == 0
     foff = foff_coarse;
   end
@@ -120,9 +125,8 @@ for f=1:frames
   rx_filt = rx_filter(rx_baseband, nin);
   rx_filt_log = [rx_filt_log rx_filt];
 
-  [rx_symbols rx_timing env] = rx_est_timing(rx_filt, rx_baseband, nin);
+  [rx_symbols rx_timing env] = rx_est_timing(rx_filt, nin);
   env_log = [env_log env];
-
   rx_timing_log = [rx_timing_log rx_timing];
   rx_symbols_log = [rx_symbols_log rx_symbols];
 
@@ -247,7 +251,7 @@ plot_sig_and_error(9, 212, foff_fine_log, foff_fine_log - foff_fine_log_c, 'Fine
 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, 'Sync & Freq Est Coarse(0) Fine(1)', [1 frames -1.5 1.5] )
 
-c=15;
+c=1;
 plot_sig_and_error(11, 211, real(rx_baseband_log(c,:)), real(rx_baseband_log(c,:) - rx_baseband_log_c(c,:)), 'Rx baseband real' )
 plot_sig_and_error(11, 212, imag(rx_baseband_log(c,:)), imag(rx_baseband_log(c,:) - rx_baseband_log_c(c,:)), 'Rx baseband imag' )
 
index 0ed9d07c73504939b735b76f52267907c36646ee..134e62d48ef2c6ee759ccc5458a6955a4b50b1b6 100644 (file)
@@ -179,10 +179,6 @@ struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc)
            f->rx_filter_mem_timing[c][k].real = 0.0;
            f->rx_filter_mem_timing[c][k].imag = 0.0;
        }
-       for(k=0; k<NFILTERTIMING; k++) {
-           f->rx_baseband_mem_timing[c][k].real = 0.0;
-           f->rx_baseband_mem_timing[c][k].imag = 0.0;
-       }
     }
     
     fdmdv_set_fsep(f, FSEP);
@@ -897,16 +893,15 @@ void rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_baseband[NC+1][M+M/P], C
 float rx_est_timing(COMP rx_symbols[], 
                     int  Nc,
                    COMP rx_filt[NC+1][P+1], 
-                   COMP rx_baseband[NC+1][M+M/P], 
                    COMP rx_filter_mem_timing[NC+1][NT*P], 
                    float env[],
-                   COMP rx_baseband_mem_timing[NC+1][NFILTERTIMING], 
                    int nin)     
 {
-    int   c,i,j,k;
-    int   adjust, s;
+    int   c,i,j;
+    int   adjust;
     COMP  x, phase, freq;
-    float rx_timing;
+    float rx_timing, fract, norm_rx_timing;
+    int   low_sample, high_sample;
 
     /*
       nin  adjust 
@@ -950,41 +945,34 @@ float rx_est_timing(COMP rx_symbols[],
        phase = cmult(phase, freq);
     }
 
-    /* Map phase to estimated optimum timing instant at rate M.  The
-       M/4 part was adjusted by experiment, I know not why.... */
+    /* Map phase to estimated optimum timing instant at rate P.  The
+       P/4 part was adjusted by experiment, I know not why.... */
     
-    rx_timing = atan2(x.imag, x.real)*M/(2*PI) + M/4;
+    norm_rx_timing = atan2(x.imag, x.real)/(2*PI);
+    rx_timing      = norm_rx_timing*P + P/4;
     
-    if (rx_timing > M)
-       rx_timing -= M;
-    if (rx_timing < -M)
-       rx_timing += M;
-   
-    /* rx_filt_mem_timing contains M + Nfilter + M samples of the
-       baseband signal at rate M this enables us to resample the
-       filtered rx symbol with M sample precision once we have
-       rx_timing */
+    if (rx_timing > P)
+       rx_timing -= P;
+    if (rx_timing < -P)
+       rx_timing += P;
 
-    for(c=0; c<Nc+1; c++) 
-       for(i=0,j=nin; i<NFILTERTIMING-nin; i++,j++)
-           rx_baseband_mem_timing[c][i] = rx_baseband_mem_timing[c][j];
-    for(c=0; c<Nc+1; c++) 
-       for(i=NFILTERTIMING-nin,j=0; i<NFILTERTIMING; i++,j++)
-           rx_baseband_mem_timing[c][i] = rx_baseband[c][j];
-    
-    /* rx filter to get symbol for each carrier at estimated optimum
-       timing instant.  We use rate M filter memory to get fine timing
-       resolution. */
+    /* rx_filter_mem_timing contains Nt*P samples (Nt symbols at rate
+       P), where Nt is odd.  Lets use linear interpolation to resample
+       in the centre of the timing estimation window .*/
+
+    rx_timing  += floorf(NT/2.0)*P;
+    low_sample = floorf(rx_timing);
+    fract = rx_timing - low_sample;
+    high_sample = ceilf(rx_timing);
 
-    s = round(rx_timing) + M;
+    //printf("rx_timing: %f low_sample: %d high_sample: %d fract: %f\n", rx_timing, low_sample, high_sample, fract);
+    
     for(c=0; c<Nc+1; c++) {
-       rx_symbols[c].real = 0.0;
-       rx_symbols[c].imag = 0.0;
-       for(k=s,j=0; k<s+NFILTER; k++,j++)
-           rx_symbols[c] = cadd(rx_symbols[c], fcmult(gt_alpha5_root[j], rx_baseband_mem_timing[c][k]));
+        rx_symbols[c] = cadd(fcmult(1.0-fract, rx_filter_mem_timing[c][low_sample-1]), fcmult(fract, rx_filter_mem_timing[c][high_sample-1]));
+        //rx_symbols[c] = rx_filter_mem_timing[c][high_sample];
     }
-       
-    return rx_timing;
+       
+    return norm_rx_timing*M;
 }
 
 /*---------------------------------------------------------------------------*\
@@ -1306,7 +1294,7 @@ void CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[],
 
     fdm_downconvert(rx_baseband, fdmdv->Nc, rx_fdm_fcorr, fdmdv->phase_rx, fdmdv->freq, *nin);
     rx_filter(rx_filt, fdmdv->Nc, rx_baseband, fdmdv->rx_filter_memory, *nin);
-    fdmdv->rx_timing = rx_est_timing(rx_symbols, fdmdv->Nc, rx_filt, rx_baseband, fdmdv->rx_filter_mem_timing, env, fdmdv->rx_baseband_mem_timing, *nin);       
+    fdmdv->rx_timing = rx_est_timing(rx_symbols, fdmdv->Nc, rx_filt, fdmdv->rx_filter_mem_timing, env, *nin);   
     
     /* Adjust number of input samples to keep timing within bounds */
 
index cb6bf1483f9d589214b026fd2e4882f0b99c7152..2be958124e9005ddd3c0c8353f63a67dab98ee8e 100644 (file)
@@ -122,15 +122,9 @@ int main(int argc, char *argv[])
        \*---------------------------------------------------------*/
 
        nin = next_nin;
-       /*
-       if (f == 2)
-           nin = 120;
-       if (f == 3)
-           nin = 200;
-       if ((f !=2) && (f != 3))
-            nin = M;
-       */
-        nin = M;
+
+        //nin = M;  // when debugging good idea to uncomment this to "open loop"
+
        /* add M tx samples to end of buffer */
 
        assert((channel_count + M) < CHANNEL_BUF_SIZE);
@@ -158,6 +152,9 @@ int main(int argc, char *argv[])
        /* freq offset estimation and correction */
 
        foff_coarse = rx_est_freq_offset(fdmdv, rx_fdm, nin);
+
+        //fdmdv->sync = 0; // when debugging good idea to uncomment this to "open loop"
+
        if (fdmdv->sync == 0)
            fdmdv->foff = foff_coarse;
        fdmdv_freq_shift(rx_fdm_fcorr, rx_fdm, -fdmdv->foff, &fdmdv->foff_phase_rect, nin);
@@ -166,7 +163,7 @@ int main(int argc, char *argv[])
 
        fdm_downconvert(rx_baseband, FDMDV_NC, rx_fdm_fcorr, fdmdv->phase_rx, fdmdv->freq, nin);
        rx_filter(rx_filt, FDMDV_NC, rx_baseband, fdmdv->rx_filter_memory, nin);
-       rx_timing = rx_est_timing(rx_symbols, FDMDV_NC, rx_filt, rx_baseband, fdmdv->rx_filter_mem_timing, env, fdmdv->rx_baseband_mem_timing, nin);     
+       rx_timing = rx_est_timing(rx_symbols, FDMDV_NC, rx_filt, fdmdv->rx_filter_mem_timing, env, nin);         
        foff_fine = qpsk_to_bits(rx_bits, &sync_bit, FDMDV_NC, fdmdv->phase_difference, fdmdv->prev_rx_symbols, rx_symbols, 0);
         //for(i=0; i<FDMDV_NC;i++)
         //    printf("rx_symbols: %f %f prev_rx_symbols: %f %f phase_difference: %f %f\n", rx_symbols[i].real, rx_symbols[i].imag,