How do you use ProcessBlock? (FIR filter)

Hi everyone,

I am trying to use the FIR filter with ProcessBlock.
I can make it work with Process but not ProcessBlock. When I say it does not work I mean, there is no audio output.

Example that works using Process (with static FIR<FIRFILTER_USER_MEMORY> flt;):

void AudioCallback(AudioHandle::InputBuffer  in,
                   AudioHandle::OutputBuffer out,
                   size_t                    size)
{       
    for(size_t i = 0; i < size; ++i) 
    {
        float input=in[0][i]; 
        float output = flt.Process(input); 
        out[0][i] = output; /*< Left */ 
    }
}

When I do that it works. The seed takes the audio signal input, apply the FIR filter and ouput the expected signal on its audio output.

Example that does not work:

void AudioCallback(AudioHandle::InputBuffer  in,
                   AudioHandle::OutputBuffer out,
                   size_t                    size)
{       
    float input[size]={};
    float output[size]={};
    for(size_t i = 0; i < size; ++i) 
    {
        input[i]=in[0][i]; 
    }
    size_t block_size = size;
    float* pSrc=&input[0];
    float* pDst=&output[0];

    flt.ProcessBlock(pSrc, pDst, block_size); 

    for(size_t i = 0; i < size; ++i) 
    {
        out[0][i] = output[i];
    } 
}

Since ProcessBlock expects float* and in and out are const float* const* and float**, I am trying to use a for loop to transfer the values of into floats and pass the pointers into ProcessBlockā€¦

But the Seed ouputs no audio (noise level).

What should I do?

What you should do is actually post complete program code, since itā€™s not clear if you even allocate and assign the buffer to be used with user memory implementation in that template. And maybe try running debug version to see if anything interesting gets detected by asserts used int FIR filter code.

I canā€™t test it myself right now, but you could probably replace your whole audio callback with something like flt.ProcessBlock(const_cast<float*>(in[0]), out[0], size) or something similar. Not sure if that would help with the actual issue.

Thanks for the tip

Iā€™ll check

Here is the code:

/**   @brief FIR Filter example
 *    @author Alexander Petrov-Savchenko (axp@soft-amp.com)
 *    @date February 2021
 */

#include "daisysp.h"
#include "daisy_seed.h"


using namespace daisysp;
using namespace daisy;

static DaisySeed                  hw;
static FIR<FIRFILTER_USER_MEMORY> flt;


static constexpr size_t flt_size    = 512;  /*< FIR filter length */


static float ir_front[flt_size]    = {0};   /*< Active FIR coefficients */
static float flt_state[flt_size + 1];       /*< Impl-specific storage */



/* Windowed Sinc filter design */
static void UpdateFilter(float freq)
{
     /* Filter coefficients  (Removed the coefficients)*/
ir_front[511] = -0.95000 ;ir_front[510] = -0.35556 ;.... ir_front[2] = -0.01645 ;ir_front[1] = -0.04990 ;ir_front[0] = -0.04105 ;
    
}

void AudioCallback(AudioHandle::InputBuffer  in,
                   AudioHandle::OutputBuffer out,
                   size_t                    size)
{       
    float input[size]={};
    float output[size]={};
    for(size_t i = 0; i < size; ++i) 
    {
        input[i]=in[0][i]; 
    }
    size_t block_size = size;
    float* __restrict pSrc=&input[0];
    float* __restrict pDst=&output[0];

    flt.ProcessBlock(pSrc, pDst, block_size); 

    for(size_t i = 0; i < size; ++i) 
    {
        out[0][i] = output[i];
    }    


}

int main(void)
{
    /* initialize seed hardware and daisysp modules */
    hw.Configure();
    hw.Init();
    hw.SetAudioBlockSize(48);
    
    hw.StartLog(false);
    //hw.StartLog(true);

    /** initialize FIR filter and set parameters 
     * Note: in this mode (user-managed memory) the coefficients
     * are NOT copied, so we may update them at runtime
     */

    flt.SetStateBuffer(flt_state, DSY_COUNTOF(flt_state));
    
    //InitWindow();
    UpdateFilter(0.05f);
    flt.SetIR(&ir_front[0], flt_size, false);

    /* start audio callback */
    hw.StartAudio(AudioCallback);

    while(1)
    {
    }
}
    The length should be determined as follows length >= max_filter_size + max_processing_block - 1

And you have just static float flt_state[flt_size + 1];, so it should be flt_size + 47 (or better yet, define a constant to be used there and when initializing codec). It likely works with a single element processing because effectively it runs code as if max_processing_block = 1 and length requirement is satisfied.

1 Like

It works!!! Thanks Antisvin.

I spent so many hours and it was just written thereā€¦

1 Like