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().
This commit is contained in:
Kevin Larke 2015-05-22 14:10:24 -07:00
parent 172b562022
commit 834b6f421f
2 changed files with 31 additions and 11 deletions

View File

@ -332,13 +332,13 @@ unsigned VECT_OP_FUNC(NormToAbsMax)( VECT_OP_TYPE* dp, unsigned dn, VECT_OP_TY
unsigned i = 0;
unsigned mi = 0;
VECT_OP_TYPE mx = fabs(dp[0]);
VECT_OP_TYPE mx = cmAbs(dp[0]);
for(i=1; i<dn; ++i)
if( fabs(dp[i])>mx )
if( cmAbs(dp[i])>mx )
{
mi = i;
mx = fabs(dp[i]);
mx = cmAbs(dp[i]);
}
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
VECT_OP_TYPE* VECT_OP_FUNC(LP_Sinc)(VECT_OP_TYPE* dp, unsigned dn, double srate, double fcHz, unsigned flags )
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 )
{
VECT_OP_TYPE* rp = dp;
int dM = dn % 2; // dM is used to handle odd length windows
int M = (dn - dM)/2;
int Mi = -M;
double signFact = cmIsFlag(flags, kHighPass_LPSincFl) ? -0.5 : 0.5;
double phsFact = 2.0 * M_PI * fcHz / srate;
double sum = 0;
VECT_OP_TYPE noWndV[ dn ];
// if no window was given then create a unity window
if( wndV == NULL )
{
VECT_OP_FUNC(Fill)(noWndV,dn,1);
wndV = noWndV;
}
M += dM;
//printf("M=%i Mi=%i sign:%f phs:%f\n",M,Mi,signFact,phsFact);
for(; Mi<M; ++Mi,++dp)
for(; Mi<M; ++Mi,++dp,++wndV)
{
double phs = phsFact * Mi;
*dp = Mi == 0 ? 0.5 : signFact * sin(phs)/phs;
if( Mi != 0 )
*dp = *wndV * 0.5 * sin(phs)/phs;
else
*dp = *wndV * 0.5;
sum += *dp;
}
// normalize the filter to produce unity gain.
if( cmIsFlag(flags,kNormalize_LPSincFl) )
VECT_OP_FUNC(DivVS)(rp,dn,sum);
VECT_OP_FUNC(DivVS)(rp,dn,fabs(sum));
// Convert low-pass filter to high-pass filter
// Note that this can only be done after the filter is normalized.
if( cmIsFlag(flags,kHighPass_LPSincFl) )
{
VECT_OP_FUNC(MultVS)(rp,dn,-1);
rp[M-1] = 1.0 + rp[M-1];
}
return rp;
}

View File

@ -443,8 +443,10 @@ struct cmFilter_str;
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 );
/// Compute the coefficients of a low/high pass FIR filter
/// See enum { kHighPass_LPSincFl=0x01, kNormalize_LPSincFl=0x02 } in acVectOps.h
VECT_OP_TYPE* VECT_OP_FUNC(LP_Sinc)(VECT_OP_TYPE* dp, unsigned dn, double srate, double fcHz, unsigned flags );
/// wndV[dn] gives the window function used to truncate the ideal low-pass impulse response.
/// Set wndV to NULL to use a unity window.
/// See enum { kHighPass_LPSincFl=0x01, kNormalize_LPSincFl=0x02 } in cmVectOps.h
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 );
/// Compute the complex transient detection function from successive spectral frames.
/// The spectral magntidue mag0V precedes mag1V and the phase (radians) spectrum phs0V precedes the phs1V which precedes phs2V.