Saturday, July 13, 2013

DVB-T2 LDPC Encoding Explained!

Well, I can't really explain LDPC encoding fully, but I have been looking at section  6.1.2 and the tables in Appendix A of the document ETSI EN 302 775 for a long time (maybe years),  without understanding anything.

Now I have written Matlab/GNU Octave code to demonstrate the algorithm.   I have tested it for the normal FEC block size (64800) and only for code rate = 2/3.   It is a lot slower than other encoders I found, but gives the same answers.  Whereas other encoders does one encoding in the blink of an eye, this demo code takes about 1 minute on my laptop.

% This is supposed to be ran interactively by copying and pasting.
% NOTE!
% You need the function t2_std_dvbt2_bl_ldpc from the
% DVB T2 Common Simulation Platform.  Best is maybe to copy it
% into your working directory.  In this function, find ct1 and ct2
% for code rate 2/3(SONY matrix).  Copy and paste them into Octave or Matlab.
%  Then copy and paste he code below:
%
% Assemble ct1 and ct2 into one matrix ck, padding ct2 with zeros
ck=zeros(size(ct1,1)+size(ct2,1), max([size(ct1,2) size(ct2,2)]));
ck(1:size(ct1,1),1:size(ct1,2)) = ct1;
ck(size(ct1,1)+1:size(ck,1), 1:size(ct2,2)) = ct2;
% Set the LDPC parameters
Nldpc=64800;
CR=2/3;
Kldpc = CR*Nldpc;
np=Nldpc-Kldpc;
% Create an information block
%i=[0 1 0 1 0 1 0 1 0 1 ones(1,Kldpc-20) 0 1 0 1 0 1 0 1 0 1] ;
i=randint(1,Kldpc,2);
% Initialize the parity bits
p=zeros(1,np);
Qldpc = 60;
tic;
for ii=0:size(i,2)-1
  ckr = idivide(ii, 360)+1;
  m360 = mod(ii, 360);
  % Some debug you can uncomment
  %fprintf(1, 'ckr = %5d m360 = %d\n', ckr, m360);
  % More debug you can enable/change to see some of the accumulation addresses
  % if ii>355 && ii<365
  %  mod(nonzeros(ck(ckr,:))'+m360*60,np)+1
  % end
  p(mod(nonzeros(ck(ckr,:))'+m360*60,np)+1) = mod(p(mod(nonzeros(ck(ckr,:))'+m360*60,np)+1) + i(ii+1), 2);
end
for pp=2:np
  p(pp) = mod(p(pp)+p(pp-1), 2);
end
toc;
% Verification agains Matlab code, if you have Matlab
% I tested this with alternative code in Octave
H = t2_std_dvbt2_bl_ldpc(CR, Nldpc, '1.3.1');
enc = fec.ldpcenc(H);
cw = encode1(enc, i);
ptest = cw(Kldpc+1:Nldpc);
nnz(p)
nnz(ptest)
nnz(p-ptest)

I hope somebody finds this useful. I think it should be useful for at least two purposes:
  • Educational.
  • Verifying other LDPC encoders.

3 comments:

  1. you know you have a LDPC matlab code in the model\tx\tx_dvbt2bll1gen\t2_tx_dvbt2bll1gen_l1coding?.

    ReplyDelete
  2. reduce time to half:

    for ii=0:size(i,2)-1
    ckr = floor(ii/360)+1;
    m360 = mod(ii, 360);
    % ckr=m360+1;
    adress=mod(nonzeros(ck(ckr,:))'+m360*Qldpc,np)+1;
    p(adress) = bitxor(p(adress),i(ii+1));
    end
    for pp=2:np
    p(pp) = bitxor(p(pp),p(pp-1));
    end

    ReplyDelete