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
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
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
% 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
\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