From a4b48182dbc993608151dd3ef626e335e8e7b7ce Mon Sep 17 00:00:00 2001 From: drowe67 Date: Wed, 3 May 2017 00:40:36 +0000 Subject: [PATCH] added AWGN and HF channel simulation, usual confusion with real signals, SNR est and meas. How rx is syncing up OK git-svn-id: https://svn.code.sf.net/p/freetel/code@3118 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/octave/ofdm_tx.m | 60 +++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/codec2-dev/octave/ofdm_tx.m b/codec2-dev/octave/ofdm_tx.m index 57b32de1..903c7c8d 100644 --- a/codec2-dev/octave/ofdm_tx.m +++ b/codec2-dev/octave/ofdm_tx.m @@ -5,7 +5,7 @@ % optional channel simulation. -function ofdm_tx(filename, Nsec) +function ofdm_tx(filename, Nsec, EbNodB=100, channel='awgn', freq_offset_Hz=0) ofdm_lib; Ts = 0.018; Tcp = 0.002; Rs = 1/Ts; bps = 2; Nc = 16; Ns = 8; states = ofdm_init(bps, Rs, Tcp, Ns, Nc); @@ -24,7 +24,63 @@ function ofdm_tx(filename, Nsec) for f=1:Nframes tx = [tx ofdm_mod(states, tx_bits)]; end + Nsam = length(tx); + + % channel simulation + + EbNo = bps * (10 .^ (EbNodB/10)); + variance = 1/(M*EbNo/2); + woffset = 2*pi*freq_offset_Hz/Fs; + + % SNR calculation is probably a bit off or confused, need to compare + % to cohpsk_frame_design.ods and make sure I've got it right. PLus + % 3 is used as we are dealing with real channels because mumble + % mumble not understood very well mumble magic number. + + SNRdB = EbNodB + 10*log10(bps*Rs*Nc/Fs) + 3; + printf("EbNo: %3.1f SNR(3k): %3.1f foff: %3.1f\n", EbNodB, SNRdB, freq_offset_Hz); + + % set up HF model --------------------------------------------------------------- + + if strcmp(channel, 'hf') + + % some typical values, or replace with user supplied + + dopplerSpreadHz = 1.0; path_delay_ms = 1; + + path_delay_samples = path_delay_ms*Fs/1000; + printf("Doppler Spread: %3.2f Hz Path Delay: %3.2f ms %d samples\n", dopplerSpreadHz, path_delay_ms, path_delay_samples); + + % generate same fading pattern for every run + + randn('seed',1); + + spread1 = doppler_spread(dopplerSpreadHz, Fs, (Nsec*(M+Ncp)/M+0.2)*Fs); + spread2 = doppler_spread(dopplerSpreadHz, Fs, (Nsec*(M+Ncp)/M+0.2)*Fs); + + % sometimes doppler_spread() doesn't return exactly the number of samples we need + + assert(length(spread1) >= Nsam, "not enough doppler spreading samples"); + assert(length(spread2) >= Nsam, "not enough doppler spreading samples"); + + hf_gain = 1.0/sqrt(var(spread1)+var(spread2)); + end + + rx = tx; + + if strcmp(channel, 'hf') + rx = hf_gain * tx(1:Nsam) .* spread1(1:Nsam); + rx += hf_gain * [zeros(1,path_delay_samples) tx(1:Nsam-path_delay_samples)] .* spread2(1:Nsam); + end + + rx = rx .* exp(j*woffset*(1:Nsam)); + + % note variance/2 as we are using real() operator + + noise = sqrt(variance/2)*(0.5*randn(1,Nsam) + j*0.5*randn(1,Nsam)); + rx += noise; + 10*log10(var(tx)/var(noise)) Ascale = 4E5; - ftx=fopen(filename,"wb"); fwrite(ftx, Ascale*real(tx), "short"); fclose(ftx); + frx=fopen(filename,"wb"); fwrite(frx, Ascale*real(rx), "short"); fclose(frx); endfunction -- 2.25.1