From 74dbe9c785b39dd009d6af134738bdb340233c6e Mon Sep 17 00:00:00 2001 From: drowe67 Date: Sun, 29 Dec 2013 03:15:05 +0000 Subject: [PATCH] unique word sync that handles different amplitude rx signals git-svn-id: https://svn.code.sf.net/p/freetel/code@1348 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/octave/ldpc.m | 83 ++++++++++++++++++++++++++++++++++--- codec2-dev/octave/ldpcenc.m | 38 +++++++++++++++-- 2 files changed, 113 insertions(+), 8 deletions(-) diff --git a/codec2-dev/octave/ldpc.m b/codec2-dev/octave/ldpc.m index c0081478..dfed5d45 100644 --- a/codec2-dev/octave/ldpc.m +++ b/codec2-dev/octave/ldpc.m @@ -20,28 +20,85 @@ function code_param = ldpc_init(rate, framesize, modulation, mod_order, mapping) code_param.bits_per_symbol = log2(mod_order); endfunction -% inserts a unique word into a frame of bits +% Gray coded QPSK modulation function + +function symbol = qpsk_mod(two_bits) + two_bits_decimal = sum(two_bits .* [1 2]); + switch(two_bits_decimal) + case (0) symbol = 1+j; + case (1) symbol = -1+j; + case (2) symbol = 1-j; + case (3) symbol = -1-j; + endswitch +endfunction + +% inserts a unique word into a frame of bits. The UW bits are spread +% throughout the input frame 2 bits at a time. function frameout = insert_uw(framein, uw) luw = length(uw); lframein = length(framein); - spacing = lframein/luw; + spacing = 2*lframein/luw; frameout = []; + mod_uw = []; - for i=1:luw - frameout(1+(i-1)*spacing+i-1:i*spacing+i-1) = framein(1+(i-1)*spacing:i*spacing); - frameout(i*spacing+i) = uw(i); + pin = 1; pout = 1; puw = 1; + while (luw) + %printf("pin %d pout %d puw %d luw %d\n", pin, pout, puw, luw); + frameout(pout:pout+spacing-1) = framein(pin:pin+spacing-1); + pin += spacing; + pout += spacing; + frameout(pout:pout+1) = uw(puw:puw+1); + mod_uw(pout:pout+1) = qpsk_mod(uw(puw:puw+1)); + puw += 2; + pout += 2; + luw -= 2; end endfunction +% builds up a sparse QPSK modulated version version of the UW for use +% in UW sync at the rx + +function mod_uw = build_mod_uw(uw, spacing) + luw = length(uw); + + mod_uw = []; + + pout = 1; puw = 1; + while (luw) + %printf("pin %d pout %d puw %d luw %d\n", pin, pout, puw, luw); + pout += spacing/2; + mod_uw(pout) = qpsk_mod(uw(puw:puw+1)); + puw += 2; + pout += 1; + luw -= 2; + end +endfunction + + +% Uses the UW to determine when we have a full codeword ready for decoding + +function found_uw = look_for_uw(mem_rx_symbols, mod_uw) + sparse_mem_rx_symbols = mem_rx_symbols(find(mod_uw)); + + % correlate with ref UW + + num = (mem_rx_symbols * mod_uw') .^ 2; + den = (sparse_mem_rx_symbols * sparse_mem_rx_symbols') * (mod_uw * mod_uw'); + + found_uw = abs(num/(den+1E-6)) > 0.8; +endfunction + + function [codeword s] = ldpc_enc(data, code_param) codeword = LdpcEncode( data, code_param.H_rows, code_param.P_matrix ); s = Modulate( codeword, code_param.S_matrix ); endfunction + function detected_data = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, r, EsNo) symbol_likelihood = Demod2D( r, code_param.S_matrix, EsNo); @@ -56,6 +113,7 @@ function detected_data = ldpc_dec(code_param, max_iterations, demod_type, decode detected_data = x_hat(max_iterations,:); endfunction + % Packs a binary array into an array of 8 bit bytes, MSB first function packed = packmsb(unpacked) @@ -71,3 +129,18 @@ function packed = packmsb(unpacked) end endfunction + +% unpacks an array of 8 bit bytes into a binary array of unpacked bits, MSB first + +function unpacked = unpackmsb(packed) + bit = 7; byte = 1; + for i=1:length(packed)*8 + unpacked(i) = bitand(bitshift(packed(byte), -bit), 1); + bit--; + if (bit < 0) + bit = 7; + byte++; + end + end +endfunction + diff --git a/codec2-dev/octave/ldpcenc.m b/codec2-dev/octave/ldpcenc.m index 0f8c5f98..9773e79f 100644 --- a/codec2-dev/octave/ldpcenc.m +++ b/codec2-dev/octave/ldpcenc.m @@ -39,11 +39,12 @@ r = []; % Encode a bunch of frames Nframes = 100; +uw = [1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0]; % repeat same codeword frame for now to ease testing vd = round( rand( 1, vocoderframesize*nvocoderframes) ); -d = insert_uw(vd, [1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0]); +d = insert_uw(vd, uw); data = [data d]; [codeword, s] = ldpc_enc(d, code_param); @@ -53,12 +54,43 @@ packedcodeword = packmsb(codeword); fc=fopen("codeword.bin","wb"); for nn = 1: Nframes - fwrite(fc,packedcodeword,"char"); + fwrite(fc,packedcodeword,"uchar"); end fclose(fc); printf("framesize: %d data_bits_per_frame: %d code_bits_per_frame: %d\n", ... framesize, code_param.data_bits_per_frame, code_param.code_bits_per_frame); +% rx simulation (separate later) + +mod_uw = build_mod_uw(uw, 2*length(vd)/length(uw)); + +lpackedcodeword=length(packedcodeword); +fc=fopen("codeword.bin","rb"); +lpackedmodem = 72/8; +mod_codeword = zeros(1, code_param.code_bits_per_frame/2); +lmod_codeword = code_param.code_bits_per_frame/2; + +for m=1:16 + + % read in one modem frame at a time + + packedmodem = fread(fc,lpackedmodem,"uchar"); + unpackedmodem = unpackmsb(packedmodem); + + j = 1; + for i=1:2:length(unpackedmodem) + mod_unpackedmodem(j) = qpsk_mod(unpackedmodem(i:i+1)); + j += 1; + end + + % keep buffer of one entire codeword + + mod_codeword(1:lmod_codeword-length(mod_unpackedmodem)) = mod_codeword(length(mod_unpackedmodem)+1:lmod_codeword); + mod_codeword(lmod_codeword-length(mod_unpackedmodem)+1:lmod_codeword) = mod_unpackedmodem; + + look_for_uw(10*mod_codeword(1:length(mod_uw)), mod_uw) +end + +fclose(fc); - -- 2.25.1