refactoring fdmdv.m to get tfdmdv.m working again. tfdmdv tests now passing, about...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 27 Aug 2016 06:12:02 +0000 (06:12 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 27 Aug 2016 06:12:02 +0000 (06:12 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@2845 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/CMakeLists.txt
codec2-dev/octave/fdmdv.m
codec2-dev/octave/tfdmdv.m
codec2-dev/unittest/tfdmdv.c

index 0c816518d9daf2896fcf328303aa6ebddea86951..41d2b00106e1c33ed3829f37147059b211afb87a 100644 (file)
@@ -48,7 +48,7 @@ message(STATUS "codec2 version: ${CODEC2_VERSION}")
 
 # Set default build type
 if(NOT CMAKE_BUILD_TYPE)
-    set(CMAKE_BUILD_TYPE "Release")
+    set(CMAKE_BUILD_TYPE "Debug")
 endif()
 
 # Set default C++ flags.
index 7cfbf9f9fda734643903340389e643f166972ce7..a3fcbbdd0eecebb5f5f4e3bb892ddfc2998b4daa 100644 (file)
@@ -191,7 +191,15 @@ function f = fdmdv_init
     % decimation filter
 
     f.Nrxdec = 31;
-    f.rxdec_coeff = fir1(f.Nrxdec-1, 0.25);
+    % fir1() output appears to have changed from when coeffs used in C port were used
+    %f.rxdec_coeff = fir1(f.Nrxdec-1, 0.25);
+    f.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];
+
     f.rxdec_lpf_mem = zeros(1,f.Nrxdec-1+M);
     f.Q=M/4;
 
@@ -199,7 +207,16 @@ function f = fdmdv_init
 
     f.Mpilotfft      = 256;
     f.Npilotcoeff    = 30;                              
-    f.pilot_coeff    = fir1(f.Npilotcoeff-1, 200/(Fs/2))'; % 200Hz LPF
+
+    % here's how to make this filter from scratch, however it appeared to change over different
+    % octave versions so have hard coded to version used for C port
+    %f.pilot_coeff    = fir1(f.Npilotcoeff-1, 200/(Fs/2))'; % 200Hz LPF
+    f.pilot_coeff    = [0.00223001 0.00301037 0.00471258 0.0075934 0.0118145 0.0174153 ...
+                       0.0242969  0.0322204  0.0408199 0.0496286  0.0581172 0.0657392 ...
+                       0.0719806  0.0764066  0.0787022 0.0787022  0.0764066 0.0719806 ...
+                       0.0657392  0.0581172  0.0496286 0.0408199  0.0322204 0.0242969 ...
+                       0.0174153  0.0118145  0.0075934 0.00471258 0.00301037 0.00223001];
+
     f.Npilotbaseband = f.Npilotcoeff + M + M/P;            % number of pilot baseband samples 
     f.Npilotlpf      = 4*M;                                % reqd for pilot LPF
                                                            % number of symbols we DFT pilot over
@@ -529,7 +546,7 @@ function [foff imax pilot_lpf_out S] = lpf_peak_pick(f, pilot_baseband, pilot_lp
   pilot_lpf(1:Npilotlpf-nin) = pilot_lpf(nin+1:Npilotlpf);
   k = Npilotbaseband-nin+1;;
   for i = Npilotlpf-nin+1:Npilotlpf
-    pilot_lpf(i) = pilot_baseband(k-Npilotcoeff+1:k) * pilot_coeff;
+    pilot_lpf(i) = pilot_baseband(k-Npilotcoeff+1:k) * pilot_coeff';
     k++;
   end
   
@@ -566,7 +583,7 @@ endfunction
 % Estimate frequency offset of FDM signal using BPSK pilot.  This is quite
 % sensitive to pilot tone level wrt other carriers
 
-function [foff S1 S2] = rx_est_freq_offset(f, rx_fdm, pilot, pilot_prev, nin, do_fft)
+function [foff S1 S2 f] = rx_est_freq_offset(f, rx_fdm, pilot, pilot_prev, nin, do_fft)
   M = f.M;
   Npilotbaseband = f.Npilotbaseband;
   pilot_baseband1 = f.pilot_baseband1;
@@ -725,6 +742,7 @@ endfunction
 function [rx_bits sync_bit f_err phase_difference] = psk_to_bits(f, prev_rx_symbols, rx_symbols, modulation)
   Nc = f.Nc;
   Nb = f.Nb;
+
   m4_binary_to_gray = [
     bin2dec("00") 
     bin2dec("01")
@@ -902,7 +920,7 @@ endfunction
 % returns nbits from a repeating sequence of random data
 
 function [bits f] = get_test_bits(f, nbits)
+
   for i=1:nbits
     bits(i) = f.test_bits(f.current_test_bit++);
     
index 2dc941a45973f1525475d8c420332941675e7dc8..c338fcacc84d8922368eddbb3e2e399ea08fee47 100644 (file)
@@ -3,6 +3,24 @@
 % Octave script that tests the C port of the FDMDV modem.  This script loads
 % the output of unittest/tfdmdv.c and compares it to the output of the
 % reference versions of the same functions written in Octave.
+%
+% Usage:
+%
+%   1/ In codec2-dev/CMakeLists.txt, ensure set(CMAKE_BUILD_TYPE "Debug"), to
+%      enable building the C unittests.  Build codec2-dev as per 
+%      codec2-dev/README.
+%
+%   2/ Run the C side from the Octave directory:
+%
+%        codec2-dev/octave$ ../build_linux/unittest/tfdmdv
+%        codec2-dev/octave$ ls -l tfdmdv_out.txt
+%         -rw-rw-r-- 1 david david 3419209 Aug 27 10:05 tfdmdv_out.txt
+%
+%   3/ Run the Octave side (this script):
+%
+%        octave:1> tfdmdv
+%
+
 %
 % Copyright David Rowe 2012
 % This program is distributed under the terms of the GNU General Public License 
@@ -28,7 +46,7 @@ Q  = f.Q;
 
 % Generate reference vectors using Octave implementation of FDMDV modem
 
-passes = fails = 0;
+global passes = fails = 0;
 frames = 35;
 prev_tx_symbols = ones(Nc+1,1); prev_tx_symbols(Nc+1) = 2;
 prev_rx_symbols = ones(Nc+1,1);
@@ -59,7 +77,7 @@ S2_log = [];
 foff_coarse_log = [];
 foff_fine_log = [];
 foff_log = [];
-rx_baseband_log = [];
+rx_fdm_filter_log = [];
 rx_filt_log = [];
 env_log = [];
 rx_timing_log = [];
@@ -74,7 +92,7 @@ noise_est_log = [];
 
 % adjust this if the screen is getting a bit cluttered
 
-no_plot_list = [1 2 3 4 5 6 7 8 11 12 13 14 15 16];
+global no_plot_list = [1 2 3 4 5 6 7 8 12 13 14 15 16];
 
 for fr=1:frames
 
@@ -85,16 +103,16 @@ for fr=1:frames
   [tx_symbols f] = bits_to_psk(f, prev_tx_symbols, tx_bits, 'dqpsk');
   prev_tx_symbols = tx_symbols;
   tx_symbols_log = [tx_symbols_log tx_symbols];
-  [tx_baseband ] = tx_filter(f, tx_symbols);
+  [tx_baseband f] = tx_filter(f, tx_symbols);
   tx_baseband_log = [tx_baseband_log tx_baseband];
-  tx_fdm = fdm_upconvert(f, tx_baseband);
+  [tx_fdm f] = fdm_upconvert(f, tx_baseband);
   tx_fdm_log = [tx_fdm_log tx_fdm];
 
   % channel
 
   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;
@@ -113,10 +131,10 @@ for fr=1:frames
   mag = abs(f.fbb_phase_rx);
   f.fbb_phase_rx /= mag;
 
-  [pilot prev_pilot f.pilot_lut_index f.prev_pilot_lut_index] = get_pilot(f, f.pilot_lut_index, f.prev_pilot_lut_index, nin);
-  [foff_coarse S1 S2] = rx_est_freq_offset(f, rx_fdm, pilot, prev_pilot, nin, !sync);
+  % sync = 0; % when debugging good idea to uncomment this to "open loop"
 
-  %sync = 0; % when debugging good idea to uncomment this to "open loop"
+  [pilot prev_pilot f.pilot_lut_index f.prev_pilot_lut_index] = get_pilot(f, f.pilot_lut_index, f.prev_pilot_lut_index, nin);
+  [foff_coarse S1 S2 f] = rx_est_freq_offset(f, rx_fdm, pilot, prev_pilot, nin, !sync);
 
   if sync == 0
     foff = foff_coarse;
@@ -139,8 +157,18 @@ for fr=1:frames
 
   [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);
-
+  #{
+  for i=1:5
+    printf("[%d] rx_fdm_fcorr: %f %f rx_fdm_filter: %f %f\n", i,
+           real(rx_fdm_fcorr(i)), imag(rx_fdm_fcorr(i)), real(rx_fdm_filter(i)), imag(rx_fdm_filter(i)));
+  end
+  for i=1:5
+    printf("[%d] rx_fdm_fcorr: %f %f rxdec_lpf_mem: %f %f\n", i,
+           real(rx_fdm_fcorr(i)), imag(rx_fdm_fcorr(i)), real(f.rxdec_lpf_mem(i)), imag(f.rxdec_lpf_mem(i)));
+  end
+  #}
   rx_filt_log = [rx_filt_log rx_filt];
+  rx_fdm_filter_log = [rx_fdm_filter_log rx_fdm_filter];
 
   [rx_symbols rx_timing env f] = rx_est_timing(f, rx_filt, nin);
   env_log = [env_log env];
@@ -179,7 +207,7 @@ end
 
 % Compare to the output from the C version
 
-load ../build_src/unittest/tfdmdv_out.txt
+load tfdmdv_out.txt
 
 
 % ---------------------------------------------------------------------------------------
@@ -199,16 +227,16 @@ plot_sig_and_error(3, 212, imag(tx_fdm_log_c), imag(tx_fdm_log - tx_fdm_log_c),
 
 % generate_pilot_lut()
 
-plot_sig_and_error(4, 211, real(pilot_lut_c), real(pilot_lut - pilot_lut_c), 'pilot lut real')
-plot_sig_and_error(4, 212, imag(pilot_lut_c), imag(pilot_lut - pilot_lut_c), 'pilot lut imag')
+plot_sig_and_error(4, 211, real(pilot_lut_c), real(f.pilot_lut - pilot_lut_c), 'pilot lut real')
+plot_sig_and_error(4, 212, imag(pilot_lut_c), imag(f.pilot_lut - pilot_lut_c), 'pilot lut imag')
 
 % rx_est_freq_offset()
 
-st=1;  en = 5*Npilotbaseband;
+st=1;  en = 5*f.Npilotbaseband;
 plot_sig_and_error(5, 211, real(pilot_baseband1_log(st:en)), real(pilot_baseband1_log(st:en) - pilot_baseband1_log_c(st:en)), 'pilot baseband1 real' )
 plot_sig_and_error(5, 212, real(pilot_baseband2_log(st:en)), real(pilot_baseband2_log(st:en) - pilot_baseband2_log_c(st:en)), 'pilot baseband2 real' )
 
-st=1;  en = 5*Npilotlpf;
+st=1;  en = 5*f.Npilotlpf;
 plot_sig_and_error(6, 211, real(pilot_lpf1_log(st:en)), real(pilot_lpf1_log(st:en) - pilot_lpf1_log_c(st:en)), 'pilot lpf1 real' )
 plot_sig_and_error(6, 212, real(pilot_lpf2_log(st:en)), real(pilot_lpf2_log(st:en) - pilot_lpf2_log_c(st:en)), 'pilot lpf2 real' )
 
@@ -224,12 +252,10 @@ plot_sig_and_error(9, 212, foff_fine_log, foff_fine_log - foff_fine_log_c, 'Fine
 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(11, 211, real(rx_fdm_filter_log), real(rx_fdm_filter_log - rx_fdm_filter_log_c), 'Rx dec filter real' )
+plot_sig_and_error(11, 212, imag(rx_fdm_filter_log), imag(rx_fdm_filter_log - rx_fdm_filter_log_c), 'Rx dec filter imag' )
 
+c=1;
 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' )
 
@@ -245,20 +271,20 @@ c = 12;
 plot_sig_and_error(16, 211, sig_est_log(c,:), sig_est_log(c,:) - sig_est_log_c(c,:), 'sig est for SNR' )
 plot_sig_and_error(16, 212, noise_est_log(c,:), noise_est_log(c,:) - noise_est_log_c(c,:), 'noise est for SNR' )
 
-f=12;
+fr=12;
 
-stem_sig_and_error(13, 211, real(rx_symbols_log(:,f)), real(rx_symbols_log(:,f) - rx_symbols_log_c(:,f)), 'rx symbols real' )
-stem_sig_and_error(13, 212, imag(rx_symbols_log(:,f)), imag(rx_symbols_log(:,f) - rx_symbols_log_c(:,f)), 'rx symbols imag' )
+stem_sig_and_error(13, 211, real(rx_symbols_log(:,fr)), real(rx_symbols_log(:,fr) - rx_symbols_log_c(:,fr)), 'rx symbols real' )
+stem_sig_and_error(13, 212, imag(rx_symbols_log(:,fr)), imag(rx_symbols_log(:,fr) - rx_symbols_log_c(:,fr)), 'rx symbols imag' )
 
-stem_sig_and_error(17, 211, real(phase_difference_log(:,f)), real(phase_difference_log(:,f) - phase_difference_log_c(:,f)), 'phase difference real' )
-stem_sig_and_error(17, 212, imag(phase_difference_log(:,f)), imag(phase_difference_log(:,f) - phase_difference_log_c(:,f)), 'phase difference imag' )
+stem_sig_and_error(17, 211, real(phase_difference_log(:,fr)), real(phase_difference_log(:,fr) - phase_difference_log_c(:,fr)), 'phase difference real' )
+stem_sig_and_error(17, 212, imag(phase_difference_log(:,fr)), imag(phase_difference_log(:,fr) - phase_difference_log_c(:,fr)), 'phase difference imag' )
 
 
 check(tx_bits_log, tx_bits_log_c, 'tx_bits');
 check(tx_symbols_log,  tx_symbols_log_c, 'tx_symbols');
 check(tx_fdm_log, tx_fdm_log_c, 'tx_fdm');
-check(pilot_lut, pilot_lut_c, 'pilot_lut');
-check(pilot_coeff, pilot_coeff_c, 'pilot_coeff');
+check(f.pilot_lut, pilot_lut_c, 'pilot_lut');
+check(f.pilot_coeff, pilot_coeff_c, 'pilot_coeff');
 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');
@@ -266,11 +292,11 @@ 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_filt_log, rx_filt_log_c, 'rx filt');
+check(rx_fdm_filter_log, rx_fdm_filter_log_c, 'rxdec filter');
+check(rx_filt_log, rx_filt_log_c, 'rx filt', 2E-3);
 check(env_log, env_log_c, 'env');
 check(rx_timing_log, rx_timing_log_c, 'rx_timing');
-check(rx_symbols_log, rx_symbols_log_c, 'rx_symbols');
+check(rx_symbols_log, rx_symbols_log_c, 'rx_symbols', 2E-3);
 check(rx_bits_log, rx_bits_log_c, 'rx bits');
 check(sync_bit_log, sync_bit_log_c, 'sync bit');
 check(sync_log, sync_log_c, 'sync');
index 686a2dd488208002b371e12603552760e19c5fcc..edd74c5c67305542127f4b766cbec7d378032bf7 100644 (file)
@@ -56,7 +56,6 @@ int main(int argc, char *argv[])
     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;
     float         env[NT*P];
@@ -76,8 +75,8 @@ int main(int argc, char *argv[])
     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;
+    COMP          rx_fdm_filter_log[(M+M/P)*FRAMES];
+    int           rx_fdm_filter_log_index;
     COMP          rx_filt_log[NC+1][(P+1)*FRAMES];
     int           rx_filt_log_col_index;
     float         env_log[NT*P*FRAMES];
@@ -99,7 +98,7 @@ int main(int argc, char *argv[])
     next_nin = M;
     channel_count = 0;
 
-    rx_baseband_log_col_index = 0;
+    rx_fdm_filter_log_index = 0;
     rx_filt_log_col_index = 0;
 
     printf("sizeof FDMDV states: %zd bytes\n", sizeof(struct FDMDV));
@@ -122,7 +121,7 @@ int main(int argc, char *argv[])
 
        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"
 
        /* add M tx samples to end of buffer */
 
@@ -154,7 +153,7 @@ int main(int argc, char *argv[])
 
        /* freq offset estimation and correction */
 
-        //fdmdv->sync = 0; // when debugging good idea to uncomment this to "open loop"
+        // fdmdv->sync = 0; // when debugging good idea to uncomment this to "open loop"
 
        foff_coarse = rx_est_freq_offset(fdmdv, rx_fdm, nin, !fdmdv->sync);
 
@@ -165,6 +164,7 @@ int main(int argc, char *argv[])
        /* baseband processing */
 
         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, M);
@@ -206,17 +206,13 @@ int main(int argc, char *argv[])
        memcpy(&S2_log[f*MPILOTFFT], fdmdv->S2, sizeof(COMP)*MPILOTFFT);
        foff_coarse_log[f] = foff_coarse;
        foff_log[f] = fdmdv->foff;
-
-       /* rx down conversion */
-
-       for(c=0; c<NC+1; c++) {
-           for(i=0; i<nin; i++)
-               rx_baseband_log[c][rx_baseband_log_col_index + i] = rx_baseband[c][i];
-       }
-       rx_baseband_log_col_index += nin;
-
+       
        /* rx filtering */
 
+        for(i=0; i<nin; i++)
+            rx_fdm_filter_log[rx_fdm_filter_log_index + i] = rx_fdm_filter[i];
+        rx_fdm_filter_log_index += nin;
+
        for(c=0; c<NC+1; c++) {
            for(i=0; i<(P*nin)/M; i++)
                rx_filt_log[c][rx_filt_log_col_index + i] = rx_filt[c][i];
@@ -269,7 +265,7 @@ int main(int argc, char *argv[])
     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, FRAMES);
     octave_save_float(fout, "foff_coarse_log_c", foff_coarse_log, 1, FRAMES, FRAMES);
-    octave_save_complex(fout, "rx_baseband_log_c", (COMP*)rx_baseband_log, (FDMDV_NC+1), rx_baseband_log_col_index, (M+M/P)*FRAMES);
+    octave_save_complex(fout, "rx_fdm_filter_log_c", (COMP*)rx_fdm_filter_log, 1, rx_fdm_filter_log_index, rx_fdm_filter_log_index);
     octave_save_complex(fout, "rx_filt_log_c", (COMP*)rx_filt_log, (FDMDV_NC+1), rx_filt_log_col_index, (P+1)*FRAMES);
     octave_save_float(fout, "env_log_c", env_log, 1, NT*P*FRAMES, NT*P*FRAMES);
     octave_save_float(fout, "rx_timing_log_c", rx_timing_log, 1, FRAMES, FRAMES);