📄 lectx.c
字号:
/*-------------------------------------------------------------------------*
* *
* THIS IS AN UNPUBLISHED WORK CONTAINING CONFIDENTIAL AND PROPRIETARY *
* INFORMATION. IF PUBLICATION OCCURS, THE FOLLOWING NOTICE APPLIES: *
* "COPYRIGHT 2001 MICHAEL TSIROULNIKOV, ALL RIGHTS RESERVED" *
* *
*-------------------------------------------------------------------------*/
#if !defined _dsp
#include <memory.h>
#include <math.h>
#include <stdlib.h>
#else
#include <string.h> /* memcpy() */
#endif
#include "stddefs.h"
#include "leci.h"
/*--------------------- local defs ----------------------------------------*/
#define _EN_VLOW LEC_DB(-40)
#define _EN_VHIGH LEC_DB(-17)
#define _EN_THR LEC_DB(25)
/* tone state machine defs */
#define _TONE_OFF (0)
#define _TONE_ON (1)
#define _TONE_HANGOVER (2)
#define _TONE_CNT (6) /* 30 ms tone echo */
#define abs(x) (((x)>0)? (x):(-x))
/*--------------------- public vars ---------------------------------------*/
/*--------------------- local vars ----------------------------------------*/
#if defined (_dsp)
#endif
/*--------------------- local functions -----------------------------------*/
/*-------------------------------------------------------------------------*/
static void _detect_high_tx
/*-------------------------------------------------------------------------*/
(
LEC_tDb *pDb,
LEC_tSc *pSc
)
{
if (pDb->Cfg.uControl & ILEC_CMD_DETECT_HIRCV)
{
// S16 sTxMax = lec_pkt_peak(pDb->psHst + (LEC_HST_SZ - ILEC_FR_SZ));
S16 sTxMax = lec_pkt_peak(pSc->psTx);
if (sTxMax > pDb->Cfg.sRcvMax)
{
pDb->sTxMaxCnt = 6;
}
else
{
pDb->sTxMaxCnt--;
if (pDb->sTxMaxCnt < 0)
{
pDb->sTxMaxCnt = 0;
}
}
if (pDb->sTxMaxCnt > 0)
pSc->uFlags |= LEC_FLAG_HIRCV;
}
else
{
pDb->sTxMaxCnt = 0;
}
}
/*-------------------------------------------------------------------------*/
static void _detect_tone
/*-------------------------------------------------------------------------*/
(
LEC_tDb *pDb,
LEC_tSc *pSc
)
{
S32 slEn = lec_pkt_energy(pSc->psTx);
S16 sLastTxEn = lec_en2log(slEn);
U16 uLow = ((sLastTxEn - pDb->asTxEn[6]) > _EN_THR) &&
((sLastTxEn - pDb->asTxEn[5]) > _EN_THR) &&
((sLastTxEn - pDb->asTxEn[4]) > _EN_THR);
U16 uHigh = (pDb->asTxEn[1] > _EN_VHIGH-LEC_DB(6)) &&
(pDb->asTxEn[0] > _EN_VHIGH) &&
(sLastTxEn > _EN_VHIGH);
U16 uEven = (abs(sLastTxEn - pDb->asTxEn[0]) < LEC_DB(6)) &&
(abs(sLastTxEn - pDb->asTxEn[1]) < LEC_DB(12));
U16 uEdge = (uLow && uHigh && uEven);
/* singularity test */
if (pSc->sJ0Tx < pDb->Cfg.sToneDetectThr)
{
if (pSc->asK[2] < Q15(-0.65))
{
pSc->uFlags |= LEC_FLAG_SINGULAR;
}
else
{
if ((pSc->asK[4] < Q15(-0.65)) &&
(pSc->asK[1] < Q15(0.5)))
{
pSc->uFlags |= LEC_FLAG_SINGULAR;
}
}
}
switch (pDb->uTone)
{
case _TONE_OFF:
{
if (uEdge && (pSc->uFlags & LEC_FLAG_SINGULAR))
{
pDb->uTone = _TONE_ON;
}
break;
}
case _TONE_ON:
{
// if tone ended...
// if there are phase reversals ??? TBD
if ((pSc->sJ0Tx > pDb->Cfg.sToneReleaseThr) ||
(sLastTxEn < _EN_VLOW))
{
pDb->uTone = _TONE_HANGOVER;
pDb->sToneCnt = _TONE_CNT;
}
break;
}
case _TONE_HANGOVER:
{
if ((pSc->sJ0Tx > pDb->Cfg.sToneReleaseThr) ||
(sLastTxEn < _EN_VLOW))
{
pDb->sToneCnt--;
}
else
{
pDb->sToneCnt++;
}
if (pDb->sToneCnt >= _TONE_CNT)
{
pDb->uTone = _TONE_ON;
}
else if (pDb->sToneCnt <= 0)
{
pDb->uTone = _TONE_OFF;
pDb->sToneCnt = 0;
}
else; // intermediate values
}
}
/* if state change or a sharp edge */
/* delay energy array */
{
S16 i;
S16 *p1 = &(pDb->asTxEn[6]);
S16 *p2 = p1 - 1;
for (i = 0; i < 6; i++)
{
*p1-- = *p2--;
}
*p1 = sLastTxEn;
}
pSc->sTxEn = sLastTxEn;
}
/*-------------------------------------------------------------------------*/
void lec_analyse_tx
/*-------------------------------------------------------------------------*/
(
LEC_tDb *pDb,
LEC_tSc *pSc
)
{
lec_tx_moments(pDb, pSc);
lec_ts_moments(pDb, pSc);
lec_normalise_rk(pDb, pSc, -7, (1<<2));
pSc->sJ0Tx = lec_durbin(pDb, pSc);
#if !defined(_dsp)
{
extern void lec_JKS(void);
lec_JKS();
}
#endif
_detect_tone(pDb, pSc);
_detect_high_tx(pDb, pSc);
lec_gs_moments(pDb, pSc);
lec_normalise_rk(pDb, pSc, -4, (1<<4));
pSc->sJ0 = lec_durbin(pDb, pSc);
#if !defined(_dsp)
{
extern void lec_JKW(void);
lec_JKW();
}
#endif
lec_gs_filter(pDb, pSc);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -