📄 rsdemo.cpp
字号:
// RSDemo.cpp : Defines the entry point for the console application.
//
#include <stdafx.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <crtdbg.h>
#include "RSEncoder.h"
#include "Modulator.h"
#include "channel.h"
#include "DeModulator.h"
#include "RSDecoder.h"
#include "KVA.h"
#include "BMA.h"
#define CONFIGFILE "Profile.txt"
#define MinMEF 50
char *srcfile, *decfile, *logfile;
bool genDecout, genLog, randata, genRandSrc;
int MEF;//Minimal Error Frame Number
int m, m0, D;
EncCore encMode;
DecAlg decAlg;
MPAStopCondit KV_MPAStopCdt;
float KV_MPAThres;
float *SNR, startSNR, endSNR, stepSNR;
/*最大公约数*/
int GCD(int a, int b) {
if (a<0) a=-a;
if (b<0) b=-b; else if (b==0) return -1;
int r=a;
while (r!=0) {
r= a%b;
a=b;
b=r;
}
return a;
}
/*最小公倍数*/
int LCM(int a, int b) {
if (a==0 || b==0) return -1;
return (a*b/GCD(a,b));
}
/*传入文件名字符串,返回加入数字序号的文件名*/
char* SeriesFilename(const char* basename, int ind) {
int bnlen=strlen(basename);
char *bname=(char*)malloc(sizeof(char)*(1+bnlen));
strcpy(bname, basename);
char *dot=strstr(bname, ".");
char *numstr=(char*)malloc(sizeof(char)*10);
itoa(ind, numstr, 10);
char *s1=(char*)malloc(sizeof(char)*(1+bnlen+strlen(numstr)));
if (dot!=NULL) {
*dot=0;
strcpy(s1, bname);
strcat(s1, numstr);
strcat(s1, ".");
strcat(s1, ++dot);
}
else {
strcpy(s1, bname);
strcat(s1, numstr);
}
return s1;
}
/*从配置文件中读入参数*/
bool ReadConfig() {
FILE *fp;
if ((fp=fopen(CONFIGFILE,"r"))==NULL) return false;
char *s=(char*)malloc(sizeof(char)*64);
srcfile=(char*)malloc(sizeof(char)*64);
decfile=(char*)malloc(sizeof(char)*64);
logfile=(char*)malloc(sizeof(char)*64);
int i, k=0;
while (!feof(fp)) {
fscanf(fp,"%s:",s);
i=0;
while (s[i]!=0) {
if (s[i]==':') {
k++;
switch(k) {
case 1:
//RS码的参数m
fscanf(fp,"%d",&m);
break;
case 2:
//RS码的参数m0
fscanf(fp,"%d",&m0);
break;
case 3:
//RS码的参数D(设计距离)
fscanf(fp,"%d",&D);
break;
case 4:
fscanf(fp,"%s",s);
if (strcmp(s, "S")==0) encMode=Systemetic;
else if (strcmp(s, "E")==0) encMode=MsgPoly;
else if (strcmp(s, "U")==0) encMode=VoidEnc;
break;
case 5:
//数据源文件名(若为"Random"则为随机产生数据)
fscanf(fp,"%s",srcfile);
randata=(strcmp(srcfile,"Random")==0);
break;
case 6:
//若为随机产生数据,则该参数指定将随机数据保存的文件名("NONE"表示不保存)
if (randata) {
fscanf(fp,"%s",srcfile);
genRandSrc=(strcmp(srcfile,"NONE")!=0);
}
break;
case 7:
fscanf(fp,"%f",&startSNR);
break;
case 8:
fscanf(fp,"%f",&endSNR);
break;
case 9:
fscanf(fp,"%f",&stepSNR);
break;
case 10:
fscanf(fp,"%s",s);
if (strcmp(s, "BMA")==0) decAlg=BMA;
else if (strcmp(s, "KVA")==0) decAlg=KVA;
else if (strcmp(s, "Void")==0) decAlg=VoidDec;
break;
case 11:
//编码输出文件("NONE"表示不产生)
fscanf(fp,"%s",decfile);
genDecout=(strcmp(decfile,"NONE")!=0);
break;
case 12:
//仿真结果记录文件("NONE"表示不产生)
fscanf(fp,"%s",logfile);
genLog=(strcmp(logfile,"NONE")!=0);
break;
case 13:
//最少错误帧数
fscanf(fp,"%d",&MEF);
if (MEF<MinMEF) MEF=MinMEF;
break;
case 14:
fscanf(fp,"%s",s);
if (strcmp(s, "S")==0) KV_MPAStopCdt=GivenS;
else if (strcmp(s, "L")==0) KV_MPAStopCdt=GivenL;
else if (strcmp(s, "C")==0) KV_MPAStopCdt=GivenC;
else if (strcmp(s, "M")==0) KV_MPAStopCdt=GivenM;
else if (strcmp(s, "Lambda")==0) KV_MPAStopCdt=GivenLambda;
break;
case 15:
fscanf(fp, "%f", &KV_MPAThres);
break;
default:
printf("\nConfigure File Error\n");
exit(0);
break;
}
break;
}
i++;
if (k==15) break;
}
}
if (k!=15) {
printf("\nConfigure File Error\n");
exit(0);
}
free(s);
return true;
}
int main(int argc, char* argv[])
{
if (!ReadConfig()) {
printf("Open CONFIGFILE Failue.\n");
return 0;
}
long i, j, k;
int totalcoded, totaldecoded, curcoded, curdecoded;
int curModed, curDemoded, iDem;
long totbits, errbits, errbytes, totframes, errframes;
long MEB;
int framebits, curfrmbits;
bool newframe;
byte *srcdata;
int datalen;
long iSrcR, iSrcW;
FILE *fpin, *fpdec, *fplog;
char *srfnSrc, *srfnDec;
byte *encbuf, *decbuf, *demodbuf;
double *modbuf, *reliabuf;
byte inbyte, mask;
// double ruined;
double curSNR;
int iSNR;
AWGN noise;
#ifdef _DEBUG
long maxdrw;
#endif
//初始化编码器,同时获得RS码参数结构体
RSCodeParam rs=InitRSParam(m, m0, D);
RSEncoder enc;
InitRSEncoder(enc, m, m0, D, encMode);
RSDecoder dec;
switch(decAlg) {
case BMA:
InitRSDecoder(dec, rs, InitBMA(rs));//初始化译码器
break;
case KVA:
InitRSDecoder(dec, rs, InitKVA(rs, KV_MPAStopCdt, KV_MPAThres));
break;
default:
break;
}
Modulator modu;
InitModulator(modu, Mod_BPSK);
Demodulator demod;
InitDemodulator(demod, Demod_BPSK, NULL);
printf("Parameter of this RS Code: [n,k,d,R]=[%d, %d, %d, %f]\n\n", rs.N, rs.K, rs.D, (double)rs.K/(double)rs.N);
if (genLog) {
printf("Simulation Log File: %s\n\n", logfile);
fplog=fopen(logfile, "w");
fprintf(fplog, "Parameter of this RS Code: [n,k,d,R]=[%d, %d, %d, %f]\n\n", rs.N, rs.K, rs.D, (double)rs.K/(double)rs.N);
}
if (!randata) {
//如果源数据是指定文件则预先读入到数组
fpin=fopen(srcfile,"rb");
for (datalen=0; !feof(fpin); datalen++) {fgetc(fpin);}
rewind(fpin);
srcdata=(byte*)malloc(sizeof(byte)*datalen);
for (i=0; i<datalen; i++) {
srcdata[i]=(byte)fgetc(fpin);
}
fclose(fpin);
}
else {
//否则srcdata将用于缓存随机产生的数据以便比较源数据与译码结果
//datalen表示缓存的最大长度
if (dec.isHardDecoder) {
i=(rs.N*rs.M<8)? 1+8/(rs.N*rs.M) : 2+1/(rs.M*rs.N/8);
datalen= i*(1+rs.K*rs.M/8)+1;
}
else {
i=1+8*modu.inW/(rs.N*rs.M);
k=(8*(i*rs.N*rs.M/8)/modu.inW)*modu.inW;
j=1+rs.N*rs.M/k;
datalen=i*j*(8/((j*k/(rs.N*rs.M))*rs.K*rs.M)+1)*
(1+rs.K*rs.M/8)+1;
}
srcdata=(byte*)malloc(sizeof(byte)*datalen);
}
MEB=LCM(LCM(LCM(8,modu.inW), (8*rs.N/GCD(8*rs.N, rs.K))),
modu.inW/GCD(modu.inW, modu.outW));
MEB*= (rs.K*rs.M/GCD(rs.K*rs.M, rs.K*MEB/rs.N));
MEB*= (8/GCD(8, modu.outW*MEB/modu.inW));
MEB= rs.K*MEB/8/rs.N;
//MEB: 为使全部比特都能被编码以及译码输出整数字节,所需的字节数单位
framebits=rs.M*rs.K;//一帧所含的比特数
for (iSNR=0, curSNR=startSNR; curSNR<=endSNR; iSNR++, curSNR+=stepSNR) {
noise=NewAWGN((double)rs.K/(double)rs.N, curSNR);
demod.gauss=&noise;
//用于误码率和误比特率性能统计的各变量:
totalcoded=0;
totaldecoded=0;
iSrcR=0; iSrcW=0;
totbits=0; errbits=0;
errbytes=0;
totframes=0; errframes=0;
curfrmbits=0;
newframe=true;
j=0;
#ifdef _DEBUG
maxdrw=10000;
#endif
//打开译码输出文件; 若数据指定为随机生成则还需打开随机数据文件
if (randata && genRandSrc) {
srfnSrc=SeriesFilename(srcfile,iSNR);
fpin=fopen(srfnSrc, "wb+");
}
if (genDecout) {
srfnDec=SeriesFilename(decfile,iSNR);
fpdec=fopen(srfnDec, "wb+");
}
while ((randata && (errframes<MEF || j%MEB!=0)) || (!randata && j<datalen)) {
if (randata) {
inbyte=(byte)rand();
srcdata[iSrcW++]=inbyte;
if (iSrcW==datalen) iSrcW=0;
if (genRandSrc) fputc(inbyte,fpin);
}
else {
inbyte=srcdata[j];
}
curcoded=EncodeOneByte(inbyte, encbuf, enc);//逐字节读入并编码
totalcoded+=curcoded;
for (k=0; k<curcoded; k++) {
//对编码输出的比特流进行调制
curModed=ModulateOneByte(encbuf[k], modbuf, modu);
for (;curModed>0; curModed--, modbuf+=modu.outW) {
//对调制得到的信号输出加入高斯白噪声(等于在每个信号矢量分量上加同样功率的白噪声)
AWGNRuin(modbuf, modu.outW, &noise);
//对接收信号矢量进行解调,若译码器为软译码方案则解调输出的是比特可信度
if (dec.isHardDecoder) curDemoded=DemodOneSignal(modbuf, demodbuf, demod);
else curDemoded=DemodOneSignal(modbuf, reliabuf, demod);
for (iDem=0; iDem<curDemoded; iDem++) {
if (dec.isHardDecoder) {
//硬译码:按解调得到的比特流进行译码
inbyte=demodbuf[iDem];
curdecoded=DecodeOneByte(inbyte, decbuf, dec);
}
else {
//软译码:按解调得到的比特可信度(比特为0的概率)进行译码
curdecoded=DecodeOneReliabBit(reliabuf[iDem], decbuf, dec);
}
if (curdecoded<0) curdecoded=-curdecoded;
_ASSERT(j-totaldecoded<datalen);
#ifdef _DEBUG
if (datalen-j+totaldecoded<maxdrw) maxdrw=datalen-j+totaldecoded;
#endif
for (i=0; i<curdecoded; i++) {
if (genDecout) fputc(decbuf[i],fpdec);
//统计误比特率,误码字率
if (randata) {
inbyte=srcdata[iSrcR++]^decbuf[i];
if (iSrcR==datalen) iSrcR=0;
}
else {
inbyte=decbuf[i]^srcdata[totaldecoded+i];
}
if (inbyte!=0) errbytes++;
for (mask=0x80; mask!=0; mask>>=1) {
if ((inbyte & mask)!=0) {
errbits++;
if (newframe) {errframes++; newframe=false;}
}
if (++curfrmbits==framebits) {
curfrmbits=0;
newframe=true;
totframes++;
printf("\rTotal Frames: %d ; Error Frames: %d",totframes, errframes);
}
}
totbits+=8;
}
totaldecoded+=curdecoded;
}
}
}
j++;
}
//重置编解码器及调制解调器以备下一SNR点的仿真
ResetRSDecoder(dec);
ResetRSEncoder(enc);
ResetModulator(modu);
ResetDemodulator(demod);
if (genDecout) fclose(fpdec);
if (randata && genRandSrc) fclose(fpin);
if (curfrmbits!=0) totframes++;
printf("\r \r");
if (randata) {
if (genRandSrc)
printf("Data Source(Random): %s\n", srfnSrc);
else
printf("Data Source(Random): No File\n");
}
else {printf("Data Source: %s\n", srcfile);}
if (genDecout) printf("Decoded OutputFile: %s\n", srfnDec);
printf("SourceData Length: %d\n", j);
printf("Coded Output Bytes: %d\n", totalcoded);
printf("Decoded Output Bytes: %d\n", totaldecoded);
printf("SNR(dB): %f\n", curSNR);
printf("Total Frames: %d; Error Frames: %d\n", totframes, errframes);
printf("Total Bits: %d; Error Bits: %d\n", totbits, errbits);
printf("bER: %e\n", (double)errbits/(double)totbits);
printf("BER: %e\n", (double)errbytes/(double)totaldecoded);
printf("FER: %e\n\n", (double)errframes/(double)totframes);
if (genLog) {
if (randata) {
if (genRandSrc)
fprintf(fplog, "Data Source(Random): %s\n", srfnSrc);
else
fprintf(fplog, "Data Source(Random): No File\n");
}
else {fprintf(fplog, "Data Source: %s\n", srcfile);};
if (genDecout) fprintf(fplog, "Decoded OutputFile: %s\n", srfnDec);
fprintf(fplog, "SourceData Length: %d\n", j);
fprintf(fplog, "Coded Output Bytes: %d\n", totalcoded);
fprintf(fplog, "Decoded Output Bytes: %d\n", totaldecoded);
fprintf(fplog, "SNR(dB): %f\n", curSNR);
fprintf(fplog, "Total Frames: %d; Error Frames: %d\n", totframes, errframes);
fprintf(fplog, "Total Bits: %d; Error Bits: %d\n", totbits, errbits);
fprintf(fplog, "bER: %e\n", (double)errbits/(double)totbits);
fprintf(fplog, "BER: %e\n", (double)errbytes/(double)totaldecoded);
fprintf(fplog, "FER: %e\n\n", (double)errframes/(double)totframes);
}
}
#ifdef _DEBUG
if (genLog) fprintf(fplog, "%d\n\n",maxdrw);
#endif
if (genLog) fclose(fplog);
CloseRSEncoder(enc);
CloseRSDecoder(dec);
CloseModulator(modu);
CloseDemodulator(demod);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -