7

I have a signal with a sample rate of 8.9286 MHz and I want to downsample it to 500 kHz.

Since 8.9286 is not an integer multiple of 0.5 I can't simply decimate. Which downsample techniques are recommended to be used?

If I use this solution then I there will be a step to decimate by a factor of 647 $$(89286=2\times3\times23\times647),$$ which is prime, and would alias my signal in frequencies that are useful, so I can't filter them.

I could apply DFT to the original signal, then reconstruct in the time domain with the sample rate of 500 kHz, but that would take too much computational effort.

Is there a faster or simpler way to downsample it?

Ivo Tebexreni
  • 127
  • 1
  • 1
  • 7

2 Answers2

9

You need a resampler. There's different resamplers!

I'm not sure you're correctly interpreting the answer you cite: you don't just decimate by 647; you'd first (at least mathematically) upsample by some other factor. I'm not even quite where you got the 647 from, but an exact rational resampler would have to interpolate by 2500 and decimate by 44643. That's indeed a very unattractive resampler. 2500 and 44643 are coprime (or relatively prime), not prime in themselves; this is only important because if they weren't, you could cancel out factors.

Generally, you'd avoid resamplers where the interpolation or decimation sizes are so extreme, because you'll need to designa a $\frac1{44643}$-band filter, and that will lead to a very long filter.

Instead, you first try to bring the input rate "closer" to the output rate, e.g. by decimation-by-4, then apply an arbitrary resampler. Such arbitrary resamplers approximate the signal shape between samples at more or less arbitrary points. There's again many arbitrary resampler architectures, but the one I most commonly use is the polyphase filter bank arbitrary resampler, as e.g. implemented by the GNU Radio PFB arbitrary resampler block.

However, it's worth noting that in you fixed-input/output-rate scenario, it might be worth considering whether you actually need your output rate to be exactly 500 kHz. For example, assuming you use this for wireless communications with packets with a preamble. Then, using an upsampling by 20 and a downsampling by 357 will give you a rate that's only 4·10⁻⁴ larger than 500 kHz. If your packet is, say, only 256 samples long after the preamble, when you properly aligned timing in the preamble, the timing of your last payload sample will be 10% too early. You could even incorporate that knowledge, and retard your timing synchronization at the preamble by 5% of a symbol period, so that the maximum absolute timing error over the whole packet is but 5%, if 10% timing error increases your error vector magnitude too much. 20 up, 357 down is still not an easy rational resampling, but on my slightly older CPU core it runs, at an output rate of 5.1 MHz/s around 20% faster than the exact arbitrary resample, and about twice as fast as the exact rational resampler (2500/44643). A quick test flow graph for the 2500/44643 resampler

Notice that

  1. even the exact arbitrary resampler is about five times as fast running on a single x86_64 CPU core than it needs to be to achieve 500 kHz, so if that's your platform, being "smarter" than just using an existing rational resampler implementation doesn't help (aside from maybe saving energy).
  2. if you plan to implement this in hardware, check whether it would be faster / easier to hold a whole set of filter coefficient vectors in memory and evaluate a different filter for every output sample, or to have one very long filter. Use the polyphase arbitrary, or the rational resampling approach, accordingly.
Peter K.
  • 25,714
  • 9
  • 46
  • 91
Marcus Müller
  • 30,525
  • 4
  • 34
  • 58
  • 2
    Note also that any sane resampling scheme is going to use some sort of polyphase filtering -- if you're not just grabbing code from somewhere and pasting it in, looking up polyphase filtering and understanding it is probably a good idea. – TimWescott Jul 03 '22 at 23:44
  • @TimWescott absolutely. I've worked with and on a rational resampler that is polyphase-decomposed (because who has time / CPU power to actually upsample first and then filter at the high rate before downsampling? Hence I wrote "(at least mathematically) upsample…") where the individual polyphase brances are fast-convolution filters (didn't in the end turn out as faster on practical hardware than just plain straightforward SIMD-optimized filters on the branches). I'll second that knowing a bit of multi-rate processing is a must, and understanding a tiny bit polyphase filter really helps, but: – Marcus Müller Jul 04 '22 at 06:16
  • Didn't want to overwhelm OP, and I think really understanding how the resampler works internally isn't as important as knowing that the idea to rationally resample is that you find a good way to upsample - anti-image filter / anti-alias filter - downsample. – Marcus Müller Jul 04 '22 at 06:18
  • @MarcusMüller, you are right, I see now that I didn't fully understood the answer that I referenced, it's clearer now. Despite the problem of the band filter that I would need in downsample step, I see no problem in using it. – Ivo Tebexreni Jul 04 '22 at 14:30
  • @TimWescott, using MATLAB cubic interpolation can be archived by using spline command – Ivo Tebexreni Jul 04 '22 at 15:06
  • Ah um, spline interpolation is not interpolation in the numerical sense of the word, as the interpolation does not go through the original points. So, spline interpolation in general is a bad idea in signal processing. – Marcus Müller Jul 04 '22 at 15:09
  • 3
    Here's one paper which compares different polynomial interpolators for resampling purpose : http://yehar.com/blog/wp-content/uploads/2009/08/deip.pdf , (source code: http://yehar.com/blog/?p=197 ) – Juha P Jul 04 '22 at 17:00
  • @JuhaP huh, nice paper – Marcus Müller Jul 04 '22 at 17:22
  • 1
    … should also (maybe even moreso) say that to @OlliNiemitalo, I guess! – Marcus Müller Jul 04 '22 at 17:22
  • 2
    @MarcusMüller: I'm pretty sure that splines can go through the original points, if you choose the flavor of the spline correctly. And I do know from working it out that interpolation using splines works out to polyphase filtering with an implied low-pass filter in the middle. It may not be the best low-pass filter, but it always works out to a low-pass filter. Actually choosing a better one is probably, well, better, but I do find it interesting that it gets you to a similar end point using an entirely different conceptual starting point. – TimWescott Jul 05 '22 at 20:28
  • 2
    @TimWescott that's true, you can constrain your splines to be proper interpolators. But: I've had a student insist they do their radar target distance (through time-difference of arrival) estimation through spline interpolation with "default" parameters, and not too surprisingly, sinc-interpolation through zero-padding the FFT of the correlation does a lot better. – Marcus Müller Jul 05 '22 at 21:26
  • (and of runs circles around scipy's splines on speed) – Marcus Müller Jul 05 '22 at 21:32
3

If python is OK, you can just resample using an appropriate (approximate) interpolator:

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d
from scipy.signal import butter, lfilter

T = 10000 t = np.linspace(0,1,T, endpoint=True) x = np.sin(2np.pit*10) ratio = 8.9286/0.5 t2 = np.linspace(0,1,int(T/ratio))

b, a = butter(6, 2*np.pi/ratio, btype='low', analog=False) x_lpf = lfilter(b,a,x)

interpolated = interp1d(t, x_lpf, kind='cubic')

plt.plot(t,x) plt.plot(t2,interpolated(t2),'.')

Image showing resampled sine wave.

Peter K.
  • 25,714
  • 9
  • 46
  • 91
  • 1
    Too bad cubic interpolation doesn't exist in any language except Python... -Seriously: I'd say this is a good suggestion that might work just as well for the OP as any complicated polyphase filtering. But it might not... it depends on what signal properties are important. A bit of discussion would be good. At any rate, an example with a single sine isn't going to show much of the up- or downsides! – leftaroundabout Jul 04 '22 at 11:16
  • @leftaroundabout Agreed! I just wanted to use a different tack from the real one (polyphase filters), and see what the OP says. And there are plenty of languages with interpolation libraries. C++, for example. – Peter K. Jul 04 '22 at 14:36
  • 1
    That should work, and fortunately I'm using Python. It's for my Msc Dissertation so, do you know if is there are paper that use it for upsample/downsample? – Ivo Tebexreni Jul 04 '22 at 14:38
  • 1
    @IvoTebexreni My guess is: yes, but I am on mobile now so finding them will be harder. I’ll be at my desk a little later and will check then. – Peter K. Jul 04 '22 at 14:41
  • 1
    @IvoTebexreni that would not be "paper" material, that's just textbook material (which is good, that's faster and easier to read). The classic would be harris' multirate processing book. But that would already be a bit over the top: – Marcus Müller Jul 04 '22 at 14:41
  • 1
    What you'd need is chapter 4 of (at least in the second edition that I got for very very cheap used online) Oppenheim and Schafer: Discrete-Time Signal Processing. That chapter is called Sampling of Continuous-Time Signals, and the section you'd need to understand 4.6 Changing the Sampling Rate Using Discrete-Time Processing. – Marcus Müller Jul 04 '22 at 14:43
  • 1
    Oppenheim & Schafer is very likely available in your university's library (if not, send them a friendly email whether they want to buy this standard book on digital signal processing), I got mine for less than 15€ – Marcus Müller Jul 04 '22 at 14:46
  • Textbook are fine as well, thanks. I thought of using those type of interpolation but I wasn't sure if was valid for academic purposes. – Ivo Tebexreni Jul 04 '22 at 14:51
  • 1
    @IvoTebexreni. Here's an example: a paper in IEEE Transactions on Geoscience and Remote Sensing that explicitly calls out its use of interp1d (see just before equation (9)).. Using it is fine for most academic purposes. And a local here, robert bristow-johnson has a soft spot for linear interpolators! – Peter K. Jul 04 '22 at 15:23