Upsample, apply FIR filter, downsample
Filter and resample a signal using polyphase interpolation.
upfirdn(x, h, p = 1, q = 1)
x |
input data, specified as a numeric vector or matrix. In case of a vector it represents a single signal; in case of a matrix each column is a signal. |
h |
Impulse response of the FIR filter specified as a numeric vector or
matrix. If it is a vector, then it represents one FIR filter to may be
applied to multiple signals in |
p |
Upsampling factor, specified as a positive integer (default: 1). |
q |
downsampling factor, specified as a positive integer (default: 1). |
upfirdn performs a cascade of three operations:
Upsample the input data in the matrix x
by a factor of the
integer p
(inserting zeros)
FIR filter the upsampled signal data with the impulse response
sequence given in the vector or matrix h
Downsample the result by a factor of the integer q
(throwing
away samples)
The FIR filter is usually a lowpass filter, which you must design using
another function such as fir1
.
output signal, returned as a vector or matrix. Each column has length
ceiling(((length(x) - 1) * p + length(h)) / q)
.
This function uses a polyphase implementation, which is generally
faster than using filter
by a factor equal to the downsampling
factor, since it only calculates the needed outputs.
Geert van Boxtel, G.J.M.vanBoxtel@gmail.com.
## Change the sample rate of a signal by a rational conversion factor ## from the DAT rate of 48 kHz to the CD sample rate of 44.1 kHz. Fdat <- 48e3 Fcd <- 44.1e3 LM <- scan(text = capture.output(pracma::rats(Fcd / Fdat)), sep = '/', quiet = TRUE) L <- LM[1]; M <- LM[2] ## Generate a 1.5 kHz sinusoid sampled at fDAT for 0.25 seconds. Plot the ## first millisecond. t <- seq(0, 0.25 - 1 / Fdat, 1 / Fdat) x <- sin(2 * pi * 1.5e3 * t) plot(t, x, type = "h", xlim = c(0, 0.001)) points(t, x) ## Design an antialiasing lowpass filter using a Kaiser window. ## band edges 90% and 110% f <- (Fdat / 2) * min(1 / L, 1 / M) ko <- kaiserord(c(f - 0.1*f, f + 0.1*f), c(1, 0), c(0.1, 0.1), Fdat) h <- L * fir1(ko$n, ko$Wc, ko$type, kaiser(ko$n + 1, ko$beta)) y <- upfirdn(x, h, L, M) delay <- floor(((ko$n - 1) / 2 - (L - 1)) / L) + 1 y <- y[(delay + 1):length(y)] ty <- seq(0, (length(y) - 1)) / Fcd points(ty, y, col = "red", pch = 2)
Please choose more modern alternatives, such as Google Chrome or Mozilla Firefox.