+ 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
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);
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)
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
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;
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