first pass at resampler for demod that can handle +/- 2000ppm
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sun, 8 Apr 2012 02:57:59 +0000 (02:57 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sun, 8 Apr 2012 02:57:59 +0000 (02:57 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@364 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/README_fdmdv.txt
codec2-dev/octave/fdmdv.m
codec2-dev/octave/fdmdv_demod.m

index d6f415ced947e9ea7d5085a7e9425b6f09ad0a86..57d29c5e9bd0d8fe06ec40fcef0afacbb4747762 100644 (file)
@@ -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
index 35017d5d0928e80e6fd41c34f28380aa43235dfa..f0cf803722597b2b3fd2cfe6d8a76e0b5f470437 100644 (file)
@@ -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
index ed26e7a256c345d1daf0bf5121c3c411728d5ea1..96ebabf7daa64871a03b89c7101d285bfb280626 100644 (file)
@@ -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