From b6d9a1f50335e86461b633a312a2253a02777139 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Sun, 29 Jun 2014 05:36:14 +0000 Subject: [PATCH] fdmdv.m and fdmdv.c passes all tfdmdv.m tests with linear interpolater, fdmdv_mem reports fdmdv states memory halved to 194k git-svn-id: https://svn.code.sf.net/p/freetel/code@1715 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/octave/fdmdv.m | 72 ++++-------------------------------- codec2-dev/octave/tfdmdv.m | 16 +++++--- codec2-dev/src/fdmdv.c | 66 ++++++++++++++------------------- codec2-dev/unittest/tfdmdv.c | 17 ++++----- 4 files changed, 51 insertions(+), 120 deletions(-) diff --git a/codec2-dev/octave/fdmdv.m b/codec2-dev/octave/fdmdv.m index d63b73de..aee46816 100644 --- a/codec2-dev/octave/fdmdv.m +++ b/codec2-dev/octave/fdmdv.m @@ -354,22 +354,6 @@ function [foff S1 S2] = rx_est_freq_offset(rx_fdm, pilot, pilot_prev, nin) global pilot_baseband2; global pilot_lpf1; global pilot_lpf2; - global Nbpf; - global Nbpfcoeff; - global bpf_coeff; - global bpf; - -if 0 - % Band Pass filter input so we have (mainly) just the pilots - - bpf(1:Nbpf-nin) = bpf(nin+1:Nbpf); - bpf(Nbpf-nin+1:Nbpf) = rx_fdm(1:nin); - k = 1; - for i = Nbpf-nin+1:Nbpf - rx_fdm_bpf(k) = bpf(i-(Nbpfcoeff-1):i) * bpf_coeff'; - k++; - end -end % down convert latest nin samples of pilot by multiplying by ideal % BPSK pilot signal we have generated locally. The peak of the DFT @@ -397,12 +381,11 @@ endfunction % Estimate optimum timing offset, re-filter receive symbols -function [rx_symbols rx_timing env] = rx_est_timing(rx_filt, rx_baseband, nin) +function [rx_symbols rx_timing_M env] = rx_est_timing(rx_filt, nin) global M; global Nt; global Nc; global rx_filter_mem_timing; - global rx_baseband_mem_timing; global P; global Nfilter; global Nfiltertiming; @@ -433,11 +416,8 @@ function [rx_symbols rx_timing env] = rx_est_timing(rx_filt, rx_baseband, nin) x = env * exp(-j*2*pi*(0:m-1)/P)'; -linear_interp = 1; - -if linear_interp - - rx_timing = angle(x)*P/(2*pi) + P/4; + norm_rx_timing = angle(x)/(2*pi); + rx_timing = norm_rx_timing*P + P/4; if (rx_timing > P) rx_timing -= P; end @@ -453,37 +433,12 @@ if linear_interp low_sample = floor(rx_timing); fract = rx_timing - low_sample; high_sample = ceil(rx_timing); - % printf("rx_timing: %f low_sample: %f high_sample: %f fract: %f\n", rx_timing, low_sample, high_sample, fract); - + %printf("rx_timing: %f low_sample: %f high_sample: %f fract: %f\n", rx_timing, low_sample, high_sample, fract); + 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); -else - - % map phase to estimated optimum timing instant at rate M - % the M/4 part was adjusted by experiment, I know not why.... - - rx_timing = angle(x)*M/(2*pi) + M/4; - if (rx_timing > M) - rx_timing -= M; - end - if (rx_timing < -M) - rx_timing += M; - end - - % rx_baseband_mem_timing contains M + Nfilter + M samples of the - % baseband signal at rate M this enables us to resample the filtered - % rx symbol with M sample precision once we have rx_timing - - rx_baseband_mem_timing(:,1:Nfiltertiming-nin) = rx_baseband_mem_timing(:,nin+1:Nfiltertiming); - rx_baseband_mem_timing(:,Nfiltertiming-nin+1:Nfiltertiming) = rx_baseband; - - % sample right in the middle of the timing estimator window, by filtering - % at rate M - - s = round(rx_timing) + M; - rx_symbols = rx_baseband_mem_timing(:,s+1:s+Nfilter) * gt_alpha5_root'; -end - + rx_timing_M = norm_rx_timing*M; endfunction @@ -1094,15 +1049,6 @@ phase_rx = ones(Nc+1,1); % Freq offset estimator constants -if 0 -global Nbpfcoeff; % number of input BPF coeffs - Nbpfcoeff = 100; -global bpf_coeff; - bpf_coeff = fir1(Nbpfcoeff-1, [Fcentre-100 Fcentre+100]/(Fs/2),'pass')'; -global Nbpf; - Nbpf = Nbpfcoeff + M + M/P; % number of pilot baseband samples reqd for pilot LPF -end - global Mpilotfft = 256; global Npilotcoeff; % number of pilot LPF coeffs @@ -1124,10 +1070,6 @@ global prev_pilot_lut_index; % Freq offset estimator states -if 0 -global bpf; - bpf = zeros(1, Nbpf); % BPF pilot input samples -end global pilot_baseband1; global pilot_baseband2; pilot_baseband1 = zeros(1, Npilotbaseband); % pilot baseband samples diff --git a/codec2-dev/octave/tfdmdv.m b/codec2-dev/octave/tfdmdv.m index 26380214..296ecf1a 100644 --- a/codec2-dev/octave/tfdmdv.m +++ b/codec2-dev/octave/tfdmdv.m @@ -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 11 12 16]; +no_plot_list = [1 2 3 4 5 6 7 8 16]; for f=1:frames @@ -82,8 +82,10 @@ for f=1:frames % channel - %nin = next_nin; - nin = M; + nin = next_nin; + + % nin = M; % when debugging good idea to uncomment this to "open loop" + channel = [channel real(tx_fdm)]; channel_count += M; rx_fdm = channel(1:nin); @@ -95,6 +97,9 @@ for f=1:frames [pilot prev_pilot pilot_lut_index prev_pilot_lut_index] = get_pilot(pilot_lut_index, prev_pilot_lut_index, nin); [foff_coarse S1 S2] = rx_est_freq_offset(rx_fdm, pilot, prev_pilot, nin); + + %sync = 0; % when debugging good idea to uncomment this to "open loop" + if sync == 0 foff = foff_coarse; end @@ -120,9 +125,8 @@ for f=1:frames rx_filt = rx_filter(rx_baseband, nin); rx_filt_log = [rx_filt_log rx_filt]; - [rx_symbols rx_timing env] = rx_est_timing(rx_filt, rx_baseband, nin); + [rx_symbols rx_timing env] = rx_est_timing(rx_filt, nin); env_log = [env_log env]; - rx_timing_log = [rx_timing_log rx_timing]; rx_symbols_log = [rx_symbols_log rx_symbols]; @@ -247,7 +251,7 @@ 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=15; +c=1; 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' ) diff --git a/codec2-dev/src/fdmdv.c b/codec2-dev/src/fdmdv.c index 0ed9d07c..134e62d4 100644 --- a/codec2-dev/src/fdmdv.c +++ b/codec2-dev/src/fdmdv.c @@ -179,10 +179,6 @@ struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc) f->rx_filter_mem_timing[c][k].real = 0.0; f->rx_filter_mem_timing[c][k].imag = 0.0; } - for(k=0; krx_baseband_mem_timing[c][k].real = 0.0; - f->rx_baseband_mem_timing[c][k].imag = 0.0; - } } fdmdv_set_fsep(f, FSEP); @@ -897,16 +893,15 @@ void rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_baseband[NC+1][M+M/P], C float rx_est_timing(COMP rx_symbols[], int Nc, COMP rx_filt[NC+1][P+1], - COMP rx_baseband[NC+1][M+M/P], COMP rx_filter_mem_timing[NC+1][NT*P], float env[], - COMP rx_baseband_mem_timing[NC+1][NFILTERTIMING], int nin) { - int c,i,j,k; - int adjust, s; + int c,i,j; + int adjust; COMP x, phase, freq; - float rx_timing; + float rx_timing, fract, norm_rx_timing; + int low_sample, high_sample; /* nin adjust @@ -950,41 +945,34 @@ float rx_est_timing(COMP rx_symbols[], phase = cmult(phase, freq); } - /* Map phase to estimated optimum timing instant at rate M. The - M/4 part was adjusted by experiment, I know not why.... */ + /* Map phase to estimated optimum timing instant at rate P. The + P/4 part was adjusted by experiment, I know not why.... */ - rx_timing = atan2(x.imag, x.real)*M/(2*PI) + M/4; + norm_rx_timing = atan2(x.imag, x.real)/(2*PI); + rx_timing = norm_rx_timing*P + P/4; - if (rx_timing > M) - rx_timing -= M; - if (rx_timing < -M) - rx_timing += M; - - /* rx_filt_mem_timing contains M + Nfilter + M samples of the - baseband signal at rate M this enables us to resample the - filtered rx symbol with M sample precision once we have - rx_timing */ + if (rx_timing > P) + rx_timing -= P; + if (rx_timing < -P) + rx_timing += P; - for(c=0; cNc, rx_fdm_fcorr, fdmdv->phase_rx, fdmdv->freq, *nin); rx_filter(rx_filt, fdmdv->Nc, rx_baseband, fdmdv->rx_filter_memory, *nin); - fdmdv->rx_timing = rx_est_timing(rx_symbols, fdmdv->Nc, rx_filt, rx_baseband, fdmdv->rx_filter_mem_timing, env, fdmdv->rx_baseband_mem_timing, *nin); + fdmdv->rx_timing = rx_est_timing(rx_symbols, fdmdv->Nc, rx_filt, fdmdv->rx_filter_mem_timing, env, *nin); /* Adjust number of input samples to keep timing within bounds */ diff --git a/codec2-dev/unittest/tfdmdv.c b/codec2-dev/unittest/tfdmdv.c index cb6bf148..2be95812 100644 --- a/codec2-dev/unittest/tfdmdv.c +++ b/codec2-dev/unittest/tfdmdv.c @@ -122,15 +122,9 @@ int main(int argc, char *argv[]) \*---------------------------------------------------------*/ nin = next_nin; - /* - if (f == 2) - nin = 120; - if (f == 3) - nin = 200; - if ((f !=2) && (f != 3)) - nin = M; - */ - nin = M; + + //nin = M; // when debugging good idea to uncomment this to "open loop" + /* add M tx samples to end of buffer */ assert((channel_count + M) < CHANNEL_BUF_SIZE); @@ -158,6 +152,9 @@ int main(int argc, char *argv[]) /* freq offset estimation and correction */ foff_coarse = rx_est_freq_offset(fdmdv, rx_fdm, nin); + + //fdmdv->sync = 0; // when debugging good idea to uncomment this to "open loop" + if (fdmdv->sync == 0) fdmdv->foff = foff_coarse; fdmdv_freq_shift(rx_fdm_fcorr, rx_fdm, -fdmdv->foff, &fdmdv->foff_phase_rect, nin); @@ -166,7 +163,7 @@ int main(int argc, char *argv[]) fdm_downconvert(rx_baseband, FDMDV_NC, rx_fdm_fcorr, fdmdv->phase_rx, fdmdv->freq, nin); rx_filter(rx_filt, FDMDV_NC, rx_baseband, fdmdv->rx_filter_memory, nin); - rx_timing = rx_est_timing(rx_symbols, FDMDV_NC, rx_filt, rx_baseband, fdmdv->rx_filter_mem_timing, env, fdmdv->rx_baseband_mem_timing, nin); + 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); //for(i=0; i