
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.