From: drowe67 Date: Fri, 13 Apr 2012 07:20:51 +0000 (+0000) Subject: some more refactoring X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=57cdb396591b5e5ab25a9da12d1b90b985af6401;p=freetel-svn-tracking.git some more refactoring git-svn-id: https://svn.code.sf.net/p/freetel/code@368 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/octave/fdmdv.m b/codec2-dev/octave/fdmdv.m index 5c6c4dab..f892046d 100644 --- a/codec2-dev/octave/fdmdv.m +++ b/codec2-dev/octave/fdmdv.m @@ -29,83 +29,11 @@ global Nt = 5; % number of symbols we estimate timing over global P = 4; % oversample factor used for rx symbol filtering global Nfilter = Nsym*M; global Nfiltertiming = M+Nfilter+M; +alpha = 0.5; % root raised cosine (Root Nyquist) filter -global gt_alpha5_root = gen_rn_coeffs(alpha, Rs, Nsym, M); - -% Initialise ---------------------------------------------------- - -global pilot_bit; -pilot_bit = 0; % current value of pilot bit - -global tx_filter_memory; -tx_filter_memory = zeros(Nc+1, Nfilter); -global rx_filter_memory; -rx_filter_memory = zeros(Nc+1, Nfilter); - -% phasors used for up and down converters - -global freq; -freq = zeros(Nc+1,1); -for c=1:Nc/2 - carrier_freq = (-Nc/2 - 1 + c)*Fsep + Fcentre; - freq(c) = exp(j*2*pi*carrier_freq/Fs); -end -for c=Nc/2+1:Nc - carrier_freq = (-Nc/2 + c)*Fsep + Fcentre; - freq(c) = exp(j*2*pi*carrier_freq/Fs); -end - -freq(Nc+1) = exp(j*2*pi*Fcentre/Fs); - -% Spread initial FDM carrier phase out as far as possible. This -% helped PAPR for a few dB. We don't need to adjust rx phase as DQPSK -% takes care of that. - -global phase_tx; -%phase_tx = ones(Nc+1,1); -phase_tx = exp(j*2*pi*(0:Nc)/(Nc+1)); -global phase_rx; -phase_rx = ones(Nc+1,1); - -% Freq offset estimator constants - -global Mpilotfft = 256; -global Npilotcoeff = 30; % number of pilot LPF coeffs -global pilot_coeff = fir1(Npilotcoeff, 200/(Fs/2))'; % 200Hz LPF -global Npilotbaseband = Npilotcoeff + 4*M; % number of pilot baseband samples reqd for pilot LPF -global Npilotlpf = 4*M; % number of samples we DFT pilot over, pilot est window - -% Freq offset estimator states - -global pilot_baseband1; -global pilot_baseband2; -pilot_baseband1 = zeros(1, Npilotbaseband); % pilot baseband samples -pilot_baseband2 = zeros(1, Npilotbaseband); % pilot baseband samples -global pilot_lpf1 -global pilot_lpf2 -pilot_lpf1 = zeros(1, Npilotlpf); % LPF pilot samples -pilot_lpf2 = zeros(1, Npilotlpf); % LPF pilot samples - -% Timing estimator states - -global rx_filter_mem_timing; -rx_filter_mem_timing = zeros(Nc+1, Nt*P); -global rx_baseband_mem_timing; -rx_baseband_mem_timing = zeros(Nc+1, Nfiltertiming); - -% Test bit stream constants - -global Ntest_bits = Nc*Nb*4; % length of test sequence -global test_bits = rand(1,Ntest_bits) > 0.5; - -% Test bit stream state variables - -global current_test_bit = 1; -current_test_bit = 1; -global rx_test_bits_mem; -rx_test_bits_mem = zeros(1,Ntest_bits); +global gt_alpha5_root = gen_rn_coeffs(alpha, T, Rs, Nsym, M); % Functions ---------------------------------------------------- @@ -606,7 +534,7 @@ endfunction % is periodic in 4M samples we can then use this vector as a look up table % for pilot signsl generation at the demod. -function pilot_lut = generate_pilot_lut +function pilot_lut = generate_pilot_lut() global Nc; global Nfilter; global M; @@ -639,6 +567,28 @@ function pilot_lut = generate_pilot_lut endfunction +% grab next pilot samples for freq offset estimation at demod + +function [pilot prev_pilot pilot_lut_index prev_pilot_lut_index] = get_pilot(pilot_lut_index, prev_pilot_lut_index, nin) + global M; + global pilot_lut; + + for i=1:nin + pilot(i) = pilot_lut(pilot_lut_index); + pilot_lut_index++; + if pilot_lut_index > 4*M + pilot_lut_index = 1; + end + prev_pilot(i) = pilot_lut(prev_pilot_lut_index); + prev_pilot_lut_index++; + if prev_pilot_lut_index > 4*M + prev_pilot_lut_index = 1; + end + end +endfunction + + + % Change the sample rate by a small amount, for example 1000ppm (ratio % = 1.001). Always returns nout samples in buf_out, but uses a % variable number of input samples nin to accomodate the change in @@ -754,3 +704,84 @@ function [track state] = freq_state(sync_bit, state) end endfunction +% Initialise ---------------------------------------------------- + +global pilot_bit; +pilot_bit = 0; % current value of pilot bit + +global tx_filter_memory; +tx_filter_memory = zeros(Nc+1, Nfilter); +global rx_filter_memory; +rx_filter_memory = zeros(Nc+1, Nfilter); + +% phasors used for up and down converters + +global freq; +freq = zeros(Nc+1,1); +for c=1:Nc/2 + carrier_freq = (-Nc/2 - 1 + c)*Fsep + Fcentre; + freq(c) = exp(j*2*pi*carrier_freq/Fs); +end +for c=Nc/2+1:Nc + carrier_freq = (-Nc/2 + c)*Fsep + Fcentre; + freq(c) = exp(j*2*pi*carrier_freq/Fs); +end + +freq(Nc+1) = exp(j*2*pi*Fcentre/Fs); + +% Spread initial FDM carrier phase out as far as possible. This +% helped PAPR for a few dB. We don't need to adjust rx phase as DQPSK +% takes care of that. + +global phase_tx; +%phase_tx = ones(Nc+1,1); +phase_tx = exp(j*2*pi*(0:Nc)/(Nc+1)); +global phase_rx; +phase_rx = ones(Nc+1,1); + +% Freq offset estimator constants + +global Mpilotfft = 256; +global Npilotcoeff = 30; % number of pilot LPF coeffs +global pilot_coeff = fir1(Npilotcoeff, 200/(Fs/2))'; % 200Hz LPF +global Npilotbaseband = Npilotcoeff + 4*M; % number of pilot baseband samples reqd for pilot LPF +global Npilotlpf = 4*M; % number of samples we DFT pilot over, pilot est window + +% pilot LUT, used for copy of pilot at rx + +global pilot_lut; +pilot_lut = generate_pilot_lut(); +pilot_lut_index = 1; +prev_pilot_lut_index = 3*M+1; + +% Freq offset estimator states + +global pilot_baseband1; +global pilot_baseband2; +pilot_baseband1 = zeros(1, Npilotbaseband); % pilot baseband samples +pilot_baseband2 = zeros(1, Npilotbaseband); % pilot baseband samples +global pilot_lpf1 +global pilot_lpf2 +pilot_lpf1 = zeros(1, Npilotlpf); % LPF pilot samples +pilot_lpf2 = zeros(1, Npilotlpf); % LPF pilot samples + +% Timing estimator states + +global rx_filter_mem_timing; +rx_filter_mem_timing = zeros(Nc+1, Nt*P); +global rx_baseband_mem_timing; +rx_baseband_mem_timing = zeros(Nc+1, Nfiltertiming); + +% Test bit stream constants + +global Ntest_bits = Nc*Nb*4; % length of test sequence +global test_bits = rand(1,Ntest_bits) > 0.5; + +% Test bit stream state variables + +global current_test_bit = 1; +current_test_bit = 1; +global rx_test_bits_mem; +rx_test_bits_mem = zeros(1,Ntest_bits); + + diff --git a/codec2-dev/octave/fdmdv_demod.m b/codec2-dev/octave/fdmdv_demod.m index a5baa49c..e1fb3b43 100644 --- a/codec2-dev/octave/fdmdv_demod.m +++ b/codec2-dev/octave/fdmdv_demod.m @@ -21,12 +21,6 @@ function fdmdv_demod(rawfilename, nbits) prev_rx_symbols = ones(Nc+1,1); foff_phase = 1; - % pilot LUT, used for copy of pilot at rx - - pilot_lut = generate_pilot_lut; - pilot_lut_index = 1; - prev_pilot_lut_index = 3*M+1; - % BER stats total_bit_errors = 0; @@ -46,7 +40,7 @@ function fdmdv_demod(rawfilename, nbits) nin = M; % timing correction for sample rate differences foff = 0; track_log = []; - track = 1; + track = 0; fest_state = 0; % Main loop ---------------------------------------------------- @@ -62,18 +56,7 @@ function fdmdv_demod(rawfilename, nbits) % frequency offset estimation and correction - for i=1:nin - pilot(i) = pilot_lut(pilot_lut_index); - pilot_lut_index++; - if pilot_lut_index > 4*M - pilot_lut_index = 1; - end - prev_pilot(i) = pilot_lut(prev_pilot_lut_index); - prev_pilot_lut_index++; - if prev_pilot_lut_index > 4*M - prev_pilot_lut_index = 1; - end - end + [pilot prev_pilot pilot_lut_index prev_pilot_lut_index] = get_pilot(pilot_lut_index, prev_pilot_lut_index, nin); foff_coarse = rx_est_freq_offset(rx_fdm, pilot, prev_pilot, nin); if track == 0 foff = foff_coarse; @@ -117,7 +100,6 @@ function fdmdv_demod(rawfilename, nbits) track_log = [track_log track]; % count bit errors if we find a test frame - % Allow 15 frames for filter memories to fill and time est to settle [test_frame_sync bit_errors] = put_test_bits(rx_bits); if (test_frame_sync == 1) @@ -182,6 +164,9 @@ function fdmdv_demod(rawfilename, nbits) title('timing offset (samples)'); subplot(212) plot(xt, foff_log) + hold on; + plot(xt, track_log*75, 'r'); + hold off; title('Freq offset (Hz)'); grid @@ -213,8 +198,4 @@ function fdmdv_demod(rawfilename, nbits) axis([0 secs 0 1.5]); title('Test Frame Sync') - figure(5) - clf; - plot(xt, track_log); - axis([0 secs 0 1.5]); endfunction diff --git a/codec2-dev/octave/fdmdv_ut.m b/codec2-dev/octave/fdmdv_ut.m index 012f9359..0a20a42b 100644 --- a/codec2-dev/octave/fdmdv_ut.m +++ b/codec2-dev/octave/fdmdv_ut.m @@ -45,12 +45,6 @@ sync_log = []; test_frame_sync_log = []; test_frame_sync_state = 0; -% pilot look up table, used for copy of pilot at rx - -pilot_lut = generate_pilot_lut; -pilot_lut_index = 1; -prev_pilot_lut_index = 3*M+1; - % fixed delay simuation Ndelay = M+20; @@ -85,10 +79,16 @@ CNo_dB = 10*log10(C) + 10*log10(Nc) - No_dBHz; B = 3000; SNR = CNo_dB - 10*log10(B); +% freq offset simulation states + phase_offset = 1; freq_offset = exp(j*2*pi*Foff_hz/Fs); foff_phase = 1; t = 0; +foff = 0; +fest_state = 0; +track = 0; +track_log = []; % --------------------------------------------------------------------- % Main loop @@ -151,23 +151,15 @@ for f=1:frames % Demodulator % ------------------- - % frequency offset estimation and correction + % frequency offset estimation and correction, need to call rx_est_freq_offset even in track + % mode to keep states updated - for i=1:M - pilot(i) = pilot_lut(pilot_lut_index); - pilot_lut_index++; - if pilot_lut_index > 4*M - pilot_lut_index = 1; - end - prev_pilot(i) = pilot_lut(prev_pilot_lut_index); - prev_pilot_lut_index++; - if prev_pilot_lut_index > 4*M - prev_pilot_lut_index = 1; - end + [pilot prev_pilot pilot_lut_index prev_pilot_lut_index] = get_pilot(pilot_lut_index, prev_pilot_lut_index, M); + foff_course = rx_est_freq_offset(rx_fdm_delay, pilot, prev_pilot, M); + if track == 0 + foff = foff_course; end - %foff = rx_est_freq_offset(rx_fdm_delay, pilot, prev_pilot, M); foff_log = [ foff_log foff ]; - %foff = 0; foff_rect = exp(j*2*pi*foff/Fs); for i=1:M @@ -198,14 +190,21 @@ for f=1:frames prev_rx_symbols = rx_symbols; sync_log = [sync_log sync]; + % freq est state machine + + [track fest_state] = freq_state(sync, fest_state); + track_log = [track_log track]; + % count bit errors if we find a test frame % Allow 15 frames for filter memories to fill and time est to settle [test_frame_sync bit_errors] = put_test_bits(rx_bits); - if ((test_frame_sync == 1) && (f > 15)) + if test_frame_sync == 1 total_bit_errors = total_bit_errors + bit_errors; total_bits = total_bits + Ntest_bits; bit_errors_log = [bit_errors_log bit_errors]; + else + bit_errors_log = [bit_errors_log 0]; end % test frame sync state machine, just for more informative plots @@ -265,6 +264,9 @@ plot(rx_timing_log) title('timing offset (samples)'); subplot(212) plot(foff_log) +hold on; +plot(track_log*75, 'r'); +hold off; title('Freq offset (Hz)'); figure(3) diff --git a/codec2-dev/octave/gen_rn_coeffs.m b/codec2-dev/octave/gen_rn_coeffs.m index b317d02e..2a67e240 100644 --- a/codec2-dev/octave/gen_rn_coeffs.m +++ b/codec2-dev/octave/gen_rn_coeffs.m @@ -4,7 +4,7 @@ % Generate root raised cosine (Root Nyquist) filter coefficients % thanks http://www.dsplog.com/db-install/wp-content/uploads/2008/05/raised_cosine_filter.m -function coeffs = gen_rn_coeffs(alpha, Rs, Nsym, M) +function coeffs = gen_rn_coeffs(alpha, T, Rs, Nsym, M) Ts = 1/Rs;