global gt_alpha5_root;
gt_alpha5_root = gen_rn_coeffs(alpha, T, Rs, Nsym, M);
+% rx decimation filter
+
+global Nrxdec;
+ Nrxdec=31;
+global rxec;
+ rxdec = fir1(Nrxdec, 0.25);
+if 0
+ % tmp code to plot freq resp. 20dB attn of any aliases should be fine
+ % not real sensitive to in-band attn, e.g. outer tones a dB down should be OK
+ % in terms of BER
+ figure(1)
+ [h,f]=freqz(rxdec,1,4000);
+ hdB=20*log10(abs(h));
+ plot(hdB(1:1200))
+ grid
+end
+
% Converts gray code to natural binary
global m4_gray_to_binary = [
global Fsep;
global phase_tx;
global freq;
+ global fbb_rect;
+ global fbb_phase_tx;
tx_fdm = zeros(1,M);
- % Nc/2 tones below centre freq
+ % Nc/2 tones below zero
for c=1:Nc/2
for i=1:M
end
end
- % Nc/2 tones above centre freq
+ % Nc/2 tones above zero
for c=Nc/2+1:Nc
for i=1:M
tx_fdm(i) = tx_fdm(i) + pilot(i);
end
+ % shift up to carrier freq
+
+ for i=1:M
+ fbb_phase_tx *= fbb_rect;
+ tx_fdm(i) = tx_fdm(i) * fbb_phase_tx;
+ end
+
% Scale such that total Carrier power C of real(tx_fdm) = Nc. This
% excludes the power of the pilot tone.
% We return the complex (single sided) signal to make frequency
tx_fdm = 2*tx_fdm;
- % normalise digital oscilators as the magnitude can drift over time
+ % normalise digital oscillators as the magnitude can drift over time
for c=1:Nc+1
mag = abs(phase_tx(c));
fclose(f);
endfunction
+
+% Saves rx decimation filter coeffs to a text file in the form of a C array
+
+function rxdec_file(filename)
+ global rxdec;
+ global Nrxdec;
+
+ f=fopen(filename,"wt");
+ fprintf(f,"/* Generated by rxdec_file() Octave function */\n\n");
+ fprintf(f,"const float rxdec[]={\n");
+ for m=1:Nfilter-1
+ fprintf(f," %g,\n",rxdec(m));
+ endfor
+ fprintf(f," %g\n};\n",rxdec(Nrxdecr));
+ fclose(f);
+endfunction
+
function pilot_coeff_file(filename)
global pilot_coeff;
global Npilotcoeff;
global freq_pol;
freq_pol = zeros(Nc+1,1);
for c=1:Nc/2
- carrier_freq = (-Nc/2 - 1 + c)*Fsep + Fcentre;
+ %carrier_freq = (-Nc/2 - 1 + c)*Fsep + Fcentre;
+ carrier_freq = (-Nc/2 - 1 + c)*Fsep;
freq_pol(c) = 2*pi*carrier_freq/Fs;
freq(c) = exp(j*freq_pol(c));
end
for c=Nc/2+1:Nc
- carrier_freq = (-Nc/2 + c)*Fsep + Fcentre;
+ %carrier_freq = (-Nc/2 + c)*Fsep + Fcentre;
+ carrier_freq = (-Nc/2 + c)*Fsep;
freq_pol(c) = 2*pi*carrier_freq/Fs;
freq(c) = exp(j*freq_pol(c));
end
-freq_pol(c) = 2*pi*Fcentre/Fs;
-freq(Nc+1) = exp(j*freq_pol(c));
+%freq_pol(Nc+1) = 2*pi*Fcentre/Fs;
+freq_pol(Nc+1) = 2*pi*0/Fs;
+freq(Nc+1) = exp(j*freq_pol(Nc+1));
+
+global fbb_rect;
+ fbb_rect = exp(j*2*pi*Fcentre/Fs);
+global fbb_phase_tx;
+ fbb_phase_tx = 1;
+global fbb_phase_rx;
+ fbb_phase_rx = 1;
% 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
% Simulation Parameters --------------------------------------
-frames = 100;
-EbNo_dB = 7.3;
+frames = 20;
+EbNo_dB = 73;
Foff_hz = -100;
modulation = 'dqpsk';
hpa_clip = 150;
% Demodulator
% -------------------
+ % shift down to complex baseband
+
+ for i=1:M
+ fbb_phase_rx = fbb_phase_rx*fbb_rect';
+ rx_fdm(i) = rx_fdm(i)*fbb_phase_rx;
+ end
+
% frequency offset estimation and correction, need to call rx_est_freq_offset even in sync
% mode to keep states updated
rx_fdm(i) = rx_fdm(i)*foff_phase;
end
-if 1
- % more memory efficient but more complex
+ % LP filter
+ % Decimate to rate M/4
+
rx_filt = down_convert_and_rx_filter(rx_fdm, M);
-else
- rx_baseband = fdm_downconvert(rx_fdm, M);
- rx_baseband_log = [rx_baseband_log rx_baseband];
- rx_filt = rx_filter(rx_baseband, M);
-end
[rx_symbols rx_timing] = rx_est_timing(rx_filt, M);
rx_timing_log = [rx_timing_log rx_timing];