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

📄 rsdemo.cpp

📁 包括RS码的编码,硬(BM)/软(KV)译码,AWGN信道调制解调仿真. 具体采用何种编译码方案和调制解调方式可在Profile.txt文件中指定(内有详细说明). 且扩展性极好,容易向其中加入新的调
💻 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 + -