From 62f708f04b24ab681b3422c233b83caf5065acd3 Mon Sep 17 00:00:00 2001 From: kevin Date: Wed, 26 Aug 2015 19:37:52 -0400 Subject: [PATCH] cmProc5.h/c : Fixed bug in cmNlmsEcExec() where weight vector was not updated correctly. --- cmProc5.c | 47 +++++++++++++++++++++++++++++++---------------- cmProc5.h | 17 ++++++++--------- 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/cmProc5.c b/cmProc5.c index 7c115b8..eabdd35 100644 --- a/cmProc5.c +++ b/cmProc5.c @@ -959,9 +959,8 @@ cmRC_t cmNlmsEcInit( cmNlmsEc_t* p, float mu, unsigned hN, unsigned delayN 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->wV = cmMemResizeZ(double,p->wV,hN); + p->hV = cmMemResizeZ(double,p->hV,hN); p->w0i = 0; return rc; @@ -982,37 +981,53 @@ cmRC_t cmNlmsEcFinal( cmNlmsEc_t* p ) cmRC_t cmNlmsEcExec( cmNlmsEc_t* p, const cmSample_t* xV, const cmSample_t* fV, cmSample_t* yV, unsigned xyN ) { + // See: http://www.eit.lth.se/fileadmin/eit/courses/ett042/CE/CE2e.pdf + // and http://www.eit.lth.se/fileadmin/eit/courses/ett042/CE/CE3e.pdf unsigned i; for(i=0; ihV[p->w0i] = xV[i]; - + double y = 0; + unsigned k = 0; + double a = 0.001; + unsigned j; + + // insert the next sample into the filter delay line + p->hV[p->w0i] = xV[i]; + + // calculate the output of the delay w0i:hN for(j=p->w0i,k=0; jhN; ++j,++k) y += p->hV[j] * p->wV[k]; + // calcuate the output of the delay 0:w0i 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; + // calculate the error + double e = fV[i] - y; + yV[i] = e; - cmSample_t z = 0; + // + double 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; + // update weights 0 through w0i + for(j=p->w0i,k=0; jhN; ++j,++k) + p->wV[k] += (p->mu/(a + z)) * p->hV[j] * e; + + // update weights w0i through hN + for(j=0; jw0i; ++j,++k) + p->wV[k] += (p->mu/(a + z)) * p->hV[j] * e; + + // advance the delay + p->w0i = (p->w0i+1) % p->hN; + } return cmOkRC; } + cmRC_t cmNlmsEcWrite( cmNlmsEc_t* p, const cmChar_t* dirStr ) { if( p->eVa != NULL ) diff --git a/cmProc5.h b/cmProc5.h index 700f908..050a07d 100644 --- a/cmProc5.h +++ b/cmProc5.h @@ -230,16 +230,15 @@ extern "C" { // 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 + cmObj obj; + float mu; // LMS step rate + unsigned hN; // filter length + unsigned delayN; // fixed delay to apply to align xV with fV. + double* wV; // wV[hN] filter weights + double* hV; // hV[hN] filter delay line + + unsigned w0i; - unsigned w0i; - cmVectArray_t* eVa; } cmNlmsEc_t;