1% fsk_lib_demo.m 2% Uncoded FSK modem demo 3 4fsk_lib; 5 6% set up waveform 7function [states M bits_per_frame] = modem_init(Rs,Fs,df) 8 M = 4; 9 states = fsk_init(Fs,Rs,M,P=8,nsym=100); 10 bits_per_frame = 512; 11 states.tx_real = 0; % complex signal 12 states.tx_tone_separation = 250; 13 states.ftx = -2.5*states.tx_tone_separation + states.tx_tone_separation*(1:M); 14 states.fest_fmin = -Fs/2; 15 states.fest_fmax = +Fs/2; 16 states.fest_min_spacing = Rs/2; 17 states.df = df; 18 19 states.ber_valid_thresh = 0.1; 20 states.ber_invalid_thresh = 0.2; 21end 22 23% Run a complete modem (freq and timing estimators running) at a 24% single Eb/No point. At low Eb/No the estimators occasionally fall 25% over so we get complete junk, we consider that case a packet error 26% and exclude it from the BER estimation. 27 28function [states ber per] = modem_run_test(EbNodB = 10, num_frames=10, Fs=8000, Rs=100, df=0, plots=0) 29 randn('state',1); rand('state',1); 30 [states M bits_per_frame] = modem_init(Rs, Fs, df); 31 N = states.N; 32 if plots; states.verbose = 0x4; end 33 EbNo = 10^(EbNodB/10); 34 variance = states.Fs/(states.Rs*EbNo*states.bitspersymbol); 35 36 nbits = bits_per_frame*num_frames; 37 test_frame = round(rand(1,bits_per_frame)); tx_bits = []; 38 for f=1:num_frames 39 tx_bits = [tx_bits test_frame]; 40 end 41 42 tx = fsk_mod(states, tx_bits); 43 noise = sqrt(variance/2)*randn(length(tx),1) + j*sqrt(variance/2)*randn(length(tx),1); 44 rx = tx + noise; 45 46 run_frames = floor(length(rx)/N)-1; 47 st = 1; f_log = []; f_log2 = []; rx_bits = []; rx_bits2 = []; 48 for f=1:run_frames 49 50 % extract nin samples from input stream 51 nin = states.nin; 52 en = st + states.nin - 1; 53 54 % due to nin variations it's possible to overrun buffer 55 if en < length(rx) 56 sf = rx(st:en); 57 states = est_freq(states, sf, states.M); states.f = states.f2; 58 [arx_bits states] = fsk_demod(states, sf); 59 rx_bits = [rx_bits arx_bits]; 60 f_log = [f_log; states.f]; 61 st += nin; 62 end 63 end 64 65 num_frames=floor(length(rx_bits)/bits_per_frame); 66 log_nerrs = []; num_frames_rx = 0; 67 for f=1:num_frames-1 68 st = (f-1)*bits_per_frame + 1; en = (f+1)*bits_per_frame; 69 states = ber_counter(states, test_frame, rx_bits(st:en)); 70 log_nerrs = [log_nerrs states.nerr]; 71 if states.ber_state; num_frames_rx++; end 72 end 73 if states.Terrs 74 printf("Fs: %d Rs: %d df % 3.2f EbNo: %4.2f ftx: %3d frx: %3d nbits: %4d nerrs: %3d ber: %4.3f\n", 75 Fs, Rs, df, EbNodB, num_frames, num_frames_rx, states.Tbits, states.Terrs, states.Terrs/states.Tbits); 76 ber = states.Terrs/states.Tbits; 77 else 78 ber = 0.5; 79 end 80 81 if plots 82 figure(1); clf; 83 ideal=ones(length(f_log),1)*states.ftx; 84 plot((1:length(f_log)),ideal(:,1),'bk;ideal;') 85 hold on; plot((1:length(f_log)),ideal(:,2:states.M),'bk'); hold off; 86 hold on; 87 plot(f_log(:,1), 'linewidth', 2, 'b;peak;'); 88 plot(f_log(:,2:states.M), 'linewidth', 2, 'b'); 89 hold off; 90 xlabel('Time (frames)'); ylabel('Frequency (Hz)'); 91 figure(2); clf; plot(log_nerrs); title('Errors per frame'); 92 end 93 94 per = 1 - num_frames_rx/num_frames; 95end 96 97[states ber per] = modem_run_test(EbNodB=6); 98BER_theory=0.01579; % for Eb/No = 6dB 99if ber < 1.5*BER_theory 100 printf("PASS\n"); 101end 102