View Raw SPL
/*****************************************************************************
* *
* ZHPFILT.SPL Copyright (C) 2008-2012 DSP Development Corporation *
* All Rights Reserved *
* *
* Author: Randy Race *
* *
* Synopsis: High pass filtering by FFT zeroing *
* *
* Revisions: 18 Jul 2008 RRR Creation *
* 9 Mar 2012 RRR Optional frequency domain mask return *
* *
*****************************************************************************/
#if @HELP_ZHPFILT
ZHPFILT
Purpose: Performs high pass filtering by zeroing the FFT values.
Syntax: ZHPFILT(s, fc, mask)
s - A series, the input series.
fc - Optional. A real, the high pass cutoff frequency.
Defaults to rate(s) / 10.
mask - Optional. An integer, return the frequency domain mask
only. Defaults to 0, return processed input.
Returns:
A series, the high pass filtered output.
Example:
W1: gsin(1000, 1/1000, 20) + gsin(1000, 1/1000, 1)
W2: zhpfilt(w1, 10)
W1 contains a 20 Hertz sinewave riding on top of a 1 Hertz
sinusoidal drift.
W2 filters out the drift an returns the 20 Hertz sinusoidal
component.
Remarks:
ZHPFILT performs high pass filtering by zeroing out the
low frequency components of the FFT of the input.
FFT zeroing is a crude but fast filtering operation.
However, the pass band and transition edge of the
equivalent filter will exhibit significant ripple. For a
flatter response, use traditional filter design methods
such as those offered by DADiSP/Filters.
If fc < 0, no filtering is performed.
If mask == 1, the frequency domain binary mask used to zero
out the stopband frequencies is returned.
See ZLPFILT for a low pass filter.
See Also:
DADiSP/Filters
Zlpfilt
#endif
/* FFT zeroing high pass filter */
ITERATE zhpfilt(s, fc, mask)
{
local len, bw, f, q;
if (argc < 3)
{
if (argc < 2)
{
if (argc < 1) error("zhpfilt - input series required");
fc = rate(s) / 10;
}
/* default to process data */
mask = 0;
}
len = length(s);
/* bin frequency width */
bw = rate(s) / len;
if (mask)
{
/* unity frequency domain mask */
f = ones(len, 1, bw);
}
/* no filtering */
if (fc < 0)
{
return(mask ? f : s);
}
/* index of samples to zero, note that fc is filtered out */
q = int(fc / bw) + 1;
if (q > len / 2)
{
q = len;
}
if (not(mask))
{
/* frequency domain */
f = fft(s);
}
/* zero out DC range */
f[1..q] = 0;
/* zero out nyquist range */
if (q >= 2 && q < len)
{
f[(len - q + 2)..len] = 0;
}
if (mask)
{
/* return mask */
return(f);
}
else
{
/* return time domain series */
f = ifft(f);
if (isreal(s))
{
f = real(f);
}
setxoffset(f, xoffset(s));
return(f);
}
}