我是靠谱客的博主 慈祥蜻蜓,最近开发中收集的这篇文章主要介绍VC++实现Turbo码,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Turbo码的概述如下,

Turbo码的设计和分析

主要包括交织器的设计、码的级联方式、译码算法、Turbo码的性能分析等。在性能分析中,主要对码重分布及距离谱进行分析,但由于没有相应的理论支持,这种分析只能是近似的,且仅局限于短码长、小码重的情况。

Turbo 码在直扩(CDMA) 系统中的研究及应用
Turbo 码不仅在信道信噪比很低的高噪声环境下性能优越,而且还具有很强的抗衰落、抗干扰能力,因此它在信道条件差的移动通信系统中有很大的应用潜力,在第三代移动通信系统(IMT-2000)中己经将Turbo码作为其传输高速数据的信道编码标准。第三代移动通信系统(IMT-2000)的特点是多媒体和智能化,要能提供多元传输速率、高性能、高质量的服务,为支持大数据量的多媒体业务,必须在布限带宽信道上传输数据。由于无线信道传输媒质的不稳定性及噪声的不确定性,一般的纠错码很难达到较高要求的译码性能(一般要求比特误码率小于10-6e),而Turbo码引起超乎寻常的优异译码性能,可以纠正高速率数据传输时发生的误码。另外,由于在直扩(CDMA) 系统中采用Turbo 码技术可以进一步提高系统的容量,所以有关Turbo码在直扩(CDMA) 系统中的应用,也就受到了各国学者的重视。

我大致记得Turbo码的编码原理是比特交织;4G系统的纠错码用的这个,5G应也是;

编码过程和原程序参阅此,

​​​​​​C/C++ 编程实现 LTE Turbo编码_Wei Xingguang-CSDN博客_turbo编码c语言

他的是Linux下的C语言程序;下面来改为MFC的;

新建一个单文档工程;

宏定义、常量数组、函数声明加到视类CPP文件的头部;

函数体拷贝到视类CPP文件的尾部;C语言函数加入到CPP文件中是可以的;

编译一下,出现很多错误;把对应的Linux数据类型改为MFC的;

类似 uint32_t 这样的都改为 UINT;然后再构建;出现下图错误,malloc函数的返回类型问题,

如下图,强转一下,(UINT*) malloc(。。。。。。;把他的printf提示改为MFC的;

 

然后在视类OnDraw()函数调用编码函数;按MFC方式输出结果;输入比特是代码中生成的随机数;

输出如下图;数据和原文不同,因为生成的随机数不同;

 

整个视类CPP文件如下;所有代码都在这里; 

 

// turbotestView.cpp : implementation of the CTurbotestView class
//

#include "stdafx.h"
#include "turbotest.h"

#include "turbotestDoc.h"
#include "turbotestView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define NOF_REGS 3
#define NOF_TAILINGS 12
#define MAX_CB_SIZE 188
#define MAX_BIT_LENGTH 6144

const UINT tc_cb_sizes[MAX_CB_SIZE] = {
40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120,       
128, 136, 144, 152, 160, 168, 176, 184, 192, 200, 208, 216, 224, 232,
240, 248, 256, 264, 272, 280, 288, 296, 304, 312, 320, 328, 336, 344,
352, 360, 368, 376, 384, 392, 400, 408, 416, 424, 432, 440, 448, 456,
464, 472, 480, 488, 496, 504, 512, 528, 544, 560, 576, 592, 608, 624,
640, 656, 672, 688, 704, 720, 736, 752, 768, 784, 800, 816, 832, 848,
864, 880, 896, 912, 928, 944, 960, 976, 992, 1008, 1024, 1056, 1088,
1120, 1152, 1184, 1216, 1248, 1280, 1312, 1344, 1376, 1408, 1440, 1472,
1504, 1536, 1568, 1600, 1632, 1664, 1696, 1728, 1760, 1792, 1824, 1856,
1888, 1920, 1952, 1984, 2016, 2048, 2112, 2176, 2240, 2304, 2368, 2432,
2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944, 3008, 3072, 3136, 3200,
3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840, 3904, 3968,
4032, 4096, 4160, 4224, 4288, 4352, 4416, 4480, 4544, 4608, 4672, 4736,
4800, 4864, 4928, 4992, 5056, 5120, 5184, 5248, 5312, 5376, 5440, 5504,
5568, 5632, 5696, 5760, 5824, 5888, 5952, 6016, 6080, 6144 };

const UINT f1_list[MAX_CB_SIZE] = { 
3, 7, 19, 7, 7, 11, 5, 11, 7, 41, 103,
15, 9, 17, 9, 21, 101, 21, 57, 23, 13, 27, 11, 27, 85, 29, 33, 15, 17, 33,
103, 19, 19, 37, 19, 21, 21, 115, 193, 21, 133, 81, 45, 23, 243, 151, 155,
25, 51, 47, 91, 29, 29, 247, 29, 89, 91, 157, 55, 31, 17, 35, 227, 65, 19,
37, 41, 39, 185, 43, 21, 155, 79, 139, 23, 217, 25, 17, 127, 25, 239, 17,
137, 215, 29, 15, 147, 29, 59, 65, 55, 31, 17, 171, 67, 35, 19, 39, 19, 199,
21, 211, 21, 43, 149, 45, 49, 71, 13, 17, 25, 183, 55, 127, 27, 29, 29, 57,
45, 31, 59, 185, 113, 31, 17, 171, 209, 253, 367, 265, 181, 39, 27, 127,
143, 43, 29, 45, 157, 47, 13, 111, 443, 51, 51, 451, 257, 57, 313, 271, 179,
331, 363, 375, 127, 31, 33, 43, 33, 477, 35, 233, 357, 337, 37, 71, 71, 37,
39, 127, 39, 39, 31, 113, 41, 251, 43, 21, 43, 45, 45, 161, 89, 323, 47, 23,
47, 263 };

const UINT f2_list[MAX_CB_SIZE] = { 
10, 12, 42, 16, 18, 20, 22, 24, 26, 84,
90, 32, 34, 108, 38, 120, 84, 44, 46, 48, 50, 52, 36, 56, 58, 60, 62, 32,           
198, 68, 210, 36, 74, 76, 78, 120, 82, 84, 86, 44, 90, 46, 94, 48, 98, 40,
102, 52, 106, 72, 110, 168, 114, 58, 118, 180, 122, 62, 84, 64, 66, 68, 420,
96, 74, 76, 234, 80, 82, 252, 86, 44, 120, 92, 94, 48, 98, 80, 102, 52, 106,
48, 110, 112, 114, 58, 118, 60, 122, 124, 84, 64, 66, 204, 140, 72, 74, 76,
78, 240, 82, 252, 86, 88, 60, 92, 846, 48, 28, 80, 102, 104, 954, 96, 110,
112, 114, 116, 354, 120, 610, 124, 420, 64, 66, 136, 420, 216, 444, 456,
468, 80, 164, 504, 172, 88, 300, 92, 188, 96, 28, 240, 204, 104, 212, 192,
220, 336, 228, 232, 236, 120, 244, 248, 168, 64, 130, 264, 134, 408, 138,
280, 142, 480, 146, 444, 120, 152, 462, 234, 158, 80, 96, 902, 166, 336,
170, 86, 174, 176, 178, 120, 182, 184, 186, 94, 190, 480 };


int search_segment_index(int );
int turbo_interleaver(UINT * , int );
void lte_turbo(UINT * , UINT * , UINT );

/
// CTurbotestView

IMPLEMENT_DYNCREATE(CTurbotestView, CView)

BEGIN_MESSAGE_MAP(CTurbotestView, CView)
	//{{AFX_MSG_MAP(CTurbotestView)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/
// CTurbotestView construction/destruction

CTurbotestView::CTurbotestView()
{
	// TODO: add construction code here

}

CTurbotestView::~CTurbotestView()
{
}

BOOL CTurbotestView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/
// CTurbotestView drawing

void CTurbotestView::OnDraw(CDC* pDC)
{
	CTurbotestDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	int row=0, col=0;
	CString str1;
	UINT input_length = 160;
    
    UINT output_length = input_length * 3 + NOF_TAILINGS;
    UINT* input = (UINT *)malloc(input_length * sizeof(UINT));
    UINT* output = (UINT *)malloc(output_length * sizeof(UINT));

    srand(time(NULL));
    int i;
    for(i = 0; i < input_length; i++)
        input[i] = rand() % 2;

    pDC->TextOut(20,5,"输入比特:");
    for(i = 0; i < input_length; i++)
    {
        str1.Format("%d ",input[i]);
		pDC->TextOut(100+10*((i+1)%20), 20+row*20, str1);
		if( (i+1)%20==0)
		{
			row=row+1;
		}
    }

    lte_turbo(input, output, input_length);

    row=0;
    pDC->TextOut(20,185,"输出比特:");
    for(i = 0; i < output_length; i++)
    {
		str1.Format("%d ",output[i]);
		pDC->TextOut(100+10*((i+1)%20), 200+row*20, str1);
		if( (i+1)%20==0)
		{
			row=row+1;
		}
    }

    free(input);
    free(output);
}

/
// CTurbotestView printing

BOOL CTurbotestView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CTurbotestView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CTurbotestView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/
// CTurbotestView diagnostics

#ifdef _DEBUG
void CTurbotestView::AssertValid() const
{
	CView::AssertValid();
}

void CTurbotestView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CTurbotestDoc* CTurbotestView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTurbotestDoc)));
	return (CTurbotestDoc*)m_pDocument;
}
#endif //_DEBUG

/
// CTurbotestView message handlers

int search_segment_index(int input_length)
{
    int j= 0;
    while( j < MAX_CB_SIZE && tc_cb_sizes[j] < input_length)
        j++;

    if(j == MAX_CB_SIZE)
        return -1;
    else
        return j;
}

int turbo_interleaver(UINT *interleaver, int input_length)
{
    if(input_length > MAX_BIT_LENGTH)
        return -1;

    // Find code block index
    int segment_index = search_segment_index(input_length);
    if(segment_index == -1)
        return -1;

    UINT f1 = f1_list[segment_index];
    UINT f2 = f2_list[segment_index];

    UINT i = 0, j;
    for(i = 0; i < input_length; i++)
    {
        j = (f1 * i + f2 * i * i) % input_length;
        interleaver[i] = j;
    }

    for(i = input_length; i < MAX_BIT_LENGTH; i++)
        interleaver[i] = 0;

    return 0;
}

void lte_turbo(UINT * input, UINT * output, UINT input_length)
{

    // Initialization of turbo registers
    UINT reg1_1, reg1_2, reg1_3, reg2_1, reg2_2, reg2_3;

    reg1_1 = 0;
    reg1_2 = 0;
    reg1_3 = 0;

    reg2_1 = 0;
    reg2_2 = 0;
    reg2_3 = 0;

    // Initialization of turbo interleaver
    UINT* input_interleaver = (UINT*)malloc(MAX_BIT_LENGTH * sizeof(UINT));
    if (turbo_interleaver(input_interleaver, input_length) < 0 )
    {
        //printf("Initialization of turbo interleaver ERROR!n");
        //exit(-1);
		AfxMessageBox("Initialization of turbo interleaver ERROR!");
    }

    UINT k = 0, i, j;
    UINT bit, in, out;
    for(i = 0; i < input_length; i++)
    {
        bit = input[i];

        // X[k]
        output[k] = input[i];
        k++;

        in = bit ^ (reg1_3 ^ reg1_2);
        out = reg1_3 ^ (reg1_1 ^ in);

        reg1_3 = reg1_2;
        reg1_2 = reg1_1;
        reg1_1 = in;

        // Z[k]
        output[k] = out;
        k++;

        bit = input[input_interleaver[i]];

        in = bit ^ (reg2_3 ^ reg2_2);
        out = reg2_3 ^ (reg2_1 ^ in);

        reg2_3 = reg2_2;
        reg2_2 = reg2_1;
        reg2_1 = in;

        // Z*[k]
        output[k] = out;
        k++;
    }

    k = 3 * input_length;

    // Tailing coder 1
    for(j = 0; j< NOF_REGS; j++)
    {
        bit = reg1_3 ^ reg1_2;

        output[k] = bit;
        k++;

        in = bit ^ (reg1_3 ^ reg1_2);
        out = reg1_3 ^ (reg1_1 ^ in);

        reg1_3 = reg1_2;
        reg1_2 = reg1_1;
        reg1_1 = in;

        output[k] = out;
        k++;
    }

    // Tailing coder 2
    for(j = 0; j < NOF_REGS; j++)
    {
        bit = reg2_3 ^ reg2_2;

        output[k] = bit;
        k++;

        in = bit ^ (reg2_3 ^ reg2_2);
        out = reg2_3 ^ (reg2_1 ^ in);

        reg2_3 = reg2_2;
        reg2_2 = reg2_1;
        reg2_1 = in;

        output[k] = out;
        k++;
    }

    free(input_interleaver);
}

 

 

最后

以上就是慈祥蜻蜓为你收集整理的VC++实现Turbo码的全部内容,希望文章能够帮你解决VC++实现Turbo码所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(54)

评论列表共有 0 条评论

立即
投稿
返回
顶部