Parcourir la source

cmProc5.h/c Added cmNlmsEc.

master
kevin il y a 8 ans
Parent
révision
dff56d7e7f
2 fichiers modifiés avec 144 ajouts et 9 suppressions
  1. 114
    9
      cmProc5.c
  2. 30
    0
      cmProc5.h

+ 114
- 9
cmProc5.c Voir le fichier

@@ -827,18 +827,123 @@ cmRC_t cmReflectCalcWrite( cmReflectCalc_t* p, const char* dirStr )
827 827
 {
828 828
   cmRC_t rc = cmOkRC;
829 829
   
830
-  if( p->phVa != NULL) 
831
-  {
832
-    //const char* path = NULL;
833
-
830
+  if( p->xVa != NULL) 
834 831
     cmVectArrayWriteDirFn(p->xVa, dirStr, "reflect_calc_x.va" );
832
+
833
+  if( p->yVa != NULL )
835 834
     cmVectArrayWriteDirFn(p->yVa, dirStr, "reflect_calc_y.va" );
835
+
836
+  if( p->phVa != NULL )
836 837
     cmVectArrayWriteDirFn(p->phVa,dirStr, "reflect_calc_ph.va");
837
-    
838
-    //if((rc = cmVectArrayWrite(p->phVa, path = cmFsMakeFn(path,"reflect_calc","va",dirStr,NULL) )) != cmOkRC )
839
-    //    rc = cmCtxRtCondition(&p->obj,cmSubSysFailRC,"Reflect calc file write failed.");    
840
-    //cmFsFreeFn(path);
841
-  }
842 838
   
843 839
   return rc;
844 840
 }
841
+
842
+//=======================================================================================================================
843
+// 
844
+//
845
+cmNlmsEc_t* cmNlmsEcAlloc( cmCtx* ctx, cmNlmsEc_t* ap, float mu, unsigned hN, unsigned delayN )
846
+{
847
+  cmNlmsEc_t* p = cmObjAlloc(cmNlmsEc_t,ctx,ap);
848
+
849
+  // allocate the vect array
850
+  p->eVa = cmVectArrayAlloc(ctx, kFloatVaFl );
851
+  
852
+  if( mu != 0 )  
853
+    if( cmNlmsEcInit(p,mu,hN,delayN) != cmOkRC )
854
+      cmNlmsEcFree(&p);
855
+
856
+  return p;
857
+
858
+}
859
+
860
+cmRC_t      cmNlmsEcFree( cmNlmsEc_t** pp )
861
+{
862
+   cmRC_t rc = cmOkRC;
863
+
864
+  if( pp == NULL || *pp == NULL )
865
+    return rc;
866
+
867
+  cmNlmsEc_t* p = *pp;
868
+  if((rc = cmNlmsEcFinal(p)) != cmOkRC )
869
+    return rc;
870
+
871
+  cmMemFree(p->wV);
872
+  cmMemFree(p->hV);
873
+  cmVectArrayFree(&p->eVa);
874
+  cmObjFree(pp);
875
+
876
+  return rc;
877
+ 
878
+}
879
+
880
+cmRC_t      cmNlmsEcInit( cmNlmsEc_t* p, float mu, unsigned hN, unsigned delayN )
881
+{
882
+  cmRC_t rc = cmOkRC;
883
+
884
+  if((rc = cmNlmsEcFinal(p)) != cmOkRC )
885
+    return rc;
886
+  
887
+  p->mu     = mu;
888
+  p->hN     = hN;
889
+  p->delayN = delayN;
890
+  p->wV     = cmMemResizeZ(cmSample_t,p->wV,hN);
891
+  p->hV     = cmMemResizeZ(cmSample_t,p->hV,hN);
892
+  p->dV     = cmMemResizeZ(cmSample_t,p->dV,delayN);
893
+  p->w0i    = 0;
894
+  
895
+  return rc;
896
+}
897
+    
898
+cmRC_t      cmNlmsEcFinal( cmNlmsEc_t* p )
899
+{ return cmOkRC; }
900
+
901
+/*
902
+  for n=M:N
903
+    uv = u(n:-1:n-M+1);
904
+    e(n) = d(n)-w'*uv;
905
+    w=w+mu/(a + uv'*uv ) * uv * conj(e(n));
906
+  endfor
907
+
908
+  e = e(:).^2;
909
+*/
910
+
911
+cmRC_t      cmNlmsEcExec( cmNlmsEc_t* p, const cmSample_t* xV, const cmSample_t* fV, cmSample_t* yV, unsigned xyN )
912
+{
913
+  unsigned i;
914
+  for(i=0; i<xyN; ++i)
915
+  {
916
+    cmSample_t y = 0;
917
+    unsigned j;
918
+    unsigned k = 0;
919
+    float a = 0.00001;
920
+    
921
+    p->hV[p->w0i] = xV[i];
922
+    
923
+    for(j=p->w0i,k=0; j<p->hN; ++j,++k)
924
+      y += p->hV[j] * p->wV[k];
925
+
926
+    for(j=0; j<p->w0i; ++j,++k)
927
+      y += p->hV[j] * p->wV[k];
928
+
929
+    p->w0i = (p->w0i+1) % p->hN;
930
+    
931
+    float e = fV[i] - y;
932
+
933
+    cmSample_t z = 0;
934
+    for(j=0; j<p->hN; ++j)
935
+      z += p->hV[j] * p->hV[j];
936
+
937
+    for(j=0; j<p->hN; ++j)
938
+      p->wV[j] += p->mu/(a + z) * p->hV[j] * e;
939
+  }
940
+
941
+  return cmOkRC;
942
+}
943
+
944
+cmRC_t      cmNlmsEcWrite( cmNlmsEc_t* p, const cmChar_t* dirStr )
945
+{
946
+  if( p->eVa != NULL )
947
+    cmVectArrayWriteDirFn(p->eVa,dirStr, "nlms_err.va");
948
+  return cmOkRC;
949
+}

+ 30
- 0
cmProc5.h Voir le fichier

@@ -217,6 +217,36 @@ extern "C" {
217 217
   cmRC_t cmReflectCalcFinal( cmReflectCalc_t* p );
218 218
   cmRC_t cmReflectCalcExec(  cmReflectCalc_t* p, const cmSample_t* xV, cmSample_t* yV, unsigned xyN );
219 219
   cmRC_t cmReflectCalcWrite( cmReflectCalc_t* p, const char* dirStr );
220
+
221
+  //=======================================================================================================================
222
+  // 
223
+  //
224
+  typedef struct
225
+  {
226
+    cmObj obj;
227
+    float           mu;        // LMS step rate
228
+    unsigned        hN;        // filter length
229
+    unsigned        delayN;    // fixed delay to apply to align xV with fV.
230
+    cmSample_t*     dV;        // delay line
231
+    cmSample_t*     wV;        // wV[hN] filter weights
232
+    cmSample_t*     hV;        // hV[hN] filter delay line
233
+    
234
+    unsigned        w0i;
235
+      
236
+    cmVectArray_t* eVa;
237
+  } cmNlmsEc_t;
238
+
239
+  cmNlmsEc_t* cmNlmsEcAlloc( cmCtx* ctx, cmNlmsEc_t* p, float mu, unsigned hN, unsigned delayN );
240
+  cmRC_t      cmNlmsEcFree( cmNlmsEc_t** pp );
241
+  cmRC_t      cmNlmsEcInit( cmNlmsEc_t* p, float mu, unsigned hN, unsigned delayN );
242
+  cmRC_t      cmNlmsEcFinal( cmNlmsEc_t* p );
243
+  
244
+  // xV[] unfiltered reference signal  (direct from xform output)
245
+  // fV[] filtered reference signal    (from mic)
246
+  // yV[] echo-canelled signal 
247
+  cmRC_t      cmNlmsEcExec( cmNlmsEc_t* p, const cmSample_t* xV, const cmSample_t* fV, cmSample_t* yV, unsigned xyN );
248
+  cmRC_t      cmNlmsEcWrite( cmNlmsEc_t* p, const cmChar_t* dir );
249
+  
220 250
   
221 251
   
222 252
 #ifdef __cplusplus

Chargement…
Annuler
Enregistrer