📄 err_conc.c
字号:
/***************************************************************************
*
* File Name: err_conc.c
*
* Purpose:
* Contains all functions for error concealment.
* Relevant specification: GSM 06.21
*
* Below is a listing of all the functions appearing in the file.
* All functions are called within speechDecoder().
*
* Error concealment on parameter level:
* para_conceal_speech_decoder()
*
* Error concealment on signal level:
* signal_conceal_sub()
*
* Additional functions to support concealment:
* level_estimator()
* level_calc()
*
**************************************************************************/
/*_________________________________________________________________________
| |
| Include Files |
|_________________________________________________________________________|
*/
#include "mathhalf.h"
#include "sp_dec.h"
#include "err_conc.h"
/*_________________________________________________________________________
| |
| Local Defines |
|_________________________________________________________________________|
*/
#define MIN_MUTE_LEVEL -45
/*_________________________________________________________________________
| |
| State variables (globals) |
|_________________________________________________________________________|
*/
Longword plSubfrEnergyMem[4];
Shortword swLevelMem[4],
lastR0,
pswLastGood[18],
swState,
swLastFlag;
/*****************************************************************************
*
* FUNCTION NAME: para_conceal_speech_decoder
*
* This subroutine performs concealment on parameter level. If the
* badframe flag (swErrorFlag[0]) has been set in the channel decoder
* parameter repetition is performed.
* If the average frame energy R0 shows an abnormal increase between two
* subsequent frames the badframe flag is also set and parameter
* repetition is performed.
* If R0 shows an important increase muting is permitted in the signal
* concealment unit. There the level of the synthesized speech signal is
* controlled and corrected if necessary.
*
* In table "psrR0RepeatThreshold[]" the maximum allowed
* increase of R0 for badframe setting is stored. The table
* is controlled by the value of R0 of the last frame.
* If e.g. the previous R0 is 10 the allowed maximum increase
* is 9 (psrR0RepeatThreshold[10]).
* The figures in psrR0RepeatThreshold[] have been determined
* by measuring the R0 statistics of an error free speech
* signal. In approximately 95 % of the frames the increase of
* R0 is less than the defined figures for error free speech.
* If the level increase is higher than the determined limit
* then the badframe flag is set.
*
* In table "psrR0MuteThreshold[]" the maximum allowed
* increase of R0 for muting is stored.
* The table is controlled by the value of R0 of the last frame
* If e.g. the previous R0 is 10 the allowed maximum increase
* is 7 (psrR0MuteThreshold[10]).
* The figures in psrR0MuteThreshold[] have been determined
* by measuring the R0 statistics of an error free speech
* signal. In approximately 85 % of the frames the increase of
* R0 is less than the defined figures for error free speech.
* If the level increase is higher than the determined limit
* then muting is allowed.
*
* Input: pswErrorFlag[0] badframe flag from channel decoder
* pswErrorFlag[1] unreliable frame flag from channel decoder
* pswSpeechPara[] unconcealed speech parameters
* Output: pswSpeechPara[] concealed speech parameters
* swMutePermit flag, indicating whether muting is
* permitted
*
* Constants: psrR0RepeatThreshold[32] maximum allowed R0 difference
* before frame is repeated
* psrR0MuteThreshold[32] maximum allowed R0 difference
* before muting is permitted
*
*
****************************************************************************/
void para_conceal_speech_decoder(Shortword pswErrorFlag[],
Shortword pswSpeechPara[], Shortword *pswMutePermit)
{
/*_________________________________________________________________________
| |
| Local Static Variables |
|_________________________________________________________________________|
*/
static const Shortword psrR0RepeatThreshold[32] =
{15, 15, 15, 12, 12, 12, 12, 11,
10, 10, 9, 9, 9, 9, 8, 8,
7, 6, 5, 5, 5, 4, 4, 3,
2, 2, 2, 2, 2, 2, 10, 10};
static const Shortword psrR0MuteThreshold[32] =
{14, 12, 11, 9, 9, 9, 9, 7,
7, 7, 7, 7, 6, 6, 6, 5,
5, 4, 3, 3, 3, 3, 3, 2,
1, 1, 1, 1, 1, 1, 10, 10};
/*_________________________________________________________________________
| |
| Automatic Variables |
|_________________________________________________________________________|
*/
Shortword swLastLag,
swR0,
swLag,
r0_diff,
i;
/*_________________________________________________________________________
| |
| Executable Code |
|_________________________________________________________________________|
*/
/* Initialise mute permission flag */
/* ------------------------------- */
*pswMutePermit = 0;
/* Determine R0-difference to last frame */
/* ------------------------------------- */
r0_diff = sub(pswSpeechPara[0], lastR0);
/* If no badframe has been declared, but the frame is unreliable then */
/* check whether there is an abnormal increase of R0 */
/* ------------------------------------------------------------------ */
if ((pswErrorFlag[0] == 0) && (pswErrorFlag[1] > 0))
{
/* Check if difference exceeds the maximum allowed threshold. */
/* If yes, set badframe flag */
/* ---------------------------------------------------------- */
if (sub(r0_diff, psrR0RepeatThreshold[lastR0]) >= 0)
{
pswErrorFlag[0] = 1;
}
else
{
/* Allow muting if R0 >= 30 */
/* ------------------------ */
if (sub(pswSpeechPara[0], 30) >= 0)
*pswMutePermit = 1;
}
}
/* If no badframe has been declared, but the frame is unreliable then */
/* check whether there is an important increase of R0 */
/* ------------------------------------------------------------------ */
if ((pswErrorFlag[1] > 0) && (pswErrorFlag[0] == 0))
{
/* Check if difference exceeds a threshold. */
/* If yes, allow muting in the signal concealment unit */
/* ---------------------------------------------------------- */
if (sub(r0_diff, psrR0MuteThreshold[lastR0]) >= 0)
{
*pswMutePermit = 1;
}
}
/* Perform parameter repetition, if necessary (badframe handling) */
/* -------------------------------------------------------------- */
if (pswErrorFlag[0] > 0)
{
swState = add(swState, 1); /* update the bad frame
* masking state */
if (sub(swState, 6) > 0)
swState = 6;
}
else
{
if (sub(swState, 6) < 0)
swState = 0;
else if (swLastFlag == 0)
swState = 0;
}
swLastFlag = pswErrorFlag[0];
/* if the decoded frame is good, save it */
/* ------------------------------------- */
if (swState == 0)
{
for (i = 0; i < 18; i++)
pswLastGood[i] = pswSpeechPara[i];
}
/* if the frame is bad, attenuate and repeat last good frame */
/* --------------------------------------------------------- */
else
{
if ((sub(swState, 3) >= 0) && (sub(swState, 5) <= 0))
{
swR0 = sub(pswLastGood[0], 2); /* attenuate by 4 dB */
if (swR0 < 0)
swR0 = 0;
pswLastGood[0] = swR0;
}
if (sub(swState, 6) >= 0) /* mute */
pswLastGood[0] = 0;
/* If the last good frame is unvoiced, use its energy, voicing mode, lpc
* coefficients, and soft interpolation. For gsp0, use only the gsp0
* value from the last good subframe. If the current bad frame is
* unvoiced, use the current codewords. If not, use the codewords from
* the last good frame. */
/* -------------------------------------------------------------- */
if (pswLastGood[5] == 0)
{ /* unvoiced good frame */
if (pswSpeechPara[5] == 0)
{ /* unvoiced bad frame */
for (i = 0; i < 5; i++)
pswSpeechPara[i] = pswLastGood[i];
for (i = 0; i < 4; i++)
pswSpeechPara[3 * i + 8] = pswLastGood[17];
}
else
{ /* voiced bad frame */
for (i = 0; i < 18; i++)
pswSpeechPara[i] = pswLastGood[i];
for (i = 0; i < 3; i++)
pswSpeechPara[3 * i + 8] = pswLastGood[17];
}
}
/* If the last good frame is voiced, the long term predictor lag at the
* last subframe is used for all subsequent subframes. Use the last good
* frame's energy, voicing mode, lpc coefficients, and soft
* interpolation. For gsp0 in all subframes, use the gsp0 value from the
* last good subframe. If the current bad frame is voiced, use the
* current codewords. If not, use the codewords from the last good
* frame. */
/* ---------------------------------------------------------------- */
else
{ /* voiced good frame */
swLastLag = pswLastGood[6]; /* frame lag */
for (i = 0; i < 3; i++)
{ /* each delta lag */
swLag = sub(pswLastGood[3 * i + 9], 0x8); /* biased around 0 */
swLag = add(swLag, swLastLag); /* reconstruct pitch */
if (sub(swLag, 0x00ff) > 0)
{ /* limit, as needed */
swLastLag = 0x00ff;
}
else if (swLag < 0)
{
swLastLag = 0;
}
else
swLastLag = swLag;
}
pswLastGood[6] = swLastLag; /* saved frame lag */
pswLastGood[9] = 0x8; /* saved delta lags */
pswLastGood[12] = 0x8;
pswLastGood[15] = 0x8;
if (pswSpeechPara[5] != 0)
{ /* voiced bad frame */
for (i = 0; i < 6; i++)
pswSpeechPara[i] = pswLastGood[i];
for (i = 0; i < 4; i++)
pswSpeechPara[3 * i + 6] = pswLastGood[3 * i + 6];
for (i = 0; i < 4; i++)
pswSpeechPara[3 * i + 8] = pswLastGood[17];
}
else
{ /* unvoiced bad frame */
for (i = 0; i < 18; i++)
pswSpeechPara[i] = pswLastGood[i];
for (i = 0; i < 3; i++)
pswSpeechPara[3 * i + 8] = pswLastGood[17];
}
}
} /* end of bad frame */
/* Update last value of R0 */
/* ----------------------- */
lastR0 = pswSpeechPara[0];
}
/****************************************************************************
*
* FUNCTION NAME: level_estimator
*
* This subroutine determines the mean level and the maximum level
* of the last four speech sub-frames. These parameters are the basis
* for the level estimation in signal_conceal_sub().
*
* Input: swUpdate = 0: the levels are determined
* = 1: the memory of the level estimator
* is updated
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -