Main Content

upfirdn

Upsample, apply FIR filter, and downsample

Description

y = upfirdn(x,h) filters the input signal x using an FIR filter with impulse response h. No upsampling or downsampling is implemented with this syntax.

y = upfirdn(x,h,p) specifies the integer upsampling factor p.

example

y = upfirdn(x,h,p,q) specifies the integer downsampling factor q.

example

Examples

collapse all

Since R2026a

Design a 50th-order FIR lowpass filter to suppress imaging artifacts from upsampling. The upsample factor is 5. Compute the group delay and impulse response of the filter.

p = 5;

n = 50;
h = p*fir1(n,1/p);
dl = grpdelay(h,1,1);
freqz(h)

Figure contains 2 axes objects. Axes object 1 with title Phase, xlabel Normalized Frequency (\times\pi rad/sample), ylabel Phase (degrees) contains an object of type line. Axes object 2 with title Magnitude, xlabel Normalized Frequency (\times\pi rad/sample), ylabel Magnitude (dB) contains an object of type line.

Define a linearly swept cosine (chirp) signal for one second at a sample rate of 30 Hz.

Fs = 1e3;
t = single(0:1/Fs:1)';
x = chirp(t,20,t(end),150);

Filter and upsample the chirp signal. Since the input signal has single precision, the output also has single precision.

xu = upfirdn(x,h,p);

Compare the input and output signals. Compensate for the delay introduced by the filter. Generate the corresponding resampled time vector.

xu = xu(dl+1:end);
tu = single(0:(length(xu)-1))/(Fs*p);
plot(t,x,".-",MarkerSize=10)
hold on
plot(tu,xu,".-",MarkerSize=4)
hold off
xlim([0 0.5])
xlabel("Time (s)")
legend(["x" "xu"])

Figure contains an axes object. The axes object with xlabel Time (s) contains 2 objects of type line. These objects represent x, xu.

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. Use the rat function to find the numerator L and the denominator M of the rational factor.

Fdat = 48e3;
Fcd = 44.1e3;
[p,q] = rat(Fcd/Fdat)
p = 
147
q = 
160

Generate a 1.5 kHz sinusoid sampled at fDAT for 0.25 seconds. Plot the first millisecond of the signal.

t = 0:1/Fdat:0.25-1/Fdat;
x = sin(2*pi*1.5e3*t);
stem(t,x)
xlim([0 0.001])
xlabel("Time (s)")
hold on

Figure contains an axes object. The axes object with xlabel Time (s) contains an object of type stem.

Design an antialiasing lowpass filter using a Kaiser window. Set the filter band edges as 90% and 110% of the cutoff frequency, (fDAT/2)×min(1/L,1/M). Specify a passband ripple of 5 dB and a stopband attenuation of 40 dB. Set the passband gain to L.

f = (Fdat/2)*min(1/p,1/q);
d = designfilt("lowpassfir", ...
    PassbandFrequency=0.9*f,StopbandFrequency=1.1*f, ...
    PassbandRipple=5,StopbandAttenuation=40, ...
    DesignMethod="kaiserwin",SampleRate=48e3);
h = p*tf(d);

Use upfirdn with the filter h to resample the sinusoid. Compute and compensate for the delay introduced by the filter. Generate the corresponding resampled time vector.

y = upfirdn(x,h,p,q);

delay = floor(((filtord(d)-1)/2-(p-1))/p);
y = y(delay+1:end);
t_res = (0:(length(y)-1))/Fcd;

Overlay the resampled signal on the plot.

stem(t_res,y,"*")
legend("Original","Resampled",Location="southeast")
hold off

Figure contains an axes object. The axes object with xlabel Time (s) contains 2 objects of type stem. These objects represent Original, Resampled.

Input Arguments

collapse all

Input signal, specified as a vector or matrix. If x is a vector, then it represents a single signal. If x is a matrix, then each column is filtered independently. For more details, see Tips.

Data Types: single | double

Filter impulse response, specified as a vector or matrix. If h is a vector, then it represents one FIR filter. If h is a matrix, then each column is a separate FIR impulse response sequence. For more details, see Tips.

Data Types: single | double

Upsampling factor, specified as a positive integer.

Data Types: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

Downsampling factor, specified as a positive integer.

Data Types: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

Output Arguments

collapse all

Output signal, returned as a vector or matrix. Each column of y has length ceil(((length(x)-1)*p+length(h))/q).

If you specify x or h as type single, then upfirdn performs the filtering operation using single-precision arithmetic, and returns y in single precision. Otherwise, upfirdn returns y as type double.

Note

Since upfirdn performs convolution and rate changing, the output signals y have a different length than the input signals x. The number of rows of y is approximately p/q times the number of rows of x.

Tips

The valid combinations of the sizes of x and h are:

  1. x is a vector and h is a vector.

    The inputs are one filter and one signal, so the function convolves x with h. The output signal y is a row vector if x is a row vector; otherwise, y is a column vector.

  2. x is a matrix and h is a vector.

    The inputs are one filter and many signals, so the function convolves h with each column of x. The resulting y is a matrix with the same number of columns as x.

  3. x is a vector and h is a matrix.

    The inputs are multiple filters and one signal, so the function convolves each column of h with x. The resulting y is a matrix with the same number of columns as h.

  4. x is a matrix and h is a matrix, both with the same number of columns.

    The inputs are multiple filters and multiple signals, so the function convolves corresponding columns of x and h. The resulting y is a matrix with the same number of columns as x and h.

Algorithms

upfirdn uses a polyphase interpolation structure. The number of multiply-add operations in the polyphase structure is approximately (LhLxpLx)/q where Lh and Lx are the lengths of h(n) and x(n), respectively. For long signals, this formula is often exact.

upfirdn performs a cascade of three operations:

  1. Upsample the input data in the matrix x by a factor of the integer p (inserting zeros)

  2. FIR filter the upsampled signal data with the impulse response sequence given in the vector or matrix h

  3. 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 firpm or fir1.

Note

The function resample performs an FIR design using firls, followed by rate changing implemented with upfirdn.

References

[1] Crochiere, R. E. "A General Program to Perform Sampling Rate Conversion of Data by Rational Ratios." Programs for Digital Signal Processing (Digital Signal Processing Committee of the IEEE Acoustics, Speech, and Signal Processing Society, eds.). New York: IEEE Press, 1979, Programs 8.2-1–8.2-7.

[2] Crochiere, R. E., and Lawrence R. Rabiner. Multirate Digital Signal Processing. Englewood Cliffs, NJ: Prentice-Hall, 1983.

Extended Capabilities

expand all

C/C++ Code Generation
Generate C and C++ code using MATLAB® Coder™.

GPU Code Generation
Generate CUDA® code for NVIDIA® GPUs using GPU Coder™.

Version History

Introduced before R2006a

expand all