Browse Source

cmVectOpsTemplateHdr.h/Code.h : Added optional window function arg. and fixed high-pass filter generation in LP_Sinc().

Added use of cmAbs() generic to NormToAbsMax().
master
Kevin Larke 9 years ago
parent
commit
834b6f421f
2 changed files with 31 additions and 11 deletions
  1. 27
    9
      vop/cmVectOpsTemplateCode.h
  2. 4
    2
      vop/cmVectOpsTemplateHdr.h

+ 27
- 9
vop/cmVectOpsTemplateCode.h View File

@@ -332,13 +332,13 @@ unsigned VECT_OP_FUNC(NormToAbsMax)(   VECT_OP_TYPE* dp, unsigned dn, VECT_OP_TY
332 332
 
333 333
   unsigned     i  = 0;
334 334
   unsigned     mi = 0;
335
-  VECT_OP_TYPE mx = fabs(dp[0]);
335
+  VECT_OP_TYPE mx = cmAbs(dp[0]);
336 336
 
337 337
   for(i=1; i<dn; ++i)
338
-    if( fabs(dp[i])>mx )
338
+    if( cmAbs(dp[i])>mx )
339 339
     {
340 340
       mi = i;
341
-      mx = fabs(dp[i]);
341
+      mx = cmAbs(dp[i]);
342 342
     }
343 343
 
344 344
   VECT_OP_FUNC(MultVS)(dp,dn,fact/mx);
@@ -2339,33 +2339,51 @@ VECT_OP_TYPE*    VECT_OP_FUNC(FilterFilter)(struct cmFilter_str* f, cmRC_t (*fun
2339 2339
 
2340 2340
 
2341 2341
 
2342
-VECT_OP_TYPE* VECT_OP_FUNC(LP_Sinc)(VECT_OP_TYPE* dp, unsigned dn, double srate, double fcHz, unsigned flags )
2342
+VECT_OP_TYPE* VECT_OP_FUNC(LP_Sinc)(VECT_OP_TYPE* dp, unsigned dn, const VECT_OP_TYPE* wndV, double srate, double fcHz, unsigned flags )
2343 2343
 {
2344 2344
   VECT_OP_TYPE* rp = dp;
2345 2345
 
2346 2346
   int    dM       = dn % 2;                  // dM is used to handle odd length windows
2347 2347
   int    M        = (dn - dM)/2;
2348 2348
   int    Mi       = -M;
2349
-  double signFact = cmIsFlag(flags, kHighPass_LPSincFl) ? -0.5 : 0.5;
2350 2349
   double phsFact  = 2.0 * M_PI * fcHz / srate;
2351 2350
   double sum      = 0;
2351
+  VECT_OP_TYPE noWndV[ dn ];
2352 2352
 
2353
+  // if no window was given then create a unity window
2354
+  if( wndV == NULL )
2355
+  {
2356
+    VECT_OP_FUNC(Fill)(noWndV,dn,1);
2357
+    wndV = noWndV;
2358
+  }
2353 2359
 
2354 2360
   M += dM; 
2355 2361
 
2356 2362
   //printf("M=%i Mi=%i sign:%f phs:%f\n",M,Mi,signFact,phsFact);
2357 2363
 
2358
-
2359
-  for(; Mi<M; ++Mi,++dp)
2364
+  for(; Mi<M; ++Mi,++dp,++wndV)
2360 2365
   {
2361 2366
     double phs = phsFact * Mi;
2362
-    *dp = Mi == 0 ? 0.5 : signFact * sin(phs)/phs;
2367
+    if( Mi != 0 )
2368
+      *dp = *wndV * 0.5 * sin(phs)/phs;
2369
+    else
2370
+      *dp = *wndV * 0.5;
2371
+    
2363 2372
     sum += *dp;
2364 2373
   }
2365 2374
 
2375
+  // normalize the filter to produce unity gain.
2366 2376
   if( cmIsFlag(flags,kNormalize_LPSincFl) )
2367
-    VECT_OP_FUNC(DivVS)(rp,dn,sum);
2377
+    VECT_OP_FUNC(DivVS)(rp,dn,fabs(sum));
2368 2378
 
2379
+  // Convert low-pass filter to high-pass filter
2380
+  // Note that this can only be done after the filter is normalized.
2381
+  if( cmIsFlag(flags,kHighPass_LPSincFl) )
2382
+  {
2383
+    VECT_OP_FUNC(MultVS)(rp,dn,-1);
2384
+    rp[M-1] = 1.0 + rp[M-1];
2385
+  }
2386
+  
2369 2387
   return rp;
2370 2388
 }
2371 2389
 

+ 4
- 2
vop/cmVectOpsTemplateHdr.h View File

@@ -443,8 +443,10 @@ struct cmFilter_str;
443 443
 VECT_OP_TYPE* VECT_OP_FUNC(FilterFilter)(struct cmFilter_str* f, cmRC_t (*func)( struct cmFilter_str* f,  const VECT_OP_TYPE* x, unsigned xn, VECT_OP_TYPE* y, unsigned yn ), const cmReal_t bb[], unsigned bn, const cmReal_t aa[], unsigned an, const VECT_OP_TYPE* x, unsigned xn, VECT_OP_TYPE* y, unsigned yn );
444 444
 
445 445
 /// Compute the coefficients of a low/high pass FIR filter
446
-/// See enum { kHighPass_LPSincFl=0x01, kNormalize_LPSincFl=0x02 } in acVectOps.h
447
-VECT_OP_TYPE* VECT_OP_FUNC(LP_Sinc)(VECT_OP_TYPE* dp, unsigned dn, double srate, double fcHz, unsigned flags );
446
+/// wndV[dn] gives the window function used to truncate the ideal low-pass impulse response.
447
+/// Set wndV to NULL to use a unity window.
448
+/// See enum { kHighPass_LPSincFl=0x01, kNormalize_LPSincFl=0x02 } in cmVectOps.h
449
+VECT_OP_TYPE* VECT_OP_FUNC(LP_Sinc)(VECT_OP_TYPE* dp, unsigned dn, const VECT_OP_TYPE* wndV, double srate, double fcHz, unsigned flags );
448 450
 
449 451
 /// Compute the complex transient detection function from successive spectral frames.
450 452
 /// The spectral magntidue mag0V precedes mag1V and the phase (radians) spectrum phs0V precedes the phs1V which precedes phs2V.  

Loading…
Cancel
Save