Browse Source

cmProc5.h/c : Added parameter setters to cmNlmsEc.

master
kevin 9 years ago
parent
commit
2d1f53c3d0
2 changed files with 84 additions and 31 deletions
  1. 75
    28
      cmProc5.c
  2. 9
    3
      cmProc5.h

+ 75
- 28
cmProc5.c View File

914
 //=======================================================================================================================
914
 //=======================================================================================================================
915
 // 
915
 // 
916
 //
916
 //
917
-cmNlmsEc_t* cmNlmsEcAlloc( cmCtx* ctx, cmNlmsEc_t* ap, float mu, unsigned hN, unsigned delayN )
917
+cmNlmsEc_t* cmNlmsEcAlloc( cmCtx* ctx, cmNlmsEc_t* ap, double srate, float mu, unsigned hN, unsigned delayN )
918
 {
918
 {
919
   cmNlmsEc_t* p = cmObjAlloc(cmNlmsEc_t,ctx,ap);
919
   cmNlmsEc_t* p = cmObjAlloc(cmNlmsEc_t,ctx,ap);
920
 
920
 
921
+  bool debugFl = false;
922
+  
921
   // allocate the vect array's
923
   // allocate the vect array's
922
-  p->uVa = cmVectArrayAlloc(ctx, kFloatVaFl );
923
-  p->fVa = cmVectArrayAlloc(ctx, kFloatVaFl );
924
-  p->eVa = cmVectArrayAlloc(ctx, kFloatVaFl );
924
+  p->uVa = debugFl ? cmVectArrayAlloc(ctx, kFloatVaFl ) : NULL;
925
+  p->fVa = debugFl ? cmVectArrayAlloc(ctx, kFloatVaFl ) : NULL;
926
+  p->eVa = debugFl ? cmVectArrayAlloc(ctx, kFloatVaFl ) : NULL;
925
    
927
    
926
   
928
   
927
-  if( mu != 0 )  
928
-    if( cmNlmsEcInit(p,mu,hN,delayN) != cmOkRC )
929
+  if( srate != 0 )  
930
+    if( cmNlmsEcInit(p,srate,mu,hN,delayN) != cmOkRC )
929
       cmNlmsEcFree(&p);
931
       cmNlmsEcFree(&p);
930
 
932
 
931
   return p;
933
   return p;
952
  
954
  
953
 }
955
 }
954
 
956
 
955
-cmRC_t      cmNlmsEcInit( cmNlmsEc_t* p, float mu, unsigned hN, unsigned delayN )
957
+cmRC_t      cmNlmsEcInit( cmNlmsEc_t* p, double srate, float mu, unsigned hN, unsigned delayN )
956
 {
958
 {
957
   cmRC_t rc = cmOkRC;
959
   cmRC_t rc = cmOkRC;
958
 
960
 
959
   if((rc = cmNlmsEcFinal(p)) != cmOkRC )
961
   if((rc = cmNlmsEcFinal(p)) != cmOkRC )
960
     return rc;
962
     return rc;
963
+
964
+  assert( srate >= hN );
965
+  assert( srate >= delayN );
961
   
966
   
962
   p->mu     = mu;
967
   p->mu     = mu;
963
   p->hN     = hN;
968
   p->hN     = hN;
964
-  p->delayN = delayN;
965
-  p->wV     = cmMemResizeZ(double,p->wV,hN);
966
-  p->hV     = cmMemResizeZ(double,p->hV,hN);
969
+  p->delayN = cmMax(1,delayN);
970
+  p->dN     = srate;
971
+  p->delayV = cmMemResizeZ(cmSample_t, p->delayV, srate );
972
+  p->di     = 0;
973
+  p->wV     = cmMemResizeZ(double,p->wV,srate);
974
+  p->hV     = cmMemResizeZ(double,p->hV,srate);
967
   p->w0i    = 0;
975
   p->w0i    = 0;
968
   
976
   
969
   return rc;
977
   return rc;
972
 cmRC_t      cmNlmsEcFinal( cmNlmsEc_t* p )
980
 cmRC_t      cmNlmsEcFinal( cmNlmsEc_t* p )
973
 { return cmOkRC; }
981
 { return cmOkRC; }
974
 
982
 
975
-/*
976
-  for n=M:N
977
-    uv = u(n:-1:n-M+1);
978
-    e(n) = d(n)-w'*uv;
979
-    w=w+mu/(a + uv'*uv ) * uv * conj(e(n));
980
-  endfor
981
-
982
-  e = e(:).^2;
983
-*/
984
-
985
 cmRC_t      cmNlmsEcExec( cmNlmsEc_t* p, const cmSample_t* xV, const cmSample_t* fV, cmSample_t* yV, unsigned xyN )
983
 cmRC_t      cmNlmsEcExec( cmNlmsEc_t* p, const cmSample_t* xV, const cmSample_t* fV, cmSample_t* yV, unsigned xyN )
986
 {
984
 {
987
   // See: http://www.eit.lth.se/fileadmin/eit/courses/ett042/CE/CE2e.pdf
985
   // See: http://www.eit.lth.se/fileadmin/eit/courses/ett042/CE/CE2e.pdf
994
     double     a = 0.001;
992
     double     a = 0.001;
995
     unsigned   j;
993
     unsigned   j;
996
 
994
 
997
-    // insert the next sample into the filter delay line
998
-    p->hV[p->w0i] = xV[i]; 
995
+    // Insert the next sample into the filter delay line.
996
+    // Note that rather than shifting the delay line on each iteration we
997
+    // increment the input location and then align it with the zeroth
998
+    // weight below.
999
+    p->hV[p->w0i] = p->delayV[ p->di ];
1000
+    
1001
+    p->delayV[ p->di ] = xV[i];
1002
+
1003
+    p->di = (p->di + 1) % p->delayN;
999
 
1004
 
1000
-    // calculate the output of the delay w0i:hN
1005
+    // calculate the output of the delay w0i:hN 
1001
     for(j=p->w0i,k=0; j<p->hN; ++j,++k)
1006
     for(j=p->w0i,k=0; j<p->hN; ++j,++k)
1002
       y += p->hV[j] * p->wV[k];
1007
       y += p->hV[j] * p->wV[k];
1003
 
1008
 
1005
     for(j=0; j<p->w0i; ++j,++k)
1010
     for(j=0; j<p->w0i; ++j,++k)
1006
       y += p->hV[j] * p->wV[k];
1011
       y += p->hV[j] * p->wV[k];
1007
 
1012
 
1008
-    // calculate the error
1013
+    // calculate the error which is also the filter output
1009
     double e = fV[i] - y;
1014
     double e = fV[i] - y;
1010
     yV[i] = e;
1015
     yV[i] = e;
1011
 
1016
 
1027
 
1032
 
1028
   }
1033
   }
1029
 
1034
 
1030
-  cmVectArrayAppendS(p->uVa,xV,xyN);
1031
-  cmVectArrayAppendS(p->fVa,fV,xyN);
1032
-  cmVectArrayAppendS(p->eVa,yV,xyN);
1035
+  if( p->uVa != NULL )
1036
+    cmVectArrayAppendS(p->uVa,xV,xyN);
1037
+  
1038
+  if( p->fVa != NULL )
1039
+    cmVectArrayAppendS(p->fVa,fV,xyN);
1040
+
1041
+  if( p->eVa != NULL )
1042
+    cmVectArrayAppendS(p->eVa,yV,xyN);
1033
    
1043
    
1034
 
1044
 
1035
   return cmOkRC;
1045
   return cmOkRC;
1047
 
1057
 
1048
   if( p->eVa != NULL )
1058
   if( p->eVa != NULL )
1049
     cmVectArrayWriteDirFn(p->eVa, dirStr, "nlms_out.va");
1059
     cmVectArrayWriteDirFn(p->eVa, dirStr, "nlms_out.va");
1050
-
1051
   
1060
   
1052
   return cmOkRC;
1061
   return cmOkRC;
1053
 }
1062
 }
1063
+
1064
+
1065
+void cmNlmsEcSetMu(     cmNlmsEc_t* p, float mu )
1066
+{
1067
+  if( mu < 0 )
1068
+    p->mu = 0.0001;
1069
+  else
1070
+    if( mu >= 1 )
1071
+      p->mu = 0.99;
1072
+    else
1073
+      p->mu = mu;
1074
+}
1075
+
1076
+void cmNlmsEcSetDelayN( cmNlmsEc_t* p, unsigned delayN )
1077
+{
1078
+  if( delayN > p->dN)
1079
+    delayN = p->dN;
1080
+  else
1081
+    if( delayN < 1 )
1082
+      delayN = 1;
1083
+  
1084
+  cmVOS_Zero(p->delayV,p->delayN);
1085
+  p->delayN = delayN;
1086
+}
1087
+
1088
+void cmNlmsEcSetIrN(    cmNlmsEc_t* p, unsigned hN )
1089
+{
1090
+  if( hN > p->dN )
1091
+    hN = p->dN;
1092
+  else
1093
+    if( hN < 1 )
1094
+      hN = 1;
1095
+
1096
+  cmVOD_Zero(p->wV,p->hN);
1097
+  cmVOD_Zero(p->hV,p->hN);
1098
+  p->hN = hN;
1099
+}
1100
+

+ 9
- 3
cmProc5.h View File

234
     float          mu;          // LMS step rate
234
     float          mu;          // LMS step rate
235
     unsigned       hN;          // filter length
235
     unsigned       hN;          // filter length
236
     unsigned       delayN;      // fixed delay to apply to align xV with fV.
236
     unsigned       delayN;      // fixed delay to apply to align xV with fV.
237
+    unsigned       dN;          // max length of the fixed delay
238
+    cmSample_t*    delayV;      // delayV[ dN ] fixed delay buffer[]
239
+    unsigned       di;          // delay index
237
     double*        wV;          // wV[hN] filter weights
240
     double*        wV;          // wV[hN] filter weights
238
     double*        hV;          // hV[hN] filter delay line    
241
     double*        hV;          // hV[hN] filter delay line    
239
     unsigned       w0i;         // The index into hV[] of the start of the delay line.
242
     unsigned       w0i;         // The index into hV[] of the start of the delay line.
243
     cmVectArray_t* eVa;
246
     cmVectArray_t* eVa;
244
   } cmNlmsEc_t;
247
   } cmNlmsEc_t;
245
 
248
 
246
-  cmNlmsEc_t* cmNlmsEcAlloc( cmCtx* ctx, cmNlmsEc_t* p, float mu, unsigned hN, unsigned delayN );
249
+  cmNlmsEc_t* cmNlmsEcAlloc( cmCtx* ctx, cmNlmsEc_t* p, double srate, float mu, unsigned hN, unsigned delayN );
247
   cmRC_t      cmNlmsEcFree( cmNlmsEc_t** pp );
250
   cmRC_t      cmNlmsEcFree( cmNlmsEc_t** pp );
248
-  cmRC_t      cmNlmsEcInit( cmNlmsEc_t* p, float mu, unsigned hN, unsigned delayN );
251
+  cmRC_t      cmNlmsEcInit( cmNlmsEc_t* p, double srate, float mu, unsigned hN, unsigned delayN );
249
   cmRC_t      cmNlmsEcFinal( cmNlmsEc_t* p );
252
   cmRC_t      cmNlmsEcFinal( cmNlmsEc_t* p );
250
   
253
   
251
   // xV[] unfiltered reference signal  (direct from xform output)
254
   // xV[] unfiltered reference signal  (direct from xform output)
253
   // yV[] echo-canelled signal 
256
   // yV[] echo-canelled signal 
254
   cmRC_t      cmNlmsEcExec( cmNlmsEc_t* p, const cmSample_t* xV, const cmSample_t* fV, cmSample_t* yV, unsigned xyN );
257
   cmRC_t      cmNlmsEcExec( cmNlmsEc_t* p, const cmSample_t* xV, const cmSample_t* fV, cmSample_t* yV, unsigned xyN );
255
   cmRC_t      cmNlmsEcWrite( cmNlmsEc_t* p, const cmChar_t* dir );
258
   cmRC_t      cmNlmsEcWrite( cmNlmsEc_t* p, const cmChar_t* dir );
256
-  
259
+
260
+  void        cmNlmsEcSetMu(     cmNlmsEc_t* p, float mu );
261
+  void        cmNlmsEcSetDelayN( cmNlmsEc_t* p, unsigned delayN );
262
+  void        cmNlmsEcSetIrN(    cmNlmsEc_t* p, unsigned irN );
257
   
263
   
258
   
264
   
259
 #ifdef __cplusplus
265
 #ifdef __cplusplus

Loading…
Cancel
Save