Originally Posted by

**rvh**
So if by any chance you'd be willing to show me just the lines I need to upsample a single 128pt audio-object block (by a factor of 4) that would be great.

Sure, here is a bit copy&paste:

The program calculates the filter on the fly, so if you want to that, you'll need this file: output_fm_math.cpp

You can do that one time and print the values and fill a const array with that. I do that dynamically, because I played a lot with the parameters, and it was faster this way.

So, for the coeffs, use can use a filter design tool, or this:

INTERPOLATION = 4

I_SAMPLERATE = SAMPLERATE * INTERPOLATION

NUM_SAMPLES = 128

I_NUM_SAMPLES = NUM_SAMPLES * INTERPOLATION

Code:

const unsigned interpolation_taps = 64;
const float n_att = 90.0; // desired stopband attenuation
const float interpolation_cutoff = 15000.0f; // AUDIO_SAMPLE_RATE_EXACT / 2.0f; //
float interpolation_coeffs[interpolation_taps]; // <- coeffs
[...]
extern void calc_FIR_coeffs (float * coeffs_I, int numCoeffs, float fc, float Astop, int type, float dfc, float Fsamprate);
[...]
//calculate the coeffs:
//calc_FIR_coeffs (float * coeffs_I, int numCoeffs, float fc, float Astop, int type, float dfc, float Fsamprate)
calc_FIR_coeffs(interpolation_coeffs, interpolation_taps, interpolation_cutoff, n_att, 0, 0.0, I_SAMPLERATE);

This code in output_fm_math is not by me, and i can't says much about it.

Cutoff is 15kHZ here. You may want to use half of the samplerate (22kHZ) or way less.

Using less taps will be faster.

Variables for interpolation:

Code:

float interpolation_L_state[(NUM_SAMPLES-1) + interpolation_taps / INTERPOLATION];
arm_fir_interpolate_instance_f32 interpolationL;

Initialize the interpolation:

Code:

// we initiate the number of input samples, NOT the number of interpolated samples
if (arm_fir_interpolate_init_f32(&interpolationL, INTERPOLATION, interpolation_taps, interpolation_coeffs, interpolation_L_state, NUM_SAMPLES)
{
Serial.println("Init of interpolation failed");
while (1);
}

do the interpolation:

I_NUM_SAMPLES = interpolation factor * 128

bL float array[128] of source,

iL interpolated output

Code:

//interpolation:
float iL[I_NUM_SAMPLES];
arm_fir_interpolate_f32(&interpolationL, bL, iL, NUM_SAMPLES);
//Scaling after interpolation
//This is done later, so we can save some multiplications
//arm_scale_f32(iL, (float)INTERPOLATION, iL, I_NUM_SAMPLES);

Done

Decimation is similar.