during FreeDV 700D integration, I discovered FreeDV 1600 was losing sync when there...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 2 May 2018 21:23:18 +0000 (21:23 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 2 May 2018 21:23:18 +0000 (21:23 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@3556 01035d8c-6547-0410-b346-abe4f91aad63

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

index eb0c0dff1d8c4e755a42cb37c0e843bd818e9871..e70aded1ff1d14af1b73b97ec6b9b129955340a0 100644 (file)
@@ -37,7 +37,7 @@ Built as part of codec2-dev, see README for build instructions.
 
     $ cd ../octave
     $ octave
-    octave:1> fdmdv_demod_c("../src/demod_dump.txt",1400)
+    octave:1> fdmdv_demod_c("../src/demod_dump.txt",14000)
 
 4. Run Octave simulation of entire modem and AWGN channel:
 
index a398f12c7f98fd676fc0fad60decc50bc841475f..202904781199465c1e3167a06778bc09542137d7 100644 (file)
@@ -11,6 +11,7 @@
 %   [X] refactor with states
 %   [X] remove commented out globals
 %   [X] tfdmdv works
+%   [X] fdmdv_demod works
 %   [ ] fdmdv_ut works
  
 % reqd to make sure we get same random bits at mod and demod
@@ -50,7 +51,8 @@ function f = fdmdv_init(Nc=14)
 
     f.tx_filter_memory = zeros(Nc+1, Nfilter);
     f.rx_filter_memory = zeros(Nc+1, Nfilter);
-    f.rx_fdm_mem = zeros(1,Nfilter+M);
+    f.Nrx_fdm_mem = Nfilter+M+M/P;
+    f.rx_fdm_mem = zeros(1,f.Nrx_fdm_mem);
 
     f.snr_coeff = 0.9;        % SNR est averaging filter coeff
 
@@ -98,7 +100,10 @@ function f = fdmdv_init(Nc=14)
                       0.0096718   0.00986375    0.00490937 0.000163906 -0.0019897 -0.00204605  ...
                       -0.00125472];
 
-    f.rxdec_lpf_mem = zeros(1,f.Nrxdec-1+M);
+    % we need room for Nrdec + the max nin, as we may need to filter max_min samples
+    
+    f.Nrxdecmem = f.Nrxdec+M+M/P;
+    f.rxdec_lpf_mem = zeros(1,f.Nrxdecmem);
     f.Q=M/4;
 
     % freq offset estimation
@@ -330,6 +335,7 @@ function [rx_filt fdmdv] = rx_filter(fdmdv, rx_baseband, nin)
   % rx filter each symbol, generate P filtered output samples for each symbol.
   % Note we keep memory at rate M, it's just the filter output at rate P
 
+  assert(mod(M,P)==0);
   N=M/P;
   j=1;
   for i=1:N:nin
@@ -343,20 +349,32 @@ function [rx_filt fdmdv] = rx_filter(fdmdv, rx_baseband, nin)
 endfunction
 
 
-% LP filter +/- 1000 Hz, allows us to perfrom rx filtering at a lower rate saving CPU
+% LP filter +/- 1000 Hz, allows us to perform rx filtering at a lower rate saving CPU
 
 function [rx_fdm_filter fdmdv] = rxdec_filter(fdmdv, rx_fdm, nin)
   M = fdmdv.M;
+  Nrxdecmem = fdmdv.Nrxdecmem;
   Nrxdec = fdmdv.Nrxdec;
   rxdec_coeff = fdmdv.rxdec_coeff;
   rxdec_lpf_mem = fdmdv.rxdec_lpf_mem;
-  rxdec_lpf_mem(1:Nrxdec-1+M-nin) = rxdec_lpf_mem(nin+1:Nrxdec-1+M);
-  rxdec_lpf_mem(Nrxdec-1+M-nin+1:Nrxdec-1+M) = rx_fdm(1:nin);
 
+  % place latest nin samples at end of buffer
+  
+  rxdec_lpf_mem(1:Nrxdecmem-nin) = rxdec_lpf_mem(nin+1:Nrxdecmem);
+  rxdec_lpf_mem(Nrxdecmem-nin+1:Nrxdecmem) = rx_fdm(1:nin);
+  
+  % init room for nin output samples
+  
   rx_fdm_filter = zeros(1,nin);
+
+  % Move starting point for filter dot product to filter newest samples
+  % in buffer.  This stuff makes my head hurt.
+  
+  st = Nrxdecmem - nin - Nrxdec + 1;
   for i=1:nin
-    rx_fdm_filter(i) = rxdec_lpf_mem(i:Nrxdec-1+i) * rxdec_coeff';
+    a = st+1; b = st+i+Nrxdec-1;
+    %printf("nin: %d i: %d a: %d b: %d\n", nin, i, a, b);
+    rx_fdm_filter(i) = rxdec_lpf_mem(st+i:st+i+Nrxdec-1) * rxdec_coeff';
   end
 
   fdmdv.rxdec_lpf_mem = rxdec_lpf_mem;
@@ -372,6 +390,7 @@ function [rx_filt fdmdv] = down_convert_and_rx_filter(fdmdv, rx_fdm, nin, dec_ra
   M = fdmdv.M;
   P = fdmdv.P;
   rx_fdm_mem = fdmdv.rx_fdm_mem;
+  Nrx_fdm_mem = fdmdv.Nrx_fdm_mem;
   phase_rx = fdmdv.phase_rx;
   freq = fdmdv.freq;
   freq_pol = fdmdv.freq_pol;
@@ -379,42 +398,55 @@ function [rx_filt fdmdv] = down_convert_and_rx_filter(fdmdv, rx_fdm, nin, dec_ra
   gt_alpha5_root = fdmdv.gt_alpha5_root;
   Q = fdmdv.Q;
 
-  % update memory of rx_fdm
+  % update memory of rx_fdm_mem, newest nin sample ast end of buffer
 
-  rx_fdm_mem(1:Nfilter+M-nin) = rx_fdm_mem(nin+1:Nfilter+M);
-  rx_fdm_mem(Nfilter+M-nin+1:Nfilter+M) = rx_fdm(1:nin);
+  rx_fdm_mem(1:Nrx_fdm_mem-nin) = rx_fdm_mem(nin+1:Nrx_fdm_mem);
+  rx_fdm_mem(Nrx_fdm_mem-nin+1:Nrx_fdm_mem) = rx_fdm(1:nin);
 
   for c=1:Nc+1
 
-     % 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
-
-     wind_back_phase = -freq_pol(c)*Nfilter;
+     #{
+     So we have rx_fdm_mem, a baseband array of samples at
+     rate Fs Hz, including the last nin samples at the end.  To
+     filter each symbol we require the baseband samples for all Nsym
+     symbols that we filter over.  So we need to downconvert the
+     entire rx_fdm_mem array.  To downconvert these we need the LO
+     phase referenced to the start of the rx_fdm_mem array.
+
+      
+      <--------------- Nrx_filt_mem ------->
+                                     nin
+      |--------------------------|---------|
+       1                          |
+                              phase_rx(c)
+     
+      This means winding phase(c) back from this point
+      to ensure phase continuity.
+     #}
+
+     wind_back_phase = -freq_pol(c)*(Nfilter);
      phase_rx(c)     =  phase_rx(c)*exp(j*wind_back_phase);
     
      % down convert all samples in buffer
 
-     rx_baseband = zeros(1,Nfilter+M);
-     st  = Nfilter+M;      % end of buffer
+     rx_baseband = zeros(1,Nrx_fdm_mem);
+     
+     st  = Nrx_fdm_mem;    % end of buffer
      st -= nin-1;          % first new sample
      st -= Nfilter;        % first sample used in filtering
-     
+
+     %printf("Nfilter: %d Nrx_fdm_mem: %d dec_rate: %d nin: %d st: %d\n",
+     %        Nfilter, Nrx_fdm_mem, dec_rate, nin,  st);
+             
      f_rect = freq(c) .^ dec_rate;
 
-     for i=st:dec_rate:Nfilter+M
+     for i=st:dec_rate:Nrx_fdm_mem
         phase_rx(c) = phase_rx(c) * f_rect;
        rx_baseband(i) = rx_fdm_mem(i)*phase_rx(c)';
      end
  
-     % now we can filter this carrier's P symbols.  Due to filtering of rx_fdm we can filter at rate at rate M/Q
+     % now we can filter this carrier's P (+/-1) symbols.  Due to
+     % filtering of rx_fdm we can filter at rate at rate M/Q
 
      N=M/P; k = 1;
      for i=1:N:nin
@@ -576,6 +608,9 @@ function [rx_symbols rx_timing_M env fdmdv] = rx_est_timing(fdmdv, rx_filt, nin)
   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);
 
+  % This value will be +/- half a symbol so will wrap around at +/-
+  % M/2 or +/- 80 samples with M=160
+
   rx_timing_M = norm_rx_timing*M;
 
   fdmdv.rx_filter_mem_timing = rx_filter_mem_timing;
index 51d398a7c415a85ea3f4ab0527d627f2b44d6730..7f4e4cf6f56bf6bcb5f2b2c8f690055e2b03e227 100644 (file)
@@ -73,6 +73,8 @@ function fdmdv_demod(rawfilename, nbits, NumCarriers=14, errorpatternfilename, s
     dual_rx_bits = zeros(1,2*Nc*Nb);
   end
 
+  atimer = 0;
+  
   % Main loop ----------------------------------------------------
 
   for fr=1:frames
@@ -108,7 +110,7 @@ function fdmdv_demod(rawfilename, nbits, NumCarriers=14, errorpatternfilename, s
     [foff_coarse S1 S2 f] = rx_est_freq_offset(f, rx_fdm, pilot, prev_pilot, nin, !sync );
     
     if sync == 0
-      foff  = foff_coarse;
+      foff = foff_coarse;
     end
     foff_coarse_log = [foff_coarse_log foff_coarse];
 
@@ -121,19 +123,30 @@ function fdmdv_demod(rawfilename, nbits, NumCarriers=14, errorpatternfilename, s
 
     % baseband processing
 
-    [rx_fdm_filter f] = rxdec_filter(f, rx_fdm_fcorr, nin);
-    [rx_filt f] = down_convert_and_rx_filter(f, rx_fdm_filter, nin, M/Q);
+    if 0
+      % easier to understand, but more memory and CPU hungry filtering and down conversion
+
+      [rx_baseband f] = fdm_downconvert(f, rx_fdm_fcorr, nin);
+      [rx_filt f] = rx_filter(f, rx_baseband, nin);
+    else
+      % more efficient filtering and down conversion
+    
+      [rx_fdm_filter f] = rxdec_filter(f, rx_fdm_fcorr, nin);
+      [rx_filt f] = down_convert_and_rx_filter(f, rx_fdm_filter, nin, M/Q);
+    end
+
     [rx_symbols rx_timing env f] = rx_est_timing(f, rx_filt, nin);
     rx_timing_log = [rx_timing_log rx_timing];
 
-    nin = M;
-    if rx_timing > 2*M/P
-       nin += M/P;
+    nin = M;    
+    if rx_timing > M/P
+      nin += M/P;
     end
-    if rx_timing < 0;
-       nin -= M/P;
+    if rx_timing < -M/P;
+      nin -= M/P;
     end
-
+    %printf("fr: %d rx_timing: %d nin = %d\n", fr, rx_timing, nin);
+    
     rx_symbols_log = [rx_symbols_log rx_symbols.*conj(prev_rx_symbols./abs(prev_rx_symbols))*exp(j*pi/4)];
     [rx_bits sync_bit f_err pd] = psk_to_bits(f, prev_rx_symbols, rx_symbols, modulation);
 
@@ -183,6 +196,9 @@ function fdmdv_demod(rawfilename, nbits, NumCarriers=14, errorpatternfilename, s
 
     [test_frame_sync bit_errors error_pattern f] = put_test_bits(f, test_bits, rx_bits);
     if (test_frame_sync == 1)
+      if (bit_errors)
+        printf("fr: %d bit_errors: %d\n", fr, bit_errors);
+      end
       total_bit_errors = total_bit_errors + bit_errors;
       total_bits = total_bits + f.Ntest_bits;
       bit_errors_log = [bit_errors_log bit_errors/f.Ntest_bits];
@@ -244,32 +260,28 @@ function fdmdv_demod(rawfilename, nbits, NumCarriers=14, errorpatternfilename, s
   xt = (1:frames)/Rs;
   secs = frames/Rs;
 
-  figure(1)
-  clf;
+  figure(1); clf;
   [n m] = size(rx_symbols_log);
   plot(real(rx_symbols_log(1:Nc+1,15:m)),imag(rx_symbols_log(1:Nc+1,15:m)),'+')
   axis([-2 2 -2 2]);
   title('Scatter Diagram');
 
-  figure(2)
-  clf;
-  subplot(211)
+  figure(2); clf;
   plot(xt, rx_timing_log)
   title('timing offset (samples)');
-  subplot(212)
+  
+  figure(3);
   plot(xt, foff_log, '-;freq offset;')
-  hold on;
-  plot(xt, sync_log*75, 'r;course-fine;');
-  hold off;
+  %hold on;
+  %plot(xt, sync_log*75, 'r;course-fine;');
+  %hold off;
   title('Freq offset (Hz)');
-  grid
+  grid;
 
-  figure(3)
-  clf;
+  figure(4); clf;
   plot_specgram(rx_fdm_log, Fs);
 
-  figure(4)
-  clf;
+  figure(5); clf;
   subplot(311)
   stem(xt, sync_log)
   axis([0 secs 0 1.5]);
@@ -282,8 +294,7 @@ function fdmdv_demod(rawfilename, nbits, NumCarriers=14, errorpatternfilename, s
   axis([0 secs 0 1.5]);
   title('Test Frame Sync')
 
-  figure(5)
-  clf;
+  figure(6); clf;
   subplot(211);
   plot(xt, snr_est_log);
   title('SNR Estimates')
@@ -292,8 +303,7 @@ function fdmdv_demod(rawfilename, nbits, NumCarriers=14, errorpatternfilename, s
   bar(snrdB_pc(1:Nc) - mean(snrdB_pc(1:Nc)))
   axis([0 Nc+1 -3 3]);
 
-  figure(6)
-  clf;
+  figure(7); clf;
   hold on;
   lep = length(error_pattern_log);
   if lep != 0 
@@ -305,8 +315,7 @@ function fdmdv_demod(rawfilename, nbits, NumCarriers=14, errorpatternfilename, s
     axis([1 lep/(Nc*Nb) 0 Nc])
   end
 
-  figure(7)
-  clf;
+  figure(8); clf;
   subplot(211)
   [a b] = size(rx_fdm_log);
   xt1 = (1:b)/Fs;
index ee075016d8534e6b9e0e3716c54de7c293c9605a..a81a6bc9fce3d8c55365fcea379705f048234685 100644 (file)
@@ -169,7 +169,7 @@ struct FDMDV * fdmdv_create(int Nc)
     f->pilot_lut_index = 0;
     f->prev_pilot_lut_index = 3*M_FAC;
 
-    for(i=0; i<NRXDEC-1+M_FAC; i++) {
+    for(i=0; i<NRXDECMEM; i++) {
         f->rxdec_lpf_mem[i].real = 0.0;
         f->rxdec_lpf_mem[i].imag = 0.0;
     }
@@ -183,7 +183,7 @@ struct FDMDV * fdmdv_create(int Nc)
     f->foff_phase_rect.real = 1.0;
     f->foff_phase_rect.imag = 0.0;
 
-    for(i=0; i<NFILTER+M_FAC; i++) {
+    for(i=0; i<NRX_FDM_MEM; i++) {
         f->rx_fdm_mem[i].real = 0.0;
         f->rx_fdm_mem[i].imag = 0.0;
     }
@@ -1006,20 +1006,21 @@ void rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_baseband[NC+1][M_FAC+M_F
 \*---------------------------------------------------------------------------*/
 
 void rxdec_filter(COMP rx_fdm_filter[], COMP rx_fdm[], COMP rxdec_lpf_mem[], int nin) {
-    int i,j,k;
+    int i,j,k,st;
 
-    for(i=0; i<NRXDEC-1+M_FAC-nin; i++)
+    for(i=0; i<NRXDECMEM-nin; i++)
         rxdec_lpf_mem[i] = rxdec_lpf_mem[i+nin];
-    for(i=0, j=NRXDEC-1+M_FAC-nin; i<nin; i++,j++)
+    for(i=0, j=NRXDECMEM-nin; i<nin; i++,j++)
         rxdec_lpf_mem[j] = rx_fdm[i];
 
+    st = NRXDECMEM - nin - NRXDEC + 1;
     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].real += rxdec_lpf_mem[st+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];
+            rx_fdm_filter[i].imag += rxdec_lpf_mem[st+i+k].imag * rxdec_coeff[k];
     }
 }
 
@@ -1144,7 +1145,7 @@ void down_convert_and_rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_fdm[],
     int i,k,c,st,Nval;
     float windback_phase, mag;
     COMP  windback_phase_rect;
-    COMP  rx_baseband[NFILTER+M_FAC];
+    COMP  rx_baseband[NRX_FDM_MEM];
     COMP  f_rect;
 
     //PROFILE_VAR(windback_start,  downconvert_start, filter_start);
@@ -1152,29 +1153,37 @@ void down_convert_and_rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_fdm[],
     /* update memory of rx_fdm */
 
 #if 0
-    for(i=0; i<NFILTER+M_FAC-nin; i++)
+    for(i=0; i<NRX_FDM_MEM-nin; i++)
         rx_fdm_mem[i] = rx_fdm_mem[i+nin];
     for(i=NFILTER+M_FAC-nin, k=0; i<NFILTER+M_FAC; i++, k++)
         rx_fdm_mem[i] = rx_fdm[k];
 #else
     // this gives only 40uS gain on STM32 but now that we have, we keep it
-    memmove(&rx_fdm_mem[0],&rx_fdm_mem[nin],(NFILTER+M_FAC-nin)*sizeof(COMP));
-    memcpy(&rx_fdm_mem[NFILTER+M_FAC-nin],&rx_fdm[0],nin*sizeof(COMP));
+    memmove(&rx_fdm_mem[0],&rx_fdm_mem[nin],(NRX_FDM_MEM-nin)*sizeof(COMP));
+    memcpy(&rx_fdm_mem[NRX_FDM_MEM-nin],&rx_fdm[0],nin*sizeof(COMP));
 #endif
     for(c=0; c<Nc+1; c++) {
 
-        /*
-          now downconvert using current freq offset to get Nfilter+nin
-          baseband samples.
+      /*
+
+        So we have rx_fdm_mem, a baseband array of samples at
+        rate Fs Hz, including the last nin samples at the end.  To
+        filter each symbol we require the baseband samples for all Nsym
+        symbols that we filter over.  So we need to downconvert the
+        entire rx_fdm_mem array.  To downconvert these we need the LO
+        phase referenced to the start of the rx_fdm_mem array.
 
-                     Nfilter             nin
-          |--------------------------|---------|
-                                      |
-                                  phase_rx(c)
+      
+        <--------------- Nrx_filt_mem ------->
+        nin
+        |--------------------------|---------|
+        1                          |
+        phase_rx(c)
+     
+        This means winding phase(c) back from this point
+        to ensure phase continuity.
 
-          This means winding phase(c) back from this point to ensure
-          phase continuity.
-         */
+      */
 
         //PROFILE_SAMPLE(windback_start);
         windback_phase           = -freq_pol[c]*NFILTER;
@@ -1185,7 +1194,7 @@ void down_convert_and_rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_fdm[],
 
         /* down convert all samples in buffer */
 
-        st  = NFILTER+M_FAC-1;    /* end of buffer                  */
+        st  = NRX_FDM_MEM-1;  /* end of buffer                  */
         st -= nin-1;          /* first new sample               */
         st -= NFILTER;        /* first sample used in filtering */
 
@@ -1195,7 +1204,7 @@ void down_convert_and_rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_fdm[],
         for(i=0; i<dec_rate-1; i++)
             f_rect = cmult(f_rect,freq[c]);
 
-        for(i=st; i<NFILTER+M_FAC; i+=dec_rate) {
+        for(i=st; i<NRX_FDM_MEM; i+=dec_rate) {
             phase_rx[c]    = cmult(phase_rx[c], f_rect);
             rx_baseband[i] = cmult(rx_fdm_mem[i],cconj(phase_rx[c]));
         }
@@ -1324,6 +1333,9 @@ float rx_est_timing(COMP rx_symbols[],
         //rx_symbols[c] = rx_filter_mem_timing[c][high_sample];
     }
 
+    /* This value will be +/- half a symbol so will wrap around at +/-
+       M/2 or +/- 80 samples with M=160 */
+    
     return norm_rx_timing*m;
 }
 
@@ -1658,10 +1670,10 @@ void fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[],
 
     *nin = M_FAC;
 
-    if (fdmdv->rx_timing > 2*M_FAC/P)
+    if (fdmdv->rx_timing > M_FAC/P)
        *nin += M_FAC/P;
 
-    if (fdmdv->rx_timing < 0)
+    if (fdmdv->rx_timing < -M_FAC/P)
        *nin -= M_FAC/P;
 
     foff_fine = qpsk_to_bits(rx_bits, &sync_bit, fdmdv->Nc, fdmdv->phase_difference, fdmdv->prev_rx_symbols, rx_symbols,
index 3f830bad0f6c8feb2f786e64b1ffe5f18ddd24d9..12123296b34bcf1e98e2d9309a9b0fb769d6d150 100644 (file)
@@ -67,6 +67,9 @@
 
 #define NSYNC_MEM                6
 
+#define NRX_FDM_MEM (NFILTER+M_FAC+M_FAC/P)           /* size of rx filter memory            */
+#define NRXDECMEM   (NRXDEC+M_FAC+M_FAC/P)            /* size of rx decimation filter memory */
+
 /* averaging filter coeffs */
 
 #define TRACK_COEFF              0.5
@@ -130,8 +133,8 @@ struct FDMDV {
 
     /* Demodulator */
 
-    COMP  rxdec_lpf_mem[NRXDEC-1+M_FAC];
-    COMP  rx_fdm_mem[NFILTER+M_FAC];
+    COMP  rxdec_lpf_mem[NRXDECMEM];
+    COMP  rx_fdm_mem[NRX_FDM_MEM];
     COMP  phase_rx[NC+1];
     COMP  rx_filter_mem_timing[NC+1][NT*P];
     float rx_timing;
index 785e8e33c75ed0b34ed6bdf59b4ffab018a2fd05..2c73dfa2d27ad8507e58a873c620d95e8686eb8b 100644 (file)
@@ -9,8 +9,8 @@
 
   Example usage (all one line):
 
-     codec2-dev/build_linux/src$ ./freedv_tx 1600 ../../raw/ve9qrp_10s.raw - |
-                                 ./freedv_rx 1600 - - | play -t raw -r 8000 -s -2 -
+    $ cd codec2-dev/build_linux/src
+    $ ./freedv_tx 1600 ../../raw/ve9qrp_10s.raw - | ./freedv_rx 1600 - - | aplay -f S16
 
 \*---------------------------------------------------------------------------*/
 
index 0cfe886254f6dc489cf4a17c3eabdf7775b59045..ba64bbaae19c8b1215a0555f4fec7470d9f827fd 100644 (file)
@@ -163,8 +163,7 @@ int main(int argc, char *argv[])
 
        /* baseband processing */
 
-        rxdec_filter(rx_fdm_filter, rx_fdm_fcorr, fdmdv->rxdec_lpf_mem, 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_FAC/Q);
        rx_timing = rx_est_timing(rx_symbols, FDMDV_NC, rx_filt, fdmdv->rx_filter_mem_timing, env, nin, M_FAC);