jontio / FastFIR

1D real fast FIR filtering. It's really fast compared to slow filtering!!!
https://jontio.github.io/FastFIR
44 stars 13 forks source link

Unexpected delay for fast fir #2

Open geoffreymbrown opened 3 years ago

geoffreymbrown commented 3 years ago

I had expected a delay of N for a filter of length 2N+1. With the slowfir implementation that's what I get; however, the fastfir implementation seems to have an unexpected and much longer delay. Since I'm using a low pass filter to smooth time series data, it's important that the delay be predictable (hence my choice of an FIR filter). I haven't dug into the code, but I'm wondering if the buffer manipulation ends up with data that are not aligned as expected.

jontio commented 3 years ago

Fastfir uses an overlap and add method. Slowfir will always have the lowest latency. It's been ages since I dealt with the nitty-gritty but as I recall the impulse response is converted to the time domain then padded so the FFT is larger than the impulse response. The larger you make the FFT the faster the Fastfir generally is but you get more latency. If you made the FFT the same size as the impulse response I think it would be slower than slowfir. I read in a book that a rule of thumb is you choose the FFT size to be about 4 times that of the impulse response so that's what happens by default. The default is...

int JFastFIRFilter::setKernel(vector<kffsamp_t> imp_responce)
{
    int _nfft=imp_responce.size()*4;//rule of thumb
    _nfft=pow(2.0,(ceil(log2(_nfft))));
    return setKernel(imp_responce,_nfft);
}

You see the 4 times rule of thumb.

If you use this one you can alter the FFT size...

int JFastFIRFilter::setKernel(vector<kffsamp_t> imp_responce, int _nfft)
{
    if(!imp_responce.size())return nfft;
    free(cfg);
    _nfft=pow(2.0,(ceil(log2(_nfft))));
    nfft=_nfft;
    cfg=kiss_fastfir_alloc(imp_responce.data(),imp_responce.size(),&nfft,0,0);
    reset();
    return nfft;
}

I can't remember how to calculate the latency but it's dependent on nfft and imp_responce.size().

https://github.com/jontio/JFFT also has a fastfir class in it.

geoffreymbrown commented 3 years ago

Thanks, that's sort of what I figured. It would be nice if the delay were documented. I ended up using the slowfir implementation because it performed well enough and I knew the delay based upon the filter parameters.