freq state machine working
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 26 Apr 2012 05:08:37 +0000 (05:08 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 26 Apr 2012 05:08:37 +0000 (05:08 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@382 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/README_fdmdv.txt
codec2-dev/octave/fdmdv_ut.m
codec2-dev/octave/tfdmdv.m
codec2-dev/src/fdmdv.c
codec2-dev/src/fdmdv.h
codec2-dev/src/fdmdv_internal.h
codec2-dev/unittest/tfdmdv.c

index fb1b3eaf2e89e483bc78e8c2812754a0f5e4fe7b..a845678eeb5f7342c6a59c52df20353fe74027e3 100644 (file)
@@ -6,6 +6,11 @@ sox -r 8000 -s -2 mod_dqpsk.raw -s -2 mod_dqpsk_8008hz.raw rate -h 8008
 
 TODO
 
+[ ] consider moving this file to root
+    [ ] sep SVN repo, automake etc?
+[ ] list each fdmdv.m script (ut, mod, demod) and Cprogram/src and what it does
+    [ ] example usage
+[ ] repair fdmdv_ut and mod/demod after new statres exposed and var renames
 [X] Get file based mod and demod working again
 [ ] try interfering sine wave
     + maybe swept
@@ -26,6 +31,7 @@ TODO
     [ ] mod in func with all vars
     [ ] check with ch impairments    
     [ ] test with freq offsets
+    [ ] measure execution speed
 [ ] document use of fdmdv_ut and fdmdv_demod + PathSim
 [ ] block diagram
     [ ] maybe in ascii art
index c99447af843c320dc1eb889a485316934bab7206..248ffe3d74d418b7291282c701b3518485fbf161 100644 (file)
@@ -185,7 +185,7 @@ for f=1:frames
   else
     rx_symbols_log = [rx_symbols_log rx_symbols];
   endif
-  [rx_bits sync ferr] = qpsk_to_bits(prev_rx_symbols, rx_symbols, modulation);
+  [rx_bits sync foff_fine] = qpsk_to_bits(prev_rx_symbols, rx_symbols, modulation);
   foff -= 0.5*ferr;
   prev_rx_symbols = rx_symbols;
   sync_log = [sync_log sync];
index 0175f7a736d5ae682ca1b17006946ebaeb0ebd5d..a1f8cf06111b6adc61b091bb57ef65a541e18e15 100644 (file)
@@ -19,6 +19,9 @@ passes = fails = 0;
 frames = 25;
 prev_tx_symbols = ones(Nc+1,1);
 prev_rx_symbols = ones(Nc+1,1);
+foff_phase_rect = 1;
+track = 0;
+fest_state = 0;
 
 % Octave outputs we want to collect for comparison to C version
 
@@ -32,6 +35,8 @@ pilot_lpf1_log = [];
 pilot_lpf2_log = [];
 S1_log = [];
 S2_log = [];
+foff_coarse_log = [];
+foff_fine_log = [];
 foff_log = [];
 rx_baseband_log = [];
 rx_filt_log = [];
@@ -39,8 +44,8 @@ env_log = [];
 rx_timing_log = [];
 rx_symbols_log = [];
 rx_bits_log = []; 
-ferr_log = [];
 sync_bit_log = [];  
+track_log = [];
 
 for f=1:frames
 
@@ -62,8 +67,12 @@ for f=1:frames
 
   [pilot prev_pilot pilot_lut_index prev_pilot_lut_index] = get_pilot(pilot_lut_index, prev_pilot_lut_index, M);
 
-  [foff S1 S2] = rx_est_freq_offset(rx_fdm, pilot, prev_pilot, M);
+  [foff_coarse S1 S2] = rx_est_freq_offset(rx_fdm, pilot, prev_pilot, M);
+  if track == 0
+    foff = foff_coarse;
+  end
   foff_log = [foff_log foff];
+  foff_coarse_log = [foff_coarse_log foff_coarse];
 
   pilot_baseband1_log = [pilot_baseband1_log pilot_baseband1];
   pilot_baseband2_log = [pilot_baseband2_log pilot_baseband2];
@@ -72,7 +81,14 @@ for f=1:frames
   S1_log  = [S1_log S1];
   S2_log  = [S2_log S2];
 
-  rx_baseband = fdm_downconvert(rx_fdm, M);
+  foff_rect = exp(j*2*pi*foff/Fs);
+
+  for i=1:M
+    foff_phase_rect *= foff_rect';
+    rx_fdm_fcorr(i) = rx_fdm(i)*foff_phase_rect;
+  end
+
+  rx_baseband = fdm_downconvert(rx_fdm_fcorr, M);
   rx_baseband_log = [rx_baseband_log rx_baseband];
 
   rx_filt = rx_filter(rx_baseband, M);
@@ -84,11 +100,16 @@ for f=1:frames
   rx_timing_log = [rx_timing_log rx_timing];
   rx_symbols_log = [rx_symbols_log rx_symbols];
 
-  [rx_bits sync_bit ferr] = qpsk_to_bits(prev_rx_symbols, rx_symbols, 'dqpsk');
+  [rx_bits sync_bit foff_fine] = qpsk_to_bits(prev_rx_symbols, rx_symbols, 'dqpsk');
   prev_rx_symbols = rx_symbols;
   rx_bits_log = [rx_bits_log rx_bits]; 
-  ferr_log = [ferr_log ferr];
+  foff_fine_log = [foff_fine_log foff_fine];
   sync_bit_log = [sync_bit_log sync_bit];  
+
+  % freq est state machine
+
+  [track fest_state] = freq_state(sync_bit, fest_state);
+  track_log = [track_log track];
 end
 
 % Compare to the output from the C version
@@ -164,26 +185,29 @@ plot_sig_and_error(7, 212, imag(S1_log), imag(S1_log - S1_log_c), 'S1 imag' )
 plot_sig_and_error(8, 211, real(S2_log), real(S2_log - S2_log_c), 'S2 real' )
 plot_sig_and_error(8, 212, imag(S2_log), imag(S2_log - S2_log_c), 'S2 imag' )
 
-plot_sig_and_error(9, 211, real(foff_log), real(foff_log - foff_log_c), 'Freq Offset' )
-plot_sig_and_error(9, 212, rx_timing_log, rx_timing_log - rx_timing_log_c, 'Rx Timing' )
+plot_sig_and_error(9, 211, foff_coarse_log, foff_coarse_log - foff_coarse_log_c, 'Coarse Freq Offset' )
+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, track_log, track_log - track_log_c, 'Freq Track' )
 
 c=15;
-plot_sig_and_error(10, 211, real(rx_baseband_log(c,:)), real(rx_baseband_log(c,:) - rx_baseband_log_c(c,:)), 'Rx baseband real' )
-plot_sig_and_error(10, 212, imag(rx_baseband_log(c,:)), imag(rx_baseband_log(c,:) - rx_baseband_log_c(c,:)), 'Rx baseband imag' )
+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' )
 
-plot_sig_and_error(11, 211, real(rx_filt_log(c,:)), real(rx_filt_log(c,:) - rx_filt_log_c(c,:)), 'Rx filt real' )
-plot_sig_and_error(11, 212, imag(rx_filt_log(c,:)), imag(rx_filt_log(c,:) - rx_filt_log_c(c,:)), 'Rx filt imag' )
+plot_sig_and_error(12, 211, real(rx_filt_log(c,:)), real(rx_filt_log(c,:) - rx_filt_log_c(c,:)), 'Rx filt real' )
+plot_sig_and_error(12, 212, imag(rx_filt_log(c,:)), imag(rx_filt_log(c,:) - rx_filt_log_c(c,:)), 'Rx filt imag' )
 
-plot_sig_and_error(12, 211, env_log, env_log - env_log_c, 'env' )
-plot_sig_and_error(12, 212, real(rx_symbols_log(c,:)), real(rx_symbols_log(c,:) - rx_symbols_log_c(c,:)), 'rx symbols' )
+plot_sig_and_error(13, 211, env_log, env_log - env_log_c, 'env' )
+plot_sig_and_error(13, 212, real(rx_symbols_log(c,:)), real(rx_symbols_log(c,:) - rx_symbols_log_c(c,:)), 'rx symbols' )
 
 st=10*28;
 en = 12*28;
-stem_sig_and_error(13, 211, rx_bits_log_c(st:en), rx_bits_log(st:en) - rx_bits_log_c(st:en), 'RX bits', [1 en-st -1.5 1.5])
-
-plot_sig_and_error(14, 211, ferr_log, ferr_log - ferr_log_c, 'Fine freq error' )
+plot_sig_and_error(14, 211, rx_timing_log, rx_timing_log - rx_timing_log_c, 'Rx Timing' )
 stem_sig_and_error(14, 212, sync_bit_log_c, sync_bit_log - sync_bit_log_c, 'Sync bit', [1 n -1.5 1.5])
 
+stem_sig_and_error(15, 211, rx_bits_log_c(st:en), rx_bits_log(st:en) - rx_bits_log_c(st:en), 'RX bits', [1 en-st -1.5 1.5])
+
 % ---------------------------------------------------------------------------------------
 % AUTOMATED CHECKS ------------------------------------------
 % ---------------------------------------------------------------------------------------
@@ -198,8 +222,8 @@ function check(a, b, test_name)
     printf(".");
   end
   printf(": ");  
-
-  if sum(a - b)/n < 1E-3
+  
+  if abs(sum(a - b))/n < 1E-3
     printf("OK\n");
     passes++;
   else
@@ -208,23 +232,24 @@ function check(a, b, test_name)
   end
 endfunction
 
-check(tx_bits_log, tx_bits_log_c, 'fdmdv_get_test_bits');
-check(tx_symbols_log,  tx_symbols_log_c, 'bits_to_dqpsk_symbols');
-check(tx_baseband_log, tx_baseband_log_c, 'tx_filter');
+check(tx_bits_log, tx_bits_log_c, 'tx_bits');
+check(tx_symbols_log,  tx_symbols_log_c, 'tx_symbols');
+check(tx_baseband_log, tx_baseband_log_c, 'tx_baseband');
 check(tx_fdm_log, tx_fdm_log_c, 'tx_fdm');
 check(pilot_lut, pilot_lut_c, 'pilot_lut');
 check(pilot_baseband1_log, pilot_baseband1_log_c, 'pilot lpf1');
 check(pilot_baseband2_log, pilot_baseband2_log_c, 'pilot lpf2');
 check(S1_log, S1_log_c, 'S1');
 check(S2_log, S2_log_c, 'S2');
-check(foff_log, foff_log_c, 'rx_est_freq_offset');
+check(foff_coarse_log, foff_coarse_log_c, 'foff_coarse');
+check(foff_fine_log, foff_fine_log_c, 'foff_fine');
+check(foff_log, foff_log_c, 'foff');
 check(rx_baseband_log, rx_baseband_log_c, 'rx baseband');
 check(rx_filt_log, rx_filt_log_c, 'rx filt');
 check(env_log, env_log_c, 'env');
-check(rx_timing_log, rx_timing_log_c, 'rx_est_timing');
+check(rx_timing_log, rx_timing_log_c, 'rx_timing');
 check(rx_symbols_log, rx_symbols_log_c, 'rx_symbols');
 check(rx_bits_log, rx_bits_log_c, 'rx bits');
-check(ferr_log, ferr_log_c, 'fine freq error');
 check(sync_bit_log, sync_bit_log_c, 'sync bit');
 
 printf("\npasses: %d fails: %d\n", passes, fails);
index a70ff11b850616632f69c4fecc4675c6eb68c0bd..abf6b94af354c54b2645157deabb7c80e9a80aae 100644 (file)
@@ -222,6 +222,14 @@ struct FDMDV *fdmdv_create(void)
        f->pilot_lpf1[i].imag = f->pilot_lpf2[i].imag = 0.0;
     }
 
+    f->foff_rect.real = 1.0;
+    f->foff_rect.imag = 0.0;
+    f->foff_phase_rect.real = 1.0;
+    f->foff_phase_rect.imag = 0.0;
+
+    f->fest_state = 0;
+    f->track = 0;
+
     return f;
 }
 
@@ -432,6 +440,31 @@ void fdm_upconvert(COMP tx_fdm[], COMP tx_baseband[NC+1][M], COMP phase_tx[], CO
 
 }
 
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: fdmdv_mod()         
+  AUTHOR......: David Rowe                           
+  DATE CREATED: 26/4/2012
+
+  FDMDV modulator, take a frame of FDMDV_BITS_PER_FRAME bits and
+  generates a frame of FDMDV_SAMPLES_PER_FRAME modulated symbols.
+  Sync bit is returned to aid alignment of your next frame.
+
+\*---------------------------------------------------------------------------*/
+
+void fdmdv_mod(struct FDMDV *fdmdv, COMP tx_fdm[], int tx_bits[], int *sync_bit)
+{
+    COMP          tx_symbols[NC+1];
+    COMP          tx_baseband[NC+1][M];
+
+    bits_to_dqpsk_symbols(tx_symbols, fdmdv->prev_tx_symbols, tx_bits, &fdmdv->tx_pilot_bit);
+    memcpy(fdmdv->prev_tx_symbols, tx_symbols, sizeof(COMP)*(NC+1));
+    tx_filter(tx_baseband, tx_symbols, fdmdv->tx_filter_memory);
+    fdm_upconvert(tx_fdm, tx_baseband, fdmdv->phase_tx, fdmdv->freq);
+
+    *sync_bit = fdmdv->tx_pilot_bit;
+}
+
 /*---------------------------------------------------------------------------*\
                                                        
   FUNCTION....: generate_pilot_fdm()        
@@ -647,6 +680,29 @@ float rx_est_freq_offset(struct FDMDV *f, float rx_fdm[], int nin)
     return foff;
 }
 
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: freq_shift()        
+  AUTHOR......: David Rowe                           
+  DATE CREATED: 26/4/2012
+
+  Frequency shift modem signal.
+
+\*---------------------------------------------------------------------------*/
+
+void freq_shift(COMP rx_fdm_fcorr[], float rx_fdm[], float foff, COMP *foff_rect, COMP *foff_phase_rect, int nin)
+{
+    int i;
+
+    foff_rect->real = cos(2.0*PI*foff/FS);
+    foff_rect->imag = sin(2.0*PI*foff/FS);
+    for(i=0; i<nin; i++) {
+       *foff_phase_rect = cmult(*foff_phase_rect, cconj(*foff_rect));
+       rx_fdm_fcorr[i] = fcmult(rx_fdm[i], *foff_phase_rect);
+    }
+  
+}
+
 /*---------------------------------------------------------------------------*\
                                                        
   FUNCTION....: fdm_downconvert()           
@@ -1031,3 +1087,46 @@ int freq_state(int sync_bit, int *state)
  
     return track;
 }
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: fdmdv_demod()       
+  AUTHOR......: David Rowe                           
+  DATE CREATED: 26/4/2012
+
+  FDMDV demodulator, take an array of FDMDV_SAMPLES_PER_FRAME
+  modulated symbols, returns an array of FDMDV_BITS_PER_FRAME bits,
+  plus the sync bit.  
+
+  The number of input samples nin will normally be M ==
+  FDMDV_SAMPLES_PER_FRAME.  However to adjust for differences in
+  transmit and receive sample clocks nin will occasionally be M-M/P,
+  or M+M/P.
+
+\*---------------------------------------------------------------------------*/
+
+void fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[], int *sync_bit, float rx_fdm[], int *nin)
+{
+    float         foff;
+    COMP          rx_fdm_fcorr[M+M/P];
+    COMP          rx_baseband[NC+1][M+M/P];
+    COMP          rx_filt[NC+1][P+1];
+    float         rx_timing;
+    float         env[NT*P];
+    COMP          rx_symbols[NC+1];
+    float         ferr;
+
+    /* freq offset estimation and correction */
+
+    foff = rx_est_freq_offset(fdmdv, rx_fdm, *nin);
+    freq_shift(rx_fdm_fcorr, rx_fdm, foff, &fdmdv->foff_rect, &fdmdv->foff_phase_rect, *nin);
+       
+    /* baseband processing */
+
+    fdm_downconvert(rx_baseband, rx_fdm_fcorr, fdmdv->phase_rx, fdmdv->freq, *nin);
+    rx_filter(rx_filt, rx_baseband, fdmdv->rx_filter_memory, *nin);
+    rx_timing = rx_est_timing(rx_symbols, rx_filt, rx_baseband, fdmdv->rx_filter_mem_timing, env, fdmdv->rx_baseband_mem_timing, *nin);         
+    ferr = qpsk_to_bits(rx_bits, sync_bit, fdmdv->prev_rx_symbols, rx_symbols);
+    memcpy(fdmdv->prev_rx_symbols, rx_symbols, sizeof(COMP)*(NC+1));
+}
+
index 755bc6a24937dfb0ae106c09d9767b6cc09b27fc..75700629ba3d55d83e9ee67a3ffa606584eb32d4 100644 (file)
@@ -52,8 +52,8 @@ struct FDMDV_STATS {
 struct FDMDV *fdmdv_create(void);
 void          fdmdv_destroy(struct FDMDV *fdmdv_state);
     
-void          fdmdv_mod(struct FDMDV *fdmdv_state, COMP tx_fdm[], int tx_bits[], int *sync);
-void          fdmdv_demod(struct FDMDV *fdmdv_state, int rx_bits[], int *sync, float rx_fdm[], int *nin);
+void          fdmdv_mod(struct FDMDV *fdmdv_state, COMP tx_fdm[], int tx_bits[], int *sync_bit);
+void          fdmdv_demod(struct FDMDV *fdmdv_state, int rx_bits[], int *sync_bit, float rx_fdm[], int *nin);
     
 void          fdmdv_get_test_bits(struct FDMDV *fdmdv_state, int tx_bits[]);
 void          fdmdv_put_test_bits(struct FDMDV *f, int *sync, int *bit_errors, int rx_bits[]);
index 9fbedd909d905e87f1f5d8039efc2f9ec1643a1c..7982ff6b01f9c93ea5cf244511ecfbce2ca3b136 100644 (file)
@@ -90,11 +90,17 @@ struct FDMDV {
     COMP S1[MPILOTFFT];
     COMP S2[MPILOTFFT];
 
+    COMP foff_rect;
+    COMP foff_phase_rect;
+    
     COMP phase_rx[NC+1];
     COMP rx_filter_memory[NC+1][NFILTER];
     COMP rx_filter_mem_timing[NC+1][NT*P];
     COMP rx_baseband_mem_timing[NC+1][NFILTERTIMING];
     COMP prev_rx_symbols[NC+1];
+    
+    int  fest_state;
+    int  track;
 };
 
 /*---------------------------------------------------------------------------*\
@@ -110,6 +116,7 @@ void generate_pilot_fdm(COMP *pilot_fdm, int *bit, float *symbol, float *filter_
 void generate_pilot_lut(COMP pilot_lut[], COMP *pilot_freq);
 float rx_est_freq_offset(struct FDMDV *f, float rx_fdm[], int nin);
 void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], COMP pilot_lpf[], COMP S[], int nin);
+void freq_shift(COMP rx_fdm_fcorr[], float rx_fdm[], float foff, COMP *foff_rect, COMP *foff_phase_rect, int nin);
 void fdm_downconvert(COMP rx_baseband[NC+1][M+M/P], COMP rx_fdm[], COMP phase_rx[], COMP freq[], int nin);
 void rx_filter(COMP rx_filt[NC+1][P+1], COMP rx_baseband[NC+1][M+M/P], COMP rx_filter_memory[NC+1][NFILTER], int nin);
 float rx_est_timing(COMP  rx_symbols[], 
index a28a3990d6b736f4229d22d981352c59962f36c8..3b8277e68f6632fd5483367fdb46ec58a92d3979 100644 (file)
@@ -52,9 +52,8 @@ int main(int argc, char *argv[])
     COMP          tx_baseband[NC+1][M];
     COMP          tx_fdm[M];
     float         rx_fdm[M+M/P];
+    float         foff_coarse;
     float         foff;
-    COMP          foff_rect;
-    COMP          foff_phase_rect;
     int           nin;
     COMP          rx_fdm_fcorr[M+M/P];
     COMP          rx_baseband[NC+1][M+M/P];
@@ -63,9 +62,10 @@ int main(int argc, char *argv[])
     float         env[NT*P];
     COMP          rx_symbols[NC+1];
     int           rx_bits[FDMDV_BITS_PER_FRAME];
-    float         ferr;
+    float         foff_fine;
     int           sync_bit;
+    int           fest_state;
+
     int           tx_bits_log[FDMDV_BITS_PER_FRAME*FRAMES];
     COMP          tx_symbols_log[(NC+1)*FRAMES];
     COMP          tx_baseband_log[(NC+1)][M*FRAMES];
@@ -76,6 +76,7 @@ int main(int argc, char *argv[])
     COMP          pilot_lpf2_log[NPILOTLPF*FRAMES];
     COMP          S1_log[MPILOTFFT*FRAMES];
     COMP          S2_log[MPILOTFFT*FRAMES];
+    float         foff_coarse_log[FRAMES];
     float         foff_log[FRAMES];
     COMP          rx_baseband_log[(NC+1)][(M+M/P)*FRAMES];
     int           rx_baseband_log_col_index;
@@ -85,14 +86,14 @@ int main(int argc, char *argv[])
     float         rx_timing_log[FRAMES];
     COMP          rx_symbols_log[NC+1][FRAMES];
     int           rx_bits_log[FDMDV_BITS_PER_FRAME*FRAMES];
-    float         ferr_log[FRAMES];
+    float         foff_fine_log[FRAMES];
     int           sync_bit_log[FRAMES];
+    int           track_log[FRAMES];
 
     FILE         *fout;
     int           f,c,i;
 
     fdmdv = fdmdv_create();
-    foff_phase_rect.real = 0.0; foff_phase_rect.imag = 0.0;
 
     rx_baseband_log_col_index = 0;
     rx_filt_log_col_index = 0;
@@ -119,7 +120,9 @@ int main(int argc, char *argv[])
 
        /* freq offset estimation and correction */
 
-       foff = rx_est_freq_offset(fdmdv, rx_fdm, nin);
+       foff_coarse = rx_est_freq_offset(fdmdv, rx_fdm, nin);
+       if (fdmdv->track == 0)
+           foff = foff_coarse;
        freq_shift(rx_fdm_fcorr, rx_fdm, foff, &fdmdv->foff_rect, &fdmdv->foff_phase_rect, nin);
        
        /* baseband processing */
@@ -127,9 +130,10 @@ int main(int argc, char *argv[])
        fdm_downconvert(rx_baseband, rx_fdm_fcorr, fdmdv->phase_rx, fdmdv->freq, nin);
        rx_filter(rx_filt, rx_baseband, fdmdv->rx_filter_memory, nin);
        rx_timing = rx_est_timing(rx_symbols, rx_filt, rx_baseband, fdmdv->rx_filter_mem_timing, env, fdmdv->rx_baseband_mem_timing, nin);       
-       ferr = qpsk_to_bits(rx_bits, &sync_bit, fdmdv->prev_rx_symbols, rx_symbols);
+       foff_fine = qpsk_to_bits(rx_bits, &sync_bit, fdmdv->prev_rx_symbols, rx_symbols);
        memcpy(fdmdv->prev_rx_symbols, rx_symbols, sizeof(COMP)*(NC+1));
-           
+       fdmdv->track = freq_state(sync_bit, &fdmdv->fest_state);
+       
        /* --------------------------------------------------------*\
                            Log each vector 
        \*---------------------------------------------------------*/
@@ -149,6 +153,7 @@ int main(int argc, char *argv[])
        memcpy(&pilot_lpf2_log[f*NPILOTLPF], fdmdv->pilot_lpf2, sizeof(COMP)*NPILOTLPF);
        memcpy(&S1_log[f*MPILOTFFT], fdmdv->S1, sizeof(COMP)*MPILOTFFT);
        memcpy(&S2_log[f*MPILOTFFT], fdmdv->S2, sizeof(COMP)*MPILOTFFT);
+       foff_coarse_log[f] = foff_coarse;
        foff_log[f] = foff;
 
        /* rx down conversion */
@@ -177,8 +182,10 @@ int main(int argc, char *argv[])
        /* qpsk_to_bits() */
 
        memcpy(&rx_bits_log[FDMDV_BITS_PER_FRAME*f], rx_bits, sizeof(int)*FDMDV_BITS_PER_FRAME);
-       ferr_log[f] = ferr;
+       foff_fine_log[f] = foff_fine;
        sync_bit_log[f] = sync_bit;
+
+       track_log[f] = fdmdv->track;
     }
 
 
@@ -202,14 +209,16 @@ int main(int argc, char *argv[])
     octave_save_complex(fout, "S1_log_c", S1_log, 1, MPILOTFFT*FRAMES, MPILOTFFT*FRAMES);  
     octave_save_complex(fout, "S2_log_c", S2_log, 1, MPILOTFFT*FRAMES, MPILOTFFT*FRAMES);  
     octave_save_float(fout, "foff_log_c", foff_log, 1, FRAMES);  
+    octave_save_float(fout, "foff_coarse_log_c", foff_coarse_log, 1, FRAMES);  
     octave_save_complex(fout, "rx_baseband_log_c", (COMP*)rx_baseband_log, (NC+1), rx_baseband_log_col_index, (M+M/P)*FRAMES);  
     octave_save_complex(fout, "rx_filt_log_c", (COMP*)rx_filt_log, (NC+1), rx_filt_log_col_index, (P+1)*FRAMES);  
     octave_save_float(fout, "env_log_c", env_log, 1, NT*P*FRAMES);  
     octave_save_float(fout, "rx_timing_log_c", rx_timing_log, 1, FRAMES);  
     octave_save_complex(fout, "rx_symbols_log_c", (COMP*)rx_symbols_log, (NC+1), FRAMES, FRAMES);  
     octave_save_int(fout, "rx_bits_log_c", rx_bits_log, 1, FDMDV_BITS_PER_FRAME*FRAMES);
-    octave_save_float(fout, "ferr_log_c", ferr_log, 1, FRAMES);  
+    octave_save_float(fout, "foff_fine_log_c", foff_fine_log, 1, FRAMES);  
     octave_save_int(fout, "sync_bit_log_c", sync_bit_log, 1, FRAMES);  
+    octave_save_int(fout, "track_log_c", track_log, 1, FRAMES);  
     fclose(fout);
 
     codec2_destroy(fdmdv);