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.

FIR Filter with circular buffer

Hi,

I am using the c64x DSPLIB DSP_fir_gen function for filtering sample based data. I can not use blocks of data because it will cause too much delay.

Now my problem is that the DSP_fir_gen function does not include a circular buffer which means that the history buffer has to be managed in C code.

I am doing the following:

1) put sample in history buffer

2) call DSP_fir_gen()

3) move all data in the buffer back by one array step.

the time required for this operations (32 Taps) is 17us for the FIR filter and 104us for the data move. (DSK6416T)

Any suggestions how this can be made faster? Any idea how a Hardware Circular Buffer can be used with this?

The c55x DSPLIB contains functions that include a Circular Buffer, why isnt this the case for the c64x Library?

 

Thank you for your help

Michael

  • MikeF,

    Welcome to the TI E2E forum! I hope you will find here a lot of value in the large set of answered threads (use the red Search box or just browse) as well as the answers you will get from the E2E Community. I also want to make sure you are aware of the information on TI.com in the form of documentation and application information, and also the breadth of helpful topics that are addressed on the TI Wiki Pages.

    Instead of moving all the data each time, I would recommend the following two choices:

    1. Better: Make an oversized buffer for your data and move down that buffer as if it were a circular buffer. Once you reach the end, then you will have to move one buffer's size -1 of data. This way, the move operation will not have to happen every time.

    2. Best: Make a double-sized buffer for your data. Write your new samples at two places so that you always have visibility to the last M samples. If the FIR size is M, make the buffer size 2*M, and write sample N [0..M-1] to offset N and N+M. When you get to the end of the double-sized buffer (M..2*M-1), you will have all of the next operation's samples ready the next time at (0..M-1).

    Regards,
    RandyP

     

    If this answers your question, please click the  Verify Answer  button below. If not, please reply back with more information.

  • Randy, I'm trying to wrap my head aroud the "best" implementation you have listed.  Shouldn't the new samples be written in the buffer but shifted by the number of FIR taps to maintain the delay line at the beginning of the buffer?  I'm sure I'm misunderstanding the implementation because the way I'm understanding it is you have 2x sized buffer with elements [0, M/2-1] and [M/2, 2*M-1] being the same ... two duplicate buffers I just don't understand how the delay line is handled ... again I'm sure that I'm just misunderstanding your suggestions.  Thanks.

  • I have not built this, but it seemed like a good idea to use as an alternative to moving a bunch of data after every sample. My brief explanation left a lot to the imagination, so thank you for asking so I could try to add some clarification.

    The easiest way I can think to explain my vision for this solution is to use some pseudo code:

    The data collection part, which puts two copies of each sample into the double-length buffer could be described like this:

    sample_type Buffer[M*2];

    while ( 1 )
      for (i=0;i<M;i++)
        FirIndex=i
        Post semaphore (RunFIR)
        Pend for semaphore (next sample)
        sample_type sample=get_input()
        Buffer[i]=sample
        Buffer[i+M]=sample


    The FIR portion will wait for the latest sample to be written to Buffer, and then it will run for one delay line.

    while ( 1 )
      Pend for (RunFIR)
      FirOut=0
      for (i=0;i<M;i++)
        FirOut+=Buffer[FirIndex+i]*Coeff[i]


    This does not handle filling the buffer for the first M samples, but it looks good (to me) for the ongoing FIR calculations without ever having to stop and move a bunch of samples. Maybe if Buffer is initialized with 0's, it will be okay to start at the beginning.

    EDMA3 can easily handle the filling part instead of using DSP code. This just seemed like a good language for describing the dataflow.

    Please let me know if this helps or not.

    Regards,
    RandyP

     

  • Hello MikeF!

    I don't know, how usefull is my answer now. I'm learning the C674x DSP and had the similar question. How to implement circular buffer for the FIR-filter from DSPLIB. I think, that a simples way to do this is to use the IDMA Controller (IDMA Channel 1 controller, please refer to the device-specific pdf for more information). After a FIR calculations, You can start IDMA-transfer, which carries data in your buffer back by one array step. IDMA transfer will be done IN BACKGROUND realtive to the DSP-core. So during this transfer DSP-core could make another work, for example, calculate next filter etc.

    Pleace note, that the number of bytes to transfer MUST BE A MULTIPLE of 4 bytes. this gives some restrictions to idma using.

    I hope, that my comment will be usefull to You, With best regards, Vitalii