From dff56d7e7f22dc603e938302df29db4aa047c427 Mon Sep 17 00:00:00 2001 From: kevin Date: Thu, 20 Aug 2015 19:38:23 -0400 Subject: [PATCH] cmProc5.h/c Added cmNlmsEc. --- cmProc5.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++---- cmProc5.h | 30 +++++++++++++ 2 files changed, 144 insertions(+), 9 deletions(-) diff --git a/cmProc5.c b/cmProc5.c index 0324e31..b4d4243 100644 --- a/cmProc5.c +++ b/cmProc5.c @@ -827,18 +827,123 @@ cmRC_t cmReflectCalcWrite( cmReflectCalc_t* p, const char* dirStr ) { cmRC_t rc = cmOkRC; - if( p->phVa != NULL) - { - //const char* path = NULL; - + if( p->xVa != NULL) cmVectArrayWriteDirFn(p->xVa, dirStr, "reflect_calc_x.va" ); + + if( p->yVa != NULL ) cmVectArrayWriteDirFn(p->yVa, dirStr, "reflect_calc_y.va" ); + + if( p->phVa != NULL ) cmVectArrayWriteDirFn(p->phVa,dirStr, "reflect_calc_ph.va"); - - //if((rc = cmVectArrayWrite(p->phVa, path = cmFsMakeFn(path,"reflect_calc","va",dirStr,NULL) )) != cmOkRC ) - // rc = cmCtxRtCondition(&p->obj,cmSubSysFailRC,"Reflect calc file write failed."); - //cmFsFreeFn(path); - } return rc; } + +//======================================================================================================================= +// +// +cmNlmsEc_t* cmNlmsEcAlloc( cmCtx* ctx, cmNlmsEc_t* ap, float mu, unsigned hN, unsigned delayN ) +{ + cmNlmsEc_t* p = cmObjAlloc(cmNlmsEc_t,ctx,ap); + + // allocate the vect array + p->eVa = cmVectArrayAlloc(ctx, kFloatVaFl ); + + if( mu != 0 ) + if( cmNlmsEcInit(p,mu,hN,delayN) != cmOkRC ) + cmNlmsEcFree(&p); + + return p; + +} + +cmRC_t cmNlmsEcFree( cmNlmsEc_t** pp ) +{ + cmRC_t rc = cmOkRC; + + if( pp == NULL || *pp == NULL ) + return rc; + + cmNlmsEc_t* p = *pp; + if((rc = cmNlmsEcFinal(p)) != cmOkRC ) + return rc; + + cmMemFree(p->wV); + cmMemFree(p->hV); + cmVectArrayFree(&p->eVa); + cmObjFree(pp); + + return rc; + +} + +cmRC_t cmNlmsEcInit( cmNlmsEc_t* p, float mu, unsigned hN, unsigned delayN ) +{ + cmRC_t rc = cmOkRC; + + if((rc = cmNlmsEcFinal(p)) != cmOkRC ) + return rc; + + p->mu = mu; + p->hN = hN; + p->delayN = delayN; + p->wV = cmMemResizeZ(cmSample_t,p->wV,hN); + p->hV = cmMemResizeZ(cmSample_t,p->hV,hN); + p->dV = cmMemResizeZ(cmSample_t,p->dV,delayN); + p->w0i = 0; + + return rc; +} + +cmRC_t cmNlmsEcFinal( cmNlmsEc_t* p ) +{ return cmOkRC; } + +/* + for n=M:N + uv = u(n:-1:n-M+1); + e(n) = d(n)-w'*uv; + w=w+mu/(a + uv'*uv ) * uv * conj(e(n)); + endfor + + e = e(:).^2; +*/ + +cmRC_t cmNlmsEcExec( cmNlmsEc_t* p, const cmSample_t* xV, const cmSample_t* fV, cmSample_t* yV, unsigned xyN ) +{ + unsigned i; + for(i=0; ihV[p->w0i] = xV[i]; + + for(j=p->w0i,k=0; jhN; ++j,++k) + y += p->hV[j] * p->wV[k]; + + for(j=0; jw0i; ++j,++k) + y += p->hV[j] * p->wV[k]; + + p->w0i = (p->w0i+1) % p->hN; + + float e = fV[i] - y; + + cmSample_t z = 0; + for(j=0; jhN; ++j) + z += p->hV[j] * p->hV[j]; + + for(j=0; jhN; ++j) + p->wV[j] += p->mu/(a + z) * p->hV[j] * e; + } + + return cmOkRC; +} + +cmRC_t cmNlmsEcWrite( cmNlmsEc_t* p, const cmChar_t* dirStr ) +{ + if( p->eVa != NULL ) + cmVectArrayWriteDirFn(p->eVa,dirStr, "nlms_err.va"); + return cmOkRC; +} diff --git a/cmProc5.h b/cmProc5.h index 4a35455..eb4134e 100644 --- a/cmProc5.h +++ b/cmProc5.h @@ -217,6 +217,36 @@ extern "C" { cmRC_t cmReflectCalcFinal( cmReflectCalc_t* p ); cmRC_t cmReflectCalcExec( cmReflectCalc_t* p, const cmSample_t* xV, cmSample_t* yV, unsigned xyN ); cmRC_t cmReflectCalcWrite( cmReflectCalc_t* p, const char* dirStr ); + + //======================================================================================================================= + // + // + typedef struct + { + cmObj obj; + float mu; // LMS step rate + unsigned hN; // filter length + unsigned delayN; // fixed delay to apply to align xV with fV. + cmSample_t* dV; // delay line + cmSample_t* wV; // wV[hN] filter weights + cmSample_t* hV; // hV[hN] filter delay line + + unsigned w0i; + + cmVectArray_t* eVa; + } cmNlmsEc_t; + + cmNlmsEc_t* cmNlmsEcAlloc( cmCtx* ctx, cmNlmsEc_t* p, float mu, unsigned hN, unsigned delayN ); + cmRC_t cmNlmsEcFree( cmNlmsEc_t** pp ); + cmRC_t cmNlmsEcInit( cmNlmsEc_t* p, float mu, unsigned hN, unsigned delayN ); + cmRC_t cmNlmsEcFinal( cmNlmsEc_t* p ); + + // xV[] unfiltered reference signal (direct from xform output) + // fV[] filtered reference signal (from mic) + // yV[] echo-canelled signal + cmRC_t cmNlmsEcExec( cmNlmsEc_t* p, const cmSample_t* xV, const cmSample_t* fV, cmSample_t* yV, unsigned xyN ); + cmRC_t cmNlmsEcWrite( cmNlmsEc_t* p, const cmChar_t* dir ); + #ifdef __cplusplus