View Raw SPL
/*****************************************************************************
* *
* FINTERP.SPL Copyright (C) 2007 DSP Development Corporation *
* All Rights Reserved *
* *
* Author: Randy Race *
* *
* Synopsis: FIR low pass series interpolation *
* *
* Revisions: 12 Apr 2007 RRR Creation *
* *
*****************************************************************************/
#include
#if @HELP_FINTERP
FINTERP
Purpose: Calculates Sinx/x interpolation using FIR low pass filtering.
Syntax: FINTERP(s, n, edge, attn)
(out, f) = FINTERP(s, n, edge, attn)
s - the input series
n - an optional integer, interpolation factor (default 2)
edge - an optional real, the transition band of the low pass
filter (default 0.95)
attn - an optional real, the attenuation in dB of the
low pass filter (default 60.0 db)
Returns: A series or array.
(out, lpf) = FINTERP(s, n) returns the series result and the
low pass filter coefficients.
Example:
W1: integ(gnorm(1000, .001))
W2: finterp(W1, 5)
W3: spectrum(W1)
W4: spectrum(W2);overp(W3, lred);
W2 interpolates the synthesized data int W1 by a factor
of 5. The original sample rate is 1000 Hz and the sample
rate of the resulting interpolated data is 5000 Hz.
Example:
W1: integ(gnorm(1000, .001))
W2: finterp(W1, 5, 0.85)
W3: spectrum(W1)
W4: spectrum(W2);overp(W3, lred);
Same as above, but the transition band of the FIR
low pass filter is widened, resulting in fewer filter
taps and faster processing.
Remarks:
FINTERP zero merges the original data and low pass filters
the merged data with an FIR Kaiser Window filter. Use:
(out, lpf) = finterp(s, n)
to return both the output data and the low pass filter
coefficients in impulse response form.
The edge frequencies of the filter are determined as
follows:
Fcut = rate(s) / 2
Fstop = Fcut + Fcut * (1 - edge)
Where rate(s) is the sample rate of the data.
FINTERP requires that DADiSP/Filters be loaded.
See Also:
DADiSP/Filters
Decimate
Interp
Xylookup
#endif
/* FIR low pass interpolation (sinx/x) */
finterp(s, n, edge, attn)
{
local y, nyq, f, z;
/* default args */
if (argc < 4)
{
attn = 60.0;
if (argc < 3)
{
edge = 0.95;
if (argc < 2)
{
if (argc < 1) error("finterp - input series required");
n = 2;
}
}
}
/* interpolation factor must be an integer */
n = int(n);
if (n < 2)
{
if (n == 1)
{
return(s);
}
else
{
error("finterp - positive decimation factor required");
}
}
if (edge < 0.0 || edge > 1.0)
{
error(sprintf("finterp - edge is %g, must lie between 0.0 and 1.0", edge));
}
if (attn <= 0.0)
{
error("finterp - positive attenuation required");
}
/* create zeros to merge */
z = zeros(length(s), 1);
setdeltax(z, deltax(s));
setxoffset(z, xoffset(s));
/* nyquist frequency */
nyq = rate(s) / 2;
/* merge zeros */
s = merge(s, z, n - 1);
/* design FIR low pass Kaiser filter */
f = kwlpass(rate(s), nyq, nyq * (2.0 - edge), attn, "unity_dc");
/* interpolate via direct filter convolution */
y = firfilter(s, f) * n;
return(y, f);
}