# How Can I Resample a Signal with an Arbitrary Factor (For Example - 128000Hz to 16000.1Hz) in MATLAB?

I need to simulate the sampling of a continuous (fsCtu = 128000Hz), acoustic signal with two microphones that have a slight offset in sampling rate (fsMic1 = 16000, fsMic2 = 16000.1) in Matlab. What is the best way to do this?

Things I tried:

• The Matlab "resample" command only works for resampling to 16000, not to 16000.1
• "interp1" doesn't seem to be an option because I think I need to use bandlimited interpolation for a correct simulation. (Is this assumption correct?)
• I tried to write my signal to a wav file and resample it via a system call using this software, then load the processed file with wavread. I'm not sure if this is a good solution. A quick test revealed that this method doesn't give the same result as the "resample" command for resampling to 16000Hz, which I find strange.

Any ideas or suggestions?

• What is the information bandwidth of your signal? I'm guessing your audio channels have anti-alias filters - do you know their bandwidths? And do you have an analytical model of your signal, or just the high-rate samples? – mtrw Dec 9 '12 at 19:56
• I don't have an analytical model of the signal, only high rate samples. In fact, I'm currently using noise 'randn(fsCtu*signalDuration,1)' as the continuous signal. – user1542912 Dec 9 '12 at 23:30

There are a couple of ways that you can do it. The first is with resample, but it is a multi-step process. First, you have to figure out which interpolation and decimation factors will get you the sample rate you want.

[n, k] = rat(16000.1 / 128000);


That gets you an interpolation factor of 20000 and a decimation factor of 159999. You factor those to break them up into smaller chunks.

nFactors = factor(n)
kFactors = factor(k)


It turns out that n factors to $2^5 * 5^4$ and k factors to $3 * 7 * 19 * 401$. All of those are doable, though the decimation by 401 will not have great filtering properties. Anyway, if you resample in stages you can get the final sample rate you want.

The other way to do it is polynomial interpolation. Essentially you model your signal as a polynomial through curve fitting techniques, and then you can simply feed in the time values that you want and out will pop the signal values. This technique can be very effective, but modelling the signal well is a bit of an art. In particular you don't want to overfit.

• An alternative to polynomial interpolation of the signal is polynomial interpolation of a FIR filter kernel (providing essentially an infinite number of "polyphases") such as a windowed Sinc (or similar remez generated) kernel. In some implementation forms this might be similar to a Farrow filter. – hotpaw2 Dec 10 '12 at 8:41
• jim-clay: I think your first solution will be difficult and slow to implement in a general way (resample to arbitrary sample rates , e.g. 16000.001). The polynomial interpolation is a good idea for my toy example, but later I will use real audio files (speech, babble noise) sampled at 44.1kHz as my signal so I won't be able to use it. @hotpaw2: what kind of side effects does that method have? I need "perfect" resampling because I'm building a simulation framework. – user1542912 Dec 10 '12 at 10:02
• @hotpaw2 So you generate the needed windowed sinc taps that you need on the fly? – Jim Clay Dec 10 '12 at 14:21
• @Jim Clay : Yes. First generate the appropriate filter kernel (windowed-Sinc or remez for example) that meets the S/N requirements. Then linear interpolate from a large polyphase table, or do a higher order polynomial interpolation from a much smaller number of points, or outright call the sin/cos math lib to compute an equation if in closed form, trading off memory against FLOPs as per the available hardware capabilities and performance requirements. – hotpaw2 Dec 10 '12 at 16:33
• @user1542912 Point taken about the arbitrary sample rates, but keep in mind that the sample rate is never exactly what you think it is. There is always some error, so once your resolution is below the accuracy of your clock, it's kind of pointless. – Jim Clay Dec 11 '12 at 17:20

What you need here is irrational sample rate conversion. This is often required when the conversion factor isn't a convenient rationale number or when real time sample rate conversion between two different clock sources needs to be done. There are multiple ways of doing this but the most popular one are polyphase FIR filters.

There are a bunch of parameters that need to be chose properly. These are

1. Filter length
2. Number of phases
3. Cutoff frequency
4. Filter shape (least square, equiripple, etc.)
5. Required stop band attenuation, allowable pass band ripple
6. Linear or minimum phase
7. Phase interpolation method (if any)

The choice of the parameter depends on the application constraints:

1. MIPS, memory
2. Sensitivity to phase distortions
3. Sensitivity to noise as a function of frequency
4. Latency requirements (if any)

Here is an article from the MATLAB application library that describes some of that in more detail.

http://www.mathworks.com/help/dsp/examples/efficient-sample-rate-conversion-between-arbitrary-factors.html

This lists a specific implementation of the phase calculation through a polynomial fit across phases. It stems mainly from this article: "http://130.230.88.154/images/0/00/Cr1006-2006.pdf" but it's typically not a good choice unless you are heavily memory constraint.

One possibility would be interpolation using a windowed-Sinc interpolation kernel.

The correct way to do this in Matlab is:

128000 -> 16000 ==> resample(x,1,8)

128000 -> 16001 ==> resample(x,16001,128000)

Having said that, I don't know what limitations Matlab places on P & Q.

John

• resample(x,16001,128000) gives an error saying that the product of P and Q has to be smaller than 2^32 – user1542912 Dec 9 '12 at 23:18