#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) {
没有合适的资源?快使用搜索试试~ 我知道了~
杰林码纠错算法库(lib、dll)以及AWGN信道BPSK信号下的仿真程序(C/C++)
共12个文件
c:4个
h:4个
exe:2个
2 下载量 28 浏览量
2023-10-30
16:48:11
上传
评论
收藏 83KB ZIP 举报
温馨提示
这个资源里面有很多的打印,目的就是让大家看到整个纠错的过程。 1、这个库是首次正式发布,部分功能可以通过输入帧长度、帧数以及信噪比Eb/N0,仿真AWGN信道BPSK信号下的测试,可修改测试程序test.c; 2、这个版本首先在国内发布,我将在近期发布到国外,期待本算法能出售; 3、目前测试4dB(含)以上10万帧随机数可以实现100%的纠错,只是信噪比值越低运算越慢; 4、仅支持C和C++,暂不提供linux下的库了,可以在windows下自行测试。 5、实测比极化码强。 202404011更新 1、优化了纠错性能 2、匹配与论文一致的测试方案 3、提升了纠错效率 4、修改了程序逻辑BUG
资源推荐
资源详情
资源评论
收起资源包目录
WJLErrRecoveryCode(SDK6.0.0DEMO6.0.0).zip (12个子文件)
BPSK_AWGN.h 249B
test.c 20KB
Testing.exe 34KB
LibWJLErrRecoveryCode6.0.0.lib 145KB
test.h 746B
QPSK_AWGN.h 249B
WJLErrRecoveryCode6.0.0.exe 42KB
QPSK_AWGN.c 4KB
DllWJLErrRecoveryCode6.0.0.dll 9KB
BPSK_AWGN.c 3KB
main.c 6KB
WJLErrRecoveryCore.h 5KB
共 12 条
- 1
资源评论
普通网友
- 粉丝: 345
- 资源: 20
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功