From f68c458305fd176218c6842641c4796fb08e85bc Mon Sep 17 00:00:00 2001 From: drowe67 Date: Sat, 27 Aug 2016 06:12:02 +0000 Subject: [PATCH] refactoring fdmdv.m to get tfdmdv.m working again. tfdmdv tests now passing, about to clean up git-svn-id: https://svn.code.sf.net/p/freetel/code@2845 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/CMakeLists.txt | 2 +- codec2-dev/octave/fdmdv.m | 28 +++++++++--- codec2-dev/octave/tfdmdv.m | 86 +++++++++++++++++++++++------------- codec2-dev/unittest/tfdmdv.c | 28 +++++------- 4 files changed, 92 insertions(+), 52 deletions(-) diff --git a/codec2-dev/CMakeLists.txt b/codec2-dev/CMakeLists.txt index 0c816518..41d2b001 100644 --- a/codec2-dev/CMakeLists.txt +++ b/codec2-dev/CMakeLists.txt @@ -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. diff --git a/codec2-dev/octave/fdmdv.m b/codec2-dev/octave/fdmdv.m index 7cfbf9f9..a3fcbbdd 100644 --- a/codec2-dev/octave/fdmdv.m +++ b/codec2-dev/octave/fdmdv.m @@ -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++); diff --git a/codec2-dev/octave/tfdmdv.m b/codec2-dev/octave/tfdmdv.m index 2dc941a4..c338fcac 100644 --- a/codec2-dev/octave/tfdmdv.m +++ b/codec2-dev/octave/tfdmdv.m @@ -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'); diff --git a/codec2-dev/unittest/tfdmdv.c b/codec2-dev/unittest/tfdmdv.c index 686a2dd4..edd74c5c 100644 --- a/codec2-dev/unittest/tfdmdv.c +++ b/codec2-dev/unittest/tfdmdv.c @@ -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