diff options
Diffstat (limited to 'octave/fsk_v_afsk.m')
| -rw-r--r-- | octave/fsk_v_afsk.m | 232 |
1 files changed, 0 insertions, 232 deletions
diff --git a/octave/fsk_v_afsk.m b/octave/fsk_v_afsk.m deleted file mode 100644 index a692c18..0000000 --- a/octave/fsk_v_afsk.m +++ /dev/null @@ -1,232 +0,0 @@ -% fsk.m -% David Rowe Nov 2014 - -% Ideal non-coherent FSK and AFSK-over-analog-FM simulation. Can draw -% Eb/No curves or run single point simulations - -rand('state',1); -randn('state',1); -graphics_toolkit ("gnuplot"); - -fm; - -function sim_out = fsk_ber_test(sim_in) - Fs = 96000; - fmark = sim_in.fmark; - fspace = sim_in.fspace; - Rs = sim_in.Rs; - Ts = Fs/Rs; - emphasis = 50E-6; - verbose = sim_in.verbose; - - nsym = sim_in.nsym; - nsam = nsym*Ts; - EbNodB = sim_in.EbNodB; - - fm = sim_in.fm; - - if fm - fm_states.pre_emp = 0; - fm_states.de_emp = 0; - fm_states.Ts = Ts; - fm_states.Fs = Fs; - fm_states.fc = Fs/4; - fm_states.fm_max = 3E3; - fm_states.fd = 5E3; - fm_states.output_filter = 1; - fm_states = analog_fm_init(fm_states); - end - - % simulate over a range of Eb/No values - - for ne = 1:length(EbNodB) - Nerrs = Terrs = Tbits = 0; - - % randn() generates noise spread across the entire Fs bandwidth. - % The power (aka variance) of this noise is N = NoFs, or No = - % N/Fs. The power of each bit is C=1, so the energy of each bit - % is Eb=1/Rs. We want to find N as a function of Eb/No, so: - - % Eb/No = (1/Rs)/(N/Fs) = Fs/(RsN) - % N = Fs/(Rs(Eb/No)) - - aEbNodB = EbNodB(ne); - EbNo = 10^(aEbNodB/10); - variance = Fs/(Rs*EbNo); - - % Modulator ------------------------------- - - tx_bits = round(rand(1, nsym)); - tx = zeros(1,nsam); - tx_phase = 0; - - for i=1:nsym - for k=1:Ts - if tx_bits(i) == 1 - tx_phase += 2*pi*fmark/Fs; - else - tx_phase += 2*pi*fspace/Fs; - end - tx_phase = tx_phase - floor(tx_phase/(2*pi))*2*pi; - tx((i-1)*Ts+k) = exp(j*tx_phase); - end - end - - % Optional AFSK over FM modulator - - if sim_in.fm - % FM mod takes real input; +/- 1 for correct deviation - tx = analog_fm_mod(fm_states, real(tx)); - end - - % Channel --------------------------------- - - % We use complex (single sided) channel simulation, as it's convenient - % for the FM simulation. - - noise = sqrt(variance/2)*(randn(1,nsam) + j*randn(1,nsam)); - rx = tx + noise; - if verbose > 1 - printf("EbNo: %f Eb: %f var No: %f EbNo (meas): %f\n", - EbNo, var(tx)*Ts/Fs, var(noise)/Fs, (var(tx)*Ts/Fs)/(var(noise)/Fs)); - end - save fsk tx_bits rx - - % Optional AFSK over FM demodulator - - if sim_in.fm - % scaling factor for convenience to match pure FSK - rx_bb = 2*analog_fm_demod(fm_states, rx); - else - rx_bb = rx; - end - - % Demodulator ----------------------------- - - % non-coherent FSK demod - - mark_dc = rx_bb .* exp(-j*(0:nsam-1)*2*pi*fmark/Fs); - space_dc = rx_bb .* exp(-j*(0:nsam-1)*2*pi*fspace/Fs); - - rx_bits = zeros(1, nsym); - for i=1:nsym - st = (i-1)*Ts+1; - en = st+Ts-1; - mark_int(i) = sum(mark_dc(st:en)); - space_int(i) = sum(space_dc(st:en)); - rx_bits(i) = abs(mark_int(i)) > abs(space_int(i)); - end - - if fm - d = fm_states.nsym_delay; - error_positions = xor(rx_bits(1+d:nsym), tx_bits(1:(nsym-d))); - else - error_positions = xor(rx_bits, tx_bits); - end - Nerrs = sum(error_positions); - Terrs += Nerrs; - Tbits += length(error_positions); - - TERvec(ne) = Terrs; - BERvec(ne) = Terrs/Tbits; - - if verbose > 1 - figure(2) - clf - Rx = 10*log10(abs(fft(rx))); - plot(Rx(1:Fs/2)); - axis([1 Fs/2 0 50]); - - figure(3) - clf; - subplot(211) - plot(real(rx_bb(1:Ts*20))) - subplot(212) - Rx_bb = 10*log10(abs(fft(rx_bb))); - plot(Rx_bb(1:3000)); - axis([1 3000 0 50]); - - figure(4); - subplot(211) - stem(abs(mark_int(1:100))); - subplot(212) - stem(abs(space_int(1:100))); - end - - if verbose - printf("EbNo (db): %3.2f Terrs: %d BER: %3.2f \n", aEbNodB, Terrs, Terrs/Tbits); - end - end - - sim_out.TERvec = TERvec; - sim_out.BERvec = BERvec; -endfunction - - -function run_fsk_curves - sim_in.fmark = 1200; - sim_in.fspace = 2200; - sim_in.Rs = 1200; - sim_in.nsym = 12000; - sim_in.EbNodB = 0:2:20; - sim_in.fm = 0; - sim_in.verbose = 1; - - EbNo = 10 .^ (sim_in.EbNodB/10); - fsk_theory.BERvec = 0.5*exp(-EbNo/2); % non-coherent BFSK demod - fsk_sim = fsk_ber_test(sim_in); - - sim_in.fm = 1; - fsk_fm_sim = fsk_ber_test(sim_in); - - % BER v Eb/No curves - - figure(1); - clf; - semilogy(sim_in.EbNodB, fsk_theory.BERvec,'r;FSK theory;') - hold on; - semilogy(sim_in.EbNodB, fsk_sim.BERvec,'g;FSK sim;') - semilogy(sim_in.EbNodB, fsk_fm_sim.BERvec,'b;FSK over FM sim;') - hold off; - grid("minor"); - axis([min(sim_in.EbNodB) max(sim_in.EbNodB) 1E-4 1]) - legend("boxoff"); - xlabel("Eb/No (dB)"); - ylabel("Bit Error Rate (BER)") - - % BER v C/No (1 Hz noise BW and Eb=C/Rs=1/Rs) - % Eb/No = (C/Rs)/(1/(N/B)) - % C/N = (Eb/No)*(Rs/B) - - RsOnB_dB = 10*log10(sim_in.Rs/1); - figure(2); - clf; - semilogy(sim_in.EbNodB+RsOnB_dB, fsk_theory.BERvec,'r;FSK theory;') - hold on; - semilogy(sim_in.EbNodB+RsOnB_dB, fsk_sim.BERvec,'g;FSK sim;') - semilogy(sim_in.EbNodB+RsOnB_dB, fsk_fm_sim.BERvec,'b;FSK over FM sim;') - hold off; - grid("minor"); - axis([min(sim_in.EbNodB+RsOnB_dB) max(sim_in.EbNodB+RsOnB_dB) 1E-4 1]) - legend("boxoff"); - xlabel("C/No for Rs=1200 bit/s and 1 Hz noise bandwidth (dB)"); - ylabel("Bit Error Rate (BER)") -end - -function run_fsk_single - sim_in.fmark = 1000; - sim_in.fspace = 2000; - sim_in.Rs = 1000; - sim_in.nsym = 2000; - sim_in.EbNodB = 7; - sim_in.fm = 0; - sim_in.verbose = 1; - - fsk_sim = fsk_ber_test(sim_in); -endfunction - -# choose one of these functions below - -run_fsk_curves -#run_fsk_single - |
