📄 gaecrcv.c
字号:
/*-------------------------------------------------------------------------*
* *
* THIS IS AN UNPUBLISHED WORK CONTAINING CONFIDENTIAL AND PROPRIETARY *
* INFORMATION. IF PUBLICATION OCCURS, THE FOLLOWING NOTICE APPLIES: *
* "COPYRIGHT 2002 MIKET DSP SOLUTIONS, ALL RIGHTS RESERVED" *
* *
*-------------------------------------------------------------------------*/
#include "gaeci.h"
/*--------------------- local defs ----------------------------------------*/
#define _EN_LOW GAEC_DB(-40.0)
#define _EN_HIGH GAEC_DB(-17.0)
#define _EN_THR GAEC_DB(25.0)
/* tone state machine defs */
#define _TONE_OFF (0)
#define _TONE_ON (1)
#define _TONE_HANGOVER (2)
#define _TONE_ON_EXT (3)
#define _TONE_HANGOVER_EXT (4)
#define _TONE_CNT (6) /* 30 ms tone echo */
#define _TONE_DETECT_THR (Q15(0.05))
#define _TONE_RELEASE_THR (Q15(0.12))
#if ! defined(_dsp)
static S16 _abs16(int x)
{
if (x > 0) return (S16)(x); else return (S16)(-x);
}
#else
#define _abs16 abs
#endif
/*--------------------- public vars ---------------------------------------*/
/*--------------------- local vars ----------------------------------------*/
/*--------------------- local functions -----------------------------------*/
/*-------------------------------------------------------------------------*/
static void _detect_tone
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb,
GAEC_tScRcv *pScr
)
{
S16 sRcvEn;
S16 sMean;
// the signal in tD buffer was shifted 2 bits down...
sRcvEn = gaec_utl_pkt_energy(pScr->asTdBuf + 5) + GAEC_DB(12);
/* silence was preceeding */
pScr->uLow = ((sRcvEn - pDb->asRinEnHst[6]) > _EN_THR) &&
((sRcvEn - pDb->asRinEnHst[5]) > _EN_THR) &&
((sRcvEn - pDb->asRinEnHst[4]) > _EN_THR);
/* 3 frames with high energy */
pScr->uHigh = (pDb->asRinEnHst[1] > _EN_HIGH-GAEC_DB(6.0)) &&
(pDb->asRinEnHst[0] > _EN_HIGH) &&
(sRcvEn > _EN_HIGH);
/* these 3 frames have similar energy */
#if !defined(_dsp)
sMean = (sRcvEn + pDb->asRinEnHst[0] + pDb->asRinEnHst[1])/3;
#else
sMean = sRcvEn + pDb->asRinEnHst[0] + pDb->asRinEnHst[1];
sMean = _smpy(sMean, 10923); // 10923 = 2^15/3
#endif
pScr->uEven = (_abs16(sMean - sRcvEn) < GAEC_DB(3.0)) &&
(_abs16(sMean - pDb->asRinEnHst[0]) < GAEC_DB(3.0)) &&
(_abs16(sMean - pDb->asRinEnHst[1]) < GAEC_DB(3.0));
pScr->uEdge = (pScr->uLow && pScr->uHigh && pScr->uEven);
/* if a sharp edge & singularity */
if (pScr->sJ0 < _TONE_DETECT_THR)
{
if (pScr->asK[2] < Q15(-0.65))
{
pScr->uIsSingular = TRUE;
}
else
{
if ((pScr->asK[4] < Q15(-0.65)) &&
(pScr->asK[1] < Q15(0.5)))
{
pScr->uIsSingular = TRUE;
}
}
}
switch (pDb->uIsTone)
{
case _TONE_OFF:
{
if (pScr->uEdge && pScr->uIsSingular)
{
pDb->uIsTone = _TONE_ON;
}
if (pDb->uControl & IGAEC_CMD_TONE)
{
pDb->uIsTone = _TONE_ON_EXT;
}
break;
}
case _TONE_ON:
{
// if tone ended...
// if there are phase reversals ??? TBD
if ((pScr->sJ0 > _TONE_RELEASE_THR) ||
(sRcvEn < _EN_LOW))
{
pDb->uIsTone = _TONE_HANGOVER;
pDb->sToneCnt = _TONE_CNT;
}
break;
}
case _TONE_HANGOVER:
{
if ((pScr->sJ0 > _TONE_RELEASE_THR) ||
(sRcvEn < _EN_LOW) ||
(!(pDb->uControl & IGAEC_CMD_TONE)))
{
pDb->sToneCnt--;
}
else
{
pDb->sToneCnt++;
}
if (pDb->sToneCnt >= _TONE_CNT)
{
pDb->uIsTone = _TONE_ON;
}
else if (pDb->sToneCnt <= 0)
{
pDb->uIsTone = _TONE_OFF;
pDb->sToneCnt = 0;
}
else; // intermediate values
}
case _TONE_ON_EXT:
{
if (!(pDb->uControl & IGAEC_CMD_TONE))
{
pDb->uIsTone = _TONE_HANGOVER_EXT;
pDb->sToneCnt = _TONE_CNT;
}
break;
}
case _TONE_HANGOVER_EXT:
{
if (!(pDb->uControl & IGAEC_CMD_TONE))
{
pDb->sToneCnt--;
}
else
{
pDb->sToneCnt++;
}
if (pDb->sToneCnt >= _TONE_CNT)
{
pDb->uIsTone = _TONE_ON_EXT;
}
else if (pDb->sToneCnt <= 0)
{
pDb->uIsTone = _TONE_OFF;
pDb->sToneCnt = 0;
}
else; // intermediate values
}
}
/* delay energy array */
{
S16 i;
S16 *p1 = &(pDb->asRinEnHst[6]);
S16 *p2 = p1 - 1;
for (i = 6; i > 0; i--)
{
*p1-- = *p2--;
}
*p1 = sRcvEn;
}
}
/*-------------------------------------------------------------------------*/
void _avrg_moments
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb,
GAEC_tScRcv *pScr
)
{
S16 k;
S32 ac0;
S32 ac1;
S32 ac2;
for (k = 0; k < 6; k++)
{
ac0 = pScr->aslRkTx[k];
ac1 = pDb->aslRkSav1[k];
ac2 = pDb->aslRkSav2[k];
pDb->aslRkSav1[k] = ac0;
pDb->aslRkSav2[k] = ac1;
pScr->aslRk[k] = ac0 + ac1 + ac2;
}
}
/*--------------------- public functions ---------------------------------*/
#if !defined(_dsp)
GAEC_tScRcv _GaecScRcv;
#endif
/*-------------------------------------------------------------------------*/
void gaec_rcv_detect_tone
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb,
GAEC_tSc *pSc,
S16 *psRcv
)
{
GAEC_tScRcv *pScr = &pSc->u.Rcv;
gaec_rcv_moments(pDb, pScr, psRcv);
_avrg_moments(pDb, pScr);
gaec_rcv_normalise_rk(pDb, pScr, -7, (1<<2));
pScr->sJ0 = gaec_rcv_durbin(pDb, pScr);
_detect_tone(pDb, pScr);
#if !defined(_dsp)
_GaecScRcv = *pScr;
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -