viterbi.cpp
来自「signal-processing.rar信号处理demo原码」· C++ 代码 · 共 562 行 · 第 1/2 页
CPP
562 行
/*
//
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright (c) 2006 Intel Corporation. All Rights Reserved.
//
*/
#include "time.h"
#include "conio.h"
#include "stdlib.h"
#include "math.h"
#include "stdio.h"
#include "viterbi.h"
static const int DX[12] = {0, 2, 2, 0, 0, 2, 2, 4, 4, -2, -2, 0};
static const int DY[12] = {0, 0, 2, 2, 4, 4, -2, 2, 0, 0, 2, -2};
static Ipp8u POINTLABEL[4][4] =
{
0, 7, 4, 3,
5, 2, 1, 6,
4, 3, 0, 7,
1, 6, 5, 2
};
Ipp8u GetEncoderPoint(int numStates, int prevState, int inBits)
{
Ipp8u tmp;
Ipp8u e;
Ipp8u c;
tmp = (Ipp8u)(prevState >> 1);
switch(numStates)
{
case 16:
tmp ^= (inBits & 3) ^ ((inBits & 2) << 1) ^ ((prevState & 1) << 2);
tmp |= (prevState & 1) << 3;
break;
case 32:
tmp ^= (((inBits & 2) >> 1) * 9) ^ ((inBits & 1) << 2) ^ ((inBits & 8) >> 2);
tmp |= (prevState & 1) << 4;
break;
case 64:
tmp = (Ipp8u)(( prevState & 1 ) << 1);
tmp |= (((prevState ^ inBits) & 2) >> 1) ^ (( prevState & 8) >> 3);
tmp |= (( prevState & 8) >> 1);
e = (Ipp8u)(((prevState & 16 ) >> 1) ^ ((inBits & 1) << 3));
tmp |= e ^ (prevState & 8);
c = (Ipp8u)((prevState & 32) ^ ((prevState & 16) << 1));
tmp |= (c >> 1) ^ ((prevState & 4) << 2 ) ^
(((prevState & 8) << 1) & ((inBits & 2) << 3)) ^ ((inBits & 4) << 2);
tmp |= ((e << 2) & ((prevState & 8) << 2 )) ^ c ^ (( inBits & 8) << 2);
break;
default:
break;
}
return tmp;
} // GetEncoderPoint()
/****************************************************************************/
/* Function: InitViterbiDecoder */
/* Initialise Viterbi decoder */
/* Input parametrs: ViterbiParam - pointer to structure with Viterbi */
/* decoder parametrs */
/* Output value: - */
/****************************************************************************/
void InitViterbiDecoder(ViterbiInfo* ViterbiParam)
{
Ipp16u i,j;
ViterbiParam->m_NumInputBits = (Ipp8u)(ViterbiParam->m_State/32+2);
ViterbiParam->m_BitInvertion = 0;
ViterbiParam->m_TableDept = ViterbiParam->m_State;
ViterbiParam->m_TickMask = (Ipp16u)(ViterbiParam->m_TableDept-1);
ViterbiParam->m_NumInputCombination = (Ipp8u)(ViterbiParam->m_State/4);
ViterbiParam->m_Tick = ViterbiParam->m_State;
for( i = 0; i < ViterbiParam->m_State; i++ )
{
ViterbiParam->m_PathError[i] = 32768;
ViterbiParam->m_BranchError[i] = 65535;
for( j = 0; j < ViterbiParam->m_NumInputCombination; j++)
{
if(ViterbiParam->m_State == 32)
{
ViterbiParam->m_NextState[i*ViterbiParam->m_NumInputCombination + j] =
GetEncoderPoint(ViterbiParam->m_State, (Ipp8u)i, (Ipp8u)(j+(j&4)*2));
}
else
{
ViterbiParam->m_NextState[i*ViterbiParam->m_NumInputCombination + j] =
GetEncoderPoint(ViterbiParam->m_State, (Ipp8u)i, (Ipp8u)j);
}
}
}
ViterbiParam->m_PathError[0] = 0;
ViterbiParam->m_flRealData = 0;
for( i = 0; i < ViterbiParam->m_State * ViterbiParam->m_TableDept; i++)
{
ViterbiParam->m_PathTable[i].m_oldState = 0;
}
return;
} // InitViterbiDecoder()
void DeepTraceBack(ViterbiInfo* ViterbiParam,Ipp16sc Output[2],Ipp32s Deep)
{
Ipp16s firstIndex;
Ipp16s secondIndex;
Ipp16s Index;
Ipp16u PrevSost;
Ipp16u i;
Index = ViterbiParam->m_Tick;
PrevSost = ViterbiParam->m_MinSost;
for(i = 0; i < Deep; i++ )
{
PrevSost = ViterbiParam->m_PathTable[ Index * ViterbiParam->m_State + PrevSost].m_oldState;
Index = (Ipp16s)((Index - 1) & ViterbiParam->m_TickMask);
}
firstIndex = (Ipp16s)(ViterbiParam->m_PathTable[ Index * ViterbiParam->m_State + PrevSost].re & 0xff);
secondIndex = (Ipp16s)(( ViterbiParam->m_PathTable[ Index * ViterbiParam->m_State + PrevSost].re >> 8 ) & 0xff);
Output[0].re = (Ipp16s)(ViterbiParam->m_ReferencePoint[Index].m_firstPoint.re + (Ipp16s)DX[firstIndex]*128);
Output[0].im = (Ipp16s)(ViterbiParam->m_ReferencePoint[Index].m_firstPoint.im + (Ipp16s)DY[firstIndex]*128);
Output[1].re = (Ipp16s)(ViterbiParam->m_ReferencePoint[Index].m_secondPoint.re + (Ipp16s)DX[secondIndex]*128);
Output[1].im = (Ipp16s)(ViterbiParam->m_ReferencePoint[Index].m_secondPoint.im + (Ipp16s)DY[secondIndex]*128);
return;
} // DeepTraceBack()
/****************************************************************************/
/* Function: TraceBack */
/* Find start point which place in start of path with */
/* minimum current accumulation error metrics */
/* Input parametrs: ViterbiParam - pointer to structure with decoder */
/* parametrs. */
/* Output - pointer to array 2 2D symbls which ideal */
/* will containe ideal symbls */
/* Output value: - */
/****************************************************************************/
void TraceBack(ViterbiInfo* ViterbiParam,Ipp16sc Output[2])
{
DeepTraceBack(ViterbiParam, Output, ViterbiParam->m_TableDept - 1);
return;
}
/***************************************************************************/
/* Function: GetViterbiData */
/* This is Viterbi algoritm */
/* Input parametrs: InputPoint - pointer to 2 2D received symbls (which */
/* consist 4D symbl) in format 9:7 */
/* OutputPoint - pointer to array where ideal 2 2D sym- */
/* bols will be written */
/* ViterbiParam - pointer to structure with decoder pa- */
/* rametrs */
/* Output value: If > 0, then data in OutputPoint is true, else dont */
/* never used this date */
/***************************************************************************/
Ipp8u GetViterbiData(Ipp16sc InputPoint[2], Ipp16sc OutputPoint[2], ViterbiInfo* ViterbiParam)
{
Ipp16sc refPointNearest;
Ipp32s PrevIndex;
Ipp32s PresentIndex;
IppStatus st;
if(ViterbiParam->m_Tick == 0)
ViterbiParam->m_flRealData = 100;
if(ViterbiParam->m_flRealData != 0)
{
TraceBack(ViterbiParam, OutputPoint);
}
PrevIndex = (ViterbiParam->m_Tick) * ViterbiParam->m_State;
ViterbiParam->m_Tick = (Ipp16u)( (ViterbiParam->m_Tick + 1) & ViterbiParam->m_TickMask );
PresentIndex = ViterbiParam->m_State*ViterbiParam->m_Tick;
/* Get variant point for first 2D symbol in 4D */
st = ippsGetVarPointDV_16sc(&InputPoint[0],
&refPointNearest,
ViterbiParam->m_VariantPoint,
(Ipp8u*)POINTLABEL,
(Ipp32s)ViterbiParam->m_State);
if(ippStsNoErr != st)
{
printf(" Error in ippiGetVarPointDV: %s\n", ippGetStatusString(st));
return 1;
}
ViterbiParam->m_ReferencePoint[ViterbiParam->m_Tick].m_firstPoint = refPointNearest;
/* Get variant point for second 2D symbol */
st = ippsGetVarPointDV_16sc(&InputPoint[1],
&refPointNearest,
ViterbiParam->m_VariantPoint+8,
(Ipp8u*)POINTLABEL,
(Ipp32s)ViterbiParam->m_State);
if(ippStsNoErr != st)
{
printf(" Error in ippiGetVarPointDV: %s\n", ippGetStatusString(st));
return 1;
}
ViterbiParam->m_ReferencePoint[ViterbiParam->m_Tick].m_secondPoint = refPointNearest;
/* compute current 4D subset */
st = ippsBuildSymblTableDV4D_16sc(ViterbiParam->m_VariantPoint,
(Ipp16sc*)ViterbiParam->m_CurrentSubsetPoint,
(Ipp32s)ViterbiParam->m_State,
(Ipp32s)ViterbiParam->m_BitInvertion);
if(ippStsNoErr != st)
{
printf(" Error in ippsBuildSymblTableDV4D: %s\n", ippGetStatusString(st));
return 1;
}
/* Work with all old state */
st = ippsCalcStatesDV_16sc( ViterbiParam->m_PathError,
ViterbiParam->m_NextState,
ViterbiParam->m_BranchError,
(Ipp16s*)ViterbiParam->m_CurrentSubsetPoint,
(Ipp16s*)ViterbiParam->m_PathTable,
(Ipp32s)ViterbiParam->m_State,
(Ipp32s)PresentIndex );
if(ippStsNoErr != st)
{
printf(" Error in ippsCalcStatesDV: %s\n", ippGetStatusString(st));
return 1;
}
st = ippsUpdatePathMetricsDV_16u(ViterbiParam->m_BranchError,
&ViterbiParam->m_MinPathError,
&ViterbiParam->m_MinSost,
ViterbiParam->m_PathError,
ViterbiParam->m_State);
if(ippStsNoErr != st)
{
printf(" Error in ippsUpdatePathMetricsDV: %s\n", ippGetStatusString(st));
return 1;
}
PresentIndex += ViterbiParam->m_MinSost;
return 0;
} // GetViterbiData()
void ViterbiInit( ViterbiTestInfo *viterbiInf, Ipp8u viterbiState)
{
switch( viterbiState )
{
case ViterbiState16:
viterbiInf->vState = 16;
viterbiInf->numPossStates = 4;
viterbiInf->ceStates = *ceStates16;
viterbiInf->ceInput = *ce16Input;
break;
case ViterbiState32:
viterbiInf->vState = 32;
viterbiInf->numPossStates = 8;
viterbiInf->ceStates = *ceStates32;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?