# Differences between Matlab resample() and CMSIS decimate_f32()

I am pretty new to DSP and I need some help to pinpoint my mistake.

I am using Matlab to simulate an embedded environment. I have three signals all centered on 50Hz (6.4KHz sampling rate) which have no offset or harmonics in them. I generate such signals and write them to file using a trusted program. All signals have the same magnitude and frequency content (ie only 50Hz signal) but are 120 degrees apart. Signal 1 starts at zero degrees, second signal is at 240 degrees and third at 120 degrees.

The Matlab signal chain starts with the opening (/dumping) of the file which contains the AC signals. Decimation of the signals is performed using resample() from 6.4KHz down to 1.6KHz (Decimation factor 4), followed by an FFT on a full signal cycle. From the fundamental component (50Hz) the RMS-Magnitude is calculated.

On the ARM Cortex M7 platform now, in a very similar manner as above, I have the same signals written in flash memory. I zero pad at the end of my signal data block to compensate for the FIR group delay. I then decimate the signals using CMSIS arm_fir_decimate_f32(), with filter coefficients generated from Maltab Filter Designer, floowed by a left shift to compensate for the FIR group delay. I then perform an FFT using arm_rfft_fast_f32() on a full signal cycle. Finally, from the fundamental component (50Hz) the RMS-Magnitude is calculated.

I was expecting the Magnitude estimation of the embedded signal to closely match that of the known generated magnitude (/Matlab estimation). However, I am finding the magnitude estimation on the embedded platform to be slightly off when compared to the signal magnitude I know I am generating.

Signal 1 is ~+0.4% (higher), signal 2 is ~-1.7% (lower) and signal 3 is ~-2.03%.

My best guess at the moment is that this discrepancy lies with a mistake I have made with regards to the arm_fir_decimate_f32() filter coefficients. As far as I can tell Matlabs resample() uses the firls() function to generate coefficients.

I have used the same firls() function to generate the coefs, from filter order 20 up to 80 but still get this discrepancy.

Typically I am using Fpass: 160Hz, Cut-off frequency (Fstop): 800Hz, Apass: 0.1dB, Astop: 106dB (ADC SINAD value).

Does resample() compensate for the FIR response?

Any help much appreciated.

Thanks Alex

• an algorithmic criticism: If you're just after a single bin, you don't need the full FFT, and can save loads of CPU and RAM by just doing a Goertzel. Also note that your resampling with a filter of 80 taps is likely to take more CPU than simply doing an FFT of four times the size! So, I'd recommend to drop the resampler all together, and do a Goertzel instead of the whole FFT, or use a different (parametric?) spectrum estimator alltogether, but that depends on your application. – Marcus Müller Jun 6 '18 at 11:17
• I have considered the implications of not downsampling, but I need to run other algorithms on the downsampled signals and would thus rather have a reduced data rate. I am only interested on the 50 and 100Hz bins, so I could run a DFT and that will be less computationally intensive that the FFT. But I am still stuck with this FIR attenuation. – almost_linear Jun 6 '18 at 11:43
• The FFT is the DFT. You could run two Goertzels to get these two bins. – Marcus Müller Jun 6 '18 at 11:48
• Oh, by the way, can you share the filter coefficients in full precision? (note: that's not what you get when you just print the numbers in matlab; that converts to a decimal base and rounds digits, so that the resulting filter is different from what matlab uses internally. A method would be to use save('filename', 'tapsvariablename') or fwrite(fileID, tapsvariable, 'double') to write the true tap values to a file and share that. – Marcus Müller Jun 6 '18 at 12:21
• firls(40,[0 0.2 0.99 1],[1 1 0 0]) ufile.io/v5vqa – almost_linear Jun 6 '18 at 13:05