File: TurboDecode.m

package info (click to toggle)
codec2 1.2.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 76,376 kB
  • sloc: ansic: 436,819; cpp: 2,091; objc: 1,736; sh: 1,510; python: 1,405; asm: 683; makefile: 605
file content (136 lines) | stat: -rw-r--r-- 6,613 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
function [detected_data, errors, output_decoder_c, input_upper_u] = TurboDecode( input_decoder_c, data, turbo_iterations, decoder_type, code_interleaver, pun_pattern, tail_pattern, g1, nsc_flag1, g2, nsc_flag2, varargin )
% TurboDecode decodes a received sequence that was encoded by a binary turbo code.  
% If input_decoder_c has multiple rows, then multiple codewords will be decoded (one for each row).
%
% The calling syntax is:
%     [detected_data, errors, output_decoder_c, [output_decoder_u] ] =
%                     TurboDecode( input_decoder_c, data, turbo_iterations, decoder_type,  ... 
%                          code_interleaver, pun_pattern, tail_pattern, g1, nsc_flag1, g2, ...
%                          nsc_flag2, [input_decoder_u] )
%
%     detected_data = a row vector containing the detected data
%     errors = a column vector containing the number of errors per
%              iteration for all the codewords.
%     output_decoder_c = the extrinsic information of the code bits
%     output_decoder_u = the extrinsic information of the systematic bits (optional)
%
%     input_decoder_c = the decoder input, in the form of bit LLRs
%                       this could have multiple rows if the data is longer
%                       than the interleaver
%     data = the row vector of data bits (used to count errors and for early halting of iterative decoding)
%     turbo_iterations = the number of turbo iterations
%     decoder_type = the decoder type
%              = 0 For linear-log-MAP algorithm, i.e. correction function is a straght line.
%              = 1 For max-log-MAP algorithm (i.e. max*(x,y) = max(x,y) ), i.e. correction function = 0.
%              = 2 For Constant-log-MAP algorithm, i.e. correction function is a constant.
%              = 3 For log-MAP, correction factor from small nonuniform table and interpolation.
%              = 4 For log-MAP, correction factor uses C function calls.
%     code_interleaver = the turbo interleaver
%     pun_pattern = the puncturing pattern for all but the tail
%     tail_pattern = the puncturing pattern just for the tail
%     g1 = the first generator polynomial
%     nsc_flag1 = 0 if first encoder is RSC and 1 if NSC
%     g2 = the second generator polynomial
%     nsc_flag2 = 0 if second encoder is RSC and 1 if NSC
%     [input_decoder_u] = the a priori information about systematic bits (optional input)
%
% Copyright (C) 2005-2006, Matthew C. Valenti
%
% Last updated on Apr. 23, 2006
%
% Function TurboDecode is part of the Iterative Solutions Coded Modulation
% Library (ISCML).  
%
% The Iterative Solutions Coded Modulation Library is free software;
% you can redistribute it and/or modify it under the terms of 
% the GNU Lesser General Public License as published by the 
% Free Software Foundation; either version 2.1 of the License, 
% or (at your option) any later version.
%
% This library is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
% Lesser General Public License for more details.
%
% You should have received a copy of the GNU Lesser General Public
% License along with this library; if not, write to the Free Software
% Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

% determine some parameters
[N1,K1] = size( g1 );
[N2,K2] = size( g2 );

% check interleaver length against data length
K_data = length( data );
K_interleaver = length( code_interleaver );
if ( rem( K_data, K_interleaver ) )
    error( 'The data length needs to be an integer multiple of the interleaver length' );
end
number_codewords = K_data/K_interleaver;
data_bits_per_frame = K_data/number_codewords;

data = reshape( data, K_interleaver, number_codewords)';

% intialize error counter
errors = zeros( turbo_iterations, 1 );   

if ( length(varargin) >= 1 )   
    input_upper_u = varargin{1};
else
    input_upper_u = zeros( number_codewords, data_bits_per_frame );
end   

% loop over each received frame
for codeword_index=1:number_codewords       
   
    % depuncture and split
    depunctured_output = Depuncture( input_decoder_c(codeword_index,:), pun_pattern, tail_pattern );
    input_upper_c = reshape( depunctured_output(1:N1,:), 1, N1*length(depunctured_output) );
    input_lower_c = reshape( depunctured_output(N1+1:N1+N2,:), 1, N2*length(depunctured_output) );
    
    % decode
    for turbo_iter=1:turbo_iterations
        % fprintf( 'Turbo iteration = %d\n', turbo_iter );
        % Pass through upper decoder
        [output_upper_u output_upper_c] = SisoDecode( input_upper_u(codeword_index,:), input_upper_c, g1, nsc_flag1, decoder_type );
        
        % Interleave and extract extrinsic information
        input_lower_u = Interleave( output_upper_u - input_upper_u(codeword_index,:), code_interleaver );    
        
        % Pass through lower decoder
        [output_lower_u output_lower_c] = SisoDecode( input_lower_u, input_lower_c, g2, nsc_flag2, decoder_type );
        
        % count errors
        detected_data(codeword_index,:) = Deinterleave( (sign(output_lower_u)+1)/2, code_interleaver );
        error_positions = xor( detected_data(codeword_index,:), data(codeword_index,:) );       
        
        % exit if all the errors are corrected
        temp_errors = sum(error_positions);
        
        % for debugging
        % fprintf( 'Codeword: %d, Iteration: %d, Errors: %d\n', codeword_index, turbo_iter, temp_errors );
        if (temp_errors==0)
            break;
        else
            errors(turbo_iter) = temp_errors + errors(turbo_iter);              
            % Interleave and extract extrinsic information
            input_upper_u(codeword_index,:) = Deinterleave( output_lower_u - input_lower_u, code_interleaver );  
        end        
                             
    end         
    
    % Combine output_c and puncture
    % convert to matrices (each row is from one row of the generator)
    upper_reshaped = [ reshape( output_upper_c, N1, length(output_upper_c)/N1 ) ];
    lower_reshaped = [ reshape( output_lower_c, N2, length(output_lower_c)/N2 ) ];
    
    % parallel concatenate
    unpunctured_word = [upper_reshaped
        lower_reshaped];                     
    % repuncture
    output_decoder_c( codeword_index,:) = Puncture( unpunctured_word, pun_pattern, tail_pattern ); 
end

detected_data = reshape( detected_data', 1, K_data);