This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

changing the function to use with different array length

Hello,

I am using this FIR_filter function shown below for the 12 filter coefficients but now I want to use

this 12 coefficients FIR_filter function for the 32 coefficients purpose I made the changes but I am not sure if it right!!

int16_t vs_filter(int16_t sample)
{
static int16_t buf[32];
static int offset = 0;
int32_t z;
int i;

buf[offset] = sample;
z = mul16(coeffs[11], buf[(offset - 11) & 0x1F]);
for (i = 0; i < 11; i++)
z += mul16(coeffs[i], buf[(offset - i) & 0x1F] + buf[(offset - 22 + i) & 0x1F]);
offset = (offset + 1) & 0x1F;
return z >> 15;
}

 Needed:for 32 coefficients 

int FIR_filter(int sample)
{
    static int buf[32];
    static int offset = 0;
    long z;
    int i;

    buf[offset] = sample;
    z = mul16(coeffs[31], buf[(offset - 11) & 0x1F]);
    for (i = 0;  i < 31;  i++)
        z += mul16(coeffs[i], buf[(offset - i) & 0x1F] + buf[(offset - 22 + i) & 0x1F]);
    offset = (offset + 1) & 0x1F;
    return  z >> 15;
}

can someone explain if the above will work for 32 coefficeints or anything else is needed.

Also what does these mean 1)buf[(offset - 11) & 0x1F])   2) buf[(offset - 22 + i) & 0x1F]

Thankyou.

  • There's a lot going on in this function, so I'm not sure I'm going to understand it all.  The expression buf[x & 0x1F] is clearly using buf as a circular buffer.  The array buf is a record of past samples, needed for the FIR calculation.  You've greatly increased the number of coeficients, so you're going to need to increase the size of buf to record more past samples.  I think you should make it size 64.  Why 64?  Well, you increased the coefficients by 20, so 32+20=52, but 52 is not a nice power of two, so it does not lend itself to a nice expression of the circular buffer.  If you bump it up to 64, you can change the constant from 0x1F to 0x3F and still have circular buffering. 

    Okay, now we need to look at the expression buf[(offset - i) & 0x1F] + buf[(offset - 22 + i) & 0x1F]. This is adding two samples from the buffer, but which two? As this function gets called repeatedly, offset is incremented, so buf[0] is an earlier sample than buf[1] (until we get to the end and wrap around, but let's ignore that for the moment).  When i=0, we add the current sample (buf[offset]) and a sample far in the past (buf[offset-22]).  When i=1, we add the previous sample (buf[offset-1]) and a sample not quite as far in the past (buf[offset-22+1]).  When i=10 (the last iteration), we add (buf[offset-10]) and (buf[offset-12]).  The loop doesn't access buf[offset -11], that's handled by the mul16 outside the loop.

    So now we have a good idea how those numbers are related, I'm going to guess that the function should look like this:

    int16_t vs_filter(int16_t sample)
    {
    static int16_t buf[64];
    static int offset = 0;
    int32_t z;
    int i;
    
    buf[offset] = sample;
    z = mul16(coeffs[31], buf[(offset - 31) & 0x3F]);
    for (i = 0; i < 31; i++)
    z += mul16(coeffs[i], buf[(offset - i) & 0x3F] + buf[(offset - 62 + i) & 0x3F]);
    offset = (offset + 1) & 0x3F;
    return z >> 15;
    }