📄 dtxamrwb.c
字号:
valExp += valExpTmp;
valExp += 4;
for (i = 0; i < FRAME_SIZE; i++)
{
tmp = Mul_16s_Sfs(pExc2vec[i], valGain, 15);
if (valExp > 0)
pExc2vec[i] = ShiftL_32s(tmp, valExp);
else
pExc2vec[i] = tmp >> (-valExp);
}
if (valDTXState == DTX_MUTE)
{
/* mute comfort noise as it has been quite a long time since last SID update was performed */
valInterFac = st->siSidLast;
if (valInterFac > 32) valInterFac = 32;
st->siSidPeriodInv = (1 << 15) / valInterFac;
st->siSidLast = 0;
st->siLogEnergyOld = st->siLogEnergy;
st->siLogEnergy -= 64;
}
/* reset interpolation length timer if data has been updated */
if ((st->siSidFrame != 0) &&
((st->siValidData != 0) || ((st->siValidData == 0) && (st->siHangoverAdded) != 0)))
{
st->siSidLast = 0;
st->siDataUpdated = 1;
}
return 0;
}
short ownRXDTXHandler(SDtxDecoderState *st, short frameType)
{
short valDTXState;
/* DTX if SID frame or previously in DTX{_MUTE} and (NO_RX OR BAD_SPEECH) */
if ((frameType == RX_SID_FIRST) ||
(frameType == RX_SID_UPDATE) ||
(frameType == RX_SID_BAD) ||
(((st->siGlobalState == DTX) ||
(st->siGlobalState == DTX_MUTE)) &&
((frameType == RX_NO_DATA) ||
(frameType == RX_SPEECH_BAD) ||
(frameType == RX_SPEECH_LOST))))
{
valDTXState = DTX;
if ((st->siGlobalState == DTX_MUTE) &&
((frameType == RX_SID_BAD) ||
(frameType == RX_SID_FIRST) ||
(frameType == RX_SPEECH_LOST) ||
(frameType == RX_NO_DATA)))
{
valDTXState = DTX_MUTE;
}
st->siSidLast += 1;
if (st->siSidLast > DTX_MAX_EMPTY_THRESH)
valDTXState = DTX_MUTE;
} else
{
valDTXState = SPEECH;
st->siSidLast = 0;
}
if ((st->siDataUpdated == 0) && (frameType == RX_SID_UPDATE))
st->siAnaElapsedCount = 0;
st->siAnaElapsedCount = Cnvrt_32s16s(st->siAnaElapsedCount+1);
st->siHangoverAdded = 0;
if ((frameType == RX_SID_FIRST) ||
(frameType == RX_SID_UPDATE) ||
(frameType == RX_SID_BAD) ||
(frameType == RX_NO_DATA))
{
if (st->siAnaElapsedCount > DTX_ELAPSED_FRAMES_THRESH)
{
st->siHangoverAdded = 1;
st->siAnaElapsedCount = 0;
st->siHangoverCount = 0/*1*/;
} else if (st->siHangoverCount == 0)
{
st->siAnaElapsedCount = 0;
} else
{
st->siHangoverCount -= 1;
}
} else
{
st->siHangoverCount = DTX_HANG_CONST;
}
if (valDTXState != SPEECH)
{
/* DTX or DTX_MUTE CN data is not in a first SID, first SIDs are marked as SID_BAD but will do
* backwards analysis if a hangover period has been added according to the state machine above */
st->siSidFrame = 0/*2*/;
st->siValidData = 0;
if (frameType == RX_SID_FIRST)
{
st->siSidFrame = 1;
} else if (frameType == RX_SID_UPDATE)
{
st->siSidFrame = 1;
st->siValidData = 1;
} else if (frameType == RX_SID_BAD)
{
st->siSidFrame = 1;
st->siHangoverAdded = 0;
}
}
return valDTXState;
}
static void ownAverageIsfHistory(short *pIsfOldvec, short *pIndices, int *pIsfAvrvec)
{
int i, j, k;
IPP_ALIGNED_ARRAY(16, short, pIsfTmpvec, 2 * LP_ORDER);
int s;
for (k = 0; k < 2; k++)
{
if ((pIndices[k] + 1) != 0)
{
ippsCopy_16s(&pIsfOldvec[pIndices[k] * LP_ORDER], &pIsfTmpvec[k * LP_ORDER], LP_ORDER);
ippsCopy_16s(&pIsfOldvec[pIndices[2] * LP_ORDER], &pIsfOldvec[pIndices[k] * LP_ORDER], LP_ORDER);
}
}
for (j = 0; j < LP_ORDER; j++)
{
s = 0;
for (i = 0; i < DTX_HIST_SIZE; i++)
s += (int)(pIsfOldvec[i * LP_ORDER + j]);
pIsfAvrvec[j] = s;
}
for (k = 0; k < 2; k++)
{
if ((pIndices[k] + 1) != 0)
ippsCopy_16s(&pIsfTmpvec[k * LP_ORDER], &pIsfOldvec[pIndices[k] * LP_ORDER], LP_ORDER);
}
return;
}
static void ownFindFrameIndices(short *pIsfOldvec, short *pIndices, SDtxEncoderState *st)
{
int s, valSumMin, valSumMax, valSumMax2;
short i, j, tmp;
short valHistPtr;
tmp = DTX_HIST_SIZE_MIN_ONE;
j = -1;
for (i = 0; i < DTX_HIST_SIZE_MIN_ONE; i++)
{
j += tmp;
st->aiSumDist[i] -= st->aiDistMatrix[j];
tmp -= 1;
}
ippsMove_32f((float*)st->aiSumDist, (float*)&st->aiSumDist[1], DTX_HIST_SIZE_MIN_ONE);
st->aiSumDist[0] = 0;
tmp = 0;
for (i = 27; i >= 12; i = (short) (i - tmp))
{
tmp += 1;
ippsMove_32f((float*)&st->aiDistMatrix[i - tmp - tmp], (float*)&st->aiDistMatrix[i - tmp + 1], tmp);
}
valHistPtr = st->siHistPtr;
for (i = 1; i < DTX_HIST_SIZE; i++)
{
/* Compute the distance between the latest isf and the other isfs. */
valHistPtr -= 1;
if (valHistPtr < 0) valHistPtr = DTX_HIST_SIZE_MIN_ONE;
s = 0;
for (j = 0; j < LP_ORDER; j++)
{
tmp = pIsfOldvec[st->siHistPtr * LP_ORDER + j] - pIsfOldvec[valHistPtr * LP_ORDER + j];
s += tmp * tmp;
}
st->aiDistMatrix[i - 1] = s << 1;
st->aiSumDist[0] += st->aiDistMatrix[i - 1];
st->aiSumDist[i] += st->aiDistMatrix[i - 1];
}
/* Find the minimum and maximum distances */
valSumMax = st->aiSumDist[0];
valSumMin = st->aiSumDist[0];
pIndices[0] = 0;
pIndices[2] = 0;
for (i = 1; i < DTX_HIST_SIZE; i++)
{
if (st->aiSumDist[i] > valSumMax)
{
pIndices[0] = i;
valSumMax = st->aiSumDist[i];
}
if (st->aiSumDist[i] < valSumMin)
{
pIndices[2] = i;
valSumMin = st->aiSumDist[i];
}
}
/* Find the second largest distance */
valSumMax2 = IPP_MIN_32S + 1;
pIndices[1] = -1;
for (i = 0; i < DTX_HIST_SIZE; i++)
{
if ((st->aiSumDist[i] > valSumMax2) && (i != pIndices[0]))
{
pIndices[1] = i;
valSumMax2 = st->aiSumDist[i];
}
}
for (i = 0; i < 3; i++)
{
pIndices[i] = st->siHistPtr - pIndices[i];
if (pIndices[i] < 0) pIndices[i] += DTX_HIST_SIZE;
}
tmp = Norm_32s_I(&valSumMax);
valSumMin <<= tmp;
s = 2 * Cnvrt_NR_32s16s(valSumMax) * INV_MED_THRESH;
if (s <= valSumMin) pIndices[0] = -1;
valSumMax2 <<= tmp;
s = 2 * Cnvrt_NR_32s16s(valSumMax2) * INV_MED_THRESH;
if (s <= valSumMin) pIndices[1] = -1;
return;
}
static short ownDitherCtrl(SDtxEncoderState *st)
{
short tmp, valMean, valCNDith, valGainDiff;
int i, valIsfDiff;
/* determine how stationary the spectrum of background noise is */
ippsSum_32s_Sfs(st->aiSumDist, 8, &valIsfDiff, 0);
// valIsfDiff = 0;
// for (i = 0; i < 8; i++)
// {
// valIsfDiff = Add_32s(valIsfDiff, st->aiSumDist[i]);
// }
if ((valIsfDiff >> 26) > 0)
valCNDith = 1;
else
valCNDith = 0;
/* determine how stationary the energy of background noise is */
ippsSum_16s_Sfs(st->siLogEnerHist, DTX_HIST_SIZE, &valMean, 3);
valGainDiff = 0;
for (i = 0; i < DTX_HIST_SIZE; i++)
{
tmp = Abs_16s((short)(st->siLogEnerHist[i] - valMean));
valGainDiff += tmp;
}
if (valGainDiff > GAIN_THRESH) valCNDith = 1;
return valCNDith;
}
static void ownCNDithering(short *pIsfvec, int *valLogIntEnergy, short *pDitherSeed)
{
short temp, temp1, valDitherFac, valRandDither, valRandDither2;
int i;
/* Insert comfort noise dithering for energy parameter */
valRandDither = Random(pDitherSeed) >> 1;
valRandDither2 = Random(pDitherSeed) >> 1;
valRandDither += valRandDither2;
*valLogIntEnergy += 2 * valRandDither * GAIN_FACTOR;
if (*valLogIntEnergy < 0) *valLogIntEnergy = 0;
/* Insert comfort noise dithering for spectral parameters (ISF-vector) */
valDitherFac = ISF_FACTOR_LOW;
valRandDither = Random(pDitherSeed) >> 1;
valRandDither2 = Random(pDitherSeed) >> 1;
valRandDither += valRandDither2;
temp = pIsfvec[0] + ((valRandDither * valDitherFac + 0x00004000) >> 15);
if (temp < ISF_GAP)
pIsfvec[0] = ISF_GAP;
else
pIsfvec[0] = temp;
for (i = 1; i < LP_ORDER - 1; i++)
{
valDitherFac += ISF_FACTOR_STEP;
valRandDither = Random(pDitherSeed) >> 1;
valRandDither2 = Random(pDitherSeed) >> 1;
valRandDither += valRandDither2;
temp = pIsfvec[i] + ((valRandDither * valDitherFac + 0x00004000) >> 15);
temp1 = temp - pIsfvec[i - 1];
/* Make sure that isf spacing remains at least ISF_DITHER_GAP Hz */
if (temp1 < ISF_DITHER_GAP)
pIsfvec[i] = pIsfvec[i - 1] + ISF_DITHER_GAP;
else
pIsfvec[i] = temp;
}
/* Make sure that pIsfvec[LP_ORDER-2] will not get values above 16384 */
if (pIsfvec[LP_ORDER - 2] > 16384) pIsfvec[LP_ORDER - 2] = 16384;
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -