⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gaeczs.c

📁 TI公司DSP/tms320c55x/tms320c54x系列的声学回声消除代码
💻 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 <string.h>
#include "gaeci.h"

/*--------------------- local defs ----------------------------------------*/

#define _SHFT   (2)

/*--------------------- public vars ---------------------------------------*/
/*--------------------- local vars ----------------------------------------*/
/*--------------------- local functions -----------------------------------*/
/*-------------------------------------------------------------------------*/
#if defined(_dsp)
S16                        _invertC
#else
S16                        _invert
#endif
/*-------------------------------------------------------------------------*/
(
S32 *psl,
S16 sStepSz
)
{
    S16 tx;
    S32 ac0, ac1;
    
    ac0 = *psl;
    for (tx = 0; ; tx--)
    {
        if (ac0 & (1L<<30)) break;
        ac0 <<= 1;
    }
    // 1/(1-x) ~= 1+x +2x^2; for 0 < x <= 0.5: relative err = 0.037;
    // 1/(1-x) E [1_2] if x E [0.5_1], so we calculate 
    // 0.5/(1-x) = 0.5 +x/2 +x^2; and adjust down for 0.037/2 to
    // center the error around 0 (+/-0.022).
    ac0 >>= 16;
    ac1 = (1L<<15) - ac0; // (1-x) <= 0.5;
    ac0 = Q15(0.5*(1.-0.6*0.037));
    ac0 += ac1 >> 1;
    ac0 += (ac1 * ac1) >> 15;

    ac0 *= sStepSz;
    ac0 += (1<<11);
    ac0 >>= 12;

    *psl = ac0; // 16 bit mantissa

    return (30+tx);
}
/*-------------------------------------------------------------------------*/
void                        gaec_add_energy
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb,
S16 band,
S32 *pslEnergy
)
{
    pDb->aslAdEn[band] += *pslEnergy >> 4;
    if (pDb->aslAdEn[band] > GAEC_ADEN)
    {
        pDb->aslAdEn[band] = GAEC_ADEN;
    }
    *pslEnergy += pDb->aslAdEn[band];
}
/*-------------------------------------------------------------------------*/
#if defined(_dsp)
void                        gaec_loopbackC
#else
void                        gaec_loopback
#endif
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb,
S16 *psSnd
)
{
	S16 k;
    S32 ac0;

	for (k = 0; k < GAEC_FR_SZ; k++)
	{
        ac0 = pDb->asRbuf[k+5] * (S32) Q15(0.5623); // 5 dB of attenuation
		psSnd[k] =  _Srnd(ac0,0);
	}
}
/*-------------------------------------------------------------------------*/
#if defined(_dsp)
void                        gaec_max_coefC
#else
void                        gaec_max_coef
#endif
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb,
GAEC_tSc *pSc
)
{
	S16 k;
	S16 sMax = 0;
	S16 *psAdf = pDb->psAdf;

	pDb->sMaxCoefBand ++;
	if (pDb->sMaxCoefBand >= (GAEC_BANDS+1))
	{
		pDb->sMaxCoefBand = 0;
		pDb->sMaxCoefAv += (pDb->sMaxCoef - pDb->sMaxCoefAv) >> 2;
		pDb->sMaxCoef = 0;
	}

	switch (pDb->sMaxCoefBand) {
	case GAEC_BANDS:
		psAdf++;
	case 0:
		for (k = 0; k < GAEC_ADF_SZ; k++)
		{
			S16 t = *psAdf;
			if (t < 0) 
				t = -t;
			if (sMax < t)
				sMax = t;
			psAdf += 2;
		}
		break;
	default:
		psAdf += GAEC_ADF_SZ*2*pDb->sMaxCoefBand;
		for (k = 0; k < GAEC_ADF_SZ*2; k++)
		{
			S16 t = *psAdf++;
			if (t < 0) 
				t = -t;
			if (sMax < t)
				sMax = t;
		}
		break;
	}

	if (pDb->sMaxCoef < sMax)
		pDb->sMaxCoef = sMax;
	pSc->sMaxCoef = sMax;
}


/*-------------------------------------------------------------------------*/
#if defined(_dsp)
void                        gaec_scale_bandC
#else
void                        gaec_scale_band
#endif
/*-------------------------------------------------------------------------*/
(
S16 *psAdf,
S16 *psAdfM,
S16  sBand,
S16  sShft
)
{
	S16 k;

	switch (sBand) {
	case GAEC_BANDS:
		psAdf++;
		psAdfM++;
	case 0:
		for (k = 0; k < GAEC_ADF_SZ; k++)
		{
			if (sShft > 0)
			{
				*psAdf  = *psAdf  << sShft;
				*psAdfM = *psAdfM << sShft;
			}
			else
			{
				*psAdf  = *psAdf  >> (-sShft);
				*psAdfM = *psAdfM >> (-sShft);
			}
			psAdf += 2;
			psAdfM += 2;
		}
		break;
	default:
		psAdf  += GAEC_ADF_SZ*2*sBand;
		psAdfM += GAEC_ADF_SZ*2*sBand;
		for (k = 0; k < GAEC_ADF_SZ*2; k++)
		{
			if (sShft > 0)
			{
				*psAdf  = *psAdf  << sShft;
				*psAdfM = *psAdfM << sShft;
			}
			else
			{
				*psAdf  = *psAdf  >> (-sShft);
				*psAdfM = *psAdfM >> (-sShft);
			}
			psAdf ++;
			psAdfM ++;
		}
		break;
	}
}
/*-------------------------------------------------------------------------*/
#if 0
/*-------------------------------------------------------------------------*/
#if !defined (_dsp)
void                        gaec_shift_err
#else
void                        gaec_shift_errC
#endif
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb
)
{
	int  band;

	for (band = 0; band < 2*GAEC_BANDS; band++)
	{
    	int  k;
		for (k = 0; k < GAEC_ERR_SZ-GAEC_BLKS; k++)
		{
			pDb->aasErrSav[band][k] = pDb->aasErrSav[band][k + GAEC_BLKS];
		}
	}
}
#endif
/*-------------------------------------------------------------------------*/
#if !defined(_dsp)
void                        gaec_update_rbuf
#else
void                        gaec_update_rbufC
#endif
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb,
S16 *psRcv
)
{
	int  k;

	for (k = 0; k < GAEC_RBUF_SZ-GAEC_FR_SZ; k++) 
    {
        pDb->asRbuf[k] = pDb->asRbuf[k + GAEC_FR_SZ];
    }
	for (k = 0; k < GAEC_FR_SZ; k++) 
    {
        pDb->asRbuf[k + GAEC_RBUF_SZ-GAEC_FR_SZ] = psRcv[k];
    }
}
/*-------------------------------------------------------------------------*/
#if !defined(_dsp)
void                        gaec_shift_rcv
#else
void                        gaec_shift_rcvC
#endif
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb
)
{
    int band;
	for (band = 0; band < 2*GAEC_BANDS; band++)
	{
        S16 sIdx = band * GAEC_RCV_SZ;
        int k;
		for (k = 0; k < GAEC_RCV_SZ-GAEC_BLKS; k++)
		{
			pDb->psRcv[sIdx + k] = pDb->psRcv[sIdx + k + GAEC_BLKS];
		}
	}
}


/*-------------------------------------------------------------------------*/
#if !defined(_dsp)
void                        gaec_update_err_sav
#else
void                        gaec_update_err_savC
#endif
/*-------------------------------------------------------------------------*/
(
GAEC_tDb *pDb,
GAEC_tSc *pSc
)
{
    int k;
    int band;

    for (band = 0; band < GAEC_BANDS*2; band++)
    {
		for (k = 0; k < GAEC_ERR_SZ-GAEC_BLKS; k++)
		{
			pDb->aasErrSav[band][k] = pDb->aasErrSav[band][k + GAEC_BLKS];
		}
        for (k = 0; k < GAEC_BLKS; k++)
        {
            int idx = GAEC_ERR_SZ-GAEC_BLKS+k;
            pDb->aasErrSav[band][idx] = pSc->aasErr[band][k];
        }
    }
}

/*-------------------------------------------------------------------------*/
#if !defined(_dsp)
void                        gaec_copy_adf
#else
void                        gaec_copy_adfC
#endif
/*-------------------------------------------------------------------------*/
(
S16 *psTo,
S16 *psFrom,
S16 band
)
{
    int k;

    if (band == 0)
    {
        for (k = 0; k < GAEC_ADF_SZ; k++)
        {
            *psTo = *psFrom;
            psFrom += 2;
            psTo += 2;
        }
    } 
    else if (band == GAEC_BANDS)
    {
        psFrom++;
        psTo++;
        for (k = 0; k < GAEC_ADF_SZ; k++)
        {
            *psTo = *psFrom;
            psFrom += 2;
            psTo += 2;
        }
    }
    else
    {
        psTo += GAEC_ADF_SZ*2*band;
        psFrom += GAEC_ADF_SZ*2*band;
        for (k = 0; k < GAEC_ADF_SZ*2; k++)
        {
            *psTo++ = *psFrom++;
        }
    }
}
/*-------------------------------------------------------------------------*/
#if !defined(_dsp)
void                        gaec_copy_err
#else
void                        gaec_copy_errC
#endif
/*-------------------------------------------------------------------------*/
(
GAEC_tSc *pSc,
S16 band
)
{
    int k;

    if ((band == 0) || (band == GAEC_BANDS))
    {
        for (k = 0; k < GAEC_BLKS; k++)
        {
            pSc->aasErr[band][k] = pSc->aasErrM[band][k];
        }
    } 
    else
    {
        for (k = 0; k < GAEC_BLKS; k++)
        {
            pSc->aasErr[band][k] = pSc->aasErrM[band][k];
        }
        for (k = 0; k < GAEC_BLKS; k++)
        {
            pSc->aasErr[band+GAEC_BANDS][k] = 
                pSc->aasErrM[band+GAEC_BANDS][k];
        }
    }
}
/*-------------------------------------------------------------------------*/
#if !defined(_dsp)
void                        gaec_in_corr
#else
void                        gaec_in_corrC
#endif
/*-------------------------------------------------------------------------*/
(
S16 *psSav,
S16 *psIO
)
{
    int k;
    for (k = 0; k < GAEC_FR_SZ; k++)
    {
        S32 ac0 = *psIO - *psSav;
        ac0 <<= _SHFT;
        ac0 += *psSav;
        ac0 += (1<<(_SHFT-1));
        *psSav = *psIO;
        *psIO++ = (S16)(ac0 >> _SHFT);
    }
}
/*-------------------------------------------------------------------------*/
#if !defined(_dsp)
void                        gaec_out_corr
#else
void                        gaec_out_corrC
#endif
/*-------------------------------------------------------------------------*/
(
S32 *pslSav,
S16 *psIO
)
{
    int k;
    for (k = 0; k < GAEC_FR_SZ; k++)
    {
        S32 ac0 = *psIO;
        ac0 <<= 15;
        ac0 += *pslSav;
        ac0 -= (*pslSav >> _SHFT);
        *pslSav = ac0;

        ac0 += (1<<14);
        ac0 >>= 15;
        *psIO++ = (S16)ac0;
    }
}

#if !defined(_dsp)
S16 _asNr[GAEC_FR_SZ];
/*-------------------------------------------------------------------------*/
void                        gaec_nr_corr
/*-------------------------------------------------------------------------*/
(
)
{
    static S32 slSav;
    int k;

    for (k = 0; k < GAEC_FR_SZ; k++)
    {
        S32 ac0 = _asNr[k];
        ac0 <<= 15;
        ac0 += slSav;
        ac0 -= (slSav >> _SHFT);
        slSav = ac0;

        ac0 += (1<<14);
        ac0 >>= 15;
        _asNr[k] = (S16)ac0;
    }
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -