⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 turbodecoder.c

📁 信道编解码中的turbo编解码程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*******************************************************************************
* 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 + -