ported rate Q rx filtering to C, tfdmdv tests out OK, demod seems to run much faster
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 1 Aug 2014 11:01:42 +0000 (11:01 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 1 Aug 2014 11:01:42 +0000 (11:01 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1776 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/fdmdv.m
codec2-dev/octave/fdmdv_demod.m
codec2-dev/octave/fdmdv_ut.m
codec2-dev/octave/tfdmdv.m
codec2-dev/src/fdmdv.c
codec2-dev/src/fdmdv_internal.h
codec2-dev/src/rxdec_coeff.h [new file with mode: 0644]
codec2-dev/stm32/Makefile
codec2-dev/unittest/tfdmdv.c

index 23febbca0d1e050c25e2d2f91a68c30eb687a309..486cf73357372eb08fe1f583358a409ef6454528 100644 (file)
@@ -254,6 +254,8 @@ function tx_fdm = fdm_upconvert(tx_filt)
     mag = abs(phase_tx(c));
     phase_tx(c) /= mag;
   end
+  mag = abs(fbb_phase_tx);
+  fbb_phase_tx /= mag;
 
 endfunction
 
@@ -344,6 +346,8 @@ end
 
 
 % Combined down convert and rx filter, more memory efficient but less intuitive design
+% TODO: Decimate mem update and downconversion, this will save some more CPU and memory
+%       note phase would have to advance 4 times as fast
 
 function rx_filt = down_convert_and_rx_filter(rx_fdm, nin, dec_rate)
   global Nc;
@@ -1047,16 +1051,16 @@ endfunction
 % Saves rx decimation filter coeffs to a text file in the form of a C array
 
 function rxdec_file(filename)
-  global rxdec;
+  global rxdec_coeff;
   global Nrxdec;
 
   f=fopen(filename,"wt");
   fprintf(f,"/* Generated by rxdec_file() Octave function */\n\n");
-  fprintf(f,"const float rxdec[]={\n");
-  for m=1:Nfilter-1
-    fprintf(f,"  %g,\n",rxdec(m));
+  fprintf(f,"const float rxdec_coeff[]={\n");
+  for m=1:Nrxdec-1
+    fprintf(f,"  %g,\n",rxdec_coeff(m));
   endfor
-  fprintf(f,"  %g\n};\n",rxdec(Nrxdecr));
+  fprintf(f,"  %g\n};\n",rxdec_coeff(Nrxdec));
   fclose(f);
 endfunction
 
index 704ac2317f897f3c255169348017ae4bd5d08009..65f0acaab0c52d2531e8590abe97e11d044a2bdf 100644 (file)
@@ -89,6 +89,15 @@ function fdmdv_demod(rawfilename, nbits, NumCarriers, errorpatternfilename, symb
     S=fft(spec_mem.*hanning(Nspec)',Nspec);
     SdB = 0.9*SdB + 0.1*20*log10(abs(S));
 
+    % shift down to complex baseband
+
+    for i=1:nin
+      fbb_phase_rx = fbb_phase_rx*fbb_rect';
+      rx_fdm(i) = rx_fdm(i)*fbb_phase_rx;
+    end
+    mag = abs(fbb_phase_rx);
+    fbb_phase_rx /= mag;
+
     % frequency offset estimation and correction
 
     [pilot prev_pilot pilot_lut_index prev_pilot_lut_index] = get_pilot(pilot_lut_index, prev_pilot_lut_index, nin);
index 0d7772e985235c0349b5d11892762e877dff4062..d46a42911b9b534d340a8f2715bedcff0b6a4220 100644 (file)
@@ -175,6 +175,8 @@ for f=1:frames
     fbb_phase_rx = fbb_phase_rx*fbb_rect';
     rx_fdm(i) = rx_fdm(i)*fbb_phase_rx;
   end
+  mag = abs(fbb_phase_rx);
+  fbb_phase_rx /= mag;
 
   % frequency offset estimation and correction, need to call rx_est_freq_offset even in sync
   % mode to keep states updated
@@ -195,10 +197,6 @@ for f=1:frames
   end
 
   rx_fdm_filter = rxdec_filter(rx_fdm, M);
-
-  % TODO: Decimate to rate Q at this point, this will save some more CPU
-  %       in down_convert_and_rx_filter
-
   rx_filt = down_convert_and_rx_filter(rx_fdm_filter, M, M/Q);
 
   [rx_symbols rx_timing] = rx_est_timing(rx_filt, M);
index 2ad4c2b41f732b8e1ca1164d6a4843d465605a7c..bba5a7ab6063f49e7cb0cb916f9bbf8ca6e1554e 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 16];
+no_plot_list = [];
 
 for f=1:frames
 
@@ -92,7 +92,16 @@ for f=1:frames
   channel = channel(nin+1:channel_count);
   channel_count -= nin;
 
-  % demodulator
+  % demodulator --------------------------------------------
+
+  % shift down to complex baseband
+
+  for i=1:nin
+    fbb_phase_rx = fbb_phase_rx*fbb_rect';
+    rx_fdm(i) = rx_fdm(i)*fbb_phase_rx;
+  end
+  mag = abs(fbb_phase_rx);
+  fbb_phase_rx /= mag;
 
   [pilot prev_pilot pilot_lut_index prev_pilot_lut_index] = get_pilot(pilot_lut_index, prev_pilot_lut_index, nin);
 
@@ -119,14 +128,8 @@ for f=1:frames
     rx_fdm_fcorr(i) = rx_fdm(i)*foff_phase_rect;
   end
 
-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_fdm_filter = rxdec_filter(rx_fdm_fcorr, nin);
+  rx_filt = down_convert_and_rx_filter(rx_fdm_filter, nin, M/Q);
 
   rx_filt_log = [rx_filt_log rx_filt];
 
index cd117d771424b3f284d7db9a65d8472924e271d5..d16b3184a9e8ed2fba6d1eba157e9b187817a040 100644 (file)
@@ -40,6 +40,7 @@
 #include "fdmdv_internal.h"
 #include "codec2_fdmdv.h"
 #include "rn.h"
+#include "rxdec_coeff.h"
 #include "test_bits.h"
 #include "pilot_coeff.h"
 #include "kiss_fft.h"
@@ -182,9 +183,17 @@ struct FDMDV * fdmdv_create(int Nc)
     }
     
     fdmdv_set_fsep(f, FSEP);
-    f->freq[Nc].real = cosf(2.0*PI*FDMDV_FCENTRE/FS);
-    f->freq[Nc].imag = sinf(2.0*PI*FDMDV_FCENTRE/FS);
-    f->freq_pol[Nc]  = 2.0*PI*FDMDV_FCENTRE/FS;
+    f->freq[Nc].real = cosf(2.0*PI*0.0/FS);
+    f->freq[Nc].imag = sinf(2.0*PI*0.0/FS);
+    f->freq_pol[Nc]  = 2.0*PI*0.0/FS;
+    
+    f->fbb_rect.real     = cosf(2.0*PI*FDMDV_FCENTRE/FS);
+    f->fbb_rect.imag     = sinf(2.0*PI*FDMDV_FCENTRE/FS);
+    f->fbb_pol           = 2.0*PI*FDMDV_FCENTRE/FS;
+    f->fbb_phase_tx.real = 1.0;
+    f->fbb_phase_tx.imag = 0.0;
+    f->fbb_phase_rx.real = 1.0;
+    f->fbb_phase_rx.imag = 0.0;
 
     /* Generate DBPSK pilot Look Up Table (LUT) */
 
@@ -202,6 +211,11 @@ struct FDMDV * fdmdv_create(int Nc)
     f->pilot_lut_index = 0;
     f->prev_pilot_lut_index = 3*M;
     
+    for(i=0; i<NRXDEC-1+M; i++) {
+        f->rxdec_lpf_mem[i].real = 0.0;
+        f->rxdec_lpf_mem[i].imag = 0.0;
+    }
+
     for(i=0; i<NPILOTLPF; i++) {
        f->pilot_lpf1[i].real = f->pilot_lpf2[i].real = 0.0;
        f->pilot_lpf1[i].imag = f->pilot_lpf2[i].imag = 0.0;
@@ -302,17 +316,18 @@ void fdmdv_set_fsep(struct FDMDV *f, float fsep) {
     float carrier_freq;
 
     f->fsep = fsep;
+
     /* Set up frequency of each carrier */
 
     for(c=0; c<f->Nc/2; c++) {
-       carrier_freq = (-f->Nc/2 + c)*f->fsep + FDMDV_FCENTRE;
+       carrier_freq = (-f->Nc/2 + c)*f->fsep;
        f->freq[c].real = cosf(2.0*PI*carrier_freq/FS);
        f->freq[c].imag = sinf(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;
+       carrier_freq = (-f->Nc/2 + c + 1)*f->fsep;
        f->freq[c].real = cosf(2.0*PI*carrier_freq/FS);
        f->freq[c].imag = sinf(2.0*PI*carrier_freq/FS);
        f->freq_pol[c]  = 2.0*PI*carrier_freq/FS;
@@ -448,7 +463,8 @@ void tx_filter(COMP tx_baseband[NC+1][M], int Nc, COMP tx_symbols[], COMP tx_fil
 
 \*---------------------------------------------------------------------------*/
 
-void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M], COMP phase_tx[], COMP freq[])
+void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M], COMP phase_tx[], COMP freq[],
+                   COMP *fbb_phase, COMP fbb_rect)
 {
     int   i,c;
     COMP  two = {2.0, 0.0};
@@ -485,6 +501,13 @@ void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M], COMP phase_
        tx_fdm[i] = cadd(tx_fdm[i], pilot);
     }
 
+    /* shift whole thing up to carrier freq */
+
+    for (i=0; i<M; i++) {
+       *fbb_phase = cmult(*fbb_phase, fbb_rect);
+       tx_fdm[i] = cmult(tx_fdm[i], *fbb_phase);
+    }
+
     /*
       Scale such that total Carrier power C of real(tx_fdm) = Nc.  This
       excludes the power of the pilot tone.
@@ -502,6 +525,10 @@ void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M], COMP phase_
        phase_tx[c].real /= mag;        
        phase_tx[c].imag /= mag;        
     }
+
+    mag = cabsolute(*fbb_phase);
+    fbb_phase->real /= mag;    
+    fbb_phase->imag /= mag;    
 }
 
 /*---------------------------------------------------------------------------*\
@@ -534,7 +561,7 @@ void fdmdv_mod(struct FDMDV *fdmdv, COMP tx_fdm[], int tx_bits[], int *sync_bit)
     TIMER_SAMPLE_AND_LOG(tx_filter_start, mod_start, "    bits_to_dqpsk_symbols"); 
     tx_filter(tx_baseband, fdmdv->Nc, tx_symbols, fdmdv->tx_filter_memory);
     TIMER_SAMPLE_AND_LOG(fdm_upconvert_start, tx_filter_start, "    tx_filter"); 
-    fdm_upconvert(tx_fdm, fdmdv->Nc, tx_baseband, fdmdv->phase_tx, fdmdv->freq);
+    fdm_upconvert(tx_fdm, fdmdv->Nc, tx_baseband, fdmdv->phase_tx, fdmdv->freq, &fdmdv->fbb_phase_tx, fdmdv->fbb_rect);
     TIMER_SAMPLE_AND_LOG2(fdm_upconvert_start, "    fdm_upconvert"); 
 
     *sync_bit = fdmdv->tx_pilot_bit;
@@ -892,6 +919,58 @@ 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....: rxdec_filter()      
+  AUTHOR......: David Rowe                           
+  DATE CREATED: 31 July 2014
+
+  +/- 1000Hz low pass filter, allows us to filter at rate Q to save CPU load.
+
+\*---------------------------------------------------------------------------*/
+
+void rxdec_filter(COMP rx_fdm_filter[], COMP rx_fdm[], COMP rxdec_lpf_mem[], int nin) {
+    int i,j,k; 
+
+    for(i=0; i<NRXDEC-1+M-nin; i++)
+        rxdec_lpf_mem[i] = rxdec_lpf_mem[i+nin];
+    for(i=0, j=NRXDEC-1+M-nin; i<nin; i++,j++)
+        rxdec_lpf_mem[j] = rx_fdm[i];
+
+    for(i=0; i<nin; i++) {
+        rx_fdm_filter[i].real = 0.0;
+        for(k=0; k<NRXDEC; k++)
+            rx_fdm_filter[i].real += rxdec_lpf_mem[i+k].real * rxdec_coeff[k];
+        rx_fdm_filter[i].imag = 0.0;
+        for(k=0; k<NRXDEC; k++)
+            rx_fdm_filter[i].imag += rxdec_lpf_mem[i+k].imag * rxdec_coeff[k];
+    }
+}
+
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: fir_filter()        
+  AUTHOR......: David Rowe                           
+  DATE CREATED: July 2014
+
+  Helper fir filter function.
+
+\*---------------------------------------------------------------------------*/
+
+static float fir_filter(float mem[], float coeff[], int dec_rate) {
+    float acc = 0.0;
+    int   m;
+
+    for(m=0; m<NFILTER; m+=dec_rate) { 
+        acc += coeff[m] * mem[2*m];
+    }
+
+    return dec_rate*acc;
+}
+
+
 /*---------------------------------------------------------------------------*\
                                                        
   FUNCTION....: down_convert_and_rx_filter()        
@@ -914,9 +993,9 @@ void rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_baseband[NC+1][M+M/P], C
 
 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 freq_pol[], int nin, int dec_rate)
 {
-    int i,k,m,c,st,N;
+    int i,k,c,st,N;
     float windback_phase, mag;
     COMP  windback_phase_rect;
     COMP  rx_baseband[NFILTER+M];
@@ -967,11 +1046,15 @@ void down_convert_and_rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_fdm[],
 
         N=M/P;
         for(i=0, k=0; i<nin; i+=N, k++) {
+           #ifdef ORIG 
            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]));
+           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]));
+           #else
+           rx_filt[c][k].real = fir_filter(&rx_baseband[st+i].real, (float*)gt_alpha5_root, dec_rate);
+           rx_filt[c][k].imag = fir_filter(&rx_baseband[st+i].imag, (float*)gt_alpha5_root, dec_rate);
+           #endif
         }
         TIMER_SAMPLE_AND_LOG2(filter_start, "        filter"); 
 
@@ -1381,6 +1464,7 @@ void fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[],
 {
     float         foff_coarse, foff_fine;
     COMP          rx_fdm_fcorr[M+M/P];
+    COMP          rx_fdm_filter[M+M/P];
     COMP          rx_filt[NC+1][P+1];
     COMP          rx_symbols[NC+1];
     float         env[NT*P];
@@ -1388,6 +1472,10 @@ void fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[],
     TIMER_VAR(demod_start, fdmdv_freq_shift_start, down_convert_and_rx_filter_start);
     TIMER_VAR(rx_est_timing_start, qpsk_to_bits_start, snr_update_start, freq_state_start);
 
+    /* shift down to complex baseband */
+
+    fdmdv_freq_shift(rx_fdm, rx_fdm, -FDMDV_FCENTRE, &fdmdv->fbb_phase_rx, *nin);
+
     /* freq offset estimation and correction */
    
     TIMER_SAMPLE(demod_start);
@@ -1401,8 +1489,9 @@ void fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[],
        
     /* baseband processing */
 
-    down_convert_and_rx_filter(rx_filt, fdmdv->Nc, rx_fdm_fcorr, fdmdv->rx_fdm_mem, fdmdv->phase_rx, fdmdv->freq, 
-                               fdmdv->freq_pol, *nin);
+    rxdec_filter(rx_fdm_filter, rx_fdm_fcorr, fdmdv->rxdec_lpf_mem, *nin);
+    down_convert_and_rx_filter(rx_filt, fdmdv->Nc, rx_fdm_filter, fdmdv->rx_fdm_mem, fdmdv->phase_rx, fdmdv->freq, 
+                               fdmdv->freq_pol, *nin, M/Q);
     TIMER_SAMPLE_AND_LOG(rx_est_timing_start, down_convert_and_rx_filter_start, "    down_convert_and_rx_filter"); 
     fdmdv->rx_timing = rx_est_timing(rx_symbols, fdmdv->Nc, rx_filt, fdmdv->rx_filter_mem_timing, env, *nin);   
     TIMER_SAMPLE_AND_LOG(qpsk_to_bits_start, rx_est_timing_start, "    rx_est_timing"); 
index d542e5e671b9bb0e81a62120cdd7c57ce2b4cc2d..b66ee9ef96a2f5679a5003aecae8c135570292b2 100644 (file)
@@ -53,7 +53,9 @@
 #define FSEP                    75  /* Default separation between carriers (Hz)                             */
 
 #define NT                       5  /* number of symbols we estimate timing over                            */
-#define P                        4  /* oversample factor used for initial rx symbol filtering               */
+#define P                        4  /* oversample factor used for initial rx symbol filtering output        */
+#define Q                     (M/4) /* oversample factor used for initial rx symbol filtering input         */
+#define NRXDEC                  31  /* number of taps in the rx decimation filter                           */
 
 #define NPILOT_LUT                 (4*M)    /* number of pilot look up table samples                 */
 #define NPILOTCOEFF                   30    /* number of FIR filter coeffs in LP filter              */
@@ -111,6 +113,13 @@ struct FDMDV {
     COMP S1[MPILOTFFT];
     COMP S2[MPILOTFFT];
 
+    /* baseband to low IF carrier states */
+
+    COMP  fbb_rect;
+    float fbb_pol;
+    COMP  fbb_phase_tx;
+    COMP  fbb_phase_rx;
+
     /* freq offset correction states */
 
     float foff;
@@ -118,6 +127,7 @@ struct FDMDV {
     
     /* Demodulator */
 
+    COMP  rxdec_lpf_mem[NRXDEC-1+M]; 
     COMP  rx_fdm_mem[NFILTER+M]; 
     COMP  phase_rx[NC+1];
     COMP  rx_filter_mem_timing[NC+1][NT*P];
@@ -155,16 +165,18 @@ struct FDMDV {
 
 void bits_to_dqpsk_symbols(COMP tx_symbols[], int Nc, COMP prev_tx_symbols[], int tx_bits[], int *pilot_bit, int old_qpsk_mapping);
 void tx_filter(COMP tx_baseband[NC+1][M], int Nc, COMP tx_symbols[], COMP tx_filter_memory[NC+1][NSYM]);
-void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M], COMP phase_tx[], COMP freq_tx[]);
+void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M], COMP phase_tx[], COMP freq_tx[],
+                   COMP *fbb_phase, COMP fbb_rect);
 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, 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 rxdec_filter(COMP rx_fdm_filter[], COMP rx_fdm[], COMP rxdec_lpf_mem[], 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 freq_pol[], int nin, int dec_rate);
 float rx_est_timing(COMP  rx_symbols[], int Nc, 
                    COMP  rx_filt[NC+1][P+1], 
                    COMP  rx_filter_mem_timing[NC+1][NT*P], 
diff --git a/codec2-dev/src/rxdec_coeff.h b/codec2-dev/src/rxdec_coeff.h
new file mode 100644 (file)
index 0000000..a08cf9f
--- /dev/null
@@ -0,0 +1,35 @@
+/* Generated by rxdec_file() Octave function */
+
+const float rxdec_coeff[]={
+  -0.00125472,
+  -0.00204605,
+  -0.0019897,
+  0.000163906,
+  0.00490937,
+  0.00986375,
+  0.0096718,
+  -0.000480351,
+  -0.019311,
+  -0.0361822,
+  -0.0341251,
+  0.000827866,
+  0.0690577,
+  0.152812,
+  0.222115,
+  0.249004,
+  0.222115,
+  0.152812,
+  0.0690577,
+  0.000827866,
+  -0.0341251,
+  -0.0361822,
+  -0.019311,
+  -0.000480351,
+  0.0096718,
+  0.00986375,
+  0.00490937,
+  0.000163906,
+  -0.0019897,
+  -0.00204605,
+  -0.00125472
+};
index fcaea9a179b8b2610101d67b43dd0d6fa2314933..89386cc54bae309d186b1e016a108111c29b9ae2 100644 (file)
@@ -13,7 +13,7 @@ SIZE=$(BINPATH)/arm-none-eabi-size
 
 ###################################################
 
-CFLAGS  = -std=gnu99 -O2 -g -Wall -Tstm32_flash.ld -DSTM32F4XX -DCORTEX_M4
+CFLAGS  = -std=gnu99 -O3 --param max-unroll-times=200 -g -Wall -Tstm32_flash.ld -DSTM32F4XX -DCORTEX_M4
 CFLAGS += -mlittle-endian -mthumb -mthumb-interwork -nostartfiles -mcpu=cortex-m4
 
 ifeq ($(FLOAT_TYPE), hard)
index af962fc61fbd165ec51a2d00903233c9c52464f7..438fb9579e3a7a134ebc9ee45c3aeb91ca47a1e0 100644 (file)
@@ -56,6 +56,7 @@ int main(int argc, char *argv[])
     float         foff_coarse;
     int           nin, next_nin;
     COMP          rx_fdm_fcorr[M+M/P];
+    COMP          rx_fdm_filter[M+M/P];
     COMP          rx_baseband[NC+1][M+M/P];
     COMP          rx_filt[NC+1][P+1];
     float         rx_timing;
@@ -115,7 +116,7 @@ int main(int argc, char *argv[])
        bits_to_dqpsk_symbols(tx_symbols, FDMDV_NC, fdmdv->prev_tx_symbols, tx_bits, &fdmdv->tx_pilot_bit, 0);
        memcpy(fdmdv->prev_tx_symbols, tx_symbols, sizeof(COMP)*(FDMDV_NC+1));
        tx_filter(tx_baseband, FDMDV_NC, tx_symbols, fdmdv->tx_filter_memory);
-       fdm_upconvert(tx_fdm, FDMDV_NC, tx_baseband, fdmdv->phase_tx, fdmdv->freq);
+       fdm_upconvert(tx_fdm, FDMDV_NC, tx_baseband, fdmdv->phase_tx, fdmdv->freq, &fdmdv->fbb_phase_tx, fdmdv->fbb_rect);
 
        /* --------------------------------------------------------*\
                                  Channel
@@ -149,6 +150,10 @@ int main(int argc, char *argv[])
                                Demodulator
        \*---------------------------------------------------------*/
 
+        /* shift down to complex baseband */
+
+        fdmdv_freq_shift(rx_fdm, rx_fdm, -FDMDV_FCENTRE, &fdmdv->fbb_phase_rx, nin);
+
        /* freq offset estimation and correction */
 
        foff_coarse = rx_est_freq_offset(fdmdv, rx_fdm, nin);
@@ -161,8 +166,9 @@ int main(int argc, char *argv[])
        
        /* baseband processing */
 
-        down_convert_and_rx_filter(rx_filt, fdmdv->Nc, rx_fdm_fcorr, fdmdv->rx_fdm_mem, fdmdv->phase_rx, fdmdv->freq, 
-                                   fdmdv->freq_pol, nin);
+        rxdec_filter(rx_fdm_filter, rx_fdm_fcorr, fdmdv->rxdec_lpf_mem, nin);
+        down_convert_and_rx_filter(rx_filt, fdmdv->Nc, rx_fdm_filter, fdmdv->rx_fdm_mem, fdmdv->phase_rx, fdmdv->freq, 
+                                   fdmdv->freq_pol, nin, M/Q);
        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);