#include "test.h"
#include "BPSK_AWGN.h"
#include "QPSK_AWGN.h"
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// 是否限制误比特差异在上下1.0dB范围内,0不限制,1限制
#define LIMIT_MODEL 0
void SynchronizationBytes(WJL_ALGORITHM_PARAMETERS* par)
{
int i, j;
WJL_ERRRECOVERY_ENCODER* encoder1 = NULL;
WJL_ERRRECOVERY_ENCODER* encoder2 = NULL;
// 防止输入的参数有错误
if (par->CODE_LENGTH <= 0 || par->LIST_SIZE <= 0) return 0;
encoder1 = (WJL_ERRRECOVERY_ENCODER*)malloc(sizeof(WJL_ERRRECOVERY_ENCODER));
encoder2 = (WJL_ERRRECOVERY_ENCODER*)malloc(sizeof(WJL_ERRRECOVERY_ENCODER));
if (encoder1 == NULL || encoder2 == NULL) {
goto Err;
}
encoder1->par = par;
encoder2->par = par;
encoder1->OutBytesLength = encoder2->OutBytesLength = encoder1->InBytesLength = encoder2->InBytesLength = par->CODE_LENGTH * 16;
encoder1->InBytesArray = (unsigned char*)malloc(encoder1->InBytesLength);
encoder1->OutBytesArray = (unsigned char*)malloc(encoder1->OutBytesLength);
encoder2->InBytesArray = (unsigned char*)malloc(encoder2->InBytesLength);
encoder2->OutBytesArray = (unsigned char*)malloc(encoder2->OutBytesLength);
if (encoder1->InBytesArray == NULL || encoder1->OutBytesArray == NULL || encoder2->InBytesArray == NULL || encoder2->OutBytesArray == NULL) {
goto Err;
}
// 用encoder1编码par->CODE_LENGTH个0x00,全0x00和全0xFF是两个极端的边缘序列
for (i = 0; i < par->CODE_LENGTH; ++i) encoder1->InBytesArray[i] = 0x00;
WJLErrRecoveryEncoder(encoder1);
// 用encoder2编码par->CODE_LENGTH个0xFF
for (i = 0; i < par->CODE_LENGTH; ++i) encoder2->InBytesArray[i] = 0xFF;
WJLErrRecoveryEncoder(encoder2);
// 根据静态码率
if (encoder1->OutBytesIndex != encoder2->OutBytesIndex) {
printf("静态码率理论出错误!\n");
goto Err;
}
// 比较encoder1->OutBytesArray和encoder2->OutBytesArray末尾字节
j = 0;
for (i = encoder1->OutBytesIndex - 1; i >= 0; --i) {
if (encoder1->OutBytesArray[i] != encoder2->OutBytesArray[i]) {
break;
}
j++;
}
// 然后将末尾j个字节存储到par->SynchronizationBytes中
par->SynchronizationLength = 0;
for (i = encoder1->OutBytesIndex - j; i < encoder1->OutBytesIndex; ++i) {
par->SynchronizationBytes[par->SynchronizationLength] = encoder1->OutBytesArray[i];
par->SynchronizationLength++;
}
Err:
// 释放资源
if (encoder1) {
if (encoder1->InBytesArray)free(encoder1->InBytesArray);
if (encoder1->OutBytesArray)free(encoder1->OutBytesArray);
free(encoder1);
}
if (encoder2) {
if (encoder2->InBytesArray)free(encoder2->InBytesArray);
if (encoder2->OutBytesArray)free(encoder2->OutBytesArray);
free(encoder2);
}
}
// 无错情况下的编译码检验
int NoErrByBytesArrayLength(WJL_ALGORITHM_PARAMETERS* par)
{
int i = 0;
WJL_ERRRECOVERY_ENCODER* encoder = NULL;
WJL_ERRRECOVERY_DECODER* decoder = NULL;
WJL_ERRRECOVERY_DECODER** list = NULL;
unsigned int OutBUFF1_Length = 0, OutBUFF2_Length = 0;
// 防止输入的参数有错误
if (par->CODE_LENGTH <= 0 || par->LIST_SIZE <= 0) return 0;
// 开辟缓存
encoder = (WJL_ERRRECOVERY_ENCODER*)malloc(sizeof(WJL_ERRRECOVERY_ENCODER));
decoder = (WJL_ERRRECOVERY_DECODER*)malloc(sizeof(WJL_ERRRECOVERY_DECODER));
list = (WJL_ERRRECOVERY_DECODER**)malloc(par->LIST_SIZE * sizeof(WJL_ERRRECOVERY_DECODER*));
if (encoder == NULL || decoder == NULL || list == NULL) {
goto Err;
}
// 直接开辟LIST_SIZE个list
for (i = 0; i < par->LIST_SIZE; ++i) {
list[i] = (WJL_ERRRECOVERY_DECODER*)malloc(sizeof(WJL_ERRRECOVERY_DECODER));
if (list[i] == NULL) {
goto Err;
}
}
// 指定系数,编码和译码的MAX_NUMBER_OF_0xFF系数必须是相同,在编码时除了MAX_NUMBER_OF_0xFF,其他的系数均无效
encoder->par = par;
decoder->par = par;
decoder->OutBytesLength = encoder->InBytesLength = par->CODE_LENGTH * 16;
// 这个是理论值,为了支持1个字节的编译码,这个最好设置encoder->InBytesLength的4倍
encoder->OutBytesLength = encoder->InBytesLength;
// 编码的缓存
encoder->InBytesArray = (unsigned char*)malloc(encoder->InBytesLength);
encoder->OutBytesArray = (unsigned char*)malloc(encoder->OutBytesLength);
// 译码的缓存
decoder->InBytesArray = (unsigned char*)malloc(encoder->InBytesLength);
decoder->OutBytesArray = (unsigned char*)malloc(encoder->InBytesLength);
decoder->BytesArray = (unsigned char*)malloc(encoder->InBytesLength);
decoder->wfp = (WJL_FUNCTION_PARAMETERS*)malloc(sizeof(WJL_FUNCTION_PARAMETERS));
if (encoder->InBytesArray == NULL || encoder->OutBytesArray == NULL || decoder->InBytesArray == NULL || decoder->OutBytesArray == NULL || decoder->BytesArray == NULL || decoder->wfp == NULL) {
goto Err;
}
// 产生随机数据
for (i = 0; i < par->CODE_LENGTH; ++i) {
encoder->InBytesArray[i] = rand() % 256;
printf("%02X,", encoder->InBytesArray[i]);
}
printf("\n");
/********************编码译码部分**********************/
WJLErrRecoveryEncoder(encoder);
// encoder->OutBytesIndex为实际输出的字节长度,把encoder->OutBytesArray中的字节复制给decoder->InBytesArray
memcpy(decoder->InBytesArray, encoder->OutBytesArray, encoder->OutBytesIndex);
decoder->InBytesLength = encoder->OutBytesIndex;
printf("编码后的字节:%d\n", encoder->OutBytesIndex);
for (i = 0; i < encoder->OutBytesIndex; ++i) {
printf("%02X,", decoder->InBytesArray[i]);
}
printf("\n");
printf("编码前:%d, 编码后:%d,实际码率R = %1.6f, 理论编码码率R=-1/log_2(1/3)=1/1.5849625=0.63092975\n", par->CODE_LENGTH, encoder->OutBytesIndex, (double)par->CODE_LENGTH / (double)encoder->OutBytesIndex);
printf("\n");
/********************纠错译码部分**********************/
WJLErrRecoveryDecoder(decoder, list);
// 检查是否有错误
for (i = 0; i < par->CODE_LENGTH; ++i) {
if (encoder->InBytesArray[i] != decoder->OutBytesArray[i]) {
goto Err;
}
}
printf("译码后的字节:%d\n", decoder->OutBytesIndex - 1);
for (i = 0; i < par->CODE_LENGTH; ++i) {
printf("%02X,", decoder->OutBytesArray[i]);
}
printf("\n");
// 释放资源
if (encoder) {
if (encoder->InBytesArray)free(encoder->InBytesArray);
if (encoder->OutBytesArray)free(encoder->OutBytesArray);
free(encoder);
}
if (list) {
for (i = 0; i < decoder->par->LIST_SIZE; ++i) if (list[i]) free(list[i]);
free(list);
}
if (decoder) {
if (decoder->InBytesArray)free(decoder->InBytesArray);
if (decoder->OutBytesArray)free(decoder->OutBytesArray);
if (decoder->BytesArray)free(decoder->BytesArray);
if (decoder->wfp)free(decoder->wfp);
free(decoder);
}
if (par) free(par);
return 1;
Err:
// 释放资源
if (encoder) {
if (encoder->InBytesArray)free(encoder->InBytesArray);
if (encoder->OutBytesArray)free(encoder->OutBytesArray);
free(encoder);
}
if (list) {
for (i = 0; i < decoder->par->LIST_SIZE; ++i) if (list[i]) free(list[i]);
free(list);
}
if (decoder) {
if (decoder->InBytesArray)free(decoder->InBytesArray);
if (decoder->OutBytesArray)free(decoder->OutBytesArray);
if (decoder->BytesArray)free(decoder->BytesArray);
if (decoder->wfp)free(decoder->wfp);
free(decoder);
}
if (par) free(par);
return 0;
}
// Q函数
double Q(double EbN0)
{
return 0.5 * erfc(sqrt(2 * EbN0) / sqrt(2.0));
}
//------------------------------------------------------------------------------------------------------
// 下面的几个函数主要是针对不同的系统进行仿真,主要是基于不同的信道类型,输入不同的信噪比计算出对应的BER
// BPSK是一个公式
double AWGN_BPSK_BER(double EbN0_dB)
{
// 参考文献:丁凯. AWGN信道中BPSK误码率仿真分析[J]. 微处理机,2021,42(3):23-26. DOI:10.3969/j.issn.1002-2279.2021.03.006.
double EbN0 = pow(10, EbN0_dB / 10);
// 计算误比特率
return 0.5 * erfc(sqrt(EbN0));
//return Q(EbN0);
}
// 判断两个字节中差异比特个数
int ErrBits(unsigned char byte1, unsigned char byte2)
{
int i, j = 0;
unsigned char tmpbyte = byte1 ^ byte2;
// 统计差异个数
for (i = 7; i >= 0; --i) {
if ((tmpbyte >> i) & 0x01) {
普通网友
- 粉丝: 345
- 资源: 20
最新资源
- 基于anyproxy抓包工具爬取微信公众号文章,应用appnium实现自动化的批量的微信公众号文章监控和历史文章自动化下拉爬取微信公众号文章url资料齐全+文档+源码.zip
- 基于Action抓取必应每日超清壁纸展示&保存到分支资料齐全+文档+源码.zip
- 基于Chrome浏览器开发的拓展应用,它可以非常方便快速的抓取阿里巴巴国际站和速卖通的商品信息并同步到您自己的网站资料齐全+文档+源码.zip
- 基于Cef叶子浏览器,访问网页时自动抓取结构化xhr数据资料齐全+文档+源码.zip
- 基于eggjs(nodejs)抓取百度高德腾讯地图、大众点评POI数据,资料齐全+文档+源码.zip
- 基于curl的抓取器资料齐全+文档+源码.zip
- 基于Ehcache和Redis实现的分布式二级缓存.简单适用,全局可控,除基本操作以外实现多机集群时一级缓存的监控,管理和抓取.资料齐全+文档+源码.zip
- 基于JAVA 基于OPC UA 抓取机台数据资料齐全+文档+源码.zip
- 基于flutter开发的混合电影和音乐music app,,后端采用springboot+mybatis+mysql开发,包括底部tab导航,,首页,电影,电视
- 基于nginx 流量统计,python +django 每天抓取数据存入数据库,根据项目部的使用域名,统计出项目部门承担费用资料齐全+文档+源码.zip
- 基于Netty的通用直播间弹幕客户端,支持网络代理,支持弹幕发送、为主播点赞,已支持B站、斗鱼、虎牙、抖音、快手,基于该项目的一个弹幕转发、过滤、处理平台;支持
- 基于Node.js的可扩展的弹幕抓取插件资料齐全+文档+源码.zip
- 基于node服务使用puppeteer进行页面抓取提供给爬虫进行seo优化资料齐全+文档+源码.zip
- 基于puppeteer的动态网站抓取资料齐全+文档+源码.zip
- 基于opencv-python视觉库,利用Robomaster EP开发放sdk,实现EP自动识别网球,并用 自身机械抓抓取,将网球放入球筐。资料齐全+文档+源码.zip
- 基于python scrapy框架抓取豆瓣影视资料资料齐全+文档+源码.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈