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
 
332
 
333
   unsigned     i  = 0;
333
   unsigned     i  = 0;
334
   unsigned     mi = 0;
334
   unsigned     mi = 0;
335
-  VECT_OP_TYPE mx = fabs(dp[0]);
335
+  VECT_OP_TYPE mx = cmAbs(dp[0]);
336
 
336
 
337
   for(i=1; i<dn; ++i)
337
   for(i=1; i<dn; ++i)
338
-    if( fabs(dp[i])>mx )
338
+    if( cmAbs(dp[i])>mx )
339
     {
339
     {
340
       mi = i;
340
       mi = i;
341
-      mx = fabs(dp[i]);
341
+      mx = cmAbs(dp[i]);
342
     }
342
     }
343
 
343
 
344
   VECT_OP_FUNC(MultVS)(dp,dn,fact/mx);
344
   VECT_OP_FUNC(MultVS)(dp,dn,fact/mx);
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
   VECT_OP_TYPE* rp = dp;
2344
   VECT_OP_TYPE* rp = dp;
2345
 
2345
 
2346
   int    dM       = dn % 2;                  // dM is used to handle odd length windows
2346
   int    dM       = dn % 2;                  // dM is used to handle odd length windows
2347
   int    M        = (dn - dM)/2;
2347
   int    M        = (dn - dM)/2;
2348
   int    Mi       = -M;
2348
   int    Mi       = -M;
2349
-  double signFact = cmIsFlag(flags, kHighPass_LPSincFl) ? -0.5 : 0.5;
2350
   double phsFact  = 2.0 * M_PI * fcHz / srate;
2349
   double phsFact  = 2.0 * M_PI * fcHz / srate;
2351
   double sum      = 0;
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
   M += dM; 
2360
   M += dM; 
2355
 
2361
 
2356
   //printf("M=%i Mi=%i sign:%f phs:%f\n",M,Mi,signFact,phsFact);
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
     double phs = phsFact * Mi;
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
     sum += *dp;
2372
     sum += *dp;
2364
   }
2373
   }
2365
 
2374
 
2375
+  // normalize the filter to produce unity gain.
2366
   if( cmIsFlag(flags,kNormalize_LPSincFl) )
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
   return rp;
2387
   return rp;
2370
 }
2388
 }
2371
 
2389
 

+ 4
- 2
vop/cmVectOpsTemplateHdr.h View File

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 );
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
 /// Compute the coefficients of a low/high pass FIR filter
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
 /// Compute the complex transient detection function from successive spectral frames.
451
 /// Compute the complex transient detection function from successive spectral frames.
450
 /// The spectral magntidue mag0V precedes mag1V and the phase (radians) spectrum phs0V precedes the phs1V which precedes phs2V.  
452
 /// The spectral magntidue mag0V precedes mag1V and the phase (radians) spectrum phs0V precedes the phs1V which precedes phs2V.  

Loading…
Cancel
Save