unique word sync that handles different amplitude rx signals
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sun, 29 Dec 2013 03:15:05 +0000 (03:15 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sun, 29 Dec 2013 03:15:05 +0000 (03:15 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1348 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/ldpc.m
codec2-dev/octave/ldpcenc.m

index c00814786a0f9a451f6921cce0c1b8accb5c2c0e..dfed5d45f8535f8a4b74ea4e5f07bf00ca3c59bc 100644 (file)
@@ -20,28 +20,85 @@ function code_param = ldpc_init(rate, framesize, modulation, mod_order, mapping)
     code_param.bits_per_symbol = log2(mod_order);\r
 endfunction\r
 \r
-% inserts a unique word into a frame of bits\r
+% Gray coded QPSK modulation function\r
+\r
+function symbol = qpsk_mod(two_bits)\r
+    two_bits_decimal = sum(two_bits .* [1 2]); \r
+    switch(two_bits_decimal)\r
+        case (0) symbol =  1+j;\r
+        case (1) symbol = -1+j;\r
+        case (2) symbol =  1-j;\r
+        case (3) symbol = -1-j;\r
+    endswitch\r
+endfunction\r
+\r
+% inserts a unique word into a frame of bits.  The UW bits are spread\r
+% throughout the input frame 2 bits at a time.\r
 \r
 function frameout = insert_uw(framein, uw)\r
 \r
     luw = length(uw);\r
     lframein = length(framein);\r
-    spacing = lframein/luw;\r
+    spacing = 2*lframein/luw;\r
 \r
     frameout = [];\r
+    mod_uw = [];\r
 \r
-    for i=1:luw\r
-        frameout(1+(i-1)*spacing+i-1:i*spacing+i-1) = framein(1+(i-1)*spacing:i*spacing);\r
-        frameout(i*spacing+i) = uw(i);\r
+    pin = 1; pout = 1; puw = 1;\r
+    while (luw)\r
+        %printf("pin %d pout %d puw %d luw %d\n", pin, pout, puw, luw);\r
+        frameout(pout:pout+spacing-1) = framein(pin:pin+spacing-1);\r
+        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
     end\r
 \r
 endfunction\r
 \r
+% builds up a sparse QPSK modulated version version of the UW for use\r
+% in UW sync at the rx\r
+\r
+function mod_uw = build_mod_uw(uw, spacing)\r
+    luw = length(uw);\r
+\r
+    mod_uw = [];\r
+\r
+    pout = 1; puw = 1;\r
+    while (luw)\r
+        %printf("pin %d pout %d puw %d luw %d\n", pin, pout, puw, luw);\r
+        pout += spacing/2;\r
+        mod_uw(pout) = qpsk_mod(uw(puw:puw+1));\r
+        puw += 2;\r
+        pout += 1;\r
+        luw -= 2;\r
+    end\r
+endfunction\r
+\r
+\r
+% Uses the UW to determine when we have a full codeword ready for decoding\r
+\r
+function found_uw = look_for_uw(mem_rx_symbols, mod_uw)\r
+    sparse_mem_rx_symbols = mem_rx_symbols(find(mod_uw));\r
+\r
+    % correlate with ref UW\r
+\r
+    num = (mem_rx_symbols * mod_uw') .^ 2;\r
+    den = (sparse_mem_rx_symbols * sparse_mem_rx_symbols') * (mod_uw * mod_uw');\r
+\r
+    found_uw = abs(num/(den+1E-6)) > 0.8;\r
+endfunction\r
+\r
+\r
 function [codeword s] = ldpc_enc(data, code_param)\r
         codeword = LdpcEncode( data, code_param.H_rows, code_param.P_matrix );\r
         s = Modulate( codeword, code_param.S_matrix );\r
 endfunction\r
 \r
+\r
 function detected_data = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, r, EsNo)\r
     symbol_likelihood = Demod2D( r, code_param.S_matrix, EsNo);\r
          \r
@@ -56,6 +113,7 @@ function detected_data = ldpc_dec(code_param, max_iterations, demod_type, decode
     detected_data = x_hat(max_iterations,:);\r
 endfunction\r
 \r
+\r
 % Packs a binary array into an array of 8 bit bytes, MSB first\r
 \r
 function packed = packmsb(unpacked)\r
@@ -71,3 +129,18 @@ function packed = packmsb(unpacked)
     end\r
 endfunction\r
 \r
+\r
+% unpacks an array of 8 bit bytes into a binary array of unpacked bits, MSB first\r
+\r
+function unpacked = unpackmsb(packed)\r
+    bit = 7; byte = 1;\r
+    for i=1:length(packed)*8\r
+        unpacked(i) = bitand(bitshift(packed(byte), -bit), 1);\r
+        bit--;\r
+        if (bit < 0)\r
+            bit = 7;\r
+            byte++;\r
+        end \r
+    end\r
+endfunction\r
+\r
index 0f8c5f9853d91461793c254fc5e0325868906727..9773e79f476d80b4c635fad8876c85c6ba5d4fa2 100644 (file)
@@ -39,11 +39,12 @@ r = [];
 % Encode a bunch of frames\r
 \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 codeword frame for now to ease testing\r
 \r
 vd = round( rand( 1, vocoderframesize*nvocoderframes) );\r
-d = insert_uw(vd, [1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0]);\r
+d  = insert_uw(vd, uw);\r
 \r
 data = [data d];\r
 [codeword, s] = ldpc_enc(d, code_param);\r
@@ -53,12 +54,43 @@ packedcodeword = packmsb(codeword);
 \r
 fc=fopen("codeword.bin","wb");\r
 for nn = 1: Nframes        \r
-    fwrite(fc,packedcodeword,"char");\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
+% rx simulation (separate later)\r
+\r
+mod_uw = build_mod_uw(uw, 2*length(vd)/length(uw));\r
+\r
+lpackedcodeword=length(packedcodeword);\r
+fc=fopen("codeword.bin","rb");\r
+lpackedmodem = 72/8;\r
+mod_codeword = zeros(1, code_param.code_bits_per_frame/2);\r
+lmod_codeword = code_param.code_bits_per_frame/2;\r
+\r
+for m=1:16\r
+\r
+    % read in one modem frame at a time\r
+\r
+    packedmodem = fread(fc,lpackedmodem,"uchar");\r
+    unpackedmodem = unpackmsb(packedmodem);\r
+\r
+    j = 1;\r
+    for i=1:2:length(unpackedmodem)\r
+        mod_unpackedmodem(j) = qpsk_mod(unpackedmodem(i:i+1));\r
+        j += 1;\r
+    end\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
+    look_for_uw(10*mod_codeword(1:length(mod_uw)), mod_uw)\r
+end\r
+\r
+fclose(fc);\r
 \r
\r