1% ldpc.m 2% 3% David Rowe 2013 4% Octave functions to help us use the CML LDPC code. 5% 6% Installing CML library 7% ---------------------- 8% 9% $ sudo apt-get install liboctave-dev 10% $ wget http://www.iterativesolutions.com/user/image/cml.1.10.zip 11% $ unzip cml.1.10.zip 12% $ patch -p0 < ~/codec2/octave/cml.patch 13% $ cd cml/source 14% $ octave --no-gui 15% octave:> make 16% (you'll see a few warnings but hopefully no errors) 17% 18% Optionally set an environment variable for CML_PATH in your shell or 19% in your codec2/octave/.octaverc file 20 211; 22 23function init_cml() 24 currentdir = pwd; 25 26 path_to_cml = getenv("CML_PATH"); 27 28 if exist(path_to_cml, 'dir') == 7 29 cd(path_to_cml) 30 CmlStartup 31 cd(currentdir); 32 else 33 printf("\n---------------------------------------------------\n"); 34 printf("Can't start CML in path: %s\n", path_to_cml); 35 printf("See CML_PATH instructions at top of this script (ldpc.m)\n"); 36 printf("-----------------------------------------------------\n\n"); 37 assert(0); 38 end 39end 40 41% init using built in WiMax or DVSB2 code 42 43function code_param = ldpc_init_builtin(code, rate, framesize, modulation, mod_order, mapping, constellation) 44 if strcmp(code,'wimax') 45 [code_param.H_rows, code_param.H_cols, code_param.P_matrix] = InitializeWiMaxLDPC( rate, framesize, 0 ); 46 end 47 if strcmp(code,'dvbs2') 48 [code_param.H_rows, code_param.H_cols, code_param.P_matrix] = InitializeDVBS2( rate, framesize); 49 end 50 if nargin == 7 51 code_param.S_matrix = constellation; 52 else 53 if length(mapping) == 0 54 code_param.S_matrix = CreateConstellation( modulation, mod_order); 55 else 56 code_param.S_matrix = CreateConstellation( modulation, mod_order, mapping ); 57 end 58 end 59 code_param.bits_per_symbol = log2(mod_order); 60 61 code_param.ldpc_data_bits_per_frame = length(code_param.H_cols) - length(code_param.P_matrix); 62 code_param.ldpc_parity_bits_per_frame = framesize - code_param.ldpc_data_bits_per_frame; 63 code_param.ldpc_coded_bits_per_frame = framesize; 64 65 code_param.data_bits_per_frame = code_param.ldpc_data_bits_per_frame; 66 code_param.coded_bits_per_frame = code_param.ldpc_coded_bits_per_frame; 67 code_param.coded_syms_per_frame = code_param.coded_bits_per_frame/code_param.bits_per_symbol; 68endfunction 69 70 71% init using user supplied code 72 73function [code_param framesize rate] = ldpc_init_user(HRA, modulation, mod_order, mapping, constellation) 74 [Nr Nc] = size(HRA); 75 rate = (Nc-Nr)/Nc; 76 framesize = Nc; 77 [H_rows, H_cols] = Mat2Hrows(HRA); 78 code_param.H_rows = H_rows; 79 code_param.H_cols = H_cols; 80 code_param.P_matrix = []; 81 if nargin == 5 82 code_param.S_matrix = constellation; 83 else 84 if length(mapping) == 0 85 code_param.S_matrix = CreateConstellation( modulation, mod_order); 86 else 87 code_param.S_matrix = CreateConstellation( modulation, mod_order, mapping ); 88 end 89 end 90 code_param.bits_per_symbol = log2(mod_order); 91 92 code_param.ldpc_data_bits_per_frame = length(code_param.H_cols) - length(code_param.P_matrix); 93 code_param.ldpc_parity_bits_per_frame = framesize - code_param.ldpc_data_bits_per_frame; 94 code_param.ldpc_coded_bits_per_frame = framesize; 95 96 % these variables support underfilling frame 97 code_param.data_bits_per_frame = code_param.ldpc_data_bits_per_frame; 98 code_param.coded_bits_per_frame = code_param.ldpc_coded_bits_per_frame; 99 code_param.coded_syms_per_frame = code_param.coded_bits_per_frame/code_param.bits_per_symbol; 100endfunction 101 102 103function [codeword s] = ldpc_enc(data, code_param) 104 codeword = LdpcEncode( data, code_param.H_rows, code_param.P_matrix ); 105 s = Modulate( codeword, code_param.S_matrix ); 106endfunction 107 108 109function [detected_data paritychecks] = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, r, EsNo, fading) 110 symbol_likelihood = Demod2D( r, code_param.S_matrix, EsNo, fading); 111 112 % initialize the extrinsic decoder input 113 114 input_somap_c = zeros(1, code_param.ldpc_coded_bits_per_frame ); 115 bit_likelihood = Somap( symbol_likelihood, demod_type, input_somap_c ); 116 117 input_decoder_c = bit_likelihood(1:code_param.ldpc_coded_bits_per_frame); 118 119 [x_hat paritychecks] = MpDecode( -input_decoder_c, code_param.H_rows, code_param.H_cols, ... 120 max_iterations, decoder_type, 1, 1); 121 [mx mx_ind] = max(paritychecks); 122 detected_data = x_hat(mx_ind,:); 123endfunction 124 125 126% Packs a binary array into an array of 8 bit bytes, MSB first 127 128function packed = packmsb(unpacked) 129 packed = zeros(1,floor(length(unpacked)+7)/8); 130 bit = 7; byte = 1; 131 for i=1:length(unpacked) 132 packed(byte) = bitor(packed(byte), bitshift(unpacked(i),bit)); 133 bit--; 134 if (bit < 0) 135 bit = 7; 136 byte++; 137 end 138 end 139endfunction 140 141 142% unpacks an array of 8 bit bytes into a binary array of unpacked bits, MSB first 143 144function unpacked = unpackmsb(packed) 145 bit = 7; byte = 1; 146 for i=1:length(packed)*8 147 unpacked(i) = bitand(bitshift(packed(byte), -bit), 1); 148 bit--; 149 if (bit < 0) 150 bit = 7; 151 byte++; 152 end 153 end 154endfunction 155 156 157% symbol interleaver that acts on bits 2 at a time 158 159function y = interleave_bits(interleaver, x) 160 y = zeros(1,length(x)); 161 for i = 1:length(interleaver) 162 dst = interleaver(i); 163 y(2*(dst-1)+1:2*dst) = x(2*(i-1)+1:2*(i)); 164 end 165endfunction 166 167% symbol de-interleaver 168 169function x = deinterleave_symbols(interleaver, y) 170 for i = 1:length(interleaver) 171 x(i) = y(interleaver(i)); 172 end 173endfunction 174