📄 utilgsmamr.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: GSMAMR speech codec: common utilities.
//
*/
#include "owngsmamr.h"
/****************************************************************************
* Function: ownVADPitchDetection_GSMAMR()
***************************************************************************/
void ownVADPitchDetection_GSMAMR(IppGSMAMRVad1State *st, Ipp16s *pTimeVec,
Ipp16s *vLagCountOld, Ipp16s *vLagOld)
{
Ipp16s lagcount, i;
lagcount = 0;
for (i = 0; i < 2; i++) {
if(Abs_16s(*vLagOld - pTimeVec[i]) < LOW_THRESHOLD) lagcount++;
*vLagOld = pTimeVec[i];
}
st->pitchFlag >>= 1;
if (*vLagCountOld + lagcount >= NUM_THRESHOLD)
st->pitchFlag = (Ipp16s)(st->pitchFlag | 0x4000);
*vLagCountOld = lagcount;
}
/***************************************************************************
* Function: ownUpdateLTPFlag_GSMAMR()
*************************************************************************/
void ownUpdateLTPFlag_GSMAMR(IppSpchBitRate rate, Ipp32s L_Rmax, Ipp32s L_R0, Ipp16s *vFlagLTP)
{
Ipp16s thresh;
Ipp16s hi1;
Ipp16s lo1;
Ipp32s Ltmp;
if ((rate == IPP_SPCHBR_4750) || (rate == IPP_SPCHBR_5150)) thresh = 18022;
else if (rate == IPP_SPCHBR_10200) thresh = 19660;
else thresh = 21299;
hi1 = (Ipp16s)(L_R0 >> 16);
lo1 = (Ipp16s)((L_R0 >> 1) & 0x7fff);
Ltmp = (hi1 * thresh + ((lo1 * thresh) >> 15));
if (L_Rmax > 2*Ltmp) *vFlagLTP = 1;
else *vFlagLTP = 0;
return;
/* End of ownUpdateLTPFlag_GSMAMR() */
}
static __ALIGN32 CONST Ipp16s TableLog2[33] = {
0, 1455, 2866, 4236, 5568, 6863, 8124, 9352,
10549, 11716, 12855, 13967, 15054, 16117, 17156, 18172,
19167, 20142, 21097, 22033, 22951, 23852, 24735, 25603,
26455, 27291, 28113, 28922, 29716, 30497, 31266, 32023,
32767 };
/*************************************************************************
* Function: ownLog2_GSMAMR_norm
*************************************************************************/
void ownLog2_GSMAMR_norm(Ipp32s inVal, Ipp16s exp, Ipp16s *expPart, Ipp16s *fracPart)
{
Ipp16s idx, a, tmp;
Ipp32s outVal;
if( inVal <= 0 ) {
*expPart = 0;
*fracPart = 0;
return;
}
*expPart = (Ipp16s)(30 - exp);
idx = (Ipp16s)(inVal >> 25);
a = (Ipp16s)((inVal >> 10) & 0x7fff);
idx -= 32;
outVal = TableLog2[idx] << 16;
tmp = (Ipp16s)(TableLog2[idx] - TableLog2[idx+1]);
outVal -= 2 * tmp * a;
*fracPart = (Ipp16s)(outVal >> 16);
return;
/* End of ownLog2_GSMAMR_norm() */
}
/*************************************************************************
* Function: ownLog2_GSMAMR()
*************************************************************************/
void ownLog2_GSMAMR(Ipp32s inVal, Ipp16s *expPart, Ipp16s *fracPart)
{
Ipp16s exp;
exp = Norm_32s_I(&inVal);
ownLog2_GSMAMR_norm (inVal, exp, expPart, fracPart);
return;
/* End of ownLog2_GSMAMR() */
}
/*************************************************************************
* Function: ownPow2_GSMAMR
*************************************************************************/
static __ALIGN32 CONST Ipp16s TablePow2[33] = {
16384, 16743, 17109, 17484, 17867, 18258, 18658, 19066,
19484, 19911, 20347, 20792, 21247, 21713, 22188, 22674,
23170, 23678, 24196, 24726, 25268, 25821, 26386, 26964,
27554, 28158, 28774, 29405, 30048, 30706, 31379, 32066,
32767 };
Ipp32s ownPow2_GSMAMR(Ipp16s expPart, Ipp16s fracPart)
{
Ipp16s exp, idx, a, tmp;
Ipp32s inVal, outVal, temp;
exp = (Ipp16s)(30 - expPart);
if (exp > 31) return 0;
idx = (Ipp16s)(fracPart >> 10);
a = (Ipp16s)((fracPart << 5) & 0x7fff);
inVal = TablePow2[idx] << 16;
tmp = (Ipp16s)(TablePow2[idx] - TablePow2[idx+1]);
inVal = inVal - 2*tmp*a;
if (exp >= 31) outVal = (inVal < 0) ? -1 : 0;
else outVal = inVal >> exp;
temp = 1 << (exp-1);
if(inVal & temp) outVal++;
return(outVal);
/* End of ownPow2_GSMAMR() */
}
/* table[i] = sqrt((i+16)*2^-6) * 2^15, i.e. sqrt(x) scaled Q15 */
static __ALIGN32 CONST Ipp16s TableSqrt[49] =
{
16384, 16888, 17378, 17854, 18318, 18770, 19212, 19644,
20066, 20480, 20886, 21283, 21674, 22058, 22435, 22806,
23170, 23530, 23884, 24232, 24576, 24915, 25249, 25580,
25905, 26227, 26545, 26859, 27170, 27477, 27780, 28081,
28378, 28672, 28963, 29251, 29537, 29819, 30099, 30377,
30652, 30924, 31194, 31462, 31727, 31991, 32252, 32511,
32767};
/********************************************************************************
* Function: ownSqrt_Exp_GSMAMR()
********************************************************************************/
Ipp32s ownSqrt_Exp_GSMAMR (Ipp32s inVal, Ipp16s *exp)
{
Ipp16s idx, a, tmp;
Ipp32s outVal;
if (inVal <= 0) { *exp = 0; return 0; }
outVal = inVal;
*exp = (Ipp16s)(Norm_32s_I(&outVal) & 0xFFFE);
inVal <<= *exp;
idx = (Ipp16s)(inVal >> 25);
a = (Ipp16s)((inVal >> 10) & 0x7fff);
idx -= 16;
outVal = TableSqrt[idx] << 16;
tmp = (Ipp16s)(TableSqrt[idx] - TableSqrt[idx+1]);
outVal = outVal - 2*tmp*a;
return (outVal);
/* End of ownSqrt_Exp_GSMAMR() */
}
/*************************************************************************
* Function: Reorder_lsf()
*************************************************************************/
void ownReorderLSFVec_GSMAMR(Ipp16s *lsf, Ipp16s minDistance, Ipp16s len)
{
Ipp32s i;
Ipp16s lsf_min;
lsf_min = minDistance;
for (i = 0; i < len; i++) {
if(lsf[i] < lsf_min) lsf[i] = lsf_min;
lsf_min = (Ipp16s)(lsf[i] + minDistance);
}
}
/*************************************************************************
* Function: ownGetMedianElements_GSMAMR()
*************************************************************************/
Ipp16s ownGetMedianElements_GSMAMR (Ipp16s *pPastGainVal, Ipp16s num)
{
Ipp16s i, j, idx = 0;
Ipp16s max;
Ipp16s medianIndex;
Ipp16s tmp[MAX_MED_SIZE];
Ipp16s tmp2[MAX_MED_SIZE];
ippsCopy_16s(pPastGainVal, tmp2, num);
for (i = 0; i < num; i++) {
max = -32767;
for (j = 0; j < num; j++) {
if (tmp2[j] >= max) {
max = tmp2[j];
idx = j;
}
}
tmp2[idx] = -32768;
tmp[i] = idx;
}
medianIndex = tmp[num >> 1];
return (pPastGainVal[medianIndex]);
}
/**************************************************************************
* Proc: ownCtrlDetectBackgroundNoise_GSMAMR() -
***************************************************************************/
Ipp16s ownCtrlDetectBackgroundNoise_GSMAMR (Ipp16s excitation[], Ipp16s excEnergy, Ipp16s exEnergyHist[],
Ipp16s vVoiceHangover, Ipp16s prevBFI, Ipp16s carefulFlag)
{
Ipp16s exp;
Ipp16s testEnergy, scaleFactor, avgEnergy, prevEnergy;
Ipp32s t0;
avgEnergy = ownGetMedianElements_GSMAMR(exEnergyHist, 9);
prevEnergy = (Ipp16s)((exEnergyHist[7] + exEnergyHist[8]) >> 1);
if( exEnergyHist[8] < prevEnergy) prevEnergy = exEnergyHist[8];
if( excEnergy < avgEnergy && excEnergy > 5) {
testEnergy = (Ipp16s)(prevEnergy << 2);
if( vVoiceHangover < 7 || prevBFI != 0 ) testEnergy = (Ipp16s)(testEnergy - prevEnergy);
if( avgEnergy > testEnergy) avgEnergy = testEnergy;
exp = 0;
for(; excEnergy < 0x4000; exp++) excEnergy <<= 1;
excEnergy = (Ipp16s)((16383<<15)/excEnergy);
t0 = avgEnergy * excEnergy;
t0 >>= 19 - exp;
if(t0 > 32767) t0 = 32767;
scaleFactor = (Ipp16s)t0;
if((carefulFlag != 0) && (scaleFactor > 3072)) scaleFactor = 3072;
ippsMulC_16s_ISfs(scaleFactor, excitation, SUBFR_SIZE_GSMAMR, 10);
}
return 0;
}
/*************************************************************************
* Function: ownComputeCodebookGain_GSMAMR
*************************************************************************/
Ipp16s ownComputeCodebookGain_GSMAMR (Ipp16s *pTargetVec, Ipp16s *pFltVec)
{
Ipp16s i;
Ipp16s xy, yy, exp_xy, exp_yy, gain;
IPP_ALIGNED_ARRAY(16, Ipp16s, pFltVecScale, SUBFR_SIZE_GSMAMR);
Ipp32s s;
ippsRShiftC_16s(pFltVec, 1, pFltVecScale, SUBFR_SIZE_GSMAMR);
ippsDotProd_16s32s_Sfs(pTargetVec, pFltVecScale, SUBFR_SIZE_GSMAMR, &s, 0);
if(s == 0) s = 1;
s <<= 1;
exp_xy = Norm_32s_I(&s);
xy = (Ipp16s)(s >> 16);
if(xy <= 0) return ((Ipp16s) 0);
ippsDotProd_16s32s_Sfs(pFltVecScale, pFltVecScale, SUBFR_SIZE_GSMAMR, &s, -1);
exp_yy = Norm_32s_I(&s);
yy = (Ipp16s)(s >> 16);
xy >>= 1;
//gain = (yy > 0)? (xy<<15)/yy : IPP_MAX_16S;
if(yy > 0) gain = (Ipp16s)((xy<<15)/yy);
else gain = IPP_MAX_16S;
i = (Ipp16s)(exp_xy + 5);
i = (Ipp16s)(i - exp_yy);
gain = (Ipp16s)((gain >> i) << 1);
return (gain);
}
/*************************************************************************
* Function: ownGainAdaptAlpha_GSMAMR
*************************************************************************/
void ownGainAdaptAlpha_GSMAMR(Ipp16s *vOnSetQntGain, Ipp16s *vPrevAdaptOut, Ipp16s *vPrevGainZero,
Ipp16s *a_LTPHistoryGain, Ipp16s ltpg, Ipp16s gainCode, Ipp16s *alpha)
{
Ipp16s adapt;
Ipp16s result;
Ipp16s filt;
Ipp16s tmp, i;
Ipp32s temp;
if (ltpg <= LTP_GAIN_LOG10_1) adapt = 0;
else if (ltpg <= LTP_GAIN_LOG10_2) adapt = 1;
else adapt = 2;
tmp = (Ipp16s)(gainCode >> 1);
if (gainCode & 1) tmp++;
if (tmp > *vPrevGainZero && gainCode > 200) *vOnSetQntGain = 8;
else if (*vOnSetQntGain != 0) *vOnSetQntGain -= 1;
if ((*vOnSetQntGain != 0) && (adapt < 2)) adapt += 1;
a_LTPHistoryGain[0] = ltpg;
filt = ownGetMedianElements_GSMAMR(a_LTPHistoryGain, 5);
if(adapt == 0) {
if (filt > 5443) result = 0;
else if (filt < 0) result = 16384;
else {
temp = (24660 * filt)>>13;
result = (Ipp16s)(16384 - temp);
}
} else result = 0;
if (*vPrevAdaptOut == 0) result >>= 1;
*alpha = result;
*vPrevAdaptOut = result;
*vPrevGainZero = gainCode;
for (i = NUM_MEM_LTPG-1; i > 0; i--)
a_LTPHistoryGain[i] = a_LTPHistoryGain[i-1];
}
/**************************************************************************
* Function: ownCBGainAverage_GSMAMR()
**************************************************************************/
Ipp16s ownCBGainAverage_GSMAMR(Ipp16s *a_GainHistory, Ipp16s *vHgAverageVar, Ipp16s *vHgAverageCount,
IppSpchBitRate rate, Ipp16s gainCode, Ipp16s *lsp, Ipp16s *lspAver,
Ipp16s badFrame, Ipp16s vPrevBadFr, Ipp16s potDegBadFrame, Ipp16s vPrevDegBadFr,
Ipp16s vBackgroundNoise, Ipp16s vVoiceHangover)
{
Ipp16s i;
Ipp16s cbGainMix, diff, bgMix, cbGainMean;
Ipp32s L_sum;
Ipp16s tmp[LP_ORDER_SIZE], tmp1, tmp2, shift1, shift2, shift;
cbGainMix = gainCode;
for (i = 0; i < (CBGAIN_HIST_SIZE-1); i++)
a_GainHistory[i] = a_GainHistory[i+1];
a_GainHistory[CBGAIN_HIST_SIZE-1] = gainCode;
for (i = 0; i < LP_ORDER_SIZE; i++) {
tmp1 = (Ipp16s)Abs_16s(lspAver[i] - lsp[i]);
shift1 = (Ipp16s)(Exp_16s(tmp1) - 1);
tmp1 <<= shift1;
shift2 = Exp_16s(lspAver[i]);
tmp2 = (Ipp16s)(lspAver[i] << shift2);
//tmp[i] = (tmp2>0)? (tmp1<<15)/tmp2 : IPP_MAX_16S;
if(tmp2 > 0) tmp[i] = (Ipp16s)((tmp1<<15)/tmp2);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -