% Version 2
%
-% reqd to mak sure we get same random bits at mod and demod
+% reqd to make sure we get same random bits at mod and demod
rand('state',1);
randn('state',1);
endfunction
-% Given Nc*Nb bits construct M samples (1 symbol) of Nc filtered
+% Given Nc symbols construct M samples (1 symbol) of Nc filtered
% symbols streams
-function tx_baseband = tx_filter(tx_symbols)
- global Nc;
- global M;
- global tx_filter_memory;
- global Nfilter;
- global gt_alpha5_root;
+function [tx_baseband fdmdv] = tx_filter(fdmdv, tx_symbols)
+ Nc = fdmdv.Nc;
+ M = fdmdv.M;
+ tx_filter_memory = fdmdv.tx_filter_memory;
+ Nfilter = fdmdv.Nfilter;
+ gt_alpha5_root = fdmdv.gt_alpha5_root;
tx_baseband = zeros(Nc+1,M);
% tx filter each symbol, generate M filtered output samples for each symbol.
% Efficient polyphase filter techniques used as tx_filter_memory is sparse
-
+
tx_filter_memory(:,Nfilter) = sqrt(2)/2*tx_symbols;
for i=1:M
tx_filter_memory(:,1:Nfilter-M) = tx_filter_memory(:,M+1:Nfilter);
tx_filter_memory(:,Nfilter-M+1:Nfilter) = zeros(Nc+1,M);
+ fdmdv.tx_filter_memory = tx_filter_memory;
endfunction
% stream. Returns complex signal so we can apply frequency offsets
% easily.
-function tx_fdm = fdm_upconvert(tx_filt)
- global Fs;
- global M;
- global Nc;
- global Fsep;
- global phase_tx;
- global freq;
- global fbb_rect;
- global fbb_phase_tx;
+function [tx_fdm fdmdv] = fdm_upconvert(fdmdv, tx_filt)
+ Fs = fdmdv.Fs;
+ M = fdmdv.M;
+ Nc = fdmdv.Nc;
+ Fsep = fdmdv.Fsep;
+ phase_tx = fdmdv.phase_tx;
+ freq = fdmdv.freq;
+ fbb_rect = fdmdv.fbb_rect;
+ fbb_phase_tx = fdmdv.fbb_phase_tx;
tx_fdm = zeros(1,M);
- % Nc/2 tones below zero
+ % Nc+1 tones
for c=1:Nc+1
for i=1:M
mag = abs(fbb_phase_tx);
fbb_phase_tx /= mag;
+ fdmdv.fbb_phase_tx = fbb_phase_tx;
+ fdmdv.phase_tx = phase_tx;
endfunction
% [ ] feedback to correct out freq offset est
% [ ] fading channel
-rand('state',1);
-randn('state',1);
graphics_toolkit ("gnuplot");
cohpsk;
+fdmdv;
autotest;
+rand('state',1);
+randn('state',1);
+
n = 2000;
frames = 35;
framesize = 160;
sim_in.framesize = 160;
sim_in.ldpc_code = 0;
sim_in.ldpc_code_rate = 1;
-sim_in.Nc = 4;
+sim_in.Nc = Nc = 4;
sim_in.Rs = 50;
sim_in.Ns = 4;
sim_in.Np = 2;
rx_bits_log = [];
noise_log = [];
nerr_log = [];
+tx_baseband_log = [];
+tx_fdm_log = [];
phase = 1;
freq = exp(j*2*pi*foff/sim_in.Rs);
Nerrs = Tbits = 0;
+fdmdv.Fs = 8000;
+fdmdv.Nc = Nc-1;
+fdmdv.M = Fs/Rs;
+fdmdv.tx_filter_memory = zeros(fdmdv.Nc+1, Nfilter);
+fdmdv.Nfilter = Nfilter;
+fdmdv.gt_alpha5_root = gt_alpha5_root;
+fdmdv.Fsep = 75;
+fdmdv.phase_tx = exp(j*2*pi*(0:Nc)/(Nc+1));
+freq_hz = Fsep*( -Nc/2 - 0.5 + (1:Nc) );
+fdmdv.freq = exp(j*2*pi*freq_hz/Fs);
+Fcentre = 1500;
+fdmdv.fbb_rect = exp(j*2*pi*Fcentre/Fs);
+fdmdv.fbb_phase_tx = 1;
+
for i=1:frames
tx_bits = tx_bits_coh(ptx_bits_coh:ptx_bits_coh+framesize-1);
ptx_bits_coh += framesize;
[tx_symb tx_bits prev_tx_sym] = bits_to_qpsk_symbols(sim_in, tx_bits, [], []);
tx_symb_log = [tx_symb_log; tx_symb];
+ for r=1:sim_in.Nsymbrowpilot
+ [tx_baseband fdmdv] = tx_filter(fdmdv, rot90(tx_symb(r,:),1));
+ tx_baseband_log = [tx_baseband_log tx_baseband];
+ [tx_fdm fdmdv] = fdm_upconvert(fdmdv, tx_baseband);
+ tx_fdm_log = [tx_fdm_log tx_fdm];
+ end
+
noise = sqrt(variance*0.5)*(randn(sim_in.Nsymbrowpilot,sim_in.Nc) + j*randn(sim_in.Nsymbrowpilot,sim_in.Nc));
noise_log = [noise_log; noise];