ldpc simulation working, but perf not that great in ccir poor 4dB channel
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 30 Jan 2014 04:28:56 +0000 (04:28 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 30 Jan 2014 04:28:56 +0000 (04:28 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1394 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/fdmdv.m
codec2-dev/octave/fdmdv_demod.m
codec2-dev/octave/ldpc.m
codec2-dev/octave/ldpcdec.m
codec2-dev/octave/ldpcenc.m
codec2-dev/octave/pl2.m

index a0b9b6a56a285a7043a2389eae28e965f6559a85..f64fe895b1e16d17348b523d83fd9ff990810976 100644 (file)
@@ -805,7 +805,9 @@ endfunction
 % then switch to a more robust tracking algorithm.  If we lose sync we switch
 % back to acquire mode for fast-requisition.
 
-function [track state bad_sync] = freq_state(sync_bit, state, bad_sync)
+function [entered_track track state bad_sync] = freq_state(sync_bit, state, bad_sync)
+
+  entered_track = 0;
 
   % acquire state, look for 6 symbol 010101 sequence from sync bit
 
@@ -845,6 +847,7 @@ function [track state bad_sync] = freq_state(sync_bit, state, bad_sync)
   end
   if state == 5
     if sync_bit == 1
+      entered_track = 1;
       next_state = 6;
       bad_sync = 0;
     else 
index 2fe42702d10a349017dbc83433820b01984fcd20..dc553127754c61e319dc02f4b39134f75069c55d 100644 (file)
@@ -52,6 +52,8 @@ function fdmdv_demod(rawfilename, nbits, NumCarriers, errorpatternfilename, symb
   track = 0;
   fest_state = 0;
   bad_sync = 0;
+  sync_track = 0;
+  entered_track_log = [];
 
   % spectrum states
 
@@ -93,7 +95,7 @@ function fdmdv_demod(rawfilename, nbits, NumCarriers, errorpatternfilename, symb
     [foff_coarse S1 S2] = rx_est_freq_offset(rx_fdm, pilot, prev_pilot, nin);
     
     if track == 0
-      foff  = foff_coarse;
+      foff  = foff_coarse = 0;
     end
     foff_log = [ foff_log foff ];
     foff_rect = exp(j*2*pi*foff/Fs);
@@ -128,8 +130,17 @@ function fdmdv_demod(rawfilename, nbits, NumCarriers, errorpatternfilename, symb
 
     % optionally save output symbols 
 
-    if (nargin == 5) && (track == 1)
-      if sync == 1 
+    if (nargin == 5)
+
+      % this free runs, and is reset by an "entered sync" state
+
+      if (sync_track == 0)
+         sync_track = 1;
+      else
+         sync_track = 0; 
+      end
+
+      if (track == 1) && (sync_track == 1)
           dual_rx_symbols(Nc+1:2*Nc) = rx_symbols(1:Nc).*conj(prev_rx_symbols(1:Nc)./abs(prev_rx_symbols(1:Nc)));
           dual_rx_symbols_float32 = []; k = 1;
           for i=1:2*Nc
@@ -138,7 +149,7 @@ function fdmdv_demod(rawfilename, nbits, NumCarriers, errorpatternfilename, symb
           end
           fwrite(fm, dual_rx_symbols_float32, "float32");
           dual_rx_bits(Nc*Nb+1:2*Nc*Nb) = rx_bits;
-          dump_bits(dual_rx_bits);
+          %dump_bits(dual_rx_bits);
       else
           dual_rx_symbols(1:Nc) = rx_symbols(1:Nc).*conj(prev_rx_symbols(1:Nc)./abs(prev_rx_symbols(1:Nc)));
           dual_rx_bits(1:Nc*Nb) = rx_bits;
@@ -156,8 +167,12 @@ function fdmdv_demod(rawfilename, nbits, NumCarriers, errorpatternfilename, symb
 
     % freq est state machine
 
-    [track fest_state bad_sync] = freq_state(sync, fest_state, bad_sync);
+    [entered_track track fest_state bad_sync] = freq_state(sync, fest_state, bad_sync);
     track_log = [track_log track];
+    if (entered_track == 1)
+        sync_track = 1;
+    end
+    entered_track_log = [entered_track_log entered_track];
 
     % count bit errors if we find a test frame
 
@@ -196,6 +211,14 @@ function fdmdv_demod(rawfilename, nbits, NumCarriers, errorpatternfilename, symb
     test_frame_sync_log = [test_frame_sync_log test_frame_sync_state];
   end
  
+  if nargin == 5
+    fclose(fm);
+    etfilename = strcat(strtok(symbolfilename,"."),"_et.bin");
+    fet = fopen(etfilename, "wb");
+    fwrite(fet, entered_track_log, "short");
+    fclose(fet);
+  end
+
   % ---------------------------------------------------------------------
   % Print Stats
   % ---------------------------------------------------------------------
index 2e9cf125b72487792689e80bb9caf95e22684fc4..a8bbedbc921fc72e3c7a3e7833b459c5c0df7c4b 100644 (file)
@@ -1,15 +1,5 @@
 % ldpc.m\r
-% ldpc functions\r
-\r
-% LDPC demo;   Bill Cowley \r
-% Call the CML routines and simulate one set of SNRs.   See test_ldpc1.m\r
-%\r
-% sim_in the input parameter structure\r
-% sim_out contains BERs and other stats for each value of SNR\r
-% resfile is the result file\r
-%\r
-% 4/oct/2013:   edited to use the WiMax eIRA codes \r
-%               see 'help InitializeWiMaxLDPC' for parameter values \r
+% LDPC functions\r
 \r
 1;\r
 \r
@@ -42,7 +32,6 @@ function frameout = insert_uw(framein, uw)
     spacing = 2*lframein/luw;\r
 \r
     frameout = [];\r
-    mod_uw = [];\r
 \r
     pin = 1; pout = 1; puw = 1;\r
     while (luw)\r
@@ -51,7 +40,6 @@ function frameout = insert_uw(framein, uw)
         pin += spacing; \r
         pout += spacing;\r
         frameout(pout:pout+1) = uw(puw:puw+1);\r
-        mod_uw(pout:pout+1) = qpsk_mod(uw(puw:puw+1));\r
         puw += 2;\r
         pout += 2;\r
         luw -= 2;\r
@@ -80,6 +68,29 @@ function frameout = remove_uw(framein, lvd, luw)
 endfunction\r
 \r
 \r
+% removes a unique word from a frame of symbols.  The UW symbols are spread\r
+% throughout the input frame 1 symbol at a time.\r
+\r
+function framesymbolsout = remove_uw_symbols(framesymbolsin, ldatasymbols, luwsymbols)\r
+\r
+    spacing = ldatasymbols/luwsymbols;\r
+\r
+    framesymbolsout = [];\r
+\r
+    pin = 1; pout = 1;\r
+    while (luwsymbols)\r
+        %printf("pin %d pout %d luw %d  ", pin, pout, luwsymbols);\r
+        %printf("pin+spacing-1 %d ldatasymbols %d lframein: %d\n", pin+spacing-1, ldatasymbols, length(framesymbolsin));\r
+        framesymbolsout(pout:pout+spacing-1) = framesymbolsin(pin:pin+spacing-1);\r
+        pin  += spacing + 1; \r
+        pout += spacing;\r
+        luwsymbols--;\r
+    end\r
+\r
+endfunction\r
+\r
+\r
+\r
 % builds up a sparse QPSK modulated version version of the UW for use\r
 % in UW sync at the rx\r
 \r
@@ -166,3 +177,21 @@ function unpacked = unpackmsb(packed)
     end\r
 endfunction\r
 \r
+\r
+% symbol interleaver that acts on bits 2 at a time\r
+\r
+function y = interleave_bits(interleaver, x)\r
+    y =  zeros(1,length(x));\r
+    for i = 1:length(interleaver)\r
+        dst = interleaver(i);\r
+        y(2*(dst-1)+1:2*dst) = x(2*(i-1)+1:2*(i));\r
+    end\r
+endfunction\r
+\r
+% symbol de-interleaver\r
+\r
+function x = deinterleave_symbols(interleaver, y)\r
+    for i = 1:length(interleaver)\r
+        x(i) = y(interleaver(i));\r
+    end\r
+endfunction\r
index 6e261cd1cf5d490dfcbe81438d5d5b33ec14a984..91e89411d840cbf9d5fc4184573e0a1e02599fa8 100644 (file)
 % LDPC decoder test program, given a file of QPSK symbols (IQIQ floats), \r
 % performs frame sync, decodes, and measures BER.\r
 \r
-% Start CML library\r
+function ldpcdec(filename)\r
 \r
-currentdir = pwd;\r
-addpath '/home/david/tmp/cml/mat'    % assume the source files stored here\r
-cd /home/david/tmp/cml\r
-CmlStartup                           % note that this is not in the cml path!\r
-cd(currentdir)\r
+  % Start CML library\r
 \r
-% Our LDPC library\r
+  currentdir = pwd;\r
+  addpath '/home/david/tmp/cml/mat'    % assume the source files stored here\r
+  cd /home/david/tmp/cml\r
+  CmlStartup                           % note that this is not in the cml path!\r
+  cd(currentdir)\r
 \r
-ldpc;\r
+  % Our LDPC library\r
 \r
-% Start simulation\r
+  ldpc;\r
 \r
-rand('state',1);\r
+  % Start simulation\r
 \r
-rate = 3/4; \r
-framesize = 576;  \r
+  rand('state',1);\r
 \r
-mod_order = 4; \r
-modulation = 'QPSK';\r
-mapping = 'gray';\r
+  rate = 3/4; \r
+  framesize = 576;  \r
 \r
-demod_type = 0;\r
-decoder_type = 0;\r
-max_iterations = 100;\r
-EsNo = 10;\r
-Eprob = 0.0;\r
+  mod_order = 4; \r
+  modulation = 'QPSK';\r
+  mapping = 'gray';\r
 \r
-vocoderframesize = 52;\r
-nvocoderframes = 8;\r
-nbitspermodemframe = 72;\r
+  demod_type = 0;\r
+  decoder_type = 0;\r
+  max_iterations = 100;\r
+  EsNo = 4;\r
+  Eprob = 0.0;\r
 \r
-code_param = ldpc_init(rate, framesize, modulation, mod_order, mapping);\r
-code_param.code_bits_per_frame = 576;\r
+  nbitspervocoderframe = 52;\r
+  nvocoderframes = 8;\r
+  nbitspermodemframe = 72;\r
 \r
-data = [];\r
-r = []; \r
+  code_param = ldpc_init(rate, framesize, modulation, mod_order, mapping);\r
+  code_param.code_bits_per_frame = 576;\r
 \r
-Nframes = 100;\r
-uw = [1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0];\r
+  data = [];\r
+  r = []; \r
+  load interleaver.txt\r
+  interleaver = interleaver + 1;\r
 \r
-% repeat same simulated vocoder data to ease testing\r
+  Nframes = 100;\r
+  uw = [1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0];\r
 \r
-vd = round( rand( 1, vocoderframesize*nvocoderframes) );\r
+  % repeat same simulated vocoder data to ease testing\r
 \r
-% Decoder: Sync with LDPC frames, LDPC decode, strip off UW, measure BER -------\r
+  vd = round( rand( 1, nbitspervocoderframe*nvocoderframes) );\r
 \r
-fm=fopen("modcodeword.bin","rb");\r
+  % Decoder: Sync with LDPC frames, de-interleave, LDPC decode, strip off UW, measure BER -------\r
 \r
-mod_uw = build_mod_uw(uw, 2*length(vd)/length(uw));\r
+  mcwfilename = strcat(filename,"_modcodeword.bin");\r
+  fm=fopen(mcwfilename,"rb");\r
+  etfilename = strcat(filename,"_et.bin");\r
+  fet=fopen(etfilename ,"rb");\r
+  epfilename = strcat(filename,".err");\r
+  fep=fopen(epfilename ,"wb");\r
+  printf("Input QPSK symbols: %s\n", mcwfilename);\r
+  if (fet == -1)\r
+    printf("Input entered track file: none\n");\r
+  else\r
+    printf("Input entered track file: %s\n", etfilename);\r
+  end\r
+  printf("Output error pattern file: %s\n", epfilename);\r
 \r
-mod_codeword = zeros(1, code_param.code_bits_per_frame/2);\r
-lmod_codeword = code_param.code_bits_per_frame/2;\r
+  mod_uw = build_mod_uw(uw, 2*length(vd)/length(uw));\r
 \r
-Terrs = 0; Ferrs = 0; Tbits = 0; Tframes = 0; nerr = [];\r
-corr = []; n = 0;\r
-sync_state = 0; sync_count = 0;\r
-mod_unpackedmodem_log = [];\r
+  mod_codeword = zeros(1, code_param.code_bits_per_frame/2);\r
+  lmod_codeword = code_param.code_bits_per_frame/2;\r
 \r
-[mod_unpackedmodem_float32, count] = fread(fm,nbitspermodemframe, "float32");\r
-while (count == nbitspermodemframe)\r
-    n++;\r
+  Terrs = 0; Ferrs = 0; Tbits = 0; Tframes = 0; nerr = [];\r
+  corr = []; n = 0;\r
+  sync_state = 0; sync_count = 0;\r
+  mod_unpackedmodem_log = [];\r
+  sync_state_log = [];\r
+  entered_track_log = [];\r
 \r
-    mod_unpackedmodem = mod_unpackedmodem_float32(1:2:nbitspermodemframe) + j*mod_unpackedmodem_float32(2:2:nbitspermodemframe);\r
-    mod_unpackedmodem_log = [mod_unpackedmodem_log mod_unpackedmodem];\r
-    erasures = rand(1,length(mod_unpackedmodem)) < Eprob; \r
-    mod_unpackedmodem(erasures) = 0;\r
+  [mod_unpackedmodem_float32, count] = fread(fm,nbitspermodemframe, "float32");\r
+  if (fet == -1)\r
+      entered_track = 0;\r
+  else\r
+     entered_track = fread(fet, 1, "int");\r
+  end\r
 \r
-    % keep buffer of one entire codeword\r
+  while (count == nbitspermodemframe)\r
+      n++;\r
 \r
-    mod_codeword(1:lmod_codeword-length(mod_unpackedmodem)) = mod_codeword(length(mod_unpackedmodem)+1:lmod_codeword);\r
-    mod_codeword(lmod_codeword-length(mod_unpackedmodem)+1:lmod_codeword) = mod_unpackedmodem;\r
+      mod_unpackedmodem = mod_unpackedmodem_float32(1:2:nbitspermodemframe) + j*mod_unpackedmodem_float32(2:2:nbitspermodemframe);\r
+      mod_unpackedmodem_log = [mod_unpackedmodem_log mod_unpackedmodem];\r
+      erasures = rand(1,length(mod_unpackedmodem)) < Eprob; \r
+      mod_unpackedmodem(erasures) = 0;\r
 \r
-    [uw_sync corr(n)] = look_for_uw(mod_codeword(1:length(mod_uw)), mod_uw);\r
-    if (uw_sync)\r
-      sync_state = 1;\r
-    end\r
+      % keep buffer of one entire codeword\r
 \r
-    if (sync_state && (sync_count == 0))\r
-        Tframes++;\r
+      mod_codeword(1:lmod_codeword-length(mod_unpackedmodem)) = mod_codeword(length(mod_unpackedmodem)+1:lmod_codeword);\r
+      mod_codeword(lmod_codeword-length(mod_unpackedmodem)+1:lmod_codeword) = mod_unpackedmodem;\r
 \r
-        % force UW symbols as they are known (is this needed?)\r
+      [uw_sync corr(n)] = look_for_uw(mod_codeword(1:length(mod_uw)), mod_uw);\r
 \r
-        % LDPC decode\r
+      next_sync_state = sync_state;\r
+      if ((sync_state == 0) && (uw_sync == 1))\r
+        next_sync_state = 1;\r
+        sync_count = 0;\r
+      end\r
+      if ((sync_state == 1) && (entered_track != 0))\r
+        next_sync_state = 0;\r
+      end\r
+      sync_state = next_sync_state;\r
+      sync_state_log = [sync_state_log sync_state];\r
+      entered_track_log = [entered_track_log entered_track];\r
 \r
-        detected_data = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, mod_codeword, EsNo);\r
-\r
-        % unpack payload data, removing UW\r
-\r
-        vd_rx = remove_uw(detected_data(1:code_param.data_bits_per_frame), length(vd), length(uw));\r
-\r
-        % measure BER\r
-\r
-        error_positions = xor(vd, vd_rx);\r
-        Nerrs = sum(error_positions);\r
-        if Nerrs>0, fprintf(1,'x'); Ferrs++; ,  else fprintf(1,'.'),  end\r
-        Tbits += length(vd);\r
-        Terrs += Nerrs;\r
-        nerr(Tframes) = Nerrs;\r
-\r
-        % save packed payload data to disk\r
-    end\r
-\r
-    if (sync_state)\r
-        sync_count++;\r
-        if (sync_count == 8)\r
-            sync_count = 0;\r
-        end\r
-    end\r
-\r
-    % read in one modulated modem frame at a time\r
-\r
-    [mod_unpackedmodem_float32, count] = fread(fm, nbitspermodemframe, "float32");\r
-end\r
-\r
-fprintf(1,"\nFrames: %d bits: %d errors: %d BER = %f FER = %f\n", Tframes, Tbits, Terrs, Terrs/Tbits, Ferrs/Tframes);\r
-%subplot(211)\r
-%plot(corr);\r
-%subplot(212)\r
-%plot(nerr);\r
-figure(1)\r
-clf;\r
-[n m] = size(mod_unpackedmodem_log);\r
-plot( real(mod_unpackedmodem_log), imag(mod_unpackedmodem_log), '+')\r
-axis([-2 2 -2 2]);\r
-title('Scatter Diagram');\r
+      if (sync_state && (sync_count == 0))\r
+          Tframes++;\r
+\r
+          % remove UW symbols\r
+\r
+          mod_codeword_no_uw = remove_uw_symbols(mod_codeword, code_param.data_bits_per_frame/2 - length(uw)/2, length(uw)/2);\r
+          mod_codeword_no_uw = [mod_codeword_no_uw mod_codeword((code_param.data_bits_per_frame/2+1):code_param.code_bits_per_frame/2)];\r
+\r
+          % de-interleave\r
+\r
+          tmp = deinterleave_symbols(interleaver, mod_codeword_no_uw);\r
+        \r
+          % insert known symbols at end of data\r
+\r
+          mod_codeword_deinter = [ tmp(1:(code_param.data_bits_per_frame/2 - length(uw)/2)) ...\r
+                                 ones(1,length(uw)/2) * qpsk_mod([0 0]) ...\r
+                                 tmp((code_param.data_bits_per_frame/2 - length(uw)/2+1):length(tmp)) ];\r
\r
+          % LDPC decode\r
+\r
+          detected_data = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, mod_codeword_deinter, EsNo);\r
+\r
+          % unpack payload data, removing UW\r
+\r
+          vd_rx = detected_data(1:(code_param.data_bits_per_frame - length(uw)));\r
+\r
+          % measure BER\r
+\r
+          error_positions = xor(vd, vd_rx);\r
+          Nerrs = sum(error_positions);\r
+          if Nerrs>0, fprintf(1,'x'); Ferrs++; ,  else fprintf(1,'.'),  end\r
+          Tbits += length(vd);\r
+          Terrs += Nerrs;\r
+          nerr(Tframes) = Nerrs;\r
+\r
+          % save error patterns is simulated vocoder data to disk\r
+\r
+          fwrite(fep, error_positions, "short");\r
+          \r
+      end\r
+\r
+      if (sync_state)\r
+          sync_count++;\r
+          if (sync_count == 8)\r
+              sync_count = 0;\r
+          end\r
+      end\r
+\r
+      % read in one modulated modem frame at a time\r
+\r
+      [mod_unpackedmodem_float32, count] = fread(fm, nbitspermodemframe, "float32");\r
+      if (fet == -1)\r
+          entered_track = 0;\r
+      else\r
+          entered_track = fread(fet, 1, "int");\r
+      end\r
+  end\r
+\r
+  fclose(fep);\r
+\r
+  fprintf(1,"\nFrames: %d bits: %d errors: %d BER = %f FER = %f\n", Tframes, Tbits, Terrs, Terrs/Tbits, Ferrs/Tframes);\r
+\r
+  figure(8)\r
+  clf;\r
+  [n m] = size(mod_unpackedmodem_log);\r
+  plot( real(mod_unpackedmodem_log), imag(mod_unpackedmodem_log), '+')\r
+  axis([-2 2 -2 2]);\r
+  title('Scatter Diagram');\r
+\r
+  figure(9)\r
+  subplot(311)\r
+  plot(sync_state_log);\r
+  subplot(312)\r
+  plot(entered_track_log);\r
+  subplot(313)\r
+  plot(nerr);\r
+endfunction\r
index 4a1e28f46f78446174d9bd0e8659ea9b64c59638..023c5172094156e4ed748eb4354e0dff61fc32a1 100644 (file)
 % ldpcenc.m\r
 % David Rowe 20 Dec 2013\r
 % \r
-% LDPC encoder test program. Encodes and modulates a random data stream \r
+% LDPC encoder function. Takes a random data pattern, LDPC Encodes and\r
+% inserts Unique Word (UW) sync bits and ouputs this as a packed\r
+% binary file suitable for the Nc=18 carrier FDMDV modulator,\r
+% fdmdv_mod.  Also produces a "modulated" output file of QPSK\r
+% symbols, suitable for feeding into ldpcdec for testing.\r
 \r
-% Start CML library\r
+function ldpcenc(filename)\r
 \r
-currentdir = pwd;\r
-addpath '/home/david/tmp/cml/mat'    % assume the source files stored here\r
-cd /home/david/tmp/cml\r
-CmlStartup                           % note that this is not in the cml path!\r
-cd(currentdir)\r
+  % Start CML library\r
 \r
-% Our LDPC library\r
+  currentdir = pwd;\r
+  addpath '/home/david/tmp/cml/mat'    % assume the source files stored here\r
+  cd /home/david/tmp/cml\r
+  CmlStartup                           % note that this is not in the cml path!\r
+  cd(currentdir)\r
+  \r
+  % Our LDPC library\r
 \r
-ldpc;\r
+  ldpc;\r
 \r
-% Start simulation\r
+  % Start simulation\r
 \r
-rand('state',1);\r
+  rand('state',1);\r
 \r
-rate = 3/4; \r
-framesize = 576;  \r
+  rate = 3/4; \r
+  framesize = 576;  \r
 \r
-mod_order = 4; \r
-modulation = 'QPSK';\r
-mapping = 'gray';\r
+  mod_order = 4; \r
+  modulation = 'QPSK';\r
+  mapping = 'gray';\r
 \r
-demod_type = 0;\r
-decoder_type = 0;\r
-max_iterations = 100;\r
-EsNo = 10;\r
-Eprob = 0.15;\r
+  demod_type = 0;\r
+  decoder_type = 0;\r
+  max_iterations = 100;\r
 \r
-vocoderframesize = 52;\r
-nvocoderframes = 8;\r
-nbitspermodemframe = 72;\r
+  nbitspervocoderframe = 52;\r
+  nvocoderframes = 8;\r
+  nbitspermodemframe = 72;\r
 \r
-code_param = ldpc_init(rate, framesize, modulation, mod_order, mapping);\r
+  code_param = ldpc_init(rate, framesize, modulation, mod_order, mapping);\r
 \r
-data = [];\r
-r = []; \r
+  data = [];\r
+  r = []; \r
+  load interleaver.txt\r
+  interleaver = interleaver + 1;\r
 \r
-% Encoder: Generate simulated vocoder data, insert UW, and LPDC encode ---------------\r
+  % Encoder: Generate simulated vocoder data\r
+  %          LPDC encode\r
+  %          interleave           \r
+  %          insert UW bits\r
 \r
-Nframes = 100;\r
-uw = [1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0];\r
+  Nframes = 100;\r
+  uw = [1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0];\r
 \r
-% repeat same simulated vocoder data to ease testing\r
+  % repeat same simulated vocoder data to ease testing\r
 \r
-vd = round( rand( 1, vocoderframesize*nvocoderframes) );\r
-d  = insert_uw(vd, uw);\r
+  vd = round( rand( 1, nbitspervocoderframe*nvocoderframes) );\r
 \r
-data = [data d];\r
-[codeword, s] = ldpc_enc(d, code_param);\r
-code_param.code_bits_per_frame = length(codeword);\r
-code_param.symbols_per_frame = length(s);\r
-packedcodeword = packmsb(codeword);\r
+  % pad data with zeros the size of UW\r
 \r
-fc=fopen("codeword.bin","wb");\r
-for nn = 1: Nframes        \r
-    fwrite(fc,packedcodeword,"uchar");\r
-end\r
-fclose(fc);\r
+  vdpad = [vd zeros(1, length(uw))];\r
 \r
-%printf("framesize: %d data_bits_per_frame: %d code_bits_per_frame: %d\n", ...\r
-%        framesize, code_param.data_bits_per_frame,  code_param.code_bits_per_frame);\r
+  % LDPC encode\r
 \r
-printf("Encoded %d LDPC frames\n", Nframes);\r
+  [codewordpad, s] = ldpc_enc(vdpad, code_param);\r
+  code_param.code_bits_per_frame = length(codewordpad);\r
+  code_param.symbols_per_frame = length(s);\r
 \r
-% Modulator: Modulate to QPSK symbols ------------------------------------------\r
+  % remove padded zeros after encoding to leave room for UW bits (code\r
+  % is systematic)\r
 \r
-lpackedcodeword=length(packedcodeword);\r
-fc=fopen("codeword.bin","rb");\r
-fm=fopen("modcodeword.bin","wb");\r
-lpackedmodem = nbitspermodemframe/8;\r
-n = 0;\r
+  codeword = [ codewordpad(1:length(vd)) codewordpad((length(vd)+length(uw)+1):length(codewordpad)) ];\r
 \r
-[packedmodem, count] = fread(fc,lpackedmodem,"uchar");\r
-while (count == lpackedmodem)\r
-    n++;\r
-    unpackedmodem = unpackmsb(packedmodem);\r
+  % interleave, insert UW bits, and pack bits (as C modulator likes packed bits)\r
 \r
-    ii = 1;\r
-    for i=1:2:length(unpackedmodem)\r
-        mod_unpackedmodem(ii) = qpsk_mod(unpackedmodem(i:i+1));\r
-        mod_unpackedmodem_float32(i) = real(mod_unpackedmodem(ii));\r
-        mod_unpackedmodem_float32(i+1) = imag(mod_unpackedmodem(ii));\r
-        ii += 1;\r
-    end\r
+  codeword_interleaved = interleave_bits(interleaver, codeword);\r
+  codeword_interleaved_uw = [insert_uw(codeword_interleaved(1:length(vd)), uw) codeword_interleaved(length(vd)+1:length(codeword_interleaved)) ];\r
+  packedcodeword = packmsb(codeword_interleaved_uw);\r
 \r
-    fwrite(fm, mod_unpackedmodem_float32, "float32");\r
-    [packedmodem, count] = fread(fc,lpackedmodem,"uchar");\r
-end\r
-fclose(fc);\r
-fclose(fm);\r
-printf("Modulated %d modem frames\n", n);\r
+  cwfilename = strcat(filename,"_codeword.bin");\r
+  fc=fopen(cwfilename,"wb");\r
+  for nn = 1: Nframes        \r
+      fwrite(fc,packedcodeword,"uchar");\r
+  end\r
+  fclose(fc);\r
 \r
+  %printf("framesize: %d data_bits_per_frame: %d code_bits_per_frame: %d\n", ...\r
+  %        framesize, code_param.data_bits_per_frame,  code_param.code_bits_per_frame);\r
 \r
-% Decoder: Sync with LDPC frames, LDPC decode, strip off UW, measure BER -------\r
+  printf("Encoded %d LDPC codewords, saved in packed file: %s\n", Nframes, cwfilename);\r
 \r
-fm=fopen("modcodeword.bin","rb");\r
+  % Modulator: Modulate to QPSK symbols ------------------------------------------\r
 \r
-mod_uw = build_mod_uw(uw, 2*length(vd)/length(uw));\r
+  nbytespackedcodeword=length(packedcodeword);\r
+  fc=fopen(cwfilename,"rb");\r
+  mcwfilename = strcat(filename,"_modcodeword.bin");\r
+  fm=fopen(mcwfilename,"wb");\r
+  nbytespackedmodemframe = nbitspermodemframe/8;\r
+  n = 0;\r
 \r
-mod_codeword = zeros(1, code_param.code_bits_per_frame/2);\r
-lmod_codeword = code_param.code_bits_per_frame/2;\r
+  [packedmodem, count] = fread(fc,nbytespackedmodemframe,"uchar");\r
+  while (count == nbytespackedmodemframe)\r
+      n++;\r
+      unpackedmodem = unpackmsb(packedmodem);\r
 \r
-Terrs = 0; Ferrs = 0; Tbits = 0; Tframes = 0; nerr = [];\r
-corr = []; n = 0;\r
-sync_state = 0; sync_count = 0;\r
+      ii = 1;\r
+      for i=1:2:length(unpackedmodem)\r
+          mod_unpackedmodem(ii) = qpsk_mod(unpackedmodem(i:i+1));\r
+          mod_unpackedmodem_float32(i) = real(mod_unpackedmodem(ii));\r
+          mod_unpackedmodem_float32(i+1) = imag(mod_unpackedmodem(ii));\r
+          ii += 1;\r
+      end\r
 \r
-[mod_unpackedmodem_float32, count] = fread(fm,nbitspermodemframe, "float32");\r
-while (count == nbitspermodemframe)\r
-    n++;\r
+      fwrite(fm, mod_unpackedmodem_float32, "float32");\r
+      [packedmodem, count] = fread(fc,nbytespackedmodemframe,"uchar");\r
+  end\r
+  fclose(fc);\r
+  fclose(fm);\r
+  printf("Modulated %d modem frames to file: %s\n", n, mcwfilename);\r
+endfunction\r
 \r
-    mod_unpackedmodem = mod_unpackedmodem_float32(1:2:nbitspermodemframe) + j*mod_unpackedmodem_float32(2:2:nbitspermodemframe);\r
-    erasures = rand(1,length(mod_unpackedmodem)) < Eprob; \r
-    mod_unpackedmodem(erasures) = 0;\r
 \r
-    % keep buffer of one entire codeword\r
-\r
-    mod_codeword(1:lmod_codeword-length(mod_unpackedmodem)) = mod_codeword(length(mod_unpackedmodem)+1:lmod_codeword);\r
-    mod_codeword(lmod_codeword-length(mod_unpackedmodem)+1:lmod_codeword) = mod_unpackedmodem;\r
-\r
-    [uw_sync corr(n)] = look_for_uw(mod_codeword(1:length(mod_uw)), mod_uw);\r
-    if (uw_sync)\r
-      sync_state = 1;\r
-    end\r
-\r
-    if (sync_state && (sync_count == 0))\r
-        Tframes++;\r
-\r
-        % force UW symbols as they are known (is this needed?)\r
-\r
-        % LDPC decode\r
-\r
-        detected_data = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, mod_codeword, EsNo);\r
-\r
-        % unpack payload data, removing UW\r
-\r
-        vd_rx = remove_uw(detected_data(1:code_param.data_bits_per_frame), length(vd), length(uw));\r
-\r
-        % measure BER\r
-\r
-        error_positions = xor(vd, vd_rx);\r
-        Nerrs = sum(error_positions);\r
-        if Nerrs>0, fprintf(1,'x'); Ferrs++; ,  else fprintf(1,'.'),  end\r
-        Tbits += length(vd);\r
-        Terrs += Nerrs;\r
-        nerr(Tframes) = Nerrs;\r
-\r
-        % save packed payload data to disk\r
-    end\r
-\r
-    if (sync_state)\r
-        sync_count++;\r
-        if (sync_count == 8)\r
-            sync_count = 0;\r
-        end\r
-    end\r
-\r
-    % read in one modulated modem frame at a time\r
-\r
-    [mod_unpackedmodem_float32, count] = fread(fm, nbitspermodemframe, "float32");\r
-end\r
-\r
-fprintf(1,"\nFrames: %d bits: %d errors: %d BER = %f FER = %f\n", Tframes, Tbits, Terrs, Terrs/Tbits, Ferrs/Tframes);\r
-subplot(211)\r
-plot(corr);\r
-subplot(212)\r
-plot(nerr);\r
index 50d822625369b5929fa2e25602e96ed42d191958..17671c0857e7d801ea5caaf6a809c64ea8771d78 100644 (file)
@@ -2,53 +2,40 @@
 % This program is distributed under the terms of the GNU General Public License 
 % Version 2
 
-function pl2(samname1, samname2, start_sam, end_sam, pngname)
+function pl2(samname1, samname2, start_sam, end_sam, offset)
   
   fs1=fopen(samname1,"rb");
   s1=fread(fs1,Inf,"short");
   fs2=fopen(samname2,"rb");
   s2=fread(fs2,Inf,"short");
 
-  st = 1;
-  en = length(s1);
+  st1 = st2 = 1;
+  en1 = en2 = length(s1);
   if (nargin >= 3)
-    st = start_sam;
+    st1 = st2 = start_sam;
   endif
   if (nargin >= 4)
-    en = end_sam;
+    en1 = en2 = end_sam;
+  endif
+
+  if (nargin == 5)
+    st2 += offset        
+    en2 += offset        
   endif
 
   figure(1);
   clf;
   subplot(211);
   l1 = strcat("r;",samname1,";");
-  plot(s1(st:en), l1);
-  axis([1 en-st min(s1(st:en)) max(s1(st:en))]);
+  plot(s1(st1:en1), l1);
+  axis([1 en1-st1 min(s1(st1:en1)) max(s1(st1:en1))]);
   subplot(212);
   l2 = strcat("r;",samname2,";");
-  plot(s2(st:en),l2);
-  axis([1 en-st min(s1(st:en)) max(s1(st:en))]);
+  plot(s2(st2:en2),l2);
+  axis([1 en2-st2 min(s1(st2:en2)) max(s1(st2:en2))]);
  
   figure(2)
-  plot(s1(st:en)-s2(st:en));
-  max(s1(st:en)-s2(st:en))
+  plot(s1(st1:en1)-s2(st2:en2));
   
-  if (nargin == 5)
-
-    % small image
-
-    __gnuplot_set__ terminal png size 420,300
-    s = sprintf("__gnuplot_set__ output \"%s.png\"", pngname);
-    eval(s)
-    replot;
-
-    % larger image
-
-    __gnuplot_set__ terminal png size 800,600
-    s = sprintf("__gnuplot_set__ output \"%s_large.png\"", pngname);
-    eval(s)
-    replot;
-
-  endif
 
 endfunction