Viterbi译码程序代码.docx
- 文档编号:30006879
- 上传时间:2023-08-04
- 格式:DOCX
- 页数:25
- 大小:22.16KB
Viterbi译码程序代码.docx
《Viterbi译码程序代码.docx》由会员分享,可在线阅读,更多相关《Viterbi译码程序代码.docx(25页珍藏版)》请在冰豆网上搜索。
Viterbi译码程序代码
译码主要部分
#include"stdafx.h"
//#defineDEBUG
voiddeci2bin(intd,intsize,int*b);
intbin2deci(int*b,intsize);
intnxt_stat(intcurrent_state,intinput,int*memory_contents);
voidinit_quantizer(void);
voidinit_adaptive_quant(floates_ovr_n0);
intsoft_quant(floatchannel_symbol);
intsoft_metric(intdata,intguess);
intquantizer_table[256];
voidsdvd(intg[2][K],floates_ovr_n0,longchannel_length,float*channel_output_vector,int*decoder_output_matrix)
{
inti,j,l,ll;//循环控制变量
longt;//时间
intmemory_contents[K];//记录输入内容
intinput[TWOTOTHEM][TWOTOTHEM];//对当前状态以及下一个状态映射
intoutput[TWOTOTHEM][2];//卷积码编码输出矩阵
intnextstate[TWOTOTHEM][2];//下一个状态矩阵
intaccum_err_metric[TWOTOTHEM][2];//误差累计矩阵
intstate_history[TWOTOTHEM][K*5+1];//历史状态表
intstate_sequence[K*5+1];//状态序列
int*channel_output_matrix;//信道输出序列
intbinary_output[2];
intbranch_output[2];//0或者1的输出分支
intm,n,number_of_states,depth_of_trellis,step,branch_metric,
sh_ptr,sh_col,x,xx,h,hh,next_state,last_stop;
n=2;//1/2为卷积码传输数据的码率
m=K-1;//寄存器个数
number_of_states=(int)pow(2.0,m);//状态个数numberofstates=2^(K-1)=2^m
depth_of_trellis=K*5;
for(i=0;i { for(j=0;j input[i][j]=0;//输入数组初始化 for(j=0;j { nextstate[i][j]=0;//下一个状态数组初始化 output[i][j]=0;//输出数组初始化 } for(j=0;j<=depth_of_trellis;j++) { state_history[i][j]=0;//历史状态数组初始化state_history[4][16] } accum_err_metric[i][0]=0;//误差累计矩阵第一列初始化为0 accum_err_metric[i][1]=MAXINT;//误差累计矩阵第二列初始化为一个很大的数 } /*前向纠错简称FEC(ForwardErrorCorrection), 其原理是: 发送方将要发送的数据附加上一定的冗余纠错码一并发送, 接收方则根据纠错码对数据进行差错检测,如发现差错,由接收方进行纠正*/ /*产生状态转移矩阵、输出矩阵、输入矩阵*/ //输入矩阵表示的是FEC编码传输给下一个状态 //下一个状态由输入和当前状态给出 //输出矩阵 for(j=0;j { for(l=0;l { next_state=nxt_stat(j,l,memory_contents); input[j][next_state]=l; /*计算给定的卷积编码器输出当前状态数和输入值*/ branch_output[0]=0; branch_output[1]=0; for(i=0;i { branch_output[0]=branch_output[0]^memory_contents[i]&g[0][i]; branch_output[1]=branch_output[1]^memory_contents[i]&g[1][i]; } nextstate[j][l]=next_state;//下一个状态 output[j][l]=bin2deci(branch_output,2);//输出十进制 } } #ifdefDEBUG printf("\nInput: "); for(j=0;j { printf("\n"); for(l=0;l printf("%2d",input[j][l]); } printf("\nOutput: "); for(j=0;j { printf("\n"); for(l=0;l printf("%2d",output[j][l]); } printf("\nNextState: "); for(j=0;j { printf("\n"); for(l=0;l printf("%2d",nextstate[j][l]); } #endif channel_output_matrix=(int*)malloc(channel_length*sizeof(int)); if(channel_output_matrix==NULL) { printf("allocationisfailure! ! \n"); exit (1); } printf("\n"); /*信道输出为n行,2列,每行对应于一个通道符号给定的位和每一列对应于一个已编码的位*/ channel_length=channel_length/n; init_adaptive_quant(es_ovr_n0);//进行优化,匹配过信噪比的量化矩阵 //量化信道输出,将浮点型数据转化为整形 for(t=0;t<(channel_length*n);t=t+n) { for(i=0;i { *(channel_output_matrix+(t/n)+(i*channel_length))=soft_quant(*(channel_output_vector+(t+i))); //printf("%d",*(channel_output_matrix+(t/n)+(i*channel_length))); } } /*结束设置: 利用网格遍历开始译码通道,在编码完成后结束*/ for(t=0;t { if(t<=m) //假设从零,所以只是计算路径的所有零状态 step=(int)pow(2.0,m-t*1);//如果不写成2.0,会出现函数重载不明确的错误 else step=1; //利用state_history矩阵作为循环缓冲区 sh_ptr=(int)((t+1)%(depth_of_trellis+1));//sh_ptr为statehistory矩阵的指针 for(j=0;j { //重复每个可能的卷积编码器的输出组 for(l=0;l { branch_metric=0; //计算每个通道符号的分支度量,以及所有的信道总和在卷积编码器的输出组信道符号 binary_output[0]=(output[j][l]&0x00000002)>>1; binary_output[1]=output[j][l]&0x00000001; branch_metric=branch_metric+ abs(*(channel_output_matrix+(0*channel_length+t))-7*binary_output[0]) +abs(*(channel_output_matrix+(1*channel_length+t))-7*binary_output[1]); //选择累加误差最小的 if(accum_err_metric[nextstate[j][l]][1]>accum_err_metric[j][0]+branch_metric) { accum_err_metric[nextstate[j][l]][1]=accum_err_metric[j][0]+branch_metric; state_history[nextstate[j][l]][sh_ptr]=j; //printf("state_history[%d][%d]=%d\n",nextstate[j][l],sh_ptr,state_history[nextstate[j][l]][sh_ptr]); } }//循环l结束 }//j结束,更新网格 //accum_err_metric矩阵第二列移到第一列,第二列标志为一个很大的数 for(j=0;j { accum_err_metric[j][0]=accum_err_metric[j][1]; //printf("accum_err_metric[%d][0]=%d\n",j,accum_err_metric[j][0]); accum_err_metric[j][1]=MAXINT; } //如果网格填充完成,现在需要追踪 { for(j=0;j<=depth_of_trellis;j++)//初始化状态序列矩阵 state_sequence[j]=0; //找到的最小累积state_history元素 x=MAXINT; for(j=0;j<(number_of_states/2);j++) { if(accum_err_metric[j][0] { xx=accum_err_metric[j][0]; hh=j; } else { xx=accum_err_metric[number_of_states-1-j][0]; hh=number_of_states-1-j; } if(xx { x=xx; h=hh; } } state_sequence[depth_of_trellis]=h; for(j=depth_of_trellis;j>0;j--) { sh_col=j+(sh_ptr-depth_of_trellis); if(sh_col<0) sh_col=sh_col+depth_of_trellis+1; state_sequence[j-1]=state_history[state_sequence[j]][sh_col]; } //找出输入序列对应的状态序列在最佳路径 *(decoder_output_matrix+t-depth_of_trellis+1)=input[state_sequence[0]][state_sequence[1]]; //printf("译码输出: %d\n",*(decoder_output_matrix+t-depth_of_trellis+1)); }//if状态 }//结束t循环 //译码信道中的数据 for(t=channel_length-m;t { sh_ptr=(int)((t+1)%(depth_of_trellis+1)); last_stop=number_of_states/pow(2.0,t-channel_length+m);//不需要考虑输入的状态是1,所以确定最高可能的状态数是0 for(j=0;j { branch_metric=0; deci2bin(output[j][0],n,binary_output); for(ll=0;ll { branch_metric=branch_metric+soft_metric(*(channel_output_matrix+(ll*channel_length+t)),binary_output[ll]); } if((accum_err_metric[nextstate[j][0]][1]>accum_err_metric[j][0]+branch_metric)) { accum_err_metric[nextstate[j][0]][1]=accum_err_metric[j][0]+branch_metric; state_history[nextstate[j][0]][sh_ptr]=j; } } for(j=0;j { accum_err_metric[j][0]=accum_err_metric[j][1]; accum_err_metric[j][1]=MAXINT; } //对所选路径进行选择 { for(j=0;j<=depth_of_trellis;j++) state_sequence[j]=0; x=accum_err_metric[0][0]; h=0; for(j=1;j { if(accum_err_metric[j][0] { x=accum_err_metric[j][0]; h=j; } } state_sequence[depth_of_trellis]=h; for(j=depth_of_trellis;j>0;j--) { sh_col=j+(sh_ptr-depth_of_trellis); if(sh_col<0) sh_col=sh_col+depth_of_trellis+1; state_sequence[j-1]=state_history[state_sequence[j]][sh_col]; } *(decoder_output_matrix+t-depth_of_trellis+1)=input[state_sequence[0]][state_sequence[1]]; }//if条件状态 }//结束t循环 for(i=1;i *(decoder_output_matrix+channel_length-depth_of_trellis+i)=input[state_sequence[i]][state_sequence[i+1]]; free(channel_output_matrix); return; } //初始化三位软判决量化编码器 //加入噪声后的量化 voidinit_adaptive_quant(floates_ovr_n0) { inti,d; floates,sn_ratio,sigma; es=1; sn_ratio=(float)pow(10.0,(es_ovr_n0/10.0)); sigma=(float)sqrt(es/(2.0*sn_ratio)); d=(int)(32*0.5*sigma); for(i=-128;i<(-3*d);i++) quantizer_table[i+128]=7; for(i=(-3*d);i<(-2*d);i++) quantizer_table[i+128]=6; for(i=(-2*d);i<(-1*d);i++) quantizer_table[i+128]=5; for(i=(-1*d);i<0;i++) quantizer_table[i+128]=4; for(i=0;i<(1*d);i++) quantizer_table[i+128]=3; for(i=(1*d);i<(2*d);i++) quantizer_table[i+128]=2; for(i=(2*d);i<(3*d);i++) quantizer_table[i+128]=1; for(i=(3*d);i<128;i++) quantizer_table[i+128]=0; } //channel_symbol信道中的值为-1或+1的加噪信号 intsoft_quant(floatchannel_symbol) { intx; x=(int)(32.0*channel_symbol);//则x的平均值为-32或+32 if(x<-128)x=-128;//小于-128,输出128 if(x>127)x=127;//大于127则输出127 return(quantizer_table[x+128]);//查找量化表 } /*thismetricisbasedonthealgorithmgiveninMichelsonandLevesque, page323.*/ intsoft_metric(intdata,intguess) { return(abs(data-(guess*7))); } //当给出当前状态以及输入时,计算下一个状态,并且计算卷积码编码内容 intnxt_stat(intcurrent_state,intinput,int*memory_contents) { intbinary_state[K-1];//二进制当前状态 intnext_state_binary[K-1];//二进制下一个状态 intnext_state;//十进制当前状态 inti; deci2bin(current_state,K-1,binary_state); next_state_binary[0]=input; for(i=1;i next_state_binary[i]=binary_state[i-1]; next_state=bin2deci(next_state_binary,K-1); memory_contents[0]=input; for(i=1;i memory_contents[i]=binary_state[i-1];//编码内容 return(next_state);//返回十进制的下一个状态 } //将十进制数据转化为特殊的二进制,例如: 十进制“100011”输出二进制数据100011 voiddeci2bin(intd,intsize,int*b){ inti; for(i=0;i b[i]=0; b[size-1]=d&0x01; for(i=size-2;i>=0;i--){ d=d>>1; b[i]=d&0x01; } } //将2进制数据转化为特殊的十进制,例如: 二进制“100011”输出十进制数据100011 intbin2deci(int*b,intsize){ inti,d; d=0;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Viterbi 译码 程序代码