aboutsummaryrefslogtreecommitdiff
path: root/octave/fdmdv_demod_c.m
blob: 0bf0a1ed7072e2e38b26aff4581517026b03e90a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
% fdmdv_demod_c.m
%
% Plots Octave dump file information from C FDMDV demodulator program,
% to give a similar set of plots to fdmdv_demod.m.  Useful for off
% line analysis of demod performance.
%
% Copyright David Rowe 2012
% This program is distributed under the terms of the GNU General Public License 
% Version 2
%

function fdmdv_demod_c(dumpfilename, bits)
  pkg load signal; 
  fdmdv; % include modem code
  f = fdmdv_init;
  Nc = f.Nc; Nb = f.Nb; Rs = f.Rs; M = f.M; Fs = f.Fs;
  
  frames = bits/(Nc*Nb);

  load(dumpfilename);

  % BER stats

  total_bit_errors = 0;
  total_bits = 0;
  bit_errors_log = [];
  sync_log = [];
  test_frame_sync_log = [];
  test_frame_sync_state = 0;

  % Run thru received bits to look for test pattern

  bits_per_frame = Nc*Nb;

  for fr=1:frames

    rx_bits = rx_bits_log_c((fr-1)*bits_per_frame+1:fr*bits_per_frame);

    % count bit errors if we find a test frame

    [test_frame_sync bit_errors error_pattern f] = put_test_bits(f, rx_bits);
    if (test_frame_sync == 1)
      total_bit_errors = total_bit_errors + bit_errors;
      total_bits = total_bits + f.Ntest_bits;
      bit_errors_log = [bit_errors_log bit_errors/f.Ntest_bits];
    else
      bit_errors_log = [bit_errors_log 0];
    end

    % test frame sync state machine, just for more informative plots
    
    next_test_frame_sync_state = test_frame_sync_state;
    if (test_frame_sync_state == 0)
      if (test_frame_sync == 1)      
        next_test_frame_sync_state = 1;
	test_frame_count = 0;
      end
    end

    if (test_frame_sync_state == 1)
      % we only expect another test_frame_sync pulse every 4 symbols
      test_frame_count++;
      if (test_frame_count == 4)
        test_frame_count = 0;
        if ((test_frame_sync == 0))      
          next_test_frame_sync_state = 0;
        end
      end
    end
    test_frame_sync_state = next_test_frame_sync_state;
    test_frame_sync_log = [test_frame_sync_log test_frame_sync_state];
  end

  ber = total_bit_errors / total_bits;
  printf("%d bits  %d errors  BER: %1.4f\n",total_bits, total_bit_errors, ber);

  % ---------------------------------------------------------------------
  % Plots
  % ---------------------------------------------------------------------

  xt = (1:frames)/Rs;
  secs = frames/Rs;

  figure(1)
  clf;
  plot(real(rx_symbols_log_c(1:Nc+1,15:frames)),imag(rx_symbols_log_c(1:Nc+1,15:frames)),'+')
  %plot(real(rx_symbols_log_c(Nc+1,15:frames)),imag(rx_symbols_log_c(Nc+1,15:frames)),'+')
  axis([-2 2 -2 2]);
  title('Scatter Diagram');

  figure(2)
  clf;
  subplot(211)
  plot(xt, rx_timing_log_c(1:frames))
  title('timing offset (samples)');
  subplot(212)
  plot(xt, foff_log_c(1:frames), '-;freq offset;')
  hold on;
  plot(xt, sync_log_c(1:frames)*75, 'r;course-fine;');
  hold off;
  title('Freq offset (Hz)');
  grid

  figure(3)
  clf;
  subplot(211)
  b = M*frames;
  xt1 = (1:b)/Fs;
  plot(xt1, rx_fdm_log_c(1:b));
  title('Rx FDM Signal');
  subplot(212);
  plot_specgram(rx_fdm_log_c(1:b), 8000);
  title('FDM Rx Spectrogram');

  figure(4)
  clf;
  subplot(311)
  stem(xt, sync_bit_log_c(1:frames))
  axis([0 secs 0 1.5]);
  title('BPSK Sync')
  subplot(312)
  stem(xt, bit_errors_log);
  title('Bit Errors for test frames')
  subplot(313)
  plot(xt, test_frame_sync_log);
  axis([0 secs 0 1.5]);
  title('Test Frame Sync')

  figure(5)
  clf;
  plot(xt, snr_est_log_c(1:frames));
  title('SNR Estimates')

endfunction