View Raw SPL
/*****************************************************************************
* *
* DECILP.SPL Copyright (C) 1998-2009 Development Corporation *
* All Rights Reserved *
* *
* Author: Randy Race *
* *
* Synopsis: Low pass filters and decimates a series *
* *
* Revisions: 9 Jun 1998 RRR Creation *
* 22 Dec 2009 RRR Use series end padding *
* *
*****************************************************************************/
#include
#if @HELP_DECILP
DECILP
Purpose: Low pass filters and decimates a series
Syntax: DECILP(s, n, edge, attn)
s - the input series
n - an optional integer, decimation factor (default 2)
edge - an optional real, the transition band of the low pass
filter (default 0.8125)
attn - an optional real, the attenuation in dB of the
low pass filter (default 70.0 db)
Returns: A series or array
Example:
W1: integ(gnorm(1000, 1/1000))
W2: decilp(W1, 5)
W3: spectrum(W2, 8*1024)
W4: spectrum(W1, 8*1024);overp(W3, lred);setylog(1, 0, 1)
The spectrum in W3 is a virtually the first 1/5 of the
spectrum of the original data. The length of the output
is 1/5 the length of the input.
Example:
W2: Decilp(W1, 5, 0.95)
Same as above, but the transition band is narrowed.
Remarks:
DECILP creates an FIR low pass filter using the Kaiser
Window method. Use
(out, lpf) = decilp(s, n)
to return both the output data and the coefficients of the
FIR low pass filter.
The edge frequencies of the filter are determined as
follows:
Fcut = edge * Fstop
Fstop = Fs / (2*n)
Where Fs is the sample rate of the data (i.e. RATE(s)).
The decimation factor automatically adjusts the sampling rate (1/deltax)
of the resulting series.
See Also:
DADiSP/Filters
Decimate
Padfilt
#endif
/* decimate with low pass filtering to preserve frequency spectrum */
ITERATE decilp(s, n, edge, attn)
{
local r, fc, f, out;
/* default args */
if (argc < 4)
{
attn = 60.0;
if (argc < 3)
{
edge = 0.8125;
if (argc < 2)
{
n = 2;
}
}
}
r = rate(s);
n = int(n);
if (n < 2)
{
if (n == 1)
{
return(s);
}
else
{
error("decilp - positive decimation factor required");
}
}
if (edge <= 0.0 || edge >= 1.0)
{
error(sprintf("decilp - edge is %g, must lie between 0.0 and 1.0", edge));
}
if (attn <= 0.0)
{
error("decilp - positive attenuation required");
}
/* cutoff freq is 1/n * nyquist frequency */
fc = r / (2 * n);
/* build a Kaiser FIR low pass filter */
// f = firlp(r, edge * fc, fc, attn);
f = firlp(r, edge * fc, fc * (2 - edge), attn);
/* FIR filter and decimate it */
out = decimate(firflt(s, f, 1), n);
if (outargc > 1)
{
/* return result and filter */
return(out, f);
}
else
{
return(out);
}
}