ssb filtering feature and bcleaned up rx logs
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 18 May 2017 00:35:23 +0000 (00:35 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 18 May 2017 00:35:23 +0000 (00:35 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@3139 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/ofdm_rx.m
codec2-dev/octave/ofdm_tx.m

index c99b8b0cfe1a5800fdc1efba463a855f9f86f54e..1f4e91d5ee0bc076936cd81c50a70d5909527cdd 100644 (file)
@@ -14,6 +14,7 @@
 function ofdm_rx(filename, interleave_frames = 1)
   ofdm_lib;
   ldpc;
+  gp_interleaver;
   more off;
 
   % init modem
@@ -37,7 +38,7 @@ function ofdm_rx(filename, interleave_frames = 1)
 
   % load real samples from file
 
-  Ascale= 2E5;
+  Ascale= 2E5*1.1491;
   frx=fopen(filename,"rb"); rx = 2*fread(frx, Inf, "short")/4E5; fclose(frx);
   Nsam = length(rx); Nframes = floor(Nsam/Nsamperframe);
   prx = 1;
@@ -81,6 +82,7 @@ function ofdm_rx(filename, interleave_frames = 1)
   phase_est_pilot_log = [];
   Terrs = Tbits = Terrs_coded = Tbits_coded = Tpackets = Tpacketerrs = 0;
   Nbitspervocframe = 28;
+  Nerrs_coded_log = Nerrs_log = [];
 
   % 'prime' rx buf to get correct coarse timing (for now)
 
@@ -167,6 +169,16 @@ function ofdm_rx(filename, interleave_frames = 1)
       states.foff_est_hz = foff_est;
     end
     
+    if strcmp(state,'synced')
+      % we are in sync so log states
+
+      rx_np_log = [rx_np_log arx_np];
+      timing_est_log = [timing_est_log states.timing_est];
+      delta_t_log = [delta_t_log states.delta_t];
+      foff_est_hz_log = [foff_est_hz_log states.foff_est_hz];
+      phase_est_pilot_log = [phase_est_pilot_log; aphase_est_pilot_log];
+    end
+
     if strcmp(state,'synced') && (frame_count == interleave_frames)
 
       % de-interleave QPSK symbols
@@ -187,29 +199,23 @@ function ofdm_rx(filename, interleave_frames = 1)
       Nerrs_coded = sum(errors_coded);
       Terrs_coded += Nerrs_coded;
       Tbits_coded += code_param.data_bits_per_frame*interleave_frames;
-      Nerrs_coded_log(f) = Nerrs_coded;
 
       printf("  Nerrs_coded: %d\n", Nerrs_coded);
 
-      % we are in sync so log states and bit/packet error stats
-
-      rx_np_log = [rx_np_log arx_np];
-      timing_est_log = [timing_est_log states.timing_est];
-      delta_t_log = [delta_t_log states.delta_t];
-      foff_est_hz_log = [foff_est_hz_log states.foff_est_hz];
-      phase_est_pilot_log = [phase_est_pilot_log; aphase_est_pilot_log];
-
-      % measure uncoded bit errors
+      % measure uncoded bit errors per modem frame
 
       rx_bits_raw = [];
       for s=1:Nsymbolsperinterleavedframe
         rx_bits_raw = [rx_bits_raw qpsk_demod(rx_np(s))];
       end
-      errors = xor(tx_bits_raw, rx_bits_raw);
-      Nerrs = sum(errors);
-      Terrs += Nerrs;
-      Nerrs_log(f) = Nerrs;
-      Tbits += code_param.code_bits_per_frame*interleave_frames;
+      for ff=1:interleave_frames
+        st = (ff-1)*Nbitsperframe+1; en = st+Nbitsperframe-1;
+        errors = xor(tx_bits_raw(st:en), rx_bits_raw(st:en));
+        Nerrs = sum(errors);
+        Terrs += Nerrs;
+        Nerrs_log = [Nerrs_log Nerrs];
+        Tbits += Nbitsperframe;
+      end
 
       % measure packet errors based on Codec 2 packet size
 
@@ -222,6 +228,7 @@ function ofdm_rx(filename, interleave_frames = 1)
           Tpacketerrs++;
         end
         Tpackets++;
+        Nerrs_coded_log = [Nerrs_coded_log Nvocpacketerrs];
       end
 
       frame_count = 0;
@@ -258,8 +265,9 @@ function ofdm_rx(filename, interleave_frames = 1)
 
   figure(5); clf;
   subplot(211)
-  title('Nerrs Log')
   stem(Nerrs_log);
+  title('Uncoded errrors/modem frame')
   subplot(212)
   stem(Nerrs_coded_log);
+  title('Coded errrors/vocoder frame')
 endfunction
index d706a491a745594e798eec8a200c78abb6df7b94..e057998faeb99a28a8805e505ac79995071557cd 100644 (file)
@@ -4,6 +4,19 @@
 % File based ofdm tx.  Generate a file of ofdm samples, inclduing
 % optional channel simulation.
 
+#{
+  Examples:
+  i) 4 frame interleaver, 10 seconds, AWGN channel at Eb/No=3dB
+
+    octave:4> ofdm_tx('awgn_ebno_3dB_700d.raw',4, 10,3);
+
+  ii) 4 frame interleaver, 10 seconds, HF channel at Eb/No=6dB
+
+    ofdm_tx('hf_ebno_6dB_700d.raw', 4, 10, 6, 'hf');
+#}
+
+
 #{
   TODO: 
     [ ] measure and report raw and coded BER
@@ -76,12 +89,28 @@ function ofdm_tx(filename, Nsec, interleave_frames = 1, EbNodB=100, channel='awg
   end
 
   % not very pretty way to process analog signals with exactly the same channel
+  % todo: work out a cleaner way
+
+  analog_hack = 0; rx_filter = 0;
+  if analog_hack || rx_filter
+
+    % simulated SSB tx filter
+
+    [b, a] = cheby1(4, 3, [600, 2600]/(Fs/2));
+    h = freqz(b,a,(600:2600)/(Fs/(2*pi)));
+    filt_gain = (2600-600)/sum(abs(h) .^ 2);   % ensures power after filter == before filter
+  end
 
-  analog_hack = 0;
   if analog_hack
+    % load analog signal and convert to complex
+
     s = load_raw('../raw/ve9qrp_10s.raw')';
     tx = hilbert(s);
 
+    % ssb tx filter
+
+    tx = filter(b,a,sqrt(filt_gain)*tx);
+
     % normalise power to same as ofdm tx
 
     nom_tx_pwr = 2/(Ns*(M*M)) + Nc/(M*M);
@@ -147,6 +176,14 @@ function ofdm_tx(filename, Nsec, interleave_frames = 1, EbNodB=100, channel='awg
   rx = real(rx) + noise;
   printf("measured SNR: %3.2f dB\n", 10*log10(var(real(tx))/var(noise))+10*log10(4000) - 10*log10(3000));
 
-  Ascale = 2E5;
+  if rx_filter
+    % ssb rx filter
+    rx = filter(b,a,sqrt(filt_gain)*rx);
+  end
+
+  % adjusted by experiment to match rms power of early test signals
+
+  Ascale = 2E5*1.1491;
+
   frx=fopen(filename,"wb"); fwrite(frx, Ascale*rx, "short"); fclose(frx);
 endfunction