📄 fixpoint_double_talk.c
字号:
//
// Project: Experiment 10.7.3 AEC using C55x Intrinsics - Chapter 10
// File name: fixPoint_double_talk.c
//
// Description: This AEC uses the fixed-point leaky LMS algorithm
//
// For the book "Real Time Digital Signal Processing:
// Implementation and Application, 2nd Ed"
// By Sen M. Kuo, Bob H. Lee, and Wenshun Tian
// Publisher: John Wiley and Sons, Ltd
// Tools used: CCS v.2.12.07
// TMS320VC5510 DSK Rev-C
//
#include "fixPoint_leaky_lms.h"
#include "gsm.h"
void fixPoint_double_talk(DTALK *dtObj, LMS *lmsObj)
{
long temp32a,temp32b;
DTALK *dt=(DTALK *)dtObj;
LMS *lms=(LMS *)lmsObj;
// Update far-end noise floor estimate of receiving far-end signal
// temp = |farEndIn|, Estimate far end input power
temp32a = L_deposit_h(lms->in);
// Estimate farEndIn power by short window
dt->farInPowS = aec_power_estimate(dt->farInPowS,
temp32a,ALPHA_SHIFT_SHORT);
// Estimate farEndIn power by medium window
dt->farInPowM = aec_power_estimate(dt->farInPowM,
temp32a,ALPHA_SHIFT_MEDIUM);
if (dt->nfFar < dt->farInPowS)
{ // Onset of speech, slow update using long window
dt->nfFar = aec_power_estimate(dt->nfFar,
temp32a,ALPHA_SHIFT_MEDIUM);
}
else
{ // Offset of speech, fast decay using medium window
dt->nfFar = aec_power_estimate(dt->nfFar,
temp32a,ALPHA_SHIFT_SHORT);
}
// Update near-end noise floor estimate of signal pickup by microphone
// temp = |microphoneIn|
temp32a = L_deposit_h(lms->des);
// Estimate microphone signal power by short window
dt->micInPowS = aec_power_estimate(dt->micInPowS,
temp32a,ALPHA_SHIFT_SHORT);
if (dt->nfNear < dt->micInPowS)
{ // Onset of speech, slow update using long window
dt->nfNear = aec_power_estimate(dt->nfNear,
temp32a,ALPHA_SHIFT_MEDIUM);
}
else
{ // Offset of speech, fast decay using medium window
dt->nfNear = aec_power_estimate(dt->nfNear,
temp32a,ALPHA_SHIFT_SHORT);
}
// Error power
// Estimate power of AEC error by short window
temp32a = L_deposit_h(lms->err);
dt->errorAECpowS = aec_power_estimate(dt->errorAECpowS,
temp32a,ALPHA_SHIFT_SHORT);
// Estimate power of AEC error by medium window
dt->errorAECpowM = aec_power_estimate(dt->errorAECpowM,
temp32a,ALPHA_SHIFT_MEDIUM);
// Threshold for far-end detector
temp32b = dt->nfFar;
temp32b = L_add(temp32b,(SAFE_MARGIN>>1));
// Threshold for near-end detector
temp32a = dt->nfNear<<2;
temp32a = L_add(temp32a,SAFE_MARGIN);
if(temp32b <= (200<<15))
{
temp32b = (200<<15);
}
// Detect speach activity at far end
if(dt->farInPowS > temp32b) // temp32b = thresFar
{ // Declare far-end speech
dt->farFlag = 1;
// Set hangover time counter
dt->farHangCount = HANGOVER_TIME;
}
else
{
if (dt->farHangCount-- < 0)// Decrement hangover counter
{
dt->farFlag = 0;
dt->farHangCount = 0; // Hangover counter expired
}
}
if(temp32a <= (400<<15))
{
temp32a= (400<<15);
}
if( (dt->micInPowS > temp32a) && // temp32a = thresNear
(dt->errorAECpowS > temp32a) )
{
dt->nearFlag = 1; // Declare speech
dt->nearHangCount = HANGOVER_TIME; // Set hangover counter
}
else
{
if (dt->nearHangCount-- < 0) // Decrement hangover counter
{
dt->nearFlag = 0;
dt->nearHangCount = 0; // Hangover counter expired
}
}
if(dt->trainTime-- <= 1 )
{
if(dt->nearFlag == 0 && dt->farFlag ==1)
{
lms->freez =0;
}
else
{
lms->freez =1;
}
dt->trainTime =0;
}
else
{
lms->freez =0;
}
}
/**************************************************************************
* POWER_ESTIMATE - function to estimate power using a losy accumulator *
***************************************************************************
* Algorithm:
* p(n) = p(n-1) + alpha * (abs(x(n) - p(n-1))
*
*************************************************************************/
long aec_power_estimate(long pn, long xn, short n)
{
long p;
p = L_abs(xn);
p = L_sub(p,pn);
p = L_shr_r(p,n);
pn = L_add(pn,p);
return(pn);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -