Main Content

This example shows how to resample a uniformly sampled signal to a new uniform rate. It shows how to reduce the impact of large transients as well as how to remove unwanted high frequency content.

The `resample`

function performs rate conversion from one sample rate to another. `resample`

allows you to upsample by an integral factor, `p`

, and subsequently decimate by another integral factor, `q`

. In this way you can resample to a rational multiple (`p`

/ `q`

) of the original sample rate.

To use the `resample`

function on uniform samples, you must provide both the numerator and denominator of this rational factor. To determine the integers you need, you can use the `rat`

function.

Here is an example of how to call `rat`

when converting from 48 kHz to 44.1 kHz:

originalFs = 48000; desiredFs = 44100; [p,q] = rat(desiredFs / originalFs)

p = 147

q = 160

`rat`

indicates that you can upsample by 147 and decimate by 160. To verify that this produces the desired rate, multiply `p`

/ `q`

by the original sample rate:

originalFs * p / q

ans = 44100

Once you have the ratio between the new and original sample rates, you can call `resample`

.

For example, create a 10 millisecond long 500 Hz sinusoid using the original sample rate of 48 kHz and convert it to 44.1 kHz:

tEnd = 0.01; Tx = 0:1/originalFs:tEnd; f = 500; x = sin(2*pi*f*Tx); y = resample(x,p,q); Ty = (0:numel(y)-1)/desiredFs; plot(Tx,x,'. ') hold on plot(Ty,y,'o ') hold off legend('Original','Resampled')

For well-behaved signals such as the sinusoid above, simply using `resample`

with a carefully chosen `p`

and `q`

should be enough to reconstruct it properly.

For signals with transients or significant noise, you may wish to have greater control over the poly-phase anti-aliasing filter in `resample`

.

The `resample`

function uses a filter when it performs rate conversion. This filtering is sensitive to large transients in the signal.

To illustrate this, resample a rectangular pulse:

x = [zeros(1,120) ones(1,241) zeros(1,120)]; y = resample(x,p,q); plot(Tx,x,'-', Ty,y,'-') legend('Original','Resampled')

The function does a good job of reconstructing the flat regions of the pulse. However, there are spikes at the edges of the pulse.

Zoom in on the edge of the first pulse:

xlim([2e-3 3e-3])

There is a damped oscillation in the transition region. You can diminish this oscillation by adjusting the settings of the internal filter.

`resample`

allows you to have control over a Kaiser window applied to the anti-aliasing filter that can mitigate some of the edge effects.

Two parameters, `n`

and `beta`

, control the relative length of the filter and the amount of smoothing it attempts to perform. A larger value of `n`

will have a larger filter length. A `beta`

of 0 will have no additional smoothing. Larger `beta`

values will have larger smoothing. By default, `n`

is 10 and `beta`

is 5.

A practical way to proceed is to start with the default values and adjust as needed. Here, set `n`

to 5 and `beta`

to 20.

n = 5; beta = 20; y = resample(x,p,q,n,beta); plot(Tx,x,'.-') hold on plot(Ty,y,'o-') hold off legend('Original','Resampled') xlim([2e-3 3e-3])

The oscillation is significantly reduced.

The `resample`

function is designed to convert sample rates to either higher or lower rates. As a consequence, the frequency cutoff of the anti-aliasing filter is set to the Nyquist frequency of the input or output sample rate (whichever is lower). This default setting allows the `resample`

function to cover a wide range of applications.

There are times when direct control of the filter may be beneficial.

To illustrate this, construct and view the spectrogram of a chirp signal sampled at 96 kHz. The chirp signal consists of a sinusoid whose frequency varies quadratically over the entire Nyquist range from 0 Hz to 48 kHz over a duration of eight seconds:

fs1 = 96000; t1 = 0:1/fs1:8; x = chirp(t1, 0, 8, fs1/2, 'quadratic'); spectrogram(x,kaiser(256,15),220,412,fs1,'yaxis')

Next, convert the chirp to 44.1 kHz using the default settings of `resample`

and view the spectrogram:

```
fs2 = 44100;
[p,q] = rat(fs2/fs1);
y = resample(x,p,q);
spectrogram(y,kaiser(256,15),220,412,fs2,'yaxis')
```

Here you can see the original signal as well as unwanted frequency content. Ideally the sinusoid should start at 0 Hz and continue until it reaches the Nyquist frequency of 22.05 kHz at 5.422 s. Instead, there are artifacts introduced due to small discontinuities introduced at the edges of the default filter used for resampling. To prevent these artifacts, you can provide a longer filter with a slightly lower cutoff frequency and greater stop-band rejection than the default filter.

To have proper temporal alignment, the filter should have odd length. The length should be a few times larger than `p`

or `q`

(whichever is larger). Similarly, divide the desired normalized cutoff frequency by the larger of `p`

or `q`

. In either case, multiply the resulting coefficients by `p`

.

Here is an example of a filter with a cutoff at 98% (0.98) of the output Nyquist frequency with an order of 256 times the decimation factor, windowed with a Kaiser window with a `beta`

of 12.

normFc = .98 / max(p,q); order = 256 * max(p,q); beta = 12; lpFilt = firls(order, [0 normFc normFc 1],[1 1 0 0]); lpFilt = lpFilt .* kaiser(order+1,beta)'; lpFilt = lpFilt / sum(lpFilt); % multiply by p lpFilt = p * lpFilt; % resample and plot the response y = resample(x,p,q,lpFilt); spectrogram(y,kaiser(256,15),220,412,fs2,'yaxis')

Note that the aliases are removed.

For more information on resampling see the Signal Processing Toolbox.

Reference: fredric j harris, "Multirate Signal Processing for Communications Systems", Prentice Hall, 2004.