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

📄 turbo_code_log_map.c

📁 一些关于Turbo编码译码实现所需的函数和原程序。
💻 C
📖 第 1 页 / 共 5 页
字号:
/*---------------------------------------------------------------
函数:
	void TurboDecodingSupflow(double *supflow_for_decode, int *supflow_decoded,
							  int *supflow_length, double EbN0dB)
介绍:
	Turbo码补充信息译码函数.
参数:
	输入参数: supflow_for_decode - 输入序列首址.
			  supflow_length - 输入序列长度.
			  EbN0dB - 信噪比.
	输出参数: supflow_decoded - 译码后的序列首址.
返回值:
---------------------------------------------------------------*/
void TurboDecodingSupflow(float *supflow_for_decode, int *supflow_decoded,
						  int *supflow_length, float EbN0dB)
{
	int i;								/* 循环变量 */
	int length_info, length_total;		/* 信息位长和总长度 */
	int iteration;						/* 信息位长和总长度 */

	float *receive_punc = NULL;					/*	接收数据	*/
	double *yk_turbo = NULL;					/* 包含ys和yp */
	double *La_turbo, *Le_turbo, *LLR_all_turbo;		/*	外信息和似然比	*/

	int *tempout;

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

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

	/* 计算信息位长度 */
	if (TURBO_PUNCTURE)
	{
		length_info = (*supflow_length)/2;
	}
	else
	{
		length_info = (*supflow_length-4*M_num_reg)/3;
	}

	/* 总长度 */
	length_total = length_info+M_num_reg;

	if ((receive_punc=(float *)malloc((3*length_info+4*M_num_reg)*sizeof(float)))==NULL)
	{
		printf("\n fail to allocate memory of receive_punc \n");
		exit(1);  
	}

	if ((yk_turbo=(double *)malloc(4*length_total*sizeof(double)))==NULL)
	{
	  printf("\n fail to allocate memory of yk_turbo \n");
	  exit(1);  
	}

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

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

	if (TURBO_PUNCTURE)		/* 填充 */
	{
		depuncture(supflow_for_decode, 2*length_info, receive_punc, 3, length_info/4, 4);
		demultiplex(receive_punc, length_info, yk_turbo, 0);		/* 解复用 */
	}
	else
	{
		demultiplex(supflow_for_decode, length_info, yk_turbo, 0);	/* 解复用 */
	}
	
	/*	scale数据	*/
	for (i=0; i<2*length_total*2; i++)
	{
		*(yk_turbo+i) = (double)( *(yk_turbo+i) * Lc_turbo *0.5 );
	}
	
	/* 初始化外信息和似然信息 */
	for (i=0; i<length_total; i++)
	{
		*(La_turbo+i) = *(Le_turbo+i) = *(LLR_all_turbo+i) = 0;
	}

	for (iteration=0; iteration<N_ITERATION; iteration++)		/* 开始叠代 */
	{
		/* 译码器1: */
		/* 得到来自译码器2的外信息 */
		de_interleave_double(La_turbo, Le_turbo, TYPE_INTERLEAVER, length_info, 0);
		
		/* 结尾处赋0 */
		for (i=length_info; i<length_total; i++)
		{
			*(La_turbo+i) = 0;
		}
		switch(TYPE_DECODER)
		{
		case 1:			/* Log-MAP算法 */
			Log_MAP_decoder(yk_turbo, La_turbo, 1, LLR_all_turbo, length_total);
			break;
		case 2:
			MAX_Log_MAP_decoder(yk_turbo, La_turbo, 1, LLR_all_turbo, length_total);
			break;
		default:
			break;
		}
		/* 计算外信息 */
		for (i=0; i<length_total; i++)
		{
			*(Le_turbo+i) = *(LLR_all_turbo+i) - *(La_turbo+i) - 2*(*(yk_turbo+2*i));
		}

		/* 译码器2: */
		/* 交织来自译码器1的外信息 */
		interleave_double(Le_turbo, La_turbo, TYPE_INTERLEAVER, length_info, 0);

		/* 结尾处赋0 */
		for (i=length_info; i<length_total; i++)
		{
			*(La_turbo+i) = 0;
		}
						
		switch(TYPE_DECODER)
		{
		case 1:			/* Log-MAP算法 */
			Log_MAP_decoder(yk_turbo+2*length_total, La_turbo, 1, LLR_all_turbo, length_total);
			break;
		case 2:
			MAX_Log_MAP_decoder(yk_turbo+2*length_total, La_turbo, 1, LLR_all_turbo, length_total);
			break;
		default:
			break;
		}
		/* 计算外信息 */
		for(i=0; i<length_total; i++)
		{
			*(Le_turbo+i) = *(LLR_all_turbo+i) - *(La_turbo+i) - 2*(*(yk_turbo+2*length_total+2*i));
		}
		/* 译码器2结束 */
	}
	
	/* 对全部似然比判决 */
	decision(LLR_all_turbo, length_total, tempout);

	/* 对判决比特解交织 */
	de_interleave_int(supflow_decoded, tempout, TYPE_INTERLEAVER, length_info, 0);

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

	free(receive_punc);
	free(yk_turbo);

	free(La_turbo);
	free(Le_turbo);
	free(LLR_all_turbo);

	free(tempout);
}
/*---------------------------------------------------------------
函数:
	void TurboCodingInit()
介绍:
	Turbo码初始化函数.
参数:
返回值:
---------------------------------------------------------------*/
void TurboCodingInit()
{
	/* 初始化生成阵 */
	turbo_g.N_num_row = 2;				/* 行数 */
	turbo_g.K_num_col = COLUMN_OF_G;	/* 列数 */

	/* 计算编码速率,打孔为1/2,不打孔为1/3 */
	rate_coding =  (double)(1/3);

	if ((turbo_g.g_matrix=(int *)malloc(turbo_g.N_num_row*turbo_g.K_num_col*sizeof(int)))==NULL)
	{
		printf("\n fail to allocate memory of turbo_g\n");
		exit(1);  
	}

	/* 得到生成阵 */
	if (!gen_g_matrix(turbo_g.K_num_col, G_ROW_1, G_ROW_2, turbo_g.g_matrix))
	{
		printf("error number of G\n");
		exit(1);
	}

	/* 生成删余阵 */
	if ((mx_puncture_turbo_80=(int *)malloc(sizeof(int)*3*80))==NULL)
	{
		printf("\n fail to allocate memory of mx_puncture_turbo_80\n");
		exit(1);  
	}
	if ((mx_puncture_turbo_160=(int *)malloc(sizeof(int)*3*160))==NULL)
	{
		printf("\n fail to allocate memory of mx_puncture_turbo_160\n");
		exit(1);  
	}
	if ((mx_puncture_turbo_320=(int *)malloc(sizeof(int)*3*320))==NULL)
	{
		printf("\n fail to allocate memory of mx_puncture_turbo_320\n");
		exit(1);  
	}

	if (!gen_mx_punc())
	{
		printf("\nError! Can not generate the puncture matrix properly!\n");
		exit(1);
	}


	/* 生成Trellis */
	if ((turbo_trellis.mx_lastout=(int *)malloc(sizeof(int)*n_states*4))==NULL)
	{
	  printf("\n fail to allocate memory of turbo_trellis.mx_lastout \n");
	  exit(1);  
	}
	if ((turbo_trellis.mx_laststat=(int *)malloc(sizeof(int)*n_states*2))==NULL)
	{
	  printf("\n fail to allocate memory of turbo_trellis.mx_laststat \n");
	  exit(1);  
	}
	if ((turbo_trellis.mx_nextout=(int *)malloc(sizeof(int)*n_states*4))==NULL)
	{
	  printf("\n fail to allocate memory of turbo_trellis.mx_nextout \n");
	  exit(1);  
	}
	if ((turbo_trellis.mx_nextstat=(int *)malloc(sizeof(int)*n_states*2))==NULL)
	{
	  printf("\n fail to allocate memory of turbo_trellis.mx_nextstat \n");
	  exit(1);  
	}

	gen_trellis();

	/* 为随机交织器分配内存 */
	if (TYPE_INTERLEAVER==2)
	{
		/* 业务信息随机交织器 */
		if ((index_randomintlvr=(int *)malloc(MAX_FRAME_LENGTH*sizeof(int)))==NULL)
		{
			printf("\n fail to allocate memory of index_randomintlvr \n");
			exit(1);  
		}
		/* 补充信息随机交织器 */
		if ((index_randomintlvr_sup=(int *)malloc(SUP_FRAME_LENGTH*sizeof(int)))==NULL)
		{
			printf("\n fail to allocate memory of index_randomintlvr_sup \n");
			exit(1);  
		}
	}
}

/*---------------------------------------------------------------
函数:
	void TurboCodingRelease()
介绍:
	释放Turbo码初始化时的内存.
参数:
返回值:
---------------------------------------------------------------*/
void TurboCodingRelease()
{
	/* 释放生成阵内存 */
	free(turbo_g.g_matrix);

	/* 释放删余阵内存 */
	free(mx_puncture_turbo_80);
	free(mx_puncture_turbo_160);
	free(mx_puncture_turbo_320);

	/* 释放trellis结构内存 */
	free(turbo_trellis.mx_lastout);
	free(turbo_trellis.mx_laststat);
	free(turbo_trellis.mx_nextout);
	free(turbo_trellis.mx_nextstat);

	/* 释放随机交织器内存 */
	if (TYPE_INTERLEAVER==2)
	{
		free(index_randomintlvr);
		free(index_randomintlvr_sup);
	}
}
/*---------------------------------------------------------------
函数:
	int gen_g_matrix(int k_column, int g_row1, int g_row2, int *mx_g_turbo)
介绍:
	得到生成阵.
参数:
	输入参数:
		k_column - 生成阵列数.
		g_row1 - 生成阵第一行.
		g_row2 - 生成阵第二行.
	输出参数:
		mx_g_turbo - 生成阵首址.
返回值:
	1 - 成功地得到生成阵.
	0 - 生成生成阵失败.
---------------------------------------------------------------*/
int gen_g_matrix(int k_column, int g_row1, int g_row2, int *mx_g_turbo)
{
	int i, position;		/* 循环变量 */
	int high_num, low_num;
	
	/* 第一行 */
	high_num = g_row1;		
	position = 1;			/* 第几个8进制数 */
	while (high_num>0)
	{
		low_num = high_num%10;	/* 得到这个8进制数 */
		if (low_num>7)			/* 判断是否为8进制数 */
		{
			return 0;
		}
		high_num = high_num/10;		/* 记下其余部分 */

		/* 将8进制数转为二进制并保存 */
		for (i=k_column-(position-1)*3-1; i>=0 && i>=k_column-position*3; i--)
		{
			*(mx_g_turbo+i) = low_num%2;
			low_num = low_num/2;
		}
		position++;		/* 下一个位置 */
		if (i<0)
		{
			break;
		}
	}

	/* 第二行 */
	high_num = g_row2;
	position = 1;			/* 第几个8进制数 */
	while (high_num>0)
	{
		low_num = high_num%10;		/* 得到这个8进制数 */
		if (low_num>7)				/* 判断是否为8进制数 */
		{
			return 0;
		}
		high_num = high_num/10;		/* 记下其余部分 */

		/* 将8进制数转为二进制并保存 */
		for (i=k_column-(position-1)*3-1; i>=0 && i>=k_column-position*3; i--)
		{
			*(mx_g_turbo+k_column+i) = low_num%2;
			low_num = low_num/2;
		}
		position++;					/* 下一个位置 */
		if (i<0)
		{
			break;
		}
	}
	return 1;
}

/*---------------------------------------------------------------
函数:
	void gen_trellis()
介绍:
	生成Trellis.
参数:
返回值:
---------------------------------------------------------------*/
void gen_trellis()
{
	int i, j, k;						/* 循环变量 */
	int dk_turbo, ak_turbo, outbit;		/* 编码器内部比特和输出比特 */

	int *tempstat;						/* 状态序列 */

	if ((tempstat=(int *)malloc(sizeof(int)*M_num_reg))==NULL)
	{
	  printf("\n fail to allocate memory of tempstat \n");
	  exit(1);  
	}
	/* 生成后向输出和后向状态矩阵 */
	for (i=0; i<n_states; i++)			/* 状态循环 */
	{
		for (j=0; j<2; j++)				/* 输入为0,1 */
		{
			int2bin(i, tempstat, M_num_reg);	/* 将状态转为二进制序列 */

			/* dk */
			dk_turbo = j;

			/* 计算ak */
			ak_turbo = (*(turbo_g.g_matrix+0)) * dk_turbo;
			for (k=1; k<turbo_g.K_num_col; k++)
			{
				ak_turbo = ak_turbo + (*(turbo_g.g_matrix+k)) * (*(tempstat+k-1));
			}

			ak_turbo = ak_turbo % 2;

			/* 计算输出比特,修改状态序列 */
			outbit = encode_bit(ak_turbo, tempstat);

			/* 写入后向输出和后向状态矩阵 */
			*(turbo_trellis.mx_nextout+i*4+2*j)=2*dk_turbo-1;
			*(turbo_trellis.mx_nextout+i*4+2*j+1)=2*outbit-1;
			*(turbo_trellis.mx_nextstat+i*2+j)=bin2int(tempstat, M_num_reg);
		}			/* 输入循环结束 */

	}	/* 状态循环结束 */

	/* 生成前向输出和前向状态矩阵 */
	for (i=0; i<n_states; i++)	/* 状态循环 */
	{
		for (j=0; j<2; j++)/* 输入为0,1 */
		{
			*(turbo_trellis.mx_laststat+(*(turbo_trellis.mx_nextstat+i*2+j))*2+j) = i;
			*(turbo_trellis.mx_lastout+(*(turbo_trellis.mx_nextstat+i*2+j))*4+2*j)
				= *(turbo_trellis.mx_nextout+i*4+2*j);
			*(turbo_trellis.mx_lastout+(*(turbo_trellis.mx_nextstat+i*2+j))*4+2*j+1)
				= *(turbo_trellis.mx_nextout+i*4+2*j+1);
		}	/* 输入循环结束 */
	}	/* 状态循环结束 */

	free(tempstat);
}

/*---------------------------------------------------------------
函数:
	void int2bin(int intstat, int *tempstat, int length)
介绍:
	十进制数转为二进制序列.
参数:
	输入参数:
		intstat - 十进制数.
		length - 要得到的二进制序列长度.
	输出参数:
		bin_stat - 二进制序列首址.
返回值:
---------------------------------------------------------------*/
void int2bin(int intstat, int *bin_stat, int length)
{
	int i, temp;

	temp = intstat;

	/* 除以2求余数 */
	for (i=length-1; i>=0; i--)
	{
		*(bin_stat+i) = temp%2;
		temp = temp/2;
	}
}

⌨️ 快捷键说明

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