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

📄 turbo_code_log_map.c

📁 一些关于Turbo编码译码实现所需的函数和原程序。
💻 C
📖 第 1 页 / 共 5 页
字号:
/*----------------------------------------------------------
* Copyright (c) 2003, 北京邮电大学移动通信实验室
* All rights reserved.
*
* 文件名称:turbo_code_Log_MAP.c
* 文件标识:
* 摘    要:Turbo编译码实现函数文件.
*
* 当前版本:1.0
* 作    者:张鹏
* 完成日期:2003年12月1日
----------------------------------------------------------*/

#include "turbo_code_Log_MAP.h"

/*==================================================*/
/* Log-MAP算法用到的查找表 */
const double lookup_index_Log_MAP[16] = {0.0, 0.08824, 0.19587, 0.31026, 0.43275, 0.56508,
								0.70963, 0.86972, 1.0502, 1.2587, 1.5078, 1.8212,
								2.2522, 2.9706, 3.6764, 4.3758};
const double lookup_table_Log_MAP[16] = {0.69315, 0.65, 0.6, 0.55, 0.5, 0.45, 0.4, 0.35,
								0.3, 0.25, 0.2, 0.15, 0.1, 0.05, 0.025, 0.0125};

/* CDMA2000中Turbo码所使用的交织器要使用该查找表。
各列分别对应于N=4,5,6,7,8,9,10。N>=log2(Nturbo)-5。*/
const int lookuptable_cdma2000[7][32] = 
{{5,15,5,15,1,9,9,15,13,15,7,11,15,3,15,5,13,15,9,3,1,3,15,1,13,1,9,15,11,3,15,5},
{27,3,1,15,13,17,23,13,9,3,15,3,13,1,13,29,21,19,1,3,29,17,25,29,9,13,23,13,13,1,13,13},
{3,27,15,13,29,5,1,31,3,9,15,31,17,5,39,1,19,27,15,13,45,5,33,15,13,9,15,31,17,5,15,33},
{15,127,89,1,31,15,61,47,127,17,119,15,57,123,95,5,85,17,55,57,15,41,93,87,63,15,13,15,81,57,31,69},
{3,1,5,83,19,179,19,99,23,1,3,13,13,3,17,1,63,131,17,131,211,173,231,171,23,147,243,213,189,51,15,67},
{13,335,87,15,15,1,333,11,13,1,121,155,1,175,421,5,509,215,47,425,295,229,427,83,409,387,193,57,501,313,489,391},
{1,349,303,721,973,703,761,327,453,95,241,187,497,909,769,349,71,557,197,499,409,259,335,253,677,717,313,757,189,15,75,163}};

/*==================================================*/
/* 与生成阵相关的参数 */
const int M_num_reg = COLUMN_OF_G-1;		/* 寄存器数 */
const int n_states = 8;						/* 状态数:2的M_num_reg次幂 */
/*==================================================*/

extern double *alpha_channel;

/*---------------------------------------------------------------
函数:
	TurboCodingTraffic(int *trafficflow_source, int *coded_trafficflow_source,
						int *traffic_source_length)
介绍:
	Turbo码业务信息编码函数.
参数:
	输入参数: trafficflow_source - 源bit序列首址.
			  traffic_source_length - 源bit序列长度.
	输出参数: coded_trafficflow_source - 编码后的序列首址.
返回值:
---------------------------------------------------------------*/
void TurboCodingTraffic(int *trafficflow_source, float *coded_trafficflow_source,
						int *traffic_source_length)
{
	int i;							/* 循环变量 */

	int *temp_send = NULL;			
	int *send = NULL;				/* 发送序列首址 */
	int *send_punc = NULL;			/* 打孔后的发送序列首址 */

	int length_info = *traffic_source_length;		/* 信息位长度 */
/*
	switch( length_info/320 )
	{
	case 1:
	case 2:
	case 4:
		break;
	default:
		{
			printf("Wrong frame length!\n");
			exit(1);
		}
	}
*/
	/* 申请内存 */
	if ((send=(int *)malloc((3*length_info+4*M_num_reg)*sizeof(int)))==NULL)
	{
		printf("\n fail to allocate memory of send \n");
		exit(1);
	}

	if ((send_punc=(int *)malloc(2*length_info*sizeof(int)))==NULL)
	{
		printf("\n fail to allocate memory of send_punc \n");
		exit(1);  
	}

	/* 生成随机交织器下标 */
	if (TYPE_INTERLEAVER == 2)
	{
		gen_rand_index(length_info, 1);
	}

	encoderm_turbo(trafficflow_source, send, length_info, 1);	/* 编码,BPSK调制 */

	temp_send = send;

	if (TURBO_PUNCTURE)			/* 打孔 */
	{
		puncture(send, 3*length_info+4*M_num_reg, send_punc, 3, length_info/4, 4);
		temp_send = send_punc;
	}

	/* 写输出序列 */
	for (i=0; i<((3-TURBO_PUNCTURE)*length_info+4*M_num_reg*(1-TURBO_PUNCTURE)); i++)
	{
		*(coded_trafficflow_source+i) = (float) *(temp_send+i);
	}

	/* 修改数据长度变量 */
	*traffic_source_length = (3-TURBO_PUNCTURE)*length_info+4*M_num_reg*(1-TURBO_PUNCTURE);

	free(send);
	free(send_punc);
}


/*---------------------------------------------------------------
函数:
	void TurboDecodingTraffic(double *trafficflow_for_decode, int *trafficflow_decoded,
						  int *trafficflow_length, double EbN0dB)
介绍:
	Turbo码业务信息译码函数.
参数:
	输入参数: trafficflow_for_decode - 输入序列首址.
			  trafficflow_length - 输入序列长度.
			  EbN0dB - 信噪比.
	输出参数: trafficflow_decoded - 译码后的序列首址.
返回值:
---------------------------------------------------------------*/
void TurboDecodingTraffic(float *trafficflow_for_decodeA,float *trafficflow_for_decodeB,float *trafficflow_for_decodeAB, int *trafficflow_decodedAB,  int *trafficflow_length, float EbN0dB)
{
	int i;							/* 循环变量 */
	int length_info, length_total;	/* 信息位长和总长度 */
	int length_infoAB, length_totalAB;
	int iteration;					/* 叠代循环变量 */

									/* 接收数据 */ 
	double *yk_turboA = NULL;					/* 包含ys和yp */
	double *yk_turboB = NULL;
	double *yk_turboAB = NULL;
	double *infoAB = NULL;
	double *interleavedAB = NULL;
	double *La_turboA, *Le_turboA, *LLR_all_turboA, *La_turboB, *Le_turboB, *LLR_all_turboB;		/* 外信息和似然比 */
	double *La_turboAB, *Le_turboAB, *LLR_all_turboAB;
	int *tempout=NULL;

	double en_rate = (double)pow(10, EbN0dB*0.1);
	double Lc_turbo = 4*en_rate/3;			/* 信道可靠性值 */

	/* 计算信息位长度 */
	length_info = *trafficflow_length;
	length_infoAB = (*(trafficflow_length))*2;

	/* 总长度 */
	length_total = length_info+M_num_reg;
	length_totalAB = length_infoAB+M_num_reg;
	/* 申请内存 */


	if ((yk_turboA=(double *)malloc(2*length_total*sizeof(double)))==NULL)
	{
	  printf("\n fail to allocate memory of yk_turbo \n");
	  exit(1);  
	}
	if ((yk_turboB=(double *)malloc(2*length_total*sizeof(double)))==NULL)
	{
		printf("\n fail to allocate memory of yk_turbo \n");
		exit(1);  
	}
	if ((yk_turboAB=(double *)malloc(2*length_totalAB*sizeof(double)))==NULL)
	{
		printf("\n fail to allocate memory of yk_turbo \n");
		exit(1);  
	}
	if ((infoAB=(double *)malloc(length_infoAB*sizeof(double)))==NULL)
	{
		printf("\n fail to allocate memory of yk_turbo \n");
		exit(1);  
	}
	if ((interleavedAB=(double *)malloc(length_infoAB*sizeof(double)))==NULL)
	{
		printf("\n fail to allocate memory of yk_turbo \n");
		exit(1);  
	}

	if ((La_turboA=(double *)malloc(length_total*sizeof(double)))==NULL)
	{
	  printf("\n fail to allocate memory of La_turbo \n");
	  exit(1);  
	}
	if ((Le_turboA=(double *)malloc(length_total*sizeof(double)))==NULL)
	{
	  printf("\n fail to allocate memory of Le_turbo \n");
	  exit(1);  
	}
	if ((LLR_all_turboA=(double *)malloc(length_total*sizeof(double)))==NULL)
	{
	  printf("\n fail to allocate memory of LLR_all_turbo \n");
	  exit(1);  
	}

	if ((La_turboB=(double *)malloc(length_total*sizeof(double)))==NULL)
	{
		printf("\n fail to allocate memory of La_turbo \n");
		exit(1);  
	}
	if ((Le_turboB=(double *)malloc(length_total*sizeof(double)))==NULL)
	{
		printf("\n fail to allocate memory of Le_turbo \n");
		exit(1);  
	}
	if ((LLR_all_turboB=(double *)malloc(length_total*sizeof(double)))==NULL)
	{
		printf("\n fail to allocate memory of LLR_all_turbo \n");
		exit(1);  
	}

	if ((La_turboAB=(double *)malloc(length_totalAB*sizeof(double)))==NULL)
	{
		printf("\n fail to allocate memory of La_turbo \n");
		exit(1);  
	}
	if ((Le_turboAB=(double *)malloc(length_totalAB*sizeof(double)))==NULL)
	{
		printf("\n fail to allocate memory of Le_turbo \n");
		exit(1);  
	}
	if ((LLR_all_turboAB=(double *)malloc(length_totalAB*sizeof(double)))==NULL)
	{
		printf("\n fail to allocate memory of LLR_all_turbo \n");
		exit(1);  
	}
	
	if ((tempout=(int *)malloc(length_totalAB*sizeof(int)))==NULL)
	{
	  printf("\n fail to allocate memory of tempout \n");
	  exit(1);  
	}

	/* 乘信道衰落 */
/*
				for (i=0; i<2*length_total; i++)
						{
							*(yk_turboA+i) =(double)( *(yk_turboA+i)*(1+TYPE_CHANNEL)*(*(alpha_channel+i)));
							*(yk_turboB+i) =(double)( *(yk_turboB+i)*(1+TYPE_CHANNEL)*(*(alpha_channel+i)));
						}
						for (i=0; i<2*length_totalAB; i++)
						{
							*(yk_turboAB+i) =(double)( *(yk_turboAB+i)*(1+TYPE_CHANNEL)*(*(alpha_channel+i)));
						}*/
			

	
		

	
	for (i=0; i<2*length_total; i++)
	{
		*(yk_turboA+i)=(double)(*(trafficflow_for_decodeA+i));
		*(yk_turboB+i)=(double)(*(trafficflow_for_decodeB+i));
	}
	comboinfoAB(infoAB,yk_turboA,yk_turboB);
	
	interleave_double(infoAB, interleavedAB, TYPE_INTERLEAVER, length_infoAB, 1);

	for (i=0; i<length_infoAB; i++)
	{
		*(yk_turboAB+2*i)=(double)(*(interleavedAB+i));
		*(yk_turboAB+2*i+1)=(double)(*(trafficflow_for_decodeAB+i));
	}
	for (i=4*length_info; i<2*length_totalAB;i++)
	{
		*(yk_turboAB+i)=(double)(*(trafficflow_for_decodeAB+i-length_infoAB));
	}

	



	
	

//	for (i=0; i<2*length_total; i++)
	//	{
	//		*(yk_turboA+i) =(double)( *(yk_turboA+i)*(1+TYPE_CHANNEL));
	//		*(yk_turboB+i) =(double)( *(yk_turboB+i)*(1+TYPE_CHANNEL));
	//	}
	//	for (i=0; i<2*length_totalAB; i++)
	//	{
	//		*(yk_turboAB+i) =(double)( *(yk_turboAB+i)*(1+TYPE_CHANNEL));
	//	}
	
	
	/*	scale数据	*/
//	for (i=0; i<2*length_total; i++)
	//	{
	//		*(yk_turboA+i) = (double)( *(yk_turboA+i) * Lc_turbo *0.5 );
	//		*(yk_turboB+i) = (double)( *(yk_turboB+i) * Lc_turbo *0.5 );
	//	}
	//	for (i=0; i<2*length_totalAB; i++)
	//	{
	//		*(yk_turboAB+i) = (double)( *(yk_turboAB+i) * Lc_turbo *0.5 );
	//	}
		

	/* 初始化外信息和似然信息 */
	for (i=0; i<length_total; i++)
	{
		*(La_turboA+i) = *(Le_turboA+i) = *(LLR_all_turboA+i) = 0;
		*(La_turboB+i) = *(Le_turboB+i) = *(LLR_all_turboB+i) = 0;
	}

	for (i=0; i<length_totalAB; i++)
	{
		*(La_turboAB+i) = *(Le_turboAB+i) = *(LLR_all_turboAB+i) = 0;
	}

	for (iteration=0; iteration<N_ITERATION; iteration++)		/* 开始叠代 */
	{
		/* 译码器1: */
		/* 解交织来自译码器2的外信息 */
		de_interleave_double(La_turboAB, Le_turboAB, TYPE_INTERLEAVER, length_infoAB, 1);
		doubledecombo(La_turboAB,La_turboA,La_turboB);

		/* 结尾处赋0 */
		for (i=length_info; i<length_total; i++)
		{
			*(La_turboA+i) = 0;
			*(La_turboB+i) = 0;
		}

		/* Log-MAP算法 */
			Log_MAP_decoder(yk_turboA, La_turboA, 1, LLR_all_turboA, length_total);
		
			Log_MAP_decoder(yk_turboB, La_turboB, 1, LLR_all_turboB, length_total);
		

			
			/* 计算外信息 */
		
		for (i=0; i<length_total; i++)
		{
			*(Le_turboA+i) = *(LLR_all_turboA+i) - *(La_turboA+i) - 2*(*(yk_turboA+2*i));
			*(Le_turboB+i) = *(LLR_all_turboB+i) - *(La_turboB+i) - 2*(*(yk_turboB+2*i));
		}
		doublecombo(Le_turboA,Le_turboB,Le_turboAB);
		
		/* 译码器2: */
		/* 交织来自译码器1的外信息 */
		interleave_double(Le_turboAB, La_turboAB, TYPE_INTERLEAVER, length_infoAB, 1);

		/* 结尾处赋0 */
		for (i=length_infoAB; i<length_totalAB; i++)
		{
			*(La_turboAB+i) = 0;
		}
						
/* Log-MAP算法 */
		Log_MAP_decoder(yk_turboAB, La_turboAB, 1, LLR_all_turboAB, length_totalAB);
		
//		for (i=0; i<length_totalAB; i++)
		//		{
		//			printf("%f ",*(LLR_all_turboAB+i));
		//		}
		
		/* 计算外信息 */
		for(i=0; i<length_totalAB; i++)
		{
			*(Le_turboAB+i) = *(LLR_all_turboAB+i) - *(La_turboAB+i) - (2-TYPE_CHANNEL)*(*(yk_turboAB+2*i));
		}
		/* 译码器2结束 */
	}
	
	/* 对全部似然比判决 */
	decision(LLR_all_turboAB, length_totalAB, tempout);

	/* 对判决比特解交织 */
	de_interleave_int(trafficflow_decodedAB, tempout, TYPE_INTERLEAVER, length_infoAB, 1);

	/* 修改长度变量 */
	*trafficflow_length = length_info;

//	free(receive_punc);
	free(yk_turboA);
	free(La_turboA);
	free(Le_turboA);
	free(LLR_all_turboA);
	
	free(yk_turboB);
	free(La_turboB);
	free(Le_turboB);
	free(LLR_all_turboB);

	free(yk_turboAB);
	free(La_turboAB);
	free(Le_turboAB);
	free(LLR_all_turboAB);
	
	free(infoAB);
	free(interleavedAB);
	free(tempout);
}

/*---------------------------------------------------------------
函数:
	void TurboCodingSupflow(int *supflow, double *coded_supflow, int *supflow_length)

介绍:
	Turbo码补充信息编码函数.
参数:
	输入参数: supflow - 源bit序列首址.
			  supflow_length - 源bit序列长度.
	输出参数: coded_supflow - 编码后的序列首址.
返回值:
---------------------------------------------------------------*/
void TurboCodingSupflow(int *supflow, float *coded_supflow, int *supflow_length)
{
	int i;						/* 循环变量 */

	int *temp_send = NULL;
	int *send = NULL;			/* 发送序列首址 */
	int *send_punc = NULL;		/* 打孔后的发送序列首址 */

	int length_info = *supflow_length;		/* 信息位长度 */

	switch( length_info/320 )
	{
	case 1:
	case 2:
	case 4:
		break;
	default:
		{
			printf("Wrong frame length!\n");
			exit(1);
			break;
		}
	}

	/* 申请内存 */
	if ((send=(int *)malloc((3*length_info+4*M_num_reg)*sizeof(int)))==NULL)
	{
		printf("\n fail to allocate memory of send \n");
		exit(1);  
	}

	if ((send_punc=(int *)malloc(2*length_info*sizeof(int)))==NULL)
	{
		printf("\n fail to allocate memory of send_punc \n");
		exit(1);  
	}

	/* 生成随机交织器下标 */
	if (TYPE_INTERLEAVER == 2)
	{
		gen_rand_index(length_info, 0);
	}

	encoderm_turbo(supflow, send, length_info, 0);	/* 编码,BPSK调制 */

	temp_send = send;

	if (TURBO_PUNCTURE)			/* 打孔 */
	{
		puncture(send, 3*length_info+4*M_num_reg, send_punc, 3, length_info/4, 4);
		temp_send = send_punc;
	}

	/* 写输出序列 */
	for (i=0; i<((3-TURBO_PUNCTURE)*length_info+4*M_num_reg*(1-TURBO_PUNCTURE)); i++)
	{
		*(coded_supflow+i) = (float) *(temp_send+i);
	}

	/* 修改数据长度变量 */
	*supflow_length = (3-TURBO_PUNCTURE)*length_info+4*M_num_reg*(1-TURBO_PUNCTURE);

	free(send);
	free(send_punc);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -