automated unit tests passing for new, memory efficient, downconvert and rx filter...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 30 Jun 2014 23:22:27 +0000 (23:22 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 30 Jun 2014 23:22:27 +0000 (23:22 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1718 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/fdmdv.m
codec2-dev/octave/tfdmdv.m
codec2-dev/src/codec2_fdmdv.h
codec2-dev/src/fdmdv.c
codec2-dev/src/fdmdv_internal.h

index 8fecdacc9153d088f3df010ca714a07fe693b8f2..a742dec85372155d7ead4945f76557a8b891ab38 100644 (file)
@@ -299,7 +299,7 @@ function rx_filt = rx_filter(rx_baseband, nin)
 endfunction
 
 
-% Combined down convert and rx filter, more memort efficentut less intuitive design
+% Combined down convert and rx filter, more memory efficient but less intuitive design
 
 function rx_filt = down_convert_and_rx_filter(rx_fdm, nin)
   global Nc;
@@ -330,7 +330,7 @@ function rx_filt = down_convert_and_rx_filter(rx_fdm, nin)
      % This means winding phase(c) back from this point
      % to ensure phase continuity
 
-      wind_back_phase = -freq_pol(c)*Nfilter;
+     wind_back_phase = -freq_pol(c)*Nfilter;
      phase_rx(c)     =  phase_rx(c)*exp(j*wind_back_phase);
     
      % down convert all samples in buffer
@@ -339,7 +339,7 @@ function rx_filt = down_convert_and_rx_filter(rx_fdm, nin)
      st  = Nfilter+M;      % end of buffer
      st -= nin-1;          % first new sample
      st -= Nfilter;        % first sample used in filtering
+     
      for i=st:Nfilter+M
         phase_rx(c) = phase_rx(c) * freq(c);
        rx_baseband(i) = rx_fdm_mem(i)*phase_rx(c)';
@@ -347,8 +347,7 @@ function rx_filt = down_convert_and_rx_filter(rx_fdm, nin)
  
      % now we can filter this carrier's P symbols
 
-     N=M/P;
-     k=1;
+     N=M/P; k = 1;
      for i=1:N:nin
        rx_filt(c,k) = rx_baseband(st+i-1:st+i-1+Nfilter-1) * gt_alpha5_root';
        k+=1;
index 296ecf1ae7e2971c9e2b27089902d50d5badc7bb..2ad4c2b41f732b8e1ca1164d6a4843d465605a7c 100644 (file)
@@ -84,7 +84,7 @@ for f=1:frames
 
   nin = next_nin;
 
-  % nin = M;  % when debugging good idea to uncomment this to "open loop"
+  %nin = M;  % when debugging good idea to uncomment this to "open loop"
 
   channel = [channel real(tx_fdm)];
   channel_count += M;
@@ -119,10 +119,15 @@ for f=1:frames
     rx_fdm_fcorr(i) = rx_fdm(i)*foff_phase_rect;
   end
 
-  rx_baseband = fdm_downconvert(rx_fdm_fcorr, nin);
+if 1
+  % more memory efficient but more complex
+  rx_filt = down_convert_and_rx_filter(rx_fdm_fcorr, nin);
+else
+  rx_baseband = fdm_downconvert(rx_fdm_corr,nin);
   rx_baseband_log = [rx_baseband_log rx_baseband];
-
   rx_filt = rx_filter(rx_baseband, nin);
+end
+
   rx_filt_log = [rx_filt_log rx_filt];
 
   [rx_symbols rx_timing env] = rx_est_timing(rx_filt, nin);
@@ -252,8 +257,10 @@ 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=1;
+if 0
 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' )
+end
 
 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' )
@@ -316,7 +323,7 @@ check(S2_log, S2_log_c, 'S2');
 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_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_timing');
index 5938c64219181d653aeed0ebf8686a0470c045ea..0b5d8babb7de8407feda70cb0bbb413953d6651d 100644 (file)
@@ -90,31 +90,31 @@ struct FDMDV_STATS {
     float  clock_offset;               /* Estimated tx/rx sample clock offset in ppm         */
 };
 
-struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc);
-void           CODEC2_WIN32SUPPORT fdmdv_destroy(struct FDMDV *fdmdv_state);
-void           CODEC2_WIN32SUPPORT fdmdv_use_old_qpsk_mapping(struct FDMDV *fdmdv_state);
-int            CODEC2_WIN32SUPPORT fdmdv_bits_per_frame(struct FDMDV *fdmdv_state);
-float          CODEC2_WIN32SUPPORT fdmdv_get_fsep(struct FDMDV *fdmdv_state);
-void           CODEC2_WIN32SUPPORT fdmdv_set_fsep(struct FDMDV *fdmdv_state, float fsep);
-
-void           CODEC2_WIN32SUPPORT fdmdv_mod(struct FDMDV *fdmdv_state, COMP tx_fdm[], int tx_bits[], int *sync_bit);
-void           CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv_state, int rx_bits[], int *reliable_sync_bit, COMP rx_fdm[], int *nin);
+struct FDMDV * fdmdv_create(int Nc);
+void           fdmdv_destroy(struct FDMDV *fdmdv_state);
+void           fdmdv_use_old_qpsk_mapping(struct FDMDV *fdmdv_state);
+int            fdmdv_bits_per_frame(struct FDMDV *fdmdv_state);
+float          fdmdv_get_fsep(struct FDMDV *fdmdv_state);
+void           fdmdv_set_fsep(struct FDMDV *fdmdv_state, float fsep);
+
+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 *reliable_sync_bit, COMP rx_fdm[], int *nin);
     
-void           CODEC2_WIN32SUPPORT fdmdv_get_test_bits(struct FDMDV *fdmdv_state, int tx_bits[]);
-int            CODEC2_WIN32SUPPORT fdmdv_error_pattern_size(struct FDMDV *fdmdv_state);
-void           CODEC2_WIN32SUPPORT fdmdv_put_test_bits(struct FDMDV *f, int *sync, short error_pattern[], int *bit_errors, int *ntest_bits, int rx_bits[]);
+void           fdmdv_get_test_bits(struct FDMDV *fdmdv_state, int tx_bits[]);
+int            fdmdv_error_pattern_size(struct FDMDV *fdmdv_state);
+void           fdmdv_put_test_bits(struct FDMDV *f, int *sync, short error_pattern[], int *bit_errors, int *ntest_bits, int rx_bits[]);
     
-void           CODEC2_WIN32SUPPORT fdmdv_get_demod_stats(struct FDMDV *fdmdv_state, struct FDMDV_STATS *fdmdv_stats);
-void           CODEC2_WIN32SUPPORT fdmdv_get_rx_spectrum(struct FDMDV *fdmdv_state, float mag_dB[], COMP rx_fdm[], int nin);
+void           fdmdv_get_demod_stats(struct FDMDV *fdmdv_state, struct FDMDV_STATS *fdmdv_stats);
+void           fdmdv_get_rx_spectrum(struct FDMDV *fdmdv_state, float mag_dB[], COMP rx_fdm[], int nin);
 
-void           CODEC2_WIN32SUPPORT fdmdv_8_to_48(float out48k[], float in8k[], int n);
-void           CODEC2_WIN32SUPPORT fdmdv_48_to_8(float out8k[], float in48k[], int n);
+void           fdmdv_8_to_48(float out48k[], float in8k[], int n);
+void           fdmdv_48_to_8(float out8k[], float in48k[], int n);
 
-void           CODEC2_WIN32SUPPORT fdmdv_freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, COMP *foff_phase_rect, int nin);
+void           fdmdv_freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, COMP *foff_phase_rect, int nin);
 
 /* debug/development function(s) */
 
-void CODEC2_WIN32SUPPORT fdmdv_dump_osc_mags(struct FDMDV *f);
+void fdmdv_dump_osc_mags(struct FDMDV *f);
  
 #ifdef __cplusplus
 }
index 134e62d48ef2c6ee759ccc5458a6955a4b50b1b6..cd488e9f567a7765c22b7110841220a0b0ff0b80 100644 (file)
@@ -121,7 +121,7 @@ static float cabsolute(COMP a)
 
 \*---------------------------------------------------------------------------*/
 
-struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc)
+struct FDMDV * fdmdv_create(int Nc)
 {
     struct FDMDV *f;
     int           c, i, k;
@@ -160,11 +160,6 @@ struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc)
            f->tx_filter_memory[c][k].imag = 0.0;
        }
 
-       for(k=0; k<NFILTER; k++) {
-           f->rx_filter_memory[c][k].real = 0.0;
-           f->rx_filter_memory[c][k].imag = 0.0;
-       }
-
        /* Spread initial FDM carrier phase out as far as possible.
            This helped PAPR for a few dB.  We don't need to adjust rx
            phase as DQPSK takes care of that. */
@@ -184,6 +179,7 @@ struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc)
     fdmdv_set_fsep(f, FSEP);
     f->freq[Nc].real = cos(2.0*PI*FDMDV_FCENTRE/FS);
     f->freq[Nc].imag = sin(2.0*PI*FDMDV_FCENTRE/FS);
+    f->freq_pol[Nc]  = 2.0*PI*FDMDV_FCENTRE/FS;
 
     /* Generate DBPSK pilot Look Up Table (LUT) */
 
@@ -210,6 +206,11 @@ struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc)
     f->foff_phase_rect.real = 1.0;
     f->foff_phase_rect.imag = 0.0;
 
+    for(i=0; i<NFILTER+M; i++) {
+        f->rx_fdm_mem[i].real = 0.0; 
+        f->rx_fdm_mem[i].imag = 0.0; 
+    }
+
     f->fest_state = 0;
     f->sync = 0;
     f->timer = 0;
@@ -240,7 +241,7 @@ struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc)
 
 \*---------------------------------------------------------------------------*/
 
-void CODEC2_WIN32SUPPORT fdmdv_destroy(struct FDMDV *fdmdv)
+void fdmdv_destroy(struct FDMDV *fdmdv)
 {
     assert(fdmdv != NULL);
     KISS_FFT_FREE(fdmdv->fft_pilot_cfg);
@@ -250,12 +251,12 @@ void CODEC2_WIN32SUPPORT fdmdv_destroy(struct FDMDV *fdmdv)
 }
 
 
-void CODEC2_WIN32SUPPORT fdmdv_use_old_qpsk_mapping(struct FDMDV *fdmdv) {
+void fdmdv_use_old_qpsk_mapping(struct FDMDV *fdmdv) {
     fdmdv->old_qpsk_mapping = 1;  
 }
 
 
-int CODEC2_WIN32SUPPORT fdmdv_bits_per_frame(struct FDMDV *fdmdv)
+int fdmdv_bits_per_frame(struct FDMDV *fdmdv)
 {
     return (fdmdv->Nc * NB);
 }
@@ -272,7 +273,7 @@ int CODEC2_WIN32SUPPORT fdmdv_bits_per_frame(struct FDMDV *fdmdv)
 
 \*---------------------------------------------------------------------------*/
 
-void CODEC2_WIN32SUPPORT fdmdv_get_test_bits(struct FDMDV *f, int tx_bits[])
+void fdmdv_get_test_bits(struct FDMDV *f, int tx_bits[])
 {
     int i;
     int bits_per_frame = fdmdv_bits_per_frame(f);
@@ -285,12 +286,12 @@ void CODEC2_WIN32SUPPORT fdmdv_get_test_bits(struct FDMDV *f, int tx_bits[])
     }
  }
 
-float CODEC2_WIN32SUPPORT fdmdv_get_fsep(struct FDMDV *f)
+float fdmdv_get_fsep(struct FDMDV *f)
 {
     return f->fsep;
 }
 
-void CODEC2_WIN32SUPPORT fdmdv_set_fsep(struct FDMDV *f, float fsep) {
+void fdmdv_set_fsep(struct FDMDV *f, float fsep) {
     int   c;
     float carrier_freq;
 
@@ -301,12 +302,14 @@ void CODEC2_WIN32SUPPORT fdmdv_set_fsep(struct FDMDV *f, float fsep) {
        carrier_freq = (-f->Nc/2 + c)*f->fsep + FDMDV_FCENTRE;
        f->freq[c].real = cos(2.0*PI*carrier_freq/FS);
        f->freq[c].imag = sin(2.0*PI*carrier_freq/FS);
+       f->freq_pol[c]  = 2.0*PI*carrier_freq/FS;
     }
 
     for(c=f->Nc/2; c<f->Nc; c++) {
        carrier_freq = (-f->Nc/2 + c + 1)*f->fsep + FDMDV_FCENTRE;
        f->freq[c].real = cos(2.0*PI*carrier_freq/FS);
        f->freq[c].imag = sin(2.0*PI*carrier_freq/FS);
+       f->freq_pol[c]  = 2.0*PI*carrier_freq/FS;
     }
 }
 
@@ -513,8 +516,7 @@ void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M], COMP phase_
 
 \*---------------------------------------------------------------------------*/
 
-void CODEC2_WIN32SUPPORT fdmdv_mod(struct FDMDV *fdmdv, COMP tx_fdm[], 
-                                  int tx_bits[], int *sync_bit)
+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];
@@ -755,8 +757,8 @@ float rx_est_freq_offset(struct FDMDV *f, COMP rx_fdm[], int nin)
 
 \*---------------------------------------------------------------------------*/
 
-void CODEC2_WIN32SUPPORT fdmdv_freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, 
-                                          COMP *foff_phase_rect, int nin)
+void fdmdv_freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, 
+                      COMP *foff_phase_rect, int nin)
 {
     COMP  foff_rect;
     float mag;
@@ -879,6 +881,95 @@ void rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_baseband[NC+1][M+M/P], C
     assert(j <= (P+1)); /* check for any over runs */
 }
 
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: down_convert_and_rx_filter()        
+  AUTHOR......: David Rowe                           
+  DATE CREATED: 30/6/2014
+
+  Combined down convert and rx filter, more memory efficient but less
+  intuitive design.  
+
+  Depending on the number of input samples to the demod nin, we
+  produce P-1, P (usually), or P+1 filtered samples at rate P.  nin is
+  occasionally adjusted to compensate for timing slips due to
+  different tx and rx sample clocks.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+TODO:
+  [ ] windback phase at init time, incl cconj
+*/
+
+void down_convert_and_rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_fdm[], 
+                                COMP rx_fdm_mem[], COMP phase_rx[], COMP freq[], 
+                                float freq_pol[], int nin)
+{
+    int i,k,m,c,st,N;
+    float windback_phase, mag;
+    COMP  windback_phase_rect;
+    COMP  rx_baseband[NFILTER+M];
+
+    /* update memory of rx_fdm */
+
+    for(i=0; i<NFILTER+M-nin; i++)
+        rx_fdm_mem[i] = rx_fdm_mem[i+nin];
+    for(i=NFILTER+M-nin, k=0; i<NFILTER+M; i++, k++)
+        rx_fdm_mem[i] = rx_fdm[k];
+
+    for(c=0; c<Nc+1; c++) {
+
+        /*
+          now downconvert using current freq offset to get Nfilter+nin
+          baseband samples.
+     
+                     Nfilter             nin
+          |--------------------------|---------|
+                                      | 
+                                  phase_rx(c)
+     
+          This means winding phase(c) back from this point to ensure
+          phase continuity.
+        */
+
+        windback_phase           = -freq_pol[c]*NFILTER;
+        windback_phase_rect.real = cos(windback_phase);
+        windback_phase_rect.imag = sin(windback_phase);
+        phase_rx[c]              = cmult(phase_rx[c],windback_phase_rect);
+    
+        /* down convert all samples in buffer */
+
+        st  = NFILTER+M-1;    /* end of buffer                  */
+        st -= nin-1;          /* first new sample               */
+        st -= NFILTER;        /* first sample used in filtering */
+        
+        for(i=st; i<NFILTER+M; i++) {
+            phase_rx[c]    = cmult(phase_rx[c], freq[c]);
+            rx_baseband[i] = cmult(rx_fdm_mem[i],cconj(phase_rx[c]));
+        }
+        /* now we can filter this carrier's P symbols */
+
+        N=M/P;
+        for(i=0, k=0; i<nin; i+=N, k++) {
+           rx_filt[c][k].real = 0.0; rx_filt[c][k].imag = 0.0;
+            
+            for(m=0; m<NFILTER; m++) 
+                rx_filt[c][k] = cadd(rx_filt[c][k], fcmult(gt_alpha5_root[m], rx_baseband[st+i+m]));
+        }
+
+        /* normalise digital oscilators as the magnitude can drift over time */
+
+        mag = cabsolute(phase_rx[c]);
+       phase_rx[c].real /= mag;          
+       phase_rx[c].imag /= mag;
+         
+       //printf("phase_rx[%d] = %f %f\n", c, phase_rx[c].real, phase_rx[c].imag);
+    }
+}
+
 /*---------------------------------------------------------------------------*\
                                                        
   FUNCTION....: rx_est_timing()             
@@ -1113,7 +1204,7 @@ void snr_update(float sig_est[], float noise_est[], int Nc, COMP phase_differenc
 
 // returns number of shorts in error_pattern[], one short per error
 
-int CODEC2_WIN32SUPPORT fdmdv_error_pattern_size(struct FDMDV *f) {
+int fdmdv_error_pattern_size(struct FDMDV *f) {
     return f->ntest_bits;
 }
 
@@ -1128,9 +1219,8 @@ int CODEC2_WIN32SUPPORT fdmdv_error_pattern_size(struct FDMDV *f) {
 
 \*---------------------------------------------------------------------------*/
 
-void CODEC2_WIN32SUPPORT fdmdv_put_test_bits(struct FDMDV *f, int *sync, short error_pattern[],
-                                            int *bit_errors, int *ntest_bits, 
-                                            int rx_bits[])
+void fdmdv_put_test_bits(struct FDMDV *f, int *sync, short error_pattern[],
+                        int *bit_errors, int *ntest_bits, int rx_bits[])
 {
     int   i,j;
     float ber;
@@ -1271,12 +1361,11 @@ int freq_state(int *reliable_sync_bit, int sync_bit, int *state, int *timer, int
 
 \*---------------------------------------------------------------------------*/
 
-void CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[], 
-                                    int *reliable_sync_bit, COMP rx_fdm[], int *nin)
+void fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[], 
+                int *reliable_sync_bit, COMP rx_fdm[], int *nin)
 {
     float         foff_coarse, foff_fine;
     COMP          rx_fdm_fcorr[M+M/P];
-    COMP          rx_baseband[NC+1][M+M/P];
     COMP          rx_filt[NC+1][P+1];
     COMP          rx_symbols[NC+1];
     float         env[NT*P];
@@ -1292,8 +1381,8 @@ void CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[],
        
     /* baseband processing */
 
-    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);
+    down_convert_and_rx_filter(rx_filt, fdmdv->Nc, rx_fdm, fdmdv->rx_fdm_mem, fdmdv->phase_rx, fdmdv->freq, 
+                               fdmdv->freq_pol, *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 */
@@ -1371,8 +1460,7 @@ float calc_snr(int Nc, float sig_est[], float noise_est[])
 
 \*---------------------------------------------------------------------------*/
 
-void CODEC2_WIN32SUPPORT fdmdv_get_demod_stats(struct FDMDV *fdmdv, 
-                                              struct FDMDV_STATS *fdmdv_stats)
+void fdmdv_get_demod_stats(struct FDMDV *fdmdv, struct FDMDV_STATS *fdmdv_stats)
 {
     int   c;
 
@@ -1412,7 +1500,7 @@ void CODEC2_WIN32SUPPORT fdmdv_get_demod_stats(struct FDMDV *fdmdv,
 
 \*---------------------------------------------------------------------------*/
 
-void CODEC2_WIN32SUPPORT fdmdv_8_to_48(float out48k[], float in8k[], int n)
+void fdmdv_8_to_48(float out48k[], float in8k[], int n)
 {
     int i,j,k,l;
 
@@ -1455,7 +1543,7 @@ void CODEC2_WIN32SUPPORT fdmdv_8_to_48(float out48k[], float in8k[], int n)
 
 \*---------------------------------------------------------------------------*/
 
-void CODEC2_WIN32SUPPORT fdmdv_48_to_8(float out8k[], float in48k[], int n)
+void fdmdv_48_to_8(float out8k[], float in48k[], int n)
 {
     int i,j;
 
@@ -1500,7 +1588,7 @@ void CODEC2_WIN32SUPPORT fdmdv_48_to_8(float out8k[], float in48k[], int n)
 
 \*---------------------------------------------------------------------------*/
 
-void CODEC2_WIN32SUPPORT fdmdv_get_rx_spectrum(struct FDMDV *f, float mag_spec_dB[], 
+void fdmdv_get_rx_spectrum(struct FDMDV *f, float mag_spec_dB[], 
                                               COMP rx_fdm[], int nin) 
 {
     int   i,j;
@@ -1544,7 +1632,7 @@ void CODEC2_WIN32SUPPORT fdmdv_get_rx_spectrum(struct FDMDV *f, float mag_spec_d
 
 \*---------------------------------------------------------------------------*/
 
-void CODEC2_WIN32SUPPORT fdmdv_dump_osc_mags(struct FDMDV *f) 
+void fdmdv_dump_osc_mags(struct FDMDV *f) 
 {
     int   i;
 
index 5957e3d4492984fc158b7a88f5fd13787b2f0f29..ca04f224cd4883c0ce1499020e26a9206d4cc2f4 100644 (file)
@@ -54,7 +54,6 @@
 
 #define NT                       5  /* number of symbols we estimate timing over                            */
 #define P                        4  /* oversample factor used for initial rx symbol filtering               */
-#define NFILTERTIMING (M+NFILTER+M) /* filter memory used for resampling after timing estimation            */
 
 #define NPILOT_LUT                 (4*M)    /* number of pilot look up table samples                 */
 #define NPILOTCOEFF                   30    /* number of FIR filter coeffs in LP filter              */
@@ -88,13 +87,14 @@ struct FDMDV {
 
     /* Modulator */
 
-    int  old_qpsk_mapping;
-    int  tx_pilot_bit;
-    COMP prev_tx_symbols[NC+1];
-    COMP tx_filter_memory[NC+1][NSYM];
-    COMP phase_tx[NC+1];
-    COMP freq[NC+1];
+    int   old_qpsk_mapping;
+    int   tx_pilot_bit;
+    COMP  prev_tx_symbols[NC+1];
+    COMP  tx_filter_memory[NC+1][NSYM];
+    COMP  phase_tx[NC+1];
+    COMP  freq[NC+1];
+    float freq_pol[NC+1];
+  
     /* Pilot generation at demodulator */
 
     COMP pilot_lut[NPILOT_LUT];
@@ -118,10 +118,9 @@ struct FDMDV {
     
     /* Demodulator */
 
+    COMP  rx_fdm_mem[NFILTER+M]; 
     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];
     float rx_timing;
     COMP  phase_difference[NC+1];
     COMP  prev_rx_symbols[NC+1];
@@ -142,7 +141,7 @@ struct FDMDV {
 
     float fft_buf[2*FDMDV_NSPEC];
     kiss_fft_cfg fft_cfg;             
- };
+};
 
 /*---------------------------------------------------------------------------*\
                                                                              
@@ -159,13 +158,14 @@ float rx_est_freq_offset(struct FDMDV *f, COMP rx_fdm[], int nin);
 void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], COMP pilot_lpf[], kiss_fft_cfg fft_pilot_cfg, COMP S[], int nin);
 void fdm_downconvert(COMP rx_baseband[NC+1][M+M/P], int Nc, COMP rx_fdm[], COMP phase_rx[], COMP freq[], int nin);
 void rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_baseband[NC+1][M+M/P], COMP rx_filter_memory[NC+1][NFILTER], int nin);
+void down_convert_and_rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_fdm[], 
+                                COMP rx_fdm_mem[], COMP phase_rx[], COMP freq[], 
+                                float freq_pol[], int nin);
 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);   
+                   COMP  rx_filt[NC+1][P+1], 
+                   COMP  rx_filter_mem_timing[NC+1][NT*P], 
+                   float env[],
+                   int   nin);  
 float qpsk_to_bits(int rx_bits[], int *sync_bit, int Nc, COMP phase_difference[], COMP prev_rx_symbols[], COMP rx_symbols[], int old_qpsk_mapping);
 void snr_update(float sig_est[], float noise_est[], int Nc, COMP phase_difference[]);
 int freq_state(int *reliable_sync_bit, int sync_bit, int *state, int *timer, int *sync_mem);