From: drowe67 Date: Sun, 8 Apr 2012 02:57:59 +0000 (+0000) Subject: first pass at resampler for demod that can handle +/- 2000ppm X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=ecaf68c079287f1d0ebe3ba278a8e083556356d4;p=freetel-svn-tracking.git first pass at resampler for demod that can handle +/- 2000ppm git-svn-id: https://svn.code.sf.net/p/freetel/code@364 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/octave/README_fdmdv.txt b/codec2-dev/octave/README_fdmdv.txt index d6f415ce..57d29c5e 100644 --- a/codec2-dev/octave/README_fdmdv.txt +++ b/codec2-dev/octave/README_fdmdv.txt @@ -13,6 +13,11 @@ TODO + do we need to logic to lose or gain a frame? + think so, add or remove samples, or a whole frame [ ] demod outputs ber (maybe after settling time) +[ ] try interfering sine wave + + maybe swept + + does modem fall over? +[ ] try non-flat channel, e.g. 3dB difference between hi and low tones + + make sure all estimators keep working [ ] try to run from shell script [ ] run a few tests [ ] start coding in C and repeat tests diff --git a/codec2-dev/octave/fdmdv.m b/codec2-dev/octave/fdmdv.m index 35017d5d..f0cf8037 100644 --- a/codec2-dev/octave/fdmdv.m +++ b/codec2-dev/octave/fdmdv.m @@ -547,9 +547,9 @@ end freq(Nc+1) = exp(j*2*pi*Fcentre/Fs); -% Spread initial FDM carrier phase out as far as possible. -% This really helped PAPR. We don't need to adjust rx -% phase a DPSK takes care of that +% 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); @@ -595,6 +595,7 @@ current_test_bit = 1; global rx_test_bits_mem; rx_test_bits_mem = zeros(1,Ntest_bits); + % Generate M samples of DBPSK pilot signal for Freq offset estimation function [pilot_fdm bit symbol filter_mem phase] = generate_pilot_fdm(bit, symbol, filter_mem, phase, freq) @@ -634,3 +635,40 @@ function [pilot_fdm bit symbol filter_mem phase] = generate_pilot_fdm(bit, symbo 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 +% sample rate. nin is nominally set to nout, but may use nout +/- 2 +% samples to accomodate the different sample rates. buf_in should be +% of length nout+6 samples to accomodate this, and buf_in should be +% updated externally based on the nin returned each time. "ratio" is +% Fs_in/Fs_out, for example 48048/48000 = 1.001 (+1000ppm) or +% 47952/48000 = 0.999 (-1000ppm). Uses linear interpolation to +% perform the resampling. This requires a highly over-sampled signal, +% for example 48000Hz sample rate for the modem signal centred on +% 1kHz, otherwise linear interpolation will have a low pass filter effect +% (for example an 8000Hz sample rate for modem signal centred on 1kHz +% would cause problems). + +function [buf_out t nin] = resample(buf_in, t, ratio, nout) + + for i=1:nout + c = floor(t); + a = t - c; + b = 1 - a; + buf_out(i) = buf_in(c)*b + buf_in(c+1)*a; + t += ratio; + end + + t -= nout; + + % adjust nin and t so that on next call we start with 3 < t < 4, + % this gives us +/- 2 samples room to move before we hit start or + % end of buf_in + + delta = floor(t - 3); + nin = nout + delta; + t -= delta; + +endfunction diff --git a/codec2-dev/octave/fdmdv_demod.m b/codec2-dev/octave/fdmdv_demod.m index ed26e7a2..96ebabf7 100644 --- a/codec2-dev/octave/fdmdv_demod.m +++ b/codec2-dev/octave/fdmdv_demod.m @@ -14,14 +14,8 @@ function fdmdv_demod(rawfilename, nbits) modulation = 'dqpsk'; fin = fopen(rawfilename, "rb"); - rx_fdm_buf = fread(fin, Inf, "short"); gain = 1000; - rx_fdm_buf /= gain; - if (nargin == 1) - frames = floor(length(rx_fdm_buf)/M); - else - frames = nbits/(Nc*Nb); - endif + frames = nbits/(Nc*Nb); prev_rx_symbols = ones(Nc+1,1); foff_phase = 1; @@ -48,10 +42,42 @@ function fdmdv_demod(rawfilename, nbits) rx_timing_log = []; foff_log = []; + % resampler states + + t = 3; + ratio = 1.002; + F=6; + MF=M*F; + nin = MF; + nin_size = MF+6; + buf_in = zeros(1,nin_size); + rx_fdm_buf = []; + % Main loop ---------------------------------------------------- for f=1:frames - rx_fdm = rx_fdm_buf((f-1)*M+1:f*M); + % update buf_in memory + + m = nin_size - nin; + for i=1:m + buf_in(i) = buf_in(i+nin); + end + + % obtain n samples of the test input signal + + for i=m+1:nin_size + buf_in(i) = fread(fin, 1, "short")/gain; + end + + [rx_fdm_mf t nin] = resample(buf_in, t, ratio, MF); + rx_fdm = rx_fdm_mf(1:F:MF); + + %rx_fdm = buf_in(m+1:m+n); + + %for i=1:M + % rx_fdm(i) = fread(fin, 1, "short")/gain; + %end + rx_fdm_buf = [rx_fdm_buf rx_fdm]; % frequency offset estimation and correction