/*
* viterbi译码9约束长度软判决 功率归一化
************************************************************************************************
* MODULE NAME: test9.cpp
*************************************************************************************************
* DESCRIPTION :BER测试程序
*
* FUNCTIONS :信息位编码,加白噪声,译码,测BER
*
*************************************************************************************************
*/
#include <iomanip>
#include "decode.h"
#include "pn_seq.h"
#include "channel.h"
void main()
{ int i,j;
double power=0;
int error_count=0; //译码后错误信息比特
int trans_error=0; //译码前传输错误码元
int error_frame=0; //错误帧
int num; //记录结束个数
bool error=false; //记录当前帧是否错误
unsigned a[192]; //信源信息帧
double channel_trans1[192]; //信道经噪声污染的已编码帧
double channel_trans2[192];
int b1_polar[192]; //已编码帧加极性
int b2_polar[192];
unsigned b1_receiv[192]; //接受后已01判决的码元
unsigned b2_receiv[192];
l=184; m=8; //信息位长度184 归零位长度8
int bit_num; //量化比特数
cout<<"量化比特数:";
cin>>bit_num;
bit_num=pow(2,(bit_num-1));
AWGN p,*pi;
cout<<"信噪比:";
cin>>p.snr;
cout<<"跳出次数:";
cin>>num;
p.rate=0.5; //设置白噪声
p.reset=1;
p.ix=1;
p.iy=1;
p.iz=1;
p.I_sigma=2*(p.rate)*(pow(10.0,(p.snr)/10));;
p.sigma=sqrt(1/p.I_sigma);
pi=&p;
PN_seq(a,l,true); //伪随机序列生成信息位
for (i=l;i<l+m;i++) //加归零位
a[i]=0;
conv_encode_m9(a,l+m); //编码
init_trans();//建立状态网格图
for ( i=0;i<l+m;i++) //编码加极性
{
if (b1[i]==1) b1_polar[i]=1;
else b1_polar[i]=-1;
if (b2[i]==1) b2_polar[i]=1;
else b2_polar[i]=-1;
}
j=0;//测试帧个数
error_count=0;
trans_error=0;
error_frame=0;
while ((error_count<num)&&(j<25000))
{ j++;
//加信道噪声
awgn_channel(b1_polar , channel_trans1 ,pi,l+m);
awgn_channel(b2_polar , channel_trans2 ,pi,l+m);
//对接受码元第1位功率归一
power=0; //求序列功率
for ( i=0;i<l+m;i++)
{
power=power+channel_trans1[i]*channel_trans1[i];
}
power=sqrt(power/192); //量化
for ( i=0;i<l+m;i++)
{if (channel_trans1[i]>=0)
receiv1[i]=floor((bit_num-1)*channel_trans1[i]/power);
else receiv1[i]=ceil((bit_num-1)*channel_trans1[i]/power);
if (receiv1[i]>bit_num) receiv1[i]=bit_num;
if (receiv1[i]<(bit_num*(-1)+1)) receiv1[i]=bit_num*(-1)+1;
}
//对接受码元第2位功率归一
power=0;
for ( i=0;i<l+m;i++) //求序列功率
{
power=power+channel_trans2[i]*channel_trans2[i];
}
power=sqrt(power/192); //量化
for ( i=0;i<l+m;i++)
{if (channel_trans1[i]>=0)
receiv2[i]=floor((bit_num-1)*channel_trans2[i]/power);
else receiv2[i]=ceil((bit_num-1)*channel_trans2[i]/power);
if (receiv2[i]>bit_num) receiv2[i]=bit_num;
if (receiv2[i]<(bit_num*(-1)+1)) receiv2[i]=bit_num*(-1)+1;
}
search(); //译码
for ( i=0;i<m+l;i++)
{
if (channel_trans1[i]>0) b1_receiv[i]=1;
else b1_receiv[i]=0;
if (channel_trans2[i]>0) b2_receiv[i]=1;
else b2_receiv[i]=0;
}
for (i=0;i<l+m;i++) //统计接收错误
{
if (b1[i]!=b1_receiv[i]) {trans_error++;}
if (b2[i]!=b2_receiv[i]) {trans_error++;}
}
error=false;
for (i=0;i<l+m;i++) //统计译码错误
if (a[i]!=result[i])
{ error=true;
error_count++;
cout<<setw(5)<<error_count;
};
if (error)error_frame++; //统计误帧
}
cout<<"总帧数:"<<j<<endl;
cout<<"错误比特:"<<error_count<<"BER:"<<(double)(error_count)/(192*j)<<endl;
cout<<"传输错误码元:"<<trans_error<<"误码元率:"<<(double)(trans_error)/(192*j*2)<<endl;
cout<<"传输错误帧:"<<error_frame<<"误帧率:"<<(double)error_frame/j<<endl;
}