📄 turbodecoder.c
字号:
/*
*******************************************************************************
* ansi c source code
* file name:
* TurboDecoder.c
* abstract:
* to implement the decoder of turbo code specified in the EV-DO specification
* wiht the Log-Map algorithm
* reference:
* EV-DO specification
* author:
* Wang Jiaheng 2004-12-24
* revision history:
* Wang Jiaheng 2004-12-24 original version
* Wang Jiaheng 2005-02-04 revised version
*******************************************************************************
*/
/*
*******************************************************************************
* include files
*******************************************************************************
*/
#include <string.h>
#include <math.h>
/*
*******************************************************************************
* constants and define declarations
*******************************************************************************
*/
/* maximum packer size in turbo code */
#define MAX_TURBO_PACKET_SIZE 4096
/* maximum number of states in the trellis of the encoder */
#define MAX_TURBO_STATE_NUM 8
/* the maximum negative value used in log-Map algorithm */
#define MAX_NEGATIVE (-1e20)
/* maximum number of the corrention terms used in log-Map algorithm */
#define MAX_CORRECT_TERM_NUM 8
/*
*******************************************************************************
* extern objects declaration
*******************************************************************************
*/
/* for storing the new addresses after turbo interleaving */
extern int turbo_interleaved_addr[MAX_TURBO_PACKET_SIZE];
/* length of the new addresses after turbo interleaving */
extern int turbo_interleaved_len;
/*
*******************************************************************************
* local object definition
*******************************************************************************
*/
/* the previous state of every current state */
int turbo_prev_state[MAX_TURBO_STATE_NUM][2] =
{
{0, 1},
{3, 2},
{4, 5},
{7, 6},
{1, 0},
{2, 3},
{5, 4},
{6, 7}
};
/* the posterior state of every current state */
int turbo_post_state[MAX_TURBO_STATE_NUM][2] =
{
{0, 4},
{4, 0},
{5, 1},
{1, 5},
{2, 6},
{6, 2},
{7, 3},
{3, 7}
};
/* the output symbols during the transition form one state to another state */
int turbo_trellis_output[MAX_TURBO_STATE_NUM][2][3] =
{
{ {+1, +1, +1}, {-1, -1, -1} },
{ {+1, +1, +1}, {-1, -1, -1} },
{ {+1, -1, +1}, {-1, +1, -1} },
{ {+1, -1, +1}, {-1, +1, -1} },
{ {+1, -1, -1}, {-1, +1, +1} },
{ {+1, -1, -1}, {-1, +1, +1} },
{ {+1, +1, -1}, {-1, -1, +1} },
{ {+1, +1, -1}, {-1, -1, +1} },
};
/* the correction term for Log-Map algorithm */
double turbo_correct_term[MAX_CORRECT_TERM_NUM][2] =
{/*{1.0,0.4740},
{2.0,0.2014},
{3.0,0.078},
{4.0,0.0297},
{0.25,0.6326},
{0.5,0.5231},
{0.75,0.4287},
{1.0,0.3484},
{1.25,0.2812},
{1.5,0.2254},
{1.75,0.1797},
{2.0,0.1427},
{2.25,0.1128},
{2.5,0.0899},
{2.75,0.0699},
{3.0,0.0549},
{3.25,0.0430},
{3.5,0.0336},
{3.75,0.0263},
{4.0,0.0205},
{0.3830, 0.6065},
{0.8814, 0.4332},
{1.6649, 0.2599},
{3.1174, 0.0866},*/
{0.5, 0.5759},
{1.0, 0.3869},
{1.5, 0.2519},
{2.0, 0.1602},
{2.5, 0.1002},
{3.0, 0.0619},
{3.5, 0.0380},
{4.0, 0.0232},
/*{0.5, 0.5759},
{1.0, 0.3869},
{1.5, 0.2519},
{2.0, 0.1602},
{3.0,0.078},
{4.0,0.0297},*/
};
/* for storing gamma used in the Max-log-Map algorithm */
double turbo_gamma[MAX_TURBO_STATE_NUM][2][MAX_TURBO_PACKET_SIZE];
/* for storing the middle values of gamma for the encoder 1 */
double turbo_gamma_mid_1[MAX_TURBO_STATE_NUM][2][MAX_TURBO_PACKET_SIZE];
/* for storing the middle values of gamma for the encoder 2 */
double turbo_gamma_mid_2[MAX_TURBO_STATE_NUM][2][MAX_TURBO_PACKET_SIZE];
/* for storing alfa used in the Max-log-Map algorithm */
double turbo_alfa[MAX_TURBO_STATE_NUM][MAX_TURBO_PACKET_SIZE];
/* for storing beta uesd in the Max-log-Map algorithm */
double turbo_beta[MAX_TURBO_STATE_NUM][MAX_TURBO_PACKET_SIZE];
/* for storing the a-posteriori LLRs generated by the decoder 1 */
double turbo_aposteriori_llr_1[MAX_TURBO_PACKET_SIZE];
/* for storing the a-posteriori LLRs generated by the decoder 2 */
double turbo_aposteriori_llr_2[MAX_TURBO_PACKET_SIZE];
/* for storing the a-priori LLRs for the decoder 1 */
double turbo_apriori_llr_1[MAX_TURBO_PACKET_SIZE];
/* for storing the a-priori LLRs for the decoder 2 */
double turbo_apriori_llr_2[MAX_TURBO_PACKET_SIZE];
/* for storing the received symbols of the encoder 1 */
double turbo_recv_sym_1[3][MAX_TURBO_PACKET_SIZE];
/* for storing the received symbols of the encoder 2 */
double turbo_recv_sym_2[3][MAX_TURBO_PACKET_SIZE];
/*
*******************************************************************************
* function definition
*******************************************************************************
*/
/*
*******************************************************************************
* description:
* to rebuild the received symbols according the encoding laws
* input:
* sym_in: input symbols sequence
* valid_len: valid length of a packet
* decode_len: length for decoding a packet
* encode_rate: the encoding rate (2, 3, 4 or 5)
* output:
* if ok, return 1; otherwise retrun 0.
* function reference:
* author:
* Wang Jiaheng, 2005-02-04 created
*******************************************************************************
*/
int RebuildSymbol(double sym_in[], int valid_len, int decode_len, int encode_rate)
{
int k;
int sub_a;
int sub_b;
/* reconstruct the received symbols for the encoder 1 and 2 respectively */
switch ( encode_rate )
{
/* 1/2 encoding rate */
case 2:
/* reconstruct the symbols of the first valid_len times */
for (k = 0; k < valid_len; k++)
{
sub_a = k * 2;
if ( k % 2 == 0 )
{
/* system symbols of the encoder 1 */
turbo_recv_sym_1[0][k] = sym_in[sub_a];
/* parity symbols of the encoder 1 */
turbo_recv_sym_1[1][k] = sym_in[sub_a + 1];
turbo_recv_sym_1[2][k] = 0;
/* parity symbols of the encoder 2 */
turbo_recv_sym_2[1][k] = 0;
turbo_recv_sym_2[2][k] = 0;
}
else
{
/* system symbols of the encoder 1 */
turbo_recv_sym_1[0][k] = sym_in[sub_a];
/* parity symbols of the encoder 1 */
turbo_recv_sym_1[1][k] = 0;
turbo_recv_sym_1[2][k] = 0;
/* parity symbols of the encoder 2 */
turbo_recv_sym_2[1][k] = sym_in[sub_a + 1];
turbo_recv_sym_2[2][k] = 0;
}
}
/* reconstruct the tail symbols */
for (k = valid_len; k < decode_len; k++)
{
sub_a = k * 2;
sub_b = (k + 3) * 2;
/* tail symbols of the encoder 1 */
turbo_recv_sym_1[0][k] = sym_in[sub_a];
turbo_recv_sym_1[1][k] = sym_in[sub_a + 1];
turbo_recv_sym_1[2][k] = 0;
/* tail symbols of the encoder 2 */
turbo_recv_sym_2[0][k] = sym_in[sub_b];
turbo_recv_sym_2[1][k] = sym_in[sub_b + 1];
turbo_recv_sym_2[2][k] = 0;
}
break;
/* 1/3 encoding rate */
case 3:
/* reconstruct the symbols of the first valid_len times */
for (k = 0; k < valid_len; k++)
{
sub_a = k * 3;
/* system symbols of the encoder 1 */
turbo_recv_sym_1[0][k] = sym_in[sub_a];
/* parity symbols of the encoder 1 */
turbo_recv_sym_1[1][k] = sym_in[sub_a + 1];
turbo_recv_sym_1[2][k] = 0;
/* parity symbols of the encoder 2 */
turbo_recv_sym_2[1][k] = sym_in[sub_a + 2];
turbo_recv_sym_2[2][k] = 0;
}
/* reconstruct the tail symbols */
for (k = valid_len; k < decode_len; k++)
{
sub_a = k * 3;
sub_b = (k + 3) * 3;
/* tail symbols of the encoder 1 */
turbo_recv_sym_1[0][k] = (sym_in[sub_a] + sym_in[sub_a + 1]) / 2;
turbo_recv_sym_1[1][k] = sym_in[sub_a + 2];
turbo_recv_sym_1[2][k] = 0;
/* tail symbols of the encoder 2 */
turbo_recv_sym_2[0][k] = (sym_in[sub_b] + sym_in[sub_b + 1]) / 2;
turbo_recv_sym_2[1][k] = sym_in[sub_b + 2];
turbo_recv_sym_2[2][k] = 0;
}
break;
/* 1/4 encoding rate */
case 4:
/* reconstruct the symbols of the first valid_len times */
for (k = 0; k < valid_len; k++)
{
sub_a = k * 4;
if ( k % 2 == 0 )
{
/* system symbols of the encoder 1 */
turbo_recv_sym_1[0][k] = sym_in[sub_a];
/* parity symbols of the encoder 1 */
turbo_recv_sym_1[1][k] = sym_in[sub_a + 1];
turbo_recv_sym_1[2][k] = sym_in[sub_a + 2];
/* parity symbols of the encoder 2 */
turbo_recv_sym_2[1][k] = 0;
turbo_recv_sym_2[2][k] = sym_in[sub_a + 3];
}
else
{
/* system symbols of the encoder 1 */
turbo_recv_sym_1[0][k] = sym_in[sub_a];
/* parity symbols of the encoder 1 */
turbo_recv_sym_1[1][k] = sym_in[sub_a + 1];
turbo_recv_sym_1[2][k] = 0;
/* parity symbols of the encoder 2 */
turbo_recv_sym_2[1][k] = sym_in[sub_a + 2];
turbo_recv_sym_2[2][k] = sym_in[sub_a + 3];
}
}
/* reconstruct the tail symbols */
for (k = valid_len; k < decode_len; k++)
{
sub_a = k * 4;
sub_b = (k + 3) * 4;
/* tail symbols of the encoder 1 */
turbo_recv_sym_1[0][k] = (sym_in[sub_a] + sym_in[sub_a + 1]) / 2;
turbo_recv_sym_1[1][k] = sym_in[sub_a + 2];
turbo_recv_sym_1[2][k] = sym_in[sub_a + 3];
/* tail symbols of the encoder 2 */
turbo_recv_sym_2[0][k] = (sym_in[sub_b] + sym_in[sub_b + 1]) / 2;
turbo_recv_sym_2[1][k] = sym_in[sub_b + 2];
turbo_recv_sym_2[2][k] = sym_in[sub_b + 3];
}
break;
/* 1/5 encoding rate */
case 5:
/* reconstruct the symbols of the first valid_len times */
for (k = 0; k < valid_len; k++)
{
sub_a = k * 5;
/* system symbols of the encoder 1 */
turbo_recv_sym_1[0][k] = sym_in[sub_a];
/* parity symbols of the encoder 1 */
turbo_recv_sym_1[1][k] = sym_in[sub_a + 1];
turbo_recv_sym_1[2][k] = sym_in[sub_a + 2];
/* parity symbols of the encoder 2 */
turbo_recv_sym_2[1][k] = sym_in[sub_a + 3];
turbo_recv_sym_2[2][k] = sym_in[sub_a + 4];
}
/* reconstruct the tail symbols */
for (k = valid_len; k < decode_len; k++)
{
sub_a = k * 5;
sub_b = (k + 3) * 5;
/* tail symbols of the encoder 1 */
turbo_recv_sym_1[0][k] = (sym_in[sub_a] + sym_in[sub_a + 1]) / 2;
turbo_recv_sym_1[1][k] = sym_in[sub_a + 2];
turbo_recv_sym_1[2][k] = (sym_in[sub_a + 3] + sym_in[sub_a + 4]) / 2;
/* tail symbols of the encoder 2 */
turbo_recv_sym_2[0][k] = (sym_in[sub_b] + sym_in[sub_b + 1]) / 2;
turbo_recv_sym_2[1][k] = sym_in[sub_b + 2];
turbo_recv_sym_2[2][k] = (sym_in[sub_b + 3] + sym_in[sub_b + 4]) / 2;
}
break;
default:
return 0;
}
/* interleave systematic symbols */
for (k = 0; k < valid_len; k++)
{
/* system symbols of the encoder 1 */
turbo_recv_sym_2[0][k] = turbo_recv_sym_1[0][turbo_interleaved_addr[k]];
}
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -