-1
$\begingroup$

I try to implement interpolation algorithm. I code this using MATLAB.

Firstly, I create a signal and I upsample my signal using zero padding.

fs = 1000;
t = 0:1/fs:0.5-1/fs;
sig1 = sin(2*pi*50*t);

x_up(1:4:sig_len*4)= 4*sig1(1:sig_len);
x_up = zeros(1,sig_len*4);

After that, I filtered this signal. I create filter coefficients.

fv = [8 12]/fs;

b = fir1(40,fv);

filt_sig = filter(b,1,x_up);

However, I obtain low amplitude output according to the input signal. I know that accordingly interpolation algorithm, output's amplitude doesn't change.

After the filter output, what can I do with this output's amplitude change?

I add my graphs.

enter image description here

$\endgroup$
2
  • 1
    $\begingroup$ I think this is not your actual code; you need to first set up x_up as zeros, then overwrite every fourth elelemt with sig1. $\endgroup$ Dec 11, 2021 at 22:19
  • $\begingroup$ does your FIR filter have a gain of 1 at the frequency of your interpolated signal? $\endgroup$ Dec 11, 2021 at 22:20

1 Answer 1

1
$\begingroup$

I first commented that a scaling by 4 is required but, as Marcus commented, we observe in the OP's code that such a scaling is already being done. I then replicated the OP's code as follows: (ordering the zero-insert operation properly in order to obtain any output)

fs = 1000;
t = 0:1/fs:0.5-1/fs;
sig1 = sin(2*pi*50*t); 
x_up = zeros(1,sig_len*4);
x_up(1:4:len(sig1)*4)= 4*sig1(1:len(sig1));
fv = [8 12]/fs;
b = fir1(40,fv);
filt_sig = filter(b,1,x_up);

enter image description here

The level is slightly reduced, but nowhere near that in the OP's plot. Given the code as shown will not work, I suspect there are other differences between the code the OP posted and what was actually used (specifically I suspect the scaling by 4 was not actually done). The observed slightly reduced level is consistent with the suboptimal filtering used for interpolation, and consistent with the frequency response of the OP's interpolation filter:

freqz(b,1,512, 4000)

Zooming in on this passband response we observe the -1.4 dB attenuation at the 50 Hz signal: Freq Response

An efficient interpolation filter can be designed using the least squares algorithm (firls in MATLAB, Octave and Python scipy.signal) that minimizes any loss or distortion in the passband and maximizes rejection only where it is needed- for example, if we assume a desired passband from DC to 50 Hz, then the only frequency bands where interpolation images will appear in the output signal after zero insert are from 975 to 1025 Hz and 1975 to 2000 Hz up to Nyquist (at the 4KHz output rate).

The following filter will provide nearly 100 dB rejection of the interpolation images and only requires 12 coefficients:

coeff = firls(12, [0 50 975 1025 1975 2000]/2000, [1 1 0 0 0 0]);

interpolation filter

Filtering x_up with this new filter results in the updated plot below showing the original signal and the interpolated signal with minimum distortion. Further we would get such a clean result for any waveform in the DC to 50 Hz passband.

final plot

(See these other posts regarding polyphase implementations where this could be converted to 4 3-tap polyphase filters all running at the original 1 KHz rate!)

Prior response regarding amplitude scaling requirements with interpolation:


An amplitude change is expected with zero padding interpolation when passed through the same FIR filter for interpolation. An FIR filter is simply a weighted moving average, so we can intuitively see what happens if we consider a case of an FIR filter with unity gain coefficients and scale the output to normalize the gain of the filter. For a simple example consider a 4 tap FIR filter with unity gain coefficients:

4 Tap FIR Filter

The output is divided by 4 to be a true moving average, alternatively the coefficients could have been each scaled by 0.25. Either way we see in this case that the output signal will now match the scaling of the input signal when the signal is within the passband of the filter. In this case when we do the simplest case of a "DC" tone as a stream of ones the output will also converge to a stream of ones:

$$x[n] = [1, 1, 1, 1, 1, 1, \ldots]$$

We will get:

$$y[n] = [0.25, 0.5, 0.75, 1, 1, 1, 1, \ldots]$$

Now consider the same case with the input interpolated by 2 (for example), which is done by inserting s zero in between each input sample:

$$x_i[n] = [1, 0, 1, 0, 1, 0, \ldots]$$

We will get:

$$y_i[n] = [0.25, 0.25, 0.5, 0.5, 0.5, 0.5 \ldots]$$

The solution is to simply scale by $N$ where $N$ is the interpolation factor (with $N-1$ zeros inserted).

$\endgroup$
1
  • 1
    $\begingroup$ I think that happens in x_up(1:4:sig_len*4)= 4*sig1(1:sig_len); note the factor of 4! $\endgroup$ Dec 12, 2021 at 1:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.