From 935c100f5aecc3389d2108d949af42a88788f57d Mon Sep 17 00:00:00 2001 From: drowe67 Date: Sat, 21 Apr 2012 22:46:47 +0000 Subject: [PATCH] FFT in freq est tested OK git-svn-id: https://svn.code.sf.net/p/freetel/code@374 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/octave/fdmdv.m | 73 +++++++++++------------ codec2-dev/octave/tfdmdv.m | 101 ++++++++++++-------------------- codec2-dev/src/fdmdv.c | 26 +++----- codec2-dev/src/fdmdv_internal.h | 6 +- codec2-dev/unittest/tfdmdv.c | 12 ++-- 5 files changed, 94 insertions(+), 124 deletions(-) diff --git a/codec2-dev/octave/fdmdv.m b/codec2-dev/octave/fdmdv.m index be274c3d..7a8f711d 100644 --- a/codec2-dev/octave/fdmdv.m +++ b/codec2-dev/octave/fdmdv.m @@ -240,41 +240,6 @@ function rx_filt = rx_filter(rx_baseband, nin) 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(rx_fdm, pilot, pilot_prev, nin) - global M; - global Npilotbaseband; - global pilot_baseband1; - global pilot_baseband2; - global pilot_lpf1; - global pilot_lpf2; - - % down convert latest nin samples of pilot by multiplying by - % ideal BPSK pilot signal we have generated locally. This - % peak of the resulting signal is sensitive to the time shift between - % the received and local version of the pilot, so we do it twice at - % different time shifts and choose the maximum. - - pilot_baseband1(1:Npilotbaseband-nin) = pilot_baseband1(nin+1:Npilotbaseband); - pilot_baseband2(1:Npilotbaseband-nin) = pilot_baseband2(nin+1:Npilotbaseband); - for i=1:nin - pilot_baseband1(Npilotbaseband-nin+i) = rx_fdm(i) * conj(pilot(i)); - pilot_baseband2(Npilotbaseband-nin+i) = rx_fdm(i) * conj(pilot_prev(i)); - end - - [foff1 max1 pilot_lpf1 s1] = lpf_peak_pick(pilot_baseband1, pilot_lpf1, nin); - [foff2 max2 pilot_lpf2 s2] = lpf_peak_pick(pilot_baseband2, pilot_lpf2, nin); - - if max1 > max2 - foff = foff1; - else - foff = foff2; - end -endfunction - - % LPF and peak pick part of freq est, put in a function as we call it twice function [foff imax pilot_lpf S] = lpf_peak_pick(pilot_baseband, pilot_lpf, nin) @@ -299,7 +264,8 @@ function [foff imax pilot_lpf S] = lpf_peak_pick(pilot_baseband, pilot_lpf, nin) Mpilot = Fs/(2*200); % calc decimation rate given new sample rate is twice LPF freq h = hanning(Npilotlpf); s = pilot_lpf(1:Mpilot:Npilotlpf) .* h(1:Mpilot:Npilotlpf)'; - S = abs(fft(s, Mpilotfft)); + s = [s zeros(1,Mpilotfft-Npilotlpf/Mpilot)]; + S = fft(s, Mpilotfft); % peak pick and convert to Hz @@ -315,6 +281,41 @@ function [foff imax pilot_lpf S] = lpf_peak_pick(pilot_baseband, pilot_lpf, nin) 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(rx_fdm, pilot, pilot_prev, nin) + global M; + global Npilotbaseband; + global pilot_baseband1; + global pilot_baseband2; + global pilot_lpf1; + global pilot_lpf2; + + % down convert latest nin samples of pilot by multiplying by + % ideal BPSK pilot signal we have generated locally. This + % peak of the resulting signal is sensitive to the time shift between + % the received and local version of the pilot, so we do it twice at + % different time shifts and choose the maximum. + + pilot_baseband1(1:Npilotbaseband-nin) = pilot_baseband1(nin+1:Npilotbaseband); + pilot_baseband2(1:Npilotbaseband-nin) = pilot_baseband2(nin+1:Npilotbaseband); + for i=1:nin + pilot_baseband1(Npilotbaseband-nin+i) = rx_fdm(i) * conj(pilot(i)); + pilot_baseband2(Npilotbaseband-nin+i) = rx_fdm(i) * conj(pilot_prev(i)); + end + + [foff1 max1 pilot_lpf1 S1] = lpf_peak_pick(pilot_baseband1, pilot_lpf1, nin); + [foff2 max2 pilot_lpf2 S2] = lpf_peak_pick(pilot_baseband2, pilot_lpf2, nin); + + if max1 > max2 + foff = foff1; + else + foff = foff2; + end +endfunction + + % Estimate optimum timing offset, re-filter receive symbols function [rx_symbols rx_timing] = rx_est_timing(rx_filt, rx_baseband, nin) diff --git a/codec2-dev/octave/tfdmdv.m b/codec2-dev/octave/tfdmdv.m index 020a5840..fd6e9e75 100644 --- a/codec2-dev/octave/tfdmdv.m +++ b/codec2-dev/octave/tfdmdv.m @@ -13,6 +13,8 @@ fdmdv; % load modem code % Generate reference vectors using Octave implementation of FDMDV modem +global passes; +global fails; passes = fails = 0; frames = 25; prev_tx_symbols = ones(Nc+1,1); @@ -27,8 +29,8 @@ pilot_baseband1_log = []; pilot_baseband2_log = []; pilot_lpf1_log = []; pilot_lpf2_log = []; -s1_log = []; -s2_log = []; +S1_log = []; +S2_log = []; for f=1:frames @@ -50,14 +52,14 @@ for f=1:frames [pilot prev_pilot pilot_lut_index prev_pilot_lut_index] = get_pilot(pilot_lut_index, prev_pilot_lut_index, M); - [foff s1 s2] = rx_est_freq_offset(rx_fdm, pilot, prev_pilot, M); + [foff S1 S2] = rx_est_freq_offset(rx_fdm, pilot, prev_pilot, M); pilot_baseband1_log = [pilot_baseband1_log pilot_baseband1]; pilot_baseband2_log = [pilot_baseband2_log pilot_baseband2]; pilot_lpf1_log = [pilot_lpf1_log pilot_lpf1]; pilot_lpf2_log = [pilot_lpf2_log pilot_lpf2]; - s1_log = [s1_log s1]; - s2_log = [s2_log s2]; + S1_log = [S1_log S1]; + S2_log = [S2_log S2]; end @@ -128,69 +130,44 @@ plot_sig_and_error(5, 212, real(pilot_baseband2_log), real(pilot_baseband2_log - plot_sig_and_error(6, 211, real(pilot_lpf1_log), real(pilot_lpf1_log - pilot_lpf1_log_c), 'pilot lpf1 real' ) plot_sig_and_error(6, 212, real(pilot_lpf2_log), real(pilot_lpf2_log - pilot_lpf2_log_c), 'pilot lpf2 real' ) -plot_sig_and_error(7, 211, real(s1_log), real(s1_log - s1_log_c), 's1 real' ) -plot_sig_and_error(7, 212, real(s2_log), real(s2_log - s2_log_c), 's2 real' ) +plot_sig_and_error(7, 211, real(S1_log), real(S1_log - S1_log_c), 'S1 real' ) +plot_sig_and_error(7, 212, imag(S1_log), imag(S1_log - S1_log_c), 'S1 imag' ) + +plot_sig_and_error(8, 211, real(S2_log), real(S2_log - S2_log_c), 'S2 real' ) +plot_sig_and_error(8, 212, imag(S2_log), imag(S2_log - S2_log_c), 'S2 imag' ) % --------------------------------------------------------------------------------------- % AUTOMATED CHECKS ------------------------------------------ % --------------------------------------------------------------------------------------- -if sum(tx_bits_log - tx_bits_log_c) == 0 - printf("fdmdv_get_test_bits..: OK\n"); - passes++; -else; - printf("fdmdv_get_test_bits..: FAIL\n"); - fails++; -end - -if sum(tx_symbols_log - tx_symbols_log_c) == 0 - printf("bits_to_dqpsk_symbols: OK\n"); - passes++; -else; - printf("bits_to_dqpsk_symbols: FAIL\n"); - fails++; -end - -if sum(tx_baseband_log - tx_baseband_log_c) < 1E-3 - printf("tx_filter............: OK\n"); - passes++; -else; - printf("tx_filter............: FAIL\n"); - fails++; -end - -if sum(tx_fdm_log - tx_fdm_log_c) < 1E-3 - printf("tx_fdm...............: OK\n"); - passes++; -else; - printf("tx_fdm...............: FAIL\n"); - fails++; -end +function check(a, b, test_name) + global passes; + global fails; -if sum(pilot_lut - pilot_lut_c) < 1E-3 - printf("pilot_lut............: OK\n"); - passes++; -else; - printf("pilot_lut............: FAIL\n"); - fails++; -end - -[m n] = size(pilot_baseband1_log); -if sum(pilot_baseband1_log - pilot_baseband1_log_c)/n < 1E-3 - printf("pilot_baseband1_log..: OK\n"); - passes++; -else; - printf("pilot_baseband1_log..: FAIL\n"); - fails++; -end + [m n] = size(a); + printf("%s", test_name); + for i=1:(25-length(test_name)) + printf("."); + end + printf(": "); + + if sum(a - b)/n < 1E-3 + printf("OK\n"); + passes++; + else + printf("FAIL\n"); + fails++; + end +endfunction -[m n] = size(pilot_baseband2_log); -if sum(pilot_baseband2_log - pilot_baseband2_log_c)/n < 1E-3 - printf("pilot_baseband2_log..: OK\n"); - passes++; -else; - printf("pilot_baseband2_log..: FAIL\n"); - fails++; -end +check(tx_bits_log, tx_bits_log_c, 'fdmdv_get_test_bits'); +check(tx_symbols_log, tx_symbols_log_c, 'bits_to_dqpsk_symbols'); +check(tx_baseband_log, tx_baseband_log_c, 'tx_filter'); +check(tx_fdm_log, tx_fdm_log_c, 'tx_fdm'); +check(pilot_lut, pilot_lut_c, 'pilot_lut'); +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'); +check(S2_log, S2_log_c, 'S2'); printf("\npasses: %d fails: %d\n", passes, fails); diff --git a/codec2-dev/src/fdmdv.c b/codec2-dev/src/fdmdv.c index 7f0b9d77..add05ace 100644 --- a/codec2-dev/src/fdmdv.c +++ b/codec2-dev/src/fdmdv.c @@ -511,7 +511,7 @@ void generate_pilot_lut(COMP pilot_lut[], COMP *pilot_freq) \*---------------------------------------------------------------------------*/ -void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], COMP pilot_lpf[], COMP s[], int nin) +void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], COMP pilot_lpf[], COMP S[], int nin) { int i,j,k; int mpilot; @@ -533,22 +533,20 @@ void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], COMP pilot_lp mpilot = FS/(2*200); /* calc decimation rate given new sample rate is twice LPF freq */ for(i=0; i imax) { imax = mag; ix = i; @@ -561,7 +559,7 @@ void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], COMP pilot_lp else *foff = (ix)*r; *max = imax; -#endif + } /*---------------------------------------------------------------------------*\ @@ -618,19 +616,13 @@ float rx_est_freq_offset(struct FDMDV *f, float rx_fdm[], int nin) f->pilot_baseband2[j] = fcmult(rx_fdm[i], cconj(prev_pilot[i])); } - lpf_peak_pick(&foff1, &max1, f->pilot_baseband1, f->pilot_lpf1, f->s1, nin); - lpf_peak_pick(&foff2, &max2, f->pilot_baseband2, f->pilot_lpf2, f->s2, nin); - //for(i=0; is1[i].real, f->s1[i].imag); - //} + lpf_peak_pick(&foff1, &max1, f->pilot_baseband1, f->pilot_lpf1, f->S1, nin); + lpf_peak_pick(&foff2, &max2, f->pilot_baseband2, f->pilot_lpf2, f->S2, nin); -#ifdef T if (max1 > max2) foff = foff1; else foff = foff2; return foff; -#endif - return 0; } diff --git a/codec2-dev/src/fdmdv_internal.h b/codec2-dev/src/fdmdv_internal.h index 68d334b0..47bee78d 100644 --- a/codec2-dev/src/fdmdv_internal.h +++ b/codec2-dev/src/fdmdv_internal.h @@ -85,8 +85,8 @@ struct FDMDV { COMP pilot_baseband2[NPILOTBASEBAND]; COMP pilot_lpf1[NPILOTLPF]; COMP pilot_lpf2[NPILOTLPF]; - COMP s1[MPILOTFFT]; - COMP s2[MPILOTFFT]; + COMP S1[MPILOTFFT]; + COMP S2[MPILOTFFT]; }; /*---------------------------------------------------------------------------*\ @@ -101,6 +101,6 @@ void fdm_upconvert(COMP tx_fdm[], COMP tx_baseband[NC+1][M], COMP phase_tx[], CO 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, float rx_fdm[], int nin); -void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], COMP pilot_lpf[], COMP s[], int nin); +void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], COMP pilot_lpf[], COMP S[], int nin); #endif diff --git a/codec2-dev/unittest/tfdmdv.c b/codec2-dev/unittest/tfdmdv.c index f2b3bd63..ae11da2d 100644 --- a/codec2-dev/unittest/tfdmdv.c +++ b/codec2-dev/unittest/tfdmdv.c @@ -60,8 +60,8 @@ int main(int argc, char *argv[]) COMP pilot_baseband2_log[NPILOTBASEBAND*FRAMES]; COMP pilot_lpf1_log[NPILOTLPF*FRAMES]; COMP pilot_lpf2_log[NPILOTLPF*FRAMES]; - COMP s1_log[32*FRAMES]; - COMP s2_log[32*FRAMES]; + COMP S1_log[MPILOTFFT*FRAMES]; + COMP S2_log[MPILOTFFT*FRAMES]; FILE *fout; int f,c,i; @@ -97,8 +97,8 @@ int main(int argc, char *argv[]) memcpy(&pilot_baseband2_log[f*NPILOTBASEBAND], fdmdv->pilot_baseband2, sizeof(COMP)*NPILOTBASEBAND); memcpy(&pilot_lpf1_log[f*NPILOTLPF], fdmdv->pilot_lpf1, sizeof(COMP)*NPILOTLPF); memcpy(&pilot_lpf2_log[f*NPILOTLPF], fdmdv->pilot_lpf2, sizeof(COMP)*NPILOTLPF); - memcpy(&s1_log[f*32], fdmdv->s1, sizeof(COMP)*32); - memcpy(&s2_log[f*32], fdmdv->s2, sizeof(COMP)*32); + memcpy(&S1_log[f*MPILOTFFT], fdmdv->S1, sizeof(COMP)*MPILOTFFT); + memcpy(&S2_log[f*MPILOTFFT], fdmdv->S2, sizeof(COMP)*MPILOTFFT); } /* dump logs to Octave file for evaluation by tfdmdv.m Octave script */ @@ -115,8 +115,8 @@ int main(int argc, char *argv[]) octave_save_complex(fout, "pilot_baseband2_log_c", pilot_baseband2_log, 1, NPILOTBASEBAND*FRAMES); octave_save_complex(fout, "pilot_lpf1_log_c", pilot_lpf1_log, 1, NPILOTLPF*FRAMES); octave_save_complex(fout, "pilot_lpf2_log_c", pilot_lpf2_log, 1, NPILOTLPF*FRAMES); - octave_save_complex(fout, "s1_log_c", s1_log, 1, 32*FRAMES); - octave_save_complex(fout, "s2_log_c", s2_log, 1, 32*FRAMES); + octave_save_complex(fout, "S1_log_c", S1_log, 1, MPILOTFFT*FRAMES); + octave_save_complex(fout, "S2_log_c", S2_log, 1, MPILOTFFT*FRAMES); fclose(fout); codec2_destroy(fdmdv); -- 2.25.1