📄 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-2007 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 ippEULA.rtf or ippEULA.txt 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"
/* extention */
extern __ALIGN32 CONST Ipp16s tblGainRampHF[64];
static void ownSynthesis(Ipp16s *pLPCvec, Ipp16s *pExcvec, Ipp16s valQNew,
Ipp16u *pSynSignal, Ipp16s pPrmvec, Ipp16s *pHfIsfvec, IppSpchBitRate mode,
Ipp16s valDTXState, AMRWBDecoder_Obj * st, Ipp16s bfi);
static void ownSynthesisDec_WBE(Ipp16s *pLPCvec, Ipp16s* pExcvec, Ipp16s valQNew,
Ipp16u *pSynSignal, Ipp16s pPrmvec, Ipp16s *pHfIsfvec, IppSpchBitRate mode,
Ipp16s valDTXState, AMRWBDecoder_Obj* st, Ipp16s bfi);
void (*ownSynthFun)(Ipp16s*, Ipp16s*, Ipp16s, Ipp16u*, Ipp16s, Ipp16s*,
IppSpchBitRate, Ipp16s, AMRWBDecoder_Obj*, Ipp16s );
static void ownBits2Prms(const Ipp8u *pBitstream, Ipp16s *pPrms , AMRWB_Rate_t rate);
AMRWB_CODECFUN( APIAMRWB_Status, apiAMRWBDecoder_GetSize,
(AMRWBDecoder_Obj* decoderObj, Ipp32u *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, Ipp32u *pCodecSize))
{
Ipp32s hpfltsize;
if(NULL == amrwb_Params) return APIAMRWB_StsBadArgErr;
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;
/* extention */
decoderObj->siOldPitchLag = 64;
decoderObj->siOldPitchLagFrac = 0;
}
AMRWB_CODECFUN( APIAMRWB_Status, apiAMRWBDecoder_Init,
(AMRWBDecoder_Obj* decoderObj))
{
Ipp32s hpfltsize, i;
DecoderInit(decoderObj);
decoderObj->pSHighPassFIRState = (HighPassFIRState_AMRWB_16s_ISfs *)((Ipp8s*)decoderObj + sizeof(AMRWBDecoder_Obj));
HighPassFIRGetSize_AMRWB_16s_ISfs(&hpfltsize);
decoderObj->pSHighPassFIRState2 = (HighPassFIRState_AMRWB_16s_ISfs *)((Ipp8s*)decoderObj->pSHighPassFIRState + hpfltsize);
decoderObj->pSHPFiltStateSgnlOut = (IppsHighPassFilterState_AMRWB_16s *)((Ipp8s*)decoderObj->pSHighPassFIRState2 + hpfltsize);
ippsHighPassFilterGetSize_AMRWB_16s(2, &hpfltsize);
decoderObj->pSHPFiltStateSgnl400 = (IppsHighPassFilterState_AMRWB_16s *)((Ipp8s*)decoderObj->pSHPFiltStateSgnlOut + hpfltsize);
decoderObj->pSAdaptCdbkDecState = (IppsAdaptiveCodebookDecodeState_AMRWB_16s *)((Ipp8s*)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((Ipp16s*)ACoeffHP50Tbl, (Ipp16s*)BCoeffHP50Tbl, 2, decoderObj->pSHPFiltStateSgnlOut);
HighPassFIRInit_AMRWB_16s_ISfs((Ipp16s*)Fir6k_7kTbl, 2, decoderObj->pSHighPassFIRState);
HighPassFIRInit_AMRWB_16s_ISfs((Ipp16s*)Fir7kTbl, 0, decoderObj->pSHighPassFIRState2);
ippsHighPassFilterInit_AMRWB_16s((Ipp16s*)ACoeffHP400Tbl, (Ipp16s*)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((Ipp16s*)decoderObj->asiSynthesis, LP_ORDER*2);
ownDTXDecReset(&decoderObj->dtxDecState, (Ipp16s*)IsfInitTbl);
decoderObj->siVadHist = 0;
/* extention */
decoderObj->siOldPitchLag = 64;
decoderObj->siOldPitchLagFrac = 0;
ippsZero_16s(decoderObj->mem_syn_out, (PITCH_LAG_MAX + SUBFRAME_SIZE));
ippsZero_16s(decoderObj->mem_oversamp_hf_plus, (2 * UP_SAMPL_FILT_DELAY) );
ippsZero_16s(decoderObj->mem_syn_hf_plus, 8);
ippsZero_16s(decoderObj->lpc_hf_plus + 1, 8);
decoderObj->lpc_hf_plus[0] = 4096;
decoderObj->gain_hf_plus = 0;
decoderObj->threshold_hf = 0;
decoderObj->lp_amp_hf = 0;
decoderObj->ramp_state = 0;
return APIAMRWB_StsNoErr;
}
AMRWB_CODECFUN( APIAMRWB_Status, apiAMRWBDecode,
(AMRWBDecoder_Obj* decoderObj, const Ipp8u* src, AMRWB_Rate_t rate,
RXFrameType rx_type, Ipp16u* dst, Ipp32s offsetWBE))
{
/* Decoder states */
AMRWBDecoder_Obj *st;
/* Excitation vector */
IPP_ALIGNED_ARRAY(16, Ipp16s, pExcOld, (FRAME_SIZE+1)+PITCH_LAG_MAX+INTERPOL_LEN);
Ipp16s *pExcvec;
/* LPC coefficients */
Ipp16s *pLPC;
IPP_ALIGNED_ARRAY(16, Ipp16s, pLPCvec, NUMBER_SUBFRAME*(LP_ORDER+1));
IPP_ALIGNED_ARRAY(16, Ipp16s, pIspvec, LP_ORDER);
IPP_ALIGNED_ARRAY(16, Ipp16s, pIsfvec, LP_ORDER);
IPP_ALIGNED_ARRAY(16, Ipp16s, pFixedCodevec, SUBFRAME_SIZE);
IPP_ALIGNED_ARRAY(16, Ipp16s, pFixedCodevec2, SUBFRAME_SIZE);
IPP_ALIGNED_ARRAY(16, Ipp16s, pExcvec2, FRAME_SIZE);
Ipp16s valFac, valStabFac, valVoiceFac, valQNew = 0;
Ipp32s s, valCodeGain;
/* Scalars */
Ipp16s i, j, valSubFrame, valAdptIndex, valMax, tmp;
Ipp16s valIntPitchLag, valFracPitchLag, valSelect;
Ipp16s valPitchGain, valGainCode, valGainCodeLow;
Ipp16s valDTXState, bfi, unusableFrame;
Ipp16s vadFlag;
Ipp16s valPitchSharp;
IPP_ALIGNED_ARRAY(16, Ipp16s, pExctmp, SUBFRAME_SIZE);
IPP_ALIGNED_ARRAY(16, Ipp16s, pIsftmp, LP_ORDER);
IPP_ALIGNED_ARRAY(16, Ipp16s, pHfIsfvec, LP_ORDER_16K);
Ipp16s pSrcCoeff[2];
Ipp16s pPrevIntPitchLagBounds[2],subFrame;
Ipp16s valPastPitchGain = 0, valPastCodeGain,exp;
Ipp32s valInvEnergy;
IPP_ALIGNED_ARRAY(16, Ipp16s, pPrmvec, MAX_PARAM_SIZE);
Ipp16s *pPrms = pPrmvec;
Ipp16s valCorrGain = 0;
IppSpchBitRate irate = Mode2RateTbl[rate];
if (offsetWBE == 0) { /* old WB mode */
ownSynthFun = ownSynthesis; /* select old Synthesis fun */
if(rx_type != RX_NO_DATA) {
if( rx_type == RX_SID_BAD || rx_type == RX_SID_UPDATE) {
ownBits2Prms(src,pPrms,AMRWB_RATE_DTX);
} else {
ownBits2Prms(src,pPrms,rate);
}
}
} else {
ownSynthFun = ownSynthesisDec_WBE;
ippsCopy_16s((const Ipp16s*)src, pPrms, MAX_PARAM_SIZE);
}
st = decoderObj;
pPrevIntPitchLagBounds[0] = 0;
valDTXState = ownRXDTXHandler(&st->dtxDecState, (Ipp16s)rx_type);
if (valDTXState != SPEECH)
{
ownDTXDec(&st->dtxDecState, pExcvec2, valDTXState, pIsfvec, (const Ipp16u*)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 = (Ipp16s)(valSubFrame >> 6);
ippsInterpolateC_NR_G729_16s_Sfs(pIsftmp, (Ipp16s)(IPP_MAX_16S - InterpolFracTbl[j]),
pIsfvec,InterpolFracTbl[j], pHfIsfvec, LP_ORDER, 15);
ownSynthFun(pLPCvec, &pExcvec2[valSubFrame], 0, &dst[valSubFrame * 5 / 4], (Ipp16s)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((Ipp16s*)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, Ipp16s, pIspTmp, LP_ORDER);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -