📄 decamrwb.c
字号:
/*/////////////////////////////////////////////////////////////////////////////
//
// 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) 2005 Intel Corporation. All Rights Reserved.
//
// Intel(R) Integrated Performance Primitives
// USC - Unified Speech Codec interface library
//
// By downloading and installing USC codec, you hereby agree that the
// accompanying Materials are being provided to you under the terms and
// conditions of the End User License Agreement for the Intel(R) Integrated
// Performance Primitives product previously accepted by you. Please refer
// to the file ipplic.htm located in the root directory of your Intel(R) IPP
// product installation for more information.
//
// A speech coding standards promoted by ITU, ETSI, 3GPP and other
// organizations. Implementations of these standards, or the standard enabled
// platforms may require licenses from various entities, including
// Intel Corporation.
//
//
// Purpose: AMRWB speech codec decoder API functions
//
*/
#include "ownamrwb.h"
static void ownSynthesis(short *pLPCvec, short *pExcvec, short valQNew,
unsigned short *pSynSignal, short pPrmvec, short *pHfIsfvec,
IppSpchBitRate mode, short valDTXState, AMRWBDecoder_Obj * st,
short bfi);
static void ownBits2Prms(const unsigned char *pBitstream, short *pPrms , AMRWB_Rate_t rate);
AMRWB_CODECFUN( APIAMRWB_Status, apiAMRWBDecoder_GetSize,
(AMRWBDecoder_Obj* decoderObj, unsigned int *pCodecSize))
{
if(NULL == decoderObj)
return APIAMRWB_StsBadArgErr;
if(NULL == pCodecSize)
return APIAMRWB_StsBadArgErr;
if(decoderObj->objPrm.iKey != DEC_KEY)
return APIAMRWB_StsNotInitialized;
*pCodecSize = decoderObj->objPrm.iObjSize;
return APIAMRWB_StsNoErr;
}
AMRWB_CODECFUN( APIAMRWB_Status, apiAMRWBDecoder_Alloc,
(const AMRWBDec_Params *amrwb_Params, unsigned int *pCodecSize))
{
int hpfltsize;
HighPassFIRGetSize_AMRWB_16s_ISfs(&hpfltsize);
*pCodecSize=sizeof(AMRWBDecoder_Obj);
*pCodecSize += (2*hpfltsize);
ippsHighPassFilterGetSize_AMRWB_16s(2, &hpfltsize);
*pCodecSize += (2*hpfltsize);
ippsAdaptiveCodebookDecodeGetSize_AMRWB_16s(&hpfltsize);
*pCodecSize += hpfltsize;
return APIAMRWB_StsNoErr;
}
static void DecoderInit(AMRWBDecoder_Obj* decoderObj)
{
ippsZero_16s(decoderObj->asiExcOld, PITCH_LAG_MAX + INTERPOL_LEN);
ippsZero_16s(decoderObj->asiIsfQuantPast, LP_ORDER);
decoderObj->siFrameFirst = 1;
decoderObj->iNoiseEnhancerThres = 0;
decoderObj->siTiltCode = 0;
ownPhaseDispInit(decoderObj->asiPhaseDisp);
/* scaling memories for excitation */
decoderObj->siScaleFactorOld = MAX_SCALE_FACTOR;
decoderObj->asiScaleFactorMax[3] = MAX_SCALE_FACTOR;
decoderObj->asiScaleFactorMax[2] = MAX_SCALE_FACTOR;
decoderObj->asiScaleFactorMax[1] = MAX_SCALE_FACTOR;
decoderObj->asiScaleFactorMax[0] = MAX_SCALE_FACTOR;
return;
}
AMRWB_CODECFUN( APIAMRWB_Status, apiAMRWBDecoder_Init,
(AMRWBDecoder_Obj* decoderObj))
{
int hpfltsize, i;
DecoderInit(decoderObj);
decoderObj->pSHighPassFIRState = (HighPassFIRState_AMRWB_16s_ISfs *)((char*)decoderObj + sizeof(AMRWBDecoder_Obj));
HighPassFIRGetSize_AMRWB_16s_ISfs(&hpfltsize);
decoderObj->pSHighPassFIRState2 = (HighPassFIRState_AMRWB_16s_ISfs *)((char*)decoderObj->pSHighPassFIRState + hpfltsize);
decoderObj->pSHPFiltStateSgnlOut = (IppsHighPassFilterState_AMRWB_16s *)((char*)decoderObj->pSHighPassFIRState2 + hpfltsize);
ippsHighPassFilterGetSize_AMRWB_16s(2, &hpfltsize);
decoderObj->pSHPFiltStateSgnl400 = (IppsHighPassFilterState_AMRWB_16s *)((char*)decoderObj->pSHPFiltStateSgnlOut + hpfltsize);
decoderObj->pSAdaptCdbkDecState = (IppsAdaptiveCodebookDecodeState_AMRWB_16s *)((char*)decoderObj->pSHPFiltStateSgnl400 + hpfltsize);
/* routines initialization */
ippsSet_16s(-14336, decoderObj->asiQuantEnerPast, 4);
ippsZero_16s(decoderObj->asiCodeGainPast, 5);
ippsZero_16s(decoderObj->asiQuantGainPast, 5);
decoderObj->siCodeGainPrev = 0;
ippsZero_16s(decoderObj->asiOversampFilt, 2 * NB_COEF_UP);
ippsHighPassFilterInit_AMRWB_16s((short*)ACoeffHP50Tbl, (short*)BCoeffHP50Tbl, 2, decoderObj->pSHPFiltStateSgnlOut);
HighPassFIRInit_AMRWB_16s_ISfs((short*)Fir6k_7kTbl, 2, decoderObj->pSHighPassFIRState);
HighPassFIRInit_AMRWB_16s_ISfs((short*)Fir7kTbl, 0, decoderObj->pSHighPassFIRState2);
ippsHighPassFilterInit_AMRWB_16s((short*)ACoeffHP400Tbl, (short*)BCoeffHP400Tbl, 2, decoderObj->pSHPFiltStateSgnl400);
/* isp initialization */
ippsCopy_16s(IspInitTbl, decoderObj->asiIspOld, LP_ORDER);
ippsCopy_16s(IsfInitTbl, decoderObj->asiIsfOld, LP_ORDER);
for (i=0; i<3; i++)
ippsCopy_16s(IsfInitTbl, &decoderObj->asiIsf[i * LP_ORDER], LP_ORDER);
/* variable initialization */
decoderObj->siDeemph = 0;
decoderObj->siSeed = RND_INIT; /* init random with 21845 */
decoderObj->siHFSeed = RND_INIT; /* init random with 21845 */
ippsAdaptiveCodebookDecodeInit_AMRWB_16s(decoderObj->pSAdaptCdbkDecState);
decoderObj->siBFHState = 0;
decoderObj->siBfiPrev = 0;
/* Static vectors to zero */
ippsZero_16s(decoderObj->asiSynthHighFilt, LP_ORDER_16K);
ippsZero_16s((short*)decoderObj->asiSynthesis, LP_ORDER*2);
ownDTXDecReset(&decoderObj->dtxDecState, (short*)IsfInitTbl);
decoderObj->siVadHist = 0;
return APIAMRWB_StsNoErr;
}
AMRWB_CODECFUN( APIAMRWB_Status, apiAMRWBDecode,
(AMRWBDecoder_Obj* decoderObj, const unsigned char* src, AMRWB_Rate_t rate,
RXFrameType rx_type, unsigned short* dst))
{
/* Decoder states */
AMRWBDecoder_Obj *st;
/* Excitation vector */
IPP_ALIGNED_ARRAY(16, short, pExcOld, (FRAME_SIZE+1)+PITCH_LAG_MAX+INTERPOL_LEN);
short *pExcvec;
/* LPC coefficients */
short *pLPC;
IPP_ALIGNED_ARRAY(16, short, pLPCvec, NUMBER_SUBFRAME*(LP_ORDER+1));
IPP_ALIGNED_ARRAY(16, short, pIspvec, LP_ORDER);
IPP_ALIGNED_ARRAY(16, short, pIsfvec, LP_ORDER);
IPP_ALIGNED_ARRAY(16, short, pFixedCodevec, SUBFRAME_SIZE);
IPP_ALIGNED_ARRAY(16, short, pFixedCodevec2, SUBFRAME_SIZE);
IPP_ALIGNED_ARRAY(16, short, pExcvec2, FRAME_SIZE);
short valFac, valStabFac, valVoiceFac, valQNew = 0;
int s, valCodeGain;
/* Scalars */
short i, j, valSubFrame, valAdptIndex, valMax, tmp;
short valIntPitchLag, valFracPitchLag, valSelect;
short valPitchGain, valGainCode, valGainCodeLow;
short valDTXState, bfi, unusableFrame;
short vadFlag;
short valPitchSharp;
IPP_ALIGNED_ARRAY(16, short, pExctmp, SUBFRAME_SIZE);
IPP_ALIGNED_ARRAY(16, short, pIsftmp, LP_ORDER);
IPP_ALIGNED_ARRAY(16, short, pHfIsfvec, LP_ORDER_16K);
short pSrcCoeff[2];
short pPrevIntPitchLagBounds[2],subFrame;
short valPastPitchGain, valPastCodeGain,exp;
int valInvEnergy;
IPP_ALIGNED_ARRAY(16, short, pPrmvec, MAX_PARAM_SIZE);
short *pPrms = pPrmvec;
short valCorrGain = 0;
IppSpchBitRate irate = Mode2RateTbl[rate];
if( rx_type == RX_SID_BAD || rx_type == RX_SID_UPDATE) {
ownBits2Prms(src,pPrms,AMRWB_RATE_DTX);
}else{
ownBits2Prms(src,pPrms,rate);
}
st = decoderObj;
pPrevIntPitchLagBounds[0] = 0;
valDTXState = ownRXDTXHandler(&st->dtxDecState, (short)rx_type);
if (valDTXState != SPEECH)
{
ownDTXDec(&st->dtxDecState, pExcvec2, valDTXState, pIsfvec, (const unsigned short*)pPrms);
}
/* SPEECH action state machine */
if ((rx_type == RX_SPEECH_BAD) ||
(rx_type == RX_SPEECH_PROBABLY_DEGRADED))
{
/* bfi for all valAdptIndex, bits are not usable */
bfi = 1;
unusableFrame = 0;
} else if ((rx_type == RX_SPEECH_LOST) ||
(rx_type == RX_NO_DATA))
{
/* bfi only for lsf, gains and pitch period */
bfi = 1;
unusableFrame = 1;
} else
{
bfi = 0;
unusableFrame = 0;
}
if (bfi != 0)
{
st->siBFHState += 1;
if (st->siBFHState > 6) st->siBFHState = 6;
} else
{
st->siBFHState >>= 1;
}
if (st->dtxDecState.siGlobalState == DTX)
{
st->siBFHState = 5;
st->siBfiPrev = 0;
} else if (st->dtxDecState.siGlobalState == DTX_MUTE)
{
st->siBFHState = 5;
st->siBfiPrev = 1;
}
if (valDTXState == SPEECH)
{
vadFlag = *(pPrms)++;
if (bfi == 0)
{
if (vadFlag == 0)
st->siVadHist += 1;
else
st->siVadHist = 0;
}
}
if (valDTXState != SPEECH) /* CNG mode */
{
ippsISFToISP_AMRWB_16s(pIsfvec, pIspvec, LP_ORDER);
// ippsISPToLPC_AMRWB_16s(pIspvec, pLPCvec, LP_ORDER);
ownISPToLPC_AMRWB_16s(pIspvec, pLPCvec, LP_ORDER, 1);
ippsCopy_16s(st->asiIsfOld, pIsftmp, LP_ORDER);
for (valSubFrame = 0; valSubFrame < FRAME_SIZE; valSubFrame += SUBFRAME_SIZE)
{
j = valSubFrame >> 6;
ippsInterpolateC_NR_G729_16s_Sfs(pIsftmp, (short)(IPP_MAX_16S - InterpolFracTbl[j]),
pIsfvec,InterpolFracTbl[j], pHfIsfvec, LP_ORDER, 15);
ownSynthesis(pLPCvec, &pExcvec2[valSubFrame], 0, &dst[valSubFrame * 5 / 4], (short)1,
pHfIsfvec, irate, valDTXState, st, bfi);
}
DecoderInit(decoderObj);
ippsCopy_16s(pIsfvec, st->asiIsfOld, LP_ORDER);
st->siBfiPrev = bfi;
st->dtxDecState.siGlobalState = valDTXState;
return APIAMRWB_StsNoErr;
}
ippsCopy_16s(st->asiExcOld, pExcOld, PITCH_LAG_MAX + INTERPOL_LEN);
pExcvec = pExcOld + PITCH_LAG_MAX + INTERPOL_LEN;
ippsISFQuantDecode_AMRWB_16s((short*)pPrms, pIsfvec, st->asiIsfQuantPast, st->asiIsfOld, st->asiIsf, bfi, irate);
if ((irate == IPP_SPCHBR_6600)||(irate == IPP_SPCHBR_DTX))
pPrms += 5;
else
pPrms += 7;
ippsISFToISP_AMRWB_16s(pIsfvec, pIspvec, LP_ORDER);
if (st->siFrameFirst != 0)
{
st->siFrameFirst = 0;
ippsCopy_16s(pIspvec, st->asiIspOld, LP_ORDER);
}
/* Find the interpolated ISPs and convert to pLPCvec for all subframes */
{
IPP_ALIGNED_ARRAY(16, short, pIspTmp, LP_ORDER);
ippsInterpolateC_NR_G729_16s_Sfs(st->asiIspOld, 18022, pIspvec,14746, pIspTmp, LP_ORDER, 15);
ippsISPToLPC_AMRWB_16s(pIspTmp, pLPCvec, LP_ORDER);
ippsInterpolateC_NR_G729_16s_Sfs(st->asiIspOld, 6554, pIspvec,26214, pIspTmp, LP_ORDER, 15);
ippsISPToLPC_AMRWB_16s(pIspTmp, &pLPCvec[LP_ORDER + 1], LP_ORDER);
ippsInterpolateC_NR_G729_16s_Sfs(st->asiIspOld, 1311, pIspvec,31457, pIspTmp, LP_ORDER, 15);
ippsISPToLPC_AMRWB_16s(pIspTmp, &pLPCvec[2*(LP_ORDER + 1)], LP_ORDER);
/* 4th subframe: pLPCvec (frac=1.0) */
ippsISPToLPC_AMRWB_16s(pIspvec, &pLPCvec[3*(LP_ORDER + 1)], LP_ORDER);
ippsCopy_16s(pIspvec, st->asiIspOld, LP_ORDER);
}
/* Check stability on pIsfvec : distance between old st->asiIsfOld and current pIsfvec */
valStabFac = ownChkStab(pIsfvec, st->asiIsfOld, LP_ORDER-1);
ippsCopy_16s(st->asiIsfOld, pIsftmp, LP_ORDER);
ippsCopy_16s(pIsfvec, st->asiIsfOld, LP_ORDER);
pLPC = pLPCvec; /* pointer to interpolated LPC parameters */
for (valSubFrame = 0,subFrame=0; valSubFrame < FRAME_SIZE; valSubFrame += SUBFRAME_SIZE,subFrame++)
{
valAdptIndex = *(pPrms)++;
ippsAdaptiveCodebookDecode_AMRWB_16s(valAdptIndex, &valFracPitchLag, &pExcvec[valSubFrame],
&valIntPitchLag, pPrevIntPitchLagBounds, subFrame, bfi, unusableFrame, irate,st->pSAdaptCdbkDecState);
if (unusableFrame)
{
valSelect = 1;
} else
{
if ((irate == IPP_SPCHBR_6600)||(irate == IPP_SPCHBR_8850)||(irate == IPP_SPCHBR_DTX))
valSelect = 0;
else
valSelect = *(pPrms)++;
}
if (valSelect == 0)
{
/* find pitch excitation with lp filter */
pSrcCoeff[0] = 20972;
pSrcCoeff[1] = -5898;
ippsHighPassFilter_Direct_AMRWB_16s(pSrcCoeff, &pExcvec[valSubFrame], pFixedCodevec, SUBFRAME_SIZE, 1);
ippsCopy_16s(pFixedCodevec, &pExcvec[valSubFrame], SUBFRAME_SIZE);
}
if (unusableFrame != 0)
{
for (i = 0; i < SUBFRAME_SIZE; i++)
{
pFixedCodevec[i] = Random(&(st->siSeed)) >> 3;
}
} else {
ippsAlgebraicCodebookDecode_AMRWB_16s((short*)pPrms, pFixedCodevec, irate);
if ((irate == IPP_SPCHBR_6600)||(irate == IPP_SPCHBR_DTX))
pPrms += 1;
else if ((irate == IPP_SPCHBR_8850) || (irate == IPP_SPCHBR_12650) ||
(irate == IPP_SPCHBR_14250) || (irate == IPP_SPCHBR_15850))
pPrms += 4;
else
pPrms += 8;
}
tmp = 0;
ippsPreemphasize_AMRWB_16s_ISfs (st->siTiltCode, pFixedCodevec, SUBFRAME_SIZE, 14, &tmp);
tmp = valIntPitchLag;
if (valFracPitchLag > 2) tmp += 1;
if (tmp < SUBFRAME_SIZE) {
ippsHarmonicFilter_NR_16s(PITCH_SHARP_FACTOR, tmp, &pFixedCodevec[tmp], &pFixedCodevec[tmp], SUBFRAME_SIZE-tmp);
}
ippsDotProd_16s32s_Sfs(pFixedCodevec, pFixedCodevec,SUBFRAME_SIZE, &s, -1);
s = Add_32s(s, 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -