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 6144const 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 );/ // CTurbotestViewIMPLEMENT_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 commandsON_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/destructionCTurbotestView::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 csreturn CView::PreCreateWindow(cs); }/ // CTurbotestView drawingvoid CTurbotestView::OnDraw(CDC* pDC) {CTurbotestDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data hereint 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 printingBOOL CTurbotestView::OnPreparePrinting(CPrintInfo* pInfo) {// default preparationreturn 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 handlersint 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;elsereturn j; }int turbo_interleaver(UINT *interleaver, int input_length) {if(input_length > MAX_BIT_LENGTH)return -1;// Find code block indexint 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 registersUINT 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 interleaverUINT* 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 1for(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 2for(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码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Bochs调试Linux内核5 - 启动
- 下一篇: MySQL存储引擎和外键学习