fdmdv demod modified to have complex freq input to support ext freq shifting
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 7 Nov 2012 02:21:07 +0000 (02:21 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 7 Nov 2012 02:21:07 +0000 (02:21 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@940 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/src/fdmdv.c
codec2-dev/src/fdmdv.h
codec2-dev/src/fdmdv_demod.c
codec2-dev/src/fdmdv_internal.h

index b3cae9d2e02695af06b464946020916ece7e3705..a884e2f1daf597eeef77ec3e0eeb2311907e7764 100644 (file)
@@ -647,7 +647,7 @@ void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[],
 
 \*---------------------------------------------------------------------------*/
 
-float rx_est_freq_offset(struct FDMDV *f, float rx_fdm[], int nin)
+float rx_est_freq_offset(struct FDMDV *f, COMP rx_fdm[], int nin)
 {
     int  i,j;
     COMP pilot[M+M/P];
@@ -685,8 +685,8 @@ float rx_est_freq_offset(struct FDMDV *f, float rx_fdm[], int nin)
     }
 
     for(i=0,j=NPILOTBASEBAND-nin; i<nin; i++,j++) {
-               f->pilot_baseband1[j] = fcmult(rx_fdm[i], cconj(pilot[i]));
-       f->pilot_baseband2[j] = fcmult(rx_fdm[i], cconj(prev_pilot[i]));
+               f->pilot_baseband1[j] = cmult(rx_fdm[i], cconj(pilot[i]));
+       f->pilot_baseband2[j] = cmult(rx_fdm[i], cconj(prev_pilot[i]));
     }
 
     lpf_peak_pick(&foff1, &max1, f->pilot_baseband1, f->pilot_lpf1, f->fft_pilot_cfg, f->S1, nin);
@@ -702,15 +702,17 @@ float rx_est_freq_offset(struct FDMDV *f, float rx_fdm[], int nin)
 
 /*---------------------------------------------------------------------------*\
                                                        
-  FUNCTION....: freq_shift()        
+  FUNCTION....: fdmdv_freq_shift()          
   AUTHOR......: David Rowe                           
   DATE CREATED: 26/4/2012
 
-  Frequency shift modem signal.
+  Frequency shift modem signal.  The use of complex input and output allows
+  single sided frequency shifting (no images).
 
 \*---------------------------------------------------------------------------*/
 
-void freq_shift(COMP rx_fdm_fcorr[], float rx_fdm[], float foff, COMP *foff_rect, COMP *foff_phase_rect, int nin)
+void CODEC2_WIN32SUPPORT fdmdv_freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, 
+                                          COMP *foff_rect, COMP *foff_phase_rect, int nin)
 {
     int   i;
 
@@ -718,7 +720,7 @@ void freq_shift(COMP rx_fdm_fcorr[], float rx_fdm[], float foff, COMP *foff_rect
     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);
+       rx_fdm_fcorr[i] = cmult(rx_fdm[i], *foff_phase_rect);
     }
 
     /* normalise digital oscilator as the magnitude can drfift over time */
@@ -1190,7 +1192,7 @@ int freq_state(int sync_bit, int *state)
   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,
+  modulated samples, returns an array of FDMDV_BITS_PER_FRAME bits,
   plus the sync bit.  
 
   The number of input samples nin will normally be M ==
@@ -1201,7 +1203,7 @@ int freq_state(int sync_bit, int *state)
 \*---------------------------------------------------------------------------*/
 
 void CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[], 
-                                    int *sync_bit, float rx_fdm[], int *nin)
+                                    int *sync_bit, COMP rx_fdm[], int *nin)
 {
     float         foff_coarse, foff_fine;
     COMP          rx_fdm_fcorr[M+M/P];
@@ -1216,7 +1218,7 @@ void CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[],
     
     if (fdmdv->coarse_fine == COARSE)
        fdmdv->foff = foff_coarse;
-    freq_shift(rx_fdm_fcorr, rx_fdm, fdmdv->foff, &fdmdv->foff_rect, &fdmdv->foff_phase_rect, *nin);
+    fdmdv_freq_shift(rx_fdm_fcorr, rx_fdm, fdmdv->foff, &fdmdv->foff_rect, &fdmdv->foff_phase_rect, *nin);
        
     /* baseband processing */
 
@@ -1224,19 +1226,15 @@ void CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[],
     rx_filter(rx_filt, rx_baseband, fdmdv->rx_filter_memory, *nin);
     fdmdv->rx_timing = rx_est_timing(rx_symbols, rx_filt, rx_baseband, fdmdv->rx_filter_mem_timing, env, fdmdv->rx_baseband_mem_timing, *nin);  
     
-    /* if we have qcquired pilot adjust number of input samples to
-       keep timing within bounds.  Avoid adjusting number of samples
-       before acquisition as it will jump about based on noise.*/
+    /* Adjust number of input samples to keep timing within bounds */
 
     *nin = M;
 
-    if (fdmdv->coarse_fine == FINE) {
-       if (fdmdv->rx_timing > 2*M/P)
-           *nin += M/P;
+    if (fdmdv->rx_timing > 2*M/P)
+       *nin += M/P;
     
-       if (fdmdv->rx_timing < 0)
-           *nin -= M/P;
-    }
+    if (fdmdv->rx_timing < 0)
+       *nin -= M/P;
     
     foff_fine = qpsk_to_bits(rx_bits, sync_bit, fdmdv->phase_difference, fdmdv->prev_rx_symbols, rx_symbols);
     memcpy(fdmdv->prev_rx_symbols, rx_symbols, sizeof(COMP)*(NC+1));
index 58fdecc86dd908671562e59228172b0ca37a5269..1f9dc6e592f5fca42b3f9cdebbf44bfcc9c319d8 100644 (file)
@@ -87,7 +87,7 @@ struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(void);
 void           CODEC2_WIN32SUPPORT fdmdv_destroy(struct FDMDV *fdmdv_state);
     
 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 *sync_bit, float rx_fdm[], int *nin);
+void           CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv_state, int rx_bits[], int *sync_bit, COMP rx_fdm[], int *nin);
     
 void           CODEC2_WIN32SUPPORT fdmdv_get_test_bits(struct FDMDV *fdmdv_state, int tx_bits[]);
 void           CODEC2_WIN32SUPPORT fdmdv_put_test_bits(struct FDMDV *f, int *sync, int *bit_errors, int *ntest_bits, int rx_bits[]);
@@ -98,6 +98,10 @@ void           CODEC2_WIN32SUPPORT fdmdv_get_rx_spectrum(struct FDMDV *fdmdv_sta
 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           CODEC2_WIN32SUPPORT fdmdv_freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, COMP *foff_rect, COMP *foff_phase_rect, int nin);
+
+/* debug/development function(s) */
+
 void CODEC2_WIN32SUPPORT fdmdv_dump_osc_mags(struct FDMDV *f);
  
 #ifdef __cplusplus
index 7929ca6894c9d126afca2d0e74699ef3856d06c2..96090d033dfce8da0b81bd2d60d6d044028e7474 100644 (file)
@@ -57,13 +57,12 @@ int main(int argc, char *argv[])
     char          packed_bits[BYTES_PER_CODEC_FRAME];
     int           rx_bits[FDMDV_BITS_PER_FRAME];
     int           codec_bits[2*FDMDV_BITS_PER_FRAME];
-    float         rx_fdm[FDMDV_MAX_SAMPLES_PER_FRAME];
+    COMP          rx_fdm[FDMDV_MAX_SAMPLES_PER_FRAME];
     short         rx_fdm_scaled[FDMDV_MAX_SAMPLES_PER_FRAME];
     int           i, bit, byte, c;
     int           nin, nin_prev;
     int           sync_bit;
     int           state, next_state;
-
     int           f;
     FILE         *foct = NULL;
     struct FDMDV_STATS stats;
@@ -115,8 +114,10 @@ int main(int argc, char *argv[])
 
     while(fread(rx_fdm_scaled, sizeof(short), nin, fin) == nin)
     {
-       for(i=0; i<nin; i++)
-           rx_fdm[i] = (float)rx_fdm_scaled[i]/FDMDV_SCALE;
+       for(i=0; i<nin; i++) {
+           rx_fdm[i].real = (float)rx_fdm_scaled[i]/FDMDV_SCALE;
+            rx_fdm[i].imag = 0;
+        }
        nin_prev = nin;
        fdmdv_demod(fdmdv, rx_bits, &sync_bit, rx_fdm, &nin);
 
index b51036e2bedd11ca8594d36aa4f292f773474eb3..34c9ab5bf73dd7dd4d1cc85559f8c0aa4145f9cd 100644 (file)
@@ -152,9 +152,9 @@ void tx_filter(COMP tx_baseband[NC+1][M], COMP tx_symbols[], COMP tx_filter_memo
 void fdm_upconvert(COMP tx_fdm[], COMP tx_baseband[NC+1][M], COMP phase_tx[], COMP freq_tx[]);
 void generate_pilot_fdm(COMP *pilot_fdm, int *bit, float *symbol, float *filter_mem, COMP *phase, COMP *freq);
 void generate_pilot_lut(COMP pilot_lut[], COMP *pilot_freq);
-float rx_est_freq_offset(struct FDMDV *f, float rx_fdm[], int nin);
+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 freq_shift(COMP rx_fdm_fcorr[], float rx_fdm[], float foff, COMP *foff_rect, COMP *foff_phase_rect, int nin);
+void freq_shift(COMP rx_fdm_fcorr[], COMP 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[],